More improvements e.g. flags and provision target

This commit is contained in:
2026-08-11 07:48:46 +02:00
parent a3d4825cbd
commit 41556cfe73
22 changed files with 961 additions and 484 deletions
+1 -1
View File
@@ -18,7 +18,7 @@ Yacht Management Software (YMS) Installation
1.3 Web GUI
- Webserver
- PHP
- PHP (>= 8.0)
- php-mysql
- php-xml
+5 -2
View File
@@ -159,7 +159,7 @@ CREATE TABLE inventory (
weight float(5,2) UNSIGNED DEFAULT NULL,
price decimal(12,2) DEFAULT NULL,
purchdate date DEFAULT NULL,
invcond enum('unknown','new','good','normal','bad','repairable','defect') NOT NULL default 'unknown',
invcond enum('unknown','excellent','good','fair','bad','repairable','defect') NOT NULL default 'unknown',
remarks varchar(150) DEFAULT NULL,
PRIMARY KEY (invid),
INDEX ix_invname (invname)
@@ -178,7 +178,7 @@ CREATE TABLE cable (
color char(6) DEFAULT NULL,
supplier smallint(6) DEFAULT NULL,
manufacturer smallint(6) DEFAULT NULL,
cablecond enum('unknown','new','good','normal','bad','repairable','defect') NOT NULL default 'unknown',
cablecond enum('unknown','new','excellent','good','fair','bad','repairable','defect') NOT NULL default 'unknown',
remarks varchar(150) DEFAULT NULL,
PRIMARY KEY (cableid),
INDEX ix_cablename (vid, cablename)
@@ -222,11 +222,13 @@ CREATE TABLE provisions (
sid smallint(6) UNSIGNED DEFAULT NULL,
boxid smallint(6) UNSIGNED NOT NULL DEFAULT 1,
number smallint(6) UNSIGNED NOT NULL DEFAULT 1,
target smallint(6) UNSIGNED DEFAULT NULL, -- for shopping list
weight float(5,2) UNSIGNED DEFAULT NULL,
weight_net float(5,2) UNSIGNED DEFAULT NULL,
unit tinyint(3) DEFAULT NULL,
storedate date DEFAULT CURRENT_DATE,
shelflife date DEFAULT NULL,
remarks varchar(150) DEFAULT NULL,
PRIMARY KEY (provid)
) ENGINE=InnoDB;
@@ -283,6 +285,7 @@ CREATE TABLE company (
customerno varchar(20),
contractno varchar(20),
remarks varchar(150) DEFAULT NULL,
flags set('deleted','historic') DEFAULT NULL,
PRIMARY KEY (compid),
UNIQUE INDEX ix_compname (compname, comptype)
) ENGINE=InnoDB;
+45
View File
@@ -171,6 +171,11 @@ $box = $sth->fetch(PDO::FETCH_OBJ);
echo '<h2>', $box->label, "</h2>\n";
// Bootstrap grid
echo '<div class="container">';
echo '<div class="row">';
echo '<div class="col">';
echo '<table class="table">', "\n";
echo '<tr><th style="width:20%">', _('Box type'),"</th><td>", ($opt_boxtype[$box->boxtype] ?? ''), "</td></tr>\n";
echo '<tr><th>', _('Content'),"</th><td>", $box->content, "</td></tr>\n";
@@ -184,6 +189,46 @@ echo "</table>\n";
form_view_buttons($g_scriptname, $id);
echo '</div>'; // Column break
echo '<div class="col">', "\n";
echo '<div class="card mb-2">', "\n";
echo '<div class="card-header">', _('Images'), "</div>\n";
echo '<div class="card-body d-flex flex-wrap gap-3">', "\n";
$sql = "SELECT d.docid, d.title "
. "FROM docref AS r INNER JOIN document AS d using (docid) "
. "WHERE d.doctype='picture' AND r.reftype='box' AND r.refid=? "
. "ORDER BY d.title";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
$res = $sth->fetchAll();
// TODO hübsche Darstellung
$doccount = 0;
foreach ($res as $row) {
$doccount += 1;
echo '<div class="border rounded p-2 d-flex flex-column" style="width: 150px;">';
echo '<a href="dl.php?id=', $row['docid'], '">';
// echo '<img width="120" src="doc/pic-', $row['hash'], '.', $row['extension'],'">';
echo '<img class="img-fluid rounded mb-2" width="120" src="dl.php?id=', $row['docid'], '" alt="', $row['title'], '">';
echo "</a>\n";
// additionally direct download and go to document details page
echo '<div class="d-flex justify-content-between mt-auto">';
echo '<a href="documents.php?f=view&id=', $row['docid'], '" title="', _('View image details'), '"> <i class="bi bi-eye"></i></a>';
echo '<a href="dl.php?id=', $row['docid'], '" title="', _('Download image'), '"><i class="bi bi-download"></i></a>';
echo "</div>\n";
echo "</div\n";
}
if ($doccount == 0) {
echo _('No referenced images'), "\n";
}
echo "</div>\n"; // card-body
echo "</div>\n"; // card
echo '</div>'; // col
echo '</div>'; // row
echo '</div>'; // container
// Inventory in box
// WIP
$sql = "SELECT invid, invname, weight, number FROM inventory WHERE conttype='box' AND boxid=?";
+18 -3
View File
@@ -63,6 +63,8 @@ switch ($submit = form_get_action()) {
$p[':customerno'] = gpc_get_string($_POST, 'customerno', 20);
$p[':contractno'] = gpc_get_string($_POST, 'contractno', 20);
$p[':remarks'] = gpc_get_string($_POST, 'remarks', 150);
$allowed = db_load_enum('company', 'flags');
$p[':flags'] = gpc_get_set($_POST, 'flags', $allowed, true, NULL);
db_exec_update('company', $p, 'compid');
$action = ACT_VIEW;
break;
@@ -136,7 +138,7 @@ $page = gpc_get_int($_REQUEST, 'p', 1);
$rows_pp = gpc_get_int($_REQUEST, 'n', $user->rows_pp);
$lastpage = ceil($numrows/$rows_pp);
$sql = "SELECT compid, compname, comptype, remarks "
$sql = "SELECT compid, compname, comptype, remarks, flags "
. "FROM company";
if ($where) $sql .= ' WHERE ' . $where;
$sql .= $order;
@@ -212,6 +214,14 @@ foreach ($res as $row) {
echo "<tr>\n";
echo '<td>', $i;
echo '<a title="', _('View'), '" href="', $g_scriptname, '?f=view&id=', $row['compid'], '"><i class="bi bi-eye ms-2"></i></a>', "\n";
// icons for some flags
$flags = explode(',', $row['flags']);
if (in_array('historic', $flags)) {
echo '<i class="bi bi-h-square ms-2" title="', _('Historic company'), '"></i>';
}
if (in_array('deleted', $flags)) {
echo '<i class="bi bi-recycle ms-2" title="', _('Deleted'), '"></i>';
}
echo "</td>\n";
echo "<td>", $row['compname'], "</td>\n";
echo "<td>", $opt_comptype[$row['comptype']], "</td>\n";
@@ -251,7 +261,7 @@ elseif ($action == ACT_VIEW):
// ========== VARIANT: view single record =====================================
$sql = "SELECT compname, comptype, comptype2, shortname, street, zip, city,"
. " country, contact, phone, email, web, customerno, contractno, remarks "
. " country, contact, phone, email, web, customerno, contractno, remarks, flags "
. "FROM company "
. "WHERE compid=?";
$sth = $pdo->prepare($sql);
@@ -283,6 +293,7 @@ echo make_weblink($company->web), ' ', $company->web, "</td></tr>\n";
echo '<tr><th scope="row">', _('Customer no.'),"</th><td>", $company->customerno, "</td></tr>\n";
echo '<tr><th scope="row">', _('Contract no.'),"</th><td>", $company->contractno, "</td></tr>\n";
echo '<tr><th scope="row">', _('Remarks'),"</th><td>", $company->remarks, "</td></tr>\n";
echo '<tr><th scope="row">', _('Flags'),"</th><td>", $company->flags, "</td></tr>\n";
echo "</table>\n";
form_view_buttons($g_scriptname, $id);
@@ -330,7 +341,7 @@ elseif ($action == ACT_EDIT):
echo '<h2>', _('Edit Company'), "</h2>\n";
$sql = "SELECT compname, comptype, comptype2, street, zip, city, country,"
. " contact, phone, email, web, customerno, contractno, remarks "
. " contact, phone, email, web, customerno, contractno, remarks, flags "
. "FROM company "
. "WHERE compid=?";
$sth = $pdo->prepare($sql);
@@ -409,6 +420,10 @@ form_create_select('comptype2', _('Secondary company type'), $g_opt_none + $opt_
<label for="remarks" class="form-label"><?=_('Remarks')?></label>
<textarea class="form-control" id="remarks" name="remarks" rows="3"><?=$company->remarks ?></textarea>
</div>
<?php
$opt_flags = db_load_enum('company', 'flags', true, true, false);
form_create_checks('flags', _('Flags'), $opt_flags, explode(',', $company->flags));
?>
<button type="submit" name="submit[update]" class="btn btn-primary"><?=_('Save')?></button>
<a href="<?=$g_scriptname?>?f=view&id=<?=$id?>" class="btn btn-secondary"><?=_('Back')?></a>
</form>
+54 -20
View File
@@ -6,6 +6,14 @@
* SPDX-License-Identifier: WTFPL
******************************************************************************/
/*
doctype icons
generic: file-earmark
image: file-earmark-image
drawing: file-earmark-easel
pdf: file-earmark-pdf
*/
require 'globals.inc';
require 'lib/gpc.inc';
require 'lib/fileutils.inc';
@@ -143,6 +151,12 @@ switch ($submit = form_get_action()) {
break;
case 'delete':
// check user rights
if ($user->role == ROLE_SAILOR) {
$g_error->Add(_('User level allows no deletion!'));
$action = ACT_VIEW;
break;
}
// Security token needed!
if (gpc_get_string($_POST, 'token', 16) != $_SESSION['token']) {
$g_error->Add(_('Delete prohibited, invalid security token!'));
@@ -189,21 +203,18 @@ switch ($submit = form_get_action()) {
$p[':docid'] = $id;
$p[':refid'] = gpc_get_int($_POST, 'refid');
$p[':reftype'] = gpc_get_enum($_POST, 'reftype', $opt_reftype, 'equipment');
/* $sql = "INSERT INTO docref "
. " (docid, refid, reftype) "
. "VALUES "
. " (:docid, :refid, :reftype)";
$sth = $pdo->prepare($sql);
$sth->bindValue(':docid', $id, PDO::PARAM_INT);
$sth->bindValue(':refid', $refid, PDO::PARAM_INT);
$sth->bindValue(':reftype', $reftype, PDO::PARAM_STR);
$sth->execute(); */
db_exec_insert('docref', $p);
$action = ACT_VIEW;
break;
case 'delref':
// remove only link, not critical so get without token is ok
// check user rights
if ($user->role == ROLE_SAILOR) {
$g_error->Add(_('User level allows no deletion!'));
$action = ACT_VIEW;
break;
}
$drid = gpc_get_int($_GET, 'drid');
$sql = "DELETE FROM docref WHERE drid=?";
$sth = $pdo->prepare($sql);
@@ -582,6 +593,18 @@ foreach ($sth->fetchAll() as $row) {
$compids[] = $row['refid'];
}
// Boxes
$boxids = array();
$sql = "SELECT drid, reftype, refid, CONCAT_WS(' - ', label, NULLIF(content, '')) AS target "
. "FROM docref INNER JOIN box ON (docref.reftype='box' AND docref.refid=box.boxid) "
. "WHERE docid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
foreach ($sth->fetchAll() as $row) {
$references[] = $row;
$boxids[] = $row['refid'];
}
echo '<table class="table table-sm">', "\n";
echo "<thead>\n";
echo "<tr>";
@@ -600,6 +623,8 @@ foreach ($references as $ref) {
echo '<a title="', _('View'), '" href="equipment.php?f=view&id=', $ref['refid'],'"><i class="bi-eye ms-2"></i></a>';
} elseif ($ref['reftype'] == 'company') {
echo '<a title="', _('View'), '" href="company.php?f=view&id=', $ref['refid'],'"><i class="bi-eye ms-2"></i></a>';
} elseif ($ref['reftype'] == 'box') {
echo '<a title="', _('View'), '" href="box.php?f=view&id=', $ref['refid'],'"><i class="bi-eye ms-2"></i></a>';
}
echo "</td>";
echo "<td>", get_enum($ref['reftype']), "</td>";
@@ -616,18 +641,12 @@ echo '<h4>', _('Add new reference'), "</h4>\n";
// enum('vessel','box','equipment','project','task','user','company')
//
// Reference options
$opt_reference = db_load_enum('docref', 'reftype', lookup:true, as_dict:true);
// Equipment options
// Do not include equipment that has already been referenced in the list!
$opt_equipment = array();
$sql = "SELECT eid, ename FROM equipment WHERE vid=? ORDER BY ename";
$sth = $pdo->prepare($sql);
$sth->execute([$user->vid]);
foreach ($sth->fetchAll() as $row) {
if (!in_array($row['eid'], $eids)) {
$opt_equipment[$row['eid']] = $row['ename'];
}
}
$opt_equipment = db_get_opt_equip($user->vid, exclude:$eids)
?>
<form class="mb-3" method="post" action="<?=$g_scriptname?>">
<input type="hidden" name="id" value="<?=$id?>">
@@ -656,8 +675,6 @@ foreach ($sth->fetchAll() as $row) {
$opt_company[$row['compid']] = $row['compname'];
}
}
?>
<form class="mb-3" method="post" action="<?=$g_scriptname?>">
<input type="hidden" name="id" value="<?=$id?>">
@@ -673,6 +690,23 @@ foreach ($opt_company as $k => $v) {
<button class="btn btn-sm btn-secondary" name="submit[addref]">Referenzieren</button>
</form>
<?php
// Box options
$opt_box = db_get_opt_box($user->vid, exclude:$boxids)
?>
<form class="mb-3" method="post" action="<?=$g_scriptname?>">
<input type="hidden" name="id" value="<?=$id?>">
<input type="hidden" name="reftype" value="box">
<label for="eid"><?=_('Box')?></label>
<select class="form-select mb-2" name="refid" id="boxid">
<?php
foreach ($opt_box as $k => $v) {
echo '<option value="', $k, '">', $v, "</option>\n";
}
?>
</select>
<button class="btn btn-sm btn-secondary" name="submit[addref]">Referenzieren</button>
</form>
<?php
// Vessel options
// Do not include vessel that has already been referenced in the list!
+18 -1
View File
@@ -74,6 +74,8 @@ switch ($submit = form_get_action()) {
$p[':ecat'] = gpc_get_int($_POST, 'category');
if ($p[':ecat'] <= 0) $p[':ecat'] = NULL;
$p[':remarks'] = gpc_get_string($_POST, 'remarks', 150);
$allowed = db_load_enum('equipment', 'flags');
$p[':flags'] = gpc_get_set($_POST, 'flags', $allowed, true, NULL);
db_exec_update('equipment', $p, 'eid');
$action = ACT_VIEW;
break;
@@ -374,6 +376,17 @@ foreach ($res as $row) {
echo "<tr>\n";
echo "<td>", $i;
echo '<a class="text-nowrap" title="', _('View'), '" href="', $g_scriptname, '?f=view&id=', $row['eid'], '"><i class="bi bi-eye ms-2"></i></a>', "\n";
// icons for some flags
$flags = explode(',', $row['flags']);
if (in_array('ordered', $flags)) {
echo '<i class="bi bi-cart3" title="', _('Ordered'), '"></i>';
}
if (in_array('deleted', $flags)) {
echo '<i class="bi bi-recycle" title="', _('Deleted'), '"></i>';
}
if (in_array('removed', $flags)) {
echo '<i class="bi bi-x-square" title="', _('Removed'), '"></i>';
}
echo "</td>\n";
echo "<td>", $row['ename'], "</td>\n";
echo "<td>", ($opt_manufacturer[$row['manufacturer']] ?? ''), "</td>\n";
@@ -624,7 +637,7 @@ foreach ($sth->fetchAll() as $row) {
}
$sql = "SELECT eid, ename, model, serial, weight, price, purchdate,"
. " supplier, manufacturer, ecat, shortname, remarks "
. " supplier, manufacturer, ecat, shortname, remarks, flags "
. "FROM equipment "
. "WHERE eid=?";
$sth = $pdo->prepare($sql);
@@ -671,6 +684,10 @@ form_create_select('category', _('Category'), $g_opt_unknown + $opt_ecat, $equip
<label for="remarks" class="form-label"><?=_('Remarks')?></label>
<textarea class="form-control" id="remarks" name="remarks" rows="3"><?=$equipment->remarks ?></textarea>
</div>
<?php
$opt_flags = db_load_enum('equipment', 'flags', true, true, false);
form_create_checks('flags', _('Flags'), $opt_flags, explode(',', $equipment->flags));
?>
<button type="submit" name="submit[update]" class="btn btn-primary"><?=_('Save')?></button>
<a href="<?=$g_scriptname?>?f=view&id=<?=$id?>" class="btn btn-secondary"><?=_('Back')?></a>
</form>
+34 -12
View File
@@ -39,6 +39,11 @@ define ('ACT_UNLINK', 11);
define ('ACT_MAIL', 12);
define ('ACT_VIEW_LIST', 13);
define('ROLE_VESSEL', 'vessel');
define('ROLE_CAPTAIN', 'captain');
define('ROLE_HELMSMAN', 'helmsman');
define('ROLE_SAILOR', 'sailor');
// ========== PAGE START CODE =================================================
// global version string
@@ -396,8 +401,8 @@ function db_exec_insert($table, $params) {
global $pdo;
global $g_error;
$keys = array_keys($params);
$fields = join(',', array_map(function($s) { return ltrim($s, ':'); }, $keys));
$pnames = join(',', $keys);
$fields = join(', ', array_map(function($s) { return ltrim($s, ':'); }, $keys));
$pnames = join(', ', $keys);
$sql = "INSERT INTO $table ($fields) VALUES ($pnames)";
// $sth = $pdo->prepare("INSERT INTO $table ($fields) VALUES ($pnames)");
$sth = $pdo->prepare($sql);
@@ -433,7 +438,7 @@ function db_exec_update($table, $params, $pk) {
unset($fields[':'.$pk]);
$where = "$pk=:$pk";
}
$fieldlist = join(',', array_map(fn($s) => ltrim($s, ':') . '=' . $s, array_keys($fields)));
$fieldlist = join(', ', array_map(fn($s) => ltrim($s, ':') . '=' . $s, array_keys($fields)));
$sql = "UPDATE $table SET $fieldlist WHERE $where";
$sth = $pdo->prepare($sql);
try {
@@ -526,12 +531,15 @@ function get_enum($enum) {
'drawing' => _('Drawing'),
'equipment' => _('Equipment'),
'estimated' => _('Estimated'),
'excellent' => _('Excellent'),
'fair' => _('Fair'),
'finished' => _('Finished'),
'fixed' => _('Fixed'),
'fuse' => _('Fuse'),
'generic' => _('Generic'),
'good' => _('Good'),
'high' => _('High'),
'historic' => _('Historic'),
'invoice' => _('Invoice'),
'locked' => _('Locked'),
'low' => _('Low'),
@@ -806,7 +814,7 @@ function db_get_opt_storage($vid) {
return $list;
}
function db_get_opt_box($vid) {
function db_get_opt_box($vid, $exclude=[]) {
global $pdo;
global $g_error;
$list = array();
@@ -821,12 +829,14 @@ function db_get_opt_box($vid) {
$g_error->Add($e->getMessage());
}
foreach ($sth->fetchAll(PDO::FETCH_NUM) as $rec) {
$list[$rec[0]] = $rec[1] . ' - '. $rec[2];
if (! in_array($rec[0], $exclude)) {
$list[$rec[0]] = $rec[1] . ($rec[2] ? ' - '. $rec[2] : '');
}
}
return $list;
}
function db_get_opt_equip($vid, $default=NULL) {
function db_get_opt_equip($vid, $default=NULL, $exclude=[]) {
global $pdo;
global $g_error;
if (isset($default)) {
@@ -842,8 +852,10 @@ function db_get_opt_equip($vid, $default=NULL) {
$g_error->Add($e->getMessage());
}
foreach ($sth->fetchAll(PDO::FETCH_NUM) as $rec) {
if (! in_array($rec[0], $exclude)) {
$list[$rec[0]] = $rec[1];
}
}
return $list;
}
@@ -1050,11 +1062,21 @@ function form_create_select($fieldname, $label, $optlist, $selval=NULL, $multipl
echo "</div>\n";
}
function form_create_checks($fieldname, $label, $optlist, $selected) {
echo '<div class="mb-3">', "\n";
echo '<label>', $label, "</label>\n";
print_r($optlist);
echo "</div>\n";
function form_create_checks($fieldname, $label, $optlist, $selected = []) {
echo '<fieldset class="mb-3">';
echo '<legend class="fs-6 mb-1 border-bottom pb-1">', $label, "</legend>\n";
echo '<div class="d-flex flex-wrap gap-3">';
foreach ($optlist as $k => $v) {
echo '<div class="form-check">';
$checked = in_array($k, $selected, true) ? ' checked' : '';
echo '<label class="form-check-label">';
echo '<input type="checkbox" class="form-check-input" name="', $fieldname, '[', $k, ']"', $checked, '>';
echo $v;
echo '</label>';
echo '</div>';
}
echo '</div>';
echo '</fieldset>';
}
// TODO DEPRECATED for touch multiple adjacent buttuns are not well suited.
@@ -1418,7 +1440,7 @@ function make_weblink($dest) {
} elseif (!in_array($scheme, ['http', 'https'], true)) {
return '';
}
return '<a href="' . $dest . '"><i class="bi-globe"></i></a>';
return '<a href="' . $dest . '" target="_blank"><i class="bi-globe"></i></a>';
}
function make_maillink($dest) {
Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

+5 -1
View File
@@ -242,7 +242,11 @@ if (isset($vessel->loa)) {
$h = round($row['wy'] * $f);
$x = round($row['x'] * $f - $w / 2.0);
$y = round($row['y'] * $f + $shape['height'] / 2.0 - $h / 2.0);
$rect = $g->addChild('rect');
$a = $g->addChild('a');
$a->addAttribute('href', 'storage.php?f=view&id=' . $row['sid']);
$rect = $a->addChild('rect');
$rect->addChild('title', $row['sname']);
$rect->addAttribute('x', $x);
$rect->addAttribute('y', $y);
+10 -5
View File
@@ -121,7 +121,7 @@ if ($action == ACT_DEFAULT):
page_caption_search($pagetitle);
$flt = db_get_filter($user->id, 201, ['cond','name','txt']);
$flt = db_get_filter($user->id, 201, ['stor', 'cond','txt']);
/*
The only way to find out whether the inventory is on the current boat is to use
@@ -301,7 +301,7 @@ echo '<h2>', _('Add Inventory'), "</h2>\n";
<form method="post" action="<?=$g_scriptname?>">
<div class="mb-3">
<label for="invname" class="form-label"><?=_('Name')?></label>
<input type="text" class="form-control" id="invname" name="invname">
<input type="text" class="form-control" id="invname" name="invname" autofocus>
</div>
<div class="mb-3">
<label for="number" class="form-label"><?=_('Number')?></label>
@@ -310,12 +310,14 @@ echo '<h2>', _('Add Inventory'), "</h2>\n";
<div class="mb-3">
<label for="conttype" class="form-label"><?=_('Container type')?></label>
<select class="form-select" name="conttype" id="conttype">
<option value="box"><?=_('Box')?></option>
<option value="storage"><?=_('Storage')?></option>
<option value="box"><?=_('Box')?></option>
</select>
</div>
<?php
form_create_select('sid', _('Storage'), $g_opt_none + $opt_storage);
// load current filter setting for storage default setting
$flt = db_get_filter($user->id, 201, ['stor','cond','txt']);
form_create_select('sid', _('Storage'), $g_opt_none + $opt_storage, $flt->stor);
form_create_select('boxid', _('Box'), $g_opt_none + $opt_box);
?>
<div class="container-fluid px-0 my-3">
@@ -371,7 +373,10 @@ echo '<tr><th style="width:20%">', _('Box type'),"</th><td>", $inventory->contty
// Container with link
echo '<tr><th>', $inventory->conttype == 'storage' ? _('Storage') : _('Container');
echo '</th><td>', sprintf(_('%s in %s'), $box['label'], $storagename);
// TODO insert link
// link to box
if ($inventory->conttype == 'box') {
echo '<a class="text-nowrap" title="', _('View Box'), '" href="box.php?f=view&id=', $inventory->boxid, '"><i class="bi bi-eye ms-2"></i></a>', "\n";
}
echo "</td></tr>\n";
echo "<tr><th>", _('Location ID'), "</th><td>", $inventory->locationid, "</td></tr>\n";
+10
View File
@@ -0,0 +1,10 @@
<?php
/******************************************************************************
* YMS - Yacht Management Software
* Copyright (C) 2024-2026 Thomas Hooge
*
* SPDX-License-Identifier: WTFPL
******************************************************************************
*/
+469 -405
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.
+20
View File
@@ -0,0 +1,20 @@
{
"name": "Shopping list",
"short_name": "Shopping",
"start_url": "/",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#0d6efd",
"icons": [
{
"src": "img/pwa-192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "img/pwa-512.png",
"sizes": "512x512",
"type": "image/png"
}
]
}
+2 -1
View File
@@ -134,7 +134,8 @@ Es handelt sich um die Eingabemöglichkeit in ein einzelnes Textfeld.</p>
<p>Benutzer können nicht über die Web-GUI eingerichtet werden.</p>
<p>Eine Kennwortänderung ist ebenfalls nicht über die Web-GUI möglich.</p>
<p>Es gibt die Berechtigungsebenen <em>Kapitän (captain)</em>,
<em>Steuermann (helmsman)</em> und <em>Matrose (sailor)</em>.
<em>Steuermann (helmsman)</em> und <em>Matrose (sailor)</em>.</p>
<p>Jeder Benutzer kann das Hauptmenü entsprechend seinen Anforderungen einstellen.</p>
<h3>Stammdaten</h3>
<p>Diese Daten ändern sich nicht sehr häufig, sind aber für den Betrieb
+59 -8
View File
@@ -1,7 +1,7 @@
<?php
/******************************************************************************
* YMS - Yacht Management Software
* Copyright (C) 2024 Thomas Hooge
* Copyright (C) 2024-2026 Thomas Hooge
*
* SPDX-License-Identifier: WTFPL
******************************************************************************/
@@ -27,6 +27,7 @@ switch ($submit = form_get_action()) {
case 'view': $action = ACT_VIEW; break;
case 'edit': $action = ACT_EDIT; break;
case 'del': $action = ACT_DELETE; break;
case 'list': $action = ACT_VIEW_LIST; break;
case 'filter':
$flt = array();
@@ -55,7 +56,8 @@ switch ($submit = form_get_action()) {
$p[':provid'] = $id;
$p[':provname'] = gpc_get_string($_POST, 'provname');
$p[':provcat'] = gpc_get_int($_POST, 'provcat');
$p[':number'] = gpc_get_int($_POST, 'number');
$p[':number'] = gpc_get_uint($_POST, 'number');
$p[':target'] = gpc_get_uint($_POST, 'target');
$p[':weight'] = min(gpc_get_float($_POST, 'weight'), 999.99); // limit max value
$p[':weight_net'] = min(gpc_get_float($_POST, 'weight_net'), 999.99);
$p[':unit'] = gpc_get_int($_POST, 'unit');
@@ -63,6 +65,7 @@ switch ($submit = form_get_action()) {
$p[':shelflife'] = gpc_get_string($_POST, 'shelflife');
$p[':sid'] = gpc_get_int($_POST, 'sid');
if ($p[':sid'] <= 0) $p[':sid'] = NULL;
$p[':remarks'] = gpc_get_string($_POST, 'remarks', 150);
db_exec_update('provisions', $p, 'provid');
$action = ACT_VIEW;
break;
@@ -134,7 +137,7 @@ $lastpage = ceil($numrows/$rows_pp);
// d0 is the maximum number of days age
// d1 is the current age in days. If negative then it is over limit
// TODO display over with warning levels: 50% over, 100% over etc.
$sql = "SELECT provid, provname, number, unit, storedate, shelflife, sid,"
$sql = "SELECT provid, provname, number, target, unit, storedate, shelflife, sid,"
. " DATEDIFF(shelflife, storedate) AS d0, DATEDIFF (shelflife, CURDATE()) AS d1 "
. "FROM provisions LEFT OUTER JOIN storage USING (sid)";
$sql .= ' WHERE ' . $where;
@@ -195,7 +198,9 @@ foreach ($res as $row) {
echo '<a class="text-nowrap" title="', _('View'), '" href="', $g_scriptname, '?f=view&id=', $row['provid'], '"><i class="bi bi-eye ms-2"></i></a>', "\n";
echo "</td>\n";
echo "<td>", ! isset($row['sid']) ? '<i class="bi bi-cart3"></i> ' : '', $row['provname'], "</td>\n";
echo "<td>", $row['number'], "</td>\n";
echo '<td>', $row['number'];
if ($row['target']) echo ' (', $row['target'], ')';
echo "</td>\n";
echo "<td>", $opt_unit[$row['unit']], "</td>\n";
echo "<td>", $row['storedate'], "</td>\n";
echo "<td>", $row['shelflife'], "</td>\n";
@@ -224,6 +229,11 @@ echo $pagination;
form_add_button($g_scriptname);
// Shopping list button
echo '<div class="container-fluid px-0 my-3">', "\n";
echo ' <a href="', $g_scriptname, '?f=list" class="btn btn-secondary">',_('Shopping list'), "</a>\n";
echo "</div>\n";
elseif ($action == ACT_ADD):
// ========== VARIANT: add record =============================================
@@ -258,7 +268,8 @@ echo '<h2>', _('Add provisions'), "</h2>\n";
elseif ($action == ACT_VIEW):
// ========== VARIANT: view single record =====================================
$sql = "SELECT provname, provcat, number, unit, weight, weight_net, storedate, shelflife, sid "
$sql = "SELECT provname, provcat, number, target, unit, weight, weight_net,"
. " storedate, shelflife, sid, remarks "
. "FROM provisions "
. "WHERE provid=?";
$sth = $pdo->prepare($sql);
@@ -269,13 +280,15 @@ echo '<h2>', $prov->provname, "</h2>\n";
echo '<table class="table">', "\n";
echo '<tr><th style="width:20%">', _('Number'),"</th><td>", $prov->number, "</td></tr>\n";
echo "<tr><th>", _('Target'), "</th><td>", $prov->target, "</td></tr>\n";
echo "<tr><th>", _('Weight'), "</th><td>", format_float($prov->weight, 2, 'kg'), "</td></tr>\n";
echo "<tr><th>", _('Weight net'), "</th><td>", format_float($prov->weight_net, 2, 'kg'), "</td></tr>\n";
echo '<tr><th>', _('Unit'),"</th><td>", $opt_unit[$prov->unit], "</td></tr>\n";
echo '<tr><th>', _('Category'),"</th><td>", $opt_category[$prov->provcat] ?? 'n/a', "</td></tr>\n";
echo '<tr><th>', _('Storedate'),"</th><td>", $prov->storedate, "</td></tr>\n";
echo '<tr><th>', _('Shelflife'),"</th><td>$prov->shelflife</td></tr>\n";
echo '<tr><th>', _('Shelflife'),"</th><td>", $prov->shelflife, "</td></tr>\n";
echo '<tr><th>', _('Storage'),"</th><td>", ($opt_storage[$prov->sid] ?? ''), "</td></tr>\n";
echo '<tr><th>', _('Remarks'),"</th><td>", nl2br($prov->remarks), "</td></tr>\n";
echo "</table>\n";
form_view_buttons($g_scriptname, $id);
@@ -283,7 +296,8 @@ form_view_buttons($g_scriptname, $id);
elseif ($action == ACT_EDIT):
// ========== VARIANT: edit single record =====================================
$sql = "SELECT provname, provcat, number, weight, weight_net, unit, storedate, shelflife, sid "
$sql = "SELECT provname, provcat, number, target, unit, weight, weight_net,"
. " storedate, shelflife, sid, remarks "
. "FROM provisions "
. "WHERE provid=?";
$sth = $pdo->prepare($sql);
@@ -302,6 +316,10 @@ echo '<h2>', _('Edit provision'), "</h2>\n";
<label for="number"><?=_('Number')?></label>
<input type="number" min="0" max="1000" class="form-control" id="number" name="number" value="<?=$prov->number ?>">
</div>
<div class="mb-3">
<label for="target"><?=_('Target')?></label>
<input type="number" min="0" max="1000" class="form-control" id="target" name="target" value="<?=$prov->target ?>">
</div>
<div class="mb-3">
<label for="weight" class="form-label"><?=_('Weight, kg')?></label>
<input type="text" class="form-control" id="weight" name="weight" value="<?=format_float($prov->weight); ?>">
@@ -324,7 +342,12 @@ form_create_select('provcat', _('Category'), $g_opt_none + $opt_category, $prov-
</div>
<?php
form_create_select('sid', _('Storage'), $g_opt_none + $opt_storage, $prov->sid);
?>
<div class="mb-3">
<label for="remarks" class="form-label"><?=_('Remarks')?></label>
<textarea class="form-control" id="remarks" name="remarks" rows="3" maxlength="150"><?=$prov->remarks ?></textarea>
</div>
<?php
form_edit_buttons($g_scriptname, $id);
echo "</form>\n";
@@ -334,6 +357,34 @@ elseif ($action == ACT_DELETE):
echo '<h2>', _('Delete provisions'), "</h2>\n";
?>
<p>Not yet implemented!</p>
<?php
elseif ($action == ACT_VIEW_LIST):
// ========== VARIANT: shopping list ==========================================
echo '<h2>', _('Shopping list'), "</h2>\n";
$sql = "SELECT provid, provname, unit, target - number AS buy "
. "FROM provisions "
. "WHERE target IS NOT NULL AND number < target "
. "ORDER BY provcat, provname";
$sth = $pdo->query($sql);
$res = $sth->fetchAll();
echo "<pre>";
foreach ($res as $row) {
echo $row['provname'];
echo ' ';
echo $row['buy'];
echo ' ';
echo $opt_unit[$row['unit']], "\n";
}
echo "</pre>";
echo '<div class="container-fluid px-0 my-3">', "\n";
echo ' <a href="shopping.php" class="btn btn-primary" target="_blank">',_('Use'), "</a>\n";
echo ' <a href="', $g_scriptname, '" class="btn btn-secondary">',_('Back'), "</a>\n";
echo "</div>\n";
else:
// ========== ERROR UNKNOWN VARIANT ===========================================
+3 -1
View File
@@ -7,7 +7,9 @@
xml:space="preserve"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
xmlns:svg="http://www.w3.org/2000/svg">
<title id="title1">Bavaria 34</title>
<defs
id="defs2" /><g
id="layer2"
transform="translate(-42.346999,-246.66202)"

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

+91 -19
View File
@@ -15,49 +15,121 @@
id="title1472">Etap 23</title><defs
id="defs2" /><metadata
id="metadata307"><rdf:RDF><cc:Work
rdf:about=""><dc:title>Etap 23</dc:title></cc:Work></rdf:RDF></metadata><g
id="layer3"><path
rdf:about=""><dc:title>Etap 23</dc:title><dc:creator><cc:Agent><dc:title>Thomas Hooge</dc:title></cc:Agent></dc:creator></cc:Work></rdf:RDF></metadata><g
id="layer3"
style="display:inline"><path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.529167;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 0.86350443,56.194479 c 0,0 0.69516577,-14.052372 2.35183327,-20.194909 1.6566675,-6.142538 7.2458203,-17.836033 7.2458203,-17.836033 0,0 26.514024,-8.2805452 34.450621,-9.6979403 12.412423,-2.2167318 31.13408,-6.4342996 53.931466,-6.3070386 19.314615,0.1078193 53.094175,5.573439 76.283115,12.8907639 16.69715,5.268824 40.14414,13.436259 63.79504,23.921131 14.71032,6.521353 26.48827,13.146633 30.48785,15.138539 1.11012,0.552872 0.96357,2.01622 0.96357,2.01622"
d="m 1.1052856,54.788917 c 0,0 0.6951658,-14.052372 2.3518333,-20.194909 C 5.1137864,28.45147 10.70294,16.757975 10.70294,16.757975 c 0,0 26.514024,-8.2805456 34.450621,-9.6979407 12.412423,-2.2167318 31.13408,-5.292081 53.931466,-5.16482 19.314613,0.1078193 53.094173,4.4312204 76.283113,11.7485457 16.69715,5.268824 40.14414,13.436259 63.79504,23.921131 14.71032,6.521353 26.48827,13.146633 30.48785,15.138539 1.11012,0.552872 0.96357,2.01622 0.96357,2.01622"
id="path245" /><use
x="0"
y="0"
xlink:href="#path245"
id="use461"
transform="matrix(1,0,0,-1,-0.01141454,112.22431)" /><path
transform="matrix(1,0,0,-1,-0.02583644,109.41506)" /><path
style="display:inline;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.529169;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:2.11667, 1.05833, 0.529169, 1.05833;stroke-dashoffset:0;stroke-opacity:1"
d="M 8.579525e-7,56.091669 270.48373,56.091668"
d="M 0.21617824,54.888403 270.69991,54.888402"
id="path271" /><path
style="display:inline;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.529168;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 243.01026,40.79159 V 71.25056"
id="path1051-5-20-3-5" /><path
style="display:inline;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.529168;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 143.32867,7.3151282 V 53.180623"
d="M 141.00077,5.7751708 V 53.289576"
id="path1051-5-20-3-5-3" /><path
style="display:inline;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.529167;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 164.7561,10.714004 V 99.134188"
id="path1051-5-20-3-5-3-12" /><path
style="display:inline;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.529168;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 143.01507,70.407464 V 105.23012"
d="M 141.32706,69.583358 V 103.57843"
id="path1051-5-20-3-5-3-1" /><path
style="display:inline;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.529168;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 117.33745,3.3521262 V 12.178617"
d="m 115.51488,2.846606 v 9.332011"
id="path1051-5-20-3-5-3-5" /><path
style="display:inline;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.529169;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 92.185244,2.3233771 V 12.236508"
d="M 89.547681,2.0649268 V 11.978058"
id="path1051-5-20-3-5-3-5-3" /><path
style="display:inline;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.529169;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 89.403808,97.231856 v 9.913134"
id="path1051-5-20-3-5-3-5-3-2" /><path
style="display:inline;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.529169;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 115.3589,96.85088 v 9.91313"
id="path1051-5-20-3-5-3-5-3-2-9" /><path
style="display:inline;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.529168;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 11.231469,16.757066 V 38.605287"
id="path1051-5-20-3-5-3-5-3-3" /><path
style="display:inline;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.529167;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 66.584543,4.8189868 V 107.726"
d="M 46.665868,6.6905874 V 102.66283"
id="path1051-5-20-3-5-3-5-3-3-5" /><path
style="display:inline;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.529167;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 28.255622,38.31381 V 70.001248"
id="path1051-5-20-3-5-3-5-3-3-5-3" /><path
style="display:inline;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.529168;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 10.947278,70.017665 V 92.794003"
id="path1051-5-20-3-5-3-5-3-3-6" /><path
style="display:inline;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.529167;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 64.382325,3.7775863 V 105.52778"
id="path1051-5-20-3-5-3-6" /><path
style="display:inline;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.529167;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 143.50598,12.19599 H 66.434472"
d="M 141.11162,12.19599 H 64.556533"
id="path1051-5-20-3-5-3-6-7" /><path
style="display:inline;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.529167;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 66.45163,38.498153 H 9.4379737"
d="M 140.97949,96.975439 H 64.42441"
id="path1051-5-20-3-5-3-6-7-56" /><path
style="display:inline;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.529167;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 64.665465,38.455882 H 11.166755"
id="path1051-5-20-3-5-3-6-7-5" /><path
style="display:inline;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.529167;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 66.508118,69.931578 H 9.494461"
d="M 64.587907,69.851251 H 10.654816"
id="path1051-5-20-3-5-3-6-7-5-6" /><path
style="display:inline;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.529167;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 142.7458,70.803411 H 67.016281"
d="M 141.45143,69.865723 H 64.299657"
id="path1051-5-20-3-5-3-6-7-5-6-2" /><path
style="display:inline;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.529167;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="M 142.96058,38.598891 H 67.231062"
id="path1051-5-20-3-5-3-6-7-5-6-2-9" /></g></svg>
d="M 141.09882,38.437352 H 64.500753"
id="path1051-5-20-3-5-3-6-7-5-6-2-9" /><rect
style="display:inline;opacity:1;fill:none;stroke:#000001;stroke-width:0.529167;stroke-linejoin:round;stop-color:#000000;stroke-opacity:1"
id="rect461"
width="30.349583"
height="24.124964"
x="102.14861"
y="42.854198"
ry="1.7931767"
rx="1.7931769" /><rect
style="display:inline;fill:none;stroke:#000001;stroke-width:0.529167;stroke-linejoin:round;stroke-opacity:1;stop-color:#000000"
id="rect461-7"
width="17.982452"
height="21.87578"
x="9.5787125"
y="42.54187"
ry="0"
rx="0" /><rect
style="display:inline;fill:none;stroke:#000001;stroke-width:0.529167;stroke-linejoin:round;stroke-opacity:1;stop-color:#000000"
id="rect461-7-7"
width="22.108604"
height="21.87578"
x="141.91139"
y="18.752796"
ry="0"
rx="0" /><path
id="rect2003"
style="opacity:1;fill:none;stroke:#000001;stroke-width:0.529167;stroke-linecap:square;stop-color:#000000"
d="m 165.88922,26.293186 22.28178,-0.232456 52.51134,22.813644 0.10876,13.821074 -53.25092,21.869236 -21.75479,0.157275 z" /><g
id="g3019"
style="display:inline;stroke-width:0.671799"
transform="matrix(0,-0.39255093,0.39513982,0,121.23836,196.67126)"><rect
style="display:inline;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.671799;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
id="rect940-6"
width="51.964359"
height="25.085226"
x="399.42645"
y="81.583931"
ry="1.2706145"
rx="1.2622898" /><ellipse
style="display:inline;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.537439;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
id="path942-2"
cx="413.8573"
cy="94.126541"
rx="6.0959363"
ry="6.1390719" /><ellipse
style="display:inline;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.537439;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
id="path942-2-9"
cx="436.95999"
cy="94.126541"
rx="6.0959363"
ry="6.1390719" /></g></g></svg>

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

+75
View File
@@ -0,0 +1,75 @@
<!DOCTYPE html>
<?php
require 'config.inc';
$pdo = new PDO("mysql:host=$g_db_host;dbname=$g_db_schema;charset=utf8mb4", $g_db_username, $g_db_password);
$sql = "SELECT p.provid, p.provname, p.target - p.number AS buy, d.ddtext as unit "
. "FROM provisions AS p LEFT JOIN dropdown AS d ON p.unit=d.ddval AND d.ddid=6 "
. "WHERE p.target IS NOT NULL AND p.number < p.target "
. "ORDER BY p.provcat, p.provname";
$sth = $pdo->query($sql);
$res = $sth->fetchAll(PDO::FETCH_ASSOC);
// aktuelle Einkaufsliste laden
// localStorage.setItem("liste", JSON.stringify(meineListe));
// let liste = JSON.parse(localStorage.getItem("liste"));
//$liste = getEinkaufsliste();
?>
<html>
<head>
<title>Shopping list</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="manifest" href="manifest.json">
<script src="js/shopping.js" defer></script>
<script>
const initialList = <?= json_encode($res, JSON_UNESCAPED_UNICODE) ?>;
// only activate for production use
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('service-worker.js');
}
</script>
<style>
body{
font-family:Arial,sans-serif;
margin:12px;
}
h1{
text-align:center;
}
table{
width:100%;
border-collapse:collapse;
}
td{
padding:10px 6px;
border-bottom:1px solid #ddd;
font-size:1.1em;
}
td:first-child{
width:40px;
}
td:last-child{
text-align:right;
width:60px;
}
</style>
</head>
<body>
<h1>YMS Einkaufsliste</h1>
<button onclick="location.reload()">Aktualisieren</button>
<h2>Offen</h2>
<div id="shoppingList">
Loading ...
</div>
<h2>Erledigt</h2>
<div id="completedList">
Empty.
</div>
</body>
</html>
+21 -1
View File
@@ -222,7 +222,7 @@ $sql = "SELECT sid, sname, stype, capacity, capaunit, x, y, z, wx, wy, wz, angle
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
$storage = $sth->fetch(PDO::FETCH_OBJ);
echo '<h2>', $storage->sname, "</h2>\n";
echo '<h1>', _('Storage'), ': ', $storage->sname, "</h1>\n";
echo '<table class="table">', "\n";
echo '<tr><th style="width:33%">', _('Typ'),"</th><td>", $opt_stype[$storage->stype], "</td></tr>\n";
@@ -257,6 +257,26 @@ if (count($res) > 0) {
echo '<p>', _('No boxes contained'), "</p>\n";
}
// show assigned inventory here
echo '<h3>', _('Inventory in storage'), "</h3>\n";
$sql = "SELECT invid, invname FROM inventory WHERE conttype='storage' and sid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
$res = $sth->fetchall();
if (count($res) > 0) {
echo '<table class="table table-sm">';
foreach ($res as $row) {
echo "<tr>";
echo '<td>', $row['invname'], "</td>";
echo '<td><a title="', _('View'), '" href="inventory.php?f=view&id=', $row['invid'], '"><i class="bi-eye"></i></a></td>';
echo "</tr>\n";
}
echo "</table>\n";
} else {
echo '<p>', _('No inventory contained'), "</p>\n";
}
// show assigned provisions here
echo '<h3>', _('Provisions in storage'), "</h3>\n";
$sql = "SELECT provid, provname, number, unit, storedate, shelflife FROM provisions WHERE sid=?";
+20 -3
View File
@@ -31,8 +31,9 @@ switch ($submit = form_get_action()) {
case 'filter':
$flt = array();
$flt['prio'] = gpc_get_enum($_POST, 'flt_prio', array_merge(array_keys($opt_priority), ['-2', '-1']));
$flt['stat'] = gpc_get_enum($_POST, 'flt_stat', array_merge(array_keys($opt_state), ['-2', '-1']));
$flt['txt'] = gpc_get_string($_POST, 'flt_txt');
$allowed = db_load_enum('task', 'taskstate');
$flt['stat'] = gpc_get_set($_POST, 'flt_stat', $allowed);
db_save_filter($flt, 206);
$action = ACT_DEFAULT;
break;
@@ -138,10 +139,22 @@ if (strlen($flt->prio) > 2 ) {
} elseif ($flt->prio == -1) {
$w[] = 'priority IS NULL';
}
if (strlen($flt->stat) > 2 ) {
/*if (strlen($flt->stat) > 2 ) {
$w[] = 'taskstate=:taskstate';
$p[':taskstate'] = $flt->stat;
} */
$parts = ["taskstate=''", 'taskstate IS NULL'];
foreach ($flt->stat as $f) {
$parts[] = "FIND_IN_SET('$f', taskstate)";
}
if (!empty($parts)) {
if (count($parts) > 1) {
$w[] = '(' . join(' OR ', $parts) . ')';
} else {
$w[] = $parts[0];
}
}
$where = join(' AND ', $w);
$order = ' ORDER BY t.taskid';
@@ -190,12 +203,16 @@ $res = $sth->fetchAll();
<div class="card-body d-flex flex-wrap gap-3">
<?php
filter_create_select('flt_prio', _('Priority'), $g_opt_all + $g_opt_none + $opt_priority, $flt->prio);
filter_create_select('flt_stat', _('State'), $g_opt_all + $opt_state, $flt->stat);
//filter_create_select('flt_stat', _('State'), $g_opt_all + $opt_state, $flt->stat);
?>
<div class="d-flex flex-nowrap gap-2">
<label for="flt_txt">Text</label>
<input type="text" class="form-control" name="flt_txt" size="15" maxlength="30" value="<?=$flt->txt ?>">
</div>
<?php
$opt_status = db_load_enum('task', 'taskstate', true, true, false);
filter_create_checks('flt_stat', _('Status'), $opt_status, $flt->stat);
?>
</div>
<div class="card-footer">
<button name="submit[filter]" class="btn btn-sm btn-primary" title="<?=_('Apply')?>"><?=_('Go')?></button>