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
+9 -4
View File
@@ -78,9 +78,12 @@ CREATE TABLE storage (
stype tinyint(3) NOT NULL DEFAULT 0,
capacity smallint(6) DEFAULT NULL,
capaunit enum('kg', 'l') DEFAULT NULL,
x smallint(6) NOT NULL DEFAULT 0,
x smallint(6) UNSIGNED NOT NULL DEFAULT 0,
y smallint(6) NOT NULL DEFAULT 0,
z smallint(6) NOT NULL DEFAULT 0,
wx smallint(6) UNSIGNED NOT NULL DEFAULT 0,
wy smallint(6) UNSIGNED NOT NULL DEFAULT 0,
wz smallint(6) UNSIGNED NOT NULL DEFAULT 0,
remarks varchar(150) DEFAULT NULL,
PRIMARY KEY (sid)
);
@@ -122,7 +125,7 @@ CREATE TABLE equipment (
eid smallint(6) NOT NULL AUTO_INCREMENT,
vid smallint(6) NOT NULL DEFAULT 1,
ename varchar(80) NOT NULL,
make varchar(40),
shortname varchar(20) DEFAULT NULL,
model varchar(40),
ecat tinyint(3) DEFAULT NULL,
serial varchar(30),
@@ -189,7 +192,8 @@ CREATE TABLE document (
title varchar(40) DEFAULT NULL,
pages smallint(6) unsigned NOT NULL DEFAULT 1,
remarks varchar(150) DEFAULT NULL,
PRIMARY KEY (docid)
PRIMARY KEY (docid),
UNIQUE INDEX ix_hash (hash)
) ENGINE=InnoDB;
CREATE TABLE docref (
@@ -207,8 +211,9 @@ CREATE TABLE docref (
CREATE TABLE company (
compid smallint(6) NOT NULL AUTO_INCREMENT,
compname varchar(40) NOT NULL,
compname varchar(60) NOT NULL,
comptype tinyint(3) NOT NULL DEFAULT 1,
shortname varchar(20) DEFAULT NULL,
street varchar(30),
zip varchar(10),
city varchar(30),
+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">
+79 -6
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
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;
+41 -35
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);
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 (
+81 -29
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
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', '100');
$line->addAttribute('x1', $x);
$line->addAttribute('y1', '0');
$line->addAttribute('x2', '100');
$line->addAttribute('y2', '350');
$line->addAttribute('x2', $x);
$line->addAttribute('y2', $shape['height']);
$line->addAttribute('style', 'stroke:#ff0000;stroke-width:1px');
}
// rectangle for storage
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->addAttribute('x', '10');
$rect->addAttribute('y', '80');
$rect->addAttribute('width', '40');
$rect->addAttribute('height', '60');
$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;
} */
}
// 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";
+50 -7
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 "<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 '</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

+56 -47
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,17 +268,33 @@ $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="mb-3">
<label for="y" class="form-label"><?=_('Position y')?></label>
<div class="col">
<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>
<div class="col">
<input type="number" class="form-control" id="z" name="z" value="<?=$storage->z ?>">
</div>
</div>
</div>
<div class="mb-3">
<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>
<textarea class="form-control" id="remarks" name="remarks" rows="3"><?=$storage->remarks ?></textarea>