Ongoing webgui work

This commit is contained in:
2025-04-01 14:49:03 +02:00
parent 0c09ce2916
commit c293ca1caa
20 changed files with 572 additions and 166 deletions
+4
View File
@@ -11,10 +11,14 @@ YMS Installation
1.2 Native GUI
- Python GTK3
- python3-gi
- gir1.2-gtk-3.0
1.3 Web GUI
- Webserver
- PHP
- php-mysql
- php-xml
2. Create database
+4 -2
View File
@@ -146,11 +146,12 @@ CREATE TABLE inventory (
conttype enum('storage','box') NOT NULL DEFAULT 'storage',
sid smallint(6) NOT NULL DEFAULT 1,
boxid smallint(6) NOT NULL DEFAULT 1,
eid smallint(6) DEFAULT NULL,
number smallint(6) UNSIGNED NOT NULL DEFAULT 1,
weight float(5,2) UNSIGNED DEFAULT NULL,
price decimal(12,2) DEFAULT NULL,
purchdate date DEFAULT NULL,
invcond enum('unknown','good','normal','bad','repairable','defect') NOT NULL default 'unknown',
invcond enum('unknown','new','good','normal','bad','repairable','defect') NOT NULL default 'unknown',
remarks varchar(150) DEFAULT NULL,
PRIMARY KEY (invid),
INDEX ix_invname (invname)
@@ -174,6 +175,7 @@ CREATE TABLE measurement (
CREATE TABLE provisions (
provid int(10) NOT NULL AUTO_INCREMENT,
provname varchar(40) NOT NULL,
provcat tinyint(3) DEFAULT NULL,
sid smallint(6) DEFAULT NULL,
number smallint(6) UNSIGNED NOT NULL DEFAULT 1,
unit tinyint(3) DEFAULT NULL,
@@ -228,7 +230,7 @@ CREATE TABLE company (
contractno varchar(20),
remarks varchar(150) DEFAULT NULL,
PRIMARY KEY (compid),
UNIQUE INDEX ix_compname (compname)
UNIQUE INDEX ix_compname (compname, comptype)
);
+1 -1
View File
@@ -157,7 +157,7 @@ echo '<tr><th style="width:20%">', _('Box type'),"</th><td>", ($opt_boxtype[$box
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;
echo '<tr><th>', _('Storage'),"</th><td>", $box->sname, '&nbsp;';
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";
+33 -5
View File
@@ -87,6 +87,8 @@ require 'header.php';
if ($action == ACT_DEFAULT):
// ========== VARIANT: default behavior =======================================
page_caption_search($pagetitle);
// load filter from db
$flt = db_get_filter($user->id, 208);
@@ -103,10 +105,34 @@ if (strlen($flt->txt) > 1) {
$where = join(' AND ', $w);
$order = ' ORDER BY comptype, compname';
// grand total of records for current vessel
$grandtotal = $pdo->query("SELECT COUNT(*) FROM company")->fetchColumn();
// get total record count for pagination and limit
$sql = "SELECT COUNT(*) FROM company";
if ($where) {
$sql .= " WHERE $where";
}
$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));
}
$numrows = $sth->fetchColumn();
$lastpage = ceil($numrows/$g_rows_pp);
$page = gpc_get_int($_REQUEST, 'p', 1);
$sql = "SELECT compid, compname, comptype, remarks "
. "FROM company";
if ($where) $sql .= ' WHERE ' . $where;
$sql .= $order;
// if pagination:
$sql .= ' LIMIT ' . ($page - 1) * $g_rows_pp . ',' . $g_rows_pp;
$sth = $pdo->prepare($sql);
try {
$sth->execute($p);
@@ -117,8 +143,6 @@ try {
}
$res = $sth->fetchAll();
echo '<h1>', $pagetitle , "</h1>\n";
// Filter
$opt_special = array(
-2 => _('&horbar; all &horbar;'),
@@ -149,6 +173,9 @@ foreach ($opt_special + $opt_comptype as $k => $v) {
<?php
// Pagination on top
$pagination = get_pagination($g_scriptname, '', $page, $lastpage);
echo $pagination;
echo '<table class="table table-striped">', "\n";
echo "<thead>\n";
@@ -173,10 +200,12 @@ foreach ($res as $row) {
}
// Table summary
echo "<tfoot>\n";
echo '<tr><td colspan="6">', sprintf(_('%d records'), count($res)), '</td></tr>', "\n";
echo '<tr><td colspan="6">', sprintf(_('%d records out of total %d'), count($res), $grandtotal), '</td></tr>', "\n";
echo "</tfoot>\n";
echo "</table>\n";
echo $pagination;
form_add_button($g_scriptname);
@@ -230,8 +259,7 @@ form_view_buttons($g_scriptname, $id);
// show referenced equipment
$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();
$sth->execute([':id' => $id]);
if ($sth->rowCount() > 0) {
echo "<p>Referenced in equipment:</p>\n";
echo "<ul>\n";
+1
View File
@@ -25,6 +25,7 @@ $g_mailto = 'captain@example.com';
$g_mailto_webmaster = 'webmaster@example.com';
// localization
$g_textdomain = 'yms';
$g_timezone = 'Europe/Berlin';
$g_locale = 'de_DE.UTF-8';
+107 -23
View File
@@ -14,6 +14,11 @@ $pagetitle = _('Documents');
$id = gpc_get_int($_REQUEST, 'id', 0);
$page = gpc_get_int($_REQUEST, 'p', 1);
$opt_doctype = db_load_enum('document', 'doctype', true, true);
asort($opt_doctype);
$opt_reftype = db_load_enum('docref', 'reftype', true, true);
asort($opt_reftype);
// ========== ACTIONS START ===================================================
switch ($submit = form_get_action()) {
@@ -27,7 +32,8 @@ switch ($submit = form_get_action()) {
case 'filter':
$flt = array();
$flt['doctype'] = gpc_get_string($_POST, 'flt_doctype');
$flt['doctype'] = gpc_get_enum($_POST, 'flt_doctype', array_keys($opt_doctype));
$flt['reftype'] = gpc_get_enum($_POST, 'flt_reftype', array_merge(array_keys($opt_reftype), ['none']));
$flt['txt'] = gpc_get_string($_POST, 'flt_txt');
db_save_filter($flt, 209);
$action = ACT_DEFAULT;
@@ -155,9 +161,10 @@ switch ($submit = form_get_action()) {
case 'addref':
$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 "
$p[':docid'] = $id;
$p[':refid'] = gpc_get_int($_POST, 'refid');
$p[':reftype'] = gpc_get_enum($_POST, 'reftype', $opt_reftype, 'equipment');
/* $sql = "INSERT INTO docref "
. " (docid, refid, reftype) "
. "VALUES "
. " (:docid, :refid, :reftype)";
@@ -165,7 +172,8 @@ switch ($submit = form_get_action()) {
$sth->bindValue(':docid', $id, PDO::PARAM_INT);
$sth->bindValue(':refid', $refid, PDO::PARAM_INT);
$sth->bindValue(':reftype', $reftype, PDO::PARAM_STR);
$sth->execute();
$sth->execute(); */
db_exec_insert('docref', $p);
$action = ACT_VIEW;
break;
@@ -194,23 +202,24 @@ require 'header.php';
if ($action == ACT_DEFAULT):
// ========== VARIANT: default behavior =======================================
// All documents
page_caption_search($pagetitle);
$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
- are assigned to an equipment or project of current vesseö
There can be multiple docref entries for a document,
behavior still needs to be clarified. */
$w = array();
$p = array();
if ($flt->doctype != 'all') {
if (isset($flt->doctype) and $flt->doctype != 'all') {
$w[] = 'doctype=:doctype';
$p[':doctype'] = $flt->doctype;
}
if (isset($flt->reftype) and $flt->reftype != 'all') {
if ($flt->reftype == 'none') {
$w[] = 'reftype IS NULL';
} else {
$w[] = 'reftype=:reftype';
$p[':reftype'] = $flt->reftype;
}
}
if (strlen($flt->txt) > 1) {
$w[] = '(filename LIKE :txt OR title LIKE :txt OR remarks LIKE :txt)';
$p[':txt'] = '%'.$flt->txt.'%';
@@ -219,17 +228,34 @@ if (strlen($flt->txt) > 1) {
$where = join(' AND ', $w);
$order = ' ORDER BY docid';
// get total recond count for pagination and limit
$sql = "SELECT COUNT(*) FROM document LEFT OUTER JOIN docref USING (docid)";
if ($where) $sql .= ' WHERE ' . $where;
$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));
}
$numrows = $sth->fetchColumn();
$lastpage = ceil($numrows/$g_rows_pp);
$page = gpc_get_int($_REQUEST, 'p', 1);
$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)";
if ($where) $sql .= ' WHERE ' . $where;
$sql .= " GROUP BY d.docid, d.doctype, d.filename, d.title";
if ($order) $sql .= $order;
// if pagination:
$sql .= ' LIMIT ' . ($page - 1) * $g_rows_pp . ',' . $g_rows_pp;
$sth = $pdo->prepare($sql);
$sth->execute($p);
$res = $sth->fetchAll();
echo "<h1>$pagetitle</h1>\n";
// Filter
$opt_special = array(
'all' => _('&horbar; all &horbar;'),
@@ -251,6 +277,19 @@ foreach ($opt_special + $opt_doctype as $k => $v) {
}
?>
</select>
<label for="flt_reftype"><?=_('Ref.-Type')?></label>
<select id="flt_reftype" name="flt_reftype">
<?php
$opt_special['none'] = _('&horbar; none &horbar;');
foreach ($opt_special + $opt_reftype as $k => $v) {
echo '<option value="', $k,'"';
if ($k == $flt->reftype) {
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>
@@ -259,6 +298,11 @@ foreach ($opt_special + $opt_doctype as $k => $v) {
</form>
<?php
// Pagination on top
$pagination = get_pagination($g_scriptname, '', $page, $lastpage);
echo $pagination;
// Data
echo '<table class="table table-striped">', "\n";
echo "<thead>\n";
echo "<tr>";
@@ -290,6 +334,8 @@ echo '<tr><td colspan="6">', sprintf(_('%d records'), count($res)), '</td></tr>'
echo "</tfoot>\n";
echo "</table>\n";
echo $pagination;
form_add_button($g_scriptname);
elseif ($action == ACT_ADD):
@@ -300,11 +346,11 @@ echo '<h2>', _('Add Document'), "</h2>\n";
<form method="post" enctype="multipart/form-data" action="<?=$g_scriptname?>">
<div class="mb-3">
<label for="title" class="form-label"><?=_('Title')?></label>
<input type="text" class="form-control" id="title" name="title" value="<?=$title?>">
<input type="text" class="form-control" id="title" name="title" value="<?=$title ?? ''?>">
</div>
<div class="mb-3">
<label for="remarks" class="form-label"><?=_('Remarks')?></label>
<textarea class="form-control" id="remarks" name="remarks" rows="3"><?=$remarks?></textarea>
<textarea class="form-control" id="remarks" name="remarks" rows="3"><?=$remarks ?? ''?></textarea>
</div>
<div class="mb-3">
<label for="files" class="form-label"><?=_('Document')?></label>
@@ -356,9 +402,29 @@ echo '<tr><th scope="row" style="width:20%">', _('Document type'),"</th><td>", $
if ($document->doctype == 'picture') {
$techname = sprintf('pic-%06d.%s', $document->docid, $document->extension);
echo '<tr><th scope="row">', _('Preview'), '</th><td>';
echo '<a href="dl.php?id=', $document->docid, '" target="_blank">';
// echo '<a href="dl.php?id=', $document->docid, '" target="_blank">';
echo '<div class="image-gallery">';
echo '<a href="#" data-bs-toggle="modal" data-bs-target="#imageModal">';
echo '<img width="', $g_thumb_size, '" src="dl.php?id=', $document->docid, '" alt="', $document->title, '">';
echo '</a>';
echo '</div>'; // gallery
?>
<div class="modal fade" id="imageModal" tabindex="-1" aria-labelledby="imageModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<img src="dl.php?id=<?=$document->docid ?>">
</div>
</div>
</div>
</div>
<?php
// echo '</a>';
echo "</td></tr>\n";
} elseif (($document->doctype == 'drawing')) {
$techname = sprintf('drw-%06d.%s', $document->docid, $document->extension);
@@ -391,7 +457,7 @@ echo "</table>\n";
echo "</div>\n", '<div class="col text-center">', "\n"; // column break
if ($document->mimetype == 'application/pdf') {
echo '<img src="dl.php?id=', $document->docid, '&p=', $page, '&t=l" alt="PDF-Preview">', "\n";
echo '<img id="preview" 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;
@@ -407,6 +473,18 @@ form_view_buttons($g_scriptname, $id);
echo '<h3>', _('Document references'), "</h3>\n";
$references = array();
// Vessel
$vids = array();
$sql = "SELECT drid, reftype, refid, vesselname AS target "
. "FROM docref INNER JOIN vessel ON (docref.reftype='vessel' AND docref.refid=vessel.vid) "
. "WHERE docid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
foreach ($sth->fetchAll() as $row) {
$references[] = $row;
$vids[] = $row['refid'];
}
// Equipment
$eids = array();
$sql = "SELECT drid, reftype, refid, ename AS target "
@@ -458,6 +536,9 @@ echo "</table>\n";
// New references
echo '<h4>', _('Add new reference'), "</h4>\n";
// enum('vessel','box','equipment','project','task','user','company')
//
// Equipment options
// Do not include equipment that has already been referenced in the list!
$opt_equipment = array();
@@ -470,7 +551,7 @@ foreach ($sth->fetchAll() as $row) {
}
}
?>
<form method="post" action="<?=$g_scriptname?>">
<form class="mb-3" method="post" action="<?=$g_scriptname?>">
<input type="hidden" name="id" value="<?=$id?>">
<input type="hidden" name="reftype" value="equipment">
<label for="eid"><?=_('Equipment')?></label>
@@ -485,19 +566,22 @@ foreach ($opt_equipment as $k => $v) {
</form>
<?php
// Company options
// Do not include compamies that have already been referenced in this list
$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)) {
if (!in_array($row['compid'], $compids)) {
$opt_company[$row['compid']] = $row['compname'];
}
}
?>
<form method="post" action="<?=$g_scriptname?>">
<form class="mb-3" method="post" action="<?=$g_scriptname?>">
<input type="hidden" name="id" value="<?=$id?>">
<input type="hidden" name="reftype" value="company">
<label for="compid"><?=_('Company')?></label>
+5 -1
View File
@@ -167,7 +167,7 @@ $listname = $sth->fetchColumn();
echo '<h2>', sprintf(_('View List: %s'), $listname), "</h2>\n";
$sql = "SELECT ddval, ddtext, ddshort, color, sort FROM dropdown WHERE ddid=?";
$sql = "SELECT ddval, ddtext, ddshort, color, sort, flags FROM dropdown WHERE ddid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
@@ -179,11 +179,14 @@ echo '<th>', _('Name'), "</th>";
echo '<th>', _('Short'), "</th>";
echo '<th>', _('Color'), "</th>";
echo '<th>', _('Sort'), "</th>";
echo '<th>', _('Flags'), "</th>";
echo "<th></th>\n";
echo "</tr>\n";
echo "</thead>\n";
foreach ($sth->fetchAll() as $row) {
$flags = explode(',', $row['flags']);
$fixed = in_array('fixed', $flags);
echo '<tr>';
echo '<td>', $row['ddval'],'</td>';
echo '<td>', $row['ddtext'], '</td>';
@@ -194,6 +197,7 @@ foreach ($sth->fetchAll() as $row) {
echo '<td></td>';
}
echo '<td>', $row['sort'], '</td>';
echo '<td>', ($fixed ? '<i class="bi bi-lock"></i>' : ''), '</td>';
echo "</tr>\n";
}
echo "</table>\n";
+42 -43
View File
@@ -7,6 +7,8 @@
******************************************************************************/
require 'globals.inc';
require 'lib/fileutils.inc';
$pagetitle = _('Equipment');
$id = gpc_get_int($_REQUEST, 'id', 0);
@@ -145,21 +147,23 @@ switch ($submit = form_get_action()) {
$sth = $pdo->prepare($sql);
$sth->execute(['picture', $file_name, $file_ext, $file_hash, $file_timestamp, $file_size, $file_mimetype]);
$docid = $pdo->lastInsertId();
$file_techname = $g_doc_basepath . '/pic-'.$file_hash.'.'.$file_ext;
move_uploaded_file($file_tmp, $file_techname);
$file_techname = file_get_docname($docid, 'picture', $file_ext);
move_uploaded_file($file_tmp, $g_doc_basepath . '/' . $file_techname);
} else {
// A document record definitely exists here, now just
// connect it to the selected equipment
$docid = $row['docid'];
}
$sql = "INSERT INTO docref (docid, refid) VALUES (?, ?)";
$sql = "INSERT INTO docref (docid, refid, reftype) VALUES (?, ?, 'equipment')";
$sth = $pdo->prepare($sql);
// Reference may already exist!
try {
$sth->execute([$docid, $id]);
} catch (PDOException $e) {
$g_error->Add('SQL-Error: '. $e->getMessage());
$g_error->Add($sql);
// $g_error->Add(print_r($params, true));
}
} // for
@@ -180,7 +184,8 @@ require 'header.php';
if ($action == ACT_DEFAULT):
// ========== VARIANT: default behavior =======================================
// load filter from db
page_caption_search($pagetitle);
$flt = db_get_filter($user->id, 200);
$sort = array(
@@ -237,54 +242,22 @@ $sth = $pdo->prepare($sql);
$sth->execute($p);
$res = $sth->fetchAll();
echo "<h1>$pagetitle</h1>\n";
// Filter
$opt_special = array(
/*$opt_special = array(
-2 => _('&horbar; all &horbar;'),
-1 => _('&horbar; none &horbar;')
);
); */
$opt_none_male = array(-1 => pgettext('male', '&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_category"><?=_('Category')?></label>
<select id="flt_category" name="flt_category">
<?php
foreach ($opt_special + $opt_ecat as $k => $v) {
echo '<option value="', $k, '"';
if ($k == $flt->cat) {
echo ' selected';
}
echo '>', $v, '</option>';
}
filter_create_select('flt_category', _('Category'), $g_opt_all + $g_opt_none + $opt_ecat, $flt->cat);
filter_create_select('flt_manuf', _('Manufacturer'), $g_opt_all + $opt_none_male + $opt_manufacturer, $flt->manuf);
filter_create_select('flt_supp', _('Supplier'), $g_opt_all + $opt_none_male + $opt_supplier, $flt->supp);
?>
</select>
<label for="flt_manuf"><?=_('Manufacturer')?></label>
<select id="flt_manuf" name="flt_manuf">
<?php
foreach ($opt_special + $opt_manufacturer as $k => $v) {
echo '<option value="', $k,'"';
if ($k == $flt->manuf) {
echo ' selected';
}
echo '>', $v, '</option>';
}
?>
</select>
<label for="flt_supp"><?=_('Supplier')?></label>
<select id="flt_supp" name="flt_supp">
<?php
foreach ($opt_special + $opt_supplier as $k => $v) {
echo '<option value="', $k,'"';
if ($k == $flt->supp) {
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>
@@ -394,7 +367,7 @@ echo '<tr><th>', _('Serial'),"</th><td>", $equipment->serial, "</td></tr>\n";
echo '<tr><th>', _('Weight'),"</th><td>", format_float($equipment->weight, 2, 'kg'), "</td></tr>\n";
echo '<tr><th>', _('Price'),"</th><td>", format_currency($equipment->price), "</td></tr>\n";
echo '<tr><th>', _('Purchase date'),"</th><td>", $equipment->purchdate, "</td></tr>\n";
echo '<tr><th>', _('Supplier'),"</th><td>", $opt_supplier[$equipment->supplier], "</td></tr>\n";
echo '<tr><th>', _('Supplier'),"</th><td>", $equipment->supplier ? $opt_supplier[$equipment->supplier] : 'n/a', "</td></tr>\n";
echo '<tr><th>', _('Category'),"</th><td>", $opt_ecat[$equipment->ecat], "</td></tr>\n";
echo '<tr><th>', _('Remarks'),"</th><td>", $equipment->remarks, "</td></tr>\n";
echo "</table>\n";
@@ -422,6 +395,14 @@ foreach ($res as $row) {
echo '<img width="120" src="dl.php?id=', $row['docid'], '&t=s" alt="', $row['title'], '">';
// echo $row['title'];
echo "</a>\n";
} elseif ($row['doctype'] == 'manual') {
echo "Manual: ";
echo '<a href="documents.php?f=view&id=', $row['docid'], '">';
echo $row['title'];
echo "</a>\n";
} else {
// unknown document type
echo "<span>Unknown document type:", $row['doctype'], "</span>\n";
}
}
?>
@@ -487,6 +468,24 @@ echo '<a href="measurement.php?f=add&id=', $id, '" class="btn btn-primary" role=
echo _('Add measurement'), "</a>\n";
echo "</div>\n";
// Spare parts
echo '<h3>', _('Spare parts'), "</h3>";
$sql = "SELECT invid, invname FROM inventory WHERE eid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
if ($sth->rowCount() > 0) {
echo "<ul>\n";
foreach ($sth->fetchAll() as $row) {
echo "<li>", $row['invname'], ': ';
echo ' <a title="', _('View'), '" href="inventory.php?f=view&id=', $row['invid'], '"><i class="bi-eye"></i></a>';
echo "</li>\n";
}
echo "</ul>\n";
} else {
echo '<p>', _('No spare parts found.'), "<p>\n";
}
elseif ($action == ACT_EDIT):
// ========== VARIANT: edit single record =====================================
+21 -10
View File
@@ -73,6 +73,9 @@ switch ($submit = form_get_action()) {
$p[':beltpos_aft'] = gpc_get_float($_POST, 'beltpos_aft');
$p[':beltpos_bow'] = gpc_get_float($_POST, 'beltpos_bow');
$p[':shapefile'] = gpc_get_string($_POST, 'shapefile');
if ($p[':shapefile'] == '-1') {
$p[':shapefile'] = NULL;
}
$p[':remarks'] = gpc_get_string($_POST, 'remarks', 150);
db_exec_update('vessel', $p, 'vid');
$action = ACT_DEFAULT;
@@ -93,8 +96,7 @@ require 'header.php';
if ($action == ACT_DEFAULT):
// ========== VARIANT: default behavior =======================================
echo '<h1>', _('Yacht data'), "</h1>\n";
page_caption_search(_('Yacht data'));
echo '<p>', _('User'), ': ', $user->displayname, ' (', $user->role, ')', "</p>\n";
@@ -108,7 +110,7 @@ $vid = ($res[0]);
// Switch between vessels
$sth = $pdo->query("SELECT vid, vesselname, model FROM vessel ORDER BY vid");
$res = $sth->fetchAll();
echo '<form class="row" method="post">', "\n";
echo '<form class="row align-items-center" method="post">', "\n";
echo '<div class="col-1">', "\n";
echo '<label class="form-label" for="vid">Yacht:</label>';
echo "</div>\n";
@@ -157,25 +159,29 @@ EOT;
$shape = new SimpleXMLElement($baseshape);
// $shape['width'], $shape['height']
// offset for coordinate origin
$ox = 0;
$oy = 0;
$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);
$x = $ox + round($vessel->beltpos_aft / $vessel->loa * 1024);
$line = $g->addChild('line');
$line->addAttribute('x1', $x);
$line->addAttribute('y1', '0');
$line->addAttribute('y1', $oy);
$line->addAttribute('x2', $x);
$line->addAttribute('y2', $shape['height']);
$line->addAttribute('style', 'stroke:#ff0000;stroke-width:1px');
}
if (isset($vessel->beltpos_bow) and isset($vessel->loa) and ($vessel->beltpos_bow < $vessel->loa)) {
$x = round($vessel->beltpos_bow / $vessel->loa * 1024);
$x = $ox + round($vessel->beltpos_bow / $vessel->loa * 1024);
$line = $g->addChild('line');
$line->addAttribute('x1', $x);
$line->addAttribute('y1', '0');
$line->addAttribute('y1', $oy);
$line->addAttribute('x2', $x);
$line->addAttribute('y2', $shape['height']);
$line->addAttribute('style', 'stroke:#ff0000;stroke-width:1px');
@@ -240,7 +246,11 @@ $text->addAttribute('y', '95'); */
?>
<div class="container-fluid my-4">
<?=$shape->asXML()?>
<?php
$xml = $shape->asXML();
// strip first line: xml version ...
echo substr($xml, strpos($xml, "\n") + 1);
?>
</div>
<div class="container-fluid">
@@ -336,6 +346,7 @@ echo "</table>\n";
<h5 class="card-title"><?=_('Base data')?></h5>
<ul class="list-group list-group-flush">
<li class="list-group-item"><a href="dropdown.php"><?=_('Selection lists')?></a></li>
<li class="list-group-item"><a href="tag.php"><?=_('Tags')?></a></li>
<li class="list-group-item"><a href="storage.php"><?=_('Storage')?></a></li>
<li class="list-group-item"><a href="company.php"><?=_('Companies')?></a></li>
</ul>
@@ -345,7 +356,6 @@ echo "</table>\n";
<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>
</ul>
</div>
</div>
@@ -387,7 +397,8 @@ elseif ($action == ACT_EDIT):
// ========== VARIANT: edit single record =====================================
// get list of shapefiles
$opt_shapefiles = array('' => _('--- none ---'));
//$opt_shapefiles = array('' => _('--- none ---'));
$opt_shapefiles = $g_opt_none;
foreach (glob($g_shapedir.'/*.svg') as $f) {
$f = basename($f);
$opt_shapefiles[$f] = $f;
+46 -25
View File
@@ -14,6 +14,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);
$opt_equipment = db_get_opt_equip($user->vid, [-1 => _('&horbar; none &horbar;')]);
// ========== ACTIONS START ===================================================
@@ -59,6 +60,7 @@ switch ($submit = form_get_action()) {
$p[':purchdate'] = gpc_get_date($_POST, 'purchdate');
$p[':invcond'] = gpc_get_string($_POST, 'invcond');
$p[':remarks'] = gpc_get_string($_POST, 'remarks', 150);
$p[':eid'] = gpc_get_int($_POST, 'eid');
db_exec_update('inventory', $p, 'invid');
$action = ACT_VIEW;
break;
@@ -92,6 +94,8 @@ require 'header.php';
if ($action == ACT_DEFAULT):
// ========== VARIANT: default behavior =======================================
page_caption_search($pagetitle);
$flt = db_get_filter($user->id, 201);
/*
@@ -99,8 +103,6 @@ The only way to find out whether the inventory is on the current boat is to use
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) {
@@ -109,10 +111,10 @@ if ($flt->stor == -1) {
$w[] = 'i.sid=:sid';
$p[':sid'] = $flt->stor;
}
/*if ($flt->cond <> 'all') {
$w[] = 'indcond=:indcond';
$p[':indcond'] = $flt->cond;
}*/
if (strlen($flt->cond) > 2 ) {
$w[] = 'invcond=:invcond';
$p[':invcond'] = $flt->cond;
}
if (strlen($flt->txt) > 1) {
$w[] = 'invname LIKE :txt';
$p[':txt'] = '%'.$flt->txt.'%';
@@ -120,6 +122,22 @@ if (strlen($flt->txt) > 1) {
$where = join(' AND ', $w);
$order = ' ORDER BY invname';
$sql = "SELECT "
. "(SELECT COUNT(*) FROM inventory AS i JOIN storage AS s ON (i.conttype='storage' AND i.sid=s.sid) WHERE $where)"
. "+"
. "(SELECT COUNT(*) 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) WHERE $where)";
$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));
}
$numrows = $sth->fetchColumn();
$lastpage = ceil($numrows/$g_rows_pp);
$page = gpc_get_int($_REQUEST, 'p', 1);
$sql = "SELECT i.invid, i.invname, i.number, i.invcond, s.sname AS container "
. "FROM inventory AS i JOIN storage AS s ON (i.conttype='storage' AND i.sid=s.sid)";
$sql .= ' WHERE ' . $where;
@@ -128,6 +146,10 @@ $sql .= " UNION SELECT i.invid, i.invname, i.number, i.invcond, b.label AS conta
. " JOIN storage AS s ON (b.sid=s.sid) ";
$sql .= ' WHERE ' . $where;
$sql .= $order;
// if pagination:
$sql .= ' LIMIT ' . ($page - 1) * $g_rows_pp . ',' . $g_rows_pp;
$sth = $pdo->prepare($sql);
try {
$sth->execute($p);
@@ -169,6 +191,9 @@ foreach ($opt_special + $opt_storage as $k => $v) {
<label for="flt_cond"><?=_('Condition')?></label>
<select id="flt_cond" name="flt_cond">
<?php
$opt_special = array(
-2 => _('&horbar; all &horbar;'),
);
foreach ($opt_special + $opt_invcond as $k => $v) {
echo '<option value="', $k,'"';
if ($k == $flt->cond) {
@@ -186,6 +211,10 @@ foreach ($opt_special + $opt_invcond as $k => $v) {
</form>
<?php
// Pagination on top
$pagination = get_pagination($g_scriptname, '', $page, $lastpage);
echo $pagination;
echo '<table class="table table-striped">', "\n";
echo "<thead>\n";
echo "<tr>\n";
@@ -213,6 +242,8 @@ echo '<tr><td colspan="5">', sprintf(_('%d records'), count($res)), '</td></tr>'
echo "</tfoot>\n";
echo "</table>\n";
echo $pagination;
form_add_button($g_scriptname);
elseif ($action == ACT_ADD):
@@ -299,10 +330,11 @@ echo "<tr><th>", _('Number'), "</th><td>", $inventory->number, "</td></tr>\n";
echo "<tr><th>", _('Weight'), "</th><td>", format_float($inventory->weight, 2, 'kg'), "</td></tr>\n";
echo "<tr><th>", _('Price'), "</th><td>", format_currency($inventory->price), "</td></tr>\n";
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>", _('Condition'), "</th><td>", $opt_invcond[$inventory->invcond], "</td></tr>\n";
echo "<tr><th>", _('Remarks'), "</th><td>", $inventory->remarks, "</td></tr>\n";
form_tag_assignment($g_scriptname, $id);
$tags = db_load_taglist('inv', $id);
form_tag_assignment($g_scriptname, $id, $tags);
echo "</table>\n";
@@ -312,7 +344,7 @@ elseif ($action == ACT_EDIT):
// ========== VARIANT: edit single record =====================================
$sql = "SELECT invname, conttype, sid, boxid, number, weight, price, purchdate, "
. " invcond, remarks "
. " invcond, eid, remarks "
. "FROM inventory "
. "WHERE invid=?";
$sth = $pdo->prepare($sql);
@@ -335,14 +367,9 @@ $inventory = $sth->fetch(PDO::FETCH_OBJ);
<label for="weight" class="form-label"><?=_('Weight, kg')?></label>
<input type="text" class="form-control" id="weight" name="weight" value="<?=format_float($inventory->weight); ?>">
</div>
<div class="mb-3">
<label for="conttype" class="form-label"><?=_('Container type')?></label>
<select class="form-select" name="conttype" id="conttype">
<option value="box"><?=_('Box')?></option>
<option value="storage"><?=_('Storage')?></option>
</select>
</div>
<?php
<?php
$opt_conttype = db_load_enum('inventory', 'conttype', true, true);
form_create_select('conttype', _('Container type'), $opt_conttype, $inventory->conttype);
form_create_select('sid', _('Storage'), $opt_storage, $inventory->sid);
form_create_select('boxid', _('Box'), $opt_box, $inventory->boxid);
?>
@@ -358,14 +385,7 @@ form_create_select('boxid', _('Box'), $opt_box, $inventory->boxid);
<label for="invcond" class="form-label"><?=_('Condition')?></label>
<select name="invcond" id="invcond" class="form-control">
<?php
$cond = array(
'good' => _('Good'),
'normal' => _('Normal'),
'bad' => _('Bad'),
'repairable' => _('Repairable'),
'defect' => _('Defect'),
'unknown' => _('Unknown')
);
$cond = db_load_enum('inventory', 'invcond', true, true);
foreach ($cond as $k => $v) {
echo '<option value="', $k, '"';
if ($k == $inventory->invcond) {
@@ -376,6 +396,7 @@ foreach ($cond as $k => $v) {
?>
</select>
</div>
<?php form_create_select('eid', _('Equipment'), $opt_equipment, $inventory->eid); ?>
<div class="mb-3">
<label for="remarks" class="form-label"><?=_('Remarks')?></label>
<textarea class="form-control" id="remarks" name="remarks" rows="3"><?=$inventory->remarks ?></textarea>
+6 -5
View File
@@ -66,11 +66,11 @@ require 'header.php';
if ($action == ACT_DEFAULT):
// ========== VARIANT: default behavior =======================================
page_caption_search($pagetitle);
// load filter from db
$flt = db_get_filter($user->id, 204);
echo '<h1>', $pagetitle, "</h1>\n";
// Filter
$opt_special = array(
-2 => _('&horbar; all &horbar;'),
@@ -122,10 +122,11 @@ foreach ($res as $row) {
echo "<td>". $row['ename'] ."</td>\n";
echo "<td>". $row['remarks'] ."</td>\n";
// Action buttons
echo "<td>";
/* echo "<td>";
echo '<a title="', _('View'), '" href="', $g_scriptname, '?f=view&id=', $row['maintid'], '"><i class="bi-eye"></i></a>', "\n";
echo '<a title="', _('Edit'), '" href="', $g_scriptname, '?f=edit&id=', $row['maintid'], '"><i class="bi-pencil"></i></a>', "\n";
echo "</td>\n";
echo "</td>\n"; */
form_action_buttons($g_scriptname, $row['maintid']);
echo "</tr>\n";
}
// Table summary
@@ -202,7 +203,7 @@ 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;
if (isset($maint->eid)) {
if (isset($maint->eid) and $maint->eid>0) {
// Link to equipment
echo ' <a href="equipment.php?f=view&id=', $maint->eid, '"><i class="bi-eye"></i></a>';
}
+5
View File
@@ -72,6 +72,11 @@ oder nach Betriebsstunden definiert werden.</p>
<p>Einem Projekt werden Aufgaben zugeordnet, es hat einen Status wie
z.B. <em>neu</em>, <em>laufend</em> oder <em>erledigt</em>.</p>
<h3>Aufgaben</h3>
<p>Aufgaben sind normalerweise den aktuell ausgewählten Boot zugeordnet,
können aber auch bootsunabhängig angelegt werden. Eine projektzuordnung
ist ebenfalls vorgesehen</p>
<h3>Firmen</h3>
<p>Es können verschiedene Arten von Firmen hinterlegt werden, wie
beispielsweise Hersteller, Lieferanten, Werften oder Dienstleister.</p>
+3 -2
View File
@@ -240,7 +240,7 @@ form_create_select('eid', _('Equipment'), $opt_equipment, $id);
elseif ($action == ACT_VIEW):
// ========== VARIANT: view single record =====================================
$sql = "SELECT mname, unit, nval, val1, val2, val3, accuracy, mdate, note "
$sql = "SELECT mname, unit, nval, val1, val2, val3, accuracy, mdate, note, eid "
. "FROM measurement "
. "WHERE mid=?";
$sth = $pdo->prepare($sql);
@@ -259,6 +259,7 @@ 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 '<tr><th>', _('Equipment'), '</th><td>', $opt_equipment[$measurement->eid], "</td></tr>\n";
echo "</table>\n";
form_view_buttons($g_scriptname, $id);
@@ -267,7 +268,7 @@ form_view_buttons($g_scriptname, $id);
elseif ($action == ACT_EDIT):
// ========== VARIANT: edit single record =====================================
$sql = "SELECT mname, nval, val1, val2, val3, unit, accuracy, note "
$sql = "SELECT mname, nval, val1, val2, val3, unit, accuracy, note, eid "
. "FROM measurement "
. "WHERE mid=?";
$sth = $pdo->prepare($sql);
+2 -3
View File
@@ -62,7 +62,7 @@ switch ($submit = form_get_action()) {
// now really delete
$sth = $pdo->prepare("DELETE FROM note WHERE noteid=?");
$sth->execute([$id]);
header_location($backlink);
header_location($backlink, ['info' => _('Note deleted.')]);
break;
default:
@@ -111,6 +111,7 @@ foreach ($res as $row) {
echo "<td>", $row['refid'], "</td>\n";
echo "<td>", $row['notetype'], "</td>\n";
echo "<td>", $row['annotation'], "</td>\n";
form_action_buttons($g_scriptname, $row['noteid']);
echo "</tr>\n";
}
@@ -204,8 +205,6 @@ 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]);
+1 -1
View File
@@ -81,7 +81,7 @@ require 'header.php';
if ($action == ACT_DEFAULT):
// ========== VARIANT: default behavior =======================================
echo '<h1>', $pagetitle, "</h1>\n";
page_caption_search($pagetitle);
$sql = "SELECT projid, projname, startdate, duration, remarks "
. "FROM project "
+14 -5
View File
@@ -12,7 +12,7 @@ $pagetitle=_('Provisions');
$id = gpc_get_int($_REQUEST, 'id', 0);
$opt_storage = db_get_opt_storage($user->vid);
$opt_catgory = db_get_options(5);
$opt_category = db_get_options(5);
$opt_unit = db_get_options(6);
// ========== ACTIONS START ===================================================
@@ -28,6 +28,7 @@ switch ($submit = form_get_action()) {
case 'filter':
$flt = array();
$flt['cat'] = gpc_get_enum($_POST, 'flt_cat', array_merge(array_keys($opt_category), ['-2', '-1']));
$flt['txt'] = gpc_get_string($_POST, 'flt_txt');
db_save_filter($flt, 202);
$action = ACT_DEFAULT;
@@ -46,6 +47,7 @@ switch ($submit = form_get_action()) {
case 'update':
$p[':provid'] = $id;
$p[':provname'] = gpc_get_string($_POST, 'provname');
$p[':provcat'] = gpc_get_int($_POST, 'provcat');
$p[':number'] = gpc_get_int($_POST, 'number');
$p[':unit'] = gpc_get_int($_POST, 'unit');
$p[':storedate'] = gpc_get_string($_POST, 'storedate');
@@ -104,12 +106,15 @@ $sth = $pdo->prepare($sql);
$sth->execute($p);
$res = $sth->fetchAll();
echo "<h1>", $pagetitle, "</h1>\n";
page_caption_search($pagetitle);
?>
<form method="post" action="<?=$g_scriptname?>">
<div id="filter" class="card">
<div class="card-header">Filter</div>
<div class="card-body">
<?php
filter_create_select('flt_cat', _('Category'), $g_opt_all + $g_opt_none + $opt_category, $flt->cat);
?>
<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>
@@ -187,7 +192,7 @@ echo '<h2>', _('Add provisions'), "</h2>\n";
elseif ($action == ACT_VIEW):
// ========== VARIANT: view single record =====================================
$sql = "SELECT provname, number, unit, storedate, shelflife, sid "
$sql = "SELECT provname, provcat, number, unit, storedate, shelflife, sid "
. "FROM provisions "
. "WHERE provid=?";
$sth = $pdo->prepare($sql);
@@ -199,6 +204,7 @@ echo '<h2>', $prov->provname, "</h2>\n";
echo '<table class="table">', "\n";
echo '<tr><th style="width:20%">', _('Number'),"</th><td>", $prov->number, "</td></tr>\n";
echo '<tr><th>', _('Unit'),"</th><td>", $opt_unit[$prov->unit], "</td></tr>\n";
echo '<tr><th>', _('Category'),"</th><td>", $opt_category[$prov->provcat] ?? 'n/a', "</td></tr>\n";
echo '<tr><th>', _('Storedate'),"</th><td>", $prov->storedate, "</td></tr>\n";
echo '<tr><th>', _('Shelflife'),"</th><td>$prov->shelflife</td></tr>\n";
echo '<tr><th>', _('Storage'),"</th><td>", ($opt_storage[$prov->sid] ?? ''), "</td></tr>\n";
@@ -209,7 +215,7 @@ form_view_buttons($g_scriptname, $id);
elseif ($action == ACT_EDIT):
// ========== VARIANT: edit single record =====================================
$sql = "SELECT provname, number, unit, storedate, shelflife, sid "
$sql = "SELECT provname, provcat, number, unit, storedate, shelflife, sid "
. "FROM provisions "
. "WHERE provid=?";
$sth = $pdo->prepare($sql);
@@ -228,7 +234,10 @@ echo '<h2>', _('Edit provision'), "</h2>\n";
<label for="number"><?=_('Number')?></label>
<input type="number" min="0" max="1000" class="form-control" id="number" name="number" value="<?=$prov->number ?>">
</div>
<?php form_create_select('unit', _('Unit'), $opt_unit, $prov->unit); ?>
<?php
form_create_select('unit', _('Unit'), $opt_unit, $prov->unit);
form_create_select('provcat', _('Category'), array_merge($g_opt_none, $opt_category), $prov->provcat);
?>
<div class="mb-3">
<label for="storedate"><?=_('Storedate')?></label>
<input type="date" class="form-control" id="storedate" name="storedate" value="<?=$prov->storedate ?>">
+73 -18
View File
@@ -26,57 +26,112 @@ echo "<h1>$pagetitle</h1>\n";
<label for="remarks">Bemerkungsfelder berücksichtigen</label>
</div>
<button type="submit" class="btn btn-primary" name="submit[search]"><?=_('Search')?></button>
</form>
<?php
if ($g_referrer != $g_scriptname) {
echo '<a class="btn btn-secondary" href="', $g_referrer, '">', _('Back'), "</a>\n";
}
echo "</form>\n";
if (isset($needle)) {
$sqlneedle = '%'.$needle.'%';
$remarks = isset($_POST['ck_remarks']) ? ' OR remarks LIKE :needle' : '';
// equipment
$remarks = isset($_POST['ck_remarks']) ? ' OR remarks LIKE :needle' : '';
$sql = "SELECT eid, ename, model, remarks "
. "FROM equipment "
. "WHERE ename LIKE :needle OR model LIKE :needle" . $remarks;
. "WHERE vid=:vid AND (ename LIKE :needle OR model LIKE :needle)" . $remarks;
$sth = $pdo->prepare($sql);
$sth->execute([':needle' => $sqlneedle]);
$sth->execute([':vid' => $user->vid, ':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) {
$p0 = stripos($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>', $out, '&nbsp;';
echo '<a href="equipment.php?f=view&id=', $row['eid'], '"><i class="bi-eye"></i></a>';
echo "</p>\n";
}
}
// inventory
$sql = "SELECT invid, invname, remarks "
. "FROM inventory "
. "WHERE invname LIKE :needle" . $remarks;
$remarks = isset($_POST['ck_remarks']) ? 'OR i.remarks LIKE :needle ' : '';
$sql = "SELECT invid, invname, i.remarks "
. "FROM inventory AS i JOIN storage AS s ON (i.conttype='storage' AND i.sid=s.sid) "
. "WHERE s.vid=:vid AND i.invname LIKE :needle " . $remarks
. "UNION "
. "SELECT invid, invname, i.remarks "
. "FROM inventory AS i JOIN box AS b ON (i.conttype='box' AND i.boxid=b.boxid) "
. " JOIN storage AS s ON (i.sid=s.sid) "
. "WHERE s.vid=:vid AND i.invname LIKE :needle " . $remarks;
$sth = $pdo->prepare($sql);
$sth->execute([':needle' => $sqlneedle]);
$sth->execute([':vid' => $user->vid, ':needle' => $sqlneedle]);
if ($sth->rowCount() > 0) {
echo '<h3>', _('Inventory'), "</h3>\n";
foreach ($sth->fetchAll() as $row) {
$out = $row['invname'] . ' ' . $row['model'];
$out = rtrim($row['invname'] . ' ' . $row['model']);
// mark needle in result
$p0 = strpos($out, $needle);
if ($p0 > 0) {
$p0 = stripos($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>', $out, '&nbsp;';
echo '<a href="inventory.php?f=view&id=', $row['invid'], '"><i class="bi-eye"></i></a>';
echo "</p>\n";
}
}
// notes
$sql = "SELECT taskid, taskname "
. "FROM task "
. "WHERE taskname LIKE :needle AND (vid IS NULL OR vid=:vid)";
$sth = $pdo->prepare($sql);
$sth->execute([':needle' => $sqlneedle, ':vid' => $user->vid]);
if ($sth->rowCount() > 0) {
echo '<h3>', _('Tasks'), "</h3>\n";
foreach ($sth->fetchAll() as $row) {
// mark needle in result
$out = $row['taskname'];
$p0 = stripos($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, '&nbsp;';
echo '<a href="task.php?f=view&id=', $row['taskid'], '"><i class="bi-eye"></i></a>';
echo "</p>\n";
}
}
// notes
$sql = "SELECT noteid, annotation "
. "FROM note "
. "WHERE annotation LIKE :needle";
$sth = $pdo->prepare($sql);
$sth->execute([':needle' => $sqlneedle]);
if ($sth->rowCount() > 0) {
echo '<h3>', _('Annotations'), "</h3>\n";
foreach ($sth->fetchAll() as $row) {
// mark needle in result
$out = $row['annotation'];
$p0 = stripos($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, '&nbsp;';
echo '<a href="note.php?f=view&id=', $row['noteid'], '"><i class="bi-eye"></i></a>';
echo "</p>\n";
}
}
}
include 'footer.php';
+2 -2
View File
@@ -91,7 +91,7 @@ require 'header.php';
if ($action == ACT_DEFAULT):
// ========== VARIANT: default behavior =======================================
echo '<h1>', $pagetitle, "</h1>\n";
page_caption_search($pagetitle);
// Storage
// stype from dropdown
@@ -219,7 +219,7 @@ if (count($res) > 0) {
foreach ($res as $row) {
echo "<tr>";
echo '<td>', $row['label'], "</td>";
echo '<td>', $row['color'], "</td>";
echo '<td>', format_color($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";
}
+64 -3
View File
@@ -38,7 +38,7 @@ switch ($submit = form_get_action()) {
case 'update':
$p[':tagid'] = $id;
$p[':tagname'] = gpc_get_string($_POST, 'tagname');
$p[':color'] = gpc_get_string($_POST, 'color');
$p[':color'] = gpc_get_color($_POST, 'color');
$p[':description'] = gpc_get_string($_POST, 'description');
db_exec_update('tag', $p, 'tagid');
$action = ACT_VIEW;
@@ -77,6 +77,8 @@ $flt = db_get_filter($user->id, 210);
echo "<h1>$pagetitle</h1>\n";
// db_save_taglist('inv', 1, 'apple, banana , , , orange, ddd');
// Filter
?>
<form method="post" action="<?=$g_scriptname?>">
@@ -85,7 +87,7 @@ echo "<h1>$pagetitle</h1>\n";
<div class="card-body">
<label for="flt_txt">Text</label>
<input type="text" name="flt_txt" size="15" maxlength="30" value="<?=$flt->txt?>">
<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>
@@ -110,7 +112,7 @@ 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>", format_color($row['color']), "</td>\n";
echo "<td>";
// Action buttons
form_action_buttons($g_scriptname, $row['tagid']);
@@ -147,6 +149,50 @@ echo "</form>\n";
elseif ($action == ACT_VIEW):
// ========== VARIANT: view 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>', _('View Tag'), "</h2>\n";
echo '<table class="table">', "\n";
echo '<tr><th style="width:20%">', _('Tag'),"</th><td>", $tag->tagname, "</td></tr>\n";
echo '<tr><th>', _('Color'),"</th><td>", format_color($tag->color), "</td></tr>\n";
echo '<tr><th>', _('Description'),"</th><td>", $tag->description, "</td></tr>\n";
echo "</table>\n";
form_view_buttons($g_scriptname, $id);
echo '<h3>', _('Tag usage'), "</h3>\n";
$sql = "SELECT objid, objtype FROM tagref WHERE tagid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
$link = array(
'equip' => 'equipment.php',
'inv' => 'inventory.php',
'prov' => 'provisions.php',
'doc' => 'documents.php',
'proj' => 'projects.php',
'task' => 'task.php',
'maint' => 'maintenance.php'
);
echo '<p>';
if ($sth->rowCount() > 0) {
foreach ($sth->fetchAll() as $row) {
echo '<a href="', $link[$row['objtype']], '?f=view&id=', $row['objid'], '">', $row['objid'], '/', $row['objtype'], "</a>\n";
}
} else {
echo _('Tag is not used anywhere');
}
echo "</p>\n";
echo '<h3>', _('Related tags'), "</h3>\n";
echo '<p>', _('Not yet implemented'), "</p>\n";
elseif ($action == ACT_EDIT):
// ========== VARIANT: edit single record =====================================
@@ -181,6 +227,21 @@ echo "</form>\n";
elseif ($action == ACT_DELETE):
// ========== VARIANT: delete record ==========================================
echo '<h2>', _('Delete tag'), "</h2>\n";
$sql = "SELECT objid, objtype FROM tagref WHERE tagid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
if ($sth->rowCount() > 0) {
foreach ($sth->fetchAll() as $row) {
echo '<a href="', $link[$row['objtype']], '?f=view&id=', $row['objid'], '">', $row['objid'], '/', $row['objtype'], "</a>\n";
}
} else {
echo _('Tag is not used anywhere');
$_SESSION['token'] = bin2hex(random_bytes(8));
form_delete_buttons($g_scriptname, $id, $_SESSION['token']);
}
else:
// ========== ERROR UNKNOWN VARIANT ===========================================
+138 -17
View File
@@ -13,6 +13,7 @@ $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);
$opt_state = db_load_enum('task', 'taskstate', true, true);
// ========== ACTIONS START ===================================================
@@ -25,6 +26,15 @@ switch ($submit = form_get_action()) {
case 'edit': $action = ACT_EDIT; break;
case 'del': $action = ACT_DELETE; break;
case 'filter':
$flt = array();
$flt['prio'] = gpc_get_enum($_POST, 'flt_prio', array_merge(array_keys($opt_priority), ['-2', '-1']));
$flt['stat'] = gpc_get_enum($_POST, 'flt_stat', array_merge(array_keys($opt_state), ['-2', '-1']));
$flt['txt'] = gpc_get_string($_POST, 'flt_txt');
db_save_filter($flt, 206);
$action = ACT_DEFAULT;
break;
case 'insert':
$p[':vid'] = $user->vid;
$p[':projid'] = gpc_get_int($_POST, 'projid');
@@ -39,21 +49,52 @@ 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');
$p[':plandate'] = gpc_get_date($_POST, 'plandate');
$p[':duedate'] = gpc_get_date($_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;
if ($p[':priority'] == '-1') {
$p[':priority'] = NULL;
}
$p[':started'] = gpc_get_datetime($_POST, 'started');
$p[':finished'] = gpc_get_datetime($_POST, 'finished');
$p[':taskstate'] = gpc_get_enum($_POST, 'taskstate', array_keys($opt_state));
db_exec_update('task', $p, 'taskid');
$action = ACT_VIEW;
break;
case 'delete':
// Only captain is allowed to delete
if ($user->role != 'captain') {
$g_warning->Add('Only captain is allowed to delete tasks.');
$action = ACT_VIEW;
break;
}
// 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 possible redirect
$sth = $pdo->prepare("SELECT projid FROM task WHERE taskid=?");
$sth->execute([$id]);
$task = $sth->fetch(PDO::FETCH_OBJ);
if (isset($task->projid)) {
$backlink = 'project.php?id='.$task->projid;
}
// now really delete
$sth = $pdo->prepare("DELETE FROM task WHERE taskid=?");
$sth->execute([$id]);
$g_success->Add(_('Task deleted'));
if (isset($backlink)) {
header_location($backlink, ['info' => _('Note deleted.')]);
}
$action = ACT_DEFAULT;
break;
default:
@@ -71,20 +112,82 @@ require 'header.php';
if ($action == ACT_DEFAULT):
// ========== VARIANT: default behavior =======================================
echo "<h1>$pagetitle</h1>\n";
page_caption_search($pagetitle);
// load filter from db
$flt = db_get_filter($user->id, 206);
$w = array('(t.vid=:vid OR t.vid IS NULL)');
$p = array(':vid' => $user->vid);
if (strlen($flt->txt) > 1) {
$w[] = '(taskname LIKE :txt)';
$p[':txt'] = '%'.$flt->txt.'%';
}
if (strlen($flt->prio) > 2 ) {
$w[] = 'priority=:priority';
$p[':priority'] = $flt->prio;
} elseif ($flt->prio == -1) {
$w[] = 'priority IS NULL';
}
if (strlen($flt->stat) > 2 ) {
$w[] = 'taskstate=:taskstate';
$p[':taskstate'] = $flt->stat;
}
$where = join(' AND ', $w);
$order = ' ORDER BY t.taskid';
// get total recond count for pagination and limit
$sql = "SELECT COUNT(*) FROM task";
if ($where) $sql .= " WHERE $where";
$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";
$sth = $pdo->prepare($sql);
try {
$sth->execute([$user->vid]);
$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);
$sql = "SELECT t.taskid, t.vid, t.projid, t.taskname, t.priority, t.taskstate,"
. " p.projname "
. "FROM task AS t LEFT JOIN project AS p USING (projid) "
. "WHERE $where";
if ($order) $sql .= $order;
// if pagination:
// $sql .= ' LIMIT ' . ($page - 1) * $g_rows_pp . ',' . $g_rows_pp;
$sth = $pdo->prepare($sql);
try {
$sth->execute($p);
} catch (PDOexception $e) {
$g_error->Add('SQL-Error: '. $e->getMessage());
$g_error->Add($sql);
$g_error->Add(print_r($p, true));
}
$res = $sth->fetchAll();
?>
<form method="post" action="<?=$g_scriptname?>">
<div id="filter" class="card">
<div class="card-header">Filter</div>
<div class="card-body">
<?php
filter_create_select('flt_prio', _('Priority'), $g_opt_all + $g_opt_none + $opt_priority, $flt->prio);
filter_create_select('flt_stat', _('State'), $g_opt_all + $opt_state, $flt->stat);
?>
<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>
<input type="reset" class="btn btn-sm btn-secondary" value="<?=_('Clear')?>">
</div>
</div>
</form>
<?php
echo '<table class="table table-striped">', "\n";
echo "<thead>\n";
echo "<tr>\n";
@@ -92,16 +195,19 @@ echo '<th>#</th>';
echo '<th>', _('Task'), "</th>";
echo '<th>', _('Project'), "</th>";
echo '<th>', _('Priority'), "</th>";
echo '<th>', _('Status'), "</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";
// mark generic tasks with braces
echo "<td>", $row['vid'] ? $row['taskid'] : '('.$row['taskid'].')', "</td>\n";
echo "<td>", $row['taskname'], "</td>\n";
echo "<td>", $row['projname'], "</td>\n";
echo "<td>", ($opt_priority[$row['priority']] ?? ''), "</td>\n";
echo "<td>", ($opt_state[$row['taskstate']]), "</td>\n";
// Action buttons
form_action_buttons($g_scriptname, $row['taskid']);
echo "</tr>\n";
@@ -141,7 +247,7 @@ elseif ($action == ACT_VIEW):
// ========== VARIANT: view single record =====================================
$sql = "SELECT t.taskname, t.priority, t.plandate, t.duedate,"
. " t.started, t.finished, p.projname "
. " t.started, t.finished, t.taskstate, p.projname "
. "FROM task AS t LEFT JOIN project AS p USING (projid) "
. "WHERE taskid=?";
$sth = $pdo->prepare($sql);
@@ -150,18 +256,19 @@ $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 style="width:20%;">', _('Task'),"</th><td>", $task->taskname, "</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 '<tr><th>', _('Status'),"</th><td>", $opt_state[$task->taskstate], "</td></tr>\n";
echo "</table>\n";
form_view_buttons($g_scriptname, $id);
echo "<h3>Annotations</h3>";
echo '<h3>', _('Annotations'), "</h3>";
$sql = "SELECT noteid, annotation "
. "FROM note "
@@ -184,13 +291,14 @@ echo '<a href="note.php?f=add&t=task&id=', $id, '" class="btn btn-primary" role=
echo _('Add note'), "</a>\n";
echo "</div>\n";
echo "<h3>Documents</h3>";
echo "<p>Not yet implemented</p>";
echo '<h3>', _('Documents'), "</h3>";
echo '<p>', _('Not yet implemented'), "</p>";
elseif ($action == ACT_EDIT):
// ========== VARIANT: edit single record =====================================
$sql = "SELECT taskname, projid, priority, plandate, duedate, started, finished "
$sql = "SELECT taskname, projid, priority, plandate, duedate, started, finished,"
. " taskstate "
. "FROM task "
. "WHERE taskid=?";
$sth = $pdo->prepare($sql);
@@ -228,13 +336,26 @@ form_create_select('priority', _('Priority'), $opt_none + $opt_priority, $task->
<input type="datetime-local" class="form-control" id="finished" name="finished" value="<?=$task->finished ?>">
</div>
<?php
form_create_select('taskstate', _('Status'), $opt_state, $task->taskstate);
form_edit_buttons($g_scriptname, $id);
echo "</form>\n";
elseif ($action == ACT_DELETE):
// ========== VARIANT: delete record ==========================================
$sql = "SELECT taskname FROM task WHERE taskid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
$task = $sth->fetch(PDO::FETCH_OBJ);
echo '<h2>', _('Delete Task'), "</h2>\n";
echo '<p>', sprintf(_('Task no. %d'), $id), "</p>\n";
echo '<p>', $task->taskname, "</p>";
echo '<p>', _('Deleting a task 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 ===========================================