Webgui: filter and pagination working

This commit is contained in:
2026-07-15 19:42:55 +02:00
parent 2177834b39
commit a183a4725f
33 changed files with 2088 additions and 750 deletions
+2
View File
@@ -1,3 +1,5 @@
*~ *~
__pycache__/ __pycache__/
compare_*
*.txt
+9 -4
View File
@@ -1,4 +1,4 @@
YMS Installation Yacht Management Software (YMS) Installation
1. Install requirements 1. Install requirements
@@ -6,12 +6,12 @@ YMS Installation
- MariaDB - MariaDB
- Python 3 - Python 3
- python3-bcrypt - python3-bcrypt
- python3-mysqldb
- optional - optional
- gettext - gettext
- mupdf-tools for extended pdf file management - mupdf-tools for extended pdf file management
1.2 Native GUI 1.2 Native GUI
- python3-mysqldb
- Python GTK3 - Python GTK3
- python3-gi - python3-gi
- gir1.2-gtk-3.0 - gir1.2-gtk-3.0
@@ -29,7 +29,12 @@ the privileges for accessing and modifying it.
CREATE DATABASE yms; CREATE DATABASE yms;
Create database-user for application with minimum necessary rights. Create system user for native gui.
CREATE USER 'ymssys'@'localhost' IDENTIFIED BY '********';
GRANT SELECT, INSERT, UPDATE, DELETE ON yms.* TO 'ymssys'@'localhost';
Create database-user for web application with minimum necessary rights.
CREATE USER 'ymsweb'@'localhost' IDENTIFIED BY '********'; CREATE USER 'ymsweb'@'localhost' IDENTIFIED BY '********';
GRANT SELECT, INSERT, UPDATE, DELETE ON yms.* TO 'ymsweb'@'localhost'; GRANT SELECT, INSERT, UPDATE, DELETE ON yms.* TO 'ymsweb'@'localhost';
@@ -72,7 +77,7 @@ file.
5.2. Create and edit webgui config file 5.2. Create and edit webgui config file
Rename sample configfile config.php-sample: Rename sample configfile config.inc-sample:
mv config.inc-sample config.inc mv config.inc-sample config.inc
+5
View File
@@ -6,3 +6,8 @@ Use at your own risk!
If inserting a new user you have also to insert a setting value If inserting a new user you have also to insert a setting value
to assign boat 0. to assign boat 0.
To set your own passwords via console there is a helper script
ymspass.py
Use it to get an SQL-statement for changing passwords.
+95 -52
View File
@@ -3,6 +3,11 @@
/* MariaDB Scheme /* MariaDB Scheme
Version: 1 */ Version: 1 */
/* User
userid is signed because nevative values are required for settings
The user table must not be writeable by the webgui user!
*/
CREATE TABLE user ( CREATE TABLE user (
userid smallint(6) NOT NULL AUTO_INCREMENT, userid smallint(6) NOT NULL AUTO_INCREMENT,
login varchar(20) NOT NULL, login varchar(20) NOT NULL,
@@ -13,7 +18,7 @@ CREATE TABLE user (
language char(2) NOT NULL DEFAULT 'en', language char(2) NOT NULL DEFAULT 'en',
PRIMARY KEY (userid), PRIMARY KEY (userid),
UNIQUE INDEX ix_login (login) UNIQUE INDEX ix_login (login)
); ) ENGINE=InnoDB;
/* Settings /* Settings
E.g. the currently selected boat. Users logged in via the web are allowed E.g. the currently selected boat. Users logged in via the web are allowed
@@ -36,11 +41,12 @@ CREATE TABLE settings (
valstr varchar(200) DEFAULT NULL, valstr varchar(200) DEFAULT NULL,
valint int(10) DEFAULT NULL, valint int(10) DEFAULT NULL,
PRIMARY KEY (userid, sno) PRIMARY KEY (userid, sno)
); ) ENGINE=InnoDB;
/* ddid=0 is list of lists, not editable /* ddid=0 is list of lists, not editable
flags: fixed=not deletable, value not changeable flags: fixed=not deletable, value not changeable
locked=not editable */ locked=not editable
*/
CREATE TABLE dropdown ( CREATE TABLE dropdown (
ddid tinyint(3) UNSIGNED NOT NULL, ddid tinyint(3) UNSIGNED NOT NULL,
ddval tinyint(3) NOT NULL, ddval tinyint(3) NOT NULL,
@@ -50,13 +56,14 @@ CREATE TABLE dropdown (
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)
); ) ENGINE=InnoDB;
CREATE TABLE vessel ( CREATE TABLE vessel (
vid smallint(10) NOT NULL AUTO_INCREMENT, vid smallint(6) NOT NULL AUTO_INCREMENT,
vtype enum('mono','cat','tri') NOT NULL DEFAULT 'mono', vtype enum('mono','cat','tri') NOT NULL DEFAULT 'mono',
vesselname varchar(40) NOT NULL, vesselname varchar(40) NOT NULL,
model varchar(20) DEFAULT NULL, model varchar(20) DEFAULT NULL,
shipyard smallint(6) DEFAULT NULL,
loa float(4,2) UNSIGNED DEFAULT NULL, loa float(4,2) UNSIGNED DEFAULT NULL,
lwl float(4,2) UNSIGNED DEFAULT NULL, lwl float(4,2) UNSIGNED DEFAULT NULL,
beam float(4,2) UNSIGNED DEFAULT NULL, beam float(4,2) UNSIGNED DEFAULT NULL,
@@ -69,10 +76,10 @@ CREATE TABLE vessel (
shapefile varchar(40) DEFAULT NULL, shapefile varchar(40) DEFAULT NULL,
remarks varchar(150) DEFAULT NULL, remarks varchar(150) DEFAULT NULL,
PRIMARY KEY (vid) PRIMARY KEY (vid)
); ) ENGINE=InnoDB;
CREATE TABLE storage ( CREATE TABLE storage (
sid smallint(6) NOT NULL AUTO_INCREMENT, sid smallint(6) UNSIGNED NOT NULL AUTO_INCREMENT,
vid smallint(6) NOT NULL DEFAULT 1, vid smallint(6) NOT NULL DEFAULT 1,
sname varchar(40) NOT NULL, sname varchar(40) NOT NULL,
stype tinyint(3) NOT NULL DEFAULT 0, stype tinyint(3) NOT NULL DEFAULT 0,
@@ -88,34 +95,31 @@ CREATE TABLE storage (
color char(6) DEFAULT NULL, color char(6) DEFAULT NULL,
remarks varchar(150) DEFAULT NULL, remarks varchar(150) DEFAULT NULL,
PRIMARY KEY (sid) PRIMARY KEY (sid)
); ) ENGINE=InnoDB;
/* TODO define cabins? CREATE TABLE cabin ... */
CREATE TABLE tag ( CREATE TABLE tag (
tagid smallint(6) NOT NULL AUTO_INCREMENT, tagid smallint(6) UNSIGNED NOT NULL AUTO_INCREMENT,
tagname varchar(20) NOT NULL, tagname varchar(20) NOT NULL,
color char(6) DEFAULT NULL, color char(6) DEFAULT NULL,
description varchar(80) DEFAULT NULL, description varchar(80) DEFAULT NULL,
PRIMARY KEY (tagid), PRIMARY KEY (tagid),
UNIQUE INDEX ix_tagname (tagname) UNIQUE INDEX ix_tagname (tagname)
); ) ENGINE=InnoDB;
CREATE TABLE tagref ( CREATE TABLE tagref (
tagid smallint(6) NOT NULL, tagid smallint(6) UNSIGNED NOT NULL,
objid smallint(6) NOT NULL, objid int(10) UNSIGNED NOT NULL,
objtype enum('equip','inv','prov','doc', 'proj', 'task', 'maint') NOT NULL, objtype enum('equip','inv','prov','doc', 'proj', 'task', 'maint') NOT NULL,
PRIMARY KEY (tagid, objid, objtype) PRIMARY KEY (tagid, objid, objtype)
); ) ENGINE=InnoDB;
/* TODO Boxes can be nested via parent /* TODO Boxes can be nested via parent
TODO boxsize: (LxWxH) in cm? */ TODO boxsize: (LxWxH) in cm? */
CREATE TABLE box ( CREATE TABLE box (
boxid smallint(6) NOT NULL AUTO_INCREMENT, boxid smallint(6) UNSIGNED NOT NULL AUTO_INCREMENT,
sid smallint(6) NOT NULL, sid smallint(6) UNSIGNED NOT NULL,
boxtype tinyint(3) DEFAULT NULL, boxtype tinyint(3) DEFAULT NULL,
parent int(10) DEFAULT NULL, parent smallint(6) UNSIGNED DEFAULT NULL,
label varchar(20) DEFAULT NULL, label varchar(20) DEFAULT NULL,
color char(6) DEFAULT NULL, color char(6) DEFAULT NULL,
content varchar(60) DEFAULT NULL, content varchar(60) DEFAULT NULL,
@@ -123,33 +127,33 @@ CREATE TABLE box (
remarks varchar(150) DEFAULT NULL, remarks varchar(150) DEFAULT NULL,
PRIMARY KEY (boxid), PRIMARY KEY (boxid),
INDEX ix_label (label) INDEX ix_label (label)
); ) ENGINE=InnoDB;
CREATE TABLE equipment ( CREATE TABLE equipment (
eid smallint(6) NOT NULL AUTO_INCREMENT, eid smallint(6) UNSIGNED NOT NULL AUTO_INCREMENT,
vid smallint(6) NOT NULL DEFAULT 1, vid smallint(6) NOT NULL DEFAULT 1,
ename varchar(80) NOT NULL, ename varchar(80) NOT NULL,
shortname varchar(20) DEFAULT NULL, shortname varchar(20) DEFAULT NULL,
model varchar(40), model varchar(40),
ecat tinyint(3) DEFAULT NULL, ecat tinyint(3) DEFAULT NULL,
serial varchar(30), serial varchar(30) DEFAULT NULL,
supplier smallint(6) DEFAULT NULL, supplier smallint(6) DEFAULT NULL,
manufacturer smallint(6) DEFAULT NULL, // -3: original; -4: own built manufacturer smallint(6) DEFAULT NULL, -- -1: unknown; -3: own built
purchdate date DEFAULT NULL, purchdate date DEFAULT NULL,
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','removed','deleted') DEFAULT NULL, flags set('ordered','removed','deleted') DEFAULT NULL,
PRIMARY KEY(eid) PRIMARY KEY(eid)
); ) ENGINE=InnoDB;
CREATE TABLE inventory ( CREATE TABLE inventory (
invid int(10) NOT NULL AUTO_INCREMENT, invid int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
invname varchar(80) NOT NULL, invname varchar(80) NOT NULL,
conttype enum('storage','box') NOT NULL DEFAULT 'storage', conttype enum('storage','box') NOT NULL DEFAULT 'storage',
sid smallint(6) NOT NULL DEFAULT 1, sid smallint(6) UNSIGNED NOT NULL DEFAULT 1,
boxid smallint(6) NOT NULL DEFAULT 1, boxid smallint(6) UNSIGNED NOT NULL DEFAULT 1,
eid smallint(6) DEFAULT NULL, eid smallint(6) UNSIGNED DEFAULT NULL,
number smallint(6) UNSIGNED NOT NULL DEFAULT 1, number smallint(6) UNSIGNED NOT NULL DEFAULT 1,
weight float(5,2) UNSIGNED DEFAULT NULL, weight float(5,2) UNSIGNED DEFAULT NULL,
price decimal(12,2) DEFAULT NULL, price decimal(12,2) DEFAULT NULL,
@@ -158,30 +162,64 @@ CREATE TABLE inventory (
remarks varchar(150) DEFAULT NULL, remarks varchar(150) DEFAULT NULL,
PRIMARY KEY (invid), PRIMARY KEY (invid),
INDEX ix_invname (invname) INDEX ix_invname (invname)
); ) ENGINE=InnoDB;
CREATE TABLE cable (
cableid smallint(6) UNSIGNED NOT NULL AUTO_INCREMENT,
vid smallint(6) NOT NULL DEFAULT 1,
cablename varchar(80) NOT NULL,
cabletype varchar(40) DEFAULT NULL, -- e.g. H07RN-F
length float(5,2) UNSIGNED NOT NULL DEFAULT 0, -- total length in m
conductors TINYINT(3) UNSIGNED NOT NULL DEFAULT 1,
diameter float(5,2) UNSIGNED DEFAULT NULL, -- outer diameter in mm
xsection float(5,2) UNSIGNED DEFAULT NULL, -- cross section in mm²
weight float(5,2) UNSIGNED DEFAULT NULL, -- kg/meter
color char(6) DEFAULT NULL,
supplier smallint(6) DEFAULT NULL,
manufacturer smallint(6) DEFAULT NULL,
cablecond enum('unknown','new','good','normal','bad','repairable','defect') NOT NULL default 'unknown',
remarks varchar(150) DEFAULT NULL,
PRIMARY KEY (cableid),
INDEX ix_cablename (vid, cablename)
) ENGINE=InnoDB;
CREATE table fuse (
fuseid smallint(6) UNSIGNED NOT NULL AUTO_INCREMENT,
vid smallint(6) NOT NULL DEFAULT 1,
fnumber smallint(6) NOT NULL,
ftype tinyint(3) DEFAULT 0, -- from dropdown id 7
current float(5,2) UNSIGNED NOT NULL, -- in A
cableid smallint(6) UNSIGNED DEFAULT NULL,
eid smallint(6) UNSIGNED DEFAULT NULL,
location tinyint(3) DEFAULT 0, -- from dropdown id 10
description varchar(60) DEFAULT NULL,
remarks varchar(150) DEFAULT NULL,
PRIMARY KEY (fuseid),
UNIQUE INDEX ix_fusenumber (vid, fnumber)
) ENGINE=InnoDB;
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,
vid smallint(6) NOT NULL DEFAULT 1,
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) DEFAULT NULL,
val3 int(10) NOT NULL, val3 int(10) DEFAULT 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) UNSIGNED DEFAULT NULL,
PRIMARY KEY (mid) PRIMARY KEY (mid)
); ) ENGINE=InnoDB;
CREATE TABLE provisions ( CREATE TABLE provisions (
provid int(10) NOT NULL AUTO_INCREMENT, provid int(10) NOT NULL AUTO_INCREMENT,
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) UNSIGNED DEFAULT NULL,
boxid smallint(6) NOT NULL DEFAULT 1, boxid smallint(6) UNSIGNED 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 float(5,2) UNSIGNED DEFAULT NULL,
weight_net float(5,2) UNSIGNED DEFAULT NULL, weight_net float(5,2) UNSIGNED DEFAULT NULL,
@@ -189,8 +227,13 @@ CREATE TABLE provisions (
storedate date DEFAULT CURRENT_DATE, storedate date DEFAULT CURRENT_DATE,
shelflife date DEFAULT NULL, shelflife date DEFAULT NULL,
PRIMARY KEY (provid) PRIMARY KEY (provid)
); ) ENGINE=InnoDB;
/* TODO
- distinction between
docdate - e.g. invoicedate
doctime -> uploadtime
*/
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',
@@ -200,6 +243,7 @@ CREATE TABLE document (
hash varchar(32) NOT NULL, hash varchar(32) NOT NULL,
docsize int(10) unsigned NOT NULL, docsize int(10) unsigned NOT NULL,
doctime datetime DEFAULT NULL, doctime datetime DEFAULT NULL,
docdate date DEFAULT NULL, -- e.g. invoice date
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,
@@ -224,10 +268,10 @@ CREATE TABLE docref (
CREATE TABLE company ( CREATE TABLE company (
compid smallint(6) NOT NULL AUTO_INCREMENT, compid smallint(6) NOT NULL AUTO_INCREMENT,
compname varchar(60) NOT NULL, compname varchar(60) NOT NULL,
comptype tinyint(3) NOT NULL DEFAULT 1, comptype tinyint(3) UNSIGNED NOT NULL DEFAULT 1,
comptype2 tinyint(3) DEFAULT NULL, comptype2 tinyint(3) UNSIGNED DEFAULT NULL,
shortname varchar(20) DEFAULT NULL, shortname varchar(20) DEFAULT NULL,
street varchar(30), street varchar(40),
zip varchar(10), zip varchar(10),
city varchar(30), city varchar(30),
country varchar(30), country varchar(30),
@@ -240,20 +284,19 @@ CREATE TABLE company (
remarks varchar(150) DEFAULT NULL, remarks varchar(150) DEFAULT NULL,
PRIMARY KEY (compid), PRIMARY KEY (compid),
UNIQUE INDEX ix_compname (compname, comptype) UNIQUE INDEX ix_compname (compname, comptype)
); ) ENGINE=InnoDB;
/* TODO optional field: plan date, target date, completion date */ /* TODO optional field: plan date, target date, completion date */
CREATE TABLE maintenance ( CREATE TABLE maintenance (
maintid int(10) NOT NULL AUTO_INCREMENT, maintid int(10) NOT NULL AUTO_INCREMENT,
vid smallint(6) NOT NULL DEFAULT 1, vid smallint(6) NOT NULL DEFAULT 1,
eid smallint(6) DEFAULT NULL, eid smallint(6) UNSIGNED DEFAULT NULL,
series smallint(6) DEFAULT NULL, series smallint(6) DEFAULT NULL,
activities varchar(40) NOT NULL, activities varchar(40) NOT NULL,
remarks varchar(150) DEFAULT NULL, remarks varchar(150) DEFAULT NULL,
maintstate enum('new','planned','ongoing','done') NOT NULL DEFAULT 'new', maintstate enum('new','planned','ongoing','done') NOT NULL DEFAULT 'new',
PRIMARY KEY (maintid) PRIMARY KEY (maintid)
); ) ENGINE=InnoDB;
/* TODO? time recording */ /* TODO? time recording */
@@ -269,7 +312,7 @@ CREATE TABLE project (
remarks varchar(150) DEFAULT NULL, remarks varchar(150) DEFAULT NULL,
projstate enum('new','plan','ongoing','paused','finished') NOT NULL DEFAULT 'new', projstate enum('new','plan','ongoing','paused','finished') NOT NULL DEFAULT 'new',
PRIMARY KEY (projid) PRIMARY KEY (projid)
); ) ENGINE=InnoDB;
CREATE TABLE task ( CREATE TABLE task (
taskid int(10) NOT NULL AUTO_INCREMENT, taskid int(10) NOT NULL AUTO_INCREMENT,
@@ -286,16 +329,16 @@ CREATE TABLE task (
responsible smallint(6) NOT NULL, responsible smallint(6) NOT NULL,
/* TODO executed_by : company or user? or both? */ /* TODO executed_by : company or user? or both? */
PRIMARY KEY (taskid) PRIMARY KEY (taskid)
); ) ENGINE=InnoDB;
// Notes can be assigned to tasks,maintenances and equipment /* 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','equip') 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)
); ) ENGINE=InnoDB;
CREATE TABLE checklist ( CREATE TABLE checklist (
clid smallint(6) NOT NULL AUTO_INCREMENT, clid smallint(6) NOT NULL AUTO_INCREMENT,
@@ -303,7 +346,7 @@ CREATE TABLE checklist (
parent smallint(6) DEFAULT 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)
); ) ENGINE=InnoDB;
CREATE TABLE checkitem ( CREATE TABLE checkitem (
checkid int(10) NOT NULL AUTO_INCREMENT, checkid int(10) NOT NULL AUTO_INCREMENT,
@@ -311,17 +354,17 @@ CREATE TABLE checkitem (
groupid tinyint(3) DEFAULT NULL, groupid tinyint(3) DEFAULT NULL,
checkresult enum('unchecked','checked','unused') NOT NULL DEFAULT 'unused', checkresult enum('unchecked','checked','unused') NOT NULL DEFAULT 'unused',
PRIMARY KEY (checkid) PRIMARY KEY (checkid)
); ) ENGINE=InnoDB;
CREATE TABLE checkref ( CREATE TABLE checkref (
clid smallint(6) NOT NULL, clid smallint(6) NOT NULL,
checkid int(10) NOT NULL, checkid int(10) NOT NULL,
sort smallint(6) DEFAULT NULL, sort smallint(6) DEFAULT NULL,
PRIMARY KEY (clid, checkid) PRIMARY KEY (clid, checkid)
); ) ENGINE=InnoDB;
CREATE TABLE checkgroup ( CREATE TABLE checkgroup (
groupid int(10) NOT NULL, groupid int(10) NOT NULL,
title varchar(30) NOT NULL, title varchar(30) NOT NULL,
PRIMARY KEY (groupid) PRIMARY KEY (groupid)
); ) ENGINE=InnoDB;
+9 -2
View File
@@ -36,6 +36,8 @@ INSERT INTO settings (userid, sno, valstr) VALUES
(-1, 108, 'company sorting order'), (-1, 108, 'company sorting order'),
(-1, 109, 'document sorting order'), (-1, 109, 'document sorting order'),
(-1, 110, 'tag sorting order'), (-1, 110, 'tag sorting order'),
(-1, 111, 'cable sorting order'),
(-1, 112, 'fuse sorting order'),
(-1, 200, 'equipment filter json'), (-1, 200, 'equipment filter json'),
(-1, 201, 'inventory filter json'), (-1, 201, 'inventory filter json'),
(-1, 202, 'provision filter json'), (-1, 202, 'provision filter json'),
@@ -46,7 +48,9 @@ INSERT INTO settings (userid, sno, valstr) VALUES
(-1, 207, 'measurement filter json'), (-1, 207, 'measurement filter json'),
(-1, 208, 'company filter json'), (-1, 208, 'company filter json'),
(-1, 209, 'document filter json'), (-1, 209, 'document filter json'),
(-1, 210, 'tag filter json'); (-1, 210, 'tag filter json'),
(-1, 211, 'cable filter json'),
(-1, 212, 'fuse filter json');
/* Liste der Listen wird immer benötigt */ /* Liste der Listen wird immer benötigt */
INSERT INTO dropdown (ddid, ddval, ddtext) VALUES INSERT INTO dropdown (ddid, ddval, ddtext) VALUES
@@ -59,11 +63,14 @@ INSERT INTO dropdown (ddid, ddval, ddtext) VALUES
(0, 6, 'Provianteinheiten'), (0, 6, 'Provianteinheiten'),
(0, 7, 'Sicherungstypen'), (0, 7, 'Sicherungstypen'),
(0, 8, 'Einheiten'), (0, 8, 'Einheiten'),
(0, 9, 'Kistentypen'); (0, 9, 'Kistentypen'),
(0, 10, 'Sicherungsblöcke'), -- fuse locations
(0, 11, 'Kabeltypen');
INSERT INTO dropdown (ddid, ddval, ddtext, flags) VALUES INSERT INTO dropdown (ddid, ddval, ddtext, flags) VALUES
(2, 1, 'Lieferant', 'fixed'), (2, 1, 'Lieferant', 'fixed'),
(2, 2, 'Hersteller', 'fixed'), (2, 2, 'Hersteller', 'fixed'),
(2, 3, 'Werft', 'fixed'), -- to store yacht manufacturer
(2, 9, 'Sonstiges', 'fixed'); (2, 9, 'Sonstiges', 'fixed');
INSERT INTO dropdown (ddid, ddval, ddtext, flags) VALUES INSERT INTO dropdown (ddid, ddval, ddtext, flags) VALUES
+20 -6
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), -- Database schema version (0, 0, 1), -- Database schema version
(0, 1, 0), -- No vessel for SYSTEM (0, 1, 0), -- No vessel assignment to SYSTEM
(1, 1, 0); -- No vessel for 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'),
@@ -30,6 +36,8 @@ INSERT INTO settings (userid, sno, valstr) VALUES
(-1, 108, 'company sorting order'), (-1, 108, 'company sorting order'),
(-1, 109, 'document sorting order'), (-1, 109, 'document sorting order'),
(-1, 110, 'tag sorting order'), (-1, 110, 'tag sorting order'),
(-1, 111, 'cable sorting order'),
(-1, 112, 'fuse sorting order'),
(-1, 200, 'equipment filter json'), (-1, 200, 'equipment filter json'),
(-1, 201, 'inventory filter json'), (-1, 201, 'inventory filter json'),
(-1, 202, 'provision filter json'), (-1, 202, 'provision filter json'),
@@ -40,9 +48,11 @@ INSERT INTO settings (userid, sno, valstr) VALUES
(-1, 207, 'measurement filter json'), (-1, 207, 'measurement filter json'),
(-1, 208, 'company filter json'), (-1, 208, 'company filter json'),
(-1, 209, 'document filter json'), (-1, 209, 'document filter json'),
(-1, 210, 'tag filter json'); (-1, 210, 'tag filter json'),
(-1, 211, 'cable filter json'),
(-1, 212, 'fuse filter json');
/* list of lists needed */ /* list of lists always needed */
INSERT INTO dropdown (ddid, ddval, ddtext) VALUES INSERT INTO dropdown (ddid, ddval, ddtext) VALUES
(0, 0, 'list of lists'), (0, 0, 'list of lists'),
(0, 1, 'hull type'), (0, 1, 'hull type'),
@@ -53,12 +63,16 @@ INSERT INTO dropdown (ddid, ddval, ddtext) VALUES
(0, 6, 'provision unit'), (0, 6, 'provision unit'),
(0, 7, 'fuse type'), (0, 7, 'fuse type'),
(0, 8 , 'unit'); (0, 8 , 'unit');
(0, 9, 'box types'),
(0.10, 'fuse blocks'),
(0,11, 'cable types');
INSERT INTO dropdown (ddid, ddval, ddtext, flags) VALUES INSERT INTO dropdown (ddid, ddval, ddtext, flags) VALUES
(2, 1, 'Supplier', 'fixed'), (2, 1, 'Supplier', 'fixed'),
(2, 2, 'Manufacturer', 'fixed'), (2, 2, 'Manufacturer', 'fixed'),
(2, 3, 'Shipyard', fixed),
(2, 9, 'Generic', 'fixed'); (2, 9, 'Generic', 'fixed');
INSERT INTO dropdown (ddid, ddval, ddtext, flags) VALUES INSERT INTO dropdown (ddid, ddval, ddtext, flags) VALUES
(3, 0, 'Generic', 'fixed'), (3, 0, 'Generic storage', 'fixed'),
(3, 1, 'Tank', 'fixed'); (3, 1, 'Tank', 'fixed');
+2
View File
@@ -6,4 +6,6 @@ mv /var/www/html/config.inc-sample /var/www/html/config.inc
chmod 640 /var/www/html/config.inc chmod 640 /var/www/html/config.inc
chgrp www-data /var/www/html/config.inc chgrp www-data /var/www/html/config.inc
rm /var/www/html/index.html rm /var/www/html/index.html
rm /var/www/html/README
rm /var/www/html/TODO
rm /var/www/html/locale/de_DE.po rm /var/www/html/locale/de_DE.po
+305
View File
@@ -0,0 +1,305 @@
<?php
/******************************************************************************
* YMS - Yacht Management Software
* Copyright (C) 2024-2026 Thomas Hooge
*
* SPDX-License-Identifier: WTFPL
******************************************************************************/
require 'globals.inc';
require 'lib/gpc.inc';
$pagetitle = _('Cables');
$id = gpc_get_int($_REQUEST, 'id', 0);
$opt_cabletype = db_get_options(11);
$opt_cablecond = db_load_enum('cable', 'cablecond', true, true);
// ========== ACTIONS START ===================================================
switch ($submit = form_get_action()) {
case NULL: break;
case 'add': $action = ACT_ADD; break;
case 'view': $action = ACT_VIEW; break;
case 'edit': $action = ACT_EDIT; break;
case 'del': $action = ACT_DELETE; break;
case 'filter':
$flt = array();
$flt['txt'] = gpc_get_string($_POST, 'flt_txt');
db_save_filter($flt, 211);
$action = ACT_DEFAULT;
break;
case 'freset':
db_clear_filter(211);
$action = ACT_DEFAULT;
break;
case 'insert':
$p[':cablename'] = gpc_get_string($_POST, 'cablename');
$p[':length'] = gpc_get_float($_POST, 'length');
$p[':conductors'] = gpc_get_int($_POST, 'conductors');
$p[':xsection'] = gpc_get_float($_POST, 'xsection');
$id = db_exec_insert('cable', $p);
$action = ACT_VIEW;
break;
case 'update':
$p[':cableid'] = $id;
$p[':cablename'] = gpc_get_string($_POST, 'cablename');
$p[':cabletype'] = gpc_get_int($_POST, 'cabletype');
$p[':length'] = gpc_get_float($_POST, 'length');
$p[':conductors'] = gpc_get_int($_POST, 'conductors');
$p[':xsection'] = gpc_get_float($_POST, 'xsection');
$p[':diameter'] = gpc_get_float($_POST, 'diameter');
$p[':weight'] = gpc_get_float($_POST, 'weight');
$p[':color'] = gpc_get_color($_POST, 'color');
$p[':cablecond'] = gpc_get_string($_POST, 'cablecond');
$p[':remarks'] = gpc_get_string($_POST, 'remarks');
db_exec_update('cable', $p, 'cableid');
$action = ACT_VIEW;
break;
case 'delete':
// Security token needed!
if (gpc_get_string($_POST, 'token', 16) != $_SESSION['token']) {
$g_error->Add(_('Delete prohibited, invalid security token!'));
$action = ACT_VIEW;
break;
}
// TODO
$action = ACT_DEFAULT;
break;
default:
$g_error->Add(sprintf(_('Unknown function!'), $submit));
$valid = FALSE;
}
// ========== ACTIONS END =====================================================
require 'header.php';
// ========== PAGE CONTENT ====================================================
if ($action == ACT_DEFAULT):
// ========== VARIANT: default behavior =======================================
// load filter from db
$flt = db_get_filter($user->id, 211);
echo "<h1>$pagetitle</h1>\n";
// Filter
?>
<form method="post" action="<?=$g_scriptname?>">
<div id="filter" class="card">
<div class="card-header"><i class="bi bi-funnel me-2"></i>Filter</div>
<div class="card-body d-flex flex-wrap gap-3">
<div class="d-flex flex-nowrap gap-2">
<label for="flt_txt">Text</label>
<input type="text" class="form-control" name="flt_txt" 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[freset]" class="btn btn-sm btn-secondary float-end" title="<?=_('Reset filter to defaults')?>"><?=_('Clear')?></button>
</div>
</div>
</form>
<?php
$sql = "SELECT cableid, cablename, conductors, length, xsection, color, cablecond "
. "FROM cable "
. "ORDER BY cablename";
$sth = $pdo->query($sql);
$res = $sth->fetchAll();
echo '<table class="table table-striped">', "\n";
echo "<thead>\n";
echo "<tr>\n";
echo '<th>#</th>';
echo '<th>', _('Cable'), "</th>";
echo '<th>', _('Name'), "</th>";
echo '<th>', _('Conductors'), "</th>";
echo '<th>', _('Length'), "</th>";
echo '<th>', _('Cross section'), "</th>";
echo '<th>', _('Color'), "</th>";
echo '<th>', _('Condition'), "</th>";
echo "<th></th>";
echo "</tr>\n";
echo "</thead>\n";
$i = 0;
foreach ($res as $row) {
$i++; // record number
echo "<tr>\n";
echo '<td>', $i;
echo '<a class="text-nowrap" title="', _('View'), '" href="', $g_scriptname, '?f=view&id=', $row['cableid'], '"><i class="bi bi-eye ms-2"></i></a>', "\n";
echo "</td>\n";
echo "<td>", $row['cableid'], "</td>\n";
echo "<td>", $row['cablename'], "</td>\n";
echo "<td>", $row['conductors'], "</td>\n";
echo "<td>", $row['length'], "m</td>\n";
echo "<td>", $row['xsection'], "mm²</td>\n";
echo "<td>", format_color($row['color']), "</td>\n";
echo "<td>", $row['condition'], "</td>\n";
echo "<td>";
echo '<a title="', _('Edit'), '" href="', $g_scriptname, '?f=edit&id=', $row['cableid'], '"><i class="bi-pencil"></i></a>', "\n";
echo "</td>\n";
echo "</tr>\n";
}
// Table summary
echo "<tfoot>\n";
echo '<tr><td colspan="6">', sprintf(_('%d records'), count($res)), '</td></tr>', "\n";
echo "</tfoot>\n";
echo "</table>\n";
form_add_button($g_scriptname);
elseif ($action == ACT_ADD):
// ========== VARIANT: add record =============================================
echo '<h2>', _('Add Cable'), "</h2>\n";
?>
<form method="post" action="<?=$g_scriptname?>">
<div class="mb-3">
<label for="tagname" class="form-label"><?=_('Name')?></label>
<input type="text" class="form-control" id="cablename" name="cablename" required autofocus>
</div>
<div class="mb-3">
<label for="note" class="form-label"><?=_('Length, m')?></label>
<input type="text" class="form-control" id="length" name="length">
</div>
<?php
form_create_select('cabletype', _('Type'), $g_opt_none + $opt_cabletype);
?>
<div class="mb-3">
<label for="note" class="form-label"><?=_('Conductors')?></label>
<input type="text" class="form-control" id="conductors" name="conductors">
</div>
<div class="mb-3">
<label for="note" class="form-label"><?=_('Cross section, mm²')?></label>
<input type="text" class="form-control" id="xsection" name="xsection">
</div>
<?php
form_new_buttons($g_scriptname);
echo "</form>\n";
elseif ($action == ACT_VIEW):
// ========== VARIANT: view single record =====================================
$sql = "SELECT cablename, cabletype, length, conductors, diameter, xsection,"
. " weight, color, supplier, manufacturer, cablecond, remarks "
. "FROM cable "
. "WHERE cableid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
$cable = $sth->fetch(PDO::FETCH_OBJ);
echo '<h2>', _('View cable'), "</h2>\n";
echo '<table class="table">', "\n";
echo '<tr><th style="width:20%">', _('Cable'),"</th><td>", $cable->cablename, "</td></tr>\n";
echo '<tr><th>', _('Type'),"</th><td>", $opt_cabletype[$cable->cabletype], "</td></tr>\n";
echo '<tr><th>', _('Length'),"</th><td>", format_float($cable->length, 1, 'm'), "</td></tr>\n";
echo '<tr><th>', _('Conductors'),"</th><td>", $cable->conductors, "</td></tr>\n";
echo '<tr><th>', _('Diameter'),"</th><td>", format_float($cable->diameter, 1, 'mm'), "</td></tr>\n";
echo '<tr><th>', _('Cross section'),"</th><td>", format_float($cable->xsection, 1, 'mm²'), "</td></tr>\n";
echo '<tr><th>', _('Weight'),"</th><td>", format_float($cable->weight, 2, 'kg/m'), "</td></tr>\n";
echo '<tr><th>', _('Color'),"</th><td>", format_color($cable->color), "</td></tr>\n";
echo '<tr><th>', _('Condition'),"</th><td>", $opt_cablecond[$cable->cablecond], "</td></tr>\n";
echo "<tr><th>", _('Remarks'), "</th><td>", nl2br($cable->remarks), "</td></tr>\n";
echo "</table>\n";
form_view_buttons($g_scriptname, $id);
elseif ($action == ACT_EDIT):
// ========== VARIANT: edit single record =====================================
$sql = "SELECT cablename, cabletype, length, conductors, diameter, xsection,"
. " weight, color, supplier, manufacturer, cablecond, remarks "
. "FROM cable "
. "WHERE cableid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
$cable = $sth->fetch(PDO::FETCH_OBJ);
echo '<h2>', _('Edit cable'), "</h2>\n";
?>
<form method="post" action="<?=$g_scriptname?>">
<input type="hidden" name="id" value="<?=$id?>">
<div class="mb-3">
<label for="mname" class="form-label"><?=_('Name')?></label>
<input type="text" class="form-control" id="cablename" name="cablename" value="<?=$cable->cablename;?>">
</div>
<?php
form_create_select('cabletype', _('Type'), $g_opt_none + $opt_cabletype, $cable->cabletype);
?>
<div class="mb-3">
<label for="note" class="form-label"><?=_('Length, m')?></label>
<input type="text" class="form-control" id="length" name="length" value="<?=format_float($cable->length, 1);?>">
</div>
<div class="mb-3">
<label for="note" class="form-label"><?=_('Conductors')?></label>
<input type="text" class="form-control" id="conductors" name="conductors" value="<?=$cable->conductors;?>">
</div>
<div class="mb-3">
<label for="note" class="form-label"><?=_('Diameter, mm')?></label>
<input type="text" class="form-control" id="diameter" name="diameter" value="<?=format_float($cable->diameter, 1);?>">
</div>
<div class="mb-3">
<label for="note" class="form-label"><?=_('Cross section, mm²')?></label>
<input type="text" class="form-control" id="xsection" name="xsection" value="<?=format_float($cable->xsection, 1);?>">
</div>
<div class="mb-3">
<label for="note" class="form-label"><?=_('Weight, kg/m')?></label>
<input type="text" class="form-control" id="weight" name="weight" value="<?=$cable->weight;?>">
</div>
<div class="mb-3">
<label for="color" class="form-label"><?=_('Color')?></label>
<input type="color" name="color" id="color" class="form-control" value="#<?=$cable->color;?>">
</div>
<?php
form_create_select('cablecond', _('Condition'), $opt_cablecond, $cable->cablecond);
?>
<div class="mb-3">
<label for="remarks" class="form-label"><?=_('Remarks')?></label>
<textarea class="form-control" id="remarks" name="remarks" rows="3"><?=$cable->remarks ?></textarea>
</div>
<?php
form_edit_buttons($g_scriptname, $id);
echo "</form>\n";
elseif ($action == ACT_DELETE):
// ========== VARIANT: delete record ==========================================
echo '<h2>', _('Delete cable'), "</h2>\n";
$sql = "SELECT objid, objtype FROM tagref WHERE tagid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
if ($sth->rowCount() > 0) {
foreach ($sth->fetchAll() as $row) {
echo '<a href="', $link[$row['objtype']], '?f=view&id=', $row['objid'], '">', $row['objid'], '/', $row['objtype'], "</a>\n";
}
} else {
echo _('Tag is not used anywhere');
$_SESSION['token'] = bin2hex(random_bytes(8));
form_delete_buttons($g_scriptname, $id, $_SESSION['token']);
}
else:
// ========== ERROR UNKNOWN VARIANT ===========================================
echo '<p>', _('Unknown function call: Please report to system development!'), "</p>\n";
endif; // $action == ...
// ========== END OF VARIANTS =================================================
include 'footer.php';
+17 -10
View File
@@ -51,7 +51,8 @@ switch ($submit = form_get_action()) {
$p[':shortname'] = gpc_get_string($_POST, 'shortname', 20); $p[':shortname'] = gpc_get_string($_POST, 'shortname', 20);
$p[':comptype'] = gpc_get_int($_POST, 'comptype'); $p[':comptype'] = gpc_get_int($_POST, 'comptype');
$p[':comptype2'] = gpc_get_int($_POST, 'comptype2'); $p[':comptype2'] = gpc_get_int($_POST, 'comptype2');
$p[':street'] = gpc_get_string($_POST, 'street', 30); if ($p[':comptype2'] <= 0) $p[':comptype2'] = NULL;
$p[':street'] = gpc_get_string($_POST, 'street', 40);
$p[':zip'] = gpc_get_string($_POST, 'zip', 10); $p[':zip'] = gpc_get_string($_POST, 'zip', 10);
$p[':city'] = gpc_get_string($_POST, 'city', 30); $p[':city'] = gpc_get_string($_POST, 'city', 30);
$p[':country'] = gpc_get_string($_POST, 'country', 30); $p[':country'] = gpc_get_string($_POST, 'country', 30);
@@ -98,7 +99,7 @@ if ($action == ACT_DEFAULT):
page_caption_search($pagetitle); page_caption_search($pagetitle);
// load filter from db // load filter from db
$flt = db_get_filter($user->id, 208); $flt = db_get_filter($user->id, 208, ['type','txt']);
$w = array(); $w = array();
$p = array(); $p = array();
@@ -132,7 +133,7 @@ try {
} }
$numrows = $sth->fetchColumn(); $numrows = $sth->fetchColumn();
$page = gpc_get_int($_REQUEST, 'p', 1); $page = gpc_get_int($_REQUEST, 'p', 1);
$rows_pp = gpc_get_int($_REQUEST, 'n', $g_rows_pp); $rows_pp = gpc_get_int($_REQUEST, 'n', $user->rows_pp);
$lastpage = ceil($numrows/$rows_pp); $lastpage = ceil($numrows/$rows_pp);
$sql = "SELECT compid, compname, comptype, remarks " $sql = "SELECT compid, compname, comptype, remarks "
@@ -141,7 +142,7 @@ if ($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);
try { try {
@@ -161,9 +162,10 @@ $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"><i class="bi bi-funnel me-2"></i>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">
<div class="d-flex flex-nowrap gap-2">
<label for="flt_type">Type</label> <label for="flt_type">Type</label>
<select id="flt_type" name="flt_type"> <select id="flt_type" class="form-select" name="flt_type">
<?php <?php
foreach ($opt_special + $opt_comptype as $k => $v) { foreach ($opt_special + $opt_comptype as $k => $v) {
echo '<option value="', $k,'"'; echo '<option value="', $k,'"';
@@ -174,10 +176,15 @@ foreach ($opt_special + $opt_comptype as $k => $v) {
} }
?> ?>
</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" class="form-control" 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[freset]" class="btn btn-sm btn-secondary float-end" title="<?=_('Reset filter to defaults')?>"><?=_('Clear')?></button>
</div> </div>
</div> </div>
</form> </form>
+2 -1
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
*****************************************************************************/ *****************************************************************************/
@@ -11,6 +11,7 @@
define('APP_TITLE', 'Yacht Management Software'); define('APP_TITLE', 'Yacht Management Software');
define('APP_TITLE_SHORT', 'YMS'); define('APP_TITLE_SHORT', 'YMS');
define('APP_SESSION', 'yms'); define('APP_SESSION', 'yms');
define('APP_ILLUSTRATION', 'sailboat.svg');
// ========== GLOBAL VARIABLES ================================================ // ========== GLOBAL VARIABLES ================================================
+6 -6
View File
@@ -229,7 +229,7 @@ if ($action == ACT_DEFAULT):
page_caption_search($pagetitle); page_caption_search($pagetitle);
$flt = db_get_filter($user->id, 209); $flt = db_get_filter($user->id, 209, ['doctype','reftype','txt']);
// $w = array('(vid=:vid OR vid IS NULL)'); // $w = array('(vid=:vid OR vid IS NULL)');
// $p = array(':vid' => $user->vid); // $p = array(':vid' => $user->vid);
@@ -289,7 +289,7 @@ try {
} }
$numrows = $sth->fetchColumn(); $numrows = $sth->fetchColumn();
$page = gpc_get_int($_REQUEST, 'p', 1); $page = gpc_get_int($_REQUEST, 'p', 1);
$rows_pp = gpc_get_int($_REQUEST, 'n', $g_rows_pp); $rows_pp = gpc_get_int($_REQUEST, 'n', $user->rows_pp);
$lastpage = ceil($numrows/$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 "
@@ -299,7 +299,7 @@ $sql .= " GROUP BY d.docid, d.doctype, d.filename, d.title";
if ($order) $sql .= $order; if ($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);
@@ -635,7 +635,7 @@ foreach ($sth->fetchAll() as $row) {
<input type="hidden" name="id" value="<?=$id?>"> <input type="hidden" name="id" value="<?=$id?>">
<input type="hidden" name="reftype" value="equipment"> <input type="hidden" name="reftype" value="equipment">
<label for="eid"><?=_('Equipment')?></label> <label for="eid"><?=_('Equipment')?></label>
<select name="refid" id="eid"> <select class="form-select mb-2" name="refid" id="eid">
<?php <?php
foreach ($opt_equipment as $k => $v) { foreach ($opt_equipment as $k => $v) {
echo '<option value="', $k, '">', $v, "</option>\n"; echo '<option value="', $k, '">', $v, "</option>\n";
@@ -665,7 +665,7 @@ foreach ($sth->fetchAll() as $row) {
<input type="hidden" name="id" value="<?=$id?>"> <input type="hidden" name="id" value="<?=$id?>">
<input type="hidden" name="reftype" value="company"> <input type="hidden" name="reftype" value="company">
<label for="compid"><?=_('Company')?></label> <label for="compid"><?=_('Company')?></label>
<select name="refid" id="compid"> <select class="form-select mb-2" name="refid" id="compid">
<?php <?php
foreach ($opt_company as $k => $v) { foreach ($opt_company as $k => $v) {
echo '<option value="', $k, '">', $v, "</option>\n"; echo '<option value="', $k, '">', $v, "</option>\n";
@@ -691,7 +691,7 @@ foreach ($sth->fetchAll() as $row) {
<input type="hidden" name="id" value="<?=$id?>"> <input type="hidden" name="id" value="<?=$id?>">
<input type="hidden" name="reftype" value="vessel"> <input type="hidden" name="reftype" value="vessel">
<label for="vid"><?=_('Vessel')?></label> <label for="vid"><?=_('Vessel')?></label>
<select name="refid" id="vid"> <select class="form-select mb-2" name="refid" id="vid">
<?php <?php
foreach ($opt_vessel as $k => $v) { foreach ($opt_vessel as $k => $v) {
echo '<option value="', $k, '">', $v, "</option>\n"; echo '<option value="', $k, '">', $v, "</option>\n";
+8 -3
View File
@@ -148,14 +148,19 @@ echo '<tr>';
echo '<th>#</th>'; echo '<th>#</th>';
echo '<th>', _('Description'),'</th>'; echo '<th>', _('Description'),'</th>';
echo '<th>', _('Number'),'</th>'; echo '<th>', _('Number'),'</th>';
echo '<td></td>'; echo '<th></th>';
echo '</tr>'; echo '</tr>';
echo '</thead>'; echo '</thead>';
foreach ($sth->fetchAll() as $row) { foreach ($sth->fetchAll() as $row) {
echo '<tr><td>', $row['ddval'],'</td>'; echo '<tr><td>', $row['ddval'];
echo '<a class="text-nowrap" title="', _('View'), '" href="', $g_scriptname, '?f=view&id=', $row['ddval'], '"><i class="bi bi-eye ms-2"></i></a>';
echo '</td>';
echo '<td>', $row['ddtext'], '</td>'; echo '<td>', $row['ddtext'], '</td>';
echo '<td>', $num[$row['ddval']] ?? 0, '</td>'; echo '<td>', $num[$row['ddval']] ?? 0, '</td>';
form_action_buttons($g_scriptname, $row['ddval']); // form_action_buttons($g_scriptname, $row['ddval']);
echo "<td>";
echo '<a class="text-nowrap" title="', _('Edit'), '" href="', $g_scriptname, '?f=edit&id=', $row['ddval'], '"><i class="bi bi-pencil ms-2"></i></a>';
echo "</td>\n";
echo "</tr>\n"; echo "</tr>\n";
} }
echo "</table>\n"; echo "</table>\n";
+7 -8
View File
@@ -14,8 +14,8 @@ $pagetitle = _('Equipment');
$id = gpc_get_int($_REQUEST, 'id', 0); $id = gpc_get_int($_REQUEST, 'id', 0);
$opt_supplier = db_get_opt_supp(array(-1 => _('--- unknown ---'))); $opt_supplier = db_get_opt_supp($g_opt_unknown);
$opt_manufacturer = db_get_opt_manuf(array(-1 => _('--- unknown ---'))); $opt_manufacturer = db_get_opt_manuf($g_opt_unknown);
$opt_ecat = db_get_options(4); // Equipment categories $opt_ecat = db_get_options(4); // Equipment categories
$opt_unit = db_get_options(8); $opt_unit = db_get_options(8);
@@ -232,7 +232,7 @@ if ($action == ACT_DEFAULT):
page_caption_search($pagetitle); page_caption_search($pagetitle);
$flt = db_get_filter($user->id, 200); $flt = db_get_filter($user->id, 200, ['cat','manuf','supp','txt','flags']);
$sort = array( $sort = array(
1 => 'ename', 1 => 'ename',
2 => 'ename DESC' 2 => 'ename DESC'
@@ -288,10 +288,9 @@ try {
$g_error->PrintOut(); $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);
// TODO check against allowed values for rows per page $rows_pp = gpc_get_int($_REQUEST, 'n', $user->rows_pp);
$rows_pp = gpc_get_int($_REQUEST, 'n', $g_rows_pp); $lastpage = ceil($numrows/$rows_pp);
$sql = "SELECT eid, ename, manufacturer, model, serial, remarks, flags," $sql = "SELECT eid, ename, manufacturer, model, serial, remarks, flags,"
. " TIMESTAMPDIFF(MONTH, purchdate, NOW()) AS age_mon " . " TIMESTAMPDIFF(MONTH, purchdate, NOW()) AS age_mon "
@@ -464,7 +463,7 @@ echo "</table>\n";
echo '</div>'; // Column break echo '</div>'; // Column break
echo '<div class="col">', "\n"; echo '<div class="col">', "\n";
echo '<div class="card">', "\n"; echo '<div class="card mb-2">', "\n";
echo '<div class="card-header">', _('Images and documents'), "</div>\n"; echo '<div class="card-header">', _('Images and documents'), "</div>\n";
echo '<div class="card-body d-flex flex-wrap gap-3">', "\n"; echo '<div class="card-body d-flex flex-wrap gap-3">', "\n";
@@ -669,7 +668,7 @@ $equipment = $sth->fetch(PDO::FETCH_OBJ);
</div> </div>
<?php <?php
form_create_select('supplier', _('Supplier'), $opt_supplier, $equipment->supplier); form_create_select('supplier', _('Supplier'), $opt_supplier, $equipment->supplier);
form_create_select('category', _('Category'), [-1 => _('--- unknown ---')] + $opt_ecat, $equipment->ecat); form_create_select('category', _('Category'), $g_opt_unknown + $opt_ecat, $equipment->ecat);
?> ?>
<div class="mb-3"> <div class="mb-3">
<label for="remarks" class="form-label"><?=_('Remarks')?></label> <label for="remarks" class="form-label"><?=_('Remarks')?></label>
+1 -1
View File
@@ -1,5 +1,5 @@
<footer class="bg-body-tertiary text-center"> <footer class="bg-body-tertiary text-center">
<p>Prototyp YMS v0.1</p> <p>Prototyp YMS <?=$g_version?></p>
</footer> </footer>
</div><?php /* Main container */?> </div><?php /* Main container */?>
+297
View File
@@ -0,0 +1,297 @@
<?php
/******************************************************************************
* YMS - Yacht Management Software
* Copyright (C) 2024-2026 Thomas Hooge
*
* SPDX-License-Identifier: WTFPL
******************************************************************************/
require 'globals.inc';
require 'lib/gpc.inc';
$pagetitle = _('Fuses');
$id = gpc_get_int($_REQUEST, 'id', 0);
$opt_ftype = db_get_options(7);
$opt_location = db_get_options(10);
// ========== ACTIONS START ===================================================
switch ($submit = form_get_action()) {
case NULL: break;
case 'add': $action = ACT_ADD; break;
case 'view': $action = ACT_VIEW; break;
case 'edit': $action = ACT_EDIT; break;
case 'del': $action = ACT_DELETE; break;
case 'filter':
$flt = array();
$flt['location'] = gpc_get_int($_POST, 'flt_location');
$flt['txt'] = gpc_get_string($_POST, 'flt_txt');
db_save_filter($flt, 212);
$action = ACT_DEFAULT;
break;
case 'freset':
db_clear_filter(212);
$action = ACT_DEFAULT;
break;
case 'insert':
$p[':vid'] = $user->vid;
$p[':fnumber'] = gpc_get_int($_POST, 'fnumber');;
$p[':ftype'] = gpc_get_int($_POST, 'ftype');;
$p[':current'] = gpc_get_int($_POST, 'current');;
$p[':location'] = gpc_get_int($_POST, 'location');;
$p[':description'] = gpc_get_string($_POST, 'description');
$id = db_exec_insert('fuse', $p);
$action = ACT_VIEW;
break;
case 'update':
$p[':fuseid'] = $id;
$p[':fnumber'] = gpc_get_string($_POST, 'fuseid');
$p[':current'] = gpc_get_float($_POST, 'current');
$p[':cableid'] = gpc_get_int($_POST, 'cableid');
$p[':eid'] = gpc_get_int($_POST, 'id');
$p[':weight'] = min(gpc_get_float($_POST, 'weight'), 9.99); // limit max value
$p[':location'] = gpc_get_int($_POST, 'location');
$p[':description'] = gpc_get_string($_POST, 'description');
$p[':remarks'] = gpc_get_string($_POST, 'remarks');
db_exec_update('tag', $p, 'tagid');
$action = ACT_VIEW;
break;
case 'delete':
// Security token needed!
if (gpc_get_string($_POST, 'token', 16) != $_SESSION['token']) {
$g_error->Add(_('Delete prohibited, invalid security token!'));
$action = ACT_VIEW;
break;
}
// tagref have to be empty
// TODO
$action = ACT_DEFAULT;
break;
default:
$g_error->Add(sprintf(_('Unknown function!'), $submit));
$valid = FALSE;
}
// ========== ACTIONS END =====================================================
require 'header.php';
// ========== PAGE CONTENT ====================================================
if ($action == ACT_DEFAULT):
// ========== VARIANT: default behavior =======================================
// lookup tables
$opt_ftype_short = db_get_options(7, '', true);
// load filter from db
$flt = db_get_filter($user->id, 212);
$w = array('vid=:vid');
$p = array(':vid' => $user->vid);
if ($flt->location == -1) {
$w[] = 'location IS NULL';
} elseif ($flt->location > 0) {
$w[] = 'location=:location';
$p[':location'] = $flt->location;
}
if (strlen($flt->txt) > 1) {
$w[] = 'description LIKE :txt';
$p[':txt'] = '%'.$flt->txt.'%';
}
$where = join(' AND ', $w);
$order = ' ORDER BY fnumber';
echo "<h1>$pagetitle</h1>\n";
// Filter
?>
<form method="post" action="<?=$g_scriptname?>">
<div id="filter" class="card">
<div class="card-header"><i class="bi bi-funnel me-2"></i>Filter</div>
<div class="card-body d-flex flex-wrap gap-3">
<?php
filter_create_select('flt_location', _('Location'), $g_opt_all + $g_opt_none + $opt_location, $flt->location);
?>
<div class="d-flex flex-nowrap gap-2">
<label for="flt_txt"><?=_('Description')?></label>
<input type="text" class="form-control" 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[freset]" class="btn btn-sm btn-secondary float-end" title="<?=_('Reset filter to defaults')?>"><?=_('Clear')?></button>
</div>
</div>
</form>
<?php
$sql = "SELECT fuseid, fnumber, ftype, location, current, description "
. "FROM fuse";
$sql .= ' WHERE ' . $where;
$sql .= $order;
$sth = $pdo->prepare($sql);
$sth->execute($p);
$res = $sth->fetchAll();
echo '<table class="table table-striped">', "\n";
echo "<thead>\n";
echo "<tr>\n";
echo '<th>#</th>';
echo '<th>', pgettext('number', 'Number'), "</th>";
echo '<th>', _('Type'), "</th>";
echo '<th>', _('Current'), "</th>";
echo '<th>', _('Location'), "</th>";
echo '<th>', _('Description'), "</th>";
echo "<th></th>";
echo "</tr>\n";
echo "</thead>\n";
$i = 1;
foreach ($res as $row) {
echo "<tr>\n";
echo '<td>', $i++;
echo '<a class="text-nowrap" title="', _('View'), '" href="', $g_scriptname, '?f=view&id=', $row['fuseid'], '"><i class="bi bi-eye ms-2"></i></a>', "\n";
echo "</td>\n";
echo "<td>F", $row['fnumber'], "</td>\n";
echo "<td>",$opt_ftype_short[$row['ftype']], "</td>\n";
echo "<td>", $row['current'], "A</td>\n";
echo "<td>", $opt_location[$row['location']], "</td>\n";
echo "<td>", $row['description'], "</td>\n";
// Edit current record button
echo "<td>";
echo '<a title="', _('Edit'), '" href="', $g_scriptname, '?f=edit&id=', $row['fusevid'], '"><i class="bi bi-pencil"></i></a>', "\n";
echo "</td>\n";
echo "</tr>\n";
}
// Table summary
echo "<tfoot>\n";
echo '<tr><td colspan="6">', sprintf(_('%d records'), count($res)), '</td></tr>', "\n";
echo "</tfoot>\n";
echo "</table>\n";
form_add_button($g_scriptname);
elseif ($action == ACT_ADD):
// ========== VARIANT: add record =============================================
echo '<h2>', _('Add fuse'), "</h2>\n";
// calc next free fuse number for convenience
$sql = "SELECT max(fnumber) FROM fuse WHERE vid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$user->vid]);
$fnumber = $sth->fetchColumn() + 1;
?>
<form method="post" action="<?=$g_scriptname?>">
<div class="mb-3">
<label for="fnumber" class="form-label"><?=_('Fuse number')?></label>
<input type="text" class="form-control" id="fnumber" name="fnumber" value="<?=$fnumber?>" required>
</div>
<div class="mb-3">
<label for="note" class="form-label"><?=_('Description')?></label>
<input type="text" class="form-control" id="description" name="description" autofocus>
</div>
<?php form_create_select('ftype', _('Type'), $opt_ftype); ?>
<div class="mb-3">
<label for="current" class="form-label"><?=_('Current, Ampere')?></label>
<input type="text" class="form-control" id="current" name="current" required>
</div>
<?php form_create_select('location', _('Location'), $g_opt_none + $opt_location); ?>
<?php
form_new_buttons($g_scriptname);
echo "</form>\n";
elseif ($action == ACT_VIEW):
// ========== VARIANT: view single record =====================================
$sql = "SELECT fnumber, ftype, current, cableid, eid, location, description, remarks "
. "FROM fuse "
. "WHERE fuseid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
$fuse = $sth->fetch(PDO::FETCH_OBJ);
echo '<h2>', _('View fuse'), "</h2>\n";
echo '<table class="table">', "\n";
echo '<tr><th style="width:20%">', _('Fuse'),"</th><td>F", $fuse->fnumber, "</td></tr>\n";
echo '<tr><th>', _('Description'),"</th><td>", $fuse->description, "</td></tr>\n";
echo '<tr><th>', _('Type'),"</th><td>", $opt_ftype[$fuse->ftype], "</td></tr>\n";
echo '<tr><th>', _('Current'),"</th><td>", $fuse->current, "A</td></tr>\n";
echo '<tr><th>', _('Location'),"</th><td>", $opt_location[$fuse->location], "</td></tr>\n";
echo '<tr><th>', _('Cable'),"</th><td>", $fuse->cableid, "</td></tr>\n";
echo '<tr><th>', _('Equipment'),"</th><td>", $fuse->eid, "</td></tr>\n";
echo '<tr><th>', _('Remarks'),"</th><td>", nl2br($fuse->remarks), "</td></tr>\n";
echo "</table>\n";
form_view_buttons($g_scriptname, $id);
elseif ($action == ACT_EDIT):
// ========== VARIANT: edit single record =====================================
$sql = "SELECT fnumber, description "
. "FROM fuse "
. "WHERE fuseid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
$fuse = $sth->fetch(PDO::FETCH_OBJ);
echo '<h2>', _('Edit fuse'), "</h2>\n";
?>
<form method="post" action="<?=$g_scriptname?>">
<input type="hidden" name="id" value="<?=$id?>">
<div class="mb-3">
<label for="mname" class="form-label"><?=pgettext('number', 'Number')?></label>
<input type="text" class="form-control" id="fnumber" name="fnumber" value="<?=$fuse->fnumber ?>">
</div>
<div class="mb-3">
<label for="note" class="form-label"><?=_('Description')?></label>
<input type="text" class="form-control" id="description" name="description" value="<?=$fuse->description ?>">
</div>
<?php
form_edit_buttons($g_scriptname, $id);
echo "</form>\n";
elseif ($action == ACT_DELETE):
// ========== VARIANT: delete record ==========================================
echo '<h2>', _('Delete fuse'), "</h2>\n";
$sql = "SELECT fusename, description FROM fuse WHERE fuseid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$id]);
if ($sth->rowCount() > 0) {
foreach ($sth->fetchAll() as $row) {
echo '<a href="', $link[$row['objtype']], '?f=view&id=', $row['objid'], '">', $row['objid'], '/', $row['objtype'], "</a>\n";
}
} else {
echo _('Fuse is not used anywhere');
$_SESSION['token'] = bin2hex(random_bytes(8));
form_delete_buttons($g_scriptname, $id, $_SESSION['token']);
}
else:
// ========== ERROR UNKNOWN VARIANT ===========================================
echo '<p>', _('Unknown function call: Please report to system development!'), "</p>\n";
endif; // $action == ...
// ========== END OF VARIANTS =================================================
include 'footer.php';
+121 -15
View File
@@ -41,6 +41,9 @@ define ('ACT_VIEW_LIST', 13);
// ========== PAGE START CODE ================================================= // ========== PAGE START CODE =================================================
// global version string
$g_version = 'v0.1.1';
$g_scriptname = basename($_SERVER['SCRIPT_NAME']); $g_scriptname = basename($_SERVER['SCRIPT_NAME']);
require 'config.inc'; require 'config.inc';
@@ -113,6 +116,7 @@ $user = User::GetInstance(); // There can be only one
if ($g_scriptname != 'login.php') { if ($g_scriptname != 'login.php') {
$user->init_from_session(); $user->init_from_session();
$user->load_vessel(); $user->load_vessel();
$user->load_settings();
} }
$action = NULL; $action = NULL;
@@ -124,6 +128,7 @@ $g_doc_mimetypes = ['image/png', 'image/jpeg', 'image/svg+xml', 'application/pdf
// form option lists // form option lists
$g_opt_all = array(-2 => _('&horbar; all &horbar;')); $g_opt_all = array(-2 => _('&horbar; all &horbar;'));
$g_opt_none = array(-1 => _('&horbar; none &horbar;')); $g_opt_none = array(-1 => _('&horbar; none &horbar;'));
$g_opt_unknown = array(-1 => _('&horbar; unknown &horbar;'));
// Initialize message system // Initialize message system
$g_message = new Message; $g_message = new Message;
@@ -227,13 +232,18 @@ class User {
public $flags; public $flags;
public $vid; // current selected vessel public $vid; // current selected vessel
public $vessel; // name of current vessel public $vessel; // name of current vessel
public $datefmt;
public $rows_pp;
private function __construct() { private function __construct() {
global $g_rows_pp;
$this->loggedin = FALSE; $this->loggedin = FALSE;
$this->errormessage = NULL; $this->errormessage = NULL;
$this->flags = []; $this->flags = [];
$this->vid = 1; $this->vid = 1;
$this->vessel = 'Yacht'; $this->vessel = 'Yacht';
$this->datefmt = 'Y-m-d';
$this->rows_pp = $g_rows_pp;
} }
public static function getInstance() { public static function getInstance() {
@@ -300,10 +310,10 @@ class User {
$sth = $pdo->prepare($sql); $sth = $pdo->prepare($sql);
$sth->execute([$this->id]); $sth->execute([$this->id]);
$row = $sth->fetch(); $row = $sth->fetch();
$this->displayname = $row['displayname']; if ($row) {
$this->role = $row['role']; $this->displayname = $row['displayname'];
//$this->displayname = $sth->fetchColumn(); $this->role = $row['role'];
}
} }
function load_vessel() { function load_vessel() {
@@ -314,8 +324,31 @@ class User {
$sth = $pdo->prepare($sql); $sth = $pdo->prepare($sql);
$sth->execute([$this->id]); $sth->execute([$this->id]);
$row = $sth->fetch(); $row = $sth->fetch();
$this->vid = $row['vid']; if ($row) {
$this->vessel = $row['vesselname']; $this->vid = $row['vid'];
$this->vessel = $row['vesselname'];
}
}
function load_settings() {
global $pdo;
// additional user settings
// date format from user settings
$sql = "SELECT valstr FROM settings WHERE userid=? AND sno=2";
$sth = $pdo->prepare($sql);
$sth->execute([$this->id]);
$user_datefmt = $sth->fetchColumn();
if ($user_datefmt) {
$this->datefmt = $user_datefmt;
}
// pagination rows from user settings
$sql = "SELECT valint FROM settings WHERE userid=? AND sno=10";
$sth = $pdo->prepare($sql);
$sth->execute([$this->id]);
$user_rows_pp = $sth->fetchColumn();
if ($user_rows_pp) {
$this->rows_pp = $user_rows_pp;
}
} }
function get_last_error() { function get_last_error() {
@@ -643,6 +676,46 @@ function db_save_taglist($objtype, $objid, $taglist) {
} }
} }
function db_get_tag_target($objtype, $objid) {
// get page name and desctiption e.g. for link creation
global $pdo;
global $g_error;
switch ($objtype) {
case 'equip':
$sql = "SELECT ename FROM equipment WHERE eid=?";
$target = "equipment.php";
break;
case 'inv':
$sql = "SELECT invname FROM inventory WHERE invid=?";
$target = "inventory.php";
break;
case 'prov':
$sql = "SELECT provname FROM provisions WHERE provvid=?";
$target = "provisions.php";
break;
case 'doc':
$sql = "SELECT title FROM document WHERE docid=?";
$target = "documents.php";
break;
case 'proj':
$sql = "SELECT projname FROM project WHERE projid=?";
$target = "projects.php";
break;
case 'task':
$sql = "SELECT taskname FROM task WHERE taskid=?";
$target = "task.php";
break;
case 'maint':
$sql = "SELECT activities FROM maintenance WHERE maintid=?";
$target = 'maintenance.php';
break;
}
$sth = $pdo->prepare($sql);
$sth->execute([$objid]);
$desc = $sth->fetchColumn();
return [$target, $desc];
}
function db_get_ddtext($ddid, $ddval) { function db_get_ddtext($ddid, $ddval) {
// returns single value for dropdown // returns single value for dropdown
global $pdo; global $pdo;
@@ -660,14 +733,20 @@ function db_get_ddtext($ddid, $ddval) {
// Functions to get option lists (key/value) // Functions to get option lists (key/value)
function db_get_options($ddid, $orderby = '', $default = NULL) { function db_get_options($ddid, $orderby = '', $short = False, $default = NULL) {
// returns list for dropdown // returns list for dropdown
// if short is set the short value will be returned
global $pdo; global $pdo;
$list = array(); $list = array();
if ($default != NULL) { if ($default != NULL) {
$list[0] = $default; $list[0] = $default;
} }
$sql = "SELECT ddval, ddtext FROM dropdown WHERE ddid=?"; if ($short) {
$sql = "SELECT ddval, ddshort";
} else {
$sql = "SELECT ddval, ddtext";
}
$sql .= " FROM dropdown WHERE ddid=?";
if ($orderby == 'ddtext') { if ($orderby == 'ddtext') {
$sql .= ' ORDER BY ddtext'; $sql .= ' ORDER BY ddtext';
} elseif ($orderby == 'sort') { } elseif ($orderby == 'sort') {
@@ -819,7 +898,8 @@ function db_get_opt_proj($vid, $default=NULL) {
return $list; return $list;
} }
function db_get_filter($user, $sno) { function db_get_filter($user, $sno, $fields = []) {
// if fields supplied empting missing field are created
global $pdo; global $pdo;
global $g_warning; global $g_warning;
$flt = new stdClass(); $flt = new stdClass();
@@ -827,15 +907,22 @@ function db_get_filter($user, $sno) {
try { try {
$sth->execute([$user, $sno]); $sth->execute([$user, $sno]);
$json = $sth->fetchColumn(); $json = $sth->fetchColumn();
if (!$json) { if ($json === false) {
// no settings record. create empty one for later updates // no settings record. create empty one for later updates
$sth = $pdo->prepare("INSERT INTO settings (userid, sno, valstr) VALUES (?, ?, '{}')"); $sth = $pdo->prepare("INSERT INTO settings (userid, sno, valstr) VALUES (?, ?, '{}')");
$sth->execute([$user, $sno]); $sth->execute([$user, $sno]);
} else { } else {
$flt = json_decode($json); $flt = json_decode($json);
} }
// create missing fields
foreach ($fields as $f) {
if (!property_exists($flt, $f)) {
$flt->$f = null;
}
}
} catch (PDOexception $e) { } catch (PDOexception $e) {
$g_warning->Add('SQL-Error: '. $e->getMessage()); $g_warning->Add('SQL-Error: '. $e->getMessage());
$g_warning->PrintOut();
} }
return $flt; return $flt;
} }
@@ -1155,7 +1242,7 @@ function get_color_brightness($color, $default=0.5) {
function page_caption_search($caption) { function page_caption_search($caption) {
// print page caption with searchbox // print page caption with searchbox
?> ?>
<div class="row align-items-center"> <div class="row row align-items-center justify-content-between">
<div class="col"> <div class="col">
<h1><?=$caption?></h1> <h1><?=$caption?></h1>
</div> </div>
@@ -1193,8 +1280,8 @@ function get_pagination($script, $param, $page, $lastpage, $small=false) {
$out .= '<li class="page-item"><a class="page-link" href="'. $script. $psep. 'p=1">'. _('First'). '</a></li>'. "\n"; $out .= '<li class="page-item"><a class="page-link" href="'. $script. $psep. 'p=1">'. _('First'). '</a></li>'. "\n";
$out .= '<li class="page-item"><a class="page-link" href="'. $script. $psep. 'p='. ($page - 1). '">'. _('Previous'). '</a></li>'. "\n"; $out .= '<li class="page-item"><a class="page-link" href="'. $script. $psep. 'p='. ($page - 1). '">'. _('Previous'). '</a></li>'. "\n";
} else { } else {
$out .= '<li class="page-item disabled"><a class="page-link href="#">'. _('First'). '</a></li>'. "\n"; $out .= '<li class="page-item disabled"><span class="page-link">'. _('First'). '</span></li>'. "\n";
$out .= '<li class="page-item disabled"><a class="page-link href="#">'. _('Previous'). '</a></li>'. "\n"; $out .= '<li class="page-item disabled"><span class="page-link">'. _('Previous'). '</span></li>'. "\n";
} }
if ($lastpage < 10) { if ($lastpage < 10) {
@@ -1205,6 +1292,25 @@ function get_pagination($script, $param, $page, $lastpage, $small=false) {
} }
} else { } else {
// start working with ... dots // start working with ... dots
$start = max(2, $page - 2);
$end = min($lastpage - 1, $page + 2);
$out .= '<li class="page-item"><a class="page-link';
if ($page == 1) $out .= ' active';
$out .= '" href="'. $script. $psep. 'p=1">1</a></li>'. "\n";
if ($start > 2) {
$out .= '<li class="page-item disabled"><span class="page-link">...</span></li>'. "\n";
}
for ($n = $start; $n <= $end; $n++) {
$out .='<li class="page-item"><a class="page-link';
if ($n == $page) $out .= ' active';
$out .= '" href="'. $script. $psep. 'p='. $n. '">'. $n. '</a></li>'. "\n";
}
if ($end < $lastpage - 1) {
$out .= '<li class="page-item disabled"><span class="page-link">...</span></li>';
}
$out .= '<li class="page-item"><a class="page-link';
if ($page == $lastpage) $out .= ' active';
$out .= '" href="'. $script. $psep. 'p='. $lastpage. '">'. $lastpage. '</a></li>'. "\n";
} }
if ($page < $lastpage) { if ($page < $lastpage) {
@@ -1212,8 +1318,8 @@ function get_pagination($script, $param, $page, $lastpage, $small=false) {
$out .= '<li class="page-item"><a class="page-link" href="'. $script. $psep. 'p='. ($page + 1). '">'. _('Next'). '</a></li>'. "\n"; $out .= '<li class="page-item"><a class="page-link" href="'. $script. $psep. 'p='. ($page + 1). '">'. _('Next'). '</a></li>'. "\n";
$out .= '<li class="page-item"><a class="page-link" href="'. $script. $psep. 'p='. $lastpage. '">'. _('Last'). '</a></li>'. "\n"; $out .= '<li class="page-item"><a class="page-link" href="'. $script. $psep. 'p='. $lastpage. '">'. _('Last'). '</a></li>'. "\n";
} else { } else {
$out .= '<li class="page-item disabled"><a class="page-link href="#">'. _('Next'). '</a></li>'. "\n"; $out .= '<li class="page-item disabled"><span class="page-link">'. _('Next'). '</span></li>'. "\n";
$out .= '<li class="page-item disabled"><a class="page-link href="#">'. _('Last'). '</a></li>'. "\n"; $out .= '<li class="page-item disabled"><span class="page-link">'. _('Last'). '</span></li>'. "\n";
} }
// idea: small entry to input page number // idea: small entry to input page number
+64 -29
View File
@@ -78,6 +78,7 @@ switch ($submit = form_get_action()) {
if ($p[':shapefile'] == '-1') { if ($p[':shapefile'] == '-1') {
$p[':shapefile'] = NULL; $p[':shapefile'] = NULL;
} }
$p[':shipyard'] = gpc_get_int($_POST, 'shipyard');
$p[':remarks'] = gpc_get_string($_POST, 'remarks', 150); $p[':remarks'] = gpc_get_string($_POST, 'remarks', 150);
db_exec_update('vessel', $p, 'vid'); db_exec_update('vessel', $p, 'vid');
$action = ACT_DEFAULT; $action = ACT_DEFAULT;
@@ -109,44 +110,68 @@ $sth->execute([$user->id]);
$res = $sth->fetch(PDO::FETCH_NUM); $res = $sth->fetch(PDO::FETCH_NUM);
$vid = ($res[0]); $vid = ($res[0]);
// Switch between vessels
$sth = $pdo->query("SELECT vid, vesselname, model FROM vessel ORDER BY vid");
$res = $sth->fetchAll();
echo '<form class="row align-items-center" method="post">', "\n";
echo '<div class="col-1">', "\n";
echo '<label class="form-label" for="vid">Yacht:</label>';
echo "</div>\n";
echo '<div class="col-4">', "\n";
echo '<select class="form-select" name="vid" id="vid">', "\n";
foreach ($res as $row) {
echo '<option value="', $row['vid'], '"', ($row['vid'] == $vid ? ' selected>' : '>');
echo $row['vesselname'], ' - ', $row['model'];
echo "</option>\n";
}
echo "</select>\n";
echo "</div>\n";
echo '<div class="col">', "\n";
echo '<button type="submit" class="btn btn-secondary" name="submit[select]">', _('Select'), '</button>', "\n";
echo '<button type="submit" class="btn btn-secondary" name="submit[add]">', _('Add yacht'), '</button>', "\n";
echo "</div>\n";
echo "</form>\n";
// Get current vessel data // Get current vessel data
$sql = "SELECT vesselname, model, loa, lwl, beam, draught, draught_min," $sql = "SELECT vesselname, model, loa, lwl, beam, draught, draught_min,"
. " displacement, ballast, beltpos_aft, beltpos_bow, shapefile," . " displacement, ballast, beltpos_aft, beltpos_bow, shapefile,"
. " remarks " . " shipyard, remarks "
. "FROM vessel " . "FROM vessel "
. "WHERE vid=?"; . "WHERE vid=?";
$sth = $pdo->prepare($sql); $sth = $pdo->prepare($sql);
$sth->execute([$vid]); $sth->execute([$vid]);
$vessel = $sth->fetch(PDO::FETCH_OBJ); $vessel = $sth->fetch(PDO::FETCH_OBJ);
// Show remarks first echo '<div class="container-fluid">', "\n"; // head block
if (strlen($vessel->remarks) > 0) {
echo "<p>"; // Switch between vessels
echo nl2br($vessel->remarks); ?>
echo "</p>\n"; <form class="row align-items-center" method="post" action="<?=$g_scriptname?>">
<div class="col-1">
<label class="form-label" for="vid">Yacht:</label>
</div>
<div class="col-4">
<select class="form-select" name="vid" id="vid">', "\n";
<?php
$sth = $pdo->query("SELECT vid, vesselname, model FROM vessel ORDER BY vid");
$res = $sth->fetchAll();
foreach ($res as $row) {
echo ' <option value="', $row['vid'], '"', ($row['vid'] == $vid ? ' selected>' : '>');
echo $row['vesselname'], ' - ', $row['model'];
echo "</option>\n";
} }
?>
</select>
</div>
<div class="col">
<?php
echo ' <button type="submit" class="btn btn-secondary" name="submit[select]">', _('Select'), '</button>', "\n";
echo ' <button type="submit" class="btn btn-secondary" name="submit[add]">', _('Add yacht'), '</button>', "\n";
?>
</div>
</form>
<?php
// Show additional yacht info
echo '<div class="row my-2">', "\n";
echo '<div class="col-1"></div>', "\n";
echo '<div class="col">';
if ($vessel->shipyard) {
if ($vessel->shipyard == -3) {
echo _('Custom-build');
} else {
$sql = "SELECT compname FROM company WHERE compid=?";
$sth = $pdo->prepare($sql);
$sth->execute([$vessel->shipyard]);
echo sprintf(_('Built by %s'), $sth->fetchColumn());
// TODO year of build?
}
}
if (strlen($vessel->remarks) > 0) {
echo nl2br($vessel->remarks);
}
echo "</div>\n";
echo "</div>\n"; // row 2
echo "</div>\n"; // end of yacht head block
// get vessel shape // get vessel shape
// test for predefined base shape // test for predefined base shape
@@ -377,6 +402,8 @@ echo "</table>\n";
<li class="list-group-item"><a href="settings.php"><?=_('Settings')?></a></li> <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="cable.php"><?=_('Cables')?></a></li>
<li class="list-group-item"><a href="fuse.php"><?=_('Fuses')?></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>
</ul> </ul>
</div> </div>
@@ -426,9 +453,16 @@ foreach (glob($g_shapedir.'/*.svg') as $f) {
$opt_shapefiles[$f] = $f; $opt_shapefiles[$f] = $f;
} }
$opt_shipyard = $g_opt_none + [-3 => _('&horbar; Custom-built &horbar;')];
$sql = "SELECT compid, compname FROM company WHERE comptype=3 ORDER BY compname";
$sth = $pdo->query($sql);
foreach ($sth->fetchAll(PDO::FETCH_NUM) as $row) {
$opt_shipyard[$row[0]] = $row[1];
}
$sql = "SELECT vesselname, vtype, model, loa, lwl, beam, draught, draught_min," $sql = "SELECT vesselname, vtype, model, loa, lwl, beam, draught, draught_min,"
. " displacement, ballast, beltpos_aft, beltpos_bow, shapefile," . " displacement, ballast, beltpos_aft, beltpos_bow, shapefile,"
. " remarks " . " shipyard, remarks "
. "FROM vessel " . "FROM vessel "
. "WHERE vid=?"; . "WHERE vid=?";
$sth = $pdo->prepare($sql); $sth = $pdo->prepare($sql);
@@ -488,6 +522,7 @@ $vessel = $sth->fetch(PDO::FETCH_OBJ);
<input type="text" class="form-control" id="shapefile" name="shapefile" value="<?=$vessel->shapefile ?>"> <input type="text" class="form-control" id="shapefile" name="shapefile" value="<?=$vessel->shapefile ?>">
</div> */ </div> */
form_create_select('shapefile', _('Shape file'), $opt_shapefiles, $vessel->shapefile); form_create_select('shapefile', _('Shape file'), $opt_shapefiles, $vessel->shapefile);
form_create_select('shipyard', _('Shipyard'), $opt_shipyard, $vessel->shipyard);
?> ?>
<div class="mb-3"> <div class="mb-3">
<label for="remarks" class="form-label"><?=_('Remarks')?></label> <label for="remarks" class="form-label"><?=_('Remarks')?></label>
+3 -3
View File
@@ -103,7 +103,7 @@ if ($action == ACT_DEFAULT):
page_caption_search($pagetitle); page_caption_search($pagetitle);
$flt = db_get_filter($user->id, 201); $flt = db_get_filter($user->id, 201, ['cond','name','txt']);
/* /*
The only way to find out whether the inventory is on the current boat is to use The only way to find out whether the inventory is on the current boat is to use
@@ -144,7 +144,7 @@ try {
} }
$numrows = $sth->fetchColumn(); $numrows = $sth->fetchColumn();
$page = gpc_get_int($_REQUEST, 'p', 1); $page = gpc_get_int($_REQUEST, 'p', 1);
$rows_pp = gpc_get_int($_REQUEST, 'n', $g_rows_pp); $rows_pp = gpc_get_int($_REQUEST, 'n', $user->rows_pp);
$lastpage = ceil($numrows/$rows_pp); $lastpage = ceil($numrows/$rows_pp);
$sql = "SELECT i.invid, i.invname, i.number, i.invcond, i.eid, s.sname AS container " $sql = "SELECT i.invid, i.invname, i.number, i.invcond, i.eid, s.sname AS container "
@@ -157,7 +157,7 @@ $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);
try { try {
+17
View File
@@ -0,0 +1,17 @@
<?php
/******************************************************************************
* YMS - Yacht Management Software
* Copyright (C) 2024 Thomas Hooge
*
* SPDX-License-Identifier: WTFPL
******************************************************************************
*/
// ========== SVG-FUNCTIONS ===================================================
function svg_create_box($cx, $cy, $w, $h, $fg, $bg) {
}
+691 -512
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.
+1 -1
View File
@@ -47,7 +47,7 @@ $(document).ready(function(){
</div> </div>
<div class="row my-3"> <div class="row my-3">
<div class="col"> <div class="col">
<img src="sailboat.svg" class="img-fluid rounded-start" alt="sailboat"> <img src="<?=APP_ILLUSTRATION?>" class="img-fluid rounded-start" alt="sailboat">
</div> </div>
<div class="col"> <div class="col">
<div class="card-body"> <div class="card-body">
+23 -3
View File
@@ -79,7 +79,7 @@ if ($action == ACT_DEFAULT):
page_caption_search($pagetitle); page_caption_search($pagetitle);
// load filter from db // load filter from db
$flt = db_get_filter($user->id, 204); $flt = db_get_filter($user->id, 204, ['equip','txt']);
// Filter // Filter
$opt_special = array( $opt_special = array(
@@ -140,6 +140,20 @@ if (strlen($flt->txt) > 1) {
$where = join(' AND ', $w); $where = join(' AND ', $w);
$order = ' ORDER BY m.maintid'; $order = ' ORDER BY m.maintid';
$sql = "SELECT COUNT(*) FROM maintenance AS m 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', $user->rows_pp);
$lastpage = ceil($numrows/$rows_pp);
$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)";
@@ -147,12 +161,16 @@ $sql .= ' WHERE ' . $where;
$sql .= $order; $sql .= $order;
// if pagination: // if pagination:
// $sql .= ' LIMIT ' . ($page - 1) * $rows_pp . ',' . $rows_pp; $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();
// 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>"; echo "<tr>";
@@ -182,10 +200,12 @@ foreach ($res as $row) {
} }
// 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";
echo $pagination;
form_add_button($g_scriptname); form_add_button($g_scriptname);
+1 -1
View File
@@ -16,7 +16,7 @@ require 'header.php';
<p class="p-3 mb-3 bg-info-subtle border border-info-subtle rounded"> <p class="p-3 mb-3 bg-info-subtle border border-info-subtle rounded">
<i class="bi bi-info-circle-fill me-2"></i> <i class="bi bi-info-circle-fill me-2"></i>
Hinweis: Es handelt sich hier um einen Prototypen! Hinweis: Es handelt sich hier um einen Prototypen (Version <?=$g_version?>)!<br>
Einige Funktionen sind noch nicht oder nicht vollständig implementiert. Einige Funktionen sind noch nicht oder nicht vollständig implementiert.
Rückmeldungen sind immer willkommen!</p> Rückmeldungen sind immer willkommen!</p>
+71 -36
View File
@@ -9,20 +9,23 @@
require 'globals.inc'; require 'globals.inc';
require 'lib/gpc.inc'; require 'lib/gpc.inc';
// TODO move to somewhere else
function format_vals($n, $v1, $v2, $v3) {
if ($n == 1) {
return $v1;
} elseif ($n == 2) {
return $v1 . 'x'. $v2;
} else {
return $v1 . 'x'. $v2 . 'x' . $v3;
}
}
$pagetitle = _('Measurements'); $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);
// TODO use enum function $opt_accuracy = db_load_enum('measurement', 'accuracy', true, true);
$opt_accuracy = array(
'unknown' => _('Unknown'),
'precise' => _('Precise'),
'normal' => _('Normal'),
'rough' => _('Rough'),
'estimated' => _('Estimated')
);
$opt_dimensions = array( $opt_dimensions = array(
1 => _('1D'), 1 => _('1D'),
2 => _('2D'), 2 => _('2D'),
@@ -54,9 +57,13 @@ switch ($submit = form_get_action()) {
$action = ACT_DEFAULT; $action = ACT_DEFAULT;
break; break;
case 'freset':
db_clear_filter(207);
$action = ACT_DEFAULT;
break;
case 'insert': case 'insert':
$p[':mname'] = gpc_get_string($_POST, 'mname'); $p[':mname'] = gpc_get_string($_POST, 'mname');
$p[':mtype'] = gpc_get_string($_POST, 'mtype');
$p[':note'] = gpc_get_string($_POST, 'note'); $p[':note'] = gpc_get_string($_POST, 'note');
$p[':nval'] = gpc_get_int($_POST, 'nval'); // 1 to 3 dimensions $p[':nval'] = gpc_get_int($_POST, 'nval'); // 1 to 3 dimensions
$p[':val1'] = gpc_get_int($_POST, 'val1'); $p[':val1'] = gpc_get_int($_POST, 'val1');
@@ -81,7 +88,6 @@ switch ($submit = form_get_action()) {
case 'update': case 'update':
$p[':mid'] = $id; $p[':mid'] = $id;
$p[':mname'] = gpc_get_string($_POST, 'mname'); $p[':mname'] = gpc_get_string($_POST, 'mname');
$p[':mtype'] = gpc_get_string($_POST, 'mtype');
$p[':nval'] = gpc_get_int($_POST, 'nval'); // 1 to 3 dimensions $p[':nval'] = gpc_get_int($_POST, 'nval'); // 1 to 3 dimensions
$p[':val1'] = gpc_get_int($_POST, 'val1'); $p[':val1'] = gpc_get_int($_POST, 'val1');
$p[':val2'] = NULL; $p[':val2'] = NULL;
@@ -130,20 +136,37 @@ 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, 207); $flt = db_get_filter($user->id, 207, ['txt']);
function format_vals($n, $v1, $v2, $v3) { $w = array('(vid=:vid OR vid IS NULL)');
if ($n == 1) { $p = array(':vid' => $user->vid);
return $v1;
} elseif ($n == 2) { // TODO precision additionally as filter
return $v1 . 'x'. $v2;
} else { if (strlen($flt->txt) > 1) {
return $v1 . 'x'. $v2 . 'x' . $v3; $w[] = 'mname LIKE :txt';
} $p[':txt'] = '%'.$flt->txt.'%';
} }
$where = join(' AND ', $w);
$order = ' ORDER BY mname';
echo "<h1>$pagetitle</h1>\n"; $sql = "SELECT COUNT(*) FROM measurement 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', $user->rows_pp);
$lastpage = ceil($numrows/$rows_pp);
// Filter // Filter
$opt_special = array( $opt_special = array(
@@ -154,23 +177,36 @@ $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"><i class="bi bi-funnel me-2"></i>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 <div class="d-flex flex-nowrap gap-2">
filter_create_select('flt_mtype', _('Type'), $g_opt_all + $g_opt_none + $opt_mtype); <label for="flt_txt">Text</label>
?> <input type="text" class="form-control" name="flt_txt" size="15" maxlength="30" value="<?=$flt->txt ?>">
<label for="flt_txt">Text</label> </div>
<input type="text" name="flt_txt" size="15" maxlength="30" value="<?=$flt->txt?>"> </div>
<button name="submit[filter]" class="btn btn-sm btn-primary" title="<?=_('Apply')?>"><?=_('Go')?></button> <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 mid, mname, nval, val1, val2, val3, unit, accuracy, mdate, note, eid " $sql = "SELECT mid, mname, nval, val1, val2, val3, unit, accuracy, mdate, note, eid "
. "FROM measurement " . "FROM measurement ";
. "ORDER BY mname"; $sql .= ' WHERE ' . $where;
$sth = $pdo->query($sql); $sql .= $order;
// if pagination:
$sql .= ' LIMIT ' . ($page - 1) * $rows_pp . ',' . $rows_pp;
$sth = $pdo->prepare($sql);
$sth->execute($p);
$res = $sth->fetchAll(); $res = $sth->fetchAll();
// 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";
@@ -206,6 +242,8 @@ echo '<tr><td colspan="6">', sprintf(_('%d records'), count($res)), '</td></tr>'
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):
@@ -224,7 +262,6 @@ echo '<h2>', _('Add measurement'), "</h2>\n";
<input type="text" class="form-control" id="note" name="note"> <input type="text" class="form-control" id="note" name="note">
</div> </div>
<?php <?php
form_create_select('mtype', _('Type'), $opt_mtype);
form_create_select('nval', _('Dimensions'), $opt_dimensions); form_create_select('nval', _('Dimensions'), $opt_dimensions);
?> ?>
<div class="mb-3"> <div class="mb-3">
@@ -254,7 +291,7 @@ form_create_select('eid', _('Equipment'), $opt_equipment, $id);
elseif ($action == ACT_VIEW): elseif ($action == ACT_VIEW):
// ========== VARIANT: view single record ===================================== // ========== VARIANT: view single record =====================================
$sql = "SELECT mname, mtype, unit, nval, val1, val2, val3, accuracy, mdate, note, eid " $sql = "SELECT mname, unit, nval, val1, val2, val3, accuracy, mdate, note, eid "
. "FROM measurement " . "FROM measurement "
. "WHERE mid=?"; . "WHERE mid=?";
$sth = $pdo->prepare($sql); $sth = $pdo->prepare($sql);
@@ -265,7 +302,6 @@ echo '<h2>', _('Measurement'), "</h2>\n";
echo '<table class="table">', "\n"; echo '<table class="table">', "\n";
echo '<tr><th style="width:20%">', _('Name'),"</th><td>", $measurement->mname, "</td></tr>\n"; echo '<tr><th style="width:20%">', _('Name'),"</th><td>", $measurement->mname, "</td></tr>\n";
echo '<tr><th>', _('Type'),"</th><td>", $opt_mtype[$measurement->mtype], "</td></tr>\n";
echo '<tr><th>', _('Unit'),"</th><td>", $opt_unit[$measurement->unit], "</td></tr>\n"; echo '<tr><th>', _('Unit'),"</th><td>", $opt_unit[$measurement->unit], "</td></tr>\n";
echo '<tr><th>', _('Values'),"</th><td>$measurement->nval</td></tr>\n"; echo '<tr><th>', _('Values'),"</th><td>$measurement->nval</td></tr>\n";
echo '<tr><th>', _('Value 1'),"</th><td>$measurement->val1</td></tr>\n"; echo '<tr><th>', _('Value 1'),"</th><td>$measurement->val1</td></tr>\n";
@@ -283,7 +319,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 mname, mtype, nval, val1, val2, val3, unit, accuracy, note, eid " $sql = "SELECT mname, nval, val1, val2, val3, unit, accuracy, note, eid "
. "FROM measurement " . "FROM measurement "
. "WHERE mid=?"; . "WHERE mid=?";
$sth = $pdo->prepare($sql); $sth = $pdo->prepare($sql);
@@ -303,7 +339,6 @@ echo '<h2>', _('Edit measurement'), "</h2>\n";
<input type="text" class="form-control" id="note" name="note" value="<?=$measurement->note ?>"> <input type="text" class="form-control" id="note" name="note" value="<?=$measurement->note ?>">
</div> </div>
<?php <?php
form_create_select('mtype', _('Type'), $opt_mtype, $measurement->mtype);
form_create_select('nval', _('Dimensions'), $opt_dimensions, $measurement->nval); form_create_select('nval', _('Dimensions'), $opt_dimensions, $measurement->nval);
?> ?>
<div class="mb-3"> <div class="mb-3">
+2 -1
View File
@@ -176,7 +176,8 @@ $note = $sth->fetch(PDO::FETCH_OBJ);
// list where annotaion used // list where annotaion used
echo '<table class="table">', "\n"; echo '<table class="table">', "\n";
echo '<tr><th>', _('Referenz'),"</th><td>", $note->refid, "</td></tr>\n"; echo '<tr><th>', _('Referenz'),"</th><td>", $note->refid, "</td></tr>\n";
echo '<tr><th>', _('Annotation'),"</th><td>", $note->annotation, "</td></tr>\n"; echo '<tr><th>', _('Type'),"</th><td>", $note->notetype, "</td></tr>\n";
echo '<tr><th>', _('Annotation'),"</th><td>", nl2br($note->annotation), "</td></tr>\n";
echo "</table>\n"; echo "</table>\n";
+27 -15
View File
@@ -47,7 +47,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'] = $_POST['flt_state']; // Array! gpc_get_string($_POST, 'flt_state'); $flt['state'] = gpc_get_string($_POST, 'flt_state'); // TODO perhaps change to checkboxes
$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;
@@ -107,16 +107,22 @@ if ($action == ACT_DEFAULT):
page_caption_search($pagetitle); 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, ['name','state','remarks']);
// name, status, text
$w = array('vid=:vid'); $w = array('vid=:vid');
$p = array(':vid' => $user->vid); $p = array(':vid' => $user->vid);
if (strlen($flt->txt) > 1) { if ($flt->state > 0) {
$w[] = '(projname LIKE :txt OR remarks LIKE :txt)'; $w[] = 'projstate=:state';
$p[':txt'] = '%'.$flt->txt.'%'; $p[':state'] = $flt->state;
}
if (strlen($flt->name) > 1) {
$w[] = '(projname LIKE :name)';
$p[':name'] = '%'.$flt->name.'%';
}
if (strlen($flt->remarks) > 1) {
$w[] = '(remarks LIKE :remarks)';
$p[':remarks'] = '%'.$flt->remarks.'%';
} }
$where = join(' AND ', $w); $where = join(' AND ', $w);
@@ -134,7 +140,7 @@ try {
} }
$numrows = $sth->fetchColumn(); $numrows = $sth->fetchColumn();
$page = gpc_get_int($_REQUEST, 'p', 1); $page = gpc_get_int($_REQUEST, 'p', 1);
$rows_pp = gpc_get_int($_REQUEST, 'n', $g_rows_pp); $rows_pp = gpc_get_int($_REQUEST, 'n', $user->rows_pp);
$lastpage = ceil($numrows/$rows_pp); $lastpage = ceil($numrows/$rows_pp);
// $grandtotal = $pdo->query("SELECT COUNT(*) FROM project WHERE " . $where)->fetchColumn(); // $grandtotal = $pdo->query("SELECT COUNT(*) FROM project WHERE " . $where)->fetchColumn();
@@ -145,7 +151,7 @@ $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);
@@ -158,15 +164,15 @@ $res = $sth->fetchAll();
<div class="card-header"><i class="bi bi-funnel me-2"></i>Filter</div> <div class="card-header"><i class="bi bi-funnel me-2"></i>Filter</div>
<div class="card-body d-flex flex-wrap gap-3"> <div class="card-body d-flex flex-wrap gap-3">
<div class="d-flex flex-nowrap gap-2"> <div class="d-flex flex-nowrap gap-2">
<label for="flt_name">Name</label> <label for="flt_name"><?=_('Name')?></label>
<input type="text" class="form-control" name="flt_name" size="15" maxlength="30" value="<?=$flt->name;?>"> <input type="text" class="form-control" name="flt_name" size="15" maxlength="30" value="<?=$flt->name ?? '';?>">
</div> </div>
<?php <?php
filter_create_select('flt_state[]', _('State'), $g_opt_all + $opt_state, $flt->state, FALSE); filter_create_select('flt_state', _('State'), $g_opt_all + $opt_state, $flt->state ?? -2, FALSE);
?> ?>
<div class="d-flex flex-nowrap gap-2"> <div class="d-flex flex-nowrap gap-2">
<label for="flt_remarks">Text</label> <label for="flt_remarks"><?=_('Remarks')?></label>
<input type="text" class="form-control" name="flt_remarks" size="15" maxlength="30" value="<?=$flt->remarks ?>"> <input type="text" class="form-control" name="flt_remarks" size="15" maxlength="30" value="<?=$flt->remarks ?? '' ?>">
</div> </div>
</div> </div>
<div class="card-footer"> <div class="card-footer">
@@ -177,6 +183,9 @@ filter_create_select('flt_state[]', _('State'), $g_opt_all + $opt_state, $flt->s
</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";
@@ -210,11 +219,14 @@ foreach ($res as $row) {
echo "</tr>\n"; echo "</tr>\n";
} }
// 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="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";
echo $pagination;
form_add_button($g_scriptname); form_add_button($g_scriptname);
echo "<h1>", _('Generic Tasks'), "</h1>\n"; echo "<h1>", _('Generic Tasks'), "</h1>\n";
+2 -2
View File
@@ -127,7 +127,7 @@ try {
} }
$numrows = $sth->fetchColumn(); $numrows = $sth->fetchColumn();
$page = gpc_get_int($_REQUEST, 'p', 1); $page = gpc_get_int($_REQUEST, 'p', 1);
$rows_pp = gpc_get_int($_REQUEST, 'n', $g_rows_pp); $rows_pp = gpc_get_int($_REQUEST, 'n', $user->rows_pp);
$lastpage = ceil($numrows/$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
@@ -218,7 +218,7 @@ foreach ($res as $row) {
} }
// Table summary // Table summary
echo "<tfoot>\n"; echo "<tfoot>\n";
echo '<tr><td colspan="8">', sprintf(_('%d records'), count($res)), '</td></tr>', "\n"; echo '<tr><td colspan="8">', 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";
+137
View File
@@ -0,0 +1,137 @@
<?php
/******************************************************************************
* YMS - Yacht Management Software
* Copyright (C) 2024-2026 Thomas Hooge
*
* SPDX-License-Identifier: WTFPL
******************************************************************************/
require 'globals.inc';
require 'lib/gpc.inc';
$pagetitle = _('Settings');
// ========== ACTIONS START ===================================================
switch ($submit = form_get_action()) {
case NULL: break;
case 'update':
$pk = ['userid', 'sno'];
// global settings
if ($user->role == 'captain') {
$p[':userid'] = 0;
$p[':sno'] = 20;
$p[':valint'] = gpc_get_int($_POST, 'maximgx');
db_exec_update('settings', $p, $pk);
$p[':sno'] = 21;
$p[':valint'] = gpc_get_int($_POST, 'maximgy');
db_exec_update('settings', $p, $pk);
}
// user settings
$p[':userid'] = $user->id;
$p[':sno'] = 2; // date format
$p[':valint'] = NULL;
$p[':valstr'] = gpc_get_string($_POST, 'datefmt');
db_exec_update('settings', $p, $pk);
$p[':sno'] = 10; // rows pp
$p[':valstr'] = NULL;
$p[':valint'] = gpc_get_int($_POST, 'rowspp');
db_exec_update('settings', $p, $pk);
break;
default:
$g_error->Add(sprintf(_("Unknown function '%s'!"), $submit));
$valid = FALSE;
}
// ========== ACTIONS END =====================================================
require 'header.php';
// ========== PAGE CONTENT ====================================================
if ($action == ACT_DEFAULT):
// ========== VARIANT: default behavior =======================================
echo '<h1>', $pagetitle, "</h1>\n";
$datefmt = 'Y-m-d';
$sql = "SELECT valstr FROM settings WHERE userid=? AND sno=2";
$sth = $pdo->prepare($sql);
$sth->execute([$user->id]);
if ($res = $sth->fetch(PDO::FETCH_NUM)) {
$datefmt = $res[0];
} else {
// create missing record in settings table
$sql = "INSERT INTO settings (userid, sno, valstr) VALUES (?, 2, ?)";
$sth = $pdo->prepare($sql);
$sth->execute([$user->id, $datefmt]);
}
$curdate = new DateTime();
$opt_datefmt = array(
'Y-m-d' => _('YYYY-MM-DD'). $curdate->format(' - Y-m-d'),
'Y/m/d' => _('YYYY/MM/DD'). $curdate->format(' - Y/m/d'),
'd.m.Y' => _('DD.MM.YYYY'). $curdate->format(' - d.m.Y'),
'd/m/Y' => _('DD/MM/YYYY'). $curdate->format(' - d/m/Y'),
'm-d-Y' => _('MM/DD/YYYY'). $curdate->format(' - m-d-Y')
);
$rowspp = 10;
$sql = "SELECT valint FROM settings WHERE userid=? AND sno=10";
$sth = $pdo->prepare($sql);
$sth->execute([$user->id]);
if ($res = $sth->fetch(PDO::FETCH_NUM)) {
$rowspp = $res[0];
} else {
// create missing record in settings table
$sql = "INSERT INTO settings (userid, sno, valint) VALUES (?, 10, ?)";
$sth = $pdo->prepare($sql);
$sth->execute([$user->id, $rowspp]);
}
$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();
?>
<form method="post" action="<?=$g_scriptname?>">
<h2>for current user</h2>
<?php
form_create_select('datefmt', _('Date format'), $opt_datefmt, $datefmt);
?>
<div class="mb-3">
<label for="rowspp" class="form-label"><?=_('Number of rows per page')?></label>
<input type="text" class="form-control" id="rowspp" name="rowspp" maxlength="3" value=<?=$rowspp?>>
</div>
<?php
// limit global settings for captain only
if ($user->role == 'captain'):
?>
<h2>global for all users</h2>
<div class="mb-3">
<label for="maximgx" class="form-label"><?=_('Maximal image width')?></label>
<input type="text" class="form-control" id="maximgx" name="maximgx" maxlength="4" value=<?=$maximgx?>>
</div>
<div class="mb-3">
<label for="maximgy" class="form-label"><?=_('Maximal image height')?></label>
<input type="text" class="form-control" id="maximgy" name="maximgy" maxlength="4" value=<?=$maximgy?>>
</div>
<?php
endif;
?>
<div class="container-fluid px-0 my-3">
<button type="submit" name="submit[update]" class="btn btn-primary"><?=_('Save')?></button>
<a href="index.php" class="btn btn-secondary"><?=_('Back')?></a>
</div>
</form>
<?php
else:
// ========== ERROR UNKNOWN VARIANT ===========================================
echo '<p>', _('Unknown function call: Please report to system development!'), "</p>\n";
endif; // $action == ...
// ========== END OF VARIANTS =================================================
include 'footer.php';
+11 -10
View File
@@ -13,7 +13,7 @@ $pagetitle = _('Storage');
$id = gpc_get_int($_REQUEST, 'id', 0); $id = gpc_get_int($_REQUEST, 'id', 0);
$stype = db_get_options(3); $opt_stype = db_get_options(3);
// ========== ACTIONS START =================================================== // ========== ACTIONS START ===================================================
@@ -37,6 +37,7 @@ switch ($submit = form_get_action()) {
case 'update': case 'update':
$p[':sid'] = $id; $p[':sid'] = $id;
$p[':sname'] = gpc_get_string($_POST, 'sname'); $p[':sname'] = gpc_get_string($_POST, 'sname');
$p[':stype'] = gpc_get_string($_POST, 'stype');
$p[':x'] = gpc_get_int($_POST, 'x'); $p[':x'] = gpc_get_int($_POST, 'x');
$p[':y'] = gpc_get_int($_POST, 'y'); $p[':y'] = gpc_get_int($_POST, 'y');
$p[':z'] = gpc_get_int($_POST, 'z'); $p[':z'] = gpc_get_int($_POST, 'z');
@@ -73,9 +74,12 @@ switch ($submit = form_get_action()) {
$action = ACT_VIEW; $action = ACT_VIEW;
break; break;
} }
$sth = $pdo->prepare("SELECT sname FROM storage WHERE sid=?");
$sth->execute([$id]);
$storagename = $sth->fetchcolumn();
$sth = $pdo->prepare("DELETE FROM storage WHERE sid=?"); $sth = $pdo->prepare("DELETE FROM storage WHERE sid=?");
$sth->execute([$id]); $sth->execute([$id]);
$g_message->Add(sprintf(_('Deleted storage no. %d'), $id)); $g_message->Add(sprintf(_('Deleted storage no. %d (%s)'), $id, $storagename));
$action = ACT_DEFAULT; $action = ACT_DEFAULT;
break; break;
@@ -194,15 +198,9 @@ echo '<h2>', _('Add Storage'), "</h2>\n";
<label for="sname" class="form-label"><?=_('Name')?></label> <label for="sname" class="form-label"><?=_('Name')?></label>
<input type="text" class="form-control" id="sname" name="sname"> <input type="text" class="form-control" id="sname" name="sname">
</div> </div>
<div class="mb-3">
<select name="stype" class="form-control">
<?php <?php
foreach ($stype as $k => $v) { form_create_select('stype', _('Type'), $opt_stype);
echo '<option value="', $k ,'">', $v, "</option>\n";
}
?> ?>
</select>
</div>
<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>
</form> </form>
@@ -223,7 +221,7 @@ $storage = $sth->fetch(PDO::FETCH_OBJ);
echo '<h2>', $storage->sname, "</h2>\n"; echo '<h2>', $storage->sname, "</h2>\n";
echo '<table class="table">', "\n"; echo '<table class="table">', "\n";
echo '<tr><th style="width:33%">', _('Typ'),"</th><td>", $stype[$storage->stype], "</td></tr>\n"; echo '<tr><th style="width:33%">', _('Typ'),"</th><td>", $opt_stype[$storage->stype], "</td></tr>\n";
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";
@@ -294,6 +292,9 @@ $storage = $sth->fetch(PDO::FETCH_OBJ);
<label for="sname" class="form-label"><?=_('Name')?></label> <label for="sname" class="form-label"><?=_('Name')?></label>
<input type="text" class="form-control" id="sname" name="sname" value="<?=$storage->sname ?>"> <input type="text" class="form-control" id="sname" name="sname" value="<?=$storage->sname ?>">
</div> </div>
<?php
form_create_select('stype', _('Type'), $opt_stype, $storage->stype);
?>
<div class="mb-3"> <div class="mb-3">
<label class="form-label"><?=_('Position (x, y, z) in mm')?></label> <label class="form-label"><?=_('Position (x, y, z) in mm')?></label>
<div class="row"> <div class="row">
+61 -21
View File
@@ -80,7 +80,7 @@ if ($action == ACT_DEFAULT):
// ========== VARIANT: default behavior ======================================= // ========== VARIANT: default behavior =======================================
// load filter from db // load filter from db
$flt = db_get_filter($user->id, 210); $flt = db_get_filter($user->id, 210, ['txt']);
echo "<h1>$pagetitle</h1>\n"; echo "<h1>$pagetitle</h1>\n";
@@ -91,12 +91,15 @@ 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"><i class="bi bi-funnel me-2"></i>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">
<div class="d-flex flex-nowrap gap-2">
<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" class="form-control" name="flt_txt" size="15" maxlength="30" value="<?=$flt->txt ?? ''?>">
<button name="submit[filter]" class="btn btn-sm btn-primary" title="<?=_('Apply')?>"><?=_('Go')?></button> </div>
<button name="submit[freset]" class="btn btn-sm btn-secondary float-end" title="<?=_('Reset filter to defaults')?>"><?=_('Clear')?></button> </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>
@@ -110,20 +113,29 @@ $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>\n"; echo "<tr>\n";
echo '<th>#</th>';
echo '<th>', _('Tag'), "</th>"; echo '<th>', _('Tag'), "</th>";
echo '<th>', _('Description'), "</th>"; echo '<th>', _('Description'), "</th>";
echo '<th>', _('Color'), "</th>"; echo '<th>', _('Color'), "</th>";
echo "<th></th>"; echo "<th></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['tagid'], '"><i class="bi bi-eye ms-2"></i></a>', "\n";
echo "</td>\n";
echo "<td>", $row['tagname'], "</td>\n"; echo "<td>", $row['tagname'], "</td>\n";
echo "<td>", $row['description'], "</td>\n"; echo "<td>", $row['description'], "</td>\n";
echo "<td>", format_color($row['color']), "</td>\n"; echo "<td>", format_color($row['color']), "</td>\n";
echo "<td>"; echo "<td>";
// Action buttons // Edit current record button
form_action_buttons($g_scriptname, $row['tagid']); echo "<td>";
echo '<a title="', _('Edit'), '" href="', $g_scriptname, '?f=edit&id=', $row['tagid'], '"><i class="bi-pencil"></i></a>', "\n";
echo "</td>\n";
echo "</td>\n"; echo "</td>\n";
echo "</tr>\n"; echo "</tr>\n";
} }
@@ -179,19 +191,47 @@ $sql = "SELECT objid, objtype FROM tagref WHERE tagid=?";
$sth = $pdo->prepare($sql); $sth = $pdo->prepare($sql);
$sth->execute([$id]); $sth->execute([$id]);
$link = array(
'equip' => 'equipment.php',
'inv' => 'inventory.php',
'prov' => 'provisions.php',
'doc' => 'documents.php',
'proj' => 'projects.php',
'task' => 'task.php',
'maint' => 'maintenance.php'
);
echo '<p>'; echo '<p>';
if ($sth->rowCount() > 0) { if ($sth->rowCount() > 0) {
foreach ($sth->fetchAll() as $row) { $res = $sth->fetchAll();
echo '<a href="', $link[$row['objtype']], '?f=view&id=', $row['objid'], '">', $row['objid'], '/', $row['objtype'], "</a>\n"; foreach ($res as $row) {
// select object name or description depending on objecttype
// TODO function db_get_tag_target($objtype, $objid);
/*switch ($row['objtype']) {
case 'equip':
$sql = "SELECT ename FROM equipment WHERE eid=?";
$target = "equipment.php";
break;
case 'inv':
$sql = "SELECT invname FROM inventory WHERE invid=?";
$target = "inventory.php";
break;
case 'prov':
$sql = "SELECT provname FROM provisions WHERE provvid=?";
$target = "provisions.php";
break;
case 'doc':
$sql = "SELECT title FROM document WHERE docid=?";
$target = "documents.php";
break;
case 'proj':
$sql = "SELECT projname FROM project WHERE projid=?";
$target = "projects.php";
break;
case 'task':
$sql = "SELECT taskname FROM task WHERE taskid=?";
$target = "task.php";
break;
case 'maint':
$sql = "SELECT activities FROM maintenance WHERE maintid=?";
$target = 'maintenance.php';
break;
}
$sth = $pdo->prepare($sql);
$sth->execute([$row['objid']]);
$desc = $sth->fetchColumn(); */
[$target, $desc] = db_get_tag_target($row['objtype'], $row['objid']);
echo '<a href="', $target, '?f=view&id=', $row['objid'], '">', $desc, ' (', $row['objid'], '/', $row['objtype'], ")</a>\n";
} }
} else { } else {
echo _('Tag is not used anywhere'); echo _('Tag is not used anywhere');
@@ -242,7 +282,7 @@ $sth = $pdo->prepare($sql);
$sth->execute([$id]); $sth->execute([$id]);
if ($sth->rowCount() > 0) { if ($sth->rowCount() > 0) {
foreach ($sth->fetchAll() as $row) { foreach ($sth->fetchAll() as $row) {
echo '<a href="', $link[$row['objtype']], '?f=view&id=', $row['objid'], '">', $row['objid'], '/', $row['objtype'], "</a>\n"; echo '<a href="', [$row['objtype']], '?f=view&id=', $row['objid'], '">', $row['objid'], '/', $row['objtype'], "</a>\n";
} }
} else { } else {
echo _('Tag is not used anywhere'); echo _('Tag is not used anywhere');
+20 -8
View File
@@ -124,7 +124,7 @@ if ($action == ACT_DEFAULT):
page_caption_search($pagetitle); page_caption_search($pagetitle);
// load filter from db // load filter from db
$flt = db_get_filter($user->id, 206); $flt = db_get_filter($user->id, 206, ['txt','prio', 'stat']);
$w = array('(t.vid=:vid OR t.vid IS NULL)'); $w = array('(t.vid=:vid OR t.vid IS NULL)');
$p = array(':vid' => $user->vid); $p = array(':vid' => $user->vid);
@@ -170,7 +170,8 @@ $sql = "SELECT t.taskid, t.vid, t.projid, t.taskname, t.priority, t.taskstate,"
if ($order) $sql .= $order; if ($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);
try { try {
$sth->execute($p); $sth->execute($p);
@@ -186,20 +187,28 @@ $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"><i class="bi bi-funnel me-2"></i>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_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);
filter_create_select('flt_stat', _('State'), $g_opt_all + $opt_state, $flt->stat); filter_create_select('flt_stat', _('State'), $g_opt_all + $opt_state, $flt->stat);
?> ?>
<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" class="form-control" name="flt_txt" size="15" maxlength="30" value="<?=$flt->txt ?>">
<input type="reset" class="btn btn-sm btn-secondary" value="<?=_('Clear')?>"> </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";
@@ -237,6 +246,9 @@ echo '<tr><td colspan="6">', sprintf(_('%d records'), count($res)), '</td></tr>'
echo "</tfoot>\n"; echo "</tfoot>\n";
echo "</table>\n"; echo "</table>\n";
// additional pagination at bottom
echo $pagination;
form_add_button($g_scriptname); form_add_button($g_scriptname);
elseif ($action == ACT_ADD): elseif ($action == ACT_ADD):
@@ -301,7 +313,7 @@ if ($sth->rowCount() > 0) {
$n = 0; $n = 0;
foreach ($sth->fetchAll() as $row) { foreach ($sth->fetchAll() as $row) {
$n += 1; $n += 1;
echo "<p>($n) {$row['annotation']}"; echo "<p>($n) ", nl2br($row['annotation']);
echo ' <a title="', _('Edit'), '" href="note.php?f=edit&id=', $row['noteid'], '"><i class="bi-pencil"></i></a>'; echo ' <a title="', _('Edit'), '" href="note.php?f=edit&id=', $row['noteid'], '"><i class="bi-pencil"></i></a>';
echo "</p>\n"; echo "</p>\n";
} }
Executable
+51
View File
@@ -0,0 +1,51 @@
#!/usr/bin/python3
import os
import sys
import configparser
from yms import database
from getpass import getpass
import bcrypt
cfg = {
'cfgfile': '~/.config/ymsgui.conf',
'host': 'localhost',
'db': 'yms',
'user': 'yms'
}
def set_pass():
newpass = getpass('New Password: ')
cryptpass = bcrypt.hashpw(newpass.encode(), bcrypt.gensalt())
print(cryptpass.decode())
sql = "UPDATE user SET pass=%s WHERE userid=%s"
def get_user():
username = input('Username: ')
sql = "SELECT userid FROM user WHERE login=%s"
db.cur.execute(sql, (username,))
row = db.cur.fetchone()
if not row:
print("User not found")
return -1
else:
return row[0]
if __name__ == "__main__":
config = configparser.ConfigParser()
configfile = os.path.expanduser(cfg['cfgfile']);
if not config.read(configfile):
print(f"Configuration file '{configfile}' not found.")
else:
cfg['host'] = config.get('DB', 'host')
cfg['db'] = config.get('DB', 'db')
cfg['user'] = config.get('DB', 'user')
cfg['pass'] = config.get('DB', 'pass')
db = database.Database(cfg['host'], cfg['db'])
if db.connect(cfg['user'], cfg['pass']):
print("Connected to database")
print(get_user())
db.disconnect()
else:
print("Cannot connect to database {}@{}".format(cfg['db'], cfg['host']))