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 '| ', _('Box type')," | ", $inventory->conttype, " |
\n";
// Container with link
-echo "| ", _('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 " |
\n";
echo "| ", _('Location ID'), " | ", $inventory->locationid, " |
\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)) {
| # |
=_('Task')?> |
+ |
";
- echo "", $i++, " | ";
- echo "", $row['taskname'], " | ";
- form_action_buttons('task.php', $row['taskid']);
- echo "\n";
+ echo "";
+ echo "| ", $i++;
+ echo '', "\n";
+ echo " | ";
+ echo "", $row['taskname'], " | ";
+ // Edit current record button
+ echo "";
+ echo '', "\n";
+ echo " | \n";
+ echo "
\n";
} // endforeach;
- 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 @@
+
+
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); ?>