Webgui: More mobile friendly touch and much more improvements

This commit is contained in:
2026-06-14 10:56:17 +02:00
parent a59f02e21b
commit f109e2621f
25 changed files with 1624 additions and 583 deletions
+3
View File
@@ -3,3 +3,6 @@ Prototype
Many features are incomplete, buggy or missing. Many features are incomplete, buggy or missing.
Use at your own risk! Use at your own risk!
If inserting a new user you have also to insert a setting value
to assign boat 0.
+29 -10
View File
@@ -8,7 +8,7 @@ CREATE TABLE user (
login varchar(20) NOT NULL, login varchar(20) NOT NULL,
pass binary(60) NOT NULL, pass binary(60) NOT NULL,
displayname varchar(100) NOT NULL, displayname varchar(100) NOT NULL,
role set('vessel', 'captain','helmsman','sailor') NOT NULL DEFAULT 'sailor', role enum('vessel','captain','helmsman','sailor') NOT NULL DEFAULT 'sailor',
flags set('deleted','locked'), flags set('deleted','locked'),
language char(2) NOT NULL DEFAULT 'en', language char(2) NOT NULL DEFAULT 'en',
PRIMARY KEY (userid), PRIMARY KEY (userid),
@@ -48,7 +48,7 @@ CREATE TABLE dropdown (
ddtext varchar(50) NOT NULL, ddtext varchar(50) NOT NULL,
ddshort varchar(4) DEFAULT NULL, ddshort varchar(4) DEFAULT NULL,
color char(6) DEFAULT NULL, color char(6) DEFAULT NULL,
flags enum('locked', 'fixed') DEFAULT NULL, flags enum('locked','fixed') DEFAULT NULL,
PRIMARY KEY (ddid, ddval) PRIMARY KEY (ddid, ddval)
); );
@@ -77,13 +77,15 @@ CREATE TABLE storage (
sname varchar(40) NOT NULL, sname varchar(40) NOT NULL,
stype tinyint(3) NOT NULL DEFAULT 0, stype tinyint(3) NOT NULL DEFAULT 0,
capacity smallint(6) DEFAULT NULL, capacity smallint(6) DEFAULT NULL,
capaunit enum('kg', 'l') DEFAULT NULL, capaunit enum('kg','l') DEFAULT NULL,
x smallint(6) UNSIGNED NOT NULL DEFAULT 0, x smallint(6) UNSIGNED NOT NULL DEFAULT 0,
y smallint(6) NOT NULL DEFAULT 0, y smallint(6) NOT NULL DEFAULT 0,
z smallint(6) NOT NULL DEFAULT 0, z smallint(6) NOT NULL DEFAULT 0,
wx smallint(6) UNSIGNED NOT NULL DEFAULT 0, wx smallint(6) UNSIGNED NOT NULL DEFAULT 0,
wy smallint(6) UNSIGNED NOT NULL DEFAULT 0, wy smallint(6) UNSIGNED NOT NULL DEFAULT 0,
wz smallint(6) UNSIGNED NOT NULL DEFAULT 0, wz smallint(6) UNSIGNED NOT NULL DEFAULT 0,
angle smallint(4) NOT NULL DEFAULT 0,
color char(6) DEFAULT NULL,
remarks varchar(150) DEFAULT NULL, remarks varchar(150) DEFAULT NULL,
PRIMARY KEY (sid) PRIMARY KEY (sid)
); );
@@ -137,7 +139,7 @@ CREATE TABLE equipment (
price decimal(12,2) DEFAULT NULL, price decimal(12,2) DEFAULT NULL,
weight float(5,2) UNSIGNED DEFAULT NULL, weight float(5,2) UNSIGNED DEFAULT NULL,
remarks varchar(150) DEFAULT NULL, remarks varchar(150) DEFAULT NULL,
flags set('ordered','deleted') DEFAULT NULL, flags set('ordered','removed','deleted') DEFAULT NULL,
PRIMARY KEY(eid) PRIMARY KEY(eid)
); );
@@ -157,16 +159,19 @@ CREATE TABLE inventory (
PRIMARY KEY (invid), PRIMARY KEY (invid),
INDEX ix_invname (invname) INDEX ix_invname (invname)
); );
/*
TODO: unit -> unit1, unit2, unit3
*/
CREATE TABLE measurement ( CREATE TABLE measurement (
mid smallint(6) NOT NULL AUTO_INCREMENT, mid smallint(6) NOT NULL AUTO_INCREMENT,
mtype enum('generic','cable','fuse') NOT NULL default 'generic',
mname varchar(80) NOT NULL, mname varchar(80) NOT NULL,
nval tinyint(1) UNSIGNED NOT NULL DEFAULT 1, nval tinyint(1) UNSIGNED NOT NULL DEFAULT 1,
val1 int(10) NOT NULL, val1 int(10) NOT NULL,
val2 int(10) NOT NULL, val2 int(10) NOT NULL,
val3 int(10) NOT NULL, val3 int(10) NOT NULL,
unit tinyint(3) NOT NULL DEFAULT 1, unit tinyint(3) NOT NULL DEFAULT 1,
accuracy enum('unknown', 'precise', 'normal', 'rough', 'estimated') NOT NULL DEFAULT 'unknown', accuracy enum('unknown','precise','normal','rough','estimated') NOT NULL DEFAULT 'unknown',
mdate date DEFAULT NULL, mdate date DEFAULT NULL,
note varchar(80) DEFAULT NULL, note varchar(80) DEFAULT NULL,
eid smallint(6) DEFAULT NULL, eid smallint(6) DEFAULT NULL,
@@ -178,7 +183,10 @@ CREATE TABLE provisions (
provname varchar(40) NOT NULL, provname varchar(40) NOT NULL,
provcat tinyint(3) DEFAULT NULL, provcat tinyint(3) DEFAULT NULL,
sid smallint(6) DEFAULT NULL, sid smallint(6) DEFAULT NULL,
boxid smallint(6) NOT NULL DEFAULT 1,
number smallint(6) UNSIGNED NOT NULL DEFAULT 1, number smallint(6) UNSIGNED NOT NULL DEFAULT 1,
weight float(5,2) UNSIGNED DEFAULT NULL,
weight_net float(5,2) UNSIGNED DEFAULT NULL,
unit tinyint(3) DEFAULT NULL, unit tinyint(3) DEFAULT NULL,
storedate date DEFAULT CURRENT_DATE, storedate date DEFAULT CURRENT_DATE,
shelflife date DEFAULT NULL, shelflife date DEFAULT NULL,
@@ -187,7 +195,7 @@ CREATE TABLE provisions (
CREATE TABLE document ( CREATE TABLE document (
docid smallint(6) NOT NULL AUTO_INCREMENT, docid smallint(6) NOT NULL AUTO_INCREMENT,
doctype enum('generic', 'manual', 'invoice', 'drawing', 'picture') NOT NULL DEFAULT 'generic', doctype enum('generic','manual','invoice','drawing','picture') NOT NULL DEFAULT 'generic',
mimetype varchar(80) NOT NULL DEFAULT 'application/octet-stream', mimetype varchar(80) NOT NULL DEFAULT 'application/octet-stream',
filename varchar(200) NOT NULL, filename varchar(200) NOT NULL,
extension char(3) NOT NULL, extension char(3) NOT NULL,
@@ -197,13 +205,14 @@ CREATE TABLE document (
title varchar(40) DEFAULT NULL, title varchar(40) DEFAULT NULL,
pages smallint(6) unsigned NOT NULL DEFAULT 1, pages smallint(6) unsigned NOT NULL DEFAULT 1,
remarks varchar(150) DEFAULT NULL, remarks varchar(150) DEFAULT NULL,
roleaccess enum('captain','helmsman','sailor','unauth') NOT NULL DEFAULT 'captain',
PRIMARY KEY (docid), PRIMARY KEY (docid),
UNIQUE INDEX ix_hash (hash) UNIQUE INDEX ix_hash (hash)
) ENGINE=InnoDB; ) ENGINE=InnoDB;
CREATE TABLE docref ( CREATE TABLE docref (
drid int(10) NOT NULL AUTO_INCREMENT, drid int(10) NOT NULL AUTO_INCREMENT,
reftype enum('vessel', 'box', 'equipment', 'project', 'task', 'user', 'company') NOT NULL DEFAULT 'vessel', reftype enum('vessel','box','equipment','project','task','user','company') NOT NULL DEFAULT 'vessel',
docid smallint(6) NOT NULL, docid smallint(6) NOT NULL,
refid smallint(6) NOT NULL, refid smallint(6) NOT NULL,
PRIMARY KEY (drid), PRIMARY KEY (drid),
@@ -270,7 +279,8 @@ CREATE TABLE task (
projid smallint(6) DEFAULT NULL, projid smallint(6) DEFAULT NULL,
taskname varchar(60) NOT NULL, taskname varchar(60) NOT NULL,
priority enum('high','medium','low') DEFAULT NULL, priority enum('high','medium','low') DEFAULT NULL,
taskstate enum('pending','waiting','deleted','completed') NOT NULL DEFAULT 'pending', taskstate enum('pending','active','waiting','deleted','completed') NOT NULL DEFAULT 'pending',
state_ts timestamp DEFAULT NULL,
plandate date DEFAULT NULL, plandate date DEFAULT NULL,
duedate date DEFAULT NULL, duedate date DEFAULT NULL,
started datetime DEFAULT NULL, started datetime DEFAULT NULL,
@@ -280,9 +290,10 @@ CREATE TABLE task (
PRIMARY KEY (taskid) PRIMARY KEY (taskid)
); );
// Notes can be assigned to tasks,maintenances and equipment
CREATE TABLE note ( CREATE TABLE note (
noteid int(10) NOT NULL AUTO_INCREMENT, noteid int(10) NOT NULL AUTO_INCREMENT,
notetype enum('task','maint') NOT NULL DEFAULT 'task', notetype enum('task','maint','equip') NOT NULL DEFAULT 'task',
refid smallint(6) NOT NULL, refid smallint(6) NOT NULL,
annotation text NOT NULL, annotation text NOT NULL,
PRIMARY KEY (noteid) PRIMARY KEY (noteid)
@@ -291,6 +302,7 @@ CREATE TABLE note (
CREATE TABLE checklist ( CREATE TABLE checklist (
clid smallint(6) NOT NULL AUTO_INCREMENT, clid smallint(6) NOT NULL AUTO_INCREMENT,
title varchar(30) NOT NULL, title varchar(30) NOT NULL,
parent smallint(6) DEFAULT NULL,
clstate enum('new','open','closed') NOT NULL DEFAULT 'new', clstate enum('new','open','closed') NOT NULL DEFAULT 'new',
PRIMARY KEY (clid) PRIMARY KEY (clid)
); );
@@ -299,6 +311,7 @@ CREATE TABLE checkitem (
checkid int(10) NOT NULL AUTO_INCREMENT, checkid int(10) NOT NULL AUTO_INCREMENT,
checkname varchar(60) NOT NULL, checkname varchar(60) NOT NULL,
groupid tinyint(3) DEFAULT NULL, groupid tinyint(3) DEFAULT NULL,
checkresult enum('unchecked','checked','unused') NOT NULL DEFAULT 'unused',
PRIMARY KEY (checkid) PRIMARY KEY (checkid)
); );
@@ -308,3 +321,9 @@ CREATE TABLE checkref (
sort smallint(6) DEFAULT NULL, sort smallint(6) DEFAULT NULL,
PRIMARY KEY (clid, checkid) PRIMARY KEY (clid, checkid)
); );
CREATE TABLE checkgroup (
groupid int(10) NOT NULL,
title varchar(30) NOT NULL,
PRIMARY KEY (groupid)
);
+9 -3
View File
@@ -12,13 +12,19 @@ INSERT INTO user (userid, login, pass, displayname, role) VALUES
(1, 'captain', '$2y$10$naVMnC4S6bZ3IakxLJPJK.iSazlkYxVLeiRt9CB/j0jSExQZU1SCK', 'Captain', 'captain'); (1, 'captain', '$2y$10$naVMnC4S6bZ3IakxLJPJK.iSazlkYxVLeiRt9CB/j0jSExQZU1SCK', 'Captain', 'captain');
INSERT INTO settings (userid, sno, valint) VALUES INSERT INTO settings (userid, sno, valint) VALUES
(0, 0, 1), -- Databankschema-Version (0, 0, 1), -- Database schema version
(0, 1, 0), -- Keine Bootszuordnung für SYSTEM (0, 1, 0), -- No vessel assignment to SYSTEM
(1, 1, 0); -- Keine Bootszuordnung für Benutzer "captain" (1, 1, 0), -- No vessel assignment to user "captain"
(0, 20, 1280), -- Image width limit
(0, 21, 1024); -- Image height limit
/* setting descriptions */ /* setting descriptions */
INSERT INTO settings (userid, sno, valstr) VALUES INSERT INTO settings (userid, sno, valstr) VALUES
(-1, 1, 'vessel id'), (-1, 1, 'vessel id'),
(-1, 2, 'date format'),
(-1, 10, 'rows in table'),
(-1, 20, 'maximum image width'),
(-1, 21, 'maximum image height'),
(-1, 100, 'equipment sorting order'), (-1, 100, 'equipment sorting order'),
(-1, 101, 'inventory sorting order'), (-1, 101, 'inventory sorting order'),
(-1, 102, 'provision sorting order'), (-1, 102, 'provision sorting order'),
+37 -15
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: YMS 0.1\n" "Project-Id-Version: YMS 0.1\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-05-15 09:05+0200\n" "POT-Creation-Date: 2026-05-07 11:50+0200\n"
"PO-Revision-Date: 2025-05-15 09:05+0200\n" "PO-Revision-Date: 2025-05-15 09:05+0200\n"
"Last-Translator: Thomas Hooge <thomas@hoogi.de>\n" "Last-Translator: Thomas Hooge <thomas@hoogi.de>\n"
"Language-Team: de <thomas@hoogi.de>\n" "Language-Team: de <thomas@hoogi.de>\n"
@@ -16,11 +16,11 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
#: ymsgui.py:98 #: ymsgui.py:150
msgid "Configuration file not found" msgid "Configuration file not found"
msgstr "Konfigurationsdatei nicht gefunden" msgstr "Konfigurationsdatei nicht gefunden"
#: ymsgui.py:110 #: ymsgui.py:172
msgid "Database connection cannot be established" msgid "Database connection cannot be established"
msgstr "Datenbankverbindung kann nicht hergestellt werden" msgstr "Datenbankverbindung kann nicht hergestellt werden"
@@ -28,46 +28,68 @@ msgstr "Datenbankverbindung kann nicht hergestellt werden"
msgid "YMS" msgid "YMS"
msgstr "" msgstr ""
#: yms/ui/main.ui:27 #: yms/ui/main.ui:28
msgid "empty" msgid "empty"
msgstr "leer" msgstr "leer"
#: yms/ui/main.ui:55 #: yms/ui/main.ui:56
msgid "Name" msgid "Name"
msgstr "" msgstr ""
#: yms/ui/main.ui:76 #: yms/ui/main.ui:77
msgid "Model" msgid "Model"
msgstr "Modell" msgstr "Modell"
#: yms/ui/main.ui:109 #: yms/ui/main.ui:119
msgid "Vessel" msgid "Vessel"
msgstr "Boot" msgstr "Boot"
#: yms/ui/main.ui:138 #: yms/ui/main.ui:148
msgid "Lists" msgid "Lists"
msgstr "Listen" msgstr "Listen"
#: yms/ui/main.ui:173 #: yms/ui/main.ui:186
msgid "Ok" msgid "Ok"
msgstr "" msgstr ""
#: yms/ui/main.ui:194 #: yms/ui/main.ui:207
msgid "User" msgid "User"
msgstr "Benutzer" msgstr "Benutzer"
#: yms/ui/main.ui:207 #: yms/ui/main.ui:220
msgid "Base data" msgid "Base data"
msgstr "Basisdaten" msgstr "Basisdaten"
#: yms/ui/main.ui:217 yms/ui/main.ui:238 #: yms/ui/main.ui:230
msgid "label" msgid ""
"Equipment\n"
"Here be dragons"
msgstr "" msgstr ""
#: yms/ui/main.ui:227 #: yms/ui/main.ui:241
msgid "Equipment" msgid "Equipment"
msgstr "Ausrüstung" msgstr "Ausrüstung"
#: yms/ui/main.ui:248 #: yms/ui/main.ui:252
msgid "label"
msgstr ""
#: yms/ui/main.ui:262
msgid "Inventory" msgid "Inventory"
msgstr "Inventar" msgstr "Inventar"
#: yms/ui/main.ui:292
msgid "Provisions"
msgstr "Verpflegung"
#: yms/ui/main.ui:322
msgid "Maintenance"
msgstr "Wartung"
#: yms/ui/main.ui:352
msgid "Projects"
msgstr "Projekte"
#: yms/ui/main.ui:382
msgid "Documents"
msgstr "Dokumente"
+24 -8
View File
@@ -1,11 +1,18 @@
<?php <?php
/****************************************************************************** /******************************************************************************
* YMS - Yacht Management Software * YMS - Yacht Management Software
* Copyright (C) 2024 Thomas Hooge * Copyright (C) 2024-2026 Thomas Hooge
* *
* SPDX-License-Identifier: WTFPL * SPDX-License-Identifier: WTFPL
******************************************************************************/ ******************************************************************************/
/*
Box weight can be entered directly and is meant as weight of box itself plus
weights of contained items.
The weight of the contained items can be displayed separately
There can be a difference because not all items have a weight entered
*/
require 'globals.inc'; require 'globals.inc';
$pagetitle = _('Boxes'); $pagetitle = _('Boxes');
@@ -79,21 +86,30 @@ $res = $sth->fetchAll();
echo '<table class="table table-striped">', "\n"; echo '<table class="table table-striped">', "\n";
echo "<thead>\n"; echo "<thead>\n";
echo "<tr>"; echo "<tr>";
echo "<th>" . _('Label') . "</th>"; echo '<th>#</th>';
echo "<th>" . _('Type') . "</th>"; echo "<th>", _('Label'), "</th>";
echo "<th>" . _('Color') . "</th>"; echo "<th>", _('Type'), "</th>";
echo "<th>" . _('Content') . "</th>"; echo "<th>", _('Color'), "</th>";
echo "<th>", _('Content'), "</th>";
echo '<th class="text-end">', _('Weight'), "</th>"; echo '<th class="text-end">', _('Weight'), "</th>";
echo "<td></td>"; echo "<td></td>";
echo "</tr>\n"; echo "</tr>\n";
$i = 0;
foreach ($res as $row) { foreach ($res as $row) {
$i++; // record number
echo "<tr>\n"; echo "<tr>\n";
echo '<td>', $i;
echo '<a class="text-nowrap" title="', _('View'), '" href="', $g_scriptname, '?f=view&id=', $row['boxid'], '"><i class="bi bi-eye ms-2"></i></a>', "\n";
echo "</td>\n";
echo '<td>', $row['label'], "</td>\n"; echo '<td>', $row['label'], "</td>\n";
echo '<td>', ($opt_boxtype[$row['boxtype']] ?? ''), "</td>\n"; echo '<td>', ($opt_boxtype[$row['boxtype']] ?? ''), "</td>\n";
echo '<td>', format_color(strtoupper($row['color'])), "</td>\n"; echo '<td>', format_color(strtoupper($row['color'])), "</td>\n";
echo '<td>', $row['content'], "</td>\n"; echo '<td>', $row['content'], "</td>\n";
echo '<td class="text-end">', format_float($row['weight'], 2), "</td>\n"; echo '<td class="text-end">', format_float($row['weight'], 2), "</td>\n";
form_action_buttons($g_scriptname, $row['boxid']); // Edit current record button
echo "<td>";
echo '<a title="', _('Edit'), '" href="', $g_scriptname, '?f=edit&id=', $row['boxid'], '"><i class="bi-pencil"></i></a>', "\n";
echo "</td>\n";
echo "</tr>\n"; echo "</tr>\n";
} }
// Table summary // Table summary
@@ -110,7 +126,7 @@ elseif ($action == ACT_ADD):
echo '<h2>', _('Add Box'), "</h2>\n"; echo '<h2>', _('Add Box'), "</h2>\n";
?> ?>
<form method="post" action="<?=$g_Scriptname?>"> <form method="post" action="<?=$g_scriptname?>">
<div class="mb-3"> <div class="mb-3">
<label for="label" class="form-label"><?=_('Label')?></label> <label for="label" class="form-label"><?=_('Label')?></label>
<input type="text" maxlength="20" class="form-control" id="label" name="label" autofocus> <input type="text" maxlength="20" class="form-control" id="label" name="label" autofocus>
@@ -143,7 +159,7 @@ foreach ($opt_storage as $k => $v) {
elseif ($action == ACT_VIEW): elseif ($action == ACT_VIEW):
// ========== VARIANT: view single record ===================================== // ========== VARIANT: view single record =====================================
$sql = "SELECT boxtype, label, content, color, weight, box.remarks, box.sid, sname " $sql = "SELECT boxtype, label, content, box.color, weight, box.remarks, box.sid, sname "
. "FROM box LEFT JOIN storage USING (sid) " . "FROM box LEFT JOIN storage USING (sid) "
. "WHERE boxid=?"; . "WHERE boxid=?";
$sth = $pdo->prepare($sql); $sth = $pdo->prepare($sql);
+7
View File
@@ -127,6 +127,13 @@ $checklist = $sth->fetch(PDO::FETCH_OBJ);
</table> </table>
<?php <?php
/*
$sql = "SELECT checkname, groupid FROM checkitem";
$sql = "SELECT clid, checkid, sort FROM checkref";
*/
form_view_buttons($g_scriptname, $id); form_view_buttons($g_scriptname, $id);
elseif ($action == ACT_EDIT): elseif ($action == ACT_EDIT):
+16 -8
View File
@@ -126,10 +126,12 @@ try {
$g_error->Add($e->getMessage()); $g_error->Add($e->getMessage());
$g_error->Add($sql); $g_error->Add($sql);
$g_error->Add(print_r($p, true)); $g_error->Add(print_r($p, true));
$g_error->PrintOut();
} }
$numrows = $sth->fetchColumn(); $numrows = $sth->fetchColumn();
$lastpage = ceil($numrows/$g_rows_pp);
$page = gpc_get_int($_REQUEST, 'p', 1); $page = gpc_get_int($_REQUEST, 'p', 1);
$rows_pp = gpc_get_int($_REQUEST, 'n', $g_rows_pp);
$lastpage = ceil($numrows/$rows_pp);
$sql = "SELECT compid, compname, comptype, remarks " $sql = "SELECT compid, compname, comptype, remarks "
. "FROM company"; . "FROM company";
@@ -156,7 +158,7 @@ $opt_special = array(
?> ?>
<form method="post" action="<?=$g_scriptname?>"> <form method="post" action="<?=$g_scriptname?>">
<div id="filter" class="card"> <div id="filter" class="card">
<div class="card-header">Filter</div> <div class="card-header"><i class="bi bi-funnel me-2"></i>Filter</div>
<div class="card-body"> <div class="card-body">
<label for="flt_type">Type</label> <label for="flt_type">Type</label>
<select id="flt_type" name="flt_type"> <select id="flt_type" name="flt_type">
@@ -187,27 +189,33 @@ echo $pagination;
echo '<table class="table table-striped">', "\n"; echo '<table class="table table-striped">', "\n";
echo "<thead>\n"; echo "<thead>\n";
echo "<tr>"; echo "<tr>";
echo '<th>#</th>';
echo "<th>" . _('Name') . "</th>"; echo "<th>" . _('Name') . "</th>";
echo "<th>" . _('Type') . "</th>"; echo "<th>" . _('Type') . "</th>";
echo "<th>" . _('Remarks') . "</th>"; echo "<th>" . _('Remarks') . "</th>";
echo "<th>&nbsp;</th>"; echo "<th>&nbsp;</th>";
echo "</tr>\n"; echo "</tr>\n";
echo "</thead>\n"; echo "</thead>\n";
$i = ($page - 1) * $rows_pp;
$i0 = $i + 1;
foreach ($res as $row) { foreach ($res as $row) {
$i++; // record number
echo "<tr>\n"; echo "<tr>\n";
echo "<td>". $row['compname'] ."</td>\n"; echo '<td>', $i;
echo "<td>". $opt_comptype[$row['comptype']] ."</td>\n"; echo '<a title="', _('View'), '" href="', $g_scriptname, '?f=view&id=', $row['compid'], '"><i class="bi bi-eye ms-2"></i></a>', "\n";
echo "<td>". $row['remarks'] ."</td>\n"; echo "</td>\n";
// Action buttons echo "<td>", $row['compname'], "</td>\n";
echo "<td>", $opt_comptype[$row['comptype']], "</td>\n";
echo "<td>", $row['remarks'], "</td>\n";
// Edit current record button
echo "<td>"; echo "<td>";
echo '<a title="', _('View'), '" href="', $g_scriptname, '?f=view&id=', $row['compid'], '"><i class="bi-eye"></i></a>', "\n";
echo '<a title="', _('Edit'), '" href="', $g_scriptname, '?f=edit&id=', $row['compid'], '"><i class="bi-pencil"></i></a>'; echo '<a title="', _('Edit'), '" href="', $g_scriptname, '?f=edit&id=', $row['compid'], '"><i class="bi-pencil"></i></a>';
echo "</td>\n"; echo "</td>\n";
echo "</tr>\n"; echo "</tr>\n";
} }
// Table summary // Table summary
echo "<tfoot>\n"; echo "<tfoot>\n";
echo '<tr><td colspan="6">', sprintf(_('%d records out of total %d'), count($res), $grandtotal), '</td></tr>', "\n"; echo '<tr><td colspan="6">', sprintf(_('Records %d to %d of %d'), $i0, $i, $numrows), '</td></tr>', "\n";
echo "</tfoot>\n"; echo "</tfoot>\n";
echo "</table>\n"; echo "</table>\n";
+1 -1
View File
@@ -7,7 +7,7 @@
******************************************************************************/ ******************************************************************************/
/* Document Downloader /* Document Downloader
Doucuments are not directly accessible via filesystem Documents are not directly accessible via filesystem
dl.php must be used with "docid" as parameter: e.g, dl.php?id=23 dl.php must be used with "docid" as parameter: e.g, dl.php?id=23
In additional parameter "t" (thumb) is set a thumbnail will be returned In additional parameter "t" (thumb) is set a thumbnail will be returned
Possible values are: s (small), m (medium), l (large) Possible values are: s (small), m (medium), l (large)
+42 -12
View File
@@ -1,7 +1,7 @@
<?php <?php
/****************************************************************************** /******************************************************************************
* YMS - Yacht Management Software * YMS - Yacht Management Software
* Copyright (C) 2024-2025 Thomas Hooge * Copyright (C) 2024-2026 Thomas Hooge
* *
* SPDX-License-Identifier: WTFPL * SPDX-License-Identifier: WTFPL
******************************************************************************/ ******************************************************************************/
@@ -222,6 +222,8 @@ page_caption_search($pagetitle);
$flt = db_get_filter($user->id, 209); $flt = db_get_filter($user->id, 209);
// $w = array('(vid=:vid OR vid IS NULL)');
// $p = array(':vid' => $user->vid);
$w = array(); $w = array();
$p = array(); $p = array();
if (isset($flt->doctype) and $flt->doctype != 'all') { if (isset($flt->doctype) and $flt->doctype != 'all') {
@@ -244,8 +246,28 @@ if (strlen($flt->txt) > 1) {
$where = join(' AND ', $w); $where = join(' AND ', $w);
$order = ' ORDER BY docid'; $order = ' ORDER BY docid';
/*
WIP
Attention: Do not count duplicate, so first select docid from different sources
an as laststep get a distinct list of docids to count.
Documents with no reference at all
SELECT docid FROM document LEFT OUTER JOIN docref USING (docid) WHERE docref.drid IS NULL;
Documents for current vessel
SELECT docid FROM document LEFT OUTER JOIN docref USING (docid) WHERE docref.reftype='vessel' AND docref.refid=:vid
Documents for equipment in current vessel
SELECT DISTINCT d.docid AS docid FROM document AS d
LEFT OUTER JOIN docref AS r USING (docid) LEFT OUTER JOIN equipment AS e ON (r.refid=e.eid)
WHERE r.reftype='equipment' AND e.vid=:vid
*/
// get total recond count for pagination and limit // get total recond count for pagination and limit
$sql = "SELECT COUNT(*) FROM document LEFT OUTER JOIN docref USING (docid)"; $sql = "SELECT COUNT(DISTINCT docid) FROM document LEFT OUTER JOIN docref USING (docid)";
if ($where) $sql .= ' WHERE ' . $where; if ($where) $sql .= ' WHERE ' . $where;
$sth = $pdo->prepare($sql); $sth = $pdo->prepare($sql);
try { try {
@@ -254,10 +276,12 @@ try {
$g_error->Add($e->getMessage()); $g_error->Add($e->getMessage());
$g_error->Add($sql); $g_error->Add($sql);
$g_error->Add(print_r($p, true)); $g_error->Add(print_r($p, true));
$g_error->PrintOut();
} }
$numrows = $sth->fetchColumn(); $numrows = $sth->fetchColumn();
$lastpage = ceil($numrows/$g_rows_pp);
$page = gpc_get_int($_REQUEST, 'p', 1); $page = gpc_get_int($_REQUEST, 'p', 1);
$rows_pp = gpc_get_int($_REQUEST, 'n', $g_rows_pp);
$lastpage = ceil($numrows/$rows_pp);
$sql = "SELECT d.docid, d.doctype, d.filename, d.title, COUNT(r.drid) AS refcount " $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)"; . "FROM document AS d LEFT OUTER JOIN docref AS r USING (docid)";
@@ -279,7 +303,7 @@ $opt_special = array(
?> ?>
<form method="post" action="<?=$g_scriptname?>"> <form method="post" action="<?=$g_scriptname?>">
<div id="filter" class="card"> <div id="filter" class="card">
<div class="card-header">Filter</div> <div class="card-header"><i class="bi bi-funnel me-2"></i>Filter</div>
<div class="card-body"> <div class="card-body">
<label for="flt_doctype">Type</label> <label for="flt_doctype">Type</label>
<select id="flt_doctype" name="flt_doctype"> <select id="flt_doctype" name="flt_doctype">
@@ -323,7 +347,7 @@ echo $pagination;
echo '<table class="table table-striped">', "\n"; echo '<table class="table table-striped">', "\n";
echo "<thead>\n"; echo "<thead>\n";
echo "<tr>"; echo "<tr>";
echo "<th>", _('ID'), "</th>"; echo '<th>#</th>';
echo "<th>", _('Type'), "</th>"; echo "<th>", _('Type'), "</th>";
echo "<th>", _('Filename'), "</th>"; echo "<th>", _('Filename'), "</th>";
echo "<th>", _('Title'), "</th>"; echo "<th>", _('Title'), "</th>";
@@ -331,23 +355,28 @@ echo "<th>", _('Links'), "</th>";
echo "<th>&nbsp;</th>"; echo "<th>&nbsp;</th>";
echo "</tr>\n"; echo "</tr>\n";
echo "</thead>\n"; echo "</thead>\n";
$i = ($page - 1) * $rows_pp;
$i0 = $i + 1;
foreach ($res as $row) { foreach ($res as $row) {
$i++; // record number
echo "<tr>\n"; echo "<tr>\n";
echo "<td>", $row['docid'], "</td>\n"; echo "<td>", $i;
echo '<a title="', _('View'), '" href="', $g_scriptname, '?f=view&id=', $row['docid'], '"><i class="bi-eye ms-2"></i></a>', "\n";
echo "</td>\n";
echo "<td>", $opt_doctype[$row['doctype']], "</td>\n"; echo "<td>", $opt_doctype[$row['doctype']], "</td>\n";
echo "<td>", $row['filename'], "</td>\n"; echo "<td>", $row['filename'], "</td>\n";
echo "<td>", $row['title'], "</td>\n"; echo "<td>", $row['title'], "</td>\n";
echo "<td>", $row['refcount'], "</td>\n"; echo "<td>", $row['refcount'], "</td>\n";
// Action buttons // Edit current record button
echo "<td>"; echo "<td>";
echo '<a title="', _('View'), '" href="', $g_scriptname, '?f=view&id=', $row['docid'], '"><i class="bi-eye"></i></a>', "\n";
echo '<a title="', _('Edit'), '" href="', $g_scriptname, '?f=edit&id=', $row['docid'], '"><i class="bi-pencil"></i></a>', "\n"; echo '<a title="', _('Edit'), '" href="', $g_scriptname, '?f=edit&id=', $row['docid'], '"><i class="bi-pencil"></i></a>', "\n";
echo "</td>\n"; echo "</td>\n";
echo "</tr>\n"; echo "</tr>\n";
} }
// Table summary // Table summary
echo "<tfoot>\n"; echo "<tfoot>\n";
echo '<tr><td colspan="6">', sprintf(_('%d records'), count($res)), '</td></tr>', "\n"; echo '<tr><td colspan="6">', sprintf(_('Records %d to %d of %d'), $i0, $i, $numrows), '</td></tr>', "\n";
echo "</tfoot>\n"; echo "</tfoot>\n";
echo "</table>\n"; echo "</table>\n";
@@ -402,7 +431,7 @@ elseif ($action == ACT_VIEW):
/* mutool: preview of page thumbs */ /* mutool: preview of page thumbs */
$sql = "SELECT docid, doctype, mimetype, filename, extension, hash," $sql = "SELECT docid, doctype, mimetype, filename, extension, hash,"
. " docsize, doctime, title, pages, remarks " . " docsize, doctime, title, pages, remarks, roleaccess "
. "FROM document " . "FROM document "
. "WHERE docid=?"; . "WHERE docid=?";
$sth = $pdo->prepare($sql); $sth = $pdo->prepare($sql);
@@ -428,13 +457,14 @@ if ($document->doctype == 'picture') {
echo '</div>'; // gallery echo '</div>'; // gallery
?> ?>
<div class="modal fade" id="imageModal" tabindex="-1" aria-labelledby="imageModalLabel" aria-hidden="true"> <div class="modal fade" id="imageModal" tabindex="-1" aria-labelledby="imageModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered"> <div class="modal-dialog modal-dialog-centered custom-image-modal">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<?=$document->title;?>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<img src="dl.php?id=<?=$document->docid ?>"> <img src="dl.php?id=<?=$document->docid ?>" class="preview-image">
</div> </div>
</div> </div>
</div> </div>
+69 -23
View File
@@ -1,7 +1,7 @@
<?php <?php
/****************************************************************************** /******************************************************************************
* YMS - Yacht Management Software * YMS - Yacht Management Software
* Copyright (C) 2024, 2025 Thomas Hooge * Copyright (C) 2024-2026 Thomas Hooge
* *
* SPDX-License-Identifier: WTFPL * SPDX-License-Identifier: WTFPL
******************************************************************************/ ******************************************************************************/
@@ -222,6 +222,9 @@ if (strlen($flt->txt) > 1) {
$w[] = '(ename LIKE :txt OR model LIKE :txt OR remarks LIKE :txt)'; $w[] = '(ename LIKE :txt OR model LIKE :txt OR remarks LIKE :txt)';
$p[':txt'] = '%'.$flt->txt.'%'; $p[':txt'] = '%'.$flt->txt.'%';
} }
// TODO flags (ordered, removed, deleted)
// if (strlen($flt->flags) > 0) {
// }
$where = join(' AND ', $w); $where = join(' AND ', $w);
$order = ' ORDER BY ename'; $order = ' ORDER BY ename';
@@ -233,19 +236,22 @@ try {
$g_error->Add($e->getMessage()); $g_error->Add($e->getMessage());
$g_error->Add($sql); $g_error->Add($sql);
$g_error->Add(print_r($p, true)); $g_error->Add(print_r($p, true));
$g_error->PrintOut();
} }
$numrows = $sth->fetchColumn(); $numrows = $sth->fetchColumn();
$lastpage = ceil($numrows/$g_rows_pp); $lastpage = ceil($numrows/$g_rows_pp);
$page = gpc_get_int($_REQUEST, 'p', 1); $page = gpc_get_int($_REQUEST, 'p', 1);
// TODO check against allowed values for rows per page
$rows_pp = gpc_get_int($_REQUEST, 'n', $g_rows_pp);
$sql = "SELECT eid, ename, manufacturer, model, serial, remarks," $sql = "SELECT eid, ename, manufacturer, model, serial, remarks, flags,"
. " TIMESTAMPDIFF(MONTH, purchdate, NOW()) AS age_mon " . " TIMESTAMPDIFF(MONTH, purchdate, NOW()) AS age_mon "
. "FROM equipment"; . "FROM equipment";
$sql .= ' WHERE ' . $where; $sql .= ' WHERE ' . $where;
$sql .= $order; $sql .= $order;
// if pagination: // if pagination:
$sql .= ' LIMIT ' . ($page - 1) * $g_rows_pp . ',' . $g_rows_pp; $sql .= ' LIMIT ' . ($page - 1) * $rows_pp . ',' . $rows_pp;
$sth = $pdo->prepare($sql); $sth = $pdo->prepare($sql);
$sth->execute($p); $sth->execute($p);
@@ -260,18 +266,28 @@ $opt_none_male = array(-1 => pgettext('male', '&horbar; none &horbar;'));
?> ?>
<form method="post" action="<?=$g_scriptname?>"> <form method="post" action="<?=$g_scriptname?>">
<div id="filter" class="card"> <div id="filter" class="card">
<div class="card-header">Filter</div> <div class="card-header"><i class="bi bi-funnel me-2"></i>Filter</div>
<div class="card-body"> <div class="card-body d-flex flex-wrap gap-3">
<?php <?php
filter_create_select('flt_category', _('Category'), $g_opt_all + $g_opt_none + $opt_ecat, $flt->cat); 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_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); filter_create_select('flt_supp', _('Supplier'), $g_opt_all + $opt_none_male + $opt_supplier, $flt->supp);
?> ?>
<label for="flt_txt"><?=_('Text')?></label> <div class="d-flex flex-nowrap gap-2">
<input type="text" name="flt_txt" size="15" maxlength="30" value="<?=$flt->txt?>"> <label for="flt_txt"><?=_('Text')?></label>
<button name="submit[filter]" class="btn btn-sm btn-primary" title="<?=_('Apply')?>"><?=_('Go')?></button> <input type="text" name="flt_txt" size="15" maxlength="30" value="<?=$flt->txt ?>">
<button name="submit[freset]" class="btn btn-sm btn-secondary float-end" title="<?=_('Reset filter to defaults')?>"><?=_('Clear')?></button> </div>
</div> <div class="d-flex flex-nowrap gap-2">
<?php
$enum_data = db_load_enum('equipment', 'flags', true, true, false);
form_create_checks('flags', _('Flags'), $enum_data, []);
?>
</div>
</div>
<div class="card-footer">
<button name="submit[filter]" class="btn btn-sm btn-primary" title="<?=_('Apply')?>"><?=_('Go')?></button>
<button name="submit[freset]" class="btn btn-sm btn-secondary float-end" title="<?=_('Reset filter to defaults')?>"><?=_('Clear')?></button>
</div>
</div> </div>
</form> </form>
@@ -284,6 +300,7 @@ echo $pagination;
echo '<table class="table table-striped">', "\n"; echo '<table class="table table-striped">', "\n";
echo "<thead>\n"; echo "<thead>\n";
echo '<tr>'; echo '<tr>';
echo '<th>#</th>';
echo '<th>', _('Description'), "</th>"; echo '<th>', _('Description'), "</th>";
echo '<th>', _('Manufacturer'), "</th>"; echo '<th>', _('Manufacturer'), "</th>";
echo '<th>', _('Model'), "</th>"; echo '<th>', _('Model'), "</th>";
@@ -293,6 +310,8 @@ echo '<th>', _('Remarks'), "</th>";
echo "<th>&nbsp;</th>"; echo "<th>&nbsp;</th>";
echo "</tr>\n"; echo "</tr>\n";
echo "</thead>\n"; echo "</thead>\n";
$i = ($page - 1) * $rows_pp;
$i0 = $i + 1;
foreach ($res as $row) { foreach ($res as $row) {
// calc nice age display // calc nice age display
if (!isset($row['age_mon'])) { if (!isset($row['age_mon'])) {
@@ -302,19 +321,26 @@ foreach ($res as $row) {
} else { } else {
$age = sprintf(_('%dy'), intdiv($row['age_mon'], 12)); $age = sprintf(_('%dy'), intdiv($row['age_mon'], 12));
} }
$i++; // record number
echo "<tr>\n"; echo "<tr>\n";
echo "<td>", $i;
echo '<a class="text-nowrap" title="', _('View'), '" href="', $g_scriptname, '?f=view&id=', $row['eid'], '"><i class="bi bi-eye ms-2"></i></a>', "\n";
echo "</td>\n";
echo "<td>", $row['ename'], "</td>\n"; echo "<td>", $row['ename'], "</td>\n";
echo "<td>", ($opt_manufacturer[$row['manufacturer']] ?? ''), "</td>\n"; echo "<td>", ($opt_manufacturer[$row['manufacturer']] ?? ''), "</td>\n";
echo "<td>", $row['model'], "</td>\n"; echo "<td>", $row['model'], "</td>\n";
echo "<td>", $row['serial'], "</td>\n"; echo "<td>", $row['serial'], "</td>\n";
echo "<td>", $age, "</td>\n"; echo "<td>", $age, "</td>\n";
echo "<td>", $row['remarks'], "</td>\n"; echo "<td>", $row['remarks'], "</td>\n";
// Action buttons // Edit current record button
form_action_buttons($g_scriptname, $row['eid']); echo "<td>";
echo '<a title="', _('Edit'), '" href="', $g_scriptname, '?f=edit&id=', $row['eid'], '"><i class="bi-pencil"></i></a>', "\n";
echo "</td>\n";
echo "</tr>\n";
} }
?> ?>
<tfoot> <tfoot>
<tr><td colspan="6"><?php printf(_('%d records of %d'), count($res), $numrows); ?></td></tr> <tr><td colspan="8"><?php printf(_('Records %d to %d of %d'), $i0, $i, $numrows); ?></td></tr>
</tfoot> </tfoot>
</table> </table>
<?php <?php
@@ -344,7 +370,7 @@ form_create_select('manufacturer', _('Manufacturer'), $opt_manufacturer, $flt->m
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label for="remarks" class="form-label"><?=_('Remarks')?></label> <label for="remarks" class="form-label"><?=_('Remarks')?></label>
<textarea class="form-control" id="remarks" name="remarks" rows="3"></textarea> <textarea class="form-control" id="remarks" name="remarks" rows="3" maxlength="150"></textarea>
</div> </div>
<div class="container-fluid px-0 my-3"> <div class="container-fluid px-0 my-3">
<button type="submit" name="submit[insert]" class="btn btn-primary"><?=_('Save')?></button> <button type="submit" name="submit[insert]" class="btn btn-primary"><?=_('Save')?></button>
@@ -356,7 +382,7 @@ elseif ($action == ACT_VIEW):
// ========== VARIANT: view single record ===================================== // ========== VARIANT: view single record =====================================
$sql = "SELECT eid, ename, model, serial, purchdate, price, weight, " $sql = "SELECT eid, ename, model, serial, purchdate, price, weight, "
. " supplier, manufacturer, ecat, shortname, remarks " . " supplier, manufacturer, ecat, shortname, remarks, flags "
. "FROM equipment " . "FROM equipment "
. "WHERE eid=?"; . "WHERE eid=?";
$sth = $pdo->prepare($sql); $sth = $pdo->prepare($sql);
@@ -371,7 +397,9 @@ echo '<div class="col">';
echo '<table class="table">', "\n"; echo '<table class="table">', "\n";
echo '<tr><th>', _('Short name'),"</th><td>", $equipment->shortname, "</td></tr>\n"; echo '<tr><th>', _('Short name'),"</th><td>", $equipment->shortname, "</td></tr>\n";
echo '<tr><th>', _('Manufacturer'),"</th><td>", $opt_manufacturer[$equipment->manufacturer], "</td></tr>\n"; echo '<tr><th>', _('Manufacturer'),"</th><td>", $opt_manufacturer[$equipment->manufacturer];
echo '&nbsp;<a title="', _('View'), '" href="company.php?f=view&id=', $equipment->manufacturer, '"><i class="bi-eye"></i></a>';
echo "</td></tr>\n";
echo '<tr><th>', _('Model'),"</th><td>", $equipment->model, "</td></tr>\n"; echo '<tr><th>', _('Model'),"</th><td>", $equipment->model, "</td></tr>\n";
echo '<tr><th>', _('Serial'),"</th><td>", $equipment->serial, "</td></tr>\n"; 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>', _('Weight'),"</th><td>", format_float($equipment->weight, 2, 'kg'), "</td></tr>\n";
@@ -379,14 +407,17 @@ echo '<tr><th>', _('Price'),"</th><td>", format_currency($equipment->price), "</
echo '<tr><th>', _('Purchase date'),"</th><td>", $equipment->purchdate, "</td></tr>\n"; echo '<tr><th>', _('Purchase date'),"</th><td>", $equipment->purchdate, "</td></tr>\n";
echo '<tr><th>', _('Supplier'),"</th><td>", $equipment->supplier ? $opt_supplier[$equipment->supplier] : 'n/a', "</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>', _('Category'),"</th><td>", $opt_ecat[$equipment->ecat], "</td></tr>\n";
echo '<tr><th>', _('Remarks'),"</th><td>", $equipment->remarks, "</td></tr>\n"; echo '<tr><th>', _('Remarks'),"</th><td>", nl2br($equipment->remarks), "</td></tr>\n";
echo '<tr><th>', _('Flags'),"</th><td>", $equipment->flags, "</td></tr>\n";
echo "</table>\n"; echo "</table>\n";
echo '</div>'; // Column break echo '</div>'; // Column break
echo '<div class="col">'; echo '<div class="col">', "\n";
?>
<p>Images and documents go here</p> echo '<div class="card">', "\n";
<?php echo '<div class="card-header">', _('Images and documents'), "</div>\n";
echo '<div class="card-body">', "\n";
$sql = "SELECT d.docid, d.doctype, d.title " $sql = "SELECT d.docid, d.doctype, d.title "
. "FROM docref AS r INNER JOIN document AS d using (docid) " . "FROM docref AS r INNER JOIN document AS d using (docid) "
. "WHERE r.reftype='equipment' AND r.refid=? " . "WHERE r.reftype='equipment' AND r.refid=? "
@@ -394,31 +425,46 @@ $sql = "SELECT d.docid, d.doctype, d.title "
$sth = $pdo->prepare($sql); $sth = $pdo->prepare($sql);
$sth->execute([$id]); $sth->execute([$id]);
$res = $sth->fetchAll(); $res = $sth->fetchAll();
// TODO hübsche Darstellung
$doccount = 0;
foreach ($res as $row) { foreach ($res as $row) {
$doccount += 1;
if ($row['doctype'] == 'picture') { if ($row['doctype'] == 'picture') {
echo '<a href="dl.php?id=', $row['docid'], '">'; echo '<a href="dl.php?id=', $row['docid'], '">';
// echo '<img width="120" src="doc/pic-', $row['hash'], '.', $row['extension'],'">'; // echo '<img width="120" src="doc/pic-', $row['hash'], '.', $row['extension'],'">';
echo '<img width="120" src="dl.php?id=', $row['docid'], '" alt="', $row['title'], '">'; echo '<img width="120" src="dl.php?id=', $row['docid'], '" alt="', $row['title'], '">';
echo "</a>\n"; echo "</a>\n";
} elseif ($row['doctype'] == 'drawing') {
echo "<p>Drawing: ", $row['title'], "<br>";
echo '<a href="dl.php?id=', $row['docid'], '">';
echo '<img width="180" src="dl.php?id=', $row['docid'], '">';
echo "</a>";
echo "</p>\n";
} elseif ($row['doctype'] == 'generic') { } elseif ($row['doctype'] == 'generic') {
echo '<a href="dl.php?id=', $row['docid'], '">'; echo '<a href="dl.php?id=', $row['docid'], '">';
echo '<img width="120" src="dl.php?id=', $row['docid'], '&t=s" alt="', $row['title'], '">'; echo '<img width="120" src="dl.php?id=', $row['docid'], '&t=s" alt="', $row['title'], '">';
// echo $row['title']; // echo $row['title'];
echo "</a>\n"; echo "</a>\n";
} elseif ($row['doctype'] == 'manual') { } elseif ($row['doctype'] == 'manual') {
echo "Manual: "; echo "<p>Manual: ";
echo '<a href="documents.php?f=view&id=', $row['docid'], '">'; echo '<a href="documents.php?f=view&id=', $row['docid'], '">';
echo $row['title']; echo $row['title'];
echo "</a>\n"; echo "</a></p>\n";
} else { } else {
// unknown document type // unknown document type
echo "<span>Unknown document type:", $row['doctype'], "</span>\n"; echo "<span>Unknown document type:", $row['doctype'], "</span>\n";
} }
} }
if ($doccount == 0) {
echo _('No referenced documents'), "\n";
}
echo "</div>\n"; // card-body
echo "</div>\n"; // card
?> ?>
<form method="post" enctype="multipart/form-data" action="<?=$g_scriptname?>"> <form method="post" enctype="multipart/form-data" action="<?=$g_scriptname?>">
<input type="hidden" name="id" value="<?=$id?>"> <input type="hidden" name="id" value="<?=$id?>">
<div class="card"> <div class="card">
<div class="card-header"><?=_('Add Image');?></div>
<div class="card-body"> <div class="card-body">
<input type="file" name="files[]" multiple accept="image/*" capture="camera"> <input type="file" name="files[]" multiple accept="image/*" capture="camera">
<input type="submit" name="submit[upload]" value="Upload"> <input type="submit" name="submit[upload]" value="Upload">
+1 -1
View File
@@ -1,7 +1,7 @@
<?php <?php
/****************************************************************************** /******************************************************************************
* YMS - Yacht Management Software * YMS - Yacht Management Software
* Copyright (C) 2024-2025 Thomas Hooge * Copyright (C) 2024-2026 Thomas Hooge
* *
* SPDX-License-Identifier: WTFPL * SPDX-License-Identifier: WTFPL
****************************************************************************** ******************************************************************************
+2
View File
@@ -7,7 +7,9 @@
<title><?=APP_TITLE_SHORT?> - <?=$pagetitle?></title> <title><?=APP_TITLE_SHORT?> - <?=$pagetitle?></title>
<link href="bootstrap/css/bootstrap.min.css" rel="stylesheet"> <link href="bootstrap/css/bootstrap.min.css" rel="stylesheet">
<link href="bootstrap/bootstrap-icons.min.css" rel="stylesheet"> <link href="bootstrap/bootstrap-icons.min.css" rel="stylesheet">
<link href="css/choices.css" rel="stylesheet">
<script src="bootstrap/js/bootstrap.bundle.min.js"></script> <script src="bootstrap/js/bootstrap.bundle.min.js"></script>
<script src="js/choices.min.js"></script>
<link rel="stylesheet" href="default.css"> <link rel="stylesheet" href="default.css">
<?php <?php
if (isset($GLOBALS['local_script'])) { if (isset($GLOBALS['local_script'])) {
+13 -8
View File
@@ -1,7 +1,7 @@
<?php <?php
/****************************************************************************** /******************************************************************************
* YMS - Yacht Management Software * YMS - Yacht Management Software
* Copyright (C) 2024 Thomas Hooge * Copyright (C) 2024-2026 Thomas Hooge
* *
* SPDX-License-Identifier: WTFPL * SPDX-License-Identifier: WTFPL
******************************************************************************/ ******************************************************************************/
@@ -142,7 +142,7 @@ $vessel = $sth->fetch(PDO::FETCH_OBJ);
// Show remarks first // Show remarks first
if (strlen($vessel->remarks) > 0) { if (strlen($vessel->remarks) > 0) {
echo "<p>"; echo "<p>";
echo $vessel->remarks; echo nl2br($vessel->remarks);
echo "</p>\n"; echo "</p>\n";
} }
@@ -321,24 +321,28 @@ $sth->execute([$user->vid]);
echo '<tr><td>&nbsp;</td><td>', _('Boxes'), '</td><td>', $sth->fetchColumn(), "</td></tr>\n"; echo '<tr><td>&nbsp;</td><td>', _('Boxes'), '</td><td>', $sth->fetchColumn(), "</td></tr>\n";
// Equipment // Equipment
$sth = $pdo->prepare("SELECT COUNT(*) FROM equipment WHERE vid=?"); $sth = $pdo->prepare("SELECT COUNT(*), SUM(weight) FROM equipment WHERE vid=?");
$sth->execute([$user->vid]); $sth->execute([$user->vid]);
$row = $sth->fetch(PDO::FETCH_NUM);
echo '<tr><td colspan="3">', _('Equipment') , "</td>"; echo '<tr><td colspan="3">', _('Equipment') , "</td>";
echo '<tr><td>&nbsp;</td><td>', _('Count'), '</td><td>', $sth->fetchColumn(), "</td></tr>\n"; echo '<tr><td>&nbsp;</td><td>', _('Count'), '</td><td>', $row[0], "</td></tr>\n";
echo '<tr><td>&nbsp;</td><td>', _('Weight'), '</td><td>', format_float($row[1], 1, 'kg'), "</td></tr>\n";
// Inventory // Inventory
// All items from vessel storage and all items from boxes in vessel storage // All items from vessel storage and all items from boxes in vessel storage
$sql = "SELECT SUM(n) FROM (" $sql = "SELECT SUM(n), SUM(w) FROM ("
. "SELECT COUNT(*) AS n FROM inventory JOIN storage USING (sid) WHERE conttype='storage' AND vid=:vid " . "SELECT COUNT(*) AS n, SUM(i.weight * i.number) as w FROM inventory AS i JOIN storage USING (sid) WHERE conttype='storage' AND vid=:vid "
. "UNION " . "UNION "
. "SELECT COUNT(*) AS n FROM inventory JOIN box USING (boxid) JOIN storage ON (box.sid=storage.sid) WHERE conttype='box' AND vid=:vid" . "SELECT COUNT(*) AS n, SUM(i.weight * i.number) as w FROM inventory AS i JOIN box USING (boxid) JOIN storage ON (box.sid=storage.sid) WHERE conttype='box' AND vid=:vid"
. ") AS x"; . ") AS x";
$sth = $pdo->prepare($sql); $sth = $pdo->prepare($sql);
$sth->bindValue(':vid', $user->vid, PDO::PARAM_INT); $sth->bindValue(':vid', $user->vid, PDO::PARAM_INT);
$sth->execute(); $sth->execute();
$row = $sth->fetch(PDO::FETCH_NUM);
echo '<tr><td colspan="3">', _('Inventory') , "</td>"; echo '<tr><td colspan="3">', _('Inventory') , "</td>";
echo '<tr><td>&nbsp;</td><td>', _('Count'), '</td><td>', $sth->fetchColumn(), "</td></tr>\n"; echo '<tr><td>&nbsp;</td><td>', _('Count'), '</td><td>', $row[0], "</td></tr>\n";
echo '<tr><td>&nbsp;</td><td>', _('Weight'), '</td><td>', format_float($row[1], 1, 'kg'), "</td></tr>\n";
// Documents // Documents
$sth = $pdo->query("SELECT COUNT(*) FROM document"); $sth = $pdo->query("SELECT COUNT(*) FROM document");
@@ -368,6 +372,7 @@ echo "</table>\n";
<hr> <hr>
<h5 class="card-title"><?=_('Additional modules')?></h5> <h5 class="card-title"><?=_('Additional modules')?></h5>
<ul class="list-group list-group-flush"> <ul class="list-group list-group-flush">
<li class="list-group-item"><a href="settings.php"><?=_('Settings')?></a></li>
<li class="list-group-item"><a href="task.php"><?=_('Tasks')?></a></li> <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="measurement.php"><?=_('Measurements')?></a></li>
<li class="list-group-item"><a href="checklist.php"><?=_('Checklists')?></a></li> <li class="list-group-item"><a href="checklist.php"><?=_('Checklists')?></a></li>
+46 -23
View File
@@ -138,15 +138,17 @@ try {
$g_error->Add($e->getMessage()); $g_error->Add($e->getMessage());
$g_error->Add($sql); $g_error->Add($sql);
$g_error->Add(print_r($p, true)); $g_error->Add(print_r($p, true));
$g_error->PrintOut();
} }
$numrows = $sth->fetchColumn(); $numrows = $sth->fetchColumn();
$lastpage = ceil($numrows/$g_rows_pp);
$page = gpc_get_int($_REQUEST, 'p', 1); $page = gpc_get_int($_REQUEST, 'p', 1);
$rows_pp = gpc_get_int($_REQUEST, 'n', $g_rows_pp);
$lastpage = ceil($numrows/$rows_pp);
$sql = "SELECT i.invid, i.invname, i.number, i.invcond, s.sname AS container " $sql = "SELECT i.invid, i.invname, i.number, i.invcond, i.eid, s.sname AS container "
. "FROM inventory AS i JOIN storage AS s ON (i.conttype='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 .= ' WHERE ' . $where;
$sql .= " UNION SELECT i.invid, i.invname, i.number, i.invcond, b.label AS container " $sql .= " UNION SELECT i.invid, i.invname, i.number, i.invcond, i.eid, b.label AS container "
. "FROM inventory AS i JOIN box AS b ON (i.conttype='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) "; . " JOIN storage AS s ON (b.sid=s.sid) ";
$sql .= ' WHERE ' . $where; $sql .= ' WHERE ' . $where;
@@ -162,6 +164,7 @@ try {
$g_error->Add($e->getMessage()); $g_error->Add($e->getMessage());
$g_error->Add($sql); $g_error->Add($sql);
$g_error->Add(print_r($p, true)); $g_error->Add(print_r($p, true));
$g_error->PrintOut();
} }
$res = $sth->fetchAll(); $res = $sth->fetchAll();
@@ -173,16 +176,17 @@ $opt_special = array(
?> ?>
<form method="post" action="<?=$g_scriptname?>"> <form method="post" action="<?=$g_scriptname?>">
<div id="filter" class="card"> <div id="filter" class="card">
<div class="card-header">Filter</div> <div class="card-header"><i class="bi bi-funnel me-2"></i>Filter</div>
<div class="card-body"> <div class="card-body d-flex flex-wrap gap-3">
<?php <?php
// page specific filter start // page specific filter start
// - selection for storage // - selection for storage
// - selection for box // - selection for box
// page specific filter end // page specific filter end
?> ?>
<label for="flt_stor"><?=_('Storage')?></label> <div class="d-flex flex-nowrap gap-2">
<select id="flt_stor" name="flt_stor"> <label for="flt_stor"><?=_('Storage')?></label>
<select id="flt_stor" name="flt_stor">
<?php <?php
foreach ($opt_special + $opt_storage as $k => $v) { foreach ($opt_special + $opt_storage as $k => $v) {
echo '<option value="', $k,'"'; echo '<option value="', $k,'"';
@@ -192,9 +196,11 @@ foreach ($opt_special + $opt_storage as $k => $v) {
echo '>', $v, '</option>'; echo '>', $v, '</option>';
} }
?> ?>
</select> </select>
<label for="flt_cond"><?=_('Condition')?></label> </div>
<select id="flt_cond" name="flt_cond"> <div class="d-flex flex-nowrap gap-2">
<label for="flt_cond"><?=_('Condition')?></label>
<select id="flt_cond" name="flt_cond">
<?php <?php
$opt_special = array( $opt_special = array(
-2 => _('&horbar; all &horbar;'), -2 => _('&horbar; all &horbar;'),
@@ -207,12 +213,17 @@ foreach ($opt_special + $opt_invcond as $k => $v) {
echo '>', $v, '</option>'; echo '>', $v, '</option>';
} }
?> ?>
</select> </select>
<label for="flt_txt">Text</label> </div>
<input type="text" name="flt_txt" size="15" maxlength="30" value="<?=$flt->txt?>"> <div class="d-flex flex-nowrap gap-2">
<button name="submit[filter]" class="btn btn-sm btn-primary" title="<?=_('Apply')?>"><?=_('Go')?></button> <label for="flt_txt">Text</label>
<button name="submit[freset]" class="btn btn-sm btn-secondary float-end" title="<?=_('Reset filter to defaults')?>"><?=_('Clear')?></button> <input type="text" name="flt_txt" size="15" maxlength="30" value="<?=$flt->txt ?>">
</div> </div>
</div>
<div class="card-footer">
<button name="submit[filter]" class="btn btn-sm btn-primary" title="<?=_('Apply')?>"><?=_('Go')?></button>
<button name="submit[freset]" class="btn btn-sm btn-secondary float-end" title="<?=_('Reset filter to defaults')?>"><?=_('Clear')?></button>
</div>
</div> </div>
</form> </form>
@@ -224,6 +235,7 @@ echo $pagination;
echo '<table class="table table-striped">', "\n"; echo '<table class="table table-striped">', "\n";
echo "<thead>\n"; echo "<thead>\n";
echo "<tr>\n"; echo "<tr>\n";
echo '<th>#</th>';
echo "<th>", _('Name'), "</th>\n"; echo "<th>", _('Name'), "</th>\n";
echo "<th>", _('Container'), "</th>\n"; echo "<th>", _('Container'), "</th>\n";
echo "<th>", _('Number'), "</th>\n"; echo "<th>", _('Number'), "</th>\n";
@@ -232,19 +244,30 @@ echo "<th>", _('Tags'), "</th>\n";
echo "<td></td>\n"; echo "<td></td>\n";
echo "</tr>\n"; echo "</tr>\n";
echo "</thead>\n"; echo "</thead>\n";
$i = ($page - 1) * $rows_pp;
$i0 = $i + 1;
foreach ($res as $row) { foreach ($res as $row) {
$i++; // record number
echo "<tr>\n"; echo "<tr>\n";
echo '<td>', $row['invname'], "</td>\n"; echo '<td>', $i;
echo '<a class="text-nowrap" title="', _('View'), '" href="', $g_scriptname, '?f=view&id=', $row['invid'], '"><i class="bi bi-eye ms-2"></i></a>', "\n";
echo "</td>\n";
// alternative symbols: wrench, wrench-adjustable, tools
echo '<td>', $row['invname'];
echo isset($row['eid']) && $row['eid'] > 0 ? ' <i class="bi bi-wrench"></i>' : '', "</td>\n";
echo "<td>", $row['container'], "</td>\n"; echo "<td>", $row['container'], "</td>\n";
echo "<td>", $row['number'], "</td>\n"; echo "<td>", $row['number'], "</td>\n";
echo "<td>", ($opt_invcond[$row['invcond']] ?? ''), "</td>\n"; echo "<td>", ($opt_invcond[$row['invcond']] ?? ''), "</td>\n";
echo "<td>", _('No tags assigned'), "</td>\n"; echo "<td>", _('No tags assigned'), "</td>\n";
form_action_buttons($g_scriptname, $row['invid']); // Edit current record button
echo "<td>";
echo '<a title="', _('Edit'), '" href="', $g_scriptname, '?f=edit&id=', $row['invid'], '"><i class="bi-pencil"></i></a>', "\n";
echo "</td>\n";
echo "</tr>\n"; echo "</tr>\n";
} }
// Table summary // Table summary
echo "<tfoot>\n"; echo "<tfoot>\n";
echo '<tr><td colspan="5">', sprintf(_('%d records'), count($res)), '</td></tr>', "\n"; echo '<tr><td colspan="7">', sprintf(_('Records %d to %d of %d'), $i0, $i, $numrows), '</td></tr>', "\n";
echo "</tfoot>\n"; echo "</tfoot>\n";
echo "</table>\n"; echo "</table>\n";
@@ -274,8 +297,8 @@ echo '<h2>', _('Add Inventory'), "</h2>\n";
</select> </select>
</div> </div>
<?php <?php
form_create_select('sid', _('Storage'), $opt_storage); form_create_select('sid', _('Storage'), $g_opt_none + $opt_storage);
form_create_select('boxid', _('Box'), $opt_box); form_create_select('boxid', _('Box'), $g_opt_none + $opt_box);
?> ?>
<div class="container-fluid px-0 my-3"> <div class="container-fluid px-0 my-3">
<button type="submit" name="submit[insert]" class="btn btn-primary"><?=_('Save')?></button> <button type="submit" name="submit[insert]" class="btn btn-primary"><?=_('Save')?></button>
@@ -337,7 +360,7 @@ echo "<tr><th>", _('Weight'), "</th><td>", format_float($inventory->weight, 2, '
echo "<tr><th>", _('Price'), "</th><td>", format_currency($inventory->price), "</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>", _('Purchase date'), "</th><td>", $inventory->purchdate, "</td></tr>\n";
echo "<tr><th>", _('Condition'), "</th><td>", $opt_invcond[$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"; echo "<tr><th>", _('Remarks'), "</th><td>", nl2br($inventory->remarks), "</td></tr>\n";
$tags = db_load_taglist('inv', $id); $tags = db_load_taglist('inv', $id);
form_tag_assignment($g_scriptname, $id, $tags); form_tag_assignment($g_scriptname, $id, $tags);
@@ -377,7 +400,7 @@ $inventory = $sth->fetch(PDO::FETCH_OBJ);
$opt_conttype = db_load_enum('inventory', 'conttype', true, true); $opt_conttype = db_load_enum('inventory', 'conttype', true, true);
form_create_select('conttype', _('Container type'), $opt_conttype, $inventory->conttype); form_create_select('conttype', _('Container type'), $opt_conttype, $inventory->conttype);
form_create_select('sid', _('Storage'), $opt_storage, $inventory->sid); form_create_select('sid', _('Storage'), $opt_storage, $inventory->sid);
form_create_select('boxid', _('Box'), $opt_box, $inventory->boxid); form_create_select('boxid', _('Box'), $g_opt_none + $opt_box, $inventory->boxid);
?> ?>
<div class="mb-3"> <div class="mb-3">
<label for="price" class="form-label"><?=sprintf(_('Price, %s'), $g_lconv['currency_symbol']); ?></label> <label for="price" class="form-label"><?=sprintf(_('Price, %s'), $g_lconv['currency_symbol']); ?></label>
+966 -363
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.
+9 -5
View File
@@ -1,7 +1,7 @@
<?php <?php
/****************************************************************************** /******************************************************************************
* YMS - Yacht Management Software * YMS - Yacht Management Software
* Copyright (C) 2024 Thomas Hooge * Copyright (C) 2024-2026 Thomas Hooge
* *
* SPDX-License-Identifier: WTFPL * SPDX-License-Identifier: WTFPL
******************************************************************************/ ******************************************************************************/
@@ -33,6 +33,10 @@ if (isset($_POST['login'])) {
<link href="bootstrap/css/bootstrap.min.css" rel="stylesheet"> <link href="bootstrap/css/bootstrap.min.css" rel="stylesheet">
<link href="bootstrap/bootstrap-icons.min.css" rel="stylesheet"> <link href="bootstrap/bootstrap-icons.min.css" rel="stylesheet">
<script src="bootstrap/js/bootstrap.bundle.min.js"></script> <script src="bootstrap/js/bootstrap.bundle.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
});
</script>
</head> </head>
<body> <body>
<div class="container"> <div class="container">
@@ -70,10 +74,10 @@ if (isset($err)) {
<?=_('Login')?> <?=_('Login')?>
</button> </button>
</form> </form>
</div> <!-- card body --> </div> <?php /* card body */?>
</div> </div> <?php /* columns */?>
</div> </div> <?php /* rows */?>
</div> </div> <?phph /* card */?>
</section> </section>
</div> </div>
</body> </body>
+56 -16
View File
@@ -84,10 +84,11 @@ $opt_special = array(
?> ?>
<form method="post" action="<?=$g_scriptname?>"> <form method="post" action="<?=$g_scriptname?>">
<div id="filter" class="card"> <div id="filter" class="card">
<div class="card-header">Filter</div> <div class="card-header"><i class="bi bi-funnel me-2"></i>Filter</div>
<div class="card-body"> <div class="card-body d-flex flex-wrap gap-3">
<label for="flt_equip">Equipment</label> <div class="d-flex flex-nowrap gap-2">
<select id="flt_equip" name="flt_equip"> <label for="flt_equip">Equipment</label>
<select id="flt_equip" name="flt_equip">
<?php <?php
foreach ($opt_special + $opt_equipment as $k => $v) { foreach ($opt_special + $opt_equipment as $k => $v) {
echo '<option value="', $k,'"'; echo '<option value="', $k,'"';
@@ -97,9 +98,14 @@ foreach ($opt_special + $opt_equipment as $k => $v) {
echo '>', $v, '</option>'; echo '>', $v, '</option>';
} }
?> ?>
</select> </select>
<label for="flt_txt">Text</label> </div>
<input type="text" name="flt_txt" size="15" maxlength="30" value="<?=$flt->txt ?? ''?>"> <div class="d-flex flex-nowrap gap-2">
<label for="flt_txt">Text</label>
<input type="text" name="flt_txt" size="15" maxlength="30" value="<?=$flt->txt ?? ''?>">
</div>
</div>
<div class="card-footer">
<button name="submit[filter]" class="btn btn-sm btn-primary" title="<?=_('Apply')?>"><?=_('Go')?></button> <button name="submit[filter]" class="btn btn-sm btn-primary" title="<?=_('Apply')?>"><?=_('Go')?></button>
<button name="submit[freset]" class="btn btn-sm btn-secondary float-end" title="<?=_('Reset filter to defaults')?>"><?=_('Clear')?></button> <button name="submit[freset]" class="btn btn-sm btn-secondary float-end" title="<?=_('Reset filter to defaults')?>"><?=_('Clear')?></button>
</div> </div>
@@ -107,32 +113,66 @@ foreach ($opt_special + $opt_equipment as $k => $v) {
</form> </form>
<?php <?php
$sort = array(
1 => 'm.maintid',
2 => 'm.maintid DESC'
);
$w = array('m.vid=:vid');
$p = array(':vid' => $user->vid);
if ($flt->equip == -1 or $flt->equip == 0) {
$w[] = 'm.eid IS NULL';
} elseif ($flt->equip > 0) {
$w[] = 'm.eid=:eid';
$p[':eid'] = $flt->equip;
}
if (strlen($flt->txt) > 1) {
$w[] = '(m.activities LIKE :txt OR m.remarks LIKE :txt)';
$p[':txt'] = '%'.$flt->txt.'%';
}
$where = join(' AND ', $w);
$order = ' ORDER BY m.maintid';
$sql = "SELECT m.maintid, m.activities, m.remarks, e.ename " $sql = "SELECT m.maintid, m.activities, m.remarks, e.ename "
. "FROM maintenance AS m LEFT OUTER JOIN equipment AS e USING (eid)" . "FROM maintenance AS m LEFT OUTER JOIN equipment AS e USING (eid)";
. "WHERE m.vid=? " $sql .= ' WHERE ' . $where;
. "ORDER BY m.maintid"; $sql .= $order;
// if pagination:
// $sql .= ' LIMIT ' . ($page - 1) * $rows_pp . ',' . $rows_pp;
$sth = $pdo->prepare($sql); $sth = $pdo->prepare($sql);
$sth->execute([$user->vid]); $sth->execute($p);
$res = $sth->fetchAll(); $res = $sth->fetchAll();
echo '<table class="table table-striped">', "\n"; echo '<table class="table table-striped">', "\n";
echo "<thead>\n"; echo "<thead>\n";
echo "<tr>"; echo "<tr>";
echo '<th>#</th>';
echo "<th>", _('Activities'), "</th>"; echo "<th>", _('Activities'), "</th>";
echo "<th>", _('Equipment'), "</th>"; echo "<th>", _('Equipment'), "</th>";
echo "<th>", _('Remarks'), "</th>"; echo "<th>", _('Remarks'), "</th>";
echo "</tr>\n"; echo "</tr>\n";
echo "</thead>\n"; echo "</thead>\n";
$i = ($page - 1) * $rows_pp;
$i0 = $i + 1;
foreach ($res as $row) { foreach ($res as $row) {
$i++; // record number
echo "<tr>\n"; echo "<tr>\n";
echo '<td>', $i;
echo '<a title="', _('View'), '" href="', $g_scriptname, '?f=view&id=', $row['maintid'], '"><i class="bi-eye ms-2"></i></a>', "\n";
echo "</td>\n";
echo "<td>". $row['activities'] ."</td>\n"; echo "<td>". $row['activities'] ."</td>\n";
echo "<td>". $row['ename'] ."</td>\n"; echo "<td>". $row['ename'] ."</td>\n";
echo "<td>". $row['remarks'] ."</td>\n"; echo "<td>". $row['remarks'] ."</td>\n";
// Action buttons echo "<td>";
/* echo "<td>"; // Edit current record button
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 '<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"; echo "</tr>\n";
} }
// Table summary // Table summary
+21 -3
View File
@@ -13,6 +13,9 @@ require 'header.php';
?> ?>
<h1>Yacht Management System</h1> <h1>Yacht Management System</h1>
<p>Hinweis: Es handelt sich hier um einen Prototyp!</p>
<h2>Integriertes Handbuch</h2> <h2>Integriertes Handbuch</h2>
<p>Es können mehrere Yachten mit dem Programm verwaltet werden. <p>Es können mehrere Yachten mit dem Programm verwaltet werden.
@@ -47,6 +50,10 @@ Wasserlinie.</p>
<p>Ausrüstung ist zumeist fest mit der Yacht verbunden, jeder Ausrüstungsgegenstand <p>Ausrüstung ist zumeist fest mit der Yacht verbunden, jeder Ausrüstungsgegenstand
existiert nur ein mal und kann eine Seriennummer besitzen.</p> existiert nur ein mal und kann eine Seriennummer besitzen.</p>
<p>Ausrüstung kann gewartet werden.</p> <p>Ausrüstung kann gewartet werden.</p>
<p>Ein Ausrüstungsgegenstand kann als bestellt, entfernt oder gelöscht gekennzeichnet
werden. Entfernt bedeutet der Gegenstand ist noch vorhanden aber nicht auf dem
Boot installiert. Gelöschte Gegenstände werden bei der nächsten Reorganisation
komplett aus dem System entfernt.</p>
<h3>Inventar</h3> <h3>Inventar</h3>
<p>Unter Inventar sind bewegliche Dinge zusammengefaßt. <p>Unter Inventar sind bewegliche Dinge zusammengefaßt.
@@ -54,6 +61,8 @@ Ein Inventargegenstand kann auch mehrfach vorkommen.
Beispiel: <em>Winschkurbel, Anzahl: 3</em></p> Beispiel: <em>Winschkurbel, Anzahl: 3</em></p>
<p>Inventar kann in einem Stauraum abgelegt werden oder aber in einer <p>Inventar kann in einem Stauraum abgelegt werden oder aber in einer
Kiste.</p> Kiste.</p>
<p>Inventar welches einem Ausrüstungsgegenstand zugeordnet ist, wird
als Ersatzteil geführt.</p>
<h3>Proviant</h3> <h3>Proviant</h3>
<p>Proviant ist verderblich. <p>Proviant ist verderblich.
@@ -61,7 +70,9 @@ Es wird das Einlagerungsdatum erfaßt und das Haltbarkeitsdatum</p>
<p>Proviant kann einem Stauraum und somit einem Boot zugeordnet sein <p>Proviant kann einem Stauraum und somit einem Boot zugeordnet sein
oder aber <em>frei</em>. oder aber <em>frei</em>.
Freier Proviant kann später zugeordnet Freier Proviant kann später zugeordnet
werden. Er ist erkennbar am Einkaufswagen-Symbol <i class="bi bi-basket"></i>.<p> werden. Er ist erkennbar am Einkaufswagen-Symbol <i class="bi bi-cart3"></i>.<p>
<p>TODO/Noch nichtimplementiert: Proviant kann auch in eine Kiste gelegt werden</p>
<h3>Wartung</h3> <h3>Wartung</h3>
<p>Es können einmalige und wiederkehrende Wartungen erfaßt werden</p> <p>Es können einmalige und wiederkehrende Wartungen erfaßt werden</p>
@@ -74,8 +85,11 @@ z.B. <em>neu</em>, <em>laufend</em> oder <em>erledigt</em>.</p>
<h3>Aufgaben</h3> <h3>Aufgaben</h3>
<p>Aufgaben sind normalerweise den aktuell ausgewählten Boot zugeordnet, <p>Aufgaben sind normalerweise den aktuell ausgewählten Boot zugeordnet,
können aber auch bootsunabhängig angelegt werden. Eine projektzuordnung können aber auch bootsunabhängig angelegt werden. Eine Projektzuordnung
ist ebenfalls vorgesehen</p> ist ebenfalls vorgesehen.</p>
<p>Die Aufgaben sind nicht als Menüpunkt auf oberster Ebene vorhanden.
Die Aufgabenübersicht kann über Zusatzmodule auf der Startseine erreicht
werden.</p>
<h3>Firmen</h3> <h3>Firmen</h3>
<p>Es können verschiedene Arten von Firmen hinterlegt werden, wie <p>Es können verschiedene Arten von Firmen hinterlegt werden, wie
@@ -108,6 +122,10 @@ ist es möglich Flächen <span style="white-space:nowrap">(L x B)</span> oder
Volumen <span style="white-space:nowrap">(L x B x H)</span> zusammenhängend Volumen <span style="white-space:nowrap">(L x B x H)</span> zusammenhängend
zu erfassen.</p> zu erfassen.</p>
<h3>Notizen</h3>
<p>Notizen können für verschiedene Aufgaben und Wartungen hinterlegt werden.
Es handelt sich um die Eingabemöglichkeit in ein einzelnes Textfeld.</p>
<h3>Benutzer</h3> <h3>Benutzer</h3>
<p>Benutzer können nicht über die Web-GUI eingerichtet werden.</p> <p>Benutzer können nicht über die Web-GUI eingerichtet werden.</p>
<p>Es gibt die Berechtigungsebenen <em>Kapitän (captain)</em>, <p>Es gibt die Berechtigungsebenen <em>Kapitän (captain)</em>,
+5 -2
View File
@@ -11,6 +11,7 @@ $pagetitle = _('Measurements');
$id = gpc_get_int($_REQUEST, 'id', 0); $id = gpc_get_int($_REQUEST, 'id', 0);
$opt_mtype = db_load_enum('measurement', 'mtype', true, false);
$opt_unit = db_get_options(8); $opt_unit = db_get_options(8);
$opt_accuracy = array( $opt_accuracy = array(
'unknown' => _('Unknown'), 'unknown' => _('Unknown'),
@@ -147,9 +148,11 @@ $opt_special = array(
?> ?>
<form method="post" action="<?=$g_scriptname?>"> <form method="post" action="<?=$g_scriptname?>">
<div id="filter" class="card"> <div id="filter" class="card">
<div class="card-header">Filter</div> <div class="card-header"><i class="bi bi-funnel me-2"></i>Filter</div>
<div class="card-body"> <div class="card-body">
<?php
filter_create_select('flt_mtype', _('Type'), $g_opt_all + $g_opt_none + $opt_mtype);
?>
<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?>"> <input type="text" name="flt_txt" size="15" maxlength="30" value="<?=$flt->txt?>">
<button name="submit[filter]" class="btn btn-sm btn-primary" title="<?=_('Apply')?>"><?=_('Go')?></button> <button name="submit[filter]" class="btn btn-sm btn-primary" title="<?=_('Apply')?>"><?=_('Go')?></button>
+94 -26
View File
@@ -19,6 +19,18 @@ foreach ($sth->fetchAll() as $row) {
} }
$opt_state = db_load_enum('project', 'projstate', true, true); $opt_state = db_load_enum('project', 'projstate', true, true);
/* Nur für choices benötigt
$local_script = "
document.addEventListener('DOMContentLoaded', function () {
const element = document.getElementById('flt_state[]');
const choices = new Choices(element, {
removeItemButton: true,
duplicateItemsAllowed: false,
searchEnabled: false
});
});
"; */
// ========== ACTIONS START =================================================== // ========== ACTIONS START ===================================================
switch ($submit = form_get_action()) { switch ($submit = form_get_action()) {
@@ -33,7 +45,7 @@ switch ($submit = form_get_action()) {
case 'filter': case 'filter':
$flt = array(); $flt = array();
$flt['name'] = gpc_get_string($_POST, 'flt_name'); $flt['name'] = gpc_get_string($_POST, 'flt_name');
$flt['state'] = gpc_get_string($_POST, 'flt_state'); $flt['state'] = $_POST['flt_state']; // Array! gpc_get_string($_POST, 'flt_state');
$flt['remarks'] = gpc_get_string($_POST, 'flt_remarks'); $flt['remarks'] = gpc_get_string($_POST, 'flt_remarks');
db_save_filter($flt, 205); db_save_filter($flt, 205);
$action = ACT_DEFAULT; $action = ACT_DEFAULT;
@@ -95,45 +107,79 @@ page_caption_search($pagetitle);
// load filter from db // load filter from db
$flt = db_get_filter($user->id, 205); $flt = db_get_filter($user->id, 205);
$w = array(); // name, status, text
$p = array();
$w = array('vid=:vid');
$p = array(':vid' => $user->vid);
if (strlen($flt->txt) > 1) {
$w[] = '(projname LIKE :txt OR remarks LIKE :txt)';
$p[':txt'] = '%'.$flt->txt.'%';
}
$where = join(' AND ', $w); $where = join(' AND ', $w);
$order = ' ORDER BY comptype, compname'; $order = ' ORDER BY projname';
// grand total of records for current vessel // grand total of records for current vessel
$grandtotal = $pdo->query("SELECT COUNT(*) FROM project")->fetchColumn(); $sth = $pdo->prepare("SELECT COUNT(*) FROM project WHERE " . $where);
try {
$sth->execute($p);
} catch(PDOException $e) {
$g_error->Add($e->getMessage());
$g_error->Add($sql);
$g_error->Add(print_r($p, true));
$g_error->PrintOut();
}
$numrows = $sth->fetchColumn();
$page = gpc_get_int($_REQUEST, 'p', 1);
$rows_pp = gpc_get_int($_REQUEST, 'n', $g_rows_pp);
$lastpage = ceil($numrows/$rows_pp);
// $grandtotal = $pdo->query("SELECT COUNT(*) FROM project WHERE " . $where)->fetchColumn();
$sql = "SELECT projid, projname, startdate, duration, projstate, remarks "
. "FROM project";
$sql .= " WHERE " . $where;
$sql .= $order;
// if pagination:
$sql .= ' LIMIT ' . ($page - 1) * $g_rows_pp . ',' . $g_rows_pp;
$sth = $pdo->prepare($sql);
$sth->execute($p);
$res = $sth->fetchAll();
// Filter // Filter
?> ?>
<form method="post" action="<?=$g_scriptname?>"> <form id="filterform" method="post" action="<?=$g_scriptname?>">
<div id="filter" class="card"> <div id="filter" class="card">
<div class="card-header">Filter</div> <div class="card-header"><i class="bi bi-funnel me-2"></i>Filter</div>
<div class="card-body"> <div class="card-body d-flex flex-wrap gap-3">
<label for="flt_name">Name</label> <div class="d-flex flex-nowrap gap-2">
<input type="text" name="flt_name" size="15" maxlength="30" value="<?=$flt->name;?>"> <label for="flt_name">Name</label>
<input type="text" name="flt_name" size="15" maxlength="30" value="<?=$flt->name;?>">
</div>
<?php <?php
filter_create_select('flt_state', _('State'), $g_opt_all + $opt_state, $flt->state); filter_create_select('flt_state[]', _('State'), $g_opt_all + $opt_state, $flt->state, FALSE);
?> ?>
<label for="flt_remarks">Text</label> <div class="d-flex flex-nowrap gap-2">
<input type="text" name="flt_remarks" size="15" maxlength="30" value="<?=$flt->remarks?>"> <label for="flt_remarks">Text</label>
<button name="submit[filter]" class="btn btn-sm btn-primary" title="<?=_('Apply')?>"><?=_('Go')?></button> <input type="text" name="flt_remarks" size="15" maxlength="30" value="<?=$flt->remarks ?>">
<button name="submit[freset]" class="btn btn-sm btn-secondary float-end" title="<?=_('Reset filter to defaults')?>"><?=_('Clear')?></button> </div>
</div>
<div class="card-footer">
<button name="submit[filter]" class="btn btn-sm btn-primary" title="<?=_('Apply')?>"><?=_('Go')?></button>
<button name="submit[freset]" class="btn btn-sm btn-secondary float-end" title="<?=_('Reset filter to defaults')?>"><?=_('Clear')?></button>
</div> </div>
</div> </div>
</form> </form>
<?php <?php
$sql = "SELECT projid, projname, startdate, duration, projstate, remarks "
. "FROM project "
. "WHERE vid=? "
. "ORDER BY projid";
$sth = $pdo->prepare($sql);
$sth->execute([$user->vid]);
$res = $sth->fetchAll();
echo '<table class="table table-striped">'. "\n"; echo '<table class="table table-striped">'. "\n";
echo "<thead>\n"; echo "<thead>\n";
echo "<tr>"; echo "<tr>";
echo '<th>#</th>';
echo "<th>" . _('Name') . "</th>"; echo "<th>" . _('Name') . "</th>";
echo "<th>" . _('Start date') . "</th>"; echo "<th>" . _('Start date') . "</th>";
echo "<th>" . _('Duration') . "</th>"; echo "<th>" . _('Duration') . "</th>";
@@ -142,15 +188,24 @@ echo "<th>" . _('Remarks') . "</th>";
echo "<th>&nbsp;</th>"; echo "<th>&nbsp;</th>";
echo "</tr>\n"; echo "</tr>\n";
echo "</thead>\n"; echo "</thead>\n";
$i = ($page - 1) * $rows_pp;
$i0 = $i + 1;
foreach ($res as $row) { foreach ($res as $row) {
$i++; // record number
echo "<tr>\n"; echo "<tr>\n";
echo '<td>', $i;
echo '<a class="text-nowrap" title="', _('View'), '" href="', $g_scriptname, '?f=view&id=', $row['projid'], '"><i class="bi bi-eye ms-2"></i></a>', "\n";
echo "</td>\n";
echo "<td>". $row['projname'] ."</td>\n"; echo "<td>". $row['projname'] ."</td>\n";
echo "<td>". $row['startdate'] ."</td>\n"; echo "<td>". $row['startdate'] ."</td>\n";
echo "<td>". $row['duration'] ."</td>\n"; echo "<td>". $row['duration'] ."</td>\n";
echo "<td>". $row['projstate'] ."</td>\n"; echo "<td>". $row['projstate'] ."</td>\n";
echo "<td>". $row['remarks'] ."</td>\n"; echo "<td>". $row['remarks'] ."</td>\n";
// Action buttons // Edit current record button
form_action_buttons($g_scriptname, $row['projid']); echo "<td>";
echo '<a title="', _('Edit'), '" href="', $g_scriptname, '?f=edit&id=', $row['projid'], '"><i class="bi-pencil"></i></a>', "\n";
echo "</td>\n";
echo "</tr>\n"; echo "</tr>\n";
} }
echo "<tfoot>\n"; echo "<tfoot>\n";
@@ -172,15 +227,28 @@ $res = $sth->fetchAll();
echo '<table class="table table-striped">', "\n"; echo '<table class="table table-striped">', "\n";
echo "<thead>\n"; echo "<thead>\n";
echo "<tr>"; echo "<tr>";
echo '<th>#</th>';
echo "<th>" . _('Name') . "</th>"; echo "<th>" . _('Name') . "</th>";
echo "<th>" . _('State') . "</th>"; echo "<th>" . _('State') . "</th>";
echo "</tr>\n"; echo "</tr>\n";
echo "</thead>\n"; echo "</thead>\n";
// TODO own pagination
// $i = ($page - 1) * $rows_pp;
$i = 0;
$i0 = $i + 1;
foreach ($res as $row) { foreach ($res as $row) {
$i++; // record number
echo "<tr>\n"; echo "<tr>\n";
echo '<td>', $i;
echo '<a class="text-nowrap" title="', _('View'), '" href="task.php?f=view&id=', $row['taskid'], '"><i class="bi bi-eye ms-2"></i></a>', "\n";
echo "</td>\n";
echo "<td>". $row['taskname'] ."</td>\n"; echo "<td>". $row['taskname'] ."</td>\n";
echo "<td>". $row['taskstate'] ."</td>\n"; echo "<td>". $row['taskstate'] ."</td>\n";
form_action_buttons('task.php', $row['taskid']); // Edit current record button
echo "<td>";
echo '<a title="', _('Edit'), '" href="task.php?f=edit&id=', $row['taskid'], '"><i class="bi-pencil"></i></a>', "\n";
echo "</td>\n";
echo "</tr>\n"; echo "</tr>\n";
} }
// Table summary // Table summary
@@ -230,7 +298,7 @@ echo '<tr><th scope="row">', _('Responsible'),"</th><td>", $opt_user[$project->r
echo '<tr><th scope="row">', _('Start date'),"</th><td>", $project->startdate, "</td></tr>\n"; echo '<tr><th scope="row">', _('Start date'),"</th><td>", $project->startdate, "</td></tr>\n";
echo '<tr><th scope="row">', _('Duration'),"</th><td>", $project->duration, "</td></tr>\n"; echo '<tr><th scope="row">', _('Duration'),"</th><td>", $project->duration, "</td></tr>\n";
echo '<tr><th scope="row">', _('State'),"</th><td>", $project->projstate, "</td></tr>\n"; echo '<tr><th scope="row">', _('State'),"</th><td>", $project->projstate, "</td></tr>\n";
echo '<tr><th scope="row">', _('Remarks'),"</th><td>", $project->remarks, "</td></tr>\n"; echo '<tr><th scope="row">', _('Remarks'),"</th><td>", nl2br($project->remarks), "</td></tr>\n";
echo "</table>\n"; echo "</table>\n";
form_view_buttons($g_scriptname, $id); form_view_buttons($g_scriptname, $id);
+95 -25
View File
@@ -54,10 +54,13 @@ switch ($submit = form_get_action()) {
$p[':provname'] = gpc_get_string($_POST, 'provname'); $p[':provname'] = gpc_get_string($_POST, 'provname');
$p[':provcat'] = gpc_get_int($_POST, 'provcat'); $p[':provcat'] = gpc_get_int($_POST, 'provcat');
$p[':number'] = gpc_get_int($_POST, 'number'); $p[':number'] = gpc_get_int($_POST, 'number');
$p[':weight'] = min(gpc_get_float($_POST, 'weight'), 999.99); // limit max value
$p[':weight_net'] = min(gpc_get_float($_POST, 'weight_net'), 999.99);
$p[':unit'] = gpc_get_int($_POST, 'unit'); $p[':unit'] = gpc_get_int($_POST, 'unit');
$p[':storedate'] = gpc_get_string($_POST, 'storedate'); $p[':storedate'] = gpc_get_string($_POST, 'storedate');
$p[':shelflife'] = gpc_get_string($_POST, 'shelflife'); $p[':shelflife'] = gpc_get_string($_POST, 'shelflife');
$p[':sid'] = gpc_get_int($_POST, 'sid'); $p[':sid'] = gpc_get_int($_POST, 'sid');
if ($p[':sid'] <= 0) $p[':sid'] = NULL;
db_exec_update('provisions', $p, 'provid'); db_exec_update('provisions', $p, 'provid');
$action = ACT_VIEW; $action = ACT_VIEW;
break; break;
@@ -88,11 +91,19 @@ require 'header.php';
if ($action == ACT_DEFAULT): if ($action == ACT_DEFAULT):
// ========== VARIANT: default behavior ======================================= // ========== VARIANT: default behavior =======================================
page_caption_search($pagetitle);
// load filter from db // load filter from db
$flt = db_get_filter($user->id, 202); $flt = db_get_filter($user->id, 202);
$w = array('(vid=:vid OR sid IS NULL)'); $w = array('(vid=:vid OR sid IS NULL)');
$p = array(':vid' => $user->vid); $p = array(':vid' => $user->vid);
if ($flt->cat == -1) {
$w[] = 'provcat IS NULL';
} elseif ($flt->cat > 0) {
$w[] = 'provcat=:provcat';
$p[':provcat'] = $flt->cat;
}
if (strlen($flt->txt) > 1) { if (strlen($flt->txt) > 1) {
$w[] = 'provname LIKE :txt'; $w[] = 'provname LIKE :txt';
$p[':txt'] = '%'.$flt->txt.'%'; $p[':txt'] = '%'.$flt->txt.'%';
@@ -101,67 +112,116 @@ $where = join(' AND ', $w);
$order = ' ORDER BY provid'; $order = ' ORDER BY provid';
// get total record count for pagination and limit
$sql = "SELECT COUNT(*) FROM provisions LEFT OUTER JOIN storage USING (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));
$g_error->PrintOut();
}
$numrows = $sth->fetchColumn();
$page = gpc_get_int($_REQUEST, 'p', 1);
$rows_pp = gpc_get_int($_REQUEST, 'n', $g_rows_pp);
$lastpage = ceil($numrows/$rows_pp);
// provisions can be assigned to a store or be free // provisions can be assigned to a store or be free
// d0 is the maximum number of days age
// d1 is the current age in days. If negative then it is over limit
// TODO display over with warning levels: 50% over, 100% over etc.
$sql = "SELECT provid, provname, number, unit, storedate, shelflife, sid," $sql = "SELECT provid, provname, number, unit, storedate, shelflife, sid,"
. " DATEDIFF(shelflife, storedate) AS d0, DATEDIFF (CURDATE(), storedate) AS d1 " . " DATEDIFF(shelflife, storedate) AS d0, DATEDIFF (shelflife, CURDATE()) AS d1 "
. "FROM provisions LEFT OUTER JOIN storage USING (sid)"; . "FROM provisions LEFT OUTER JOIN storage USING (sid)";
$sql .= ' WHERE ' . $where; $sql .= ' WHERE ' . $where;
$sql .= $order; $sql .= $order;
// if pagination:
$sql .= ' LIMIT ' . ($page - 1) * $rows_pp . ',' . $rows_pp;
$sth = $pdo->prepare($sql); $sth = $pdo->prepare($sql);
$sth->execute($p); $sth->execute($p);
$res = $sth->fetchAll(); $res = $sth->fetchAll();
page_caption_search($pagetitle);
?> ?>
<form method="post" action="<?=$g_scriptname?>"> <form method="post" action="<?=$g_scriptname?>">
<div id="filter" class="card"> <div id="filter" class="card">
<div class="card-header">Filter</div> <div class="card-header"><i class="bi bi-funnel me-2"></i>Filter</div>
<div class="card-body"> <div class="card-body d-flex flex-wrap gap-3">
<?php <?php
filter_create_select('flt_cat', _('Category'), $g_opt_all + $g_opt_none + $opt_category, $flt->cat); filter_create_select('flt_cat', _('Category'), $g_opt_all + $g_opt_none + $opt_category, $flt->cat);
?> ?>
<label for="flt_txt">Text</label> <div class="d-flex flex-nowrap gap-2">
<input type="text" name="flt_txt" size="15" maxlength="30" value="<?=$flt->txt?>"> <label for="flt_txt">Text</label>
<button name="submit[filter]" class="btn btn-sm btn-primary" title="<?=_('Apply')?>"><?=_('Go')?></button> <input type="text" name="flt_txt" size="15" maxlength="30" value="<?=$flt->txt;?>">
<button name="submit[freset]" class="btn btn-sm btn-secondary float-end" title="<?=_('Reset filter to defaults')?>"><?=_('Clear')?></button> </div>
</div>
<div class="card-footer">
<button name="submit[filter]" class="btn btn-sm btn-primary" title="<?=_('Apply')?>"><?=_('Go')?></button>
<button name="submit[freset]" class="btn btn-sm btn-secondary float-end" title="<?=_('Reset filter to defaults')?>"><?=_('Clear')?></button>
</div> </div>
</div> </div>
</form> </form>
<?php <?php
// Pagination on top
$pagination = get_pagination($g_scriptname, '', $page, $lastpage);
echo $pagination;
echo '<table class="table table-striped">', "\n"; echo '<table class="table table-striped">', "\n";
echo "<thead>\n"; echo "<thead>\n";
echo "<tr>\n"; echo "<tr>\n";
echo '<th>#</th>';
echo '<th>', _('Description'), "</th>"; echo '<th>', _('Description'), "</th>";
echo '<th>', _('Number'), "</th>"; echo '<th>', _('Number'), "</th>";
echo '<th>', _('Unit'), "</th>"; echo '<th>', _('Unit'), "</th>";
echo '<th>', _('Stored'), "</th>"; echo '<th>', _('Stored'), "</th>";
echo '<th>', _('Best before'), "</th>"; echo '<th>', _('Best before'), "</th>";
echo "<th></th>"; echo "<th></th>"; // Meter
echo "<th></th>\n"; echo "<th></th>\n"; // Buttons
echo "</tr>\n"; echo "</tr>\n";
echo "</thead>\n"; echo "</thead>\n";
$i = ($page - 1) * $rows_pp;
$i0 = $i + 1;
foreach ($res as $row) { foreach ($res as $row) {
$i++; // record number
echo "<tr>\n"; echo "<tr>\n";
echo "<td>", ! isset($row['sid']) ? '<i class="bi bi-basket"></i> ' : '', $row['provname'], "</td>\n"; echo "<td>", $i;
echo "<td>". $row['number'] ."</td>\n"; echo '<a class="text-nowrap" title="', _('View'), '" href="', $g_scriptname, '?f=view&id=', $row['provid'], '"><i class="bi bi-eye ms-2"></i></a>', "\n";
echo "<td>". $opt_unit[$row['unit']] ."</td>\n";
echo "<td>". $row['storedate'] ."</td>\n";
echo "<td>". $row['shelflife'] ."</td>\n";
echo "<td>";
echo '<meter min="0" max="', $row['d0'], '" value="', $row['d1'], '">';
// Action buttons
form_action_buttons($g_scriptname, $row['provid']);
echo "</td>\n"; echo "</td>\n";
echo "<td>", ! isset($row['sid']) ? '<i class="bi bi-cart3"></i> ' : '', $row['provname'], "</td>\n";
echo "<td>", $row['number'], "</td>\n";
echo "<td>", $opt_unit[$row['unit']], "</td>\n";
echo "<td>", $row['storedate'], "</td>\n";
echo "<td>", $row['shelflife'], "</td>\n";
// TODO shelflife in der Vergangenheit
echo "<td>";
if ($row['d1'] > 0) {
echo '<meter min="0" max="', $row['d0'], '" value="', $row['d1'], '"></meter>';
} else {
if ($row['d1'] < 0) {
echo '<i class="bi bi-exclamation-triangle-fill"></i>&nbsp;', abs($row['d1']);
}
}
echo "</td>\n";
// Edit current record button
echo "<td>";
echo '<a title="', _('Edit'), '" href="', $g_scriptname, '?f=edit&id=', $row['provid'], '"><i class="bi-pencil"></i></a>';
echo "</td>\n";
echo "</tr>\n"; echo "</tr>\n";
} }
// Table summary // Table summary
echo "<tfoot>\n"; echo "<tfoot>\n";
echo '<tr><td colspan="6">', sprintf(_('%d records'), count($res)), '</td></tr>', "\n"; echo '<tr><td colspan="8">', sprintf(_('%d records'), count($res)), '</td></tr>', "\n";
echo "</tfoot>\n"; echo "</tfoot>\n";
echo "</table>\n"; echo "</table>\n";
echo $pagination;
form_add_button($g_scriptname); form_add_button($g_scriptname);
elseif ($action == ACT_ADD): elseif ($action == ACT_ADD):
@@ -187,7 +247,7 @@ echo '<h2>', _('Add provisions'), "</h2>\n";
<label for="shelflife"><?=_('Shelflife')?></label> <label for="shelflife"><?=_('Shelflife')?></label>
<input type="date" class="form-control" id="shelflife" name="shelflife"> <input type="date" class="form-control" id="shelflife" name="shelflife">
</div> </div>
<?php form_create_select('sid', _('Storage'), [-1 => '- none -'] + $opt_storage); ?> <?php form_create_select('sid', _('Storage'), $g_opt_none + $opt_storage); ?>
<div class="container-fluid px-0 my-3"> <div class="container-fluid px-0 my-3">
<button type="submit" name="submit[insert]" class="btn btn-primary"><?=_('Save')?></button> <button type="submit" name="submit[insert]" class="btn btn-primary"><?=_('Save')?></button>
<a href="<?=$g_scriptname?>" class="btn btn-secondary"><?=_('Back')?></a> <a href="<?=$g_scriptname?>" class="btn btn-secondary"><?=_('Back')?></a>
@@ -198,7 +258,7 @@ echo '<h2>', _('Add provisions'), "</h2>\n";
elseif ($action == ACT_VIEW): elseif ($action == ACT_VIEW):
// ========== VARIANT: view single record ===================================== // ========== VARIANT: view single record =====================================
$sql = "SELECT provname, provcat, number, unit, storedate, shelflife, sid " $sql = "SELECT provname, provcat, number, unit, weight, weight_net, storedate, shelflife, sid "
. "FROM provisions " . "FROM provisions "
. "WHERE provid=?"; . "WHERE provid=?";
$sth = $pdo->prepare($sql); $sth = $pdo->prepare($sql);
@@ -209,6 +269,8 @@ echo '<h2>', $prov->provname, "</h2>\n";
echo '<table class="table">', "\n"; echo '<table class="table">', "\n";
echo '<tr><th style="width:20%">', _('Number'),"</th><td>", $prov->number, "</td></tr>\n"; echo '<tr><th style="width:20%">', _('Number'),"</th><td>", $prov->number, "</td></tr>\n";
echo "<tr><th>", _('Weight'), "</th><td>", format_float($prov->weight, 2, 'kg'), "</td></tr>\n";
echo "<tr><th>", _('Weight net'), "</th><td>", format_float($prov->weight_net, 2, 'kg'), "</td></tr>\n";
echo '<tr><th>', _('Unit'),"</th><td>", $opt_unit[$prov->unit], "</td></tr>\n"; echo '<tr><th>', _('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>', _('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>', _('Storedate'),"</th><td>", $prov->storedate, "</td></tr>\n";
@@ -221,7 +283,7 @@ form_view_buttons($g_scriptname, $id);
elseif ($action == ACT_EDIT): elseif ($action == ACT_EDIT):
// ========== VARIANT: edit single record ===================================== // ========== VARIANT: edit single record =====================================
$sql = "SELECT provname, provcat, number, unit, storedate, shelflife, sid " $sql = "SELECT provname, provcat, number, weight, weight_net, unit, storedate, shelflife, sid "
. "FROM provisions " . "FROM provisions "
. "WHERE provid=?"; . "WHERE provid=?";
$sth = $pdo->prepare($sql); $sth = $pdo->prepare($sql);
@@ -240,9 +302,17 @@ echo '<h2>', _('Edit provision'), "</h2>\n";
<label for="number"><?=_('Number')?></label> <label for="number"><?=_('Number')?></label>
<input type="number" min="0" max="1000" class="form-control" id="number" name="number" value="<?=$prov->number ?>"> <input type="number" min="0" max="1000" class="form-control" id="number" name="number" value="<?=$prov->number ?>">
</div> </div>
<div class="mb-3">
<label for="weight" class="form-label"><?=_('Weight, kg')?></label>
<input type="text" class="form-control" id="weight" name="weight" value="<?=format_float($prov->weight); ?>">
</div>
<div class="mb-3">
<label for="weight_net" class="form-label"><?=_('Weight net, kg')?></label>
<input type="text" class="form-control" id="weight" name="weight_net" value="<?=format_float($prov->weight_net); ?>">
</div>
<?php <?php
form_create_select('unit', _('Unit'), $opt_unit, $prov->unit); form_create_select('unit', _('Unit'), $opt_unit, $prov->unit);
form_create_select('provcat', _('Category'), array_merge($g_opt_none, $opt_category), $prov->provcat); form_create_select('provcat', _('Category'), $g_opt_none + $opt_category, $prov->provcat);
?> ?>
<div class="mb-3"> <div class="mb-3">
<label for="storedate"><?=_('Storedate')?></label> <label for="storedate"><?=_('Storedate')?></label>
@@ -253,7 +323,7 @@ form_create_select('provcat', _('Category'), array_merge($g_opt_none, $opt_categ
<input type="date" class="form-control" id="shelflife" name="shelflife" value="<?=$prov->shelflife ?>"> <input type="date" class="form-control" id="shelflife" name="shelflife" value="<?=$prov->shelflife ?>">
</div> </div>
<?php <?php
form_create_select('sid', _('Storage'), $opt_storage, $prov->sid); form_create_select('sid', _('Storage'), $g_opt_none + $opt_storage, $prov->sid);
form_edit_buttons($g_scriptname, $id); form_edit_buttons($g_scriptname, $id);
echo "</form>\n"; echo "</form>\n";
+32 -7
View File
@@ -1,7 +1,7 @@
<?php <?php
/****************************************************************************** /******************************************************************************
* YMS - Yacht Management Software * YMS - Yacht Management Software
* Copyright (C) 2024 Thomas Hooge * Copyright (C) 2024-2026 Thomas Hooge
* *
* SPDX-License-Identifier: WTFPL * SPDX-License-Identifier: WTFPL
******************************************************************************/ ******************************************************************************/
@@ -95,7 +95,7 @@ page_caption_search($pagetitle);
// Storage // Storage
// stype from dropdown // stype from dropdown
$sql = "SELECT sid, sname, x, y, z, remarks " $sql = "SELECT sid, sname, x, y, z, angle, remarks "
. "FROM storage " . "FROM storage "
. "WHERE vid=? " . "WHERE vid=? "
. "ORDER BY sid"; . "ORDER BY sid";
@@ -105,22 +105,36 @@ $res = $sth->fetchAll();
echo '<table class="table table-striped">', "\n"; echo '<table class="table table-striped">', "\n";
echo "<thead>\n"; echo "<thead>\n";
echo "<tr>"; echo "<tr>";
echo '<th>#</th>';
echo "<th>", _('Name'), "</th>"; echo "<th>", _('Name'), "</th>";
echo "<th>", _('Position'), "</th>"; echo "<th>", _('Position'), "</th>";
echo "<th>", _('Remarks'), "</th>"; echo "<th>", _('Remarks'), "</th>";
echo "<th>&nbsp;</th>"; echo "<th>&nbsp;</th>";
echo "</tr>\n"; echo "</tr>\n";
echo "</thead>\n"; echo "</thead>\n";
$i = 0;
foreach ($res as $row) { foreach ($res as $row) {
$i++; // record number
echo "<tr>\n"; echo "<tr>\n";
echo '<td>', $i;
echo '<a class="text-nowrap" title="', _('View'), '" href="', $g_scriptname, '?f=view&id=', $row['sid'], '"><i class="bi bi-eye ms-2"></i></a>', "\n";
echo "</td>\n";
echo "<td>", $row['sname'], "</td>\n"; echo "<td>", $row['sname'], "</td>\n";
echo "<td>", join(',', array($row['x'] ?? '?', $row['y'] ?? '?', $row['z'])), "</td>\n"; if ($row['angle'] != 0) {
$angle = " (" . $row['angle'] . "°)";
} else {
$angle = "";
}
echo "<td>", join(',', array($row['x'] ?? '?', $row['y'] ?? '?', $row['z'])), $angle, "</td>\n";
echo "<td>", $row['remarks'], "</td>\n"; echo "<td>", $row['remarks'], "</td>\n";
form_action_buttons($g_scriptname, $row['sid']); // Edit current record button
echo "<td>";
echo '<a title="', _('Edit'), '" href="', $g_scriptname, '?f=edit&id=', $row['sid'], '"><i class="bi-pencil"></i></a>', "\n";
echo "</td>\n";
echo "</tr>\n"; echo "</tr>\n";
} }
echo "<tfoot>\n"; echo "<tfoot>\n";
echo '<tr><td colspan="3">', sprintf(_('%d records'), count($res)), '</td></tr>', "\n"; echo '<tr><td colspan="5">', sprintf(_('%d records'), count($res)), '</td></tr>', "\n";
echo "</tfoot>\n"; echo "</tfoot>\n";
echo "</table>\n"; echo "</table>\n";
@@ -136,17 +150,26 @@ $res = $sth->fetchAll();
echo '<table class="table table-striped">', "\n"; echo '<table class="table table-striped">', "\n";
echo "<thead>\n"; echo "<thead>\n";
echo "<tr>"; echo "<tr>";
echo '<th>#</th>';
echo "<th>" . _('Label') . "</th>"; echo "<th>" . _('Label') . "</th>";
echo "<th>" . _('Color') . "</th>"; echo "<th>" . _('Color') . "</th>";
echo "<th>" . _('Content') . "</th>"; echo "<th>" . _('Content') . "</th>";
echo "<td></td>"; echo "<td></td>";
echo "</tr>\n"; echo "</tr>\n";
$i = 0;
foreach ($res as $row) { foreach ($res as $row) {
$i++; // record number
echo "<tr>\n"; echo "<tr>\n";
echo '<td>', $i;
echo '<a class="text-nowrap" title="', _('View'), '" href="box.php?f=view&id=', $row['boxid'], '"><i class="bi bi-eye ms-2"></i></a>', "\n";
echo "</td>\n";
echo "<td>". $row['label'] ."</td>\n"; echo "<td>". $row['label'] ."</td>\n";
echo '<td>', format_color($row['color']), "</td>\n"; echo '<td>', format_color($row['color']), "</td>\n";
echo "<td>". $row['content'] ."</td>\n"; echo "<td>". $row['content'] ."</td>\n";
form_action_buttons('box.php', $row['boxid']); // Edit current record button
echo "<td>";
echo '<a title="', _('Edit'), '" href="box.php?f=edit&id=', $row['boxid'], '"><i class="bi-pencil"></i></a>', "\n";
echo "</td>\n";
echo "</tr>\n"; echo "</tr>\n";
} }
// Table summary // Table summary
@@ -189,7 +212,7 @@ elseif ($action == ACT_VIEW):
// ========== VARIANT: view single record ===================================== // ========== VARIANT: view single record =====================================
$opt_unit = db_get_options(6); $opt_unit = db_get_options(6);
$sql = "SELECT sid, sname, stype, capacity, capaunit, x, y, z, wx, wy, wz, remarks " $sql = "SELECT sid, sname, stype, capacity, capaunit, x, y, z, wx, wy, wz, angle, color, remarks "
. "FROM storage " . "FROM storage "
. "WHERE sid=?"; . "WHERE sid=?";
$sth = $pdo->prepare($sql); $sth = $pdo->prepare($sql);
@@ -202,6 +225,8 @@ echo '<tr><th style="width:33%">', _('Typ'),"</th><td>", $stype[$storage->stype]
echo '<tr><th>', _('Capacity'),"</th><td>", $storage->capacity, ' ', $storage->capaunit, "</td></tr>\n"; echo '<tr><th>', _('Capacity'),"</th><td>", $storage->capacity, ' ', $storage->capaunit, "</td></tr>\n";
echo '<tr><th>', _('Location (x, y, z)'),"</th><td>(", $storage->x, ', ', $storage->y, ', ', $storage->z, ")</td></tr>\n"; echo '<tr><th>', _('Location (x, y, z)'),"</th><td>(", $storage->x, ', ', $storage->y, ', ', $storage->z, ")</td></tr>\n";
echo '<tr><th>', _('Width (wx, wy, wz)'),"</th><td>(", $storage->wx, ', ', $storage->wy, ', ', $storage->wz, ")</td></tr>\n"; echo '<tr><th>', _('Width (wx, wy, wz)'),"</th><td>(", $storage->wx, ', ', $storage->wy, ', ', $storage->wz, ")</td></tr>\n";
echo '<tr><th>', _('Angle'),"</th><td>", $storage->angle, "°</td></tr>\n";
echo '<tr><th>', _('Color'),"</th><td>", $storage->color, "</td></tr>\n";
echo '<tr><th>', _('Remarks'),"</th><td>", $storage->remarks, "</td></tr>\n"; echo '<tr><th>', _('Remarks'),"</th><td>", $storage->remarks, "</td></tr>\n";
echo "</table>\n"; echo "</table>\n";
+1 -1
View File
@@ -88,7 +88,7 @@ echo "<h1>$pagetitle</h1>\n";
?> ?>
<form method="post" action="<?=$g_scriptname?>"> <form method="post" action="<?=$g_scriptname?>">
<div id="filter" class="card"> <div id="filter" class="card">
<div class="card-header">Filter</div> <div class="card-header"><i class="bi bi-funnel me-2"></i>Filter</div>
<div class="card-body"> <div class="card-body">
<label for="flt_txt">Text</label> <label for="flt_txt">Text</label>
+30 -7
View File
@@ -35,6 +35,11 @@ switch ($submit = form_get_action()) {
$action = ACT_DEFAULT; $action = ACT_DEFAULT;
break; break;
case 'freset':
db_clear_filter(206);
$action = ACT_DEFAULT;
break;
case 'insert': case 'insert':
$p[':vid'] = $user->vid; $p[':vid'] = $user->vid;
$p[':projid'] = gpc_get_int($_POST, 'projid'); $p[':projid'] = gpc_get_int($_POST, 'projid');
@@ -42,6 +47,7 @@ switch ($submit = form_get_action()) {
$p[':projid'] = NULL; $p[':projid'] = NULL;
} }
$p[':taskname'] = gpc_get_string($_POST, 'taskname'); $p[':taskname'] = gpc_get_string($_POST, 'taskname');
$p[':responsible'] = $user->id;
$id = db_exec_insert('task', $p); $id = db_exec_insert('task', $p);
$action = ACT_VIEW; $action = ACT_VIEW;
break; break;
@@ -62,6 +68,7 @@ switch ($submit = form_get_action()) {
$p[':started'] = gpc_get_datetime($_POST, 'started'); $p[':started'] = gpc_get_datetime($_POST, 'started');
$p[':finished'] = gpc_get_datetime($_POST, 'finished'); $p[':finished'] = gpc_get_datetime($_POST, 'finished');
$p[':taskstate'] = gpc_get_enum($_POST, 'taskstate', array_keys($opt_state)); $p[':taskstate'] = gpc_get_enum($_POST, 'taskstate', array_keys($opt_state));
$p[':responsible'] = gpc_get_int($_POST, 'responsible');
db_exec_update('task', $p, 'taskid'); db_exec_update('task', $p, 'taskid');
$action = ACT_VIEW; $action = ACT_VIEW;
break; break;
@@ -137,7 +144,7 @@ $where = join(' AND ', $w);
$order = ' ORDER BY t.taskid'; $order = ' ORDER BY t.taskid';
// get total recond count for pagination and limit // get total recond count for pagination and limit
$sql = "SELECT COUNT(*) FROM task"; $sql = "SELECT COUNT(*) FROM task AS t";
if ($where) $sql .= " WHERE $where"; if ($where) $sql .= " WHERE $where";
$sth = $pdo->prepare($sql); $sth = $pdo->prepare($sql);
@@ -147,10 +154,12 @@ try {
$g_error->Add($e->getMessage()); $g_error->Add($e->getMessage());
$g_error->Add($sql); $g_error->Add($sql);
$g_error->Add(print_r($p, true)); $g_error->Add(print_r($p, true));
$g_error->PrintOut();
} }
$numrows = $sth->fetchColumn(); $numrows = $sth->fetchColumn();
$lastpage = ceil($numrows/$g_rows_pp);
$page = gpc_get_int($_REQUEST, 'p', 1); $page = gpc_get_int($_REQUEST, 'p', 1);
$rows_pp = gpc_get_int($_REQUEST, 'n', $g_rows_pp);
$lastpage = ceil($numrows/$rows_pp);
$sql = "SELECT t.taskid, t.vid, t.projid, t.taskname, t.priority, t.taskstate," $sql = "SELECT t.taskid, t.vid, t.projid, t.taskname, t.priority, t.taskstate,"
. " p.projname " . " p.projname "
@@ -167,13 +176,14 @@ try {
$g_error->Add('SQL-Error: '. $e->getMessage()); $g_error->Add('SQL-Error: '. $e->getMessage());
$g_error->Add($sql); $g_error->Add($sql);
$g_error->Add(print_r($p, true)); $g_error->Add(print_r($p, true));
$g_error->Printout();
} }
$res = $sth->fetchAll(); $res = $sth->fetchAll();
?> ?>
<form method="post" action="<?=$g_scriptname?>"> <form method="post" action="<?=$g_scriptname?>">
<div id="filter" class="card"> <div id="filter" class="card">
<div class="card-header">Filter</div> <div class="card-header"><i class="bi bi-funnel me-2"></i>Filter</div>
<div class="card-body"> <div class="card-body">
<?php <?php
filter_create_select('flt_prio', _('Priority'), $g_opt_all + $g_opt_none + $opt_priority, $flt->prio); filter_create_select('flt_prio', _('Priority'), $g_opt_all + $g_opt_none + $opt_priority, $flt->prio);
@@ -200,16 +210,23 @@ echo "<th></th>";
echo "<th></th>\n"; echo "<th></th>\n";
echo "</tr>\n"; echo "</tr>\n";
echo "</thead>\n"; echo "</thead>\n";
$i = ($page - 1) * $rows_pp;
$i0 = $i + 1;
foreach ($res as $row) { foreach ($res as $row) {
$i++; // record number
echo "<tr>\n"; echo "<tr>\n";
// mark generic tasks with braces // mark generic tasks with braces
echo "<td>", $row['vid'] ? $row['taskid'] : '('.$row['taskid'].')', "</td>\n"; echo "<td>", $row['vid'] ? $i : "($i)";
echo '<a class="text-nowrap" title="', _('View'), '" href="', $g_scriptname, '?f=view&id=', $row['taskid'], '"><i class="bi bi-eye ms-2"></i></a>';
echo "</td>\n";
echo "<td>", $row['taskname'], "</td>\n"; echo "<td>", $row['taskname'], "</td>\n";
echo "<td>", $row['projname'], "</td>\n"; echo "<td>", $row['projname'], "</td>\n";
echo "<td>", ($opt_priority[$row['priority']] ?? ''), "</td>\n"; echo "<td>", ($opt_priority[$row['priority']] ?? ''), "</td>\n";
echo "<td>", ($opt_state[$row['taskstate']]), "</td>\n"; echo "<td>", ($opt_state[$row['taskstate']]), "</td>\n";
// Action buttons // Edit current record button
form_action_buttons($g_scriptname, $row['taskid']); echo "<td>";
echo '<a title="', _('Edit'), '" href="', $g_scriptname, '?f=edit&id=', $row['taskid'], '"><i class="bi-pencil"></i></a>', "\n";
echo "</td>\n";
echo "</tr>\n"; echo "</tr>\n";
} }
// Table summary // Table summary
@@ -247,8 +264,10 @@ elseif ($action == ACT_VIEW):
// ========== VARIANT: view single record ===================================== // ========== VARIANT: view single record =====================================
$sql = "SELECT t.taskname, t.priority, t.plandate, t.duedate," $sql = "SELECT t.taskname, t.priority, t.plandate, t.duedate,"
. " t.started, t.finished, t.taskstate, p.projname " . " t.started, t.finished, t.taskstate, t.responsible,"
. " u.displayname, p.projname "
. "FROM task AS t LEFT JOIN project AS p USING (projid) " . "FROM task AS t LEFT JOIN project AS p USING (projid) "
. " LEFT JOIN user AS u ON (t.responsible=u.userid) "
. "WHERE taskid=?"; . "WHERE taskid=?";
$sth = $pdo->prepare($sql); $sth = $pdo->prepare($sql);
$sth->execute([$id]); $sth->execute([$id]);
@@ -264,6 +283,7 @@ 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>', _('Started at'),"</th><td>", $task->started, "</td></tr>\n";
echo '<tr><th>', _('Finished at'),"</th><td>", $task->finished, "</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 '<tr><th>', _('Status'),"</th><td>", $opt_state[$task->taskstate], "</td></tr>\n";
echo '<tr><th>', _('Responsible'),"</th><td>", $task->displayname, "</td></tr>\n";
echo "</table>\n"; echo "</table>\n";
form_view_buttons($g_scriptname, $id); form_view_buttons($g_scriptname, $id);
@@ -297,6 +317,8 @@ echo '<p>', _('Not yet implemented'), "</p>";
elseif ($action == ACT_EDIT): elseif ($action == ACT_EDIT):
// ========== VARIANT: edit single record ===================================== // ========== VARIANT: edit single record =====================================
$opt_user = db_get_opt_user($user->id); // only used here
$sql = "SELECT taskname, projid, priority, plandate, duedate, started, finished," $sql = "SELECT taskname, projid, priority, plandate, duedate, started, finished,"
. " taskstate " . " taskstate "
. "FROM task " . "FROM task "
@@ -337,6 +359,7 @@ form_create_select('priority', _('Priority'), $opt_none + $opt_priority, $task->
</div> </div>
<?php <?php
form_create_select('taskstate', _('Status'), $opt_state, $task->taskstate); form_create_select('taskstate', _('Status'), $opt_state, $task->taskstate);
form_create_select('responsible', _('Responsible'), $opt_user, $user->id);
form_edit_buttons($g_scriptname, $id); form_edit_buttons($g_scriptname, $id);
echo "</form>\n"; echo "</form>\n";