diff --git a/INSTALL b/INSTALL
index f8adab8..acba838 100644
--- a/INSTALL
+++ b/INSTALL
@@ -81,7 +81,7 @@ group (here as example 'yms'). The user which runs the local gui (here
chgrp yms /var/local/lib/yms/thumb
chmod -R 770 /var/local/lib/yms
-4. Setup local GUI
+5. Setup local GUI
Create a local database user with same name as your computer user and allow
database access with current unix credentials. E.g if your current unix user
diff --git a/debian/control b/debian/control
index f831913..2f04de6 100644
--- a/debian/control
+++ b/debian/control
@@ -17,6 +17,7 @@ Depends:
gir1.2-gtk-3.0,
gir1.2-rsvg-2.0,
python3-mysqldb,
+ python3-fitz,
python3-bcrypt,
python3-pyudev,
php (>= 8.0),
diff --git a/webgui/box.php b/webgui/box.php
index 3106b94..bc0f5ec 100644
--- a/webgui/box.php
+++ b/webgui/box.php
@@ -31,7 +31,7 @@ foreach ($sth->fetchAll() as $row) {
$opt_storage[$row['sid']] = $row['sname'];
}
-$opt_boxtype = db_get_options(9);
+$opt_boxtype = db_get_options(DD_BOX_TYPE);
// ========== ACTIONS START ===================================================
diff --git a/webgui/cable.php b/webgui/cable.php
index 019e87a..edda1c3 100644
--- a/webgui/cable.php
+++ b/webgui/cable.php
@@ -14,8 +14,8 @@ $pagetitle = _('Cables');
$id = gpc_get_int($_REQUEST, 'id', 0);
-$opt_cabletype = db_get_options(11);
-$opt_techname = db_get_options(12);
+$opt_cabletype = db_get_options(DD_CABLE_TYPE);
+$opt_techname = db_get_options(DD_CABLE_TECHNAME);
$opt_cablecond = db_load_enum('cable', 'cablecond', true, true);
// ========== ACTIONS START ===================================================
diff --git a/webgui/company.php b/webgui/company.php
index e6dbec3..6761ec7 100644
--- a/webgui/company.php
+++ b/webgui/company.php
@@ -13,7 +13,7 @@ require 'lib/gpc.inc';
$pagetitle=_('Company');
$id = gpc_get_int($_REQUEST, 'id', 0);
-$opt_comptype = db_get_options(2);
+$opt_comptype = db_get_options(DD_COMPANY_TYPE);
// ========== ACTIONS START ===================================================
diff --git a/webgui/dropdown.php b/webgui/dropdown.php
index 357f500..6c52356 100644
--- a/webgui/dropdown.php
+++ b/webgui/dropdown.php
@@ -84,6 +84,8 @@ switch ($submit = form_get_action()) {
break;
case 'update':
+ # changing ddval would need to update all dependent data
+ # so this is not intended here!
$p[':ddtext'] = gpc_get_string($_POST, 'ddtext');
$p[':ddshort'] = gpc_get_string($_POST, 'ddshort');
$p[':color'] = gpc_get_color($_POST, 'color');
@@ -132,7 +134,7 @@ $sth = $pdo->query($sql);
foreach ($sth->fetchAll(PDO::FETCH_NUM) as $row) {
$num[$row[0]] = $row[1];
}
-$sql = "SELECT ddval, ddtext FROM dropdown WHERE ddid=0 AND ddval>0";
+$sql = "SELECT ddval, ddtext, flags FROM dropdown WHERE ddid=0 AND ddval>0";
$sth = $pdo->query($sql);
echo "
$pagetitle \n";
@@ -160,7 +162,11 @@ foreach ($sth->fetchAll() as $row) {
echo '', $num[$row['ddval']] ?? 0, ' ';
// form_action_buttons($g_scriptname, $row['ddval']);
echo "";
- echo ' ';
+ if ($row['flags'] == 'locked') {
+ echo _('Locked');
+ } else {
+ echo ' ';
+ }
echo " \n";
echo "\n";
}
diff --git a/webgui/equipment.php b/webgui/equipment.php
index 465a3d8..8bdfc65 100644
--- a/webgui/equipment.php
+++ b/webgui/equipment.php
@@ -18,8 +18,8 @@ $id = gpc_get_int($_REQUEST, 'id', 0);
$opt_supplier = db_get_opt_supp($g_opt_unknown);
$opt_manufacturer = db_get_opt_manuf($g_opt_unknown);
-$opt_ecat = db_get_options(4); // Equipment categories
-$opt_unit = db_get_options(8);
+$opt_ecat = db_get_options(DD_EQUIPMENT_CATEGORY);
+$opt_unit = db_get_options(DD_UNIT);
// ========== ACTIONS START ===================================================
diff --git a/webgui/fuse.php b/webgui/fuse.php
index 7c174d4..1914da4 100644
--- a/webgui/fuse.php
+++ b/webgui/fuse.php
@@ -14,8 +14,8 @@ $pagetitle = _('Fuses');
$id = gpc_get_int($_REQUEST, 'id', 0);
-$opt_ftype = db_get_options(7);
-$opt_location = db_get_options(10);
+$opt_ftype = db_get_options(DD_FUSE_TYPE);
+$opt_location = db_get_options(DD_FUSE_BLOCK);
// ========== ACTIONS START ===================================================
@@ -94,7 +94,7 @@ if ($action == ACT_DEFAULT):
// ========== VARIANT: default behavior =======================================
// lookup tables
-$opt_ftype_short = db_get_options(7, '', true);
+$opt_ftype_short = db_get_options(DD_FUSE_TYPE, '', true);
// load filter from db
$flt = db_get_filter($user->id, 212);
diff --git a/webgui/globals.inc b/webgui/globals.inc
index bbc3584..2c692f1 100644
--- a/webgui/globals.inc
+++ b/webgui/globals.inc
@@ -15,6 +15,7 @@
* 0.2.0 2026-08-18 First public release tho
* 0.2.1 2026-08-28 Foreign keys, bugfixes and output sanitation tho
* 0.2.2 2026-09-21 Lots of improvements and fixes tho
+ * 2026-10-01 Dropdown constants for readability tho
*
*/
@@ -47,6 +48,22 @@ define('ROLE_CAPTAIN', 'captain');
define('ROLE_HELMSMAN', 'helmsman');
define('ROLE_SAILOR', 'sailor');
+define('DD_HULL_TYPE', 1);
+define('DD_COMPANY_TYPE', 2);
+define('DD_STORAGE_TYPE', 3);
+define('DD_EQUIPMENT_CATEGORY', 4);
+define('DD_PROVISION_CATEGORY', 5);
+define('DD_PROVISION_UNIT', 6);
+define('DD_FUSE_TYPE', 7);
+define('DD_UNIT', 8);
+define('DD_BOX_TYPE', 9);
+define('DD_FUSE_BLOCK', 10);
+define('DD_CABLE_TYPE', 11);
+define('DD_CABLE_TECHNAME', 12);
+define('DD_INVENTORY_CATEGORY', 13);
+define('DD_BBN_VESSELDATA', 14);
+define('DD_MEASUREMENT_CATEGORY', 15);
+
// ========== PAGE START CODE =================================================
// global version string
diff --git a/webgui/index.php b/webgui/index.php
index 4fb20d8..856b7a5 100644
--- a/webgui/index.php
+++ b/webgui/index.php
@@ -351,7 +351,7 @@ if ($user->role == 'captain') {
// Storage: 0 - default, 1 - tank
// $stype = [ 0 => _('Default'), 1 => _('Tank')];
-$stype = db_get_options(3);
+$stype = db_get_options(DD_STORAGE_TYPE);
$sql = "SELECT stype, COUNT(stype) "
. "FROM storage "
. "WHERE vid=? "
diff --git a/webgui/inventory.php b/webgui/inventory.php
index a5005df..8296192 100644
--- a/webgui/inventory.php
+++ b/webgui/inventory.php
@@ -18,7 +18,7 @@ $opt_storage = db_get_opt_storage($user->vid);
$opt_box = db_get_opt_box($user->vid);
$opt_invcond = db_load_enum('inventory', 'invcond', true, true);
$opt_equipment = db_get_opt_equip($user->vid, [-1 => _('― none ―')]);
-$opt_icat = db_get_options(13);
+$opt_icat = db_get_options(DD_INVENTORY_CATEGORY);
// ========== ACTIONS START ===================================================
diff --git a/webgui/measurement.php b/webgui/measurement.php
index 9929be8..504950c 100644
--- a/webgui/measurement.php
+++ b/webgui/measurement.php
@@ -25,7 +25,8 @@ $pagetitle = _('Measurements');
$id = gpc_get_int($_REQUEST, 'id', 0);
-$opt_unit = db_get_options(8);
+$opt_unit = db_get_options(DD_UNIT);
+$opt_category = db_get_options(DD_MEASUREMENT_CATEGORY);
$opt_accuracy = db_load_enum('measurement', 'accuracy', true, true);
$opt_dimensions = array(
1 => _('1D'),
@@ -102,6 +103,10 @@ switch ($submit = form_get_action()) {
$p[':unit'] = gpc_get_int($_POST, 'unit');
$p[':accuracy'] = gpc_get_string($_POST, 'accuracy');
$p[':mdate'] = gpc_get_date($_POST, 'mdate');
+ $p[':mcat'] = gpc_get_int($_POST, 'mcat');
+ if ($p[':mcat'] == -1) {
+ $p[':mcat'] = NULL;
+ }
$p[':note'] = gpc_get_string($_POST, 'note');
$p[':eid'] = gpc_get_int($_POST, 'eid');
if ($p[':eid'] == -1) {
@@ -291,7 +296,7 @@ form_create_select('eid', _('Equipment'), $opt_equipment, $id);
elseif ($action == ACT_VIEW):
// ========== VARIANT: view single record =====================================
-$sql = "SELECT mname, unit, nval, val1, val2, val3, accuracy, mdate, note, eid "
+$sql = "SELECT mname, unit, nval, val1, val2, val3, accuracy, mdate, mcat, note, eid "
. "FROM measurement "
. "WHERE mid=?";
$sth = $pdo->prepare($sql);
@@ -310,6 +315,7 @@ echo '', _('Value 3'), ' ', $measurement->val3, " \n";
echo '', _('Accuracy'), ' ', get_enum($measurement->accuracy), " \n";
echo '', _('Date'), ' ', format_date($measurement->mdate), " \n";
echo '', _('Note'), ' ', h($measurement->note), " \n";
+echo '', _('Category')," ", $opt_category[$measurement->mcat] ?? 'n/a', " \n";
echo '', _('Equipment'), ' ', $opt_equipment[$measurement->eid], " \n";
echo "\n";
@@ -319,7 +325,7 @@ form_view_buttons($g_scriptname, $id);
elseif ($action == ACT_EDIT):
// ========== VARIANT: edit single record =====================================
-$sql = "SELECT mname, nval, val1, val2, val3, unit, accuracy, note, eid "
+$sql = "SELECT mname, nval, val1, val2, val3, unit, accuracy, note, eid, mcat "
. "FROM measurement "
. "WHERE mid=?";
$sth = $pdo->prepare($sql);
@@ -356,6 +362,7 @@ form_create_select('nval', _('Dimensions'), $opt_dimensions, $measurement->nval)
unit);
form_create_select('accuracy', _('Accuracy'), $opt_accuracy, $measurement->accuracy);
+form_create_select('mcat', _('Category'), $g_opt_none + $opt_category, $measurement->mcat);
form_create_select('eid', _('Equipment'), $opt_equipment, $measurement->eid);
form_edit_buttons($g_scriptname, $id);
diff --git a/webgui/provisions.php b/webgui/provisions.php
index 0fabf86..d92c57b 100644
--- a/webgui/provisions.php
+++ b/webgui/provisions.php
@@ -15,8 +15,8 @@ $pagetitle=_('Provisions');
$id = gpc_get_int($_REQUEST, 'id', 0);
$opt_storage = db_get_opt_storage($user->vid);
-$opt_category = db_get_options(5);
-$opt_unit = db_get_options(6);
+$opt_category = db_get_options(DD_PROVISION_CATEGORY);
+$opt_unit = db_get_options(DD_PROVISION_UNIT);
// ========== ACTIONS START ===================================================
diff --git a/webgui/storage.php b/webgui/storage.php
index 793dd0e..906e3c2 100644
--- a/webgui/storage.php
+++ b/webgui/storage.php
@@ -14,7 +14,7 @@ $pagetitle = _('Storage');
$id = gpc_get_int($_REQUEST, 'id', 0);
-$opt_stype = db_get_options(3);
+$opt_stype = db_get_options(SS_STORAGE_TYPE);
$opt_capaunit = $g_opt_empty + db_load_enum('storage', 'capaunit', true, true);
// ========== ACTIONS START ===================================================
@@ -50,6 +50,7 @@ switch ($submit = form_get_action()) {
$p[':capacity'] = gpc_get_int($_POST, 'capacity');
if ($p[':capacity'] == 0) $p[':capacity'] = NULL;
$p[':capaunit'] = gpc_get_string($_POST, 'capaunit');
+ $p[':color'] = gpc_get_color($_POST, 'color');
$p[':remarks'] = gpc_get_string($_POST, 'remarks', 150);
db_exec_update('storage', $p, 'sid');
$action = ACT_VIEW;
@@ -107,7 +108,7 @@ page_caption_search($pagetitle);
// Storage
// stype from dropdown
-$sql = "SELECT sid, sname, x, y, z, angle, remarks "
+$sql = "SELECT sid, sname, color, x, y, z, angle, remarks "
. "FROM storage "
. "WHERE vid=? "
. "ORDER BY sid";
@@ -119,6 +120,7 @@ echo "\n";
echo "";
echo '# ';
echo "", _('Name'), " ";
+echo "", _('Color'), " ";
echo "", _('Position'), " ";
echo "", _('Remarks'), " ";
echo " ";
@@ -132,6 +134,7 @@ foreach ($res as $row) {
echo ' ', "\n";
echo "\n";
echo "", $row['sname'], " \n";
+ echo '', format_color(strtoupper($row['color'])), " \n";
if ($row['angle'] != 0) {
$angle = " (" . $row['angle'] . "°)";
} else {
@@ -216,7 +219,7 @@ form_create_select('stype', _('Type'), $opt_stype);
elseif ($action == ACT_VIEW):
// ========== VARIANT: view single record =====================================
-$opt_unit = db_get_options(6);
+$opt_unit = db_get_options(DD_PROVISION_UNIT);
$sql = "SELECT sid, sname, stype, capacity, capaunit, x, y, z, wx, wy, wz, angle, color, remarks "
. "FROM storage "
. "WHERE sid=?";
@@ -358,6 +361,10 @@ form_create_select('stype', _('Type'), $opt_stype, $storage->stype);
capaunit); ?>
+
+ =_('Color')?>
+
+
=_('Remarks')?>
diff --git a/yms.1 b/yms.1
index 703b1ad..7e6754b 100644
--- a/yms.1
+++ b/yms.1
@@ -1,4 +1,4 @@
-.TH YMS 1 "August 2026" "YMS 0.2" "User Commands"
+.TH YMS 1 "September 2026" "YMS 0.2" "User Commands"
.SH NAME
yms - Yacht Management Software
.SH SYNOPSIS
@@ -50,7 +50,7 @@ the application is running.
Per-user configuration file for the YMS graphical user interface.
.TP
-.I /var/local/yms/
+.I /var/local/lib/yms/
Persistent storage for files managed by YMS.
The directory contains photos, documents and other media associated
@@ -60,7 +60,7 @@ SVG and PDF.
YMS stores application data in two separate locations.
The directory
-.I /var/local/yms/
+.I /var/local/lib/yms/
contains user-managed photos and documents and should be included
in regular backups.