From 562aa587ad141b43e4a9beaa35fafcdc63c1b7a2 Mon Sep 17 00:00:00 2001 From: Thomas Hooge Date: Mon, 20 Jul 2026 13:05:15 +0200 Subject: [PATCH] Added default storage to vessel and some other fixes --- db/mariadb.sql | 1 + db/minimal_en.sql | 2 +- webgui/box.php | 7 +++-- webgui/globals.inc | 37 ++++++++++++++++++++++- webgui/index.php | 41 +++++++++++++++++++++----- webgui/inventory.php | 32 ++++++++++++++++---- webgui/lib/gpc.inc | 11 +++++++ webgui/projects.php | 18 ++++++++---- webgui/shapes/etap23.svg | 63 ++++++++++++++++++++++++++++++++++++++++ webgui/storage.php | 18 ++++++++++-- 10 files changed, 205 insertions(+), 25 deletions(-) create mode 100644 webgui/shapes/etap23.svg diff --git a/db/mariadb.sql b/db/mariadb.sql index aac3e8d..7dfd123 100644 --- a/db/mariadb.sql +++ b/db/mariadb.sql @@ -74,6 +74,7 @@ CREATE TABLE vessel ( beltpos_aft float(4,2) UNSIGNED DEFAULT NULL, beltpos_bow float(4,2) UNSIGNED DEFAULT NULL, shapefile varchar(40) DEFAULT NULL, + sid_default smallint(6) UNSIGNED DEFAULT NULL, -- default storage remarks varchar(150) DEFAULT NULL, PRIMARY KEY (vid) ) ENGINE=InnoDB; diff --git a/db/minimal_en.sql b/db/minimal_en.sql index 41ee71f..4849c77 100644 --- a/db/minimal_en.sql +++ b/db/minimal_en.sql @@ -70,7 +70,7 @@ INSERT INTO dropdown (ddid, ddval, ddtext) VALUES INSERT INTO dropdown (ddid, ddval, ddtext, flags) VALUES (2, 1, 'Supplier', 'fixed'), (2, 2, 'Manufacturer', 'fixed'), -(2, 3, 'Shipyard', fixed), +(2, 3, 'Shipyard', 'fixed'), (2, 9, 'Generic', 'fixed'); INSERT INTO dropdown (ddid, ddval, ddtext, flags) VALUES diff --git a/webgui/box.php b/webgui/box.php index ff7ab54..ec65943 100644 --- a/webgui/box.php +++ b/webgui/box.php @@ -20,6 +20,7 @@ $pagetitle = _('Boxes'); $id = gpc_get_int($_REQUEST, 'id', 0); +// TODO use global function // Storage options $sql = "SELECT sid, sname FROM storage WHERE vid=? ORDER BY sname"; $sth = $pdo->prepare($sql); @@ -44,7 +45,7 @@ switch ($submit = form_get_action()) { case 'insert': $p[':label'] = gpc_get_string($_POST, 'label'); - $p[':sid'] = gpc_get_int($_POST, 'sid'); + $p[':sid'] = gpc_get_uint($_POST, 'sid'); $p[':content'] = gpc_get_string($_POST, 'content'); $p[':remarks'] = gpc_get_string($_POST, 'remarks'); $id = db_exec_insert('box', $p); @@ -59,6 +60,7 @@ switch ($submit = form_get_action()) { $p[':content'] = gpc_get_string($_POST, 'content'); $p[':color'] = gpc_get_color($_POST, 'color'); $p[':weight'] = min(gpc_get_float($_POST, 'weight'), 99.99); + $p[':sid'] = gpc_get_uint($_POST, 'sid'); $p[':remarks'] = gpc_get_string($_POST, 'remarks', 150); db_exec_update('box', $p, 'boxid'); $action = ACT_VIEW; @@ -231,7 +233,7 @@ if ($res) { elseif ($action == ACT_EDIT): // ========== VARIANT: edit single record ===================================== -$sql = "SELECT boxtype, label, content, color, weight, remarks " +$sql = "SELECT boxtype, label, content, color, weight, sid, remarks " . "FROM box " . "WHERE boxid=?"; $sth = $pdo->prepare($sql); @@ -261,6 +263,7 @@ echo '

', _('Edit Box'), "

\n"; +sid); ?>
diff --git a/webgui/globals.inc b/webgui/globals.inc index d3e2ccc..12f55f6 100644 --- a/webgui/globals.inc +++ b/webgui/globals.inc @@ -128,6 +128,7 @@ $g_doc_mimetypes = ['image/png', 'image/jpeg', 'image/svg+xml', 'application/pdf // form option lists $g_opt_all = array(-2 => _('― all ―')); $g_opt_none = array(-1 => _('― none ―')); +$g_opt_empty = array('' => _('― none ―')); $g_opt_unknown = array(-1 => _('― unknown ―')); // Initialize message system @@ -392,6 +393,7 @@ function db_exec_insert($table, $params) { $g_error->Add('SQL-Error: '. $e->getMessage()); $g_error->Add($sql); $g_error->Add(print_r($params, true)); + return false; } return $pdo->LastInsertId(); } @@ -772,7 +774,6 @@ function db_get_opt_vessel() { return $list; } - function db_get_opt_storage($vid) { global $pdo; global $g_error; @@ -927,6 +928,40 @@ function db_get_filter($user, $sno, $fields = []) { return $flt; } +function db_get_default_storage($vesselid, $fallback=true) { + global $pdo; + global $g_error, $g_warning; + $sql = "SELECT sid_default FROM vessel WHERE vid=?"; + $sth = $pdo->prepare($sql); + try { + $sth->execute([$vesselid]); + } catch(PDOException $e) { + $g_error->Add($e->getMessage()); + return false; + } + $sid = $sth->fetchColumn(); + if ($sid == NULL && $fallback) { + // try to get another storage as last fallback + $g_warning->Add(_('No default storage defined for current vessel')); + $sql = "SELECT MIN(sid), sname FROM storage WHERE vid=?"; + $sth = $pdo->prepare($sql); + try { + $sth->execute([$vesselid]); + } catch(PDOException $e) { + $g_error->Add($e->getMessage()); + return false; + } + $row = $sth->fetch(PDO::FETCH_NUM); + if ($row[0] == NULL) { + $g_error->Add('Error: No storage defined for current vessel'); + return false; + } + $sid = $row[0]; + $g_warning->Add(sprintf(_("Selected fallback storage '%s'"), $row[1])); + } + return $sid; +} + function date_to_sql($var) { if (!isset($var) || $var == '') { return NULL; diff --git a/webgui/index.php b/webgui/index.php index 029ceb8..54efd45 100644 --- a/webgui/index.php +++ b/webgui/index.php @@ -79,6 +79,7 @@ switch ($submit = form_get_action()) { $p[':shapefile'] = NULL; } $p[':shipyard'] = gpc_get_int($_POST, 'shipyard'); + $p[':sid_default'] = gpc_get_uint($_POST, 'sid'); $p[':remarks'] = gpc_get_string($_POST, 'remarks', 150); db_exec_update('vessel', $p, 'vid'); $action = ACT_DEFAULT; @@ -448,13 +449,37 @@ echo '

', _('Add additional yacht'), "

\n"; elseif ($action == ACT_EDIT): // ========== VARIANT: edit single record ===================================== -// get list of shapefiles -//$opt_shapefiles = array('' => _('--- none ---')); -$opt_shapefiles = $g_opt_none; -foreach (glob($g_shapedir.'/*.svg') as $f) { - $f = basename($f); - $opt_shapefiles[$f] = $f; +// check if there is a shapefile-index +$shapeindexfile = $g_doc_basepath . '/shapeindex.json'; +$shapeindex = []; +if (!file_exists($shapeindexfile)) { + // try to read metadata from top of svg file + foreach (glob($g_shapedir.'/*.svg') as $f) { + $fh = fopen($f, 'r'); + $fname = basename($f); + $header = fread($fh, 1024); + if (preg_match('/]*>(.*?)<\/title>/is', $header, $match)) { + $title = trim($match[1]); + } else { + $title = $fname; + } + $shapeindex[$fname] = $title; + fclose($fh); + } + $json = json_encode($shapeindex, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); + file_put_contents($shapeindexfile, $json); +} else { + // read svg metadata from existing file + $json = file_get_contents($shapeindexfile); + $shapeindex = json_decode($json, true); + if (json_last_error() !== JSON_ERROR_NONE) { + // TODO some kind of error and fallback + // perhaps regenerate index file? + } } +$opt_shapefiles = $g_opt_none + $shapeindex; + +$opt_storage = db_get_opt_storage($user->vid); $opt_shipyard = $g_opt_none + [-3 => _('― Custom-built ―')]; $sql = "SELECT compid, compname FROM company WHERE comptype=3 ORDER BY compname"; @@ -465,7 +490,7 @@ foreach ($sth->fetchAll(PDO::FETCH_NUM) as $row) { $sql = "SELECT vesselname, vtype, model, loa, lwl, beam, draught, draught_min," . " displacement, ballast, beltpos_aft, beltpos_bow, shapefile," - . " shipyard, remarks " + . " shipyard, sid_default, remarks " . "FROM vessel " . "WHERE vid=?"; $sth = $pdo->prepare($sql); @@ -526,6 +551,8 @@ $vessel = $sth->fetch(PDO::FETCH_OBJ);
*/ form_create_select('shapefile', _('Shape file'), $opt_shapefiles, $vessel->shapefile); form_create_select('shipyard', _('Shipyard'), $opt_shipyard, $vessel->shipyard); +form_create_select('sid', _('Default Storage'), $g_opt_none + $opt_storage, $vessel->sid_default); + ?>
diff --git a/webgui/inventory.php b/webgui/inventory.php index 43f9a01..0a4ae2b 100644 --- a/webgui/inventory.php +++ b/webgui/inventory.php @@ -48,9 +48,18 @@ switch ($submit = form_get_action()) { $p[':invname'] = gpc_get_string($_POST, 'invname'); $p[':number'] = gpc_get_int($_POST, 'number'); $p[':conttype'] = gpc_get_string($_POST, 'conttype'); - $p[':sid'] = gpc_get_int($_POST, 'sid'); - $p[':boxid'] = gpc_get_int($_POST, 'boxid'); - $p[':invcond'] = 'good'; + $p[':sid'] = gpc_get_uint($_POST, 'sid', 0); + $p[':boxid'] = gpc_get_uint($_POST, 'boxid', 0); + if ($p[':sid'] == NULL && $p[':boxid'] == NULL) { + $p[':conttype'] = 'storage'; + $sid = db_get_default_storage($user->vid); + if ($sid === false) { + $action = ACT_ADD; + break; + } + $p[':sid'] = $sid; + } + $p[':invcond'] = 'unknown'; $id = db_exec_insert('inventory', $p); $action = ACT_VIEW; break; @@ -60,8 +69,17 @@ switch ($submit = form_get_action()) { $p[':invname'] = gpc_get_string($_POST, 'invname'); $p[':number'] = gpc_get_int($_POST, 'number'); $p[':conttype'] = gpc_get_string($_POST, 'conttype'); - $p[':sid'] = gpc_get_int($_POST, 'sid'); - $p[':boxid'] = gpc_get_int($_POST, 'boxid'); + $p[':sid'] = gpc_get_uint($_POST, 'sid', 0); + $p[':boxid'] = gpc_get_uint($_POST, 'boxid', 0); + if ($p[':sid'] == NULL && $p[':boxid'] == NULL) { + $p[':conttype'] = 'storage'; + $sid = db_get_default_storage($user->vid); + if ($sid === false) { + $action = ACT_VIEW; + break; + } + $p[':sid'] = $sid; + } $p[':weight'] = min(gpc_get_float($_POST, 'weight'), 999.99); // limit max value $p[':price'] = gpc_get_currency($_POST, 'price'); $p[':purchdate'] = gpc_get_date($_POST, 'purchdate'); @@ -351,7 +369,9 @@ echo '', "\n"; echo '\n"; // Container with link -echo "\n"; echo "\n"; diff --git a/webgui/lib/gpc.inc b/webgui/lib/gpc.inc index c2758db..1fb6f51 100644 --- a/webgui/lib/gpc.inc +++ b/webgui/lib/gpc.inc @@ -30,6 +30,17 @@ function gpc_get_int(&$GPC, $varname, $default = NULL) { return (int)$GPC[$varname]; } +function gpc_get_uint(&$GPC, $varname, $default = NULL) { + if (!isset($GPC[$varname])) { + return $default; + } + $val = (int)$GPC[$varname]; + if ($val < 0) { + $val = $default; + } + return $val; +} + function gpc_get_float(&$GPC, $varname, $default = NULL) { global $g_lconv; if (!isset($GPC[$varname]) or (strlen(trim($GPC[$varname])) == 0)) { diff --git a/webgui/projects.php b/webgui/projects.php index 9d2b68e..e4e76e4 100644 --- a/webgui/projects.php +++ b/webgui/projects.php @@ -330,18 +330,24 @@ if (empty($res)) { + "; - echo ""; - echo ""; - form_action_buttons('task.php', $row['taskid']); - echo "\n"; + echo ""; + echo ""; + echo ""; + // Edit current record button + echo "\n"; + echo "\n"; } // endforeach; - echo "
', _('Box type'),"", $inventory->conttype, "
", _('Container'),"", sprintf(_('%s in %s'), $box['label'], $storagename); +echo '
', $inventory->conttype == 'storage' ? _('Storage') : _('Container'); +echo '', sprintf(_('%s in %s'), $box['label'], $storagename); +// TODO insert link echo "
", _('Location ID'), "", $inventory->locationid, "
#
", $i++, "", $row['taskname'], "
", $i++; + echo '', "\n"; + echo "", $row['taskname'], ""; + echo '', "\n"; + echo "
\n"; + echo "\n"; } // not empty form_add_button('task.php', $id, 'projid'); diff --git a/webgui/shapes/etap23.svg b/webgui/shapes/etap23.svg new file mode 100644 index 0000000..2f9b1a0 --- /dev/null +++ b/webgui/shapes/etap23.svg @@ -0,0 +1,63 @@ + +Etap 23Etap 23 diff --git a/webgui/storage.php b/webgui/storage.php index 4b4aa06..8ddaa18 100644 --- a/webgui/storage.php +++ b/webgui/storage.php @@ -14,6 +14,7 @@ $pagetitle = _('Storage'); $id = gpc_get_int($_REQUEST, 'id', 0); $opt_stype = db_get_options(3); +$opt_capaunit = $g_opt_empty + db_load_enum('storage', 'capaunit', true, true); // ========== ACTIONS START =================================================== @@ -44,6 +45,10 @@ switch ($submit = form_get_action()) { $p[':wx'] = gpc_get_int($_POST, 'wx'); $p[':wy'] = gpc_get_int($_POST, 'wy'); $p[':wz'] = gpc_get_int($_POST, 'wz'); + $p[':angle'] = gpc_get_int($_POST, 'angle'); + $p[':capacity'] = gpc_get_int($_POST, 'capacity'); + if ($p[':capacity'] == 0) $p[':capacity'] = NULL; + $p[':capaunit'] = gpc_get_string($_POST, 'capaunit'); $p[':remarks'] = gpc_get_string($_POST, 'remarks', 150); db_exec_update('storage', $p, 'sid'); $action = ACT_VIEW; @@ -180,7 +185,7 @@ foreach ($res as $row) { } // Table summary $numrows = count($res); -table_rec_summary($i, $numrows, $numrows, 4); +table_rec_summary($i, $numrows, $numrows, 5); echo "\n"; form_add_button('box.php'); @@ -277,7 +282,7 @@ elseif ($action == ACT_EDIT): echo '

', _('Edit Storage'), "

\n"; -$sql = "SELECT sid, sname, stype, x, y, z, wx, wy, wz, remarks " +$sql = "SELECT sid, sname, stype, x, y, z, wx, wy, wz, angle, capacity, capaunit, remarks " . "FROM storage " . "WHERE sid=?"; $sth = $pdo->prepare($sql); @@ -322,6 +327,15 @@ form_create_select('stype', _('Type'), $opt_stype, $storage->stype);
+
+ + +
+
+ + +
+capaunit); ?>