More webgui work. Filters e.g.

This commit is contained in:
2024-04-19 13:25:56 +02:00
parent 851f7e13a2
commit c3b5ef95a9
20 changed files with 853 additions and 585 deletions
+5 -2
View File
@@ -137,8 +137,8 @@ foreach ($opt_storage as $k => $v) {
elseif ($action == ACT_VIEW):
// ========== VARIANT: view single record =====================================
$sql = "SELECT label, content, color, weight, remarks "
. "FROM box "
$sql = "SELECT label, content, color, weight, box.remarks, box.sid, sname "
. "FROM box LEFT JOIN storage USING (sid) "
. "WHERE boxid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
@@ -150,6 +150,9 @@ echo '<table class="table">', "\n";
echo '<tr><th style="width:20%">', _('Content'),"</th><td>", $box->content, "</td></tr>\n";
echo '<tr><th>', _('Color'), '</th><td>', format_color($box->color), "</td></tr>\n";
echo '<tr><th>', _('Weight'), '</th><td>', format_float($box->weight, 2, 'kg'), "</td></tr>\n";
echo '<tr><th>', _('Storage'),"</th><td>", $box->sname;
echo '<a title="', _('View'), '" href="storage.php?f=view&id=', $box->sid, '"><i class="bi-eye"></i></a>';
echo "</td></tr>\n";
echo '<tr><th>', _('Remarks'),"</th><td>", $box->remarks, "</td></tr>\n";
echo "</table>\n";
+81 -9
View File
@@ -23,6 +23,14 @@ switch ($submit = form_get_action()) {
case 'edit': $action = ACT_EDIT; break;
case 'del': $action = ACT_DELETE; break;
case 'filter':
$flt = array();
$flt['type'] = gpc_get_int($_POST, 'flt_type');
$flt['txt'] = gpc_get_string($_POST, 'flt_txt');
db_save_filter($flt, 208);
$action = ACT_DEFAULT;
break;
case 'insert':
$p[':compname'] = gpc_get_string($_POST, 'compname');
$p[':comptype'] = gpc_get_int($_POST, 'comptype');
@@ -33,6 +41,7 @@ switch ($submit = form_get_action()) {
case 'update':
$p[':compid'] = $id;
$p[':compname'] = gpc_get_string($_POST, 'compname');
$p[':shortname'] = gpc_get_string($_POST, 'shortname', 20);
$p[':comptype'] = gpc_get_int($_POST, 'comptype');
$p[':street'] = gpc_get_string($_POST, 'street', 30);
$p[':zip'] = gpc_get_string($_POST, 'zip', 10);
@@ -78,13 +87,69 @@ require 'header.php';
if ($action == ACT_DEFAULT):
// ========== VARIANT: default behavior =======================================
echo '<h1>', $pagetitle , "</h1>\n";
// load filter from db
$flt = db_get_filter($user->id, 208);
$w = array();
$p = array();
if ($flt->type > 0) {
$w[] = 'comptype=:comptype';
$p[':comptype'] = $flt->type;
}
if (strlen($flt->txt) > 1) {
$w[] = '(compname LIKE :txt OR remarks LIKE :txt)';
$p[':txt'] = '%'.$flt->txt.'%';
}
$where = join(' AND ', $w);
$order = ' ORDER BY comptype, compname';
$sql = "SELECT compid, compname, comptype, remarks "
. "FROM company "
. "ORDER BY comptype, compname";
$sth = $pdo->query($sql);
. "FROM company";
if ($where) $sql .= ' WHERE ' . $where;
$sql .= $order;
$sth = $pdo->prepare($sql);
try {
$sth->execute($p);
} catch(PDOException $e) {
$g_error->Add($e->getMessage());
$g_error->Add($sql);
$g_error->Add(print_r($p, true));
}
$res = $sth->fetchAll();
echo '<h1>', $pagetitle , "</h1>\n";
// Filter
$opt_special = array(
-2 => _('&horbar; all &horbar;'),
);
?>
<form method="post" action="<?=$g_scriptname?>">
<div id="filter" class="card">
<div class="card-header">Filter</div>
<div class="card-body">
<label for="flt_type">Type</label>
<select id="flt_type" name="flt_type">
<?php
foreach ($opt_special + $opt_comptype as $k => $v) {
echo '<option value="', $k,'"';
if ($k == $flt->type) {
echo ' selected';
}
echo '>', $v, '</option>';
}
?>
</select>
<label for="flt_txt">Text</label>
<input type="text" name="flt_txt" size="15" maxlength="30" value="<?=$flt->txt?>">
<button name="submit[filter]" class="btn btn-sm btn-primary" title="<?=_('Apply')?>"><?=_('Go')?></button>
</div>
</div>
</form>
<?php
echo '<table class="table table-striped">', "\n";
echo "<thead>\n";
echo "<tr>";
@@ -134,7 +199,7 @@ echo '<h2>', _('Add Company'), "</h2>\n";
elseif ($action == ACT_VIEW):
// ========== VARIANT: view single record =====================================
$sql = "SELECT compname, comptype, street, zip, city, country,"
$sql = "SELECT compname, comptype, shortname, street, zip, city, country,"
. " contact, phone, email, web, customerno, contractno, remarks "
. "FROM company "
. "WHERE compid=?";
@@ -145,7 +210,8 @@ $company = $sth->fetch(PDO::FETCH_OBJ);
echo "<h2>", $company->compname, "</h2>\n";
echo '<table class="table">', "\n";
echo '<tr><th scope="row">', _('Name'),"</th><td>", $company->compname, "</td></tr>\n";
echo '<tr><th scope="row" style="width:20%">', _('Name'),"</th><td>", $company->compname, "</td></tr>\n";
echo '<tr><th scope="row">', _('Short name'),"</th><td>", $company->shortname, "</td></tr>\n";
echo '<tr><th scope="row">', _('Type'),"</th><td>", $opt_comptype[$company->comptype], "</td></tr>\n";
echo '<tr><th scope="row">', _('Street'),"</th><td>", $company->street, "</td></tr>\n";
echo '<tr><th scope="row">', _('Zip, City'),"</th><td>", $company->zip, ' ', $company->city, "</td></tr>\n";
@@ -162,15 +228,17 @@ echo "</table>\n";
form_view_buttons($g_scriptname, $id);
// show referenced equipment
$sql = "SELECT ename FROM equipment WHERE supplier=:id OR manufacturer=:id";
$sql = "SELECT eid, ename FROM equipment WHERE supplier=:id OR manufacturer=:id";
$sth = $pdo->prepare($sql);
$sth->bindValue(':id', $id, PDO::PARAM_INT);
$sth->execute();
if ($sth->rowCount > 0) {
if ($sth->rowCount() > 0) {
echo "<p>Referenced in equipment:</p>\n";
echo "<ul>\n";
foreach ($sth->fetchAll() as $row) {
echo "<li>", $row['ename'], "</li>\n";
echo "<li>", $row['ename'], ' ';
echo '<a title="', _('View'), '" href="equipment.php?f=view&id=', $row['eid'], '"><i class="bi-eye"></i></a>';
echo "</li>\n";
}
echo "</ul>\n";
} else {
@@ -197,6 +265,10 @@ $company = $sth->fetch(PDO::FETCH_OBJ);
<label for="compname" class="form-label"><?=_('Name')?></label>
<input type="text" class="form-control" id="compname" name="compname" value="<?=$company->compname ?>">
</div>
<div class="mb-3">
<label for="shortname" class="form-label"><?=_('Short name')?></label>
<input type="text" class="form-control" id="shortname" name="shortname" value="<?=$company->shortname ?>">
</div>
<div class="mb-3">
<label for="comptype" class="form-label"><?=_('Company type')?></label>
<select name="comptype" class="form-control">
+80 -7
View File
@@ -8,12 +8,27 @@
/* Document Downloader
Doucuments are not directly accessible via filesystem
dl.php must be used with docid as parameter:
e,g, dl.php?id=23 */
dl.php must be used with "docid" as parameter: e.g, dl.php?id=23
In additional parameter "t" (thumb) is set a thumbnail will be returned
Possible values are: s (small), m (medium), l (large)
Thumbnails are generated for pictures (png, jpg) and documents (pdf)
TODO thumbs for svg? needed? perhaps small png thumbs?
*/
require 'globals.inc';
$docid = gpc_get_int($_GET, 'id');
if (! isset($docid)) {
exit(1);
}
$thumb = gpc_get_string($_GET, 't', 1);
$size = array ('s' => 120, 'm' => 240, 'l' => '320');
if (!array_key_exists($thumb, $size)) {
unset($thumb);
}
$sql = "SELECT doctype, docsize, mimetype, hash, extension, filename FROM document WHERE docid=?";
$sth = $pdo->prepare($sql);
@@ -25,23 +40,81 @@ $dtmap = array(
'invoice' => 'inv',
'picture' => 'pic',
'drawing' => 'drw');
// alter Dateiname
// $ofn = sprintf("%s-%s.%s", $dtmap[$row['doctype']], $row['hash'], $row['extension'])
$file = sprintf("%s/%s-%s.%s", $g_doc_basepath, $dtmap[$row['doctype']], $row['hash'], $row['extension']);
if (file_exists($file)) {
// Hash-Dateinamen: Umbenennen in neues Format
// document-format: ttt-nnnnnn.eee
// thumbnail-format: ttt-nnnnnn-ppp-s.eee
$fnew = sprintf('%s/%s-%06d.%s', $g_doc_basepath, $dtmap[$row['doctype']], $docid, $row['extension']);
rename($file, $fnew);
$file = $fnew;
} else {
$file = sprintf('%s/%s-%06d.%s', $g_doc_basepath, $dtmap[$row['doctype']], $docid, $row['extension']);
}
if (isset($thumb)) {
$page = 1; // could be variable in future
if ($row['mimetype'] == 'application/pdf') {
// PDF creates PNG-thumbnails
$thumbname = sprintf('%s-%06d-%03d-%s.png', $dtmap[$row['doctype']], $docid, $page, $thumb);
} else {
$thumbname = sprintf('%s-%06d-%03d-%s.%s', $dtmap[$row['doctype']], $docid, $page, $thumb, $row['extension']);
}
$thumbpath = $g_doc_basepath . '/thumb/' . $thumbname;
if (!file_exists($thumbpath)) {
list($width, $height) = getimagesize($file);
$factor = $size[$thumb] / max($width, $height);
// scale down
if ($row['mimetype'] == 'image/jpeg') {
$orig = imagecreatefromjpeg($file);
$scaled = imagescale($orig, $width * $factor, $height * $factor, IMG_BICUBIC);
imagejpeg($scaled, $thumbpath, 85);
$file = $thumbpath;
$filename = $thumbname;
$fsize = 0; // let's calc later
} elseif ($row['mimetype'] == 'image/png') {
$orig = imagecreatefrompng($file);
} elseif ($row['mimetype'] == 'application/pdf') {
// create preview image from first page of png
// mutool draw -o <thumb>.png -w <width> <filename>.pdf <page>
exec("/usr/bin/mutool draw -o {$thumbpath} -w {$size[$thumb]} $file $page", $output, $retval);
}
}
$file = $thumbpath;
$filename = $thumbname;
$fsize = 0; // let's calc later
} else {
// normal
$filename = $row['filename'];
$fsize = $row['docsize'];
}
if (file_exists($file)) {
// send file to caller
header('Content-Description: File Transfer');
header('Content-Type: ' . $row['mimetype']);
header('Content-Disposition: attachment; filename="' . $row['filename'] . '"');
header('Content-Disposition: attachment; filename="' . $filename . '"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
if ($row['docsize'] == 0) {
if ($fsize == 0) {
header('Content-Length: ' . filesize($file));
} else {
header('Content-Length: ' . $row['docsize']);
header('Content-Length: ' . $fsize);
}
readfile($file);
exit;
} else {
// dynamically create error image
// TODO
// dynamically create error image
header("Content-Type: image/png");
$im = @imagecreate(110, 20) or die(_("Cannot initialize new GD image stream"));
$bgcolor = imagecolorallocate($im, 0, 0, 0);
$txcolor = imagecolorallocate($im, 233, 14, 91);
imagestring($im, 1, 5, 5, "Resource not found!", $txcolor);
imagepng($im);
imagedestroy($im);
}
+98 -30
View File
@@ -22,6 +22,14 @@ switch ($submit = form_get_action()) {
case 'edit': $action = ACT_EDIT; break;
case 'del': $action = ACT_DELETE; break;
case 'filter':
$flt = array();
$flt['doctype'] = gpc_get_string($_POST, 'flt_doctype');
$flt['txt'] = gpc_get_string($_POST, 'flt_txt');
db_save_filter($flt, 209);
$action = ACT_DEFAULT;
break;
case 'insert':
// WIP New standalone document
// debug $g_message->Add(print_r($_FILES, true));
@@ -62,21 +70,20 @@ switch ($submit = form_get_action()) {
}
switch ($file_mimetype) {
case 'application/pdf':
$file_techname = $g_doc_basepath . '/doc-'.$file_hash.'.'.$file_ext;
$doctype = 'generic';
// $p['pages'] = pdf_get_pagecount($file_tmp);
$p[':doctype'] = 'generic';
$p[':pages'] = pdf_get_pagecount($file_tmp);
$prefix = 'doc';
break;
case 'image/svg+xml':
$file_techname = $g_doc_basepath . '/drw-'.$file_hash.'.'.$file_ext;
$doctype = 'drawing';
$p[':doctype'] = 'drawing';
$prefix = 'drw';
break;
case 'image/png':
case 'image/jpeg':
$file_techname = $g_doc_basepath . '/pic-'.$file_hash.'.'.$file_ext;
$doctype = 'picture';
$p[':doctype'] = 'picture';
$prefix = 'pic';
break;
}
$p[':doctype'] = $doctype;
$p[':mimetype'] = $file_mimetype;
$p[':filename'] = $file_name;
$p[':extension'] = $file_ext;
@@ -86,14 +93,15 @@ switch ($submit = form_get_action()) {
$p[':title'] = gpc_get_string($_POST, 'title');
$p[':remarks'] = gpc_get_string($_POST, 'remarks');
$id = db_exec_insert('document', $p);
$file_techname = sprintf('%s/%s-%06d.%s', $g_doc_basepath, $prefix, $id, $file_ext);
move_uploaded_file($file_tmp, $file_techname);
$action = ACT_VIEW;
break;
case 'update':
$p[':docid'] = $id;
$p['filename'] = gpc_get_string($_POST, 'filename');
$p['title'] = gpc_get_string($_POST, 'title', 40);
$p[':filename'] = gpc_get_string($_POST, 'filename');
$p[':title'] = gpc_get_string($_POST, 'title', 40);
$p['remarks'] = gpc_get_string($_POST, 'remarks', 150);
db_exec_update('document', $p, 'docid');
$action = ACT_VIEW;
@@ -149,6 +157,8 @@ if ($action == ACT_DEFAULT):
// All documents
$flt = db_get_filter($user->id, 209);
$opt_doctype = db_load_enum('document', 'doctype', true, true);
/* TODO show all documents which
- are completely unbound: no docref available
- assigned to the current boat: docref with doctype vessel
@@ -156,31 +166,78 @@ if ($action == ACT_DEFAULT):
There can be multiple docref entries for a document,
behavior still needs to be clarified. */
echo "<h1>$pagetitle</h1>\n";
$w = array();
$p = array();
if ($flt->doctype != 'all') {
$w[] = 'doctype=:doctype';
$p[':doctype'] = $flt->doctype;
}
if (strlen($flt->txt) > 1) {
$w[] = '(filename LIKE :txt OR title LIKE :txt OR remarks LIKE :txt)';
$p[':txt'] = '%'.$flt->txt.'%';
}
$where = join(' AND ', $w);
$order = ' ORDER BY docid';
$sql = "SELECT d.docid, d.doctype, d.filename, d.title, COUNT(r.drid) AS refcount "
. "FROM document AS d LEFT OUTER JOIN docref AS r USING (docid) "
. "GROUP BY d.docid, d.doctype, d.filename, d.title";
$sth = $pdo->query($sql);
. "FROM document AS d LEFT OUTER JOIN docref AS r USING (docid)";
if ($where) $sql .= ' WHERE ' . $where;
$sql .= " GROUP BY d.docid, d.doctype, d.filename, d.title";
if ($order) $sql .= $order;
$sth = $pdo->prepare($sql);
$sth->execute($p);
$res = $sth->fetchAll();
echo "<h1>$pagetitle</h1>\n";
// Filter
$opt_special = array(
'all' => _('&horbar; all &horbar;'),
);
?>
<form method="post" action="<?=$g_scriptname?>">
<div id="filter" class="card">
<div class="card-header">Filter</div>
<div class="card-body">
<label for="flt_doctype">Type</label>
<select id="flt_doctype" name="flt_doctype">
<?php
foreach ($opt_special + $opt_doctype as $k => $v) {
echo '<option value="', $k,'"';
if ($k == $flt->doctype) {
echo ' selected';
}
echo '>', $v, '</option>';
}
?>
</select>
<label for="flt_txt">Text</label>
<input type="text" name="flt_txt" size="15" maxlength="30" value="<?=$flt->txt?>">
<button name="submit[filter]" class="btn btn-sm btn-primary" title="<?=_('Apply')?>"><?=_('Go')?></button>
</div>
</div>
</form>
<?php
echo '<table class="table table-striped">', "\n";
echo "<thead>\n";
echo "<tr>";
echo "<th>" . _('ID') . "</th>";
echo "<th>" . _('Type') . "</th>";
echo "<th>" . _('Filename') . "</th>";
echo "<th>" . _('Title') . "</th>";
echo "<th>" . _('Links') . "</th>";
echo "<th>", _('ID'), "</th>";
echo "<th>", _('Type'), "</th>";
echo "<th>", _('Filename'), "</th>";
echo "<th>", _('Title'), "</th>";
echo "<th>", _('Links'), "</th>";
echo "<th>&nbsp;</th>";
echo "</tr>\n";
echo "</thead>\n";
foreach ($res as $row) {
echo "<tr>\n";
echo "<td>". $row['docid'] ."</td>\n";
echo "<td>". $row['doctype'] ."</td>\n";
echo "<td>". $row['filename'] ."</td>\n";
echo "<td>". $row['title'] ."</td>\n";
echo "<td>". $row['refcount'] ."</td>\n";
echo "<td>", $row['docid'], "</td>\n";
echo "<td>", $opt_doctype[$row['doctype']], "</td>\n";
echo "<td>", $row['filename'], "</td>\n";
echo "<td>", $row['title'], "</td>\n";
echo "<td>", $row['refcount'], "</td>\n";
// Action buttons
echo "<td>";
echo '<a title="', _('View'), '" href="', $g_scriptname, '?f=view&id=', $row['docid'], '"><i class="bi-eye"></i></a>', "\n";
@@ -252,6 +309,8 @@ $document = $sth->fetch(PDO::FETCH_OBJ);
echo '<h2>', _('View Document'), "</h2>\n";
echo '<div class="row">', "\n";
echo '<div class="col">', "\n";
echo '<table class="table table-borderless">', "\n";
echo '<tr><th scope="row" style="width:20%">', _('Document type'),"</th><td>", $document->doctype, "</td></tr>\n";
if ($document->doctype == 'picture') {
@@ -266,22 +325,30 @@ if ($document->doctype == 'picture') {
echo '<tr><th scope="row">', _('Drawing'), '</th>';
echo '<td><img src="dl.php?id=', $document->docid, '" alt="', $document->title, '"></td></tr>', "\n";
} elseif (($document->doctype == 'generic')) {
$techname = 'doc-' . $document->hash . '.' . $document->extension;
$techname = sprintf('doc-%06d.%s', $document->docid, $document->extension);
if ($document->mimetype == 'application/pdf') {
// TODO show preview of previewpage, ctrate thumbnail if needed
// TODO show preview of previewpage, create thumbnail if needed
$pages = pdf_get_pagecount("$g_doc_basepath/$techname");
// Download link
echo '<tr><th scope="row">', _('PDF'), '</th><td><a href="dl.php?id=', $document->docid, '">', $document->title ?? _('Download'), "</a></td></tr>\n";
echo '<tr><th scope="row">', _('PDF'), '</th><td><a href="dl.php?id=', $document->docid, '">', $document->title ?? _('Download'), '</a> (', sprintf(_('%d Pages'), $pages), ")</td></tr>\n";
}
}
echo '<tr><th scope="row">', _('Mimetype'),"</th><td>", $document->mimetype, "</td></tr>\n";
echo '<tr><th scope="row">', _('Filename'),"</th><td>", $document->filename, "</td></tr>\n";
echo '<tr><th scope="row">', _('File size'),"</th><td>", $document->docsize, "</td></tr>\n";
echo '<tr><th scope="row">', _('File size'),"</th><td>", format_filesize($document->docsize), "</td></tr>\n";
echo '<tr><th scope="row">', _('Upload date'),"</th><td>", $document->doctime, "</td></tr>\n";
echo '<tr><th scope="row">', _('Title'),"</th><td>", $document->title, "</td></tr>\n";
echo '<tr><th scope="row">', _('Remarks'),"</th><td>", $document->remarks, "</td></tr>\n";
echo "</table>\n";
echo "</div>\n", '<div class="col">', "\n"; // column break
if ($document->mimetype == 'application/pdf') {
echo '<img src="dl.php?id=', $document->docid,'&t=l" alt="PDF-Preview">', "\n";
}
echo "</div>\n</div>\n"; // end of columns
form_view_buttons($g_scriptname, $id);
@@ -306,7 +373,8 @@ foreach ($sth->fetchAll() as $row) {
echo "<td>", $row['reftype'], "</td>";
echo "<td>", $row['name'], "</td>";
echo "<td>";
echo '<a title="', _('Remove'), '" href="', $script, '?f=delref&id=', $id, '&drid=', $row['drid'], '"><i class="bi-trash"></i></a>';
echo '<a title="', _('View'), '" href="equipment.php?f=view&id=', $row['eid'],'"><i class="bi-eye"></i></a>';
echo '<a title="', _('Remove'), '" href="', $g_scriptname, '?f=delref&id=', $id, '&drid=', $row['drid'], '"><i class="bi-trash"></i></a>';
echo "</td>";
echo "</tr>\n";
}
+11 -10
View File
@@ -38,7 +38,7 @@ function create_ddval_form($script, $ddid, $formtype, $row=NULL) {
echo '<div class="col"><div class="form-floating">';
echo '<input type="color" name="color" id="color" class="form-control"';
if ($update) echo ' value="', $row['color'],'"';
if ($update) echo ' value="#', $row['color'],'"';
echo '><label for="color">Color</label></div></div>', "\n";
echo '<div class="col"><div class="form-floating">';
@@ -76,15 +76,7 @@ switch ($submit = form_get_action()) {
$p[':ddshort'] = gpc_get_string($_POST, 'ddshort');
$p[':color'] = gpc_get_color($_POST, 'color');
$p[':sort'] = gpc_get_string($_POST, 'sort');
$keys = array_keys($p);
$fields = join(',', array_map(function($s) { return ltrim($s, ':'); }, $keys));
$pnames = join(',', $keys);
$sth = $pdo->prepare("INSERT INTO dropdown ($fields) VALUES ($pnames)");
try {
$sth->execute($p);
} catch (PDOexception $e) {
$g_error->Add('SQL-Error: '. $e->getMessage());
}
db_exec_insert('dropdown', $p);
$action = ACT_EDIT;
break;
@@ -106,6 +98,15 @@ switch ($submit = form_get_action()) {
$action = ACT_EDIT;
break;
case 'delete':
// only deletable if not used anywhere!
// equipment.?
if ($v <= 0) {
$g_warning->Add(_('Selection lists are not deletable!'));
}
$g_message->Add(_('Delete not yet implemented'));
break;
default:
$g_error->Add(sprintf(_('Unknown function!'), $submit));
$valid = FALSE;
+42 -36
View File
@@ -27,16 +27,12 @@ switch ($submit = form_get_action()) {
case 'del': $action = ACT_DELETE; break;
case 'filter':
// TODO save new filter settings
$flt = array();
$flt['cat'] = gpc_get_int($_POST, 'flt_category');
$flt['manuf'] = gpc_get_int($_POST, 'flt_manuf');
$flt['supp'] = gpc_get_int($_POST, 'flt_supp');
$flt['txt'] = gpc_get_string($_POST, 'flt_txt');
$sql = "UPDATE settings SET valstr=? WHERE userid=? AND sno=200";
$sth = $pdo->prepare($sql);
$sth->execute([json_encode($flt), $user->id]);
// Only warning in case of failure
db_save_filter($flt, 200);
$action = ACT_DEFAULT;
break;
@@ -54,6 +50,7 @@ switch ($submit = form_get_action()) {
case 'update':
$p[':eid'] = $id;
$p[':ename'] = gpc_get_string($_POST, 'ename');
$p[':shortname'] = gpc_get_string($_POST, 'shortname', 20);
$p[':model'] = gpc_get_string($_POST, 'model');
$p[':serial'] = gpc_get_string($_POST, 'serial');
$p[':weight'] = min(gpc_get_float($_POST, 'weight'), 999.99); // limit max value
@@ -185,21 +182,6 @@ if ($action == ACT_DEFAULT):
// load filter from db
$flt = db_get_filter($user->id, 200);
/*$flt = new stdClass();
$sth = $pdo->prepare("SELECT valstr FROM settings WHERE userid=? AND sno=200");
try {
$sth->execute([$user->id]);
$json = $sth->fetchColumn();
if (!$json) {
// no settings record. create empty one for later updates
$sth = $pdo->prepare("INSERT INTO settings (userid, sno, valstr) VALUES (?, 200, '[]')");
$sth->execute([$user->id]);
} else {
$flt = json_decode($json);
}
} catch (PDOexception $e) {
$g_warning->Add('SQL-Error: '. $e->getMessage());
} */
$sort = array(
1 => 'ename',
@@ -223,7 +205,7 @@ if ($flt->supp > 0) {
$p[':supp'] = $flt->supp;
}
if (strlen($flt->txt) > 1) {
$w[] = '(ename LIKE :txt OR model LIKE :txt OR remarks LIK :txt';
$w[] = '(ename LIKE :txt OR model LIKE :txt OR remarks LIKE :txt)';
$p[':txt'] = '%'.$flt->txt.'%';
}
$where = join(' AND ', $w);
@@ -231,7 +213,13 @@ $order = ' ORDER BY ename';
// get total recond count for pagination and limit
$sth = $pdo->prepare("SELECT COUNT(*) FROM equipment WHERE " . $where);
$sth->execute($p);
try {
$sth->execute($p);
} catch(PDOException $e) {
$g_error->Add($e->getMessage());
$g_error->Add($sql);
$g_error->Add(print_r($p, true));
}
$numrows = $sth->fetchColumn();
$lastpage = ceil($numrows/$g_rows_pp);
$page = gpc_get_int($_REQUEST, 'p', 1);
@@ -299,7 +287,7 @@ foreach ($opt_special + $opt_supplier as $k => $v) {
</select>
<label for="flt_txt">Text</label>
<input type="text" name="flt_txt" size="15" maxlength="30" value="<?=$flt->txt?>">
<button name="submit[filter]" class="btn btn-sm btn-primary" title="<?=_('Apply')?>">Go</button>
<button name="submit[filter]" class="btn btn-sm btn-primary" title="<?=_('Apply')?>"><?=_('Go')?></button>
</div>
</div>
</form>
@@ -347,15 +335,6 @@ foreach ($res as $row) {
</tfoot>
</table>
<?php
/*
<nav>
<ul class="pagination justify-content-center">
<li class="page-item"><a class="page-link" href="#">Previous</a></li>
<li class="page-item"><a class="page-link" href="#">1</a></li>
<li class="page-item"><a class="page-link" href="#">2</a></li>
<li class="page-item"><a class="page-link" href="#">Next</a></li>
</ul>
</nav> */
echo $pagination;
form_add_button($g_scriptname);
@@ -394,7 +373,7 @@ elseif ($action == ACT_VIEW):
// ========== VARIANT: view single record =====================================
$sql = "SELECT eid, ename, model, serial, purchdate, price, weight, "
. " supplier, manufacturer, ecat, remarks "
. " supplier, manufacturer, ecat, shortname, remarks "
. "FROM equipment "
. "WHERE eid=?";
$sth = $pdo->prepare($sql);
@@ -408,6 +387,7 @@ echo '<div class="row">';
echo '<div class="col">';
echo '<table class="table">', "\n";
echo '<tr><th>', _('Short name'),"</th><td>", $equipment->shortname, "</td></tr>\n";
echo '<tr><th>', _('Manufacturer'),"</th><td>", $opt_manufacturer[$equipment->manufacturer], "</td></tr>\n";
echo '<tr><th>', _('Model'),"</th><td>", $equipment->model, "</td></tr>\n";
echo '<tr><th>', _('Serial'),"</th><td>", $equipment->serial, "</td></tr>\n";
@@ -426,7 +406,8 @@ echo '<div class="col">';
<?php
$sql = "SELECT d.docid, d.doctype, d.title "
. "FROM docref AS r INNER JOIN document AS d using (docid) "
. "WHERE r.refid=?";
. "WHERE r.refid=? "
. "ORDER BY d.doctype";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
$res = $sth->fetchAll();
@@ -438,7 +419,8 @@ foreach ($res as $row) {
echo "</a>\n";
} elseif ($row['doctype'] == 'generic') {
echo '<a href="dl.php?id=', $row['docid'], '">';
echo $row['title'];
echo '<img width="120" src="dl.php?id=', $row['docid'], '&t=s" alt="', $row['title'], '">';
// echo $row['title'];
echo "</a>\n";
}
}
@@ -460,6 +442,26 @@ echo '</div>'; // container
// Buttons at bottom of data area
form_view_buttons($g_scriptname, $id);
// Maintenance records
echo '<h3>', _('Maintenances'), "</h3>";
$sql = "SELECT maintid, series, activities FROM maintenance WHERE eid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
if ($sth->rowCount() > 0) {
echo "<ul>\n";
foreach ($sth->fetchAll() as $row) {
echo "<li>", $row['activities'], ' ';
echo '<a title="', _('View'), '" href="maintenance.php?f=view&id=', $row['maintid'], '"><i class="bi-eye"></i></a>';
echo "</li>\n";
}
echo "</ul>\n";
} else {
echo '<p>', _('No maintenance records found.'), "<p>\n";
}
elseif ($action == ACT_EDIT):
// ========== VARIANT: edit single record =====================================
@@ -471,7 +473,7 @@ foreach ($sth->fetchAll() as $row) {
}
$sql = "SELECT eid, ename, model, serial, weight, price, purchdate,"
. " supplier, manufacturer, ecat, remarks "
. " supplier, manufacturer, ecat, shortname, remarks "
. "FROM equipment "
. "WHERE eid=?";
$sth = $pdo->prepare($sql);
@@ -485,6 +487,10 @@ $equipment = $sth->fetch(PDO::FETCH_OBJ);
<label for="ename" class="form-label"><?=_('Name')?></label>
<input type="text" class="form-control" id="ename" name="ename" value="<?=$equipment->ename ?>">
</div>
<div class="mb-3">
<label for="shortname" class="form-label"><?=_('Short name')?></label>
<input type="text" class="form-control" id="shortname" name="shortname" value="<?=$equipment->shortname ?>">
</div>
<?php form_create_select('manufacturer', _('Manufacturer'), $opt_manufacturer, $equipment->manufacturer); ?>
<div class="mb-3">
<label for="model" class="form-label"><?=_('Model')?></label>
-294
View File
@@ -1,294 +0,0 @@
<?php
/******************************************************************************
* YMS - Yacht Management Software
* Copyright (C) 2024 Thomas Hooge
*
* SPDX-License-Identifier: WTFPL
******************************************************************************/
require 'globals.inc';
$pagetitle=_('Equipment');
$id = gpc_get_int($_REQUEST, 'id', 0);
// ========== ACTIONS START ===================================================
switch ($submit = form_get_action()) {
case NULL: break;
case 'add': $action = ACT_ADD; break;
case 'view': $action = ACT_VIEW; break;
case 'edit': $action = ACT_EDIT; break;
case 'del': $action = ACT_DELETE; break;
case 'insert':
break;
case 'update':
$action = ACT_VIEW;
break;
case 'delete':
$action = ACT_DEFAULT;
break;
default:
$g_error->Add("Unbekannte Funktion!");
$valid = FALSE;
}
// ========== ACTIONS END =====================================================
require 'header.php';
// ========== PAGE CONTENT ====================================================
if ($action == ACT_DEFAULT):
// ========== VARIANT: default behavior =======================================
echo "<h1>$pagetitle</h1>\n";
$sql = "SELECT eid, ename, make, model, serial, remarks "
. "FROM equipment "
. "ORDER BY eid";
$sth = $pdo->query($sql);
$res = $sth->fetchAll();
echo '<table class="table table-striped">', "\n";
echo "<thead>\n";
echo "<tr>";
echo "<th>" . _('Description') . "</th>";
echo "<th>" . _('Make') . "</th>";
echo "<th>" . _('Model') . "</th>";
echo "<th>" . _('Serial') . "</th>";
echo "<th>" . _('Remarks') . "</th>";
echo "<th>&nbsp;</th>";
echo "</tr>\n";
echo "</thead>\n";
foreach ($res as $row) {
echo "<tr>\n";
echo "<td>". $row['ename'] ."</td>\n";
echo "<td>". $row['make'] ."</td>\n";
echo "<td>". $row['model'] ."</td>\n";
echo "<td>". $row['serial'] ."</td>\n";
echo "<td>". $row['remarks'] ."</td>\n";
// Action buttons
echo "<td>";
echo '<a href="', $g_scriptname, '?f=view&id=', $row['eid'], '">View</a>&nbsp;';
echo '<a href="">Edit</a>';
echo "</td>\n";
echo "</tr>\n";
}
// Table summary
echo "<tfoot>\n";
echo '<tr><td colspan="6">', sprintf(_('%d records'), count($res)), '</td></tr>', "\n";
echo "</tfoot>\n";
echo "</table>\n";
echo '<a href="', $g_scriptname, '?f=add" class="btn btn-info" role="button">', _('Add'), "</a>\n";
elseif ($action == ACT_ADD):
// ========== VARIANT: add record =============================================
?>
<h2><?=_('Add Equipment')?></h2>
<form method="post">
<div class="mb-3">
<label for="ename" class="form-label"><?=_('Name')?></label>
<input type="text" class="form-control" id="ename" name="ename">
</div>
<div class="mb-3">
<label for="make" class="form-label"><?=_('Make')?></label>
<input type="text" class="form-control" id="make" name="make">
</div>
<div class="mb-3">
<label for="model" class="form-label"><?=_('Model')?></label>
<input type="text" class="form-control" id="model" name="make">
</div>
<div class="mb-3">
<label for="serial" class="form-label"><?=_('Serial')?></label>
<input type="text" class="form-control" id="serial" name="serial">
</div>
<button type="submit" class="btn btn-primary"><?=_('Save')?></button>
<a href="<?=$g_scriptname?>" class="btn btn-secondary"><?=_('Back')?></a>
</form>
<?php
elseif ($action == ACT_VIEW):
// ========== VARIANT: view single record =====================================
$sql = "SELECT eid, ename, make, model, serial, remarks "
. "FROM equipment "
. "WHERE eid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
$equipment = $sth->fetch(PDO::FETCH_OBJ);
echo "<h2>", $equipment->ename, "</h2>\n";
// Bootstrap grid
echo '<div class="container">';
echo '<div class="row">';
echo '<div class="col">';
echo "<table>\n";
echo "<tr><td>", _('Make'),"</td><td>", $equipment->make, "</td></tr>\n";
echo "<tr><td>", _('Model'),"</td><td>", $equipment->model, "</td></tr>\n";
echo "<tr><td>", _('Serial'),"</td><td>", $equipment->serial, "</td></tr>\n";
echo "</table>\n";
echo '</div>'; // Column break
echo '<div class="col">';
?>
<p>Images and documents go here</p>
<form id="uploadform" method="post" enctype="multipart/form-data">
<div class="card">
<div class="card-body">
<div id="drop-area" class="border rounded d-flex justify-content-center align-items-center"
style="height: 200px; cursor: pointer;">
<div class="text-center" id="result">
<p>Drag and drop your image here or click to select a file.</p>
</div>
</div>
<input type="file" id="fileElem" multiple accept="image/*" class="d-none" capture="camera">
<input type="submit" name="submit" value="Upload">
</div>
</div>
</form>
<progress id="progress" value="100" max="100" style="display: none;"></progress>
<script>
let dropArea = document.getElementById("drop-area");
["dragenter", "dragover", "dragleave", "drop"].forEach((eventName) => {
dropArea.addEventListener(eventName, preventDefaults, false);
document.body.addEventListener(eventName, preventDefaults, false);
});
["dragenter", "dragover"].forEach((eventName) => {
dropArea.addEventListener(eventName, highlight, false);
});
["dragleave", "drop"].forEach((eventName) => {
dropArea.addEventListener(eventName, unhighlight, false);
});
dropArea.addEventListener("drop", handleDrop, false);
function preventDefaults(e) {
e.preventDefault();
e.stopPropagation();
}
function highlight(e) {
dropArea.classList.add("highlight");
}
function unhighlight(e) {
dropArea.classList.remove("highlight");
}
function handleDrop(e) {
let dt = e.dataTransfer;
let files = dt.files;
handleFiles(files);
}
function handleFiles(files) {
[...files].forEach(uploadFile);
}
function uploadFile(file) {
console.log("Uploading", file.name);
const form = document.querySelector("#uploadform");
const formData = new FormData();
formData.append('files[]', file);
fetch("fileupload.php", { method: "POST", body: formData }).then(
(response) => {
console.log(response);
if (response.status === 200) {
document.querySelector("#result").innerHTML = "Dateien wurden geladen";
}
});
}
dropArea.addEventListener("click", () => {
fileElem.click();
});
let fileElem = document.getElementById("fileElem");
fileElem.addEventListener("change", function (e) {
handleFiles(this.files);
});
// Previes
document.querySelector("#files").addEventListener ("change", function (evt) {
let files = event.target.files;
for (let i = 0, f; f = files[i]; i++) {
let reader = new FileReader();
reader.onload = (function(theFile) {
return function(e) {
let span = document.createElement('span');
span.innerHTML = ['<img class="thumb" src="', e.target.result, '" title="', escape(theFile.name), '"/>'].join('');
document.querySelector ('.filelist').insertBefore(span, null);
};
})(f);
reader.readAsDataURL(f);
}
})
</script>
<?php
echo '</div>'; // col
echo '</div>'; // row
echo '</div>'; // container
// Buttons at bottom of data area
echo '<div class="container">', "\n";
echo '<a href="', $g_scriptname, '?f=edit&id=', $id, '" class="btn btn-info" role="button">', _('Edit'), "</a>\n";
echo '&nbsp;';
echo '<a href="', $g_scriptname, '?f=del&id=', $id, '" class="btn btn-info" role="button">', _('Delete'), "</a>\n";
echo '&nbsp;';
echo '<a href="', $g_scriptname, '" class="btn btn-secondary" role="button">', _('Back'), "</a>\n";
echo "</div>\n";
elseif ($action == ACT_EDIT):
// ========== VARIANT: edit single record =====================================
$sql = "SELECT eid, ename, make, model, serial, remarks "
. "FROM equipment "
. "WHERE eid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
$equipment = $sth->fetch(PDO::FETCH_OBJ);
?>
<h2><?=_('Edit Equipment')?></h2>
<form method="post">
<div class="mb-3">
<label for="ename" class="form-label"><?=_('Name')?></label>
<input type="text" class="form-control" id="ename" name="ename" value="<?=$equipment->ename ?>">
</div>
<div class="mb-3">
<label for="make" class="form-label"><?=_('Make')?></label>
<input type="text" class="form-control" id="make" name="make" value="<?=$equipment->make ?>">
</div>
<div class="mb-3">
<label for="model" class="form-label"><?=_('Model')?></label>
<input type="text" class="form-control" id="model" name="make" value="<?=$equipment->model ?>">
</div>
<div class="mb-3">
<label for="serial" class="form-label"><?=_('Serial')?></label>
<input type="text" class="form-control" id="serial" name="serial" value="<?=$equipment->serial ?>">
</div>
<button type="submit" class="btn btn-primary"><?=_('Save')?></button>
<a href="<?=$g_scriptname?>?f=view&id=<?=$id?>" class="btn btn-secondary"><?=_('Back')?></a>
</form>
<?php
elseif ($action == ACT_DELETE):
// ========== VARIANT: delete record ==========================================
else:
// ========== ERROR UNKNOWN VARIANT ===========================================
echo "<p>", _('Unknown function call: Please report to system development!'), "</p>\n";
endif; // $action == ...
// ========== END OF VARIANTS =================================================
include 'footer.php';
+123 -14
View File
@@ -288,24 +288,50 @@ function db_exec_insert($table, $params) {
$keys = array_keys($params);
$fields = join(',', array_map(function($s) { return ltrim($s, ':'); }, $keys));
$pnames = join(',', $keys);
$sth = $pdo->prepare("INSERT INTO $table ($fields) VALUES ($pnames)");
$sql = "INSERT INTO $table ($fields) VALUES ($pnames)";
// $sth = $pdo->prepare("INSERT INTO $table ($fields) VALUES ($pnames)");
$sth = $pdo->prepare($sql);
try {
$sth->execute($params);
} catch (PDOexception $e) {
$g_error->Add('SQL-Error: '. $e->getMessage());
$g_error->Add($sql);
$g_error->Add(print_r($params, true));
}
return $pdo->LastInsertId();
}
function db_exec_update($table, $params, $pk) {
// TODO primary key with multiple fields: $pk is an array
global $pdo;
global $g_error;
$fields = join(',', array_map(function($s) { return ltrim($s, ':') . '=' . $s; }, array_keys($params)));
$sth = $pdo->prepare("UPDATE $table SET $fields WHERE $pk=:$pk");
$sql = "UPDATE $table SET $fields WHERE $pk=:$pk";
$sth = $pdo->prepare($sql);
try {
$sth->execute($params);
} catch (PDOexception $e) {
$g_error->Add('SQL-Error: '. $e->getMessage());
$g_error->Add($sql);
$g_error->Add(print_r($params, true));
return false;
}
return true;
}
function db_save_filter($flt, $sno) {
global $user;
global $pdo;
global $g_warning;
$sql = "UPDATE settings SET valstr=? WHERE userid=? AND sno=?";
$sth = $pdo->prepare($sql);
try {
$sth->execute([json_encode($flt), $user->id, $sno]);
} catch (PDOexception $e) {
$g_warning->Add('SQL-Error: '. $e->getMessage());
$g_warning->Add($sql);
$g_warning->Add(print_r($flt, true));
$g_warning->Add('Setting: ', $sno);
return false;
}
return true;
@@ -320,7 +346,7 @@ function get_enum($enum) {
'closed' => _('Closed'),
'defect' => _('Defect'),
'done' => _('Done'),
'drawing' => _('Drawng'),
'drawing' => _('Drawing'),
'equipment' => _('Equipment'),
'estimated' => _('Estimated'),
'finished' => _('Finished'),
@@ -330,7 +356,7 @@ function get_enum($enum) {
'invoice' => _('Invoice'),
'locked' => _('Locked'),
'manual' => _('Manual'),
'mono' => _('Monoholl'),
'mono' => _('Monohull'),
'new' => _('New'),
'normal' => _('Normal'),
'ongoing' => _('Ongoing'),
@@ -338,6 +364,7 @@ function get_enum($enum) {
'picture' => _('Picture'),
'planned' => _('Planned'),
'precise' => _('Precise'),
'repairable' => _('Repairable'),
'rough' => _('Rough'),
'storage' => _('Storage'),
'task' => _('Task'),
@@ -536,6 +563,27 @@ function db_get_opt_proj($vid, $default=NULL) {
return $list;
}
function db_get_filter($user, $sno) {
global $pdo;
global $g_warning;
$flt = new stdClass();
$sth = $pdo->prepare("SELECT valstr FROM settings WHERE userid=? AND sno=?");
try {
$sth->execute([$user, $sno]);
$json = $sth->fetchColumn();
if (!$json) {
// no settings record. create empty one for later updates
$sth = $pdo->prepare("INSERT INTO settings (userid, sno, valstr) VALUES (?, ?, '{}')");
$sth->execute([$user, $sno]);
} else {
$flt = json_decode($json);
}
} catch (PDOexception $e) {
$g_warning->Add('SQL-Error: '. $e->getMessage());
}
return $flt;
}
function date_to_sql($var) {
if (!isset($var) || $var == '') {
return NULL;
@@ -563,7 +611,6 @@ function float_to_sql($var) {
// ========== FORM FUNCTIONS ==================================================
function form_create_select($fieldname, $label, $optlist, $selval=NULL) {
//if (
echo '<div class="mb-3">', "\n";
echo '<label for="', $fieldname, '">', $label, "</label>\n";
echo '<select class="form-select" name="', $fieldname,'" id="', $fieldname,'">';
@@ -782,29 +829,29 @@ function format_filesize($size, $format=2) {
switch ($format) {
case 1: // short
if ($size < 1024) {
$size_string = sprintf(_('%d&tinysp;B'), $size);
$size_string = sprintf(_('%d&thinsp;B'), $size);
} elseif ($size < 1048576) {
$size_string = sprintf(_('%.1f&tinysp;kB'), $size/1024);
$size_string = sprintf(_('%.1f&thinsp;kB'), $size/1024);
} else {
$size_string = sprintf(_('%.1f&tinysp;MB'), $size/1048576);
$size_string = sprintf(_('%.1f&thinsp;MB'), $size/1048576);
}
break;
case 2: // medium
if ($size < 1024) {
$size_string = sprintf(_('%d&tinysp;Byte'), $size);
$size_string = sprintf(_('%d&thinsp;Byte'), $size);
} elseif ($size < 1048576) {
$size_string = sprintf(_('%.1f&tinysp;kByte'), $size/1024);
$size_string = sprintf(_('%.1f&thinsp;kByte'), $size/1024);
} else {
$size_string = sprintf(_('%.1f&tinysp;MByte'), $size/1048576);
$size_string = sprintf(_('%.1f&thinsp;MByte'), $size/1048576);
}
break;
case 3: // long
if ($size < 1024) {
$size_string = sprintf(_('%d Byte'), $size);
$size_string = sprintf(_('%d&thinsp;Byte'), $size);
} elseif ($size < 1048576) {
$size_string = sprintf(_('approx. %.1f kByte'), $size/1024);
$size_string = sprintf(_('approx. %.1f&thinsp;kByte'), $size/1024);
} else {
$size_string = sprintf(_('approx. %.1f MByte'), $size/1048576);
$size_string = sprintf(_('approx. %.1f&thinsp;MByte'), $size/1048576);
}
break;
default:
@@ -813,6 +860,68 @@ function format_filesize($size, $format=2) {
return $size_string;
}
function get_pagination($script, $page, $lastpage) {
// no direct output, returns string for multiple output
if ($lastpage < 2) {
return '';
}
$out = '<nav class="my-3">' . "\n";
$out .= '<ul class="pagination justify-content-center">' . "\n";
// First Prev ... Next Last
// TODO build entries for first, prev, next last
if ($lastpage < 10) {
if ($page > 1) {
// Go to first page or previous page
$out .= '<li class="page-item"><a class="page-link" href="'. $script. '?p=1">First</a></li>'. "\n";
$out .= '<li class="page-item"><a class="page-link" href="'. $script. '?p='. ($page - 1). '">Previous</a></li>'. "\n";
} else {
$out .= '<li class="page-item disabled"><a class="page-link href="#">First</a></li>'. "\n";
$out .= '<li class="page-item disabled"><a class="page-link href="#">Previous</a></li>'. "\n";
}
for ($n = 1; $n <= $lastpage; $n++) {
$out .='<li class="page-item"><a class="page-link';
if ($n == $page) $out .= ' active';
$out .= '" href="'. $script. '?p='. $n. '">'. $n. '</a></li>'. "\n";
}
if ($page < $lastpage) {
// go to last page or next page
$out .= '<li class="page-item"><a class="page-link" href="'. $script. '?p='. ($page + 1). '">Next</a></li>'. "\n";
$out .= '<li class="page-item"><a class="page-link" href="'. $script. '?p='. $lastpage. '">Last</a></li>'. "\n";
} else {
$out .= '<li class="page-item disabled"><a class="page-link href="#">Next</a></li>'. "\n";
$out .= '<li class="page-item disabled"><a class="page-link href="#">Last</a></li>'. "\n";
}
} else {
// start working with ... dots
}
// idea: small entry to input page number
$out .= "</ul>\n</nav>\n";
return $out;
}
function pdf_get_pagecount($filename) {
$pages = exec("/usr/bin/mutool show $filename Root/Pages/Count", $output, $retval);
// TODO error checking
return $pages;
}
function pdf_get_preview($docid) {
global $g_doc_basepath;
// create file in thumbs if needed
$thumbfile = $g_doc_basepath . '/thumbs/doc-' . $docid . '.jpg';
if (file_exists($thumbfile)) {
//return "<img src=""
// return existing thumbfile
}
}
// ========== MENU FUNCTIONS ==================================================
$g_menu = Array (
+89 -37
View File
@@ -135,12 +135,11 @@ $sql = "SELECT vesselname, model, loa, lwl, beam, draught, draught_min,"
. "WHERE vid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$vid]);
$vessel = $sth->fetch();
$vessel = $sth->fetch(PDO::FETCH_OBJ);
// get vessel shape
// test for predefined base shape
$shapefilepath = dirname(__FILE__).'/'.$g_shapedir.'/'.$vessel['shapefile'];
if (isset($vessel['shapefile']) and file_exists($shapefilepath)) {
$shapefilepath = dirname(__FILE__).'/'.$g_shapedir.'/'.$vessel->shapefile;
if (isset($vessel->shapefile) and file_exists($shapefilepath)) {
$baseshape = file_get_contents($shapefilepath);
} else {
// use internal default shape
@@ -156,35 +155,88 @@ EOT;
}
$shape = new SimpleXMLElement($baseshape);
// $shape['width'], $shape['height']
$g = $shape->addChild('g');
$g->addAttribute('id', 'boxlayout');
// line for belt
$line = $g->addChild('line');
$line->addAttribute('x1', '100');
$line->addAttribute('y1', '0');
$line->addAttribute('x2', '100');
$line->addAttribute('y2', '350');
$line->addAttribute('style', 'stroke:#ff0000;stroke-width:1px');
if (isset($vessel->beltpos_aft) and isset($vessel->loa) and ($vessel->beltpos_aft < $vessel->loa)) {
$x = round($vessel->beltpos_aft / $vessel->loa * 1024);
$line = $g->addChild('line');
$line->addAttribute('x1', $x);
$line->addAttribute('y1', '0');
$line->addAttribute('x2', $x);
$line->addAttribute('y2', $shape['height']);
$line->addAttribute('style', 'stroke:#ff0000;stroke-width:1px');
}
if (isset($vessel->beltpos_bow) and isset($vessel->loa) and ($vessel->beltpos_bow < $vessel->loa)) {
$x = round($vessel->beltpos_bow / $vessel->loa * 1024);
$line = $g->addChild('line');
$line->addAttribute('x1', $x);
$line->addAttribute('y1', '0');
$line->addAttribute('x2', $x);
$line->addAttribute('y2', $shape['height']);
$line->addAttribute('style', 'stroke:#ff0000;stroke-width:1px');
}
// select all visible storages
// - x,y,z is center of storage
// - todo: shape offset x and y for non centered shapes?
// read center line y-coordinate from shape?
if (isset($vessel->loa)) {
$f = $shape['width'] / ($vessel->loa * 1000);
$sql = "SELECT sid, sname, x, y, wx, wy FROM storage WHERE x>0 AND wx>0 AND wy>0 AND vid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$user->vid]);
foreach ($sth->fetchAll() as $row) {
$w = round($row['wx'] * $f);
$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');
$rect->addChild('title', $row['sname']);
$rect->addAttribute('x', $x);
$rect->addAttribute('y', $y);
$rect->addAttribute('width', $w);
$rect->addAttribute('height', $h);
$rect->addAttribute('stroke', '#000');
$rect->addAttribute('stroke-width', '1px');
$rect->addAttribute('fill', '#57E389');
$rect->addAttribute('fill-opacity', '0.4');
}
// grid
// not yet production ready
/* $step = round($shape['width'] / ($vessel->loa * 10)); // 10cm steps
$x = $step;
$n = 0;
while ($x < ($vessel->loa * 1000)) {
$n += 1;
$line = $g->addChild('line');
$line->addAttribute('x1', $x);
$line->addAttribute('y1', '0');
$line->addAttribute('x2', $x);
$line->addAttribute('y2', $shape['height']);
if ($n % 10 == 0) {
$line->addAttribute('style', 'stroke:#0000dd;stroke-width:1px');
} else {
$line->addAttribute('style', 'stroke:#0000aa;stroke-width:0.3px');
}
$x += $step;
} */
}
// rectangle for storage
$rect = $g->addChild('rect');
$rect->addAttribute('x', '10');
$rect->addAttribute('y', '80');
$rect->addAttribute('width', '40');
$rect->addAttribute('height', '60');
$rect->addAttribute('stroke', '#000');
$rect->addAttribute('stroke-width', '1px');
$rect->addAttribute('fill', '#57E389');
$rect->addAttribute('fill-opacity', '0.4');
// text with link
$link = $g->addChild('a');
/*$link = $g->addChild('a');
$link->addAttribute('xlink:href', 'storage.php?f=view&id=1');
$text = $link->addChild('text', 'Box1');
$text->addAttribute('font-size', '10');
$text->addAttribute('x', '14');
$text->addAttribute('y', '95');
$text->addAttribute('y', '95'); */
?>
<div class="container-fluid my-4">
@@ -199,15 +251,15 @@ $text->addAttribute('y', '95');
<div class="card-body">
<h5 class="card-title"><?=_('Boat data') ?></h5>
<table class="table table-sm">
<tr><td><?=_('Loa')?></td><td><?=format_float($vessel['loa'], 2, 'm')?></td></tr>
<tr><td><?=_('Lwl')?></td><td><?=format_float($vessel['lwl'], 2, 'm')?></td></tr>
<tr><td><?=_('Beam')?></td><td><?=format_float($vessel['beam'], 2, 'm')?></td></tr>
<tr><td><?=_('Draught')?></td><td><?=format_float($vessel['draught'], 2, 'm')?></td></tr>
<tr><td><?=_('Draught, min.')?></td><td><?=format_float($vessel['draught_min'], 2, 'm')?></td></tr>
<tr><td><?=_('Displacement')?></td><td><?=$vessel['displacement']?>&thinsp;kg</td></tr>
<tr><td><?=_('Ballast')?></td><td><?=$vessel['ballast']?>&thinsp;kg</td></tr>
<tr><td><?=_('Belt position aft')?></td><td><?=format_float($vessel['beltpos_aft'], 2, 'm')?></td></tr>
<tr><td><?=_('Belt position bow')?></td><td><?=format_float($vessel['beltpos_bow'], 2, 'm')?></td></tr>
<tr><td><?=_('Loa')?></td><td><?=format_float($vessel->loa, 2, 'm')?></td></tr>
<tr><td><?=_('Lwl')?></td><td><?=format_float($vessel->lwl, 2, 'm')?></td></tr>
<tr><td><?=_('Beam')?></td><td><?=format_float($vessel->beam, 2, 'm')?></td></tr>
<tr><td><?=_('Draught')?></td><td><?=format_float($vessel->draught, 2, 'm')?></td></tr>
<tr><td><?=_('Draught, min.')?></td><td><?=format_float($vessel->draught_min, 2, 'm')?></td></tr>
<tr><td><?=_('Displacement')?></td><td><?=$vessel->displacement?>&thinsp;kg</td></tr>
<tr><td><?=_('Ballast')?></td><td><?=$vessel->ballast?>&thinsp;kg</td></tr>
<tr><td><?=_('Belt position aft')?></td><td><?=format_float($vessel->beltpos_aft, 2, 'm')?></td></tr>
<tr><td><?=_('Belt position bow')?></td><td><?=format_float($vessel->beltpos_bow, 2, 'm')?></td></tr>
</table>
<?php
// Edit vessel only for captain
@@ -363,19 +415,19 @@ $vessel = $sth->fetch(PDO::FETCH_OBJ);
<input type="text" class="form-control" id="model" name="model" value="<?=$vessel->model ?>">
</div>
<div class="mb-3">
<label for="loa" class="form-label"><?=_('LoA')?></label>
<label for="loa" class="form-label"><?=_('LoA')?>, m</label>
<input type="text" class="form-control" id="loa" name="loa" value="<?=format_float($vessel->loa, 2) ?>">
</div>
<div class="mb-3">
<label for="lwl" class="form-label"><?=_('LwL')?></label>
<label for="lwl" class="form-label"><?=_('LwL')?>, m</label>
<input type="text" class="form-control" id="lwl" name="lwl" value="<?=format_float($vessel->lwl, 2) ?>">
</div>
<div class="mb-3">
<label for="beam" class="form-label"><?=_('Beam')?></label>
<label for="beam" class="form-label"><?=_('Beam')?>, m</label>
<input type="text" class="form-control" id="beam" name="beam" value="<?=format_float($vessel->beam, 2) ?>">
</div>
<div class="mb-3">
<label for="draught" class="form-label"><?=_('Draught')?></label>
<label for="draught" class="form-label"><?=_('Draught')?>, m</label>
<input type="text" class="form-control" id="draught" name="draught" value="<?=format_float($vessel->draught, 2) ?>">
</div>
<div class="mb-3">
@@ -391,11 +443,11 @@ $vessel = $sth->fetch(PDO::FETCH_OBJ);
<input type="number" input-mode="decimal" min="0" max="100000" step="1" class="form-control" id="ballast" name="ballast" value="<?=$vessel->ballast ?>">
</div>
<div class="mb-3">
<label for="beltpos_aft" class="form-label"><?=_('Belt position aft')?></label>
<label for="beltpos_aft" class="form-label"><?=_('Belt position aft')?>, m</label>
<input type="text" class="form-control" id="beltpos_aft" name="beltpos_aft" value="<?=format_float($vessel->beltpos_aft, 2) ?>">
</div>
<div class="mb-3">
<label for="beltpos_bow" class="form-label"><?=_('Belt position bow')?></label>
<label for="beltpos_bow" class="form-label"><?=_('Belt position bow')?>, m</label>
<input type="text" class="form-control" id="beltpos_bow" name="beltpos_bow" value="<?=format_float($vessel->beltpos_bow, 2) ?>">
</div>
<?php /*
+97 -17
View File
@@ -13,6 +13,7 @@ $id = gpc_get_int($_REQUEST, 'id', 0);
$opt_storage = db_get_opt_storage($user->vid);
$opt_box = db_get_opt_box($user->vid);
$opt_invcond = db_load_enum('inventory', 'invcond', true, true);
// ========== ACTIONS START ===================================================
@@ -26,6 +27,12 @@ switch ($submit = form_get_action()) {
case 'del': $action = ACT_DELETE; break;
case 'filter':
$flt = array();
$flt['stor'] = gpc_get_string($_POST, 'flt_stor');
//$flt['box'] = gpc_get_string($_POST, 'flt_box');
$flt['cond'] = gpc_get_string($_POST, 'flt_cond');
$flt['txt'] = gpc_get_string($_POST, 'flt_txt');
db_save_filter($flt, 201);
$action = ACT_DEFAULT;
break;
@@ -94,40 +101,113 @@ the box assignment. But this is also intentional to allow easy rearrangement.
echo "<h1>$pagetitle</h1>\n";
$w = array('vid=:vid');
$p = array(':vid' => $user->vid);
if ($flt->stor == -1) {
$w[] = 'i.sid IS NULL';
} elseif ($flt->stor > 0) {
$w[] = 'i.sid=:sid';
$p[':sid'] = $flt->stor;
}
/*if ($flt->cond <> 'all') {
$w[] = 'indcond=:indcond';
$p[':indcond'] = $flt->cond;
}*/
if (strlen($flt->txt) > 1) {
$w[] = 'invname LIKE :txt';
$p[':txt'] = '%'.$flt->txt.'%';
}
$where = join(' AND ', $w);
$order = ' ORDER BY invname';
$sql = "SELECT i.invid, i.invname, i.number, i.invcond, s.sname AS container "
. "FROM inventory AS i JOIN storage AS s ON (i.boxtype='storage' AND i.sid=s.sid)"
. "WHERE s.vid=:vid "
. "UNION "
. "SELECT i.invid, i.invname, i.number, i.invcond, b.label AS container "
. "FROM inventory AS i JOIN storage AS s ON (i.boxtype='storage' AND i.sid=s.sid)";
$sql .= ' WHERE ' . $where;
$sql .= " UNION SELECT i.invid, i.invname, i.number, i.invcond, b.label AS container "
. "FROM inventory AS i JOIN box AS b ON (i.boxtype='box' AND i.boxid=b.boxid) "
. " JOIN storage AS s ON (b.sid=s.sid) "
. "WHERE s.vid=:vid "
. "ORDER BY invname";
. " JOIN storage AS s ON (b.sid=s.sid) ";
$sql .= ' WHERE ' . $where;
$sql .= $order;
$sth = $pdo->prepare($sql);
$sth->bindValue(':vid', $user->vid, PDO::PARAM_INT);
$sth->execute();
try {
$sth->execute($p);
} catch(PDOException $e) {
$g_error->Add($e->getMessage());
$g_error->Add($sql);
$g_error->Add(print_r($p, true));
}
$res = $sth->fetchAll();
// Filter
$opt_special = array(
-2 => _('&horbar; all &horbar;'),
-1 => _('&horbar; none &horbar;')
);
?>
<form method="post" action="<?=$g_scriptname?>">
<div id="filter" class="card">
<div class="card-header">Filter</div>
<div class="card-body">
<?php
// page specific filter start
// - selection for storage
// - selection for box
// page specific filter end
?>
<label for="flt_stor"><?=_('Storage')?></label>
<select id="flt_stor" name="flt_stor">
<?php
foreach ($opt_special + $opt_storage as $k => $v) {
echo '<option value="', $k,'"';
if ($k == $flt->stor) {
echo ' selected';
}
echo '>', $v, '</option>';
}
?>
</select>
<label for="flt_cond"><?=_('Condition')?></label>
<select id="flt_cond" name="flt_cond">
<?php
foreach ($opt_special + $opt_invcond as $k => $v) {
echo '<option value="', $k,'"';
if ($k == $flt->cond) {
echo ' selected';
}
echo '>', $v, '</option>';
}
?>
</select>
<label for="flt_txt">Text</label>
<input type="text" name="flt_txt" size="15" maxlength="30" value="<?=$flt->txt?>">
<button name="submit[filter]" class="btn btn-sm btn-primary" title="<?=_('Apply')?>"><?=_('Go')?></button>
</div>
</div>
</form>
<?php
echo '<table class="table table-striped">', "\n";
echo "<thead>\n";
echo "<tr>\n";
echo "<th>" . _('Name') . "</th>\n";
echo "<th>" . _('Container') . "</th>";
echo "<th>" . _('Number') . "</th>";
echo "<th>" . _('Condition') . "</th>";
echo "<th>", _('Name'), "</th>\n";
echo "<th>", _('Container'), "</th>\n";
echo "<th>", _('Number'), "</th>\n";
echo "<th>", _('Condition'), "</th>\n";
echo "<td></td>\n";
echo "</tr>\n";
echo "</thead>\n";
foreach ($res as $row) {
echo "<tr>\n";
echo '<td>', $row['invname'], "</td>\n";
echo "<td>". $row['container'] ."</td>\n";
echo "<td>". $row['number'] ."</td>\n";
echo "<td>". $row['invcond'] ."</td>\n";
echo "<td>", $row['container'], "</td>\n";
echo "<td>", $row['number'], "</td>\n";
echo "<td>", ($opt_invcond[$row['invcond']] ?? ''), "</td>\n";
form_action_buttons($g_scriptname, $row['invid']);
echo "</tr>\n";
}
// Table summary
echo "<tfoot>\n";
echo '<tr><td colspan="6">', sprintf(_('%d records'), count($res)), '</td></tr>', "\n";
echo '<tr><td colspan="5">', sprintf(_('%d records'), count($res)), '</td></tr>', "\n";
echo "</tfoot>\n";
echo "</table>\n";
+54 -11
View File
@@ -24,6 +24,14 @@ switch ($submit = form_get_action()) {
case 'edit': $action = ACT_EDIT; break;
case 'del': $action = ACT_DELETE; break;
case 'filter':
$flt = array();
$flt['equip'] = gpc_get_int($_POST, 'flt_equip');
$flt['txt'] = gpc_get_string($_POST, 'flt_txt');
db_save_filter($flt, 204);
$action = ACT_DEFAULT;
break;
case 'insert':
$p[':vid'] = $user->vid;
$p[':eid'] = gpc_get_int($_POST, 'eid');
@@ -58,8 +66,41 @@ require 'header.php';
if ($action == ACT_DEFAULT):
// ========== VARIANT: default behavior =======================================
// load filter from db
$flt = db_get_filter($user->id, 204);
echo '<h1>', $pagetitle, "</h1>\n";
// Filter
$opt_special = array(
-2 => _('&horbar; all &horbar;'),
-1 => _('&horbar; none &horbar;')
);
?>
<form method="post" action="<?=$g_scriptname?>">
<div id="filter" class="card">
<div class="card-header">Filter</div>
<div class="card-body">
<label for="flt_equip">Equipment</label>
<select id="flt_equip" name="flt_equip">
<?php
foreach ($opt_special + $opt_equipment as $k => $v) {
echo '<option value="', $k,'"';
if (isset($flt->equip) and $k == $flt->equip) {
echo ' selected';
}
echo '>', $v, '</option>';
}
?>
</select>
<label for="flt_txt">Text</label>
<input type="text" name="flt_txt" size="15" maxlength="30" value="<?=$flt->txt ?? ''?>">
<button name="submit[filter]" class="btn btn-sm btn-primary" title="<?=_('Apply')?>"><?=_('Go')?></button>
</div>
</div>
</form>
<?php
$sql = "SELECT m.maintid, m.activities, m.remarks, e.ename "
. "FROM maintenance AS m LEFT OUTER JOIN equipment AS e USING (eid)"
. "WHERE m.vid=? "
@@ -70,9 +111,9 @@ $res = $sth->fetchAll();
echo '<table class="table table-striped">', "\n";
echo "<thead>\n";
echo "<tr>";
echo "<th>" . _('Activities') . "</th>";
echo "<th>" . _('Equipment') . "</th>";
echo "<th>" . _('Remarks') . "</th>";
echo "<th>", _('Activities'), "</th>";
echo "<th>", _('Equipment'), "</th>";
echo "<th>", _('Remarks'), "</th>";
echo "</tr>\n";
echo "</thead>\n";
foreach ($res as $row) {
@@ -145,6 +186,7 @@ if (isset($maint->eid)) {
$docs = $sth->fetchAll();
} else {
$maint->ename = _('n/a');
unset($docs);
}
// Bootstrap grid
@@ -162,15 +204,16 @@ echo '</div>'; // Column break
echo '<div class="col">';
// TODO Show documents for equipment
?>
<p>Documents</p>
<?php
echo '<ul>', "\n";
foreach ($docs as $d) {
echo '<li>', $d['title'] ?? $d['filename'], ' (', $d['docid'], ")</li>\n";
echo "<h4>Documents</h4>\n";
if (isset($docs)) {
echo '<ul>', "\n";
foreach ($docs as $d) {
echo '<li>', $d['title'] ?? $d['filename'], ' (', $d['docid'], ")</li>\n";
}
echo "</ul>\n";
} else {
echo '<p>', _('No documents found.'), "</p>\n";
}
echo "</ul>\n";
echo '</div>'; // col
echo '</div>'; // row
+4
View File
@@ -58,6 +58,10 @@ Kiste.</p>
<h3>Proviant</h3>
<p>Proviant ist verderblich.
Es wird das Einlagerungsdatum erfaßt und das Haltbarkeitsdatum</p>
<p>Proviant kann einem Stauraum und somit einem Boot zugeordnet sein
oder aber <em>frei</em>.
Freier Proviant kann später zugeordnet
werden. Er ist erkennbar am Einkaufswagen-Symbol <i class="bi bi-basket"></i>.<p>
<h3>Wartung</h3>
<p>Es können einmalige und wiederkehrende Wartungen erfaßt werden</p>
+30 -18
View File
@@ -42,6 +42,14 @@ switch ($submit = form_get_action()) {
case 'edit': $action = ACT_EDIT; break;
case 'del': $action = ACT_DELETE; break;
case 'filter':
$flt = array();
$flt['precision'] = gpc_get_string($_POST, 'flt_precision');
$flt['txt'] = gpc_get_string($_POST, 'flt_txt');
db_save_filter($flt, 207);
$action = ACT_DEFAULT;
break;
case 'insert':
$p[':mname'] = gpc_get_string($_POST, 'mname');
$p[':note'] = gpc_get_string($_POST, 'note');
@@ -61,20 +69,12 @@ switch ($submit = form_get_action()) {
if ($p[':eid'] == -1) {
$p[':eid'] = NULL;
}
$keys = array_keys($p);
$fields = join(',', array_map(function($s) { return ltrim($s, ':'); }, $keys));
$pnames = join(',', $keys);
$sth = $pdo->prepare("INSERT INTO measurement ($fields) VALUES ($pnames)");
try {
$sth->execute($p);
} catch (PDOexception $e) {
$g_error->Add('SQL-Error: '. $e->getMessage());
}
$id = $pdo->LastInsertId();
$id = db_exec_insert('measurement', $p);
$action = ACT_VIEW;
break;
case 'update':
$p[':mid'] = $id;
$p[':mname'] = gpc_get_string($_POST, 'mname');
$p[':nval'] = gpc_get_int($_POST, 'nval'); // 1 to 3 dimensions
$p[':val1'] = gpc_get_int($_POST, 'val1');
@@ -94,14 +94,7 @@ switch ($submit = form_get_action()) {
if ($p[':eid'] == -1) {
$p[':eid'] = NULL;
}
$fields = join(',', array_map(function($s) { return ltrim($s, ':') . '=' . $s; }, array_keys($p)));
$sth = $pdo->prepare("UPDATE measurement SET $fields WHERE mid=:mid");
$p[':mid'] = $id;
try {
$sth->execute($p);
} catch (PDOexception $e) {
$g_error->Add('SQL-Error: '. $e->getMessage());
}
db_exec_update('measurement', $p, 'mid');
$action = ACT_VIEW;
break;
@@ -143,6 +136,25 @@ function format_vals($n, $v1, $v2, $v3) {
echo "<h1>$pagetitle</h1>\n";
// Filter
$opt_special = array(
-2 => _('&horbar; all &horbar;'),
-1 => _('&horbar; none &horbar;')
);
?>
<form method="post" action="<?=$g_scriptname?>">
<div id="filter" class="card">
<div class="card-header">Filter</div>
<div class="card-body">
<label for="flt_txt">Text</label>
<input type="text" name="flt_txt" size="15" maxlength="30" value="<?=$flt->txt?>">
<button name="submit[filter]" class="btn btn-sm btn-primary" title="<?=_('Apply')?>"><?=_('Go')?></button>
</div>
</div>
</form>
<?php
$sql = "SELECT mid, mname, nval, val1, val2, val3, unit, accuracy, mdate, note, eid "
. "FROM measurement "
. "ORDER BY mname";
+26 -31
View File
@@ -29,46 +29,41 @@ switch ($submit = form_get_action()) {
case 'edit': $action = ACT_EDIT; break;
case 'del': $action = ACT_DELETE; break;
case 'filter':
$flt = array();
$flt['txt'] = gpc_get_string($_POST, 'flt_txt');
db_save_filter($flt, 205);
$action = ACT_DEFAULT;
break;
case 'insert':
$projname = gpc_get_string($_POST, 'projname');
$responsible = gpc_get_int($_POST, 'responsible');
$remarks = gpc_get_string($_POST, 'remarks', 150);
$sql = "INSERT INTO project "
. " (vid, projname, responsible, remarks) "
. "VALUES "
. " (:vid, :projname, :responsible, :remarks)";
$sth = $pdo->prepare($sql);
$sth->bindValue(':vid', $user->vid, PDO::PARAM_INT);
$sth->bindValue(':projname', $projname, PDO::PARAM_STR);
$sth->bindValue(':responsible', $responsible, PDO::PARAM_INT);
$sth->bindValue(':remarks', $remarks, PDO::PARAM_STR);
$sth->execute();
$id = $pdo->lastInsertId();
$p['vid'] = $user->id;
$p[':projname'] = gpc_get_string($_POST, 'projname');
$p[':responsible'] = gpc_get_int($_POST, 'responsible');
$p[':remarks'] = gpc_get_string($_POST, 'remarks', 150);
$id = db_exec_insert('company', $p);
$action = ACT_VIEW;
break;
case 'update':
$projname = gpc_get_string($_POST, 'projname');
$startdate = gpc_get_date($_POST, 'startdate');
$duration = gpc_get_int($_POST, 'duration');
$remarks = gpc_get_string($_POST, 'remarks', 150);
$sql = "UPDATE project "
. "SET projname=:projname,"
. " startdate=:startdate,"
. " duration=:duration,"
. " remarks=:remarks "
. "WHERE projid=:projid";
$sth = $pdo->prepare($sql);
$sth->bindValue(':projid', $id, PDO::PARAM_INT);
$sth->bindValue(':projname', $projname, PDO::PARAM_STR);
$sth->bindValue(':startdate', $startdate, PDO::PARAM_STR);
$sth->bindValue(':duration', $duration, PDO::PARAM_INT);
$sth->bindValue(':remarks', $remarks, PDO::PARAM_STR);
$sth->execute();
$p[':projid'] = $id;
$p[':projname'] = gpc_get_string($_POST, 'projname');
$p[':startdate'] = gpc_get_date($_POST, 'startdate');
$p[':duration'] = gpc_get_int($_POST, 'duration');
$p[':remarks'] = gpc_get_string($_POST, 'remarks', 150);
db_exec_update('project', $p, 'projid');
$action = ACT_VIEW;
break;
case 'delete':
// Security token needed!
if (gpc_get_string($_POST, 'token', 16) != $_SESSION['token']) {
$g_error->Add(_('Delete prohibited, invalid security token!'));
$action = ACT_VIEW;
break;
}
unset($_SESSION['token']);
// TBD
$action = ACT_DEFAULT;
break;
+46 -9
View File
@@ -26,6 +26,13 @@ switch ($submit = form_get_action()) {
case 'edit': $action = ACT_EDIT; break;
case 'del': $action = ACT_DELETE; break;
case 'filter':
$flt = array();
$flt['txt'] = gpc_get_string($_POST, 'flt_txt');
db_save_filter($flt, 202);
$action = ACT_DEFAULT;
break;
case 'insert':
$p[':provname'] = gpc_get_string($_POST, 'provname');
$p[':number'] = gpc_get_int($_POST, 'number');
@@ -74,14 +81,44 @@ require 'header.php';
if ($action == ACT_DEFAULT):
// ========== VARIANT: default behavior =======================================
echo "<h1>", $pagetitle, "</h1>\n";
// load filter from db
$flt = db_get_filter($user->id, 202);
$sql = "SELECT provid, provname, number, unit, storedate, shelflife, "
$w = array('(vid=:vid OR sid IS NULL)');
$p = array(':vid' => $user->vid);
if (strlen($flt->txt) > 1) {
$w[] = 'provname LIKE :txt';
$p[':txt'] = '%'.$flt->txt.'%';
}
$where = join(' AND ', $w);
$order = ' ORDER BY provid';
// provisions can be assigned to a store or be free
$sql = "SELECT provid, provname, number, unit, storedate, shelflife, sid,"
. " DATEDIFF(shelflife, storedate) AS d0, DATEDIFF (CURDATE(), storedate) AS d1 "
. "FROM provisions "
. "ORDER BY provid";
$sth = $pdo->query($sql);
. "FROM provisions LEFT OUTER JOIN storage USING (sid)";
$sql .= ' WHERE ' . $where;
$sql .= $order;
$sth = $pdo->prepare($sql);
$sth->execute($p);
$res = $sth->fetchAll();
echo "<h1>", $pagetitle, "</h1>\n";
?>
<form method="post" action="<?=$g_scriptname?>">
<div id="filter" class="card">
<div class="card-header">Filter</div>
<div class="card-body">
<label for="flt_txt">Text</label>
<input type="text" name="flt_txt" size="15" maxlength="30" value="<?=$flt->txt?>">
<button name="submit[filter]" class="btn btn-sm btn-primary" title="<?=_('Apply')?>"><?=_('Go')?></button>
</div>
</div>
</form>
<?php
echo '<table class="table table-striped">', "\n";
echo "<thead>\n";
echo "<tr>\n";
@@ -96,7 +133,7 @@ echo "</tr>\n";
echo "</thead>\n";
foreach ($res as $row) {
echo "<tr>\n";
echo "<td>". $row['provname'] ."</td>\n";
echo "<td>", ! isset($row['sid']) ? '<i class="bi bi-basket"></i> ' : '', $row['provname'], "</td>\n";
echo "<td>". $row['number'] ."</td>\n";
echo "<td>". $opt_unit[$row['unit']] ."</td>\n";
echo "<td>". $row['storedate'] ."</td>\n";
@@ -139,7 +176,7 @@ echo '<h2>', _('Add provisions'), "</h2>\n";
<label for="shelflife"><?=_('Shelflife')?></label>
<input type="date" class="form-control" id="shelflife" name="shelflife">
</div>
<?php form_create_select('sid', _('Storage'), $opt_storage); ?>
<?php form_create_select('sid', _('Storage'), [-1 => '- none -'] + $opt_storage); ?>
<div class="container-fluid px-0 my-3">
<button type="submit" name="submit[insert]" class="btn btn-primary"><?=_('Save')?></button>
<a href="<?=$g_scriptname?>" class="btn btn-secondary"><?=_('Back')?></a>
@@ -163,8 +200,8 @@ echo '<table class="table">', "\n";
echo '<tr><th style="width:20%">', _('Number'),"</th><td>", $prov->number, "</td></tr>\n";
echo '<tr><th>', _('Unit'),"</th><td>", $opt_unit[$prov->unit], "</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>', _('Storage'),"</th><td>", $opt_storage[$prov->sid], "</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 "</table>\n";
form_view_buttons($g_scriptname, $id);
-3
View File
@@ -1,6 +1,3 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="1024"
height="350"

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

-1
View File
@@ -1,4 +1,3 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="297.52466mm"
height="81.989235mm"

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

-3
View File
@@ -1,6 +1,3 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="1024"
height="320"

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

+58 -49
View File
@@ -25,40 +25,24 @@ switch ($submit = form_get_action()) {
case 'del': $action = ACT_DELETE; break;
case 'insert':
$sname = gpc_get_string($_POST, 'sname');
$stype = gpc_get_int($_POST, 'stype');
$sql = "INSERT INTO storage "
. " (vid, sname, stype) "
. "VALUES "
. " (:vid, :sname, :stype)";
$sth = $pdo->prepare($sql);
$sth->bindValue(':vid', $user->vid, PDO::PARAM_INT);
$sth->bindValue(':sname', $sname, PDO::PARAM_STR);
$sth->bindValue(':stype', $stype, PDO::PARAM_INT);
$sth->execute();
$id = $pdo->lastInsertId();
$p[':vid'] = $user->vid;
$p[':sname'] = gpc_get_string($_POST, 'sname');
$p[':stype'] = gpc_get_int($_POST, 'stype');
$id = db_exec_insert('storage', $p);
$action = ACT_VIEW;
break;
case 'update':
$sname = gpc_get_string($_POST, 'sname');
$x = gpc_get_int($_POST, 'x');
$y = gpc_get_int($_POST, 'y');
$z = gpc_get_int($_POST, 'z');
$remarks = gpc_get_string($_POST, 'remarks', 150);
$sql = "UPDATE storage "
. "SET sname=:sname,"
. " x=:x, y=:y, z=:z,"
. " remarks=:remarks "
. "WHERE sid=:sid";
$sth = $pdo->prepare($sql);
$sth->bindValue(':sid', $id, PDO::PARAM_INT);
$sth->bindValue(':sname', $sname, PDO::PARAM_STR);
$sth->bindValue(':x', $x, PDO::PARAM_INT);
$sth->bindValue(':y', $y, PDO::PARAM_INT);
$sth->bindValue(':z', $z, PDO::PARAM_INT);
$sth->bindValue(':remarks', $remarks, PDO::PARAM_STR);
$sth->execute();
$p[':sid'] = $id;
$p[':sname'] = gpc_get_string($_POST, 'sname');
$p[':x'] = gpc_get_int($_POST, 'x');
$p[':y'] = gpc_get_int($_POST, 'y');
$p[':z'] = gpc_get_int($_POST, 'z');
$p[':wx'] = gpc_get_int($_POST, 'wx');
$p[':wy'] = gpc_get_int($_POST, 'wy');
$p[':wz'] = gpc_get_int($_POST, 'wz');
$p[':remarks'] = gpc_get_string($_POST, 'remarks', 150);
db_exec_update('storage', $p, 'sid');
$action = ACT_VIEW;
break;
@@ -111,7 +95,7 @@ echo '<h1>', $pagetitle, "</h1>\n";
// Storage
// stype from dropdown
$sql = "SELECT sid, sname, remarks "
$sql = "SELECT sid, sname, x, y, z, remarks "
. "FROM storage "
. "WHERE vid=? "
. "ORDER BY sid";
@@ -121,15 +105,17 @@ $res = $sth->fetchAll();
echo '<table class="table table-striped">', "\n";
echo "<thead>\n";
echo "<tr>";
echo "<th>" . _('Name') . "</th>";
echo "<th>" . _('Remarks') . "</th>";
echo "<th>", _('Name'), "</th>";
echo "<th>", _('Position'), "</th>";
echo "<th>", _('Remarks'), "</th>";
echo "<th>&nbsp;</th>";
echo "</tr>\n";
echo "</thead>\n";
foreach ($res as $row) {
echo "<tr>\n";
echo "<td>". $row['sname'] ."</td>\n";
echo "<td>". $row['remarks'] ."</td>\n";
echo "<td>", $row['sname'], "</td>\n";
echo "<td>", join(',', array($row['x'] ?? '?', $row['y'] ?? '?', $row['z'])), "</td>\n";
echo "<td>", $row['remarks'], "</td>\n";
form_action_buttons($g_scriptname, $row['sid']);
echo "</tr>\n";
}
@@ -203,7 +189,7 @@ elseif ($action == ACT_VIEW):
// ========== VARIANT: view single record =====================================
$opt_unit = db_get_options(6);
$sql = "SELECT sid, sname, stype, capacity, capaunit, x, y, z, remarks "
$sql = "SELECT sid, sname, stype, capacity, capaunit, x, y, z, wx, wy, wz, remarks "
. "FROM storage "
. "WHERE sid=?";
$sth = $pdo->prepare($sql);
@@ -212,15 +198,16 @@ $storage = $sth->fetch(PDO::FETCH_OBJ);
echo '<h2>', $storage->sname, "</h2>\n";
echo '<table class="table">', "\n";
echo '<tr><th style="width:20%">', _('Typ'),"</th><td>", $stype[$storage->stype], "</td></tr>\n";
echo '<tr><th style="width:33%">', _('Typ'),"</th><td>", $stype[$storage->stype], "</td></tr>\n";
echo '<tr><th>', _('Capacity'),"</th><td>", $storage->capacity, ' ', $storage->capaunit, "</td></tr>\n";
echo '<tr><th>', _('Location (x, y, z)'),"</th><td>(", $storage->x ?? '?', ', ', $storage->y ?? '?', ', ', $storage->z, ")</td></tr>\n";
echo '<tr><th>', _('Location (x, y, z)'),"</th><td>(", $storage->x, ', ', $storage->y, ', ', $storage->z, ")</td></tr>\n";
echo '<tr><th>', _('Width (wx, wy, wz)'),"</th><td>(", $storage->wx, ', ', $storage->wy, ', ', $storage->wz, ")</td></tr>\n";
echo '<tr><th>', _('Remarks'),"</th><td>", $storage->remarks, "</td></tr>\n";
echo "</table>\n";
form_view_buttons($g_scriptname, $id);
// Zugeordnete Kisten hier anzeigen
// show assigned boxes here
echo '<h3>', _('Boxes in storage'), "</h3>\n";
$sql = "SELECT boxid, label, color FROM box WHERE sid=?";
@@ -228,9 +215,15 @@ $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 "$boxid $label $color";
echo "<tr>";
echo '<td>', $row['label'], "</td>";
echo '<td>', $row['color'], "</td>";
echo '<td><a title="', _('View'), '" href="box.php?f=view&id=', $row['boxid'], '"><i class="bi-eye"></i></a></td>';
echo "</tr>\n";
}
echo "</table>\n";
} else {
echo '<p>', _('No boxes contained'), "</p>\n";
}
@@ -260,7 +253,7 @@ elseif ($action == ACT_EDIT):
echo '<h2>', _('Edit Storage'), "</h2>\n";
$sql = "SELECT sid, sname, stype, remarks "
$sql = "SELECT sid, sname, stype, x, y, z, wx, wy, wz, remarks "
. "FROM storage "
. "WHERE sid=?";
$sth = $pdo->prepare($sql);
@@ -275,16 +268,32 @@ $storage = $sth->fetch(PDO::FETCH_OBJ);
<input type="text" class="form-control" id="sname" name="sname" value="<?=$storage->sname ?>">
</div>
<div class="mb-3">
<label for="x" class="form-label"><?=_('Position x')?></label>
<input type="number" class="form-control" id="x" name="x" value="<?=$storage->x ?>">
<label class="form-label"><?=_('Position (x, y, z) in mm')?></label>
<div class="row">
<div class="col">
<input type="number" class="form-control" id="x" name="x" min="0" value="<?=$storage->x ?>">
</div>
<div class="col">
<input type="number" class="form-control" id="y" name="y" value="<?=$storage->y ?>">
</div>
<div class="col">
<input type="number" class="form-control" id="z" name="z" value="<?=$storage->z ?>">
</div>
</div>
</div>
<div class="mb-3">
<label for="y" class="form-label"><?=_('Position y')?></label>
<input type="number" class="form-control" id="y" name="y" value="<?=$storage->y ?>">
</div>
<div class="mb-3">
<label for="z" class="form-label"><?=_('Position z')?></label>
<input type="number" class="form-control" id="z" name="z" value="<?=$storage->z ?>">
<label class="form-label"><?=_('Width (x, y, z) in mm')?></label>
<div class="row">
<div class="col">
<input type="number" class="form-control" id="wx" name="wx" min="0" value="<?=$storage->wx ?>">
</div>
<div class="col">
<input type="number" class="form-control" id="wy" name="wy" min="0" value="<?=$storage->wy ?>">
</div>
<div class="col">
<input type="number" class="form-control" id="wz" name="wz" min="0" value="<?=$storage->wz ?>">
</div>
</div>
</div>
<div class="mb-3">
<label for="remarks" class="form-label"><?=_('Remarks')?></label>