More webgui development

This commit is contained in:
2024-04-30 19:38:28 +02:00
parent c3b5ef95a9
commit 0c09ce2916
21 changed files with 1056 additions and 155 deletions
+20 -4
View File
@@ -95,6 +95,7 @@ CREATE TABLE tag (
tagid smallint(6) NOT NULL AUTO_INCREMENT,
tagname varchar(20) NOT NULL,
color char(6) DEFAULT NULL,
description varchar(80) DEFAULT NULL,
PRIMARY KEY (tagid),
UNIQUE INDEX ix_tagname (tagname)
);
@@ -102,7 +103,7 @@ CREATE TABLE tag (
CREATE TABLE tagref (
tagid smallint(6) NOT NULL,
objid smallint(6) NOT NULL,
objtype enum('equip','inv','prov','doc') NOT NULL,
objtype enum('equip','inv','prov','doc', 'proj', 'task', 'maint') NOT NULL,
PRIMARY KEY (tagid, objid, objtype)
);
@@ -111,6 +112,7 @@ CREATE TABLE tagref (
CREATE TABLE box (
boxid smallint(6) NOT NULL AUTO_INCREMENT,
sid smallint(6) NOT NULL,
boxtype tinyint(3) DEFAULT NULL,
parent int(10) DEFAULT NULL,
label varchar(20) DEFAULT NULL,
color char(6) DEFAULT NULL,
@@ -141,7 +143,7 @@ CREATE TABLE equipment (
CREATE TABLE inventory (
invid int(10) NOT NULL AUTO_INCREMENT,
invname varchar(80) NOT NULL,
boxtype enum('storage','box') NOT NULL DEFAULT 'storage',
conttype enum('storage','box') NOT NULL DEFAULT 'storage',
sid smallint(6) NOT NULL DEFAULT 1,
boxid smallint(6) NOT NULL DEFAULT 1,
number smallint(6) UNSIGNED NOT NULL DEFAULT 1,
@@ -198,7 +200,7 @@ CREATE TABLE document (
CREATE TABLE docref (
drid int(10) NOT NULL AUTO_INCREMENT,
reftype enum('vessel', 'box', 'equipment', 'project', 'task', 'user') NOT NULL DEFAULT 'vessel',
reftype enum('vessel', 'box', 'equipment', 'project', 'task', 'user', 'company') NOT NULL DEFAULT 'vessel',
docid smallint(6) NOT NULL,
refid smallint(6) NOT NULL,
PRIMARY KEY (drid),
@@ -260,12 +262,26 @@ CREATE TABLE project (
CREATE TABLE task (
taskid int(10) NOT NULL AUTO_INCREMENT,
vid smallint(6) DEFAULT NULL,
projid smallint(6) DEFAULT NULL,
taskname varchar(60) NOT NULL,
taskstate enum('new','finished') NOT NULL DEFAULT 'new',
priority enum('high','medium','low') DEFAULT NULL,
taskstate enum('pending','waiting','deleted','completed') NOT NULL DEFAULT 'pending',
plandate date DEFAULT NULL,
duedate date DEFAULT NULL,
started datetime DEFAULT NULL,
finished datetime DEFAULT NULL,
PRIMARY KEY (taskid)
);
CREATE TABLE note (
noteid int(10) NOT NULL AUTO_INCREMENT,
notetype enum('task','maint') NOT NULL DEFAULT 'task',
refid smallint(6) NOT NULL,
annotation text NOT NULL,
PRIMARY KEY (noteid)
);
CREATE TABLE checklist (
clid smallint(6) NOT NULL AUTO_INCREMENT,
title varchar(30) NOT NULL,
+2 -1
View File
@@ -26,7 +26,8 @@ INSERT INTO dropdown (ddid, ddval, ddtext) VALUES
(0, 5, 'Proviantkategorien'),
(0, 6, 'Provianteinheiten'),
(0, 7, 'Sicherungstypen'),
(0, 8 , 'Einheiten');
(0, 8, 'Einheiten'),
(0, 9, 'Kistentypen');
INSERT INTO dropdown (ddid, ddval, ddtext, flags) VALUES
(2, 1, 'Lieferant', 'fixed'),
+15 -5
View File
@@ -20,6 +20,8 @@ foreach ($sth->fetchAll() as $row) {
$opt_storage[$row['sid']] = $row['sname'];
}
$opt_boxtype = db_get_options(9);
// ========== ACTIONS START ===================================================
switch ($submit = form_get_action()) {
@@ -42,6 +44,8 @@ switch ($submit = form_get_action()) {
case 'update':
$p[':boxid'] = $id;
$p[':boxtype'] = gpc_get_int($_POST, 'boxtype');
if ($p[':boxtype'] == -1) $p[':boxtype'] = NULL;
$p[':label'] = gpc_get_string($_POST, 'label');
$p[':content'] = gpc_get_string($_POST, 'content');
$p[':color'] = gpc_get_color($_POST, 'color');
@@ -67,7 +71,7 @@ if ($action == ACT_DEFAULT):
echo "<h1>$pagetitle</h1>\n";
$sql = "SELECT boxid, sid, label, color, content, weight, remarks "
$sql = "SELECT boxid, boxtype, sid, label, color, content, weight, remarks "
. "FROM box "
. "ORDER BY label";
$sth = $pdo->query($sql);
@@ -76,6 +80,7 @@ echo '<table class="table table-striped">', "\n";
echo "<thead>\n";
echo "<tr>";
echo "<th>" . _('Label') . "</th>";
echo "<th>" . _('Type') . "</th>";
echo "<th>" . _('Color') . "</th>";
echo "<th>" . _('Content') . "</th>";
echo '<th class="text-end">', _('Weight'), "</th>";
@@ -84,6 +89,7 @@ echo "</tr>\n";
foreach ($res as $row) {
echo "<tr>\n";
echo '<td>', $row['label'], "</td>\n";
echo '<td>', ($opt_boxtype[$row['boxtype']] ?? ''), "</td>\n";
echo '<td>', format_color(strtoupper($row['color'])), "</td>\n";
echo '<td>', $row['content'], "</td>\n";
echo '<td class="text-end">', format_float($row['weight'], 2), "</td>\n";
@@ -137,7 +143,7 @@ foreach ($opt_storage as $k => $v) {
elseif ($action == ACT_VIEW):
// ========== VARIANT: view single record =====================================
$sql = "SELECT label, content, color, weight, box.remarks, box.sid, sname "
$sql = "SELECT boxtype, label, content, color, weight, box.remarks, box.sid, sname "
. "FROM box LEFT JOIN storage USING (sid) "
. "WHERE boxid=?";
$sth = $pdo->prepare($sql);
@@ -147,7 +153,8 @@ $box = $sth->fetch(PDO::FETCH_OBJ);
echo '<h2>', $box->label, "</h2>\n";
echo '<table class="table">', "\n";
echo '<tr><th style="width:20%">', _('Content'),"</th><td>", $box->content, "</td></tr>\n";
echo '<tr><th style="width:20%">', _('Box type'),"</th><td>", ($opt_boxtype[$box->boxtype] ?? ''), "</td></tr>\n";
echo '<tr><th>', _('Content'),"</th><td>", $box->content, "</td></tr>\n";
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;
@@ -160,7 +167,7 @@ form_view_buttons($g_scriptname, $id);
// Inventory in box
// WIP
$sql = "SELECT invid, invname, weight FROM inventory WHERE boxtype='box' AND boxid=?";
$sql = "SELECT invid, invname, weight FROM inventory WHERE conttype='box' AND boxid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
$res = $sth->fetchAll();
@@ -194,13 +201,15 @@ if ($res) {
elseif ($action == ACT_EDIT):
// ========== VARIANT: edit single record =====================================
$sql = "SELECT label, content, color, weight, remarks "
$sql = "SELECT boxtype, label, content, color, weight, remarks "
. "FROM box "
. "WHERE boxid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
$box = $sth->fetch(PDO::FETCH_OBJ);
$opt_none = [ -1 => _('&horbar; none &horbar;')];
echo '<h2>', _('Edit Box'), "</h2>\n";
?>
<form method="post" action="<?=$g_scriptname?>">
@@ -209,6 +218,7 @@ echo '<h2>', _('Edit Box'), "</h2>\n";
<label for="label" class="form-label"><?=_('Label')?></label>
<input type="text" class="form-control" id="label" name="label" value="<?=$box->label ?>">
</div>
<?php form_create_select('boxtype', _('Box type'), $opt_none + $opt_boxtype, $box->boxtype); ?>
<div class="mb-3">
<label for="content" class="form-label"><?=_('Content')?></label>
<input type="text" class="form-control" id="content" name="content" value="<?=$box->content ?>">
+13 -1
View File
@@ -10,6 +10,19 @@ require 'globals.inc';
$pagetitle = _('Checklists');
$id = gpc_get_int($_REQUEST, 'id', 0);
$c = gpc_get_int($_REQUEST, 'c', -1);
function create_clitem_form($script, $clid, $formtype, $row=NULL) {
// formtype: insert or update
$update = ($formtype == 'update');
echo '<form method="post" action="', $script, '">';
echo '<input type="hidden" name="id" value="', $clid, '">';
if ($update) {
echo '<input type="hidden" name="v" value="', $row['checkid'], '">';
}
}
// ========== ACTIONS START ===================================================
@@ -24,7 +37,6 @@ switch ($submit = form_get_action()) {
case 'insert':
$p[':title'] = gpc_get_string($_POST, 'title');
$p[':clstate'] = gpc_get_string($_POST, 'clstate');
$id = db_exec_insert('checklist', $p);
$action = ACT_VIEW;
break;
+21
View File
@@ -245,6 +245,27 @@ if ($sth->rowCount() > 0) {
echo '<p>', _('Not referenced in any equipment'), "<p>\n";
}
// show referenced invoices
$sql = "SELECT docid, refid, filename, title "
. "FROM docref AS r JOIN document AS d USING (docid) "
. "WHERE reftype='company' AND refid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
if ($sth->rowCount() > 0) {
echo "<p>Invoices:</p>\n";
echo "<ul>\n";
foreach ($sth->fetchAll() as $row) {
echo "<li>";
echo '<a href="dl.php?id=', $row['docid'], '">', $row['filename'], "</a>\n";
echo ' ', $row['title'];
echo "</li>\n";
}
echo "</ul>\n";
} else {
echo '<p>', _('No invoices'), "<p>\n";
}
elseif ($action == ACT_EDIT):
// ========== VARIANT: edit single record =====================================
+32 -29
View File
@@ -18,70 +18,73 @@
*/
require 'globals.inc';
require 'lib/fileutils.inc';
$docid = gpc_get_int($_GET, 'id');
if (! isset($docid)) {
exit(1);
}
$page = gpc_get_int($_REQUEST, 'p', 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=?";
$sql = "SELECT doctype, docsize, mimetype, hash, extension, filename, pages FROM document WHERE docid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$docid]);
$row = $sth->fetch();
$dtmap = array(
'generic' => 'doc',
'manual' => 'man',
'invoice' => 'inv',
'picture' => 'pic',
'drawing' => 'drw');
$doc = $sth->fetch(PDO::FETCH_OBJ);
// 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)) {
// $file = sprintf("%s/%s-%s.%s", $g_doc_basepath, $g_doc_typemap[$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']);
$fnew = sprintf('%s/%s-%06d.%s', $g_doc_basepath, $g_doc_typemap[$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']);
}
} else { */
$file = sprintf('%s/%s-%06d.%s', $g_doc_basepath, $g_doc_typemap[$doc->doctype], $docid, $doc->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']);
if ($page < 1) {
$page = 1;
} elseif ($page > $doc->pages) {
$page = $doc->pages;
}
if ($doc->mimetype == 'application/pdf') {
// PDF creates PNG-thumbnails
$thumbname = sprintf('%s-%06d-%03d-%s.png', $g_doc_typemap[$doc->doctype], $docid, $page, $thumb);
$thumbpath = $g_doc_basepath . '/thumb/' . $thumbname;
if (!file_exists($thumbpath)) {
exec("/usr/bin/mutool draw -o {$thumbpath} -w {$size[$thumb]} $file $page", $output, $retval);
}
} else {
$thumbname = sprintf('%s-%06d-%03d-%s.%s', $g_doc_typemap[$doc->doctype], $docid, $page, $thumb, $doc->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') {
if ($doc->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') {
} elseif ($doc->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);
} elseif ($doc_>mimetype == 'image/xml+svg') {
// TODO anything here?
}
}
}
$file = $thumbpath;
@@ -89,14 +92,14 @@ if (isset($thumb)) {
$fsize = 0; // let's calc later
} else {
// normal
$filename = $row['filename'];
$fsize = $row['docsize'];
$filename = $doc->filename;
$fsize = $doc->docsize;
}
if (file_exists($file)) {
// send file to caller
header('Content-Description: File Transfer');
header('Content-Type: ' . $row['mimetype']);
header('Content-Type: ' . $doc->mimetype);
header('Content-Disposition: attachment; filename="' . $filename . '"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
+165 -27
View File
@@ -7,9 +7,12 @@
******************************************************************************/
require 'globals.inc';
require 'lib/fileutils.inc';
$pagetitle = _('Documents');
$id = gpc_get_int($_REQUEST, 'id', 0);
$page = gpc_get_int($_REQUEST, 'p', 1);
// ========== ACTIONS START ===================================================
@@ -38,7 +41,6 @@ switch ($submit = form_get_action()) {
$action = ACT_ADD;
break;
}
$mimetypes = ['image/png', 'image/jpeg', 'image/svg+xml', 'application/pdf'];
$nerr = 0;
$file_name = $_FILES['files']['name'];
$file_tmp = $_FILES['files']['tmp_name'];
@@ -46,7 +48,7 @@ switch ($submit = form_get_action()) {
$file_size = $_FILES['files']['size'];
$file_ext = strtolower(end(explode('.', $_FILES['files']['name'])));
$file_mimetype = mime_content_type($file_tmp);
if (!in_array($file_mimetype, $mimetypes)) {
if (!in_array($file_mimetype, $g_doc_mimetypes)) {
$g_error->Add(sprintf(_("Mimetype '%s' not allowed for upload."), $file_mimetype));
$action = ACT_ADD;
break;
@@ -68,6 +70,12 @@ switch ($submit = form_get_action()) {
$action = ACT_VIEW;
break;
}
if ($file_size > $g_doc_maxsize) {
$g_error->Add(sprintf(_('File to big: %s.%s'), $file_name, $file_type));
break;
}
switch ($file_mimetype) {
case 'application/pdf':
$p[':doctype'] = 'generic';
@@ -100,6 +108,7 @@ switch ($submit = form_get_action()) {
case 'update':
$p[':docid'] = $id;
$p[':doctype'] = gpc_get_string($_POST, 'doctype');
$p[':filename'] = gpc_get_string($_POST, 'filename');
$p[':title'] = gpc_get_string($_POST, 'title', 40);
$p['remarks'] = gpc_get_string($_POST, 'remarks', 150);
@@ -109,23 +118,53 @@ switch ($submit = form_get_action()) {
case 'delete':
// Security token needed!
if (gpc_get_string($_POST, 'token', 16) != $_SESSION['token']) {
/*if (gpc_get_string($_POST, 'token', 16) != $_SESSION['token']) {
$g_error->Add(_('Delete prohibited, invalid security token!'));
$action = ACT_VIEW;
break;
}
$action = ACT_DEFAULT;
unset($_SESSION['token']);
*/
$sql = "SELECT doctype, extension FROM document WHERE docid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
$doc = $sth->fetch(PDO::FETCH_OBJ);
// clean thumbs
$thumbdir = $g_doc_basepath . '/thumbs/';
$pattern = sprintf('%s-%06d*', $g_doc_typemap[$doctype], $docid);
foreach (glob($thumbdir . $pattern) as $f) {
// unlink($f);
$g_success->Add($f);
}
// remove document
$g_success->Add(_('Deleted document %s'), $docfilename);
// sprintf('%s/%s-%06d.%s', $g_doc_basepath, $dtmap[$row['doctype']], $docid, $row['extension']);
/*
$sth = $pdo->prepare("DELETE FROM document WHERE docid=?");
try {
$sth->execute([$id]);
} catch (PDOexception $e) {
$g_error->Add(sprintf(_('SQL-Error: %s', $e->getMessage())));
}*/
//$action = ACT_DEFAULT;
$action = ACT_DELETE;
break;
case 'addref':
$eid = gpc_get_int($_POST, 'eid');
$opt_reftype = db_load_enum('docref', 'reftype');
$refid = gpc_get_int($_POST, 'refid');
$reftype = gpc_get_enum($_POST, 'reftype', $opt_reftype, 'equipment');
$sql = "INSERT INTO docref "
. " (docid, refid, reftype) "
. "VALUES "
. " (:docid, :refid, 'equipment')";
. " (:docid, :refid, :reftype)";
$sth = $pdo->prepare($sql);
$sth->bindValue(':docid', $id, PDO::PARAM_INT);
$sth->bindValue(':refid', $eid, PDO::PARAM_INT);
$sth->bindValue(':refid', $refid, PDO::PARAM_INT);
$sth->bindValue(':reftype', $reftype, PDO::PARAM_STR);
$sth->execute();
$action = ACT_VIEW;
break;
@@ -300,13 +339,14 @@ elseif ($action == ACT_VIEW):
/* mutool: preview of page thumbs */
$sql = "SELECT docid, doctype, mimetype, filename, extension, hash,"
. " docsize, doctime, title, remarks "
. " docsize, doctime, title, pages, remarks "
. "FROM document "
. "WHERE docid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
$document = $sth->fetch(PDO::FETCH_OBJ);
echo '<h2>', _('View Document'), "</h2>\n";
echo '<div class="row">', "\n";
@@ -314,25 +354,32 @@ 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') {
$techname = 'pic-' . $document->hash . '.' . $document->extension;
$techname = sprintf('pic-%06d.%s', $document->docid, $document->extension);
echo '<tr><th scope="row">', _('Preview'), '</th><td>';
// echo '<a href="doc/', $techname, '" target="_blank"><img width="', $g_thumb_size, '" src="doc/', $techname, '" alt="', $document->title, '"></a>';
echo '<a href="dl.php?id=', $document->docid, '" target="_blank">';
echo '<img width="', $g_thumb_size, '" src="dl.php?id=', $document->docid, '" alt="', $document->title, '">';
echo '</a>';
echo "</td></tr>\n";
} elseif (($document->doctype == 'drawing')) {
$techname = sprintf('drw-%06d.%s', $document->docid, $document->extension);
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')) {
} elseif (in_array($document->doctype, ['generic', 'manual', 'invoice'])) {
$techname = sprintf('doc-%06d.%s', $document->docid, $document->extension);
if ($document->mimetype == 'application/pdf') {
// TODO show preview of previewpage, create thumbnail if needed
$pages = pdf_get_pagecount("$g_doc_basepath/$techname");
// read page count from pdf file:
// $pdfpages = pdf_get_pagecount("$g_doc_basepath/$techname");
echo '<tr><th scope="row">', _('PDF'), '</th><td>';
// Download link
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 '<a href="dl.php?id=', $document->docid, '">', $document->title ?? _('Download'), '</a> (', sprintf(_('%d Pages'), $document->pages), ')';
echo "</td></tr>\n";
}
}
if ($document->docsize == 0) {
// update get current size in db
$document->docsize = file_fix_filesize($document->docid, "$g_doc_basepath/$techname");
}
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>", format_filesize($document->docsize), "</td></tr>\n";
@@ -341,10 +388,15 @@ echo '<tr><th scope="row">', _('Title'),"</th><td>", $document->title, "</td></t
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
echo "</div>\n", '<div class="col text-center">', "\n"; // column break
if ($document->mimetype == 'application/pdf') {
echo '<img src="dl.php?id=', $document->docid,'&t=l" alt="PDF-Preview">', "\n";
echo '<img src="dl.php?id=', $document->docid, '&p=', $page, '&t=l" alt="PDF-Preview">', "\n";
if ($document->pages > 1) {
$pagination = get_pagination($g_scriptname, 'f=view&id='.$id, $page, $document->pages, true);
echo $pagination;
// $pagination;
}
}
echo "</div>\n</div>\n"; // end of columns
@@ -353,11 +405,32 @@ form_view_buttons($g_scriptname, $id);
echo '<h3>', _('Document references'), "</h3>\n";
$sql = "SELECT drid, reftype, ename AS name, eid "
$references = array();
// Equipment
$eids = array();
$sql = "SELECT drid, reftype, refid, ename AS target "
. "FROM docref INNER JOIN equipment ON (docref.reftype='equipment' AND docref.refid=equipment.eid) "
. "WHERE docid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
foreach ($sth->fetchAll() as $row) {
$references[] = $row;
$eids[] = $row['refid'];
}
// Companies
$compids = array();
$sql = "SELECT drid, reftype, refid, compname AS target "
. "FROM docref INNER JOIN company ON (docref.reftype='company' AND docref.refid=company.compid) "
. "WHERE docid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
foreach ($sth->fetchAll() as $row) {
$references[] = $row;
$compids[] = $row['refid'];
}
echo '<table class="table table-sm">', "\n";
echo "<thead>\n";
echo "<tr>";
@@ -366,20 +439,25 @@ echo "<th>" . _('Used by') . "</th>";
echo "<td></td>";
echo "</tr>\n";
echo "</thead>\n";
$eids = array();
foreach ($sth->fetchAll() as $row) {
$eids[] = $row['eid'];
foreach ($references as $ref) {
echo "<tr>";
echo "<td>", $row['reftype'], "</td>";
echo "<td>", $row['name'], "</td>";
echo "<td>", $ref['reftype'], "</td>";
echo "<td>", $ref['target'], "</td>";
echo "<td>";
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>';
if ($ref['reftype'] == 'equipment') {
echo '<a title="', _('View'), '" href="equipment.php?f=view&id=', $ref['refid'],'"><i class="bi-eye"></i></a>';
} elseif ($ref['reftype'] == 'company') {
echo '<a title="', _('View'), '" href="company.php?f=view&id=', $ref['refid'],'"><i class="bi-eye"></i></a>';
}
echo '<a title="', _('Remove reference'), '" href="', $g_scriptname, '?f=delref&id=', $id, '&drid=', $ref['drid'], '"><i class="bi-trash"></i></a>';
echo "</td>";
echo "</tr>\n";
}
echo "</table>\n";
// New references
echo '<h4>', _('Add new reference'), "</h4>\n";
// Equipment options
// Do not include equipment that has already been referenced in the list!
$opt_equipment = array();
@@ -394,14 +472,43 @@ foreach ($sth->fetchAll() as $row) {
?>
<form method="post" action="<?=$g_scriptname?>">
<input type="hidden" name="id" value="<?=$id?>">
<select name="eid">
<input type="hidden" name="reftype" value="equipment">
<label for="eid"><?=_('Equipment')?></label>
<select name="refid" id="eid">
<?php
foreach ($opt_equipment as $k => $v) {
echo '<option value="', $k, '">', $v, "</option>\n";
}
?>
</select>
<button class="btn btn-secondary" name="submit[addref]">Referenzieren</button>
<button class="btn btn-sm btn-secondary" name="submit[addref]">Referenzieren</button>
</form>
<?php
$opt_company = array();
$sql = "SELECT compid, compname FROM company ORDER BY compname";
$sth = $pdo->prepare($sql);
$sth->execute();
foreach ($sth->fetchAll() as $row) {
if (!in_array($row['eid'], $compids)) {
$opt_company[$row['compid']] = $row['compname'];
}
}
?>
<form method="post" action="<?=$g_scriptname?>">
<input type="hidden" name="id" value="<?=$id?>">
<input type="hidden" name="reftype" value="company">
<label for="compid"><?=_('Company')?></label>
<select name="refid" id="compid">
<?php
foreach ($opt_company as $k => $v) {
echo '<option value="', $k, '">', $v, "</option>\n";
}
?>
</select>
<button class="btn btn-sm btn-secondary" name="submit[addref]">Referenzieren</button>
</form>
<?php
@@ -411,7 +518,7 @@ elseif ($action == ACT_EDIT):
echo '<h2>', _('Edit Document'), "</h2>\n";
$sql = "SELECT docid, doctype, filename, extension, hash, title, remarks "
$sql = "SELECT docid, doctype, mimetype, filename, extension, hash, title, remarks "
. "FROM document "
. "WHERE docid=?";
$sth = $pdo->prepare($sql);
@@ -433,6 +540,20 @@ if ($document->doctype == 'picture') {
<label for="title" class="form-label"><?=_('Title')?></label>
<input type="text" class="form-control" id="title" name="title" value="<?=$document->title ?>">
</div>
<?php
if ($document->mimetype == 'application/pdf') {
echo '<div class="mb-3">', "\n";
$opt_doctype = array(
'generic' => _('Generic'),
'manual' => _('Manual'),
'invoice' => _('Invoice')
) ;
form_create_select('doctype', _('Document type'), $opt_doctype, $document->doctype);
echo "</div>";
} else {
echo '<input type="hidden" name="doctype" value="', $document->doctype, '">', "\n";
}
?>
<div class="mb-3">
<label for="remarks" class="form-label"><?=_('Remarks')?></label>
<textarea class="form-control" id="remarks" name="remarks" rows="3"><?=$document->remarks ?></textarea>
@@ -445,7 +566,24 @@ if ($document->doctype == 'picture') {
elseif ($action == ACT_DELETE):
// ========== VARIANT: delete record ==========================================
$sql = "SELECT docid, doctype, mimetype, filename, extension, title "
. "FROM document "
. "WHERE docid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
$document = $sth->fetch(PDO::FETCH_OBJ);
echo '<h2>', _('Delete Document'), "</h2>\n";
echo '<p>', sprintf(_('Record no. %d'), $id), "</p>\n";
echo '<p>Dokument: ', $document->filename, "</p>";
echo '<p>Title: ', $document->title, "</p>";
echo '<p>', _('Deleting a document item is final. There is no way back. Only delete if you are absolute sure.'), "</p>\n";
$_SESSION['token'] = bin2hex(random_bytes(8));
form_delete_buttons($g_scriptname, $id, $_SESSION['token']);
else:
// ========== ERROR UNKNOWN VARIANT ===========================================
+35 -10
View File
@@ -14,6 +14,7 @@ $id = gpc_get_int($_REQUEST, 'id', 0);
$opt_supplier = db_get_opt_supp(array(-1 => _('--- unknown ---')));
$opt_manufacturer = db_get_opt_manuf(array(-1 => _('--- unknown ---')));
$opt_ecat = db_get_options(4); // Equipment categories
$opt_unit = db_get_options(8);
// ========== ACTIONS START ===================================================
@@ -102,7 +103,6 @@ switch ($submit = form_get_action()) {
break;
}
$extensions = ['jpg', 'png'];
$mimetypes = ['image/png', 'image/jpeg', 'image/svg+xml', 'application/pdf'];
$all_files = count($_FILES ["files"]["tmp_name"]);
$nerr = 0;
for ($i = 0; $i < $all_files; $i++) {
@@ -113,7 +113,7 @@ switch ($submit = form_get_action()) {
$file_ext = strtolower(end(explode('.', $_FILES['files']['name'][$i])));
// $file = $g_doc_basepath . '/' . $file_name;
$file_mimetype = mime_content_type($file_tmp);
if (!in_array($file_mimetype, $mimetypes)) {
if (!in_array($file_mimetype, $g_doc_mimetypes)) {
$g_error->Add(sprintf(_("Mimetype '%s' not allowed for upload."), $file_mimetype));
$nerr += 1;
}
@@ -121,7 +121,7 @@ switch ($submit = form_get_action()) {
$g_error->Add(_('Filetype not allowed for upload:') . ' ' . $file_type);
$nerr += 1;
}
if ($file_size > 2097152) {
if ($file_size > $g_doc_maxsize) {
$g_error->Add(sprintf(_('File to big: %s.%s'), $file_name, $file_type));
$nerr += 1;
}
@@ -249,7 +249,7 @@ $opt_special = array(
<div id="filter" class="card">
<div class="card-header">Filter</div>
<div class="card-body">
<label for="flt_category">Category</label>
<label for="flt_category"><?=_('Category')?></label>
<select id="flt_category" name="flt_category">
<?php
foreach ($opt_special + $opt_ecat as $k => $v) {
@@ -261,7 +261,7 @@ foreach ($opt_special + $opt_ecat as $k => $v) {
}
?>
</select>
<label for="flt_manuf">Manufacturer</label>
<label for="flt_manuf"><?=_('Manufacturer')?></label>
<select id="flt_manuf" name="flt_manuf">
<?php
foreach ($opt_special + $opt_manufacturer as $k => $v) {
@@ -273,7 +273,7 @@ foreach ($opt_special + $opt_manufacturer as $k => $v) {
}
?>
</select>
<label for="flt_supp">Supplier</label>
<label for="flt_supp"><?=_('Supplier')?></label>
<select id="flt_supp" name="flt_supp">
<?php
foreach ($opt_special + $opt_supplier as $k => $v) {
@@ -285,7 +285,7 @@ foreach ($opt_special + $opt_supplier as $k => $v) {
}
?>
</select>
<label for="flt_txt">Text</label>
<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>
@@ -294,7 +294,7 @@ foreach ($opt_special + $opt_supplier as $k => $v) {
<?php
// Pagination on top
$pagination = get_pagination($g_scriptname, $page, $lastpage);
$pagination = get_pagination($g_scriptname, '', $page, $lastpage);
echo $pagination;
// Data
@@ -442,9 +442,7 @@ 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=?";
@@ -461,6 +459,33 @@ if ($sth->rowCount() > 0) {
} else {
echo '<p>', _('No maintenance records found.'), "<p>\n";
}
echo '<div class="container-fluid px-0 my-3">', "\n";
echo '<a href="maintenance.php?f=add&id=', $id, '" class="btn btn-primary" role="button">';
echo _('Add maintenance'), "</a>\n";
echo "</div>\n";
// Measurement records
echo '<h3>', _('Measurements'), "</h3>";
$sql = "SELECT mid, mname, nval, val1, val2, val3, unit, accuracy FROM measurement WHERE eid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
if ($sth->rowCount() > 0) {
echo "<ul>\n";
foreach ($sth->fetchAll() as $row) {
echo "<li>", $row['mname'], ': ';
echo format_measurement($row['nval'], $opt_unit[$row['unit']], $row['val1'], $row['val2'], $row['val3']);
echo ' <a title="', _('View'), '" href="measurement.php?f=view&id=', $row['mid'], '"><i class="bi-eye"></i></a>';
echo "</li>\n";
}
echo "</ul>\n";
} else {
echo '<p>', _('No measurement records found.'), "<p>\n";
}
echo '<div class="container-fluid px-0 my-3">', "\n";
echo '<a href="measurement.php?f=add&id=', $id, '" class="btn btn-primary" role="button">';
echo _('Add measurement'), "</a>\n";
echo "</div>\n";
elseif ($action == ACT_EDIT):
// ========== VARIANT: edit single record =====================================
+1
View File
@@ -3,5 +3,6 @@
</footer>
</div><?php /* Main container */?>
</body>
</html>
+71 -17
View File
@@ -63,8 +63,11 @@ if ($g_scriptname != 'login.php') {
$_SESSION['prelogin'] = $_SERVER['REQUEST_URI'];
header_location('login.php');
}
$g_referrer = $_SESSION['coming_from'];
$_SESSION['coming_from'] = $g_scriptname;
}
// database
$pdo = new PDO("mysql:host=$g_db_host;dbname=$g_db_schema;charset=utf8mb4", $g_db_username, $g_db_password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
@@ -81,6 +84,9 @@ if ($g_scriptname != 'login.php') {
$action = NULL;
$valid = FALSE;
// document storage
$g_doc_mimetypes = ['image/png', 'image/jpeg', 'image/svg+xml', 'application/pdf'];
// Initialize message system
$g_message = new Message;
$g_success = new MessageSuccess;
@@ -353,9 +359,12 @@ function get_enum($enum) {
'fixed' => _('Fixed'),
'generic' => _('Generic'),
'good' => _('Good'),
'high' => _('High'),
'invoice' => _('Invoice'),
'locked' => _('Locked'),
'low' => _('Low'),
'manual' => _('Manual'),
'mediim' => _('Medium'),
'mono' => _('Monohull'),
'new' => _('New'),
'normal' => _('Normal'),
@@ -642,13 +651,13 @@ function form_add_button($script, $id=NULL, $idname='id') {
echo "</div>\n";
}
function form_view_buttons($script, $id) {
function form_view_buttons($script, $id, $backlink=NULL) {
echo '<div class="container-fluid px-0 my-3">', "\n";
echo '<a href="', $script, '?f=edit&id=', $id, '" class="btn btn-primary" role="button">', _('Edit'), "</a>\n";
echo '&nbsp;';
echo '<a href="', $script, '?f=del&id=', $id, '" class="btn btn-secondary" role="button">', _('Delete'), "</a>\n";
echo '&nbsp;';
echo '<a href="', $script, '" class="btn btn-secondary">', _('Back'), "</a>\n";
echo '<a href="', $backlink ?? $script, '" class="btn btn-secondary">', _('Back'), "</a>\n";
echo "</div>\n";
}
@@ -673,8 +682,23 @@ function form_delete_buttons($script, $id, $token) {
echo '<input type="hidden" name="token" value="', $token, '">', "\n";
echo '<button type="submit" name="submit[delete]" class="btn btn-primary">', _('Delete'), "</button>\n";
echo '<a href="', $script, '?f=view&id=', $id, '" class="btn btn-secondary">', _('Back'), "</a>\n";
echo "</div>\n";
echo "</form>\n";
echo "</div>\n";
}
function form_tag_assignment($script, $id) {
echo '<tr>';
echo '<th>', _('Tags'), "</th>\n";
echo "</tr>\n<tr>";
echo '<th>', _('Tag assignment'), "</th>\n";
echo '<td><form method="post" action="', $script, '">', "\n";
echo '<div class="form-floating">';
echo '<input type="hidden" name="id" value="', $id .'">', "\n";
echo '<label>', _('(Separate by comma)'), '</label>', "\n";
echo '<input type="text" maxlength="80" class="form-control" name="tagstring">', "\n";
echo '<input type="submit">', "\n";
echo "</div></form></td></td>\n";
echo "</tr>";
}
// ========== COMMON FUNCTIONS ================================================
@@ -795,6 +819,16 @@ function gpc_get_color(&$GPC, $varname, $default = NULL) {
return strtoupper($color);
}
function gpc_get_enum(&$GPC, $varname, $values, $default = NULL) {
if (!isset($GPC[$varname]) or (strlen(trim($GPC[$varname])) == 0)) {
return $default;
}
if (! in_array($GPC[$varname], $values)) {
return $default;
}
return $GPC[$varname];
}
function format_float($val, $decimals = 2, $suffix = '') {
global $g_lconv;
if (!isset($val) || $val == '') {
@@ -860,45 +894,65 @@ function format_filesize($size, $format=2) {
return $size_string;
}
function get_pagination($script, $page, $lastpage) {
function format_measurement($n, $unit, $v1, $v2, $v3) {
$m = '';
switch ($n) {
case 1:
$m = "$v1&thinsp;$unit";
break;
case 2:
$m = "$v1&times;$v2&thinsp;$unit";
break;
case 3:
$m = "$v1&times;$v2&times;$v3&thinsp;$unit";
break;
}
return $m;
}
function get_pagination($script, $param, $page, $lastpage, $small=false) {
// no direct output, returns string for multiple output
if ($lastpage < 2) {
return '';
}
$psep = empty($param) ? '?' : "?$param&";
$out = '<nav class="my-3">' . "\n";
$out .= '<ul class="pagination justify-content-center">' . "\n";
$out .= '<ul class="pagination ' . ($small ? 'pagination-sm ' : '') . '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";
$out .= '<li class="page-item"><a class="page-link" href="'. $script. $psep. 'p=1">First</a></li>'. "\n";
$out .= '<li class="page-item"><a class="page-link" href="'. $script. $psep. '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";
}
if ($lastpage < 10) {
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";
$out .= '" href="'. $script. $psep. 'p='. $n. '">'. $n. '</a></li>'. "\n";
}
} else {
// start working with ... dots
}
if ($page < $lastpage) {
// go to last page or next page
$out .= '<li class="page-item"><a class="page-link" href="'. $script. $psep. 'p='. ($page + 1). '">Next</a></li>'. "\n";
$out .= '<li class="page-item"><a class="page-link" href="'. $script. $psep. '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";
}
// idea: small entry to input page number
$out .= "</ul>\n</nav>\n";
+4 -5
View File
@@ -28,8 +28,8 @@ switch ($submit = form_get_action()) {
} catch (PDOException $e) {
$g_error->Add('SQL-Error: '. $e->getMessage());
}
$g_message->Add(sprintf(_('Selected vessel %d'), $vid));
$user->load_vessel();
$g_message->Add(sprintf(_('Selected vessel %d: %s'), $vid, $user->vessel));
break;
case 'insert':
@@ -310,19 +310,17 @@ echo '<tr><td>', _('Count'), '</td><td>', $sth->fetchColumn(), "</td></tr>\n";
// Inventory
// All items from vessel storage and all items from boxes in vessel storage
$sql = "SELECT SUM(n) FROM ("
. "SELECT COUNT(*) AS n FROM inventory JOIN storage USING (sid) WHERE boxtype='storage' AND vid=:vid "
. "SELECT COUNT(*) AS n FROM inventory JOIN storage USING (sid) WHERE conttype='storage' AND vid=:vid "
. "UNION "
. "SELECT COUNT(*) AS n FROM inventory JOIN box USING (boxid) JOIN storage ON (box.sid=storage.sid) WHERE boxtype='box' AND vid=:vid"
. "SELECT COUNT(*) AS n FROM inventory JOIN box USING (boxid) JOIN storage ON (box.sid=storage.sid) WHERE conttype='box' AND vid=:vid"
. ") AS x";
$sth = $pdo->prepare($sql);
$sth->bindValue(':vid', $user->vid, PDO::PARAM_INT);
$sth->execute();
// Tasks
echo '<tr><td colspan="2">', _('Inventory') , "</td>";
echo '<tr><td>', _('Count'), '</td><td>', $sth->fetchColumn(), "</td></tr>\n";
echo "</table>\n";
?>
@@ -344,6 +342,7 @@ echo "</table>\n";
<hr>
<h5 class="card-title"><?=_('Additional modules')?></h5>
<ul class="list-group list-group-flush">
<li class="list-group-item"><a href="task.php"><?=_('Tasks')?></a></li>
<li class="list-group-item"><a href="measurement.php"><?=_('Measurements')?></a></li>
<li class="list-group-item"><a href="checklist.php"><?=_('Checklists')?></a></li>
<li class="list-group-item"><a href="search.php"><?=_('Search')?></a></li>
+19 -14
View File
@@ -39,7 +39,7 @@ switch ($submit = form_get_action()) {
case 'insert':
$p[':invname'] = gpc_get_string($_POST, 'invname');
$p[':number'] = gpc_get_int($_POST, 'number');
$p[':boxtype'] = gpc_get_string($_POST, 'boxtype');
$p[':conttype'] = gpc_get_string($_POST, 'conttype');
$p[':sid'] = gpc_get_int($_POST, 'sid');
$p[':boxid'] = gpc_get_int($_POST, 'boxid');
$p[':invcond'] = 'good';
@@ -51,7 +51,7 @@ switch ($submit = form_get_action()) {
$p[':invid'] = $id;
$p[':invname'] = gpc_get_string($_POST, 'invname');
$p[':number'] = gpc_get_int($_POST, 'number');
$p[':boxtype'] = gpc_get_string($_POST, 'boxtype');
$p[':conttype'] = gpc_get_string($_POST, 'conttype');
$p[':sid'] = gpc_get_int($_POST, 'sid');
$p[':boxid'] = gpc_get_int($_POST, 'boxid');
$p[':weight'] = min(gpc_get_float($_POST, 'weight'), 999.99); // limit max value
@@ -121,10 +121,10 @@ $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)";
. "FROM inventory AS i JOIN storage AS s ON (i.conttype='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) "
. "FROM inventory AS i JOIN box AS b ON (i.conttype='box' AND i.boxid=b.boxid) "
. " JOIN storage AS s ON (b.sid=s.sid) ";
$sql .= ' WHERE ' . $where;
$sql .= $order;
@@ -193,6 +193,7 @@ echo "<th>", _('Name'), "</th>\n";
echo "<th>", _('Container'), "</th>\n";
echo "<th>", _('Number'), "</th>\n";
echo "<th>", _('Condition'), "</th>\n";
echo "<th>", _('Tags'), "</th>\n";
echo "<td></td>\n";
echo "</tr>\n";
echo "</thead>\n";
@@ -202,6 +203,7 @@ foreach ($res as $row) {
echo "<td>", $row['container'], "</td>\n";
echo "<td>", $row['number'], "</td>\n";
echo "<td>", ($opt_invcond[$row['invcond']] ?? ''), "</td>\n";
echo "<td>", _('No tags assigned'), "</td>\n";
form_action_buttons($g_scriptname, $row['invid']);
echo "</tr>\n";
}
@@ -228,8 +230,8 @@ echo '<h2>', _('Add Inventory'), "</h2>\n";
<input type="number" class="form-control" id="number" name="number" value="1">
</div>
<div class="mb-3">
<label for="boxtype" class="form-label"><?=_('Boxtype')?></label>
<select class="form-select" name="boxtype" id="boxtype">
<label for="conttype" class="form-label"><?=_('Container type')?></label>
<select class="form-select" name="conttype" id="conttype">
<option value="box"><?=_('Box')?></option>
<option value="storage"><?=_('Storage')?></option>
</select>
@@ -248,16 +250,16 @@ form_create_select('boxid', _('Box'), $opt_box);
elseif ($action == ACT_VIEW):
// ========== VARIANT: view single record =====================================
$sql = "SELECT invname, boxtype, sid, boxid, number, weight, price, purchdate,"
. " invcond,remarks "
$sql = "SELECT invname, conttype, sid, boxid, number, weight, price, purchdate,"
. " invcond, remarks "
. "FROM inventory "
. "WHERE invid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
$inventory = $sth->fetch(PDO::FETCH_OBJ);
// boxtype can be storage or box
switch ($inventory->boxtype) {
// container type can be storage or box
switch ($inventory->conttype) {
case 'storage':
$sql = "SELECT sname, vid FROM storage WHERE sid=?";
$sth = $pdo->prepare($sql);
@@ -286,7 +288,7 @@ switch ($inventory->boxtype) {
echo '<h2>', $inventory->invname, "</h2>\n";
echo '<table class="table">', "\n";
echo '<tr><th style="width:20%">', _('Box type'),"</th><td>", $inventory->boxtype, "</td></tr>\n";
echo '<tr><th style="width:20%">', _('Box type'),"</th><td>", $inventory->conttype, "</td></tr>\n";
// Container with link
echo "<tr><th>", _('Container'),"</th><td>", sprintf(_('%s in %s'), $box['label'], $storagename);
@@ -299,6 +301,9 @@ echo "<tr><th>", _('Price'), "</th><td>", format_currency($inventory->price), "<
echo "<tr><th>", _('Purchase date'), "</th><td>", $inventory->purchdate, "</td></tr>\n";
echo "<tr><th>", _('Condition'), "</th><td>", $inventory->invcond, "</td></tr>\n";
echo "<tr><th>", _('Remarks'), "</th><td>", $inventory->remarks, "</td></tr>\n";
form_tag_assignment($g_scriptname, $id);
echo "</table>\n";
form_view_buttons($g_scriptname, $id);
@@ -306,7 +311,7 @@ form_view_buttons($g_scriptname, $id);
elseif ($action == ACT_EDIT):
// ========== VARIANT: edit single record =====================================
$sql = "SELECT invname, boxtype, sid, boxid, number, weight, price, purchdate, "
$sql = "SELECT invname, conttype, sid, boxid, number, weight, price, purchdate, "
. " invcond, remarks "
. "FROM inventory "
. "WHERE invid=?";
@@ -331,8 +336,8 @@ $inventory = $sth->fetch(PDO::FETCH_OBJ);
<input type="text" class="form-control" id="weight" name="weight" value="<?=format_float($inventory->weight); ?>">
</div>
<div class="mb-3">
<label for="boxtype" class="form-label"><?=_('Boxtype')?></label>
<select class="form-select" name="boxtype" id="boxtype">
<label for="conttype" class="form-label"><?=_('Container type')?></label>
<select class="form-select" name="conttype" id="conttype">
<option value="box"><?=_('Box')?></option>
<option value="storage"><?=_('Storage')?></option>
</select>
+25
View File
@@ -0,0 +1,25 @@
<?php
/******************************************************************************
* YMS - Yacht Management Software
* Copyright (C) 2024 Thomas Hooge
*
* SPDX-License-Identifier: WTFPL
******************************************************************************
*/
// ========== FILE FUNCTIONS ==================================================
function file_fix_filesize($docid, $filepath) {
// set filesize in database to current size in filesystem
global $pdo;
$newsize = filesize($filepath);
$sth = $pdo->prepare("UPDATE document SET docsize=? WHERE docid=?");
$sth->execute([$docid, $newsize]);
return $newsize;
}
function file_get_docname($docid, $doctype, $extension) {
global $g_doc_typemap;
return sprintf('%s-%06d.%s', $g_doc_typemap[$doctype], $docid, $extension);
}
+38 -3
View File
@@ -153,10 +153,14 @@ echo '<h2>', _('Add Maintenance'), "</h2>\n";
?>
<div class="mb-3">
<label for="eid" class="form-label"><?=_('Equipment')?></label>
<select name="eid" id="eid" class="form-control">
<select name="eid" id="eid" class="form-select">
<?php
foreach ($opt_equipment as $k => $v) {
echo '<option value="', $k, '">', $v, "</option>\n";
echo '<option value="', $k, '"';
if ($k == $id) {
echo ' selected';
}
echo '>', $v, "</option>\n";
}
?>
</select>
@@ -165,6 +169,7 @@ foreach ($opt_equipment as $k => $v) {
<a href="<?=$g_scriptname?>" class="btn btn-secondary"><?=_('Back')?></a>
</div>
<?php
elseif ($action == ACT_VIEW):
// ========== VARIANT: view single record =====================================
@@ -196,7 +201,12 @@ echo '<div class="col">';
echo '<table class="table">', "\n";
echo '<tr><th>', _('Activities'),"</th><td>", $maint->activities, "</td></tr>\n";
echo '<tr><th>', _('Equipment'),"</th><td>", $maint->ename, "</td></tr>\n";
echo '<tr><th>', _('Equipment'),"</th><td>", $maint->ename;
if (isset($maint->eid)) {
// Link to equipment
echo ' <a href="equipment.php?f=view&id=', $maint->eid, '"><i class="bi-eye"></i></a>';
}
echo "</td></tr>\n";
echo '<tr><th>', _('Remarks'),"</th><td>", $maint->remarks, "</td></tr>\n";
echo "</table>\n";
@@ -221,6 +231,31 @@ echo '</div>'; // container
form_view_buttons($g_scriptname, $id);
echo '<h3>', _('Annotations'), "</h3>\n";
$sql = "SELECT noteid, annotation "
. "FROM note "
. "WHERE notetype='maint' AND refid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
if ($sth->rowCount() > 0) {
$n = 0;
foreach ($sth->fetchAll() as $row) {
$n += 1;
echo "<p>($n) {$row['annotation']}";
echo ' <a title="', _('Edit'), '" href="note.php?f=edit&id=', $row['noteid'], '"><i class="bi-pencil"></i></a>';
echo "</p>\n";
}
} else {
echo '<p>', _('No annotations for this maintenance'), "</p>\n";
}
echo '<div class="container-fluid px-0 my-3">', "\n";
echo '<a href="note.php?f=add&t=maint&id=', $id, '" class="btn btn-primary" role="button">';
echo _('Add note'), "</a>\n";
echo "</div>\n";
elseif ($action == ACT_EDIT):
// ========== VARIANT: edit single record =====================================
+3 -2
View File
@@ -17,7 +17,7 @@ require 'header.php';
<p>Es können mehrere Yachten mit dem Programm verwaltet werden.
Die Umschaltung erfolgt über eine Auswahlliste auf der Übersichtsseite.</p>
<p>Die Yachtdaten können nur mit de Berechtigungsebene <em>captain</em>
<p>Die Yachtdaten können nur mit der Berechtigungsebene <em>captain</em>
verändert werden.</p>
<p>Es kann eine Aufsicht für die betreffende Yacht eingerichtet werden.
@@ -77,6 +77,7 @@ z.B. <em>neu</em>, <em>laufend</em> oder <em>erledigt</em>.</p>
beispielsweise Hersteller, Lieferanten, Werften oder Dienstleister.</p>
<p>Hersteller und Lieferanten sind immer vorhanden, sie werden als
Auswahl an anderen Stellen im Programm benötigt.</p>
<p>Rechnungen können Firmen zugeordnet werden.</p>
<h3>Dokumente</h3>
<p>Ein Dokument kann mehrfach zugeordnet werden. Z.B. einem
@@ -85,7 +86,7 @@ Ausrüstungsgegenstand und gleichzeitig einem Projekt oder einer Aufgabe.</p>
<ul>
<li>Fotos bzw. Bilder als png- oder jpg-Dateien</li>
<li>Zeichnungen als svg-Dateien</li>
<li>Dokumente als pdf-Dateien</li>
<li>Dokumente als pdf-Dateien, genauere Kennzeichnung als Rechnung oder Handbuch ist möglich.</li>
</ul>
<h3>Checklisten</h3>
+28 -1
View File
@@ -124,6 +124,9 @@ require 'header.php';
if ($action == ACT_DEFAULT):
// ========== VARIANT: default behavior =======================================
// load filter from db
$flt = db_get_filter($user->id, 207);
function format_vals($n, $v1, $v2, $v3) {
if ($n == 1) {
return $v1;
@@ -225,7 +228,7 @@ form_create_select('nval', _('Dimensions'), $opt_dimensions);
<?php
form_create_select('unit', _('Unit'), $opt_unit);
form_create_select('accuracy', _('Accuracy'), $opt_accuracy);
form_create_select('eid', _('Equipment'), $opt_equipment);
form_create_select('eid', _('Equipment'), $opt_equipment, $id);
?>
<div class="container-fluid px-0 my-3">
<button type="submit" name="submit[insert]" class="btn btn-primary"><?=_('Save')?></button>
@@ -237,6 +240,30 @@ form_create_select('eid', _('Equipment'), $opt_equipment);
elseif ($action == ACT_VIEW):
// ========== VARIANT: view single record =====================================
$sql = "SELECT mname, unit, nval, val1, val2, val3, accuracy, mdate, note "
. "FROM measurement "
. "WHERE mid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
$measurement = $sth->fetch(PDO::FETCH_OBJ);
echo '<h2>', _('Measurement'), "</h2>\n";
echo '<table class="table">', "\n";
echo '<tr><th style="width:20%">', _('Name'),"</th><td>", $measurement->mname, "</td></tr>\n";
echo '<tr><th>', _('Unit'),"</th><td>", $opt_unit[$measurement->unit], "</td></tr>\n";
echo '<tr><th>', _('Values'),"</th><td>$measurement->nval</td></tr>\n";
echo '<tr><th>', _('Value 1'),"</th><td>$measurement->val1</td></tr>\n";
echo '<tr><th>', _('Value 2'),"</th><td>$measurement->val2</td></tr>\n";
echo '<tr><th>', _('Value 3'),"</th><td>$measurement->val3</td></tr>\n";
echo '<tr><th>', _('Accuracy'),"</th><td>$measurement->accuracy</td></tr>\n";
echo '<tr><th>', _('Date'),"</th><td>$measurement->mdate</td></tr>\n";
echo '<tr><th>', _('Note'),"</th><td>$measurement->note</td></tr>\n";
echo "</table>\n";
form_view_buttons($g_scriptname, $id);
elseif ($action == ACT_EDIT):
// ========== VARIANT: edit single record =====================================
+229
View File
@@ -0,0 +1,229 @@
<?php
/******************************************************************************
* YMS - Yacht Management Software
* Copyright (C) 2024 Thomas Hooge
*
* SPDX-License-Identifier: WTFPL
******************************************************************************/
require 'globals.inc';
$pagetitle = _('Note');
$id = gpc_get_int($_REQUEST, 'id', 0);
$opt_notetype = db_load_enum('note', 'notetype');
// ========== 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':
$p[':notetype'] = gpc_get_enum($_POST, 'notetype', $opt_notetype, 'task');
$p[':refid'] = gpc_get_int($_POST, 'refid');
$p[':annotation'] = gpc_get_string($_POST, 'annotation');
$id = db_exec_insert('note', $p);
$caller = gpc_get_string($_POST, 'caller');
$callid = $p[':refid'];
$action = ACT_VIEW;
break;
case 'update':
$p[':noteid'] = $id;
$p[':annotation'] = gpc_get_string($_POST, 'annotation');
db_exec_update('note', $p, 'noteid');
$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']);
// get information for redirect
$sth = $pdo->prepare("SELECT notetype, refid FROM note WHERE noteid=?");
$sth->execute([$id]);
$note = $sth->fetch(PDO::FETCH_OBJ);
if ($note->notetype == 'task') {
$backlink = 'task.php';
} else {
$backlink = 'maintenance.php';
}
$backlink .= '?f=view&id='. $note->refid;
// now really delete
$sth = $pdo->prepare("DELETE FROM note WHERE noteid=?");
$sth->execute([$id]);
header_location($backlink);
break;
default:
$g_error->Add(sprintf(_("Unknown function '%s'!"), $submit));
$valid = FALSE;
}
// ========== ACTIONS END =====================================================
require 'header.php';
// ========== PAGE CONTENT ====================================================
if ($action == ACT_DEFAULT):
// ========== VARIANT: default behavior =======================================
echo '<h1>', $pagetitle, "</h1>\n";
$sql = "SELECT n.noteid, n.notetype, n.refid,"
. " IF(CHAR_LENGTH(n.annotation) > 60, CONCAT(LEFT(n.annotation, 60), '&hellip;'), n.annotation) AS annotation "
. "FROM note AS n JOIN task AS t ON (n.notetype='task' AND n.refid=t.taskid AND t.vid=:vid) "
. "UNION "
. "SELECT n.noteid, n.notetype, n.refid,"
. " IF(CHAR_LENGTH(n.annotation) > 60, CONCAT(LEFT(n.annotation, 60), '&hellip;'), n.annotation) AS annotation "
. "FROM note AS n JOIN maintenance AS m ON (n.notetype='maint' AND n.refid=m.maintid AND m.vid=:vid) "
. "ORDER BY noteid";
$sth = $pdo->prepare($sql);
$sth->execute([':vid' => $user->vid]);
$res = $sth->fetchAll();
?>
<table class="table table-striped">
<thead>
<tr>
<th><?=_('ID')?></th>
<th><?=_('Reference')?></th>
<th><?=_('Type')?></th>
<th><?=_('Note')?></th>
</tr>
</thead>
<?php
foreach ($res as $row) {
echo "<tr>\n";
echo "<td>", $row['noteid'], "</td>\n";
echo "<td>", $row['refid'], "</td>\n";
echo "<td>", $row['notetype'], "</td>\n";
echo "<td>", $row['annotation'], "</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";
elseif ($action == ACT_ADD):
// ========== VARIANT: add record =============================================
echo '<h2>', _('Add Note'), "</h2>\n";
$notetype = gpc_get_enum($_REQUEST, 't', $opt_notetype);
// get task info for reference
if ($notetype == 'task') {
$sql = "SELECT taskname FROM task WHERE taskid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
$taskname = $sth->fetchColumn();
echo '<h3>', sprintf(_('Task: %s'), $taskname), "</h3>\n";
} elseif ($notetype == 'maint') {
$sql = "SELECT activities FROM maintenance WHERE maintid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
$activities = $sth->fetchColumn();
echo '<h3>', sprintf(_('Maintenance: %s'), $activities), "</h3>\n";
}
?>
<form method="post" action="<?=$g_scriptname?>">
<input type="hidden" name="refid" value="<?=$id?>">
<input type="hidden" name="notetype" value="<?=$notetype?>">
<input type="hidden" name="caller" value="<?=$g_referrer?>">
<div class="mb-3">
<label for="annotation" class="form-label"><?=_('Annotation')?></label>
<textarea class="form-control" id="annotation" name="annotation" rows="5" autofocus></textarea>
</div>
<div class="container-fluid px-0 my-3">
<button type="submit" name="submit[insert]" class="btn btn-primary"><?=_('Save')?></button>
<a href="<?=$g_referrer?>?f=view&id=<?=$id?>" class="btn btn-secondary"><?=_('Back')?></a>
</div>
<?php
elseif ($action == ACT_VIEW):
// ========== VARIANT: view single record =====================================
echo '<h2>', _('View Note'), "</h2>\n";
$sql = "SELECT refid, notetype, annotation FROM note WHERE noteid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
$note = $sth->fetch(PDO::FETCH_OBJ);
// TODO
// view annotation
// edit button
// list where annotaion used
echo '<table class="table">', "\n";
echo '<tr><th>', _('Referenz'),"</th><td>", $note->refid, "</td></tr>\n";
echo '<tr><th>', _('Annotation'),"</th><td>", $note->annotation, "</td></tr>\n";
echo "</table>\n";
$link = $note->notetype == 'task' ? 'task.php' : 'maintenance.php';
// echo '<p><a href="', $link, '?f=view&id=', $note->refid, '">', _('Parent'), "</a></p>\n";
form_view_buttons($g_scriptname, $id, $link.'?f=view&id='.$note->refid);
elseif ($action == ACT_EDIT):
// ========== VARIANT: edit single record =====================================
$sql = "SELECT refid, notetype, annotation FROM note WHERE noteid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
$note = $sth->fetch(PDO::FETCH_OBJ);
echo '<h2>', _('Edit Note'), "</h2>\n";
?>
<form method="post" action="<?=$g_scriptname?>">
<input type="hidden" name="id" value="<?=$id?>">
<div class="mb-3">
<label for="annotation" class="form-label"><?=_('Annotation')?></label>
<textarea class="form-control" id="annotation" name="annotation" rows="5" autofocus><?=$note->annotation;?></textarea>
</div>
<?php
form_edit_buttons($g_scriptname, $id);
echo "</form>\n";
elseif ($action == ACT_DELETE):
// ========== VARIANT: delete record ==========================================
echo '<h2>', _('Delete Note'), "</h2>\n";
$sql = "SELECT notetype, annotation FROM note WHERE noteid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
$note = $sth->fetch(PDO::FETCH_OBJ);
echo '<h2>', _('Delete Note'), "</h2>\n";
echo '<p>', sprintf(_('Record no. %d'), $id), "</p>\n";
echo '<p>', $note->annotation, "</p>";
echo '<p>', _('Deleting an note item is final. There is no way back. Only delete if you are absolute sure.'), "</p>\n";
$_SESSION['token'] = bin2hex(random_bytes(8));
form_delete_buttons($g_scriptname, $id, $_SESSION['token']);
else:
// ========== ERROR UNKNOWN VARIANT ===========================================
echo '<p>', _('Unknown function call: Please report to system development!'), "</p>\n";
endif; // $action == ...
// ========== END OF VARIANTS =================================================
include 'footer.php';
+48 -6
View File
@@ -16,17 +16,14 @@ require 'header.php';
echo "<h1>$pagetitle</h1>\n";
?>
<p>Search will be implemented later.
This page is currently just a placeholder.</p>
<form method="post" action="<?=$g_scriptname?>">
<div>
<label for="needle">Suche nach:</label>
<input type="text" id="needle" name="needle" value="<?=$needle?>" autofocus>
</div>
<div>
<input type="checkbox" id="remarks" name="ck_remarks">
<label for="remarks">Bemerkungsfelder Berücksichtigen</label>
<input type="checkbox" id="remarks" name="ck_remarks"<?php if (isset($_POST['ck_remarks'])) echo ' checked'; ?>>
<label for="remarks">Bemerkungsfelder berücksichtigen</label>
</div>
<button type="submit" class="btn btn-primary" name="submit[search]"><?=_('Search')?></button>
</form>
@@ -35,6 +32,51 @@ This page is currently just a placeholder.</p>
if (isset($needle)) {
$sqlneedle = '%'.$needle.'%';
}
$remarks = isset($_POST['ck_remarks']) ? ' OR remarks LIKE :needle' : '';
// equipment
$sql = "SELECT eid, ename, model, remarks "
. "FROM equipment "
. "WHERE ename LIKE :needle OR model LIKE :needle" . $remarks;
$sth = $pdo->prepare($sql);
$sth->execute([':needle' => $sqlneedle]);
if ($sth->rowCount() > 0) {
echo '<h3>', _('Equipment'), "</h3>\n";
foreach ($sth->fetchAll() as $row) {
$out = $row['ename'] . ' ' . $row['model'];
// mark needle in result
$p0 = strpos($out, $needle);
if ($p0 > 0) {
$out = substr_replace($out, '</span>', $p0 + strlen($needle), 0);
$out = substr_replace($out, '<span style="background:#ffef00;">', $p0, 0);
}
echo '<p>', $out;
echo '';
echo "</p>\n";
}
}
// inventory
$sql = "SELECT invid, invname, remarks "
. "FROM inventory "
. "WHERE invname LIKE :needle" . $remarks;
$sth = $pdo->prepare($sql);
$sth->execute([':needle' => $sqlneedle]);
if ($sth->rowCount() > 0) {
echo '<h3>', _('Inventory'), "</h3>\n";
foreach ($sth->fetchAll() as $row) {
$out = $row['invname'] . ' ' . $row['model'];
// mark needle in result
$p0 = strpos($out, $needle);
if ($p0 > 0) {
$out = substr_replace($out, '</span>', $p0 + strlen($needle), 0);
$out = substr_replace($out, '<span style="background:#ffef00;">', $p0, 0);
}
echo '<p>', $out;
echo '';
echo "</p>\n";
}
}
}
include 'footer.php';
+1 -1
View File
@@ -64,7 +64,7 @@ switch ($submit = form_get_action()) {
break;
}
// - no assigned equipment
$sth = $pdo->prepare("SELECT COUNT(*) FROM inventory WHERE boxtype='storage' AND sid=?");
$sth = $pdo->prepare("SELECT COUNT(*) FROM inventory WHERE conttype='storage' AND sid=?");
$sth->execute([$id]);
if ($sth->fetchColumn() > 0) {
$g_error->Add(_('Delete failed, assigned equipment detected!'));
+192
View File
@@ -0,0 +1,192 @@
<?php
/******************************************************************************
* YMS - Yacht Management Software
* Copyright (C) 2024 Thomas Hooge
*
* SPDX-License-Identifier: WTFPL
******************************************************************************/
require 'globals.inc';
$pagetitle = _('Tags');
$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 'filter':
$flt = array();
$flt['txt'] = gpc_get_string($_POST, 'flt_txt');
db_save_filter($flt, 210);
$action = ACT_DEFAULT;
break;
case 'insert':
$p[':tagname'] = gpc_get_string($_POST, 'tagname');;
$id = db_exec_insert('tag', $p);
$action = ACT_VIEW;
break;
case 'update':
$p[':tagid'] = $id;
$p[':tagname'] = gpc_get_string($_POST, 'tagname');
$p[':color'] = gpc_get_string($_POST, 'color');
$p[':description'] = gpc_get_string($_POST, 'description');
db_exec_update('tag', $p, 'tagid');
$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;
}
// tagref have to be empty
// TODO
$action = ACT_DEFAULT;
break;
default:
$g_error->Add(sprintf(_('Unknown function!'), $submit));
$valid = FALSE;
}
// ========== ACTIONS END =====================================================
require 'header.php';
// ========== PAGE CONTENT ====================================================
if ($action == ACT_DEFAULT):
// ========== VARIANT: default behavior =======================================
// load filter from db
$flt = db_get_filter($user->id, 210);
echo "<h1>$pagetitle</h1>\n";
// Filter
?>
<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 tagid, tagname, color, description "
. "FROM tag "
. "ORDER BY tagname";
$sth = $pdo->query($sql);
$res = $sth->fetchAll();
echo '<table class="table table-striped">', "\n";
echo "<thead>\n";
echo "<tr>\n";
echo '<th>', _('Tag'), "</th>";
echo '<th>', _('Description'), "</th>";
echo '<th>', _('Color'), "</th>";
echo "<th></th>";
echo "</tr>\n";
echo "</thead>\n";
foreach ($res as $row) {
echo "<tr>\n";
echo "<td>", $row['tagname'], "</td>\n";
echo "<td>", $row['description'], "</td>\n";
echo "<td>", $row['color'], "</td>\n";
echo "<td>";
// Action buttons
form_action_buttons($g_scriptname, $row['tagid']);
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";
form_add_button($g_scriptname);
elseif ($action == ACT_ADD):
// ========== VARIANT: add record =============================================
echo '<h2>', _('Add Tag'), "</h2>\n";
?>
<form method="post" action="<?=$g_scriptname?>">
<div class="mb-3">
<label for="tagname" class="form-label"><?=_('Name')?></label>
<input type="text" class="form-control" id="tagname" name="tagname" required autofocus>
</div>
<div class="mb-3">
<label for="note" class="form-label"><?=_('Description')?></label>
<input type="text" class="form-control" id="description" name="description">
</div>
<?php
form_new_buttons($g_scriptname);
echo "</form>\n";
elseif ($action == ACT_VIEW):
// ========== VARIANT: view single record =====================================
elseif ($action == ACT_EDIT):
// ========== VARIANT: edit single record =====================================
$sql = "SELECT tagname, description, color "
. "FROM tag "
. "WHERE tagid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
$tag = $sth->fetch(PDO::FETCH_OBJ);
echo '<h2>', _('Edit tag'), "</h2>\n";
?>
<form method="post" action="<?=$g_scriptname?>">
<input type="hidden" name="id" value="<?=$id?>">
<div class="mb-3">
<label for="mname" class="form-label"><?=_('Tag')?></label>
<input type="text" class="form-control" id="tagname" name="tagname" value="<?=$tag->tagname ?>">
</div>
<div class="mb-3">
<label for="note" class="form-label"><?=_('Description')?></label>
<input type="text" class="form-control" id="description" name="description" value="<?=$tag->description ?>">
</div>
<div class="mb-3">
<label for="color" class="form-label"><?=_('Color')?></label>
<input type="color" name="color" id="color" class="form-control" value="#<?=$tag->color ?>">
</div>
<?php
form_edit_buttons($g_scriptname, $id);
echo "</form>\n";
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';
+74 -9
View File
@@ -12,6 +12,7 @@ $pagetitle = _('Task');
$id = gpc_get_int($_REQUEST, 'id', 0);
$opt_projects = db_get_opt_proj($user->vid, array(-1 => _('unassigned')));
$opt_priority = db_load_enum('task', 'priority', true, true);
// ========== ACTIONS START ===================================================
@@ -25,6 +26,7 @@ switch ($submit = form_get_action()) {
case 'del': $action = ACT_DELETE; break;
case 'insert':
$p[':vid'] = $user->vid;
$p[':projid'] = gpc_get_int($_POST, 'projid');
if ($p[':projid'] == -1) {
$p[':projid'] = NULL;
@@ -37,10 +39,16 @@ switch ($submit = form_get_action()) {
case 'update':
$p[':taskid'] = $id;
$p[':projid'] = gpc_get_int($_POST, 'projid');
$p[':plandate'] = gpc_get_string($_POST, 'plandate');
$p[':duedate'] = gpc_get_string($_POST, 'duedate');
if ($p[':projid'] == -1) {
$p[':projid'] = NULL;
}
$p[':taskname'] = gpc_get_string($_POST, 'taskname');
$p[':priority'] = gpc_get_string($_POST, 'priority', 10);
if ($p[':priority'] == 'X') {
$p[':projid'] = NULL;
}
db_exec_update('task', $p, 'taskid');
$action = ACT_VIEW;
break;
@@ -65,7 +73,7 @@ if ($action == ACT_DEFAULT):
echo "<h1>$pagetitle</h1>\n";
$sql = "SELECT t.taskid, t.projid, t.taskname, p.projname "
$sql = "SELECT t.taskid, t.projid, t.taskname, t.priority, p.projname "
. "FROM task AS t LEFT JOIN project AS p USING (projid) "
. "WHERE p.projid IS NULL OR p.vid=? "
. "ORDER BY t.taskid";
@@ -83,15 +91,17 @@ echo "<tr>\n";
echo '<th>#</th>';
echo '<th>', _('Task'), "</th>";
echo '<th>', _('Project'), "</th>";
echo '<th>', _('Priority'), "</th>";
echo "<th></th>";
echo "<th></th>\n";
echo "</tr>\n";
echo "</thead>\n";
foreach ($res as $row) {
echo "<tr>\n";
echo "<td>" . $row['taskid'] . "</td>\n";
echo "<td>" . $row['taskname'] . "</td>\n";
echo "<td>" . $row['projname'] . "</td>\n";
echo "<td>", $row['taskid'], "</td>\n";
echo "<td>", $row['taskname'], "</td>\n";
echo "<td>", $row['projname'], "</td>\n";
echo "<td>", ($opt_priority[$row['priority']] ?? ''), "</td>\n";
// Action buttons
form_action_buttons($g_scriptname, $row['taskid']);
echo "</tr>\n";
@@ -102,6 +112,8 @@ echo '<tr><td colspan="6">', sprintf(_('%d records'), count($res)), '</td></tr>'
echo "</tfoot>\n";
echo "</table>\n";
form_add_button($g_scriptname);
elseif ($action == ACT_ADD):
// ========== VARIANT: add record =============================================
@@ -111,7 +123,8 @@ echo '<h2>', _('Add Task'), "</h2>\n";
<?php
// preselect project if parameter is set
$projid = gpc_get_int($_REQUEST, 'projid');
form_create_select('projid', _('Project'), $opt_projects, $projid);
$opt_none = [-1 => '&horbar; none &horbar;'];
form_create_select('projid', _('Project'), $opt_none + $opt_projects, $projid);
?>
<div class="mb-3">
<label for="taskname" class="form-label"><?=_('Task')?></label>
@@ -127,7 +140,8 @@ form_create_select('projid', _('Project'), $opt_projects, $projid);
elseif ($action == ACT_VIEW):
// ========== VARIANT: view single record =====================================
$sql = "SELECT t.taskname, p.projname "
$sql = "SELECT t.taskname, t.priority, t.plandate, t.duedate,"
. " t.started, t.finished, p.projname "
. "FROM task AS t LEFT JOIN project AS p USING (projid) "
. "WHERE taskid=?";
$sth = $pdo->prepare($sql);
@@ -137,15 +151,46 @@ $task = $sth->fetch(PDO::FETCH_OBJ);
echo '<h2>', _('View Task'), "</h2>\n";
echo '<table class="table">', "\n";
echo '<tr><th>', _('Task'),"</th><td>", $task->taskname, "</td></tr>\n";
echo '<tr><th>', _('Project'),"</th><td>", $task->projname ?? _('unassigned'), "</td></tr>\n";
echo '<tr><th>', _('Project'),"</th><td>", ($task->projname ?? _('unassigned')), "</td></tr>\n";
echo '<tr><th>', _('Priority'),"</th><td>", ($task->priority ?? _('none')), "</td></tr>\n";
echo '<tr><th>', _('Plan date'),"</th><td>", $task->plandate, "</td></tr>\n";
echo '<tr><th>', _('Due date'),"</th><td>", $task->duedate, "</td></tr>\n";
echo '<tr><th>', _('Started at'),"</th><td>", $task->started, "</td></tr>\n";
echo '<tr><th>', _('Finished at'),"</th><td>", $task->finished, "</td></tr>\n";
echo "</table>\n";
form_view_buttons($g_scriptname, $id);
echo "<h3>Annotations</h3>";
$sql = "SELECT noteid, annotation "
. "FROM note "
. "WHERE notetype='task' AND refid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
if ($sth->rowCount() > 0) {
$n = 0;
foreach ($sth->fetchAll() as $row) {
$n += 1;
echo "<p>($n) {$row['annotation']}";
echo ' <a title="', _('Edit'), '" href="note.php?f=edit&id=', $row['noteid'], '"><i class="bi-pencil"></i></a>';
echo "</p>\n";
}
} else {
echo '<p>', _('No annotations for this task'), "</p>\n";
}
echo '<div class="container-fluid px-0 my-3">', "\n";
echo '<a href="note.php?f=add&t=task&id=', $id, '" class="btn btn-primary" role="button">';
echo _('Add note'), "</a>\n";
echo "</div>\n";
echo "<h3>Documents</h3>";
echo "<p>Not yet implemented</p>";
elseif ($action == ACT_EDIT):
// ========== VARIANT: edit single record =====================================
$sql = "SELECT taskname, projid "
$sql = "SELECT taskname, projid, priority, plandate, duedate, started, finished "
. "FROM task "
. "WHERE taskid=?";
$sth = $pdo->prepare($sql);
@@ -162,7 +207,27 @@ echo '<h2>', _('Edit Task'), "</h2>\n";
<input type="text" class="form-control" id="taskname" name="taskname" value="<?=$task->taskname ?>">
</div>
<?php
form_create_select('projid', _('Project'), $opt_projects, $task->projid);
$opt_none = [-1 => '&horbar; none &horbar;'];
form_create_select('projid', _('Project'), $opt_none + $opt_projects, $task->projid);
form_create_select('priority', _('Priority'), $opt_none + $opt_priority, $task->priority ?? 'X');
?>
<div class="mb-3">
<label for="plandate" class="form-label"><?=_('Plan date')?></label>
<input type="date" class="form-control" id="plandate" name="plandate" value="<?=$task->plandate ?>">
</div>
<div class="mb-3">
<label for="duedate" class="form-label"><?=_('Due date')?></label>
<input type="date" class="form-control" id="duedate" name="duedate" value="<?=$task->duedate ?>">
</div>
<div class="mb-3">
<label for="started" class="form-label"><?=_('Started at')?></label>
<input type="datetime-local" class="form-control" id="started" name="started" value="<?=$task->started ?>">
</div>
<div class="mb-3">
<label for="finished" class="form-label"><?=_('Finished at')?></label>
<input type="datetime-local" class="form-control" id="finished" name="finished" value="<?=$task->finished ?>">
</div>
<?php
form_edit_buttons($g_scriptname, $id);
echo "</form>\n";