From 57c42d139829696318d806dc0bedad7c495f5807 Mon Sep 17 00:00:00 2001 From: Thomas Hooge Date: Mon, 14 Sep 2026 10:12:32 +0200 Subject: [PATCH] Some database improvements and associated changes in webgui --- db/mariadb.sql | 99 ++++++++++++++++++++++++++++++------------ install.sh | 7 +++ webgui/box.php | 1 + webgui/cable.php | 1 + webgui/checklist.php | 1 + webgui/company.php | 1 + webgui/dl.php | 1 + webgui/dropdown.php | 1 + webgui/fuse.php | 1 + webgui/globals.inc | 33 ++++++++++++-- webgui/index.php | 5 ++- webgui/inventory.php | 1 + webgui/lib/db.inc | 47 ++++++++++++++++++++ webgui/maintenance.php | 3 +- webgui/measurement.php | 1 + webgui/note.php | 11 +++-- webgui/projects.php | 1 + webgui/provisions.php | 1 + webgui/search.php | 1 + webgui/settings.php | 11 +++++ webgui/storage.php | 1 + webgui/tag.php | 1 + webgui/task.php | 12 ++++- 23 files changed, 203 insertions(+), 39 deletions(-) diff --git a/db/mariadb.sql b/db/mariadb.sql index 74017c0..b66a1de 100644 --- a/db/mariadb.sql +++ b/db/mariadb.sql @@ -3,10 +3,12 @@ /* MariaDB Scheme Version: 1 */ -/* TODO +/* REMARKS + - there are by design no created_at, updated_at, updates_by or similar fields + + TODO - check all values if unsigned can be used or not - - implement foreign keys where missing and possible - - add referential actions where appropriate + - add referential actions where appropriate - rename provisions to provision(?) - review defaults */ @@ -66,6 +68,7 @@ CREATE TABLE dropdown ( PRIMARY KEY (ddid, ddval) ) ENGINE=InnoDB; +/* compid is signed because negative values needed for special purpose */ CREATE TABLE company ( compid smallint(6) NOT NULL AUTO_INCREMENT, compname varchar(60) NOT NULL, @@ -110,6 +113,7 @@ CREATE TABLE vessel ( PRIMARY KEY (vid), FOREIGN KEY fk_vessel_shipyard (shipyard) REFERENCES company(compid) + ON DELETE RESTRICT ) ENGINE=InnoDB; CREATE TABLE storage ( @@ -131,13 +135,15 @@ CREATE TABLE storage ( PRIMARY KEY (sid), FOREIGN KEY fk_storage_vessel (vid) REFERENCES vessel(vid) + ON DELETE RESTRICT ) ENGINE=InnoDB; /* intentionally after storage creation */ ALTER TABLE vessel ADD CONSTRAINT fk_vessel_storage FOREIGN KEY (sid_default) - REFERENCES storage(sid); + REFERENCES storage(sid) + ON DELETE RESTRICT; CREATE TABLE tag ( tagid smallint(6) UNSIGNED NOT NULL AUTO_INCREMENT, @@ -153,13 +159,14 @@ CREATE TABLE tagref ( objid int(10) UNSIGNED NOT NULL, objtype enum('equip','inv','prov','doc', 'proj', 'task', 'maint') NOT NULL, PRIMARY KEY (tagid, objid, objtype), + INDEX ix_tagref_obj (objid, objtype), FOREIGN KEY fk_tagref_tag (tagid) REFERENCES tag(tagid) ON DELETE CASCADE ) ENGINE=InnoDB; -/* TODO Boxes can be nested via parent - TODO boxsize: (LxWxH) in cm? */ +/* TODO Boxes can be nested via parent, + very low priority because perhaps rarely used */ CREATE TABLE box ( boxid smallint(6) UNSIGNED NOT NULL AUTO_INCREMENT, sid smallint(6) UNSIGNED NOT NULL, @@ -169,11 +176,18 @@ CREATE TABLE box ( color char(6) DEFAULT NULL, content varchar(60) DEFAULT NULL, weight float(5,2) UNSIGNED DEFAULT NULL, + wx smallint(6) UNSIGNED NOT NULL DEFAULT 0, + wy smallint(6) UNSIGNED NOT NULL DEFAULT 0, + wz smallint(6) UNSIGNED NOT NULL DEFAULT 0, remarks varchar(150) DEFAULT NULL, PRIMARY KEY (boxid), INDEX ix_label (label), FOREIGN KEY fk_box_storage (sid) REFERENCES storage(sid) + ON DELETE RESTRICT, + FOREIGN KEY fk_box_parent (parent) + REFERENCES box(boxid) + ON DELETE RESTRICT ) ENGINE=InnoDB; CREATE TABLE equipment ( @@ -196,6 +210,9 @@ CREATE TABLE equipment ( REFERENCES vessel(vid) ON DELETE RESTRICT, FOREIGN KEY fk_equipment_supplier (supplier) + REFERENCES company(compid) + ON DELETE RESTRICT, + FOREIGN KEY fk_equipment_manufacturer (manufacturer) REFERENCES company(compid) ON DELETE RESTRICT ) ENGINE=InnoDB; @@ -206,7 +223,7 @@ CREATE TABLE inventory ( conttype enum('storage','box') NOT NULL DEFAULT 'storage', sid smallint(6) UNSIGNED DEFAULT NULL, boxid smallint(6) UNSIGNED DEFAULT NULL, - eid smallint(6) UNSIGNED DEFAULT NULL, + eid smallint(6) UNSIGNED DEFAULT NULL, -- spare part reference to equipment number smallint(6) UNSIGNED NOT NULL DEFAULT 1, weight float(5,2) UNSIGNED DEFAULT NULL, price decimal(12,2) DEFAULT NULL, @@ -217,11 +234,14 @@ CREATE TABLE inventory ( PRIMARY KEY (invid), INDEX ix_invname (invname), FOREIGN KEY fk_inventory_storage (sid) - REFERENCES storage(sid), + REFERENCES storage(sid) + ON DELETE RESTRICT, FOREIGN KEY fk_inventory_box (boxid) - REFERENCES box(boxid), + REFERENCES box(boxid) + ON DELETE RESTRICT, FOREIGN KEY fk_inventory_equipment (eid) - REFERENCES equipment(eid), + REFERENCES equipment(eid) + ON DELETE RESTRICT, CHECK ( (sid IS NOT NULL AND boxid IS NULL) OR @@ -248,11 +268,14 @@ CREATE TABLE cable ( PRIMARY KEY (cableid), INDEX ix_cablename (vid, cablename), FOREIGN KEY fk_cable_vessel (vid) - REFERENCES vessel(vid), + REFERENCES vessel(vid) + ON DELETE RESTRICT, FOREIGN KEY fk_cable_supplier (supplier) - REFERENCES company(compid), + REFERENCES company(compid) + ON DELETE RESTRICT, FOREIGN KEY fk_cable_manufacturer (manufacturer) REFERENCES company(compid) + ON DELETE RESTRICT ) ENGINE=InnoDB; CREATE table fuse ( @@ -269,11 +292,14 @@ CREATE table fuse ( PRIMARY KEY (fuseid), UNIQUE INDEX ix_fusenumber (vid, fnumber), FOREIGN KEY fk_fuse_vessel (vid) - REFERENCES vessel(vid), + REFERENCES vessel(vid) + ON DELETE RESTRICT, FOREIGN KEY fk_fuse_cable (cableid) - REFERENCES cable(cableid), + REFERENCES cable(cableid) + ON DELETE RESTRICT, FOREIGN KEY fk_fuse_equipment (eid) REFERENCES equipment(eid) + ON DELETE RESTRICT ) ENGINE=InnoDB; -- change vals to decimal(12,4)? @@ -292,9 +318,11 @@ CREATE TABLE measurement ( note varchar(80) DEFAULT NULL, PRIMARY KEY (mid), FOREIGN KEY fk_measurement_vessel (vid) - REFERENCES vessel(vid), + REFERENCES vessel(vid) + ON DELETE RESTRICT, FOREIGN KEY fk_measurement_equipment (eid) REFERENCES equipment(eid) + ON DELETE RESTRICT ) ENGINE=InnoDB; CREATE TABLE provisions ( @@ -315,9 +343,11 @@ CREATE TABLE provisions ( remarks varchar(150) DEFAULT NULL, PRIMARY KEY (provid), FOREIGN KEY fk_provisions_storage (sid) - REFERENCES storage(sid), + REFERENCES storage(sid) + ON DELETE RESTRICT, FOREIGN KEY fk_provisions_box (boxid) REFERENCES box(boxid) + ON DELETE RESTRICT ) ENGINE=InnoDB; /* TODO @@ -345,19 +375,19 @@ CREATE TABLE document ( CREATE TABLE docref ( 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','maint', 'task','user','company') NOT NULL DEFAULT 'vessel', docid smallint(6) NOT NULL, refid int(10) NOT NULL, PRIMARY KEY (drid), UNIQUE INDEX ix_docref (docid, refid, reftype), + INDEX ix_docref_ref (refid, reftype), FOREIGN KEY fk_docref_doc (docid) REFERENCES document (docid) - ON DELETE RESTRICT - ON UPDATE CASCADE + ON DELETE CASCADE ) ENGINE=InnoDB; -/* TODO optional fields: plan date, target date, completion date - interval_hours, last_hours +/* TODO optional fields: target date? + responsible? signalk: operating hours current vs maint every n operating hours in separate */ CREATE TABLE maintenance ( @@ -374,13 +404,14 @@ CREATE TABLE maintenance ( maintstate enum('new','plan','ongoing','done') NOT NULL DEFAULT 'new', PRIMARY KEY (maintid), FOREIGN KEY fk_maintenance_vessel (vid) - REFERENCES vessel(vid), + REFERENCES vessel(vid) + ON DELETE RESTRICT, FOREIGN KEY fk_maintenance_equipment (eid) REFERENCES equipment(eid) + ON DELETE RESTRICT ) ENGINE=InnoDB; -/* TODO? time recording */ - +/* TODO time recording? */ CREATE TABLE project ( projid smallint(6) NOT NULL AUTO_INCREMENT, projname varchar(40) NOT NULL, @@ -394,9 +425,11 @@ CREATE TABLE project ( projstate enum('new','plan','ongoing','paused','finished') NOT NULL DEFAULT 'new', PRIMARY KEY (projid), FOREIGN KEY fk_project_vessel (vid) - REFERENCES vessel(vid), + REFERENCES vessel(vid) + ON DELETE RESTRICT, FOREIGN KEY fk_project_user (responsible) REFERENCES user(userid) + ON DELETE RESTRICT ) ENGINE=InnoDB; /* TODO executed_by : company or user? or both? */ @@ -413,13 +446,17 @@ CREATE TABLE task ( started datetime DEFAULT NULL, finished datetime DEFAULT NULL, responsible smallint(6) NOT NULL, + remarks varchar(150) DEFAULT NULL, PRIMARY KEY (taskid), FOREIGN KEY fk_task_user (responsible) - REFERENCES user(userid), + REFERENCES user(userid) + ON DELETE RESTRICT, FOREIGN KEY fk_task_vessel (vid) - REFERENCES vessel(vid), + REFERENCES vessel(vid) + ON DELETE RESTRICT, FOREIGN KEY fk_task_project (projid) REFERENCES project(projid) + ON DELETE RESTRICT ) ENGINE=InnoDB; /* Notes can be assigned to tasks, maintenances and equipment */ @@ -428,7 +465,12 @@ CREATE TABLE note ( notetype enum('task','maint','equip') NOT NULL DEFAULT 'task', refid int(10) NOT NULL, annotation text NOT NULL, + created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + created_by smallint(6) DEFAULT NULL, PRIMARY KEY (noteid) + FOREIGN KEY fk_note_user (created_by) + REFERENCES user(userid) + ON DELETE RESTRICT ) ENGINE=InnoDB; CREATE TABLE checklist ( @@ -439,6 +481,7 @@ CREATE TABLE checklist ( PRIMARY KEY (clid), FOREIGN KEY fk_checklist_parent (parent) REFERENCES checklist(clid) + ON DELETE RESTRICT ) ENGINE=InnoDB; CREATE TABLE checkgroup ( @@ -455,6 +498,7 @@ CREATE TABLE checkitem ( PRIMARY KEY (checkid), FOREIGN KEY fk_checkitem_group (groupid) REFERENCES checkgroup(groupid) + ON DELETE RESTRICT ) ENGINE=InnoDB; CREATE TABLE checkref ( @@ -483,6 +527,7 @@ CREATE TABLE signalk ( (vid, objtype, objid, datatype), FOREIGN KEY fk_signalk_vessel (vid) REFERENCES vessel(vid) + ON DELETE RESTRICT ) ENGINE=InnoDB; /* Token diff --git a/install.sh b/install.sh index 83d076c..241e30b 100755 --- a/install.sh +++ b/install.sh @@ -15,6 +15,13 @@ SOURCEDIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) if [ "$1" = "uninstall" ]; then echo "Uninstalling YMS..." + if [ "$(id -u)" -ne 0 ]; then + echo "Error: this script must be run as root." + echo "Please use:" + echo " sudo $0" + exit 1 + fi + rm -f "${BINDIR}/yms" rm -rf "${LIBDIR}" rm -rf "${SHAREDIR}" diff --git a/webgui/box.php b/webgui/box.php index 816ba4e..9f5b7c7 100644 --- a/webgui/box.php +++ b/webgui/box.php @@ -14,6 +14,7 @@ There can be a difference because not all items have a weight entered */ require 'globals.inc'; +require 'lib/db.inc'; require 'lib/gpc.inc'; $pagetitle = _('Boxes'); diff --git a/webgui/cable.php b/webgui/cable.php index 44bf457..a9c6818 100644 --- a/webgui/cable.php +++ b/webgui/cable.php @@ -7,6 +7,7 @@ ******************************************************************************/ require 'globals.inc'; +require 'lib/db.inc'; require 'lib/gpc.inc'; $pagetitle = _('Cables'); diff --git a/webgui/checklist.php b/webgui/checklist.php index a16b57a..9b526f9 100644 --- a/webgui/checklist.php +++ b/webgui/checklist.php @@ -7,6 +7,7 @@ ******************************************************************************/ require 'globals.inc'; +require 'lib/db.inc'; require 'lib/gpc.inc'; $pagetitle = _('Checklists'); diff --git a/webgui/company.php b/webgui/company.php index 0c80b73..855b5ae 100644 --- a/webgui/company.php +++ b/webgui/company.php @@ -7,6 +7,7 @@ ******************************************************************************/ require 'globals.inc'; +require 'lib/db.inc'; require 'lib/gpc.inc'; $pagetitle=_('Company'); diff --git a/webgui/dl.php b/webgui/dl.php index 5d5d9f6..581cf71 100644 --- a/webgui/dl.php +++ b/webgui/dl.php @@ -18,6 +18,7 @@ */ require 'globals.inc'; +require 'lib/db.inc'; require 'lib/gpc.inc'; require 'lib/fileutils.inc'; diff --git a/webgui/dropdown.php b/webgui/dropdown.php index de858a9..357f500 100644 --- a/webgui/dropdown.php +++ b/webgui/dropdown.php @@ -7,6 +7,7 @@ ******************************************************************************/ require 'globals.inc'; +require 'lib/db.inc'; require 'lib/gpc.inc'; $pagetitle = _('Lists'); diff --git a/webgui/fuse.php b/webgui/fuse.php index b177267..17ae3ef 100644 --- a/webgui/fuse.php +++ b/webgui/fuse.php @@ -7,6 +7,7 @@ ******************************************************************************/ require 'globals.inc'; +require 'lib/db.inc'; require 'lib/gpc.inc'; $pagetitle = _('Fuses'); diff --git a/webgui/globals.inc b/webgui/globals.inc index 3c1e40f..030653c 100644 --- a/webgui/globals.inc +++ b/webgui/globals.inc @@ -114,14 +114,25 @@ try { $sth = $pdo->query("SELECT valint FROM settings WHERE userid=0 AND sno=0"); } catch (PDOException $e) { if ($e->getCode() == 1146) { - echo '
';
-        echo 'Settings table not found! Perhaps database is not initialized';
-        echo '
'; + echo "
\n";
+        echo "Settings table not found! Perhaps database is not initialized?\n";
+        echo "
\n"; exit(1); } } $g_db_scheme_version = $sth->fetchColumn(); -// TODO Check version +$g_db_scheme_required = 1; +// Schema version check +if ($g_db_scheme_version !== $g_db_scheme_required) { + echo "
\n";
+    echo "Database schema is wrong: detected version $g_db_scheme_version, but required version $g_db_scheme_required!\n";
+    echo "
\n"; + exit(1); +} + +// currency symbol is global +$sth = $pdo->query("SELECT valint FROM settings WHERE userid=0 AND sno=4"); +$g_currsym = $sth->fetchColumn(); $user = User::GetInstance(); // There can be only one if ($g_scriptname != 'login.php') { @@ -1269,6 +1280,20 @@ function format_date($date) { return date($user->datefmt, $timestamp); } +function format_datetime($datetime, $seconds=false) { + // datetime is string in ISO format + global $user; + if (empty($datetime)) { + return ''; + } + $timestamp = strtotime($datetime); + if ($timestamp === false) { + return ''; + } + $timefmt = $seconds ? 'H:i:s' : 'H:i'; + return date($user->datefmt. ' ' . $timefmt, $timestamp); +} + function format_color($color) { $colstr = '', _('Add additional yacht'), "\n";
- +
@@ -602,7 +603,7 @@ form_create_select('sid', _('Default Storage'), $g_opt_none + $opt_storage, $ves ?>
- +
prepare($sql); + $sth->execute([$table, $key, $token, $userid]); + return $token; + } catch (PDOException $e) { + if ($e->errorInfo[1] != 1062) { + throw $e; + } + } + // lazy locking: lock exists but is old, so we use it + $sql = "UPDATE recordlock " + . "SET token=?, userid=?, " + . "created_at=CURRENT_TIMESTAMP, last_seen=CURRENT_TIMESTAMP " + . "WHERE lock_table=? AND lock_key=? " + . "AND last_seenprepare($sql); + $sth->execute([$token, $userid, $table, $key]); + if ($stmt->rowCount() === 1) { + return $token; + } + return null; +} + +function db_lock_refresh($token) { + global $pdo; + $sql = "UPDATE recordlock " + . "SET last_seen=CURRENT_TIMESTAMP " + . "WHERE token=?"; + $sth = $pdo->prepare($sql); + $sth->execute([$token]); + return $sth->rowCount() === 1; +} + + +function db_lock_release($token) { + global $pdo; + $sql = "DELETE FROM recordlock WHERE token=?"; + $sth = $pdo->prepare($sql); + $sth->execute([$token]); + return $sth->rowCount() === 1; +} diff --git a/webgui/maintenance.php b/webgui/maintenance.php index 76c6423..11420e2 100644 --- a/webgui/maintenance.php +++ b/webgui/maintenance.php @@ -7,6 +7,7 @@ ******************************************************************************/ require 'globals.inc'; +require 'lib/db.inc'; require 'lib/gpc.inc'; $pagetitle = _('Maintenance'); @@ -288,7 +289,7 @@ echo '
'; // Column break echo '
'; // TODO Show documents for equipment -echo "

Documents

\n"; +echo '

Documents for ', h($maint->ename), "

\n"; if (isset($docs)) { echo '
    ', "\n"; foreach ($docs as $d) { diff --git a/webgui/measurement.php b/webgui/measurement.php index 368dade..9929be8 100644 --- a/webgui/measurement.php +++ b/webgui/measurement.php @@ -7,6 +7,7 @@ ******************************************************************************/ require 'globals.inc'; +require 'lib/db.inc'; require 'lib/gpc.inc'; // TODO move to somewhere else diff --git a/webgui/note.php b/webgui/note.php index 1310ac2..c613126 100644 --- a/webgui/note.php +++ b/webgui/note.php @@ -7,6 +7,7 @@ ******************************************************************************/ require 'globals.inc'; +require 'lib/db.inc'; require 'lib/gpc.inc'; $pagetitle = _('Note'); @@ -30,6 +31,7 @@ switch ($submit = form_get_action()) { $p[':notetype'] = gpc_get_enum($_POST, 'notetype', $opt_notetype, 'task'); $p[':refid'] = gpc_get_int($_POST, 'refid'); $p[':annotation'] = gpc_get_string($_POST, 'annotation'); + $p[':created_by'] = $user->id; $id = db_exec_insert('note', $p); $caller = gpc_get_string($_POST, 'caller'); $callid = $p[':refid']; @@ -171,7 +173,9 @@ elseif ($action == ACT_VIEW): echo '

    ', _('View Note'), "

    \n"; -$sql = "SELECT refid, notetype, annotation FROM note WHERE noteid=?"; +$sql = "SELECT n.refid, n.notetype, n.annotation, n.created_at, u.displayname " + . "FROM note AS n LEFT OUTER JOIN user AS u ON (n.created_by=u.userid) " + . "WHERE noteid=?"; $sth = $pdo->prepare($sql); $sth->execute([$id]); $note = $sth->fetch(PDO::FETCH_OBJ); @@ -184,9 +188,10 @@ echo '', "\n"; echo '\n"; echo '\n"; echo '\n"; +echo '\n"; +echo '\n"; echo "
    ', _('Reference'),"", $note->refid, "
    ', _('Type'),"", $note->notetype, "
    ', _('Annotation'),"", nl2br($note->annotation), "
    ', _('Created at'),"", format_datetime($note->created_at), "
    ', _('Created by'),"", h($note->displayname), "
    \n"; - $link = $note->notetype == 'task' ? 'task.php' : 'maintenance.php'; // echo '

    ', _('Parent'), "

    \n"; form_view_buttons($g_scriptname, $id, $link.'?f=view&id='.$note->refid); @@ -205,7 +210,7 @@ echo '

    ', _('Edit Note'), "

    \n";
    - +
    role == 'captain') { $p[':userid'] = 0; + $p[':sno'] = 4; + $p[':valstr'] = gpc_get_string($_POST, 'currsym', 3, '€'); + db_exec_update('settings', $p, $pk); + $p[':valstr'] = NULL; + // image dimensions $p[':sno'] = 20; $p[':valint'] = gpc_get_int($_POST, 'maximgx'); db_exec_update('settings', $p, $pk); @@ -101,6 +107,7 @@ if ($res = $sth->fetch(PDO::FETCH_NUM)) { $sth->execute([$user->id, $rowspp]); } +$currsym = $pdo->query("SELECT valstr FROM settings WHERE userid=0 AND sno=4")->fetchColumn(); $maximgx = $pdo->query("SELECT valint FROM settings WHERE userid=0 AND sno=20")->fetchColumn(); $maximgy = $pdo->query("SELECT valint FROM settings WHERE userid=0 AND sno=21")->fetchColumn(); @@ -131,6 +138,10 @@ form_create_select('datefmt', _('Date format'), $opt_datefmt, $datefmt); if ($user->role == 'captain'): ?>

    +
    + + > +
    > diff --git a/webgui/storage.php b/webgui/storage.php index 8821878..a42e26b 100644 --- a/webgui/storage.php +++ b/webgui/storage.php @@ -7,6 +7,7 @@ ******************************************************************************/ require 'globals.inc'; +require 'lib/db.inc'; require 'lib/gpc.inc'; $pagetitle = _('Storage'); diff --git a/webgui/tag.php b/webgui/tag.php index 2fd9f03..20a6907 100644 --- a/webgui/tag.php +++ b/webgui/tag.php @@ -7,6 +7,7 @@ ******************************************************************************/ require 'globals.inc'; +require 'lib/db.inc'; require 'lib/gpc.inc'; $pagetitle = _('Tags'); diff --git a/webgui/task.php b/webgui/task.php index a9cdaf5..ebda77b 100644 --- a/webgui/task.php +++ b/webgui/task.php @@ -7,6 +7,7 @@ ******************************************************************************/ require 'globals.inc'; +require 'lib/db.inc'; require 'lib/gpc.inc'; $pagetitle = _('Task'); @@ -73,6 +74,7 @@ switch ($submit = form_get_action()) { $p[':finished'] = gpc_get_datetime($_POST, 'finished'); $p[':taskstate'] = gpc_get_enum($_POST, 'taskstate', array_keys($opt_state)); $p[':responsible'] = gpc_get_int($_POST, 'responsible'); + $p[':remarks'] = gpc_get_string($_POST, 'remarks', 150); db_exec_update('task', $p, 'taskid'); $action = ACT_VIEW; break; @@ -297,7 +299,7 @@ elseif ($action == ACT_VIEW): $sql = "SELECT t.taskname, t.priority, t.plandate, t.duedate," . " t.started, t.finished, t.taskstate, t.responsible," - . " u.displayname, p.projname " + . " t.remarks, u.displayname, p.projname " . "FROM task AS t LEFT JOIN project AS p USING (projid) " . " LEFT JOIN user AS u ON (t.responsible=u.userid) " . "WHERE taskid=?"; @@ -316,6 +318,7 @@ echo '', _('Started at'),"", $task->started, "\n"; echo '', _('Finished at'),"", $task->finished, "\n"; echo '', _('Status'),"", $opt_state[$task->taskstate], "\n"; echo '', _('Responsible'),"", $task->displayname, "\n"; +echo '', _('Remarks'),"", h($task->remarks, br:true), "\n"; echo "\n"; form_view_buttons($g_scriptname, $id); @@ -392,7 +395,12 @@ form_create_select('priority', _('Priority'), $opt_none + $opt_priority, $task-> taskstate); form_create_select('responsible', _('Responsible'), $opt_user, $user->id); - +?> +
    + + +
    +\n";