First web gui prototype
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
<FilesMatch "\.inc$">
|
||||
Require all denied
|
||||
</FilesMatch>
|
||||
+5
File diff suppressed because one or more lines are too long
+6
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
+7
File diff suppressed because one or more lines are too long
+253
@@ -0,0 +1,253 @@
|
||||
<?php
|
||||
/******************************************************************************
|
||||
* YMS - Yacht Management Software
|
||||
* Copyright (C) 2024 Thomas Hooge
|
||||
*
|
||||
* SPDX-License-Identifier: WTFPL
|
||||
******************************************************************************/
|
||||
|
||||
require 'globals.inc';
|
||||
$pagetitle = _('Boxes');
|
||||
|
||||
$id = gpc_get_int($_REQUEST, 'id', 0);
|
||||
|
||||
// Storage options
|
||||
$sql = "SELECT sid, sname FROM storage WHERE vid=? ORDER BY sname";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$user->vid]);
|
||||
$opt_storage = array();
|
||||
foreach ($sth->fetchAll() as $row) {
|
||||
$opt_storage[$row['sid']] = $row['sname'];
|
||||
}
|
||||
|
||||
// ========== 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 'insert':
|
||||
$p[':label'] = gpc_get_string($_POST, 'label');
|
||||
$p[':sid'] = gpc_get_int($_POST, 'sid');
|
||||
$p[':content'] = gpc_get_string($_POST, 'content');
|
||||
$p[':remarks'] = gpc_get_string($_POST, 'remarks');
|
||||
$keys = array_keys($p);
|
||||
$fields = join(',', array_map(function($s) { return ltrim($s, ':'); }, $keys));
|
||||
$pnames = join(',', $keys);
|
||||
$sth = $pdo->prepare("INSERT INTO box ($fields) VALUES ($pnames)");
|
||||
try {
|
||||
$sth->execute($p);
|
||||
} catch (PDOexception $e) {
|
||||
$g_error->Add('SQL-Error: '. $e->getMessage());
|
||||
}
|
||||
$id = $pdo->LastInsertId();
|
||||
$action = ACT_VIEW;
|
||||
break;
|
||||
|
||||
case 'update':
|
||||
$p[':label'] = gpc_get_string($_POST, 'label');
|
||||
$p[':content'] = gpc_get_string($_POST, 'content');
|
||||
$p[':color'] = gpc_get_color($_POST, 'color');
|
||||
$p[':weight'] = min(gpc_get_float($_POST, 'weight'), 99.99);
|
||||
$p[':remarks'] = gpc_get_string($_POST, 'remarks', 150);
|
||||
$fields = join(',', array_map(function($s) { return ltrim($s, ':') . '=' . $s; }, array_keys($p)));
|
||||
$sth = $pdo->prepare("UPDATE box SET $fields WHERE boxid=:boxid");
|
||||
$p[':boxid'] = $id;
|
||||
try {
|
||||
$sth->execute($p);
|
||||
} catch (PDOexception $e) {
|
||||
$g_error->Add('SQL-Error: '. $e->getMessage());
|
||||
}
|
||||
$action = ACT_VIEW;
|
||||
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";
|
||||
|
||||
$sql = "SELECT boxid, sid, label, color, content, weight, remarks "
|
||||
. "FROM box "
|
||||
. "ORDER BY label";
|
||||
$sth = $pdo->query($sql);
|
||||
$res = $sth->fetchAll();
|
||||
echo '<table class="table table-striped">', "\n";
|
||||
echo "<thead>\n";
|
||||
echo "<tr>";
|
||||
echo "<th>" . _('Label') . "</th>";
|
||||
echo "<th>" . _('Color') . "</th>";
|
||||
echo "<th>" . _('Content') . "</th>";
|
||||
echo '<th class="text-end">', _('Weight'), "</th>";
|
||||
echo "<td></td>";
|
||||
echo "</tr>\n";
|
||||
foreach ($res as $row) {
|
||||
echo "<tr>\n";
|
||||
echo "<td>". $row['label'] ."</td>\n";
|
||||
$style = 'background-color:#' . $row['color'];
|
||||
if (get_color_brightness($row['color']) < 0.4) {
|
||||
$style .= ';color:white';
|
||||
}
|
||||
echo '<td><span style="', $style,'">#'. $row['color'] ."</span></td>\n";
|
||||
echo "<td>". $row['content'] ."</td>\n";
|
||||
echo '<td class="text-end">', format_float($row['weight'], 2), "</td>\n";
|
||||
form_action_buttons($g_scriptname, $row['boxid']);
|
||||
echo "</tr>\n";
|
||||
}
|
||||
// Table summary
|
||||
echo "<tfoot>\n";
|
||||
echo '<tr><td colspan="4">', sprintf(_('%d records'), count($res)), '</td></tr>', "\n";
|
||||
echo "</tfoot>\n";
|
||||
echo "</table>\n";
|
||||
|
||||
form_add_button('box.php');
|
||||
|
||||
|
||||
elseif ($action == ACT_ADD):
|
||||
// ========== VARIANT: add record =============================================
|
||||
|
||||
echo '<h2>', _('Add Box'), "</h2>\n";
|
||||
?>
|
||||
<form method="post">
|
||||
<div class="mb-3">
|
||||
<label for="label" class="form-label"><?=_('Label')?></label>
|
||||
<input type="text" maxlength="20" class="form-control" id="label" name="label" autofocus>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="sid" class="form-label"><?=_('Storage')?></label>
|
||||
<select name="sid" id="sid" class="form-control">
|
||||
<?php
|
||||
foreach ($opt_storage as $k => $v) {
|
||||
echo '<option value="', $k, '">', $v, "</option>\n";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="content" class="form-label"><?=_('Content')?></label>
|
||||
<input type="text" maxlength="60" class="form-control" id="content" name="content">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="remarks" class="form-label"><?=_('Remarks')?></label>
|
||||
<textarea class="form-control" id="remarks" name="remarks" rows="3"></textarea>
|
||||
</div>
|
||||
<div class="container-fluid px-0 my-3">
|
||||
<button type="submit" name="submit[insert]" class="btn btn-primary"><?=_('Save')?></button>
|
||||
<a href="<?=$g_scriptname?>" class="btn btn-secondary"><?=_('Back')?></a>
|
||||
</div>
|
||||
</form>
|
||||
<?php
|
||||
|
||||
elseif ($action == ACT_VIEW):
|
||||
// ========== VARIANT: view single record =====================================
|
||||
|
||||
$sql = "SELECT label, content, color, weight, remarks "
|
||||
. "FROM box "
|
||||
. "WHERE boxid=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$id]);
|
||||
$box = $sth->fetch(PDO::FETCH_OBJ);
|
||||
|
||||
echo '<h2>', $box->label, "</h2>\n";
|
||||
|
||||
echo '<table class="table">', "\n";
|
||||
echo '<tr><th style="width:20%">', _('Content'),"</th><td>", $box->content, "</td></tr>\n";
|
||||
echo '<tr><th>', _('Color'), '</th><td style="background-color:#', $box->color, '">#', $box->color, "</td></tr>\n";
|
||||
echo '<tr><th>', _('Weight'), '</th><td>', format_float($box->weight, 2, 'kg'), "</td></tr>\n";
|
||||
echo '<tr><th>', _('Remarks'),"</th><td>", $box->remarks, "</td></tr>\n";
|
||||
echo "</table>\n";
|
||||
|
||||
form_view_buttons($g_scriptname, $id);
|
||||
|
||||
// Inventory in box
|
||||
// WIP
|
||||
$sql = "SELECT invid, invname FROM inventory WHERE boxtype='box' AND boxid=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$id]);
|
||||
$res = $sth->fetchAll();
|
||||
|
||||
echo '<h3>', _('Inventory in box'), "</h3>\n";
|
||||
if ($res) {
|
||||
echo '<table class="table table-striped">', "\n";
|
||||
echo "<thead>\n";
|
||||
echo "<tr>";
|
||||
echo '<th>', _('Inventory'), "</th>";
|
||||
echo "<td></td>";
|
||||
echo "</tr>\n";
|
||||
foreach ($res as $row) {
|
||||
echo "<tr>\n";
|
||||
echo "<td>", $row['invname'], "</td>\n";
|
||||
form_action_buttons('inventory.php', $row['invid']);
|
||||
echo "</tr>\n";
|
||||
}
|
||||
echo "</table>\n";
|
||||
} else {
|
||||
echo '<p>', _('Box is empty'), "</p>\n";
|
||||
}
|
||||
|
||||
elseif ($action == ACT_EDIT):
|
||||
// ========== VARIANT: edit single record =====================================
|
||||
|
||||
$sql = "SELECT label, content, color, weight, remarks "
|
||||
. "FROM box "
|
||||
. "WHERE boxid=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$id]);
|
||||
$box = $sth->fetch(PDO::FETCH_OBJ);
|
||||
|
||||
echo '<h2>', _('Edit Box'), "</h2>\n";
|
||||
?>
|
||||
<form method="post">
|
||||
<input type="hidden" name="id" value="<?=$id?>">
|
||||
<div class="mb-3">
|
||||
<label for="label" class="form-label"><?=_('Label')?></label>
|
||||
<input type="text" class="form-control" id="label" name="label" value="<?=$box->label ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="content" class="form-label"><?=_('Content')?></label>
|
||||
<input type="text" class="form-control" id="content" name="content" value="<?=$box->content ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="color"><?=_('Color')?></label>
|
||||
<input type="color" class="form-control" id="color" name="color" value="#<?=$box->color ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="weight" class="form-label"><?=_('Weight, kg')?></label>
|
||||
<input type="text" class="form-control" id="weight" name="weight" value="<?=format_float($box->weight); ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="remarks" class="form-label"><?=_('Remarks')?></label>
|
||||
<textarea class="form-control" id="remarks" name="remarks" rows="3"><?=$box->remarks ?></textarea>
|
||||
</div>
|
||||
<?php
|
||||
|
||||
form_edit_buttons($g_scriptname, $id);
|
||||
echo "</form>\n";
|
||||
|
||||
elseif ($action == ACT_DELETE):
|
||||
// ========== VARIANT: delete record ==========================================
|
||||
|
||||
else:
|
||||
// ========== ERROR UNKNOWN VARIANT ===========================================
|
||||
|
||||
echo '<p>', _('Unknown function call: Please report to system development!'), "</p>\n";
|
||||
|
||||
endif; // $action == ...
|
||||
// ========== END OF VARIANTS =================================================
|
||||
|
||||
include 'footer.php';
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
/******************************************************************************
|
||||
* YMS - Yacht Management Software
|
||||
* Copyright (C) 2024 Thomas Hooge
|
||||
*
|
||||
* SPDX-License-Identifier: WTFPL
|
||||
******************************************************************************/
|
||||
|
||||
require 'globals.inc';
|
||||
$pagetitle = _('Checklists');
|
||||
|
||||
$id = gpc_get_int($_REQUEST, 'id', 0);
|
||||
|
||||
require 'header.php';
|
||||
|
||||
echo "<h1>$pagetitle</h1>\n";
|
||||
?>
|
||||
|
||||
<p>Search will be implemented later.
|
||||
This page is currently just a placeholder.</p>
|
||||
|
||||
<?php
|
||||
include 'footer.php';
|
||||
@@ -0,0 +1,338 @@
|
||||
<?php
|
||||
/******************************************************************************
|
||||
* YMS - Yacht Management Software
|
||||
* Copyright (C) 2024 Thomas Hooge
|
||||
*
|
||||
* SPDX-License-Identifier: WTFPL
|
||||
******************************************************************************/
|
||||
|
||||
require 'globals.inc';
|
||||
$pagetitle=_('Company');
|
||||
|
||||
$id = gpc_get_int($_REQUEST, 'id', 0);
|
||||
$opt_comptype = db_get_options(2);
|
||||
|
||||
// ========== 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 'insert':
|
||||
$compname = gpc_get_string($_POST, 'compname');
|
||||
$comptype = gpc_get_int($_POST, 'comptype');
|
||||
$sql = "INSERT INTO company "
|
||||
. " (compname, comptype) "
|
||||
. "VALUES "
|
||||
. " (:compname, :comptype)";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->bindValue(':compname', $compname, PDO::PARAM_STR);
|
||||
$sth->bindValue(':comptype', $comptype, PDO::PARAM_INT);
|
||||
$sth->execute();
|
||||
$id = $pdo->lastInsertId();
|
||||
$action = ACT_VIEW;
|
||||
break;
|
||||
|
||||
case 'update':
|
||||
$compname = gpc_get_string($_POST, 'compname');
|
||||
$comptype = gpc_get_int($_POST, 'comptype');
|
||||
$street = gpc_get_string($_POST, 'street', 30);
|
||||
$zip = gpc_get_string($_POST, 'zip', 10);
|
||||
$city = gpc_get_string($_POST, 'city', 30);
|
||||
$country = gpc_get_string($_POST, 'country', 30);
|
||||
$contact = gpc_get_string($_POST, 'contact', 30);
|
||||
$phone = gpc_get_string($_POST, 'phone', 30);
|
||||
$email = gpc_get_string($_POST, 'email', 50);
|
||||
$web = gpc_get_string($_POST, 'web', 40);
|
||||
$customerno = gpc_get_string($_POST, 'customerno', 20);
|
||||
$contractno = gpc_get_string($_POST, 'contractno', 20);
|
||||
$remarks = gpc_get_string($_POST, 'remarks', 150);
|
||||
$sql = "UPDATE company "
|
||||
. "SET compname=:compname,"
|
||||
. " comptype=:comptype,"
|
||||
. " street=:street,"
|
||||
. " zip=:zip,"
|
||||
. " city=:city,"
|
||||
. " country=:country,"
|
||||
. " contact=:contact,"
|
||||
. " phone=:phone,"
|
||||
. " email=:email,"
|
||||
. " web=:web,"
|
||||
. " customerno=:customerno,"
|
||||
. " contractno=:contractno,"
|
||||
. " remarks=:remarks "
|
||||
. "WHERE compid=:compid";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->bindValue(':compid', $id, PDO::PARAM_INT);
|
||||
$sth->bindValue(':compname', $compname, PDO::PARAM_STR);
|
||||
$sth->bindValue(':comptype', $comptype, PDO::PARAM_INT);
|
||||
$sth->bindValue(':street', $street, PDO::PARAM_STR);
|
||||
$sth->bindValue(':zip', $zip, PDO::PARAM_STR);
|
||||
$sth->bindValue(':city', $city, PDO::PARAM_STR);
|
||||
$sth->bindValue(':country', $country, PDO::PARAM_STR);
|
||||
$sth->bindValue(':contact', $contact, PDO::PARAM_STR);
|
||||
$sth->bindValue(':phone', $phone, PDO::PARAM_STR);
|
||||
$sth->bindValue(':email', $email, PDO::PARAM_STR);
|
||||
$sth->bindValue(':web', $web, PDO::PARAM_STR);
|
||||
$sth->bindValue(':customerno', $customerno, PDO::PARAM_STR);
|
||||
$sth->bindValue(':contractno', $contractno, PDO::PARAM_STR);
|
||||
$sth->bindValue(':remarks', $remarks, PDO::PARAM_STR);
|
||||
$sth->execute();
|
||||
$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;
|
||||
}
|
||||
unset($_SESSION['token']);
|
||||
$sth = $pdo->prepare("DELETE FROM company WHERE compid=?");
|
||||
$sth->execute([$id]);
|
||||
$g_message->Add(sprintf(_('Deleted company no. %d'), $id));
|
||||
$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 =======================================
|
||||
|
||||
echo '<h1>', $pagetitle , "</h1>\n";
|
||||
|
||||
$sql = "SELECT compid, compname, comptype, remarks "
|
||||
. "FROM company "
|
||||
. "ORDER BY comptype, compname";
|
||||
$sth = $pdo->query($sql);
|
||||
$res = $sth->fetchAll();
|
||||
echo '<table class="table table-striped">', "\n";
|
||||
echo "<thead>\n";
|
||||
echo "<tr>";
|
||||
echo "<th>" . _('Name') . "</th>";
|
||||
echo "<th>" . _('Type') . "</th>";
|
||||
echo "<th>" . _('Remarks') . "</th>";
|
||||
echo "<th> </th>";
|
||||
echo "</tr>\n";
|
||||
echo "</thead>\n";
|
||||
foreach ($res as $row) {
|
||||
echo "<tr>\n";
|
||||
echo "<td>". $row['compname'] ."</td>\n";
|
||||
echo "<td>". $opt_comptype[$row['comptype']] ."</td>\n";
|
||||
echo "<td>". $row['remarks'] ."</td>\n";
|
||||
// Action buttons
|
||||
echo "<td>";
|
||||
echo '<a title="', _('View'), '" href="', $g_scriptname, '?f=view&id=', $row['compid'], '"><i class="bi-eye"></i></a>', "\n";
|
||||
echo '<a title="', _('Edit'), '" href="', $g_scriptname, '?f=edit&id=', $row['compid'], '"><i class="bi-pencil"></i></a>';
|
||||
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 Company'), "</h2>\n";
|
||||
?>
|
||||
<form method="post">
|
||||
<div class="mb-3">
|
||||
<label for="compname" class="form-label"><?=_('Name')?></label>
|
||||
<input type="text" class="form-control" id="compname" name="compname">
|
||||
</div>
|
||||
<?php form_create_select('comptype', _('Company type'), $opt_comptype); ?>
|
||||
<button type="submit" name="submit[insert]" class="btn btn-primary"><?=_('Save')?></button>
|
||||
<a href="<?=$g_scriptname?>" class="btn btn-secondary"><?=_('Back')?></a>
|
||||
</form>
|
||||
<?php
|
||||
|
||||
elseif ($action == ACT_VIEW):
|
||||
// ========== VARIANT: view single record =====================================
|
||||
|
||||
$sql = "SELECT compname, comptype, street, zip, city, country,"
|
||||
. " contact, phone, email, web, customerno, contractno, remarks "
|
||||
. "FROM company "
|
||||
. "WHERE compid=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$id]);
|
||||
$company = $sth->fetch(PDO::FETCH_OBJ);
|
||||
|
||||
echo "<h2>", $company->compname, "</h2>\n";
|
||||
|
||||
echo '<table class="table">', "\n";
|
||||
echo '<tr><th scope="row">', _('Name'),"</th><td>", $company->compname, "</td></tr>\n";
|
||||
echo '<tr><th scope="row">', _('Type'),"</th><td>", $opt_comptype[$company->comptype], "</td></tr>\n";
|
||||
echo '<tr><th scope="row">', _('Street'),"</th><td>", $company->street, "</td></tr>\n";
|
||||
echo '<tr><th scope="row">', _('Zip, City'),"</th><td>", $company->zip, ' ', $company->city, "</td></tr>\n";
|
||||
echo '<tr><th scope="row">', _('Country'),"</th><td>", $company->country, "</td></tr>\n";
|
||||
echo '<tr><th scope="row">', _('Contact'),"</th><td>", $company->contact, "</td></tr>\n";
|
||||
echo '<tr><th scope="row">', _('Phone'),"</th><td>", $company->phone, "</td></tr>\n";
|
||||
echo '<tr><th scope="row">', _('Email'),"</th><td>", $company->email, "</td></tr>\n";
|
||||
echo '<tr><th scope="row">', _('Web'),"</th><td>", $company->web, "</td></tr>\n";
|
||||
echo '<tr><th scope="row">', _('Customer no.'),"</th><td>", $company->customerno, "</td></tr>\n";
|
||||
echo '<tr><th scope="row">', _('Contract no.'),"</th><td>", $company->contractno, "</td></tr>\n";
|
||||
echo '<tr><th scope="row">', _('Remarks'),"</th><td>", $company->remarks, "</td></tr>\n";
|
||||
echo "</table>\n";
|
||||
|
||||
form_view_buttons($g_scriptname, $id);
|
||||
|
||||
// show referenced equipment
|
||||
$sql = "SELECT ename FROM equipment WHERE supplier=:id OR manufacturer=:id";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->bindValue(':id', $id, PDO::PARAM_INT);
|
||||
$sth->execute();
|
||||
if ($sth->rowCount > 0) {
|
||||
echo "<p>Referenced in equipment:</p>\n";
|
||||
echo "<ul>\n";
|
||||
foreach ($sth->fetchAll() as $row) {
|
||||
echo "<li>", $row['ename'], "</li>\n";
|
||||
}
|
||||
echo "</ul>\n";
|
||||
} else {
|
||||
echo '<p>', _('Not referenced in any equipment'), "<p>\n";
|
||||
}
|
||||
|
||||
elseif ($action == ACT_EDIT):
|
||||
// ========== VARIANT: edit single record =====================================
|
||||
|
||||
echo '<h2>', _('Edit Company'), "</h2>\n";
|
||||
|
||||
$sql = "SELECT compname, comptype, street, zip, city, country,"
|
||||
. " contact, phone, email, web, customerno, contractno, remarks "
|
||||
. "FROM company "
|
||||
. "WHERE compid=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$id]);
|
||||
$company = $sth->fetch(PDO::FETCH_OBJ);
|
||||
|
||||
?>
|
||||
<form method="post" action="<?=$g_scriptname?>">
|
||||
<input type="hidden" name="id" value="<?=$id?>">
|
||||
<div class="mb-3">
|
||||
<label for="compname" class="form-label"><?=_('Name')?></label>
|
||||
<input type="text" class="form-control" id="compname" name="compname" value="<?=$company->compname ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="comptype" class="form-label"><?=_('Company type')?></label>
|
||||
<select name="comptype" class="form-control">
|
||||
<?php
|
||||
foreach ($opt_comptype as $k => $v) {
|
||||
echo '<option value="', $k ,'"';
|
||||
if ($company->comptype == $k) {
|
||||
echo ' selected';
|
||||
}
|
||||
echo '>', $v, "</option>\n";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="street" class="form-label"><?=_('Street')?></label>
|
||||
<input type="text" class="form-control" id="street" name="street" value="<?=$company->street ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="zip" class="form-label"><?=_('Zip')?></label>
|
||||
<input type="text" class="form-control" id="zip" name="zip" value="<?=$company->zip ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="city" class="form-label"><?=_('City')?></label>
|
||||
<input type="text" class="form-control" id="city" name="city" value="<?=$company->city ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="country" class="form-label"><?=_('Country')?></label>
|
||||
<input type="text" class="form-control" id="country" name="country" value="<?=$company->country ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="contact" class="form-label"><?=_('Contact')?></label>
|
||||
<input type="text" class="form-control" id="contact" name="contact" value="<?=$company->contact ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="phone" class="form-label"><?=_('Phone')?></label>
|
||||
<input type="text" class="form-control" id="phone" name="phone" value="<?=$company->phone ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="email" class="form-label"><?=_('Email')?></label>
|
||||
<input type="text" class="form-control" id="email" name="email" value="<?=$company->email ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="web" class="form-label"><?=_('Web')?></label>
|
||||
<input type="text" class="form-control" id="web" name="web" value="<?=$company->web ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="customerno" class="form-label"><?=_('Customer no.')?></label>
|
||||
<input type="text" class="form-control" id="customerno" name="customerno" value="<?=$company->customerno ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="contractno" class="form-label"><?=_('Contract no.')?></label>
|
||||
<input type="text" class="form-control" id="contractno" name="contractno" value="<?=$company->contractno ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="remarks" class="form-label"><?=_('Remarks')?></label>
|
||||
<textarea class="form-control" id="remarks" name="remarks" rows="3"><?=$company->remarks ?></textarea>
|
||||
</div>
|
||||
<button type="submit" name="submit[update]" class="btn btn-primary"><?=_('Save')?></button>
|
||||
<a href="<?=$g_scriptname?>?f=view&id=<?=$id?>" class="btn btn-secondary"><?=_('Back')?></a>
|
||||
</form>
|
||||
<?php
|
||||
|
||||
elseif ($action == ACT_DELETE):
|
||||
// ========== VARIANT: delete record ==========================================
|
||||
|
||||
$sql = "SELECT compname, remarks FROM company WHERE compid=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$id]);
|
||||
$company = $sth->fetch(PDO::FETCH_OBJ);
|
||||
|
||||
echo '<h2>', _('Delete Company'), "</h2>\n";
|
||||
echo '<p>', sprintf(_('Record no. %d'), $id), "</p>\n";
|
||||
echo '<p>Name: ', $company->compname, "</p>";
|
||||
echo '<p>Remarks: ', $company->remarks, "</p>";
|
||||
|
||||
// Still used as a supplier or manufacturer for equipment?
|
||||
$sql = "SELECT COUNT(*) FROM equipment WHERE supplier=:id OR manufacturer=:id";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->bindValue(':id', $id, PDO::PARAM_INT);
|
||||
$sth->execute();
|
||||
$usecount = $sth->fetchColumn();
|
||||
|
||||
if ($usecount > 0) {
|
||||
echo '<p class="alert alert-warning">', _('Company can not be deleted as there are equipment-references!'), "<p>\n";
|
||||
echo '<a href="', $g_scriptname, '?f=view&id=', $id, '" class="btn btn-secondary">', _('Back'), "</a>\n";
|
||||
|
||||
} else {
|
||||
echo '<p>', _('Deleting a company is final. There is no way back. Only delete if you are absolute sure.'), "</p>\n";
|
||||
$_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';
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
/******************************************************************************
|
||||
* YMS - Yacht Management Software
|
||||
* Copyright (C) 2024 Thomas Hooge
|
||||
*
|
||||
* SPDX-License-Identifier: WTFPL
|
||||
*****************************************************************************/
|
||||
|
||||
// ========== GLOBAL CONSTANTS ================================================
|
||||
|
||||
define('APP_TITLE', 'Yacht Management Software');
|
||||
define('APP_TITLE_SHORT', 'YMS');
|
||||
define('APP_SESSION', 'yms');
|
||||
|
||||
// ========== GLOBAL VARIABLES ================================================
|
||||
|
||||
// database connection
|
||||
$g_db_host = 'localhost';
|
||||
$g_db_username = 'yms';
|
||||
$g_db_password = 'changeme!';
|
||||
$g_db_schema = 'yms';
|
||||
|
||||
// mail settings
|
||||
$g_mailto = 'captain@example.com';
|
||||
$g_mailto_webmaster = 'webmaster@example.com';
|
||||
|
||||
// localization
|
||||
$g_timezone = 'Europe/Berlin';
|
||||
$g_locale = 'de_DE.UTF-8';
|
||||
|
||||
// documents and images
|
||||
$g_doc_basepath = '/var/local/yms';
|
||||
$g_doc_maxsize = 1024*1024*16; // 16 MB
|
||||
|
||||
$g_storage_limit = 1024; // MB
|
||||
|
||||
$g_thumb_size = 120;
|
||||
@@ -0,0 +1,16 @@
|
||||
body {
|
||||
font-family: "Noto Sans", "Bitstream Vera Sans", Arial, sans;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: #444;
|
||||
}
|
||||
|
||||
@media print {
|
||||
footer {
|
||||
display : none;
|
||||
}
|
||||
.noPrint {
|
||||
display : none;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
/******************************************************************************
|
||||
* YMS - Yacht Management Software
|
||||
* Copyright (C) 2024 Thomas Hooge
|
||||
*
|
||||
* SPDX-License-Identifier: WTFPL
|
||||
******************************************************************************/
|
||||
|
||||
/* Document Downloader
|
||||
Doucuments are not directly accessible via filesystem
|
||||
dl.php must be used with docid as parameter:
|
||||
e,g, dl.php?id=23 */
|
||||
|
||||
require 'globals.inc';
|
||||
|
||||
$docid = gpc_get_int($_GET, 'id');
|
||||
|
||||
$sql = "SELECT doctype, docsize, mimetype, hash, extension, filename FROM document WHERE docid=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$docid]);
|
||||
$row = $sth->fetch();
|
||||
$dtmap = array(
|
||||
'generic' => 'doc',
|
||||
'manual' => 'man',
|
||||
'invoice' => 'inv',
|
||||
'picture' => 'pic',
|
||||
'drawing' => 'drw');
|
||||
$file = sprintf("%s/%s-%s.%s", $g_doc_basepath, $dtmap[$row['doctype']], $row['hash'], $row['extension']);
|
||||
|
||||
if (file_exists($file)) {
|
||||
header('Content-Description: File Transfer');
|
||||
header('Content-Type: ' . $row['mimetype']);
|
||||
header('Content-Disposition: attachment; filename="' . $row['filename'] . '"');
|
||||
header('Expires: 0');
|
||||
header('Cache-Control: must-revalidate');
|
||||
header('Pragma: public');
|
||||
if ($row['docsize'] == 0) {
|
||||
header('Content-Length: ' . filesize($file));
|
||||
} else {
|
||||
header('Content-Length: ' . $row['docsize']);
|
||||
}
|
||||
readfile($file);
|
||||
exit;
|
||||
} else {
|
||||
// dynamically create error image
|
||||
// TODO
|
||||
}
|
||||
@@ -0,0 +1,405 @@
|
||||
<?php
|
||||
/******************************************************************************
|
||||
* YMS - Yacht Management Software
|
||||
* Copyright (C) 2024 Thomas Hooge
|
||||
*
|
||||
* SPDX-License-Identifier: WTFPL
|
||||
******************************************************************************/
|
||||
|
||||
require 'globals.inc';
|
||||
$pagetitle = _('Documents');
|
||||
|
||||
$id = gpc_get_int($_REQUEST, 'id', 0);
|
||||
|
||||
// ========== 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 'insert':
|
||||
// WIP New standalone document
|
||||
$title = gpc_get_string($_POST, 'title');
|
||||
$remarks = gpc_get_string($_POST, 'remarks');
|
||||
$g_message->Add(print_r($_FILES, true));
|
||||
if (empty($_FILES['files']['tmp_name']) ) {
|
||||
$g_warning->Add(_('No file for upload submitted. Try again by selecting a file first.'));
|
||||
$action = ACT_ADD;
|
||||
break;
|
||||
}
|
||||
$mimetypes = ['image/png', 'image/jpeg', 'image/svg+xml', 'application/pdf'];
|
||||
$nerr = 0;
|
||||
$file_name = $_FILES['files']['name'];
|
||||
$file_tmp = $_FILES['files']['tmp_name'];
|
||||
$file_type = $_FILES['files']['type'];
|
||||
$file_size = $_FILES['files']['size'];
|
||||
$file_ext = strtolower(end(explode('.', $_FILES['files']['name'])));
|
||||
$file_mimetype = mime_content_type($file_tmp);
|
||||
if (!in_array($file_mimetype, $mimetypes)) {
|
||||
$g_error->Add(sprintf(_("Mimetype '%s' not allowed for upload."), $file_mimetype));
|
||||
$action = ACT_ADD;
|
||||
break;
|
||||
};
|
||||
if ($file_type != $file_mimetype) {
|
||||
$g_warning->Add(sprintf(_("Mimetype mismatch: '%s'."), $file_type));
|
||||
}
|
||||
// ok let's go
|
||||
$file_hash = md5_file($file_tmp);
|
||||
$file_timestamp = date('Y-m-d H:i:s', filemtime($file_tmp));
|
||||
|
||||
// check if the file already exists, in which case issue
|
||||
// a notice and display the existing document
|
||||
$sth = $pdo->prepare("SELECT docid FROM document WHERE hash=?");
|
||||
$sth->execute([$file_hash]);
|
||||
$id = $sth->fetchColumn();
|
||||
if ($id) {
|
||||
$g_warning->Add(_('Document already exists!'));
|
||||
$action = ACT_VIEW;
|
||||
break;
|
||||
}
|
||||
switch ($file_mimetype) {
|
||||
case 'application/pdf':
|
||||
$file_techname = $g_doc_basepath . '/doc-'.$file_hash.'.'.$file_ext;
|
||||
$doctype = 'generic';
|
||||
break;
|
||||
case 'image/svg+xml':
|
||||
$file_techname = $g_doc_basepath . '/drw-'.$file_hash.'.'.$file_ext;
|
||||
$doctype = 'drawing';
|
||||
break;
|
||||
case 'image/png':
|
||||
case 'image/jpeg':
|
||||
$file_techname = $g_doc_basepath . '/pic-'.$file_hash.'.'.$file_ext;
|
||||
$doctype = 'picture';
|
||||
break;
|
||||
}
|
||||
$sql = "INSERT INTO document"
|
||||
. " (doctype, filename, extension, hash, doctime, docsize, mimetype) "
|
||||
. "VALUES"
|
||||
. " (?, ?, ?, ?, ?, ?, ?)";
|
||||
$sth = $pdo->prepare($sql);
|
||||
try {
|
||||
$sth->execute([$doctype, $file_name, $file_ext, $file_hash, $file_timestamp, $file_size, $file_mimetype]);
|
||||
} catch (PDOException $e) {
|
||||
$g_error->Add('SQL-Error: '. $e->getMessage());
|
||||
}
|
||||
$id = $pdo->lastInsertId();
|
||||
move_uploaded_file($file_tmp, $file_techname);
|
||||
$action = ACT_VIEW;
|
||||
break;
|
||||
|
||||
case 'update':
|
||||
$filename = gpc_get_string($_POST, 'filename');
|
||||
$title = gpc_get_string($_POST, 'title', 40);
|
||||
$remarks = gpc_get_string($_POST, 'remarks', 150);
|
||||
$sql = "UPDATE document "
|
||||
. "SET filename=:filename,"
|
||||
. " title=:title,"
|
||||
. " remarks=:remarks "
|
||||
. "WHERE docid=:docid";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->bindValue(':docid', $id, PDO::PARAM_INT);
|
||||
$sth->bindValue(':filename', $filename, PDO::PARAM_STR);
|
||||
$sth->bindValue(':title', $title, PDO::PARAM_STR);
|
||||
$sth->bindValue(':remarks', $remarks, PDO::PARAM_STR);
|
||||
try {
|
||||
$sth->execute();
|
||||
} catch (PDOException $e) {
|
||||
$g_error->Add('SQL-Error: '. $e->getMessage());
|
||||
}
|
||||
$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;
|
||||
}
|
||||
$action = ACT_DEFAULT;
|
||||
break;
|
||||
|
||||
case 'addref':
|
||||
$eid = gpc_get_int($_POST, 'eid');
|
||||
$sql = "INSERT INTO docref "
|
||||
. " (docid, refid, reftype) "
|
||||
. "VALUES "
|
||||
. " (:docid, :refid, 'equipment')";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->bindValue(':docid', $id, PDO::PARAM_INT);
|
||||
$sth->bindValue(':refid', $eid, PDO::PARAM_INT);
|
||||
$sth->execute();
|
||||
$action = ACT_VIEW;
|
||||
break;
|
||||
|
||||
case 'delref':
|
||||
// remove only link, not critical so get without token is ok
|
||||
$drid = gpc_get_int($_GET, 'drid');
|
||||
$sql = "DELETE FROM docref WHERE drid=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$drid]);
|
||||
$g_message->Add(_('Removed document reference'));
|
||||
$action = ACT_VIEW;
|
||||
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 =======================================
|
||||
|
||||
// All documents
|
||||
|
||||
/* TODO show all documents which
|
||||
- are completely unbound: no docref available
|
||||
- assigned to the current boat: docref with doctype vessel
|
||||
- are assigned to an equipment or project of current vesseö
|
||||
There can be multiple docref entries for a document,
|
||||
behavior still needs to be clarified. */
|
||||
|
||||
echo "<h1>$pagetitle</h1>\n";
|
||||
|
||||
$sql = "SELECT d.docid, d.doctype, d.filename, d.title, COUNT(r.drid) AS refcount "
|
||||
. "FROM document AS d LEFT OUTER JOIN docref AS r USING (docid) "
|
||||
. "GROUP BY d.docid, d.doctype, d.filename, d.title";
|
||||
$sth = $pdo->query($sql);
|
||||
$res = $sth->fetchAll();
|
||||
echo '<table class="table table-striped">', "\n";
|
||||
echo "<thead>\n";
|
||||
echo "<tr>";
|
||||
echo "<th>" . _('ID') . "</th>";
|
||||
echo "<th>" . _('Type') . "</th>";
|
||||
echo "<th>" . _('Filename') . "</th>";
|
||||
echo "<th>" . _('Title') . "</th>";
|
||||
echo "<th>" . _('Links') . "</th>";
|
||||
echo "<th> </th>";
|
||||
echo "</tr>\n";
|
||||
echo "</thead>\n";
|
||||
foreach ($res as $row) {
|
||||
echo "<tr>\n";
|
||||
echo "<td>". $row['docid'] ."</td>\n";
|
||||
echo "<td>". $row['doctype'] ."</td>\n";
|
||||
echo "<td>". $row['filename'] ."</td>\n";
|
||||
echo "<td>". $row['title'] ."</td>\n";
|
||||
echo "<td>". $row['refcount'] ."</td>\n";
|
||||
// Action buttons
|
||||
echo "<td>";
|
||||
echo '<a title="', _('View'), '" href="', $g_scriptname, '?f=view&id=', $row['docid'], '"><i class="bi-eye"></i></a>', "\n";
|
||||
echo '<a title="', _('Edit'), '" href="', $g_scriptname, '?f=edit&id=', $row['docid'], '"><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 Document'), "</h2>\n";
|
||||
?>
|
||||
<form method="post" enctype="multipart/form-data" action="<?=$g_scriptname?>">
|
||||
<div class="mb-3">
|
||||
<label for="title" class="form-label"><?=_('Title')?></label>
|
||||
<input type="text" class="form-control" id="title" name="title" value="<?=$title?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="remarks" class="form-label"><?=_('Remarks')?></label>
|
||||
<textarea class="form-control" id="remarks" name="remarks" rows="3"><?=$remarks?></textarea>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="files" class="form-label"><?=_('Document')?></label>
|
||||
<input class="form-control" type="file" id="files" name="files" onchange="preview()">
|
||||
<img id="frame" src="" class="img-fluid">
|
||||
<button class="btn btn-secondary" onclick="clearimg();return false;"><?=_('Clear')?></button>
|
||||
<script>
|
||||
function preview() {
|
||||
var images = ["image/png", "image/jpeg", "image/svg+xml"];
|
||||
console.log(event.target.files[0].type);
|
||||
if (images.indexOf(event.target.files[0].type) > -1) {
|
||||
frame.src = URL.createObjectURL(event.target.files[0]);
|
||||
} else {
|
||||
frame.src = "";
|
||||
}
|
||||
}
|
||||
function clearimg() {
|
||||
document.getElementById('file').value = null;
|
||||
frame.src = "";
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
<div class="container-fluid px-0 my-3">
|
||||
<button type="submit" name="submit[insert]" class="btn btn-primary"><?=_('Save')?></button>
|
||||
<a href="<?=$g_scriptname?>" class="btn btn-secondary"><?=_('Back')?></a>
|
||||
</div>
|
||||
</form>
|
||||
<?php
|
||||
elseif ($action == ACT_VIEW):
|
||||
// ========== VARIANT: view single record =====================================
|
||||
|
||||
/* mutool: preview of page thumbs */
|
||||
|
||||
$sql = "SELECT docid, doctype, mimetype, filename, extension, hash,"
|
||||
. " docsize, doctime, title, remarks "
|
||||
. "FROM document "
|
||||
. "WHERE docid=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$id]);
|
||||
$document = $sth->fetch(PDO::FETCH_OBJ);
|
||||
|
||||
echo '<h2>', _('View Document'), "</h2>\n";
|
||||
|
||||
echo '<table class="table table-borderless">', "\n";
|
||||
echo '<tr><th scope="row" style="width:20%">', _('Document type'),"</th><td>", $document->doctype, "</td></tr>\n";
|
||||
if ($document->doctype == 'picture') {
|
||||
$techname = 'pic-' . $document->hash . '.' . $document->extension;
|
||||
echo '<tr><th scope="row">', _('Preview'), '</th><td>';
|
||||
// echo '<a href="doc/', $techname, '" target="_blank"><img width="', $g_thumb_size, '" src="doc/', $techname, '" alt="', $document->title, '"></a>';
|
||||
echo '<a href="dl.php?id=', $document->docid, '" target="_blank">';
|
||||
echo '<img width="', $g_thumb_size, '" src="dl.php?id=', $document->docid, '" alt="', $document->title, '">';
|
||||
echo '</a>';
|
||||
echo "</td></tr>\n";
|
||||
} elseif (($document->doctype == 'drawing')) {
|
||||
echo '<tr><th scope="row">', _('Drawing'), '</th>';
|
||||
echo '<td><img src="dl.php?id=', $document->docid, '" alt="', $document->title, '"></td></tr>', "\n";
|
||||
} elseif (($document->doctype == 'generic')) {
|
||||
$techname = 'doc-' . $document->hash . '.' . $document->extension;
|
||||
if ($document->mimetype == 'application/pdf') {
|
||||
// TODO show preview of previewpage, ctrate thumbnail if needed
|
||||
|
||||
// Download link
|
||||
echo '<tr><th scope="row">', _('PDF'), '</th><td><a href="dl.php?id=', $document->docid, '">', $document->title ?? _('Download'), "</a></td></tr>\n";
|
||||
}
|
||||
}
|
||||
echo '<tr><th scope="row">', _('Mimetype'),"</th><td>", $document->mimetype, "</td></tr>\n";
|
||||
echo '<tr><th scope="row">', _('Filename'),"</th><td>", $document->filename, "</td></tr>\n";
|
||||
echo '<tr><th scope="row">', _('File size'),"</th><td>", $document->docsize, "</td></tr>\n";
|
||||
echo '<tr><th scope="row">', _('Upload date'),"</th><td>", $document->doctime, "</td></tr>\n";
|
||||
echo '<tr><th scope="row">', _('Title'),"</th><td>", $document->title, "</td></tr>\n";
|
||||
echo '<tr><th scope="row">', _('Remarks'),"</th><td>", $document->remarks, "</td></tr>\n";
|
||||
echo "</table>\n";
|
||||
|
||||
form_view_buttons($g_scriptname, $id);
|
||||
|
||||
|
||||
echo '<h3>', _('Document references'), "</h3>\n";
|
||||
$sql = "SELECT drid, reftype, ename AS name, eid "
|
||||
. "FROM docref INNER JOIN equipment ON (docref.reftype='equipment' AND docref.refid=equipment.eid) "
|
||||
. "WHERE docid=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$id]);
|
||||
echo '<table class="table table-sm">', "\n";
|
||||
echo "<thead>\n";
|
||||
echo "<tr>";
|
||||
echo '<th style="width:20%">' . _('Type') . "</th>";
|
||||
echo "<th>" . _('Used by') . "</th>";
|
||||
echo "<td></td>";
|
||||
echo "</tr>\n";
|
||||
echo "</thead>\n";
|
||||
$eids = array();
|
||||
foreach ($sth->fetchAll() as $row) {
|
||||
$eids[] = $row['eid'];
|
||||
echo "<tr>";
|
||||
echo "<td>", $row['reftype'], "</td>";
|
||||
echo "<td>", $row['name'], "</td>";
|
||||
echo "<td>";
|
||||
echo '<a title="', _('Remove'), '" href="', $script, '?f=delref&id=', $id, '&drid=', $row['drid'], '"><i class="bi-trash"></i></a>';
|
||||
echo "</td>";
|
||||
echo "</tr>\n";
|
||||
}
|
||||
echo "</table>\n";
|
||||
|
||||
// Equipment options
|
||||
// Do not include equipment that has already been referenced in the list!
|
||||
$opt_equipment = array();
|
||||
$sql = "SELECT eid, ename FROM equipment WHERE vid=? ORDER BY ename";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$user->vid]);
|
||||
foreach ($sth->fetchAll() as $row) {
|
||||
if (!in_array($row['eid'], $eids)) {
|
||||
$opt_equipment[$row['eid']] = $row['ename'];
|
||||
}
|
||||
}
|
||||
?>
|
||||
<form method="post" action="<?=$g_scriptname?>">
|
||||
<input type="hidden" name="id" value="<?=$id?>">
|
||||
<select name="eid">
|
||||
<?php
|
||||
foreach ($opt_equipment as $k => $v) {
|
||||
echo '<option value="', $k, '">', $v, "</option>\n";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<button class="btn btn-secondary" name="submit[addref]">Referenzieren</button>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
|
||||
elseif ($action == ACT_EDIT):
|
||||
// ========== VARIANT: edit single record =====================================
|
||||
|
||||
echo '<h2>', _('Edit Document'), "</h2>\n";
|
||||
|
||||
$sql = "SELECT docid, doctype, filename, extension, hash, title, remarks "
|
||||
. "FROM document "
|
||||
. "WHERE docid=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$id]);
|
||||
$document = $sth->fetch(PDO::FETCH_OBJ);
|
||||
|
||||
if ($document->doctype == 'picture') {
|
||||
echo '<img width="', $g_thumb_size, '" src="doc/pic-', $document->hash, '.', $document->extension, '">';
|
||||
}
|
||||
|
||||
?>
|
||||
<form method="post" action="<?=$g_scriptname?>">
|
||||
<input type="hidden" name="id" value="<?=$id?>">
|
||||
<div class="mb-3">
|
||||
<label for="title" class="form-label"><?=_('Filename')?></label>
|
||||
<input type="text" class="form-control" id="filename" name="filename" value="<?=$document->filename ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="title" class="form-label"><?=_('Title')?></label>
|
||||
<input type="text" class="form-control" id="title" name="title" value="<?=$document->title ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="remarks" class="form-label"><?=_('Remarks')?></label>
|
||||
<textarea class="form-control" id="remarks" name="remarks" rows="3"><?=$storage->remarks ?></textarea>
|
||||
</div>
|
||||
<button type="submit" name="submit[update]" class="btn btn-primary"><?=_('Save')?></button>
|
||||
<a href="<?=$g_scriptname?>?f=view&id=<?=$id?>" class="btn btn-secondary"><?=_('Back')?></a>
|
||||
</form>
|
||||
<?php
|
||||
|
||||
elseif ($action == ACT_DELETE):
|
||||
// ========== VARIANT: delete record ==========================================
|
||||
|
||||
echo '<h2>', _('Delete Document'), "</h2>\n";
|
||||
|
||||
else:
|
||||
// ========== ERROR UNKNOWN VARIANT ===========================================
|
||||
|
||||
echo '<p>', _('Unknown function call: Please report to system development!'), "</p>\n";
|
||||
|
||||
endif; // $action == ...
|
||||
// ========== END OF VARIANTS =================================================
|
||||
|
||||
include 'footer.php';
|
||||
@@ -0,0 +1,271 @@
|
||||
<?php
|
||||
/******************************************************************************
|
||||
* YMS - Yacht Management Software
|
||||
* Copyright (C) 2024 Thomas Hooge
|
||||
*
|
||||
* SPDX-License-Identifier: WTFPL
|
||||
******************************************************************************/
|
||||
|
||||
require 'globals.inc';
|
||||
$pagetitle = _('Lists');
|
||||
|
||||
$id = gpc_get_int($_REQUEST, 'id', 0); // list id
|
||||
$v = gpc_get_int($_REQUEST, 'v', -1); // list value id
|
||||
|
||||
function create_ddval_form($script, $ddid, $formtype, $row=NULL) {
|
||||
|
||||
// formtype: insert or update
|
||||
$update = ($formtype == 'update');
|
||||
echo '<form method="post" action="', $script, '">';
|
||||
echo '<input type="hidden" name="id" value="', $ddid, '">';
|
||||
if ($update) {
|
||||
echo '<input type="hidden" name="v" value="', $row['ddval'], '">';
|
||||
}
|
||||
|
||||
// text in one row
|
||||
echo '<div class="form-floating">';
|
||||
echo '<input type="text" name="ddtext" id="ddtext" class="form-control"';
|
||||
if ($update) echo ' value="', $row['ddtext'],'"';
|
||||
echo '><label for="ddtext">Description</label></div>', "\n";
|
||||
|
||||
// all other fields in secondary row
|
||||
echo '<div class="row my-3">';
|
||||
|
||||
echo '<div class="col"><div class="form-floating">';
|
||||
echo '<input type="text" name="ddshort" id="ddshort"class="form-control"';
|
||||
if ($update) echo ' value="', $row['ddshort'],'"';
|
||||
echo '><label for="ddshort">Short description</label></div></div>', "\n";
|
||||
|
||||
echo '<div class="col"><div class="form-floating">';
|
||||
echo '<input type="color" name="color" id="color" class="form-control"';
|
||||
if ($update) echo ' value="', $row['color'],'"';
|
||||
echo '><label for="color">Color</label></div></div>', "\n";
|
||||
|
||||
echo '<div class="col"><div class="form-floating">';
|
||||
echo '<input type="text" name="sort" id="sort" class="form-control"';
|
||||
if ($update) echo ' value="', $row['sort'],'"';
|
||||
echo '><label for="sort">Sort</label></div></div>', "\n";
|
||||
|
||||
echo '</div>'; // finish row
|
||||
|
||||
// buttons
|
||||
echo '<button name="submit" value="', $formtype, '" class="btn btn-primary btn-sm" title="Save"><i class="bi-save"></i> Save</button>';
|
||||
echo ' ';
|
||||
echo '<a href="', $script, '?f=edit&id=', $ddid, '" class="btn btn-secondary btn-sm" title="Cancel"><i class="bi-x-square"></i> Cancel</a>';
|
||||
|
||||
echo "</form>\n";
|
||||
}
|
||||
|
||||
// ========== ACTIONS START ===================================================
|
||||
|
||||
switch ($submit = form_get_action()) {
|
||||
|
||||
case NULL: break;
|
||||
|
||||
case 'add': $v = -2; $action = ACT_EDIT; break;
|
||||
case 'view': $action = ACT_VIEW; break;
|
||||
case 'edit': $action = ACT_EDIT; break;
|
||||
case 'del': $action = ACT_DELETE; break;
|
||||
|
||||
case 'insert':
|
||||
$p[':ddid'] = gpc_get_int($_POST, 'id');
|
||||
$sth = $pdo->prepare("SELECT MAX(ddval)+1 FROM dropdown WHERE ddid=?");
|
||||
$sth->execute([$p[':ddid']]);
|
||||
$p[':ddval'] = $sth->fetchColumn() ?? 1;
|
||||
$p[':ddtext'] = gpc_get_string($_POST, 'ddtext');
|
||||
$p[':ddshort'] = gpc_get_string($_POST, 'ddshort');
|
||||
$p[':color'] = gpc_get_color($_POST, 'color');
|
||||
$p[':sort'] = gpc_get_string($_POST, 'sort');
|
||||
$keys = array_keys($p);
|
||||
$fields = join(',', array_map(function($s) { return ltrim($s, ':'); }, $keys));
|
||||
$pnames = join(',', $keys);
|
||||
$sth = $pdo->prepare("INSERT INTO dropdown ($fields) VALUES ($pnames)");
|
||||
try {
|
||||
$sth->execute($p);
|
||||
} catch (PDOexception $e) {
|
||||
$g_error->Add('SQL-Error: '. $e->getMessage());
|
||||
}
|
||||
$action = ACT_EDIT;
|
||||
break;
|
||||
|
||||
case 'update':
|
||||
$p[':ddtext'] = gpc_get_string($_POST, 'ddtext');
|
||||
$p[':ddshort'] = gpc_get_string($_POST, 'ddshort');
|
||||
$p[':color'] = gpc_get_color($_POST, 'color');
|
||||
$p[':sort'] = gpc_get_string($_POST, 'sort');
|
||||
$fields = join(',', array_map(function($s) { return ltrim($s, ':') . '=' . $s; }, array_keys($p)));
|
||||
$sth = $pdo->prepare("UPDATE dropdown SET $fields WHERE ddid=:ddid AND ddval=:ddval");
|
||||
$p[':ddid'] = gpc_get_int($_POST, 'id');
|
||||
$p[':ddval'] = gpc_get_int($_POST, 'v');
|
||||
try {
|
||||
$sth->execute($p);
|
||||
} catch (PDOexception $e) {
|
||||
$g_error->Add('SQL-Error: '. $e->getMessage());
|
||||
}
|
||||
unset($v);
|
||||
$action = ACT_EDIT;
|
||||
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 =======================================
|
||||
|
||||
// record counts
|
||||
$num = array();
|
||||
$sql = "SELECT ddid, COUNT(*) AS n FROM dropdown WHERE ddid>0 GROUP BY ddid";
|
||||
$sth = $pdo->query($sql);
|
||||
foreach ($sth->fetchAll(PDO::FETCH_NUM) as $row) {
|
||||
$num[$row[0]] = $row[1];
|
||||
}
|
||||
$sql = "SELECT ddval, ddtext FROM dropdown WHERE ddid=0 AND ddval>0";
|
||||
$sth = $pdo->query($sql);
|
||||
|
||||
echo "<h1>$pagetitle</h1>\n";
|
||||
|
||||
echo '<p>', _('Danger! Only adjust if it is clear what impact this will have!'), "<br>\n";
|
||||
// <p>Achtung! Nur anpassen wenn klar ist was das für Auswirkungen hat!</p>
|
||||
|
||||
echo _('Adding values is usually not critical.'), "</p>\n";
|
||||
// <p>Hinzufügen von Werten ist in der Regel unkritisch.</p>
|
||||
|
||||
echo '<table class="table">', "\n";
|
||||
echo '<thead>';
|
||||
echo '<tr>';
|
||||
echo '<th>#</th>';
|
||||
echo '<th>', _('Description'),'</th>';
|
||||
echo '<th>', _('Number'),'</th>';
|
||||
echo '<td></td>';
|
||||
echo '</tr>';
|
||||
echo '</thead>';
|
||||
foreach ($sth->fetchAll() as $row) {
|
||||
echo '<tr><td>', $row['ddval'],'</td>';
|
||||
echo '<td>', $row['ddtext'], '</td>';
|
||||
echo '<td>', $num[$row['ddval']] ?? 0, '</td>';
|
||||
form_action_buttons($g_scriptname, $row['ddval']);
|
||||
echo "</tr>\n";
|
||||
}
|
||||
echo "</table>\n";
|
||||
|
||||
elseif ($action == ACT_VIEW):
|
||||
// ========== VARIANT: view single record =====================================
|
||||
|
||||
$sth = $pdo->prepare("SELECT ddtext FROM dropdown WHERE ddid=0 AND ddval=?");
|
||||
$sth->execute([$id]);
|
||||
$listname = $sth->fetchColumn();
|
||||
|
||||
echo '<h2>', sprintf(_('View List: %s'), $listname), "</h2>\n";
|
||||
|
||||
$sql = "SELECT ddval, ddtext, ddshort, color, sort FROM dropdown WHERE ddid=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$id]);
|
||||
|
||||
echo '<table class="table">';
|
||||
echo "<thead>\n";
|
||||
echo "<tr>\n";
|
||||
echo '<th>#</th>';
|
||||
echo '<th>', _('Name'), "</th>";
|
||||
echo '<th>', _('Short'), "</th>";
|
||||
echo '<th>', _('Color'), "</th>";
|
||||
echo '<th>', _('Sort'), "</th>";
|
||||
echo "<th></th>\n";
|
||||
echo "</tr>\n";
|
||||
echo "</thead>\n";
|
||||
|
||||
foreach ($sth->fetchAll() as $row) {
|
||||
echo '<tr>';
|
||||
echo '<td>', $row['ddval'],'</td>';
|
||||
echo '<td>', $row['ddtext'], '</td>';
|
||||
echo '<td>', $row['ddshort'], '</td>';
|
||||
echo '<td>', $row['color'], '</td>';
|
||||
echo '<td>', $row['sort'], '</td>';
|
||||
echo "</tr>\n";
|
||||
}
|
||||
echo "</table>\n";
|
||||
|
||||
echo '<a href="', $g_scriptname, '" class="btn btn-secondary">', _('Back'), "</a>\n";
|
||||
|
||||
elseif ($action == ACT_EDIT):
|
||||
// ========== VARIANT: edit single record =====================================
|
||||
|
||||
$sth = $pdo->prepare("SELECT ddtext FROM dropdown WHERE ddid=0 AND ddval=?");
|
||||
$sth->execute([$id]);
|
||||
$listname = $sth->fetchColumn();
|
||||
|
||||
echo '<h2>', sprintf(_('Edit List: %s'), $listname), "</h2>\n";
|
||||
|
||||
$sql = "SELECT ddval, ddtext, ddshort, color, sort FROM dropdown WHERE ddid=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$id]);
|
||||
|
||||
echo '<table class="table">';
|
||||
echo "<thead>\n";
|
||||
echo "<tr>\n";
|
||||
echo '<th>#</th>';
|
||||
echo '<th>', _('Name'), "</th>";
|
||||
echo '<th>', _('Short'), "</th>";
|
||||
echo '<th>', _('Color'), "</th>";
|
||||
echo '<th>', _('Sort'), "</th>";
|
||||
echo "<th></th>\n";
|
||||
echo "</tr>\n";
|
||||
echo "</thead>\n";
|
||||
|
||||
foreach ($sth->fetchAll() as $row) {
|
||||
echo '<tr>';
|
||||
if ($row['ddval'] == $v) {
|
||||
echo '<td>', $row['ddval'], '</td>';
|
||||
echo '<td colspan="4">';
|
||||
create_ddval_form($g_scriptname, $id, 'update', $row);
|
||||
echo '</td>';
|
||||
echo "<td></td>\n";
|
||||
} else {
|
||||
echo '<td>', $row['ddval'],'</td>';
|
||||
echo '<td>', $row['ddtext'], '</td>';
|
||||
echo '<td>', $row['ddshort'], '</td>';
|
||||
echo '<td>', $row['color'], '</td>';
|
||||
echo '<td>', $row['sort'], '</td>';
|
||||
// Action links
|
||||
echo '<td>';
|
||||
echo '<a href="', $g_scriptname, '?f=edit&id=', $id, '&v=', $row['ddval'], '"><i class="bi-pencil"></i></a>';
|
||||
echo ' ';
|
||||
echo '<i class="bi-trash"></i>';
|
||||
echo '</td>', "\n";
|
||||
// TODO extend function to accept additional parameters
|
||||
// form_action_buttons($g_scriptname, $row['ddid'];
|
||||
}
|
||||
echo "</tr>\n";
|
||||
}
|
||||
if ($v == -2) {
|
||||
echo '<tr>';
|
||||
echo '<td>(+)</td>';
|
||||
echo '<td colspan="4">';
|
||||
create_ddval_form($g_scriptname, $id, 'insert');
|
||||
echo '</td>';
|
||||
echo "<td></td>\n";
|
||||
echo "</tr>";
|
||||
}
|
||||
echo "</table>\n";
|
||||
|
||||
echo '<a href="', $g_scriptname, '?f=add&id=', $id, '" class="btn btn-primary">', _('Add'), "</a>\n";
|
||||
echo '<a href="', $g_scriptname, '" class="btn btn-secondary">', _('Back'), "</a>\n";
|
||||
|
||||
|
||||
else:
|
||||
// ========== ERROR UNKNOWN VARIANT ===========================================
|
||||
|
||||
echo '<p>', _('Unknown function call: Please report to system development!'), "</p>\n";
|
||||
|
||||
endif; // $action == ...
|
||||
// ========== END OF VARIANTS =================================================
|
||||
|
||||
include 'footer.php';
|
||||
@@ -0,0 +1,474 @@
|
||||
<?php
|
||||
/******************************************************************************
|
||||
* YMS - Yacht Management Software
|
||||
* Copyright (C) 2024 Thomas Hooge
|
||||
*
|
||||
* SPDX-License-Identifier: WTFPL
|
||||
******************************************************************************/
|
||||
|
||||
require 'globals.inc';
|
||||
$pagetitle = _('Equipment');
|
||||
|
||||
$id = gpc_get_int($_REQUEST, 'id', 0);
|
||||
|
||||
$opt_supplier = db_get_opt_supp(array(-1 => _('unknown')));
|
||||
$opt_manufacturer = db_get_opt_manuf(array(-1 => _('unknown')));
|
||||
$opt_ecat = db_get_options(4); // Equipment categories
|
||||
|
||||
// ========== 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 'insert':
|
||||
$ename = gpc_get_string($_POST, 'ename');
|
||||
$ecat = gpc_get_int($_POST, 'category');
|
||||
$manufacturer = gpc_get_int($_POST, 'manufacturer');
|
||||
$model = gpc_get_string($_POST, 'model');
|
||||
$remarks = gpc_get_string($_POST, 'remarks', 150);
|
||||
$sql = "INSERT INTO equipment "
|
||||
. " (vid, ename, manufacturer, model, ecat, remarks) "
|
||||
. "VALUES "
|
||||
. " (:vid, :ename, :manufacturer, :model, :ecat, :remarks)";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->bindValue(':vid', $user->vid, PDO::PARAM_INT);
|
||||
$sth->bindValue(':ename', $ename, PDO::PARAM_STR);
|
||||
$sth->bindValue(':model', $model, PDO::PARAM_STR);
|
||||
$sth->bindValue(':ecat', $ecat, PDO::PARAM_INT);
|
||||
$sth->bindValue(':manufacturer', $manufacturer, PDO::PARAM_INT);
|
||||
$sth->bindValue(':remarks', $remarks, PDO::PARAM_STR);
|
||||
try {
|
||||
$sth->execute();
|
||||
} catch (PDOException $e) {
|
||||
$g_error->Add('SQL-Error: '. $e->getMessage());
|
||||
}
|
||||
$id = $pdo->lastInsertId();
|
||||
$action = ACT_VIEW;
|
||||
break;
|
||||
|
||||
case 'update':
|
||||
$ename = gpc_get_string($_POST, 'ename');
|
||||
$model = gpc_get_string($_POST, 'model');
|
||||
$serial = gpc_get_string($_POST, 'serial');
|
||||
$weight = min(gpc_get_float($_POST, 'weight'), 999.99); // limit max value
|
||||
$price = gpc_get_currency($_POST, 'price');
|
||||
$purchdate = gpc_get_date($_POST, 'purchdate');
|
||||
$supplier = gpc_get_int($_POST, 'supplier');
|
||||
$manufacturer = gpc_get_int($_POST, 'manufacturer');
|
||||
$ecat = gpc_get_int($_POST, 'category');
|
||||
$remarks = gpc_get_string($_POST, 'remarks', 150);
|
||||
$sql = "UPDATE equipment "
|
||||
. "SET ename=:ename,"
|
||||
. " model=:model,"
|
||||
. " serial=:serial,"
|
||||
. " weight=:weight,"
|
||||
. " price=:price,"
|
||||
. " purchdate=:purchdate,"
|
||||
. " supplier=:supplier,"
|
||||
. " manufacturer=:manufacturer,"
|
||||
. " ecat=:ecat,"
|
||||
. " remarks=:remarks "
|
||||
. "WHERE eid=:eid";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->bindValue(':eid', $id, PDO::PARAM_INT);
|
||||
$sth->bindValue(':ename', $ename, PDO::PARAM_STR);
|
||||
$sth->bindValue(':model', $model, PDO::PARAM_STR);
|
||||
$sth->bindValue(':serial', $serial, PDO::PARAM_STR);
|
||||
$sth->bindValue(':weight', $weight);
|
||||
$sth->bindValue(':price', $price);
|
||||
$sth->bindValue(':purchdate', $purchdate, PDO::PARAM_STR);
|
||||
$sth->bindValue(':supplier', $supplier, PDO::PARAM_INT);
|
||||
$sth->bindValue(':manufacturer', $manufacturer, PDO::PARAM_INT);
|
||||
$sth->bindValue(':ecat', $ecat, PDO::PARAM_INT);
|
||||
$sth->bindValue(':remarks', $remarks, PDO::PARAM_STR);
|
||||
try {
|
||||
$sth->execute();
|
||||
} catch (PDOException $e) {
|
||||
$g_error->Add('SQL-Error: '. $e->getMessage());
|
||||
}
|
||||
$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;
|
||||
}
|
||||
unset($_SESSION['token']);
|
||||
$sth = $pdo->prepare("DELETE FROM docref WHERE reftype='equipment' AND refid=?");
|
||||
try {
|
||||
$sth->execute([$id]);
|
||||
} catch (PDOException $e) {
|
||||
$g_error->Add('SQL-Error: '. $e->getMessage());
|
||||
}
|
||||
$refcount = $sth->rowCount();
|
||||
$sth = $pdo->prepare("DELETE FROM equipment WHERE eid=?");
|
||||
try {
|
||||
$sth->execute([$id]);
|
||||
} catch (PDOException $e) {
|
||||
$g_error->Add('SQL-Error: '. $e->getMessage());
|
||||
}
|
||||
$g_message->Add(sprintf(_('Deleted equipment no. %d'), $id));
|
||||
if ($refcount > 0) {
|
||||
$g_message->Add(sprintf(_('%d document links were removed'), $refcount));
|
||||
}
|
||||
$action = ACT_DEFAULT;
|
||||
break;
|
||||
|
||||
case 'upload':
|
||||
$action = ACT_VIEW;
|
||||
if (!isset($_FILES['files'])) {
|
||||
$g_warning->Add(_('No files for upload submitted'));
|
||||
break;
|
||||
}
|
||||
$extensions = ['jpg', 'png'];
|
||||
$mimetypes = ['image/png', 'image/jpeg', 'image/svg+xml', 'application/pdf'];
|
||||
$all_files = count($_FILES ["files"]["tmp_name"]);
|
||||
$nerr = 0;
|
||||
for ($i = 0; $i < $all_files; $i++) {
|
||||
$file_name = $_FILES['files']['name'][$i];
|
||||
$file_tmp = $_FILES['files']['tmp_name'][$i];
|
||||
$file_type = $_FILES['files']['type'][$i];
|
||||
$file_size = $_FILES['files']['size'][$i];
|
||||
$file_ext = strtolower(end(explode('.', $_FILES['files']['name'][$i])));
|
||||
// $file = $g_doc_basepath . '/' . $file_name;
|
||||
$file_mimetype = mime_content_type($file_tmp);
|
||||
if (!in_array($file_mimetype, $mimetypes)) {
|
||||
$g_error->Add(sprintf(_("Mimetype '%s' not allowed for upload."), $file_mimetype));
|
||||
$nerr += 1;
|
||||
}
|
||||
if (!in_array($file_ext, $extensions)) {
|
||||
$g_error->Add(_('Filetype not allowed for upload:') . ' ' . $file_type);
|
||||
$nerr += 1;
|
||||
}
|
||||
if ($file_size > 2097152) {
|
||||
$g_error->Add(sprintf(_('File to big: %s.%s'), $file_name, $file_type));
|
||||
$nerr += 1;
|
||||
}
|
||||
if ($nerr > 0) {
|
||||
break;
|
||||
}
|
||||
$file_hash = md5_file($file_tmp);
|
||||
$file_timestamp = date('Y-m-d H:i:s', filemtime($file_tmp));
|
||||
|
||||
// check whether the file already exists, in this case issue
|
||||
// a message and just create a link to the already known file
|
||||
$sql = "SELECT docid FROM document WHERE hash=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$file_hash]);
|
||||
$row = $sth->fetch();
|
||||
if (!$row) {
|
||||
$sql = "INSERT INTO document"
|
||||
. " (doctype, filename, extension, hash, doctime, docsize, mimetype) "
|
||||
. "VALUES"
|
||||
. " (?, ?, ?, ?, ?, ?, ?)";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute(['picture', $file_name, $file_ext, $file_hash, $file_timestamp, $file_size, $file_mimetype]);
|
||||
$docid = $pdo->lastInsertId();
|
||||
$file_techname = $g_doc_basepath . '/pic-'.$file_hash.'.'.$file_ext;
|
||||
move_uploaded_file($file_tmp, $file_techname);
|
||||
} else {
|
||||
// A document record definitely exists here, now just
|
||||
// connect it to the selected equipment
|
||||
$docid = $row['docid'];
|
||||
}
|
||||
|
||||
$sql = "INSERT INTO docref (docid, refid) VALUES (?, ?)";
|
||||
$sth = $pdo->prepare($sql);
|
||||
// Reference may already exist!
|
||||
try {
|
||||
$sth->execute([$docid, $id]);
|
||||
} catch (PDOException $e) {
|
||||
$g_error->Add('SQL-Error: '. $e->getMessage());
|
||||
}
|
||||
|
||||
} // for
|
||||
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 =======================================
|
||||
|
||||
$sql = "SELECT eid, ename, manufacturer, model, serial, remarks,"
|
||||
. " TIMESTAMPDIFF(MONTH, purchdate, NOW()) AS age_mon "
|
||||
. "FROM equipment WHERE vid=? "
|
||||
. "ORDER BY eid";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$user->vid]);
|
||||
$res = $sth->fetchAll();
|
||||
|
||||
echo "<h1>$pagetitle</h1>\n";
|
||||
|
||||
// Filter
|
||||
?>
|
||||
|
||||
<form method="post">
|
||||
<div id="filter" class="card">
|
||||
<div class="card-header">Filter</div>
|
||||
<div class="card-body">
|
||||
<label>Category</label>
|
||||
<select>
|
||||
<?php
|
||||
foreach ($opt_ecat as $k => $v) {
|
||||
echo '<option value="', $k,'">', $v, '</option>';
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<button class="btn btn-sm btn-primary" title="<?=_('Apply')?>">Go</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
// Data
|
||||
echo '<table class="table table-striped">', "\n";
|
||||
echo "<thead>\n";
|
||||
echo "<tr>";
|
||||
echo "<th>" . _('Description') . "</th>";
|
||||
echo "<th>" . _('Manufacturer') . "</th>";
|
||||
echo "<th>" . _('Model') . "</th>";
|
||||
echo "<th>" . _('Serial') . "</th>";
|
||||
echo "<th>" . _('Age') . "</th>";
|
||||
echo "<th>" . _('Remarks') . "</th>";
|
||||
echo "<th> </th>";
|
||||
echo "</tr>\n";
|
||||
echo "</thead>\n";
|
||||
foreach ($res as $row) {
|
||||
// calc nice age display
|
||||
if (!isset($row['age_mon'])) {
|
||||
$age = '';
|
||||
} elseif ($row['age_mon'] < 12) {
|
||||
$age = sprintf(_('%dm'), $row['age_mon']);
|
||||
} else {
|
||||
$age = sprintf(_('%dy'), intdiv($row['age_mon'], 12));
|
||||
}
|
||||
echo "<tr>\n";
|
||||
echo "<td>". $row['ename'] ."</td>\n";
|
||||
echo "<td>". $opt_manufacturer[$row['manufacturer']] ."</td>\n";
|
||||
echo "<td>". $row['model'] ."</td>\n";
|
||||
echo "<td>". $row['serial'] ."</td>\n";
|
||||
echo "<td>". $age ."</td>\n";
|
||||
echo "<td>". $row['remarks'] ."</td>\n";
|
||||
// Action buttons
|
||||
form_action_buttons($g_scriptname, $row['eid']);
|
||||
}
|
||||
?>
|
||||
<tfoot>
|
||||
<tr><td colspan="6"><?php printf(_('%d records'), count($res)); ?></td></tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
<nav>
|
||||
<ul class="pagination justify-content-center">
|
||||
<li class="page-item"><a class="page-link" href="#">Previous</a></li>
|
||||
<li class="page-item"><a class="page-link" href="#">1</a></li>
|
||||
<li class="page-item"><a class="page-link" href="#">2</a></li>
|
||||
<li class="page-item"><a class="page-link" href="#">Next</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<?php
|
||||
|
||||
form_add_button($g_scriptname);
|
||||
|
||||
elseif ($action == ACT_ADD):
|
||||
// ========== VARIANT: add record =============================================
|
||||
?>
|
||||
<h2><?=_('Add Equipment')?></h2>
|
||||
<form method="post">
|
||||
<div class="mb-3">
|
||||
<label for="ename" class="form-label"><?=_('Name')?></label>
|
||||
<input type="text" class="form-control" id="ename" name="ename">
|
||||
</div>
|
||||
<?php
|
||||
form_create_select('category', _('Category'), $opt_ecat);
|
||||
form_create_select('manufacturer', _('Manufacturer'), $opt_manufacturer);
|
||||
?>
|
||||
<div class="mb-3">
|
||||
<label for="model" class="form-label"><?=_('Model')?></label>
|
||||
<input type="text" class="form-control" id="model" name="model">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="remarks" class="form-label"><?=_('Remarks')?></label>
|
||||
<textarea class="form-control" id="remarks" name="remarks" rows="3"></textarea>
|
||||
</div>
|
||||
<div class="container-fluid px-0 my-3">
|
||||
<button type="submit" name="submit[insert]" class="btn btn-primary"><?=_('Save')?></button>
|
||||
<a href="<?=$g_scriptname?>" class="btn btn-secondary"><?=_('Back')?></a>
|
||||
</div>
|
||||
</form>
|
||||
<?php
|
||||
elseif ($action == ACT_VIEW):
|
||||
// ========== VARIANT: view single record =====================================
|
||||
|
||||
$sql = "SELECT eid, ename, model, serial, purchdate, price, weight, "
|
||||
. " supplier, manufacturer, ecat, remarks "
|
||||
. "FROM equipment "
|
||||
. "WHERE eid=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$id]);
|
||||
$equipment = $sth->fetch(PDO::FETCH_OBJ);
|
||||
echo "<h2>", $equipment->ename, "</h2>\n";
|
||||
|
||||
// Bootstrap grid
|
||||
echo '<div class="container">';
|
||||
echo '<div class="row">';
|
||||
echo '<div class="col">';
|
||||
|
||||
echo '<table class="table">', "\n";
|
||||
echo '<tr><th>', _('Manufacturer'),"</th><td>", $opt_manufacturer[$equipment->manufacturer], "</td></tr>\n";
|
||||
echo '<tr><th>', _('Model'),"</th><td>", $equipment->model, "</td></tr>\n";
|
||||
echo '<tr><th>', _('Serial'),"</th><td>", $equipment->serial, "</td></tr>\n";
|
||||
echo '<tr><th>', _('Weight'),"</th><td>", format_float($equipment->weight, 2, 'kg'), "</td></tr>\n";
|
||||
echo '<tr><th>', _('Price'),"</th><td>", format_currency($equipment->price), "</td></tr>\n";
|
||||
echo '<tr><th>', _('Purchase date'),"</th><td>", $equipment->purchdate, "</td></tr>\n";
|
||||
echo '<tr><th>', _('Supplier'),"</th><td>", $opt_supplier[$equipment->supplier], "</td></tr>\n";
|
||||
echo '<tr><th>', _('Category'),"</th><td>", $opt_ecat[$equipment->ecat], "</td></tr>\n";
|
||||
echo '<tr><th>', _('Remarks'),"</th><td>", $equipment->remarks, "</td></tr>\n";
|
||||
echo "</table>\n";
|
||||
|
||||
echo '</div>'; // Column break
|
||||
echo '<div class="col">';
|
||||
?>
|
||||
<p>Images and documents go here</p>
|
||||
<?php
|
||||
$sql = "SELECT d.docid, d.doctype, d.title "
|
||||
. "FROM docref AS r INNER JOIN document AS d using (docid) "
|
||||
. "WHERE r.refid=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$id]);
|
||||
$res = $sth->fetchAll();
|
||||
foreach ($res as $row) {
|
||||
if ($row['doctype'] == 'picture') {
|
||||
echo '<a href="dl.php?id=', $row['docid'], '">';
|
||||
// echo '<img width="120" src="doc/pic-', $row['hash'], '.', $row['extension'],'">';
|
||||
echo '<img width="120" src="dl.php?id=', $row['docid'], '" alt="', $row['title'], '">';
|
||||
echo "</a>\n";
|
||||
} elseif ($row['doctype'] == 'generic') {
|
||||
echo '<a href="dl.php?id=', $row['docid'], '">';
|
||||
echo $row['title'];
|
||||
echo "</a>\n";
|
||||
}
|
||||
}
|
||||
?>
|
||||
<form method="post" enctype="multipart/form-data" action="<?=$g_scriptname?>">
|
||||
<input type="hidden" name="id" value="<?=$id?>">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<input type="file" name="files[]" multiple accept="image/*" capture="camera">
|
||||
<input type="submit" name="submit[upload]" value="Upload">
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<?php
|
||||
echo '</div>'; // col
|
||||
echo '</div>'; // row
|
||||
echo '</div>'; // container
|
||||
|
||||
// Buttons at bottom of data area
|
||||
form_view_buttons($g_scriptname, $id);
|
||||
|
||||
elseif ($action == ACT_EDIT):
|
||||
// ========== VARIANT: edit single record =====================================
|
||||
|
||||
$sql = "SELECT compid, compname FROM company WHERE comptype=1 ORDER BY compname";
|
||||
$sth = $pdo->query($sql);
|
||||
$supplier = array();
|
||||
foreach ($sth->fetchAll() as $row) {
|
||||
$supplier[$row['compid']] = $row['compname'];
|
||||
}
|
||||
|
||||
$sql = "SELECT eid, ename, model, serial, weight, price, purchdate,"
|
||||
. " supplier, manufacturer, ecat, remarks "
|
||||
. "FROM equipment "
|
||||
. "WHERE eid=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$id]);
|
||||
$equipment = $sth->fetch(PDO::FETCH_OBJ);
|
||||
?>
|
||||
<h2><?=_('Edit Equipment')?></h2>
|
||||
<form method="post" action="<?=$g_scriptname?>">
|
||||
<input type="hidden" name="id" value="<?=$id?>">
|
||||
<div class="mb-3">
|
||||
<label for="ename" class="form-label"><?=_('Name')?></label>
|
||||
<input type="text" class="form-control" id="ename" name="ename" value="<?=$equipment->ename ?>">
|
||||
</div>
|
||||
<?php form_create_select('manufacturer', _('Manufacturer'), $opt_manufacturer, $equipment->manufacturer); ?>
|
||||
<div class="mb-3">
|
||||
<label for="model" class="form-label"><?=_('Model')?></label>
|
||||
<input type="text" class="form-control" id="model" name="model" value="<?=$equipment->model ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="serial" class="form-label"><?=_('Serial')?></label>
|
||||
<input type="text" class="form-control" id="serial" name="serial" value="<?=$equipment->serial ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="weight" class="form-label"><?=_('Weight, kg')?></label>
|
||||
<input type="text" class="form-control" id="weight" name="weight" value="<?=format_float($equipment->weight); ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="price" class="form-label"><?=sprintf(_('Price, %s'), $g_lconv['currency_symbol']); ?></label>
|
||||
<input type="text" class="form-control" id="price" name="price" value="<?=format_float($equipment->price) ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="purchdate"><?=_('Purchase date')?></label>
|
||||
<input type="date" class="form-control" id="startdate" name="purchdate" value="<?=$equipment->purchdate ?>">
|
||||
</div>
|
||||
<?php
|
||||
form_create_select('supplier', _('Supplier'), $opt_supplier, $equipment->supplier);
|
||||
form_create_select('category', _('Category'), $opt_ecat, $equipment->ecat);
|
||||
?>
|
||||
<div class="mb-3">
|
||||
<label for="remarks" class="form-label"><?=_('Remarks')?></label>
|
||||
<textarea class="form-control" id="remarks" name="remarks" rows="3"><?=$equipment->remarks ?></textarea>
|
||||
</div>
|
||||
<button type="submit" name="submit[update]" class="btn btn-primary"><?=_('Save')?></button>
|
||||
<a href="<?=$g_scriptname?>?f=view&id=<?=$id?>" class="btn btn-secondary"><?=_('Back')?></a>
|
||||
</form>
|
||||
<?php
|
||||
|
||||
elseif ($action == ACT_DELETE):
|
||||
// ========== VARIANT: delete record ==========================================
|
||||
|
||||
$_SESSION['token'] = bin2hex(random_bytes(8));
|
||||
$sql = "SELECT ename, remarks FROM equipment WHERE eid=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$id]);
|
||||
$equipment = $sth->fetch(PDO::FETCH_OBJ);
|
||||
|
||||
echo '<h2>', _('Delete equipment'),"</h2>\n";
|
||||
|
||||
echo '<p>', sprintf(_('Record no. %d'), $id), "</p>\n";
|
||||
echo '<p>Name: ', $equipment->ename, "</p>";
|
||||
echo '<p>Remarks: ', $equipment->remarks, "</p>";
|
||||
|
||||
echo '<p>', _('Deleting an equipment item is final. There is no way back. Only delete if you are absolute sure.'), "</p>\n";
|
||||
|
||||
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';
|
||||
@@ -0,0 +1,7 @@
|
||||
<footer class="bg-body-tertiary text-center">
|
||||
<p>Prototyp YMS v0.1</p>
|
||||
</footer>
|
||||
|
||||
</div><?php /* Main container */?>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,709 @@
|
||||
<?php
|
||||
/******************************************************************************
|
||||
* YMS - Yacht Management Software
|
||||
* Copyright (C) 2024 Thomas Hooge
|
||||
*
|
||||
* SPDX-License-Identifier: WTFPL
|
||||
******************************************************************************
|
||||
|
||||
******************
|
||||
* Edition History
|
||||
*
|
||||
* # Date Changes by
|
||||
* ------ ------------ ---------------------------------------------- -----
|
||||
* 0.1.0 2024-03-12 Started development tho
|
||||
*
|
||||
*/
|
||||
|
||||
// ========== CONSTANT DEFINITIONS ============================================
|
||||
|
||||
define ('E_NONE', 0);
|
||||
|
||||
define ('OPTIONAL', 0);
|
||||
define ('REQUIRED', 1);
|
||||
define ('ENABLED', 1);
|
||||
define ('DISABLED', 0);
|
||||
|
||||
define ('ACT_DEFAULT', 0);
|
||||
define ('ACT_ADD', 1);
|
||||
define ('ACT_VIEW', 2);
|
||||
define ('ACT_EDIT', 3);
|
||||
define ('ACT_DELETE', 4);
|
||||
define ('ACT_COPY', 5);
|
||||
define ('ACT_JOIN', 6);
|
||||
define ('ACT_LEAVE', 7);
|
||||
define ('ACT_EDIT_DETAIL', 8);
|
||||
define ('ACT_DEL_DETAIL', 9);
|
||||
define ('ACT_LINK', 10);
|
||||
define ('ACT_UNLINK', 11);
|
||||
define ('ACT_MAIL', 12);
|
||||
define ('ACT_VIEW_LIST', 13);
|
||||
|
||||
// ========== PAGE START CODE =================================================
|
||||
|
||||
$g_scriptname = basename($_SERVER['SCRIPT_NAME']);
|
||||
|
||||
require 'config.inc';
|
||||
|
||||
// Localization
|
||||
setlocale(LC_ALL, $g_locale);
|
||||
$g_lconv = localeconv();
|
||||
$g_lang = substr($g_locale, 0, 2); // short language identifier
|
||||
|
||||
bindtextdomain('yms', 'locale');
|
||||
bind_textdomain_codeset('yms', 'UTF-8');
|
||||
textdomain('yms');
|
||||
|
||||
date_default_timezone_set($g_timezone);
|
||||
|
||||
if ($g_scriptname != 'login.php') {
|
||||
session_name(APP_SESSION);
|
||||
session_start();
|
||||
if (!isset($_SESSION['userid'])) {
|
||||
$_SESSION['prelogin'] = $_SERVER['REQUEST_URI'];
|
||||
header_location('login.php');
|
||||
}
|
||||
}
|
||||
|
||||
$pdo = new PDO("mysql:host=$g_db_host;dbname=$g_db_schema;charset=utf8mb4", $g_db_username, $g_db_password);
|
||||
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
|
||||
# $pdo->query("SET lc_time_names='de_DE'");
|
||||
$sth = $pdo->query("SELECT valint FROM settings WHERE userid=0 AND sno=0");
|
||||
$g_db_scheme_version = $sth->fetchColumn();
|
||||
|
||||
$user = User::GetInstance(); // There can be only one
|
||||
if ($g_scriptname != 'login.php') {
|
||||
$user->init_from_session();
|
||||
$user->load_vessel();
|
||||
}
|
||||
|
||||
$action = NULL;
|
||||
$valid = FALSE;
|
||||
|
||||
// Initialize message system
|
||||
$g_message = new Message;
|
||||
$g_success = new MessageSuccess;
|
||||
$g_warning = new MessageWarning;
|
||||
$g_error = new MessageError;
|
||||
|
||||
// ========== MESSAGE FUNCTIONS ===============================================
|
||||
|
||||
class Message {
|
||||
|
||||
var $count = 0;
|
||||
var $text = array();
|
||||
var $caption;
|
||||
var $alertclass;
|
||||
|
||||
function __construct() {
|
||||
$this->caption = _('Information');
|
||||
$this->alertclass = 'alert-info';
|
||||
}
|
||||
|
||||
function SetCaption($str) {
|
||||
$this->caption = $str;
|
||||
}
|
||||
|
||||
function Add($msg) {
|
||||
$this->count++;
|
||||
$this->text[$this->count] = $msg;
|
||||
}
|
||||
|
||||
function GetCount() {
|
||||
return $this->count;
|
||||
}
|
||||
|
||||
function PrintOut() {
|
||||
if ($this->count > 0) {
|
||||
echo '<div class="alert ', $this->alertclass, ' alert-dismissible fade show" role="alert">', "\n";
|
||||
echo '<h4 class="alert-heading">', $this->caption, "</h4>\n";
|
||||
echo "<ul>\n";
|
||||
for ($i=1; $i<=$this->count; $i++) {
|
||||
echo "\t<li>", $this->text[$i],"</li>\n";
|
||||
}
|
||||
echo "</ul>\n";
|
||||
echo '<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>', "\n";
|
||||
echo "</div>\n";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class MessageSuccess extends Message {
|
||||
function __construct() {
|
||||
$this->caption = _('Success');
|
||||
$this->alertclass = 'alert-success';
|
||||
}
|
||||
}
|
||||
|
||||
class MessageWarning extends Message {
|
||||
function __construct() {
|
||||
$this->caption = _('Warning');
|
||||
$this->alertclass = 'alert-warning';
|
||||
}
|
||||
}
|
||||
|
||||
class MessageError extends Message {
|
||||
function __construct() {
|
||||
$this->caption = _('Error');
|
||||
$this->alertclass = 'alert-danger';
|
||||
}
|
||||
}
|
||||
|
||||
// ========== USER FUNCTIONS ==================================================
|
||||
|
||||
class User {
|
||||
|
||||
private static $instance = NULL;
|
||||
|
||||
private $loggedin;
|
||||
private $errormessage;
|
||||
|
||||
public $id;
|
||||
public $login;
|
||||
public $displayname;
|
||||
public $role;
|
||||
public $flags;
|
||||
public $vid; // current selected vessel
|
||||
public $vessel; // name of current vessel
|
||||
|
||||
private function __construct() {
|
||||
$this->loggedin = FALSE;
|
||||
$this->errormessage = NULL;
|
||||
$this->flags = [];
|
||||
$this->vid = 1;
|
||||
$this->vessel = 'Yacht';
|
||||
}
|
||||
|
||||
public static function getInstance() {
|
||||
if (self::$instance == NULL) {
|
||||
self::$instance = new User();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
function login($user_name, $user_pass) {
|
||||
global $pdo;
|
||||
if ($user_name == '' or $user_pass == '') {
|
||||
$this->loggedin = FALSE;
|
||||
$this->errormessage = _('Username or password was empty');
|
||||
return FALSE;
|
||||
}
|
||||
$sql = "SELECT userid, pass, displayname, role, flags FROM user WHERE login=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$user_name]);
|
||||
$row = $sth->fetch(PDO::FETCH_OBJ);
|
||||
$this->role = $row->role;
|
||||
$this->flags = array_filter(explode(',', $row->flags));
|
||||
if ($row->flags != 0 ) {
|
||||
// deleted or locked, intentionally not return detailed reason
|
||||
$this->errormessage = _('User account does not exist');
|
||||
} elseif (password_verify($user_pass, $row->pass)) {
|
||||
// password check successful
|
||||
$_SESSION['userid'] = $row->userid;
|
||||
$this->loggedin = TRUE;
|
||||
header_location($_SESSION['prelogin'] ?? 'index.php');
|
||||
} else {
|
||||
$this->errormessage = _('Username or password invalid');
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
function logout() {
|
||||
global $pdo;
|
||||
// remove session completely
|
||||
$_SESSION = array();
|
||||
if (ini_get("session.use_cookies")) {
|
||||
$params = session_get_cookie_params();
|
||||
setcookie(session_name(), '', time() - 42000,
|
||||
$params["path"], $params["domain"],
|
||||
$params["secure"], $params["httponly"]
|
||||
);
|
||||
}
|
||||
session_destroy();
|
||||
}
|
||||
|
||||
function init_from_session() {
|
||||
global $pdo;
|
||||
if (!isset($_SESSION['userid'])) {
|
||||
$this->loggedin = FALSE;
|
||||
$this->errormessage = _('User not logged in');
|
||||
$this->id = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
$this->id = $_SESSION['userid'];
|
||||
$sql = "SELECT displayname, role FROM user WHERE userid=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$this->id]);
|
||||
$row = $sth->fetch();
|
||||
$this->displayname = $row['displayname'];
|
||||
$this->role = $row['role'];
|
||||
//$this->displayname = $sth->fetchColumn();
|
||||
|
||||
}
|
||||
|
||||
function load_vessel() {
|
||||
global $pdo;
|
||||
$sql = "SELECT v.vid, v.vesselname "
|
||||
. "FROM settings AS s INNER JOIN vessel AS v ON s.valint=v.vid "
|
||||
. "WHERE s.userid=? and s.sno=1";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$this->id]);
|
||||
$row = $sth->fetch();
|
||||
$this->vid = $row['vid'];
|
||||
$this->vessel = $row['vesselname'];
|
||||
}
|
||||
|
||||
function get_last_error() {
|
||||
return $this->errormessage;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function get_userlist() {
|
||||
// Get list of all users for fast name lookup
|
||||
global $pdo;
|
||||
$ulist = array(-1 => ['-', 0]); // unknown
|
||||
$sql = "SELECT userid, displayname, role, flags FROM user ORDER BY displayname";
|
||||
$sth = $pdo->query($sql);
|
||||
$res = $sth->fetchAll();
|
||||
foreach ($res as $row) {
|
||||
$flags = array_filter(explode(',', $row['flags']));
|
||||
$deleted = in_array('deleted', $flags);
|
||||
$locked = in_array('locked', $flags);
|
||||
$ulist[$row['userid']] = [$row['displayname'], $deleted, $locked];
|
||||
}
|
||||
return $ulist;
|
||||
}
|
||||
|
||||
// ========== DATABASE FUNCTIONS ==============================================
|
||||
|
||||
function db_load_enum($table, $column) {
|
||||
// returns array of enum-values as defined in database
|
||||
global $pdo;
|
||||
$sql = "SELECT TRIM(TRAILING ')' FROM SUBSTRING(column_type,6)) "
|
||||
. "FROM information_schema.columns "
|
||||
. "WHERE table_name=? AND column_name=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$table, $column]);
|
||||
// for PHP < 7.4
|
||||
// return array_map(function($x) { return trim($x, "'"); }, explode(',', $sth->fetchColumn()));
|
||||
// for PHP => 7.4
|
||||
return array_map(fn($x) => trim($x, "'"), explode(',', $sth->fetchColumn()));
|
||||
}
|
||||
|
||||
function db_get_ddtext($ddid, $ddval) {
|
||||
// returns single value for dropdown
|
||||
global $pdo;
|
||||
global $g_error;
|
||||
$sql = "SELECT ddtext FROM dropdown WHERE ddid=? AND ddval=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
try {
|
||||
$sth->execute([$ddid, $ddval]);
|
||||
} catch(PDOException $e) {
|
||||
$g_error->Add($e->getMessage());
|
||||
return '#err';
|
||||
}
|
||||
return $sth->fetchColumn();
|
||||
}
|
||||
|
||||
function db_get_options($ddid, $orderby = '', $default = NULL) {
|
||||
// returns list for dropdown
|
||||
global $pdo;
|
||||
$list = array();
|
||||
if ($default != NULL) {
|
||||
$list[0] = $default;
|
||||
}
|
||||
$sql = "SELECT ddval, ddtext FROM dropdown WHERE ddid=?";
|
||||
if ($orderby == 'ddtext') {
|
||||
$sql .= ' ORDER BY ddtext';
|
||||
} elseif ($orderby == 'sort') {
|
||||
$sql .= ' ORDER BY sort';
|
||||
} else {
|
||||
$sql .= ' ORDER BY ddval';
|
||||
}
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$ddid]);
|
||||
foreach ($sth->fetchAll(PDO::FETCH_NUM) as $rec) {
|
||||
$list[$rec[0]] = $rec[1];
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
function db_get_opt_vessel() {
|
||||
global $pdo;
|
||||
$list = array();
|
||||
$sth = $pdo->query("SELECT vid, vesselname, model FROM vessel ORDER BY vid");
|
||||
foreach ($sth->fetchAll(PDO::FETCH_NUM) as $row) {
|
||||
$list[$rec[0]] = $rec[1];
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
// Functions to get option lists (key/value)
|
||||
|
||||
function db_get_opt_storage($vid) {
|
||||
global $pdo;
|
||||
global $g_error;
|
||||
$list = array();
|
||||
$sql = "SELECT sid, sname FROM storage WHERE vid=? ORDER BY sname";
|
||||
$sth = $pdo->prepare($sql);
|
||||
try {
|
||||
$sth->execute([$vid]);
|
||||
} catch(PDOException $e) {
|
||||
$g_error->Add($e->getMessage());
|
||||
}
|
||||
foreach ($sth->fetchAll(PDO::FETCH_NUM) as $rec) {
|
||||
$list[$rec[0]] = $rec[1];
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
function db_get_opt_box($vid) {
|
||||
global $pdo;
|
||||
global $g_error;
|
||||
$list = array();
|
||||
$sql = "SELECT boxid, label, content "
|
||||
. "FROM box INNER JOIN storage USING (sid) "
|
||||
. "WHERE vid=? "
|
||||
. "ORDER BY label";
|
||||
$sth = $pdo->prepare($sql);
|
||||
try {
|
||||
$sth->execute([$vid]);
|
||||
} catch(PDOException $e) {
|
||||
$g_error->Add($e->getMessage());
|
||||
}
|
||||
foreach ($sth->fetchAll(PDO::FETCH_NUM) as $rec) {
|
||||
$list[$rec[0]] = $rec[1] . ' - '. $rec[2];
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
function db_get_opt_equip($vid) {
|
||||
}
|
||||
|
||||
function db_get_opt_manuf($default=NULL) {
|
||||
global $pdo;
|
||||
if (isset($default)) {
|
||||
$list = $default;
|
||||
} else {
|
||||
$list = array();
|
||||
}
|
||||
$sql = "SELECT compid, compname FROM company WHERE comptype=2 ORDER BY compname";
|
||||
$sth = $pdo->query($sql);
|
||||
foreach ($sth->fetchAll(PDO::FETCH_NUM) as $row) {
|
||||
$list[$row[0]] = $row[1];
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
function db_get_opt_supp($default=NULL) {
|
||||
global $pdo;
|
||||
if (isset($default)) {
|
||||
$list = $default;
|
||||
} else {
|
||||
$list = array();
|
||||
}
|
||||
$sql = "SELECT compid, compname FROM company WHERE comptype=1 ORDER BY compname";
|
||||
$sth = $pdo->query($sql);
|
||||
foreach ($sth->fetchAll(PDO::FETCH_NUM) as $row) {
|
||||
$list[$row[0]] = $row[1];
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
function db_get_opt_proj($vid, $default=NULL) {
|
||||
global $pdo;
|
||||
global $g_error;
|
||||
if (isset($default)) {
|
||||
$list = $default;
|
||||
} else {
|
||||
$list = array();
|
||||
}
|
||||
$sql = "SELECT projid, projname FROM project WHERE vid=? ORDER BY projname";
|
||||
$sth = $pdo->prepare($sql);
|
||||
try {
|
||||
$sth->execute([$vid]);
|
||||
} catch(PDOException $e) {
|
||||
$g_error->Add($e->getMessage());
|
||||
}
|
||||
foreach ($sth->fetchAll(PDO::FETCH_NUM) as $rec) {
|
||||
$list[$rec[0]] = $rec[1];
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
function date_to_sql($var) {
|
||||
if (!isset($var) || $var == '') {
|
||||
return NULL;
|
||||
} else {
|
||||
list($d, $m, $y) = explode('.', $var);
|
||||
return sprintf("%04d-%02d-%02d", $y, $m, $d);
|
||||
}
|
||||
}
|
||||
|
||||
function float_to_sql($var) {
|
||||
global $g_lconv;
|
||||
if (!isset($var) || $var == '') {
|
||||
return NULL;
|
||||
} else {
|
||||
// remove thousands separator
|
||||
$var = str_replace($g_lconv['thousands_sep'], '', $var);
|
||||
// force decimal point
|
||||
if ($g_lconv['decimal_point'] != '.') {
|
||||
$var = str_replace($g_lconv['decimal_point'], '.', $var);
|
||||
}
|
||||
return $var;
|
||||
}
|
||||
}
|
||||
|
||||
// ========== FORM FUNCTIONS ==================================================
|
||||
|
||||
function form_create_select($fieldname, $label, $optlist, $selval=NULL) {
|
||||
//if (
|
||||
echo '<div class="mb-3">', "\n";
|
||||
echo '<label for="', $fieldname, '">', $label, "</label>\n";
|
||||
echo '<select class="form-select" name="', $fieldname,'" id="', $fieldname,'">';
|
||||
foreach ($optlist as $k => $v) {
|
||||
echo '<option value="', $k, '"';
|
||||
if (isset($selval) and ($k == $selval)) {
|
||||
echo ' selected';
|
||||
}
|
||||
echo '>', $v, "</option>\n";
|
||||
}
|
||||
echo "</select>\n";
|
||||
echo "</div>\n";
|
||||
}
|
||||
|
||||
function form_action_buttons($script, $id) {
|
||||
echo "<td>";
|
||||
echo '<a title="', _('View'), '" href="', $script, '?f=view&id=', $id, '"><i class="bi-eye"></i></a>', "\n";
|
||||
echo '<a title="', _('Edit'), '" href="', $script, '?f=edit&id=', $id, '"><i class="bi-pencil"></i></a>', "\n";
|
||||
echo "</td>\n";
|
||||
}
|
||||
|
||||
function form_add_button($script, $id=NULL, $idname='id') {
|
||||
echo '<div class="container-fluid px-0 my-3">', "\n";
|
||||
echo '<a href="', $script, '?f=add';
|
||||
if (isset($id)) {
|
||||
echo '&'.$idname.'='.$id;
|
||||
}
|
||||
echo '" class="btn btn-primary" role="button">', _('Add'), "</a>\n";
|
||||
echo "</div>\n";
|
||||
}
|
||||
|
||||
function form_view_buttons($script, $id) {
|
||||
echo '<div class="container-fluid px-0 my-3">', "\n";
|
||||
echo '<a href="', $script, '?f=edit&id=', $id, '" class="btn btn-primary" role="button">', _('Edit'), "</a>\n";
|
||||
echo ' ';
|
||||
echo '<a href="', $script, '?f=del&id=', $id, '" class="btn btn-secondary" role="button">', _('Delete'), "</a>\n";
|
||||
echo ' ';
|
||||
echo '<a href="', $script, '" class="btn btn-secondary">', _('Back'), "</a>\n";
|
||||
echo "</div>\n";
|
||||
}
|
||||
|
||||
function form_edit_buttons($script, $id) {
|
||||
echo '<div class="container-fluid px-0 my-3">', "\n";
|
||||
echo '<button type="submit" name="submit[update]" class="btn btn-primary">', _('Save'), "</button>\n";
|
||||
echo '<a href="', $script, '?f=view&id=', $id, '" class="btn btn-secondary">', _('Back'), "</a>\n";
|
||||
echo "</div>\n";
|
||||
}
|
||||
|
||||
function form_delete_buttons($script, $id, $token) {
|
||||
echo '<div class="container-fluid px-0 my-3">', "\n";
|
||||
echo '<form method="post" action="', $script, '">', "\n";
|
||||
echo '<input type="hidden" name="id" value="', $id .'">', "\n";
|
||||
echo '<input type="hidden" name="token" value="', $token, '">', "\n";
|
||||
echo '<button type="submit" name="submit[delete]" class="btn btn-primary">', _('Delete'), "</button>\n";
|
||||
echo '<a href="', $script, '?f=view&id=', $id, '" class="btn btn-secondary">', _('Back'), "</a>\n";
|
||||
echo "</div>\n";
|
||||
echo "</form>\n";
|
||||
}
|
||||
|
||||
// ========== COMMON FUNCTIONS ================================================
|
||||
|
||||
function header_location($location) {
|
||||
header("Location: $location");
|
||||
exit;
|
||||
}
|
||||
|
||||
function form_get_action() {
|
||||
if (!isset($_POST['submit'])) {
|
||||
if (isset($_GET['f'])) {
|
||||
$submit = $_GET['f'];
|
||||
// strip parameters
|
||||
/* $pos = strpos($submit, '?');
|
||||
if ($pos > 2) {
|
||||
$submit = substr($submit, 0, $pos);
|
||||
} */
|
||||
} else {
|
||||
$submit = NULL;
|
||||
}
|
||||
} else {
|
||||
$submit = $_POST['submit'];
|
||||
}
|
||||
if (is_array($submit)) {
|
||||
$submit = key($submit);
|
||||
}
|
||||
return strtolower($submit);
|
||||
}
|
||||
|
||||
function get_color_brightness($color) {
|
||||
// returns a value between 0 and 1
|
||||
// color is a 6 char hex string
|
||||
list($red, $green, $blue) = array_map('hexdec', str_split($color, 2));
|
||||
$red = $red / 255 * 0.2126;
|
||||
$green = $green / 255 * 0.7152;
|
||||
$blue = $blue / 255 * 0.0722;
|
||||
return $red + $green + $blue;
|
||||
}
|
||||
|
||||
function gpc_get_string(&$GPC, $varname, $maxlen = NULL, $default = NULL) {
|
||||
if (!isset($GPC[$varname]) or (strlen(trim($GPC[$varname])) == 0)) {
|
||||
return $default;
|
||||
}
|
||||
$s = trim($GPC[$varname]);
|
||||
if (isset($maxlen)) {
|
||||
return substr($s, 0, $maxlen);
|
||||
}
|
||||
return $s;
|
||||
}
|
||||
|
||||
function gpc_get_int(&$GPC, $varname, $default = NULL) {
|
||||
if (!isset($GPC[$varname])) {
|
||||
return $default;
|
||||
}
|
||||
return (int)$GPC[$varname];
|
||||
}
|
||||
|
||||
function gpc_get_float(&$GPC, $varname, $default = NULL) {
|
||||
global $g_lconv;
|
||||
if (!isset($GPC[$varname]) or (strlen(trim($GPC[$varname])) == 0)) {
|
||||
return $default;
|
||||
}
|
||||
$var = str_replace($g_lconv['thousands_sep'], '', $GPC[$varname]);
|
||||
if ($g_lconv['decimal_point'] != '.') {
|
||||
$var = str_replace($g_lconv['decimal_point'], '.', $var);
|
||||
}
|
||||
return (double)$var;
|
||||
}
|
||||
|
||||
function gpc_get_currency(&$GPC, $varname, $default = NULL) {
|
||||
global $g_lconv;
|
||||
if (!isset($GPC[$varname]) or (strlen(trim($GPC[$varname])) == 0)) {
|
||||
return $default;
|
||||
}
|
||||
$var = str_replace($g_lconv['thousands_sep'], '', $GPC[$varname]);
|
||||
if ($g_lconv['decimal_point'] != '.') {
|
||||
$var = str_replace($g_lconv['decimal_point'], '.', $var);
|
||||
}
|
||||
return (double)$var;
|
||||
}
|
||||
|
||||
function gpc_get_bool(&$GPC, $varname, $default = FALSE) {
|
||||
if (!isset($GPC[$varname])) {
|
||||
return $default;
|
||||
}
|
||||
$gpcvar = trim($GPC[$varname]);
|
||||
if (strcasecmp('off', $gpcvar) == 0 ||
|
||||
strcasecmp('no', $gpcvar) == 0 ||
|
||||
strcasecmp('false', $gpcvar) == 0 ||
|
||||
strcasecmp('no', $gpcvar) == 0 ||
|
||||
strcasecmp('0', $gpcvar) == 0 ||
|
||||
strcasecmp('nein', $gpcvar) == 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
function gpc_get_date(&$GPC, $varname, $default = NULL) {
|
||||
if (!isset($GPC[$varname]) || $GPC[$varname] == '') {
|
||||
return $default;
|
||||
}
|
||||
return $GPC[$varname];
|
||||
}
|
||||
|
||||
function gpc_get_color(&$GPC, $varname, $default = NULL) {
|
||||
if (!isset($GPC[$varname]) or (strlen(trim($GPC[$varname])) == 0)) {
|
||||
return $default;
|
||||
}
|
||||
$color = $GPC[$varname];
|
||||
if ((strlen($color) == 7) and (substr($color, 0, 1) == '#')) {
|
||||
$color = substr($color, 1);
|
||||
}
|
||||
if ((strlen($color) != 6) or (! ctype_xdigit($color))) {
|
||||
return $default;
|
||||
}
|
||||
return strtoupper($color);
|
||||
}
|
||||
|
||||
function format_float($val, $decimals = 2, $suffix = '') {
|
||||
global $g_lconv;
|
||||
if (!isset($val) || $val == '') {
|
||||
return '';
|
||||
}
|
||||
return number_format($val, $decimals, $g_lconv['decimal_point'], $g_lconv['thousands_sep']) . ($suffix ? " $suffix" : '');
|
||||
}
|
||||
|
||||
function format_currency($val) {
|
||||
global $g_lconv;
|
||||
if (!isset($val) || $val == '') {
|
||||
return '';
|
||||
}
|
||||
if ($g_lconv['currency_symbol'] == '$') {
|
||||
return '$'.number_format($val, 2, $g_lconv['decimal_point'], $g_lconv['thousands_sep']);
|
||||
} else {
|
||||
return number_format($val, 2, $g_lconv['decimal_point'], $g_lconv['thousands_sep']) . ' ' . $g_lconv['currency_symbol'];
|
||||
}
|
||||
}
|
||||
|
||||
function format_filesize($size, $format=2) {
|
||||
switch ($format) {
|
||||
case 1: // short
|
||||
if ($size < 1024) {
|
||||
$size_string = sprintf(_('%d&tinysp;B'), $size);
|
||||
} elseif ($size < 1048576) {
|
||||
$size_string = sprintf(_('%.1f&tinysp;kB'), $size/1024);
|
||||
} else {
|
||||
$size_string = sprintf(_('%.1f&tinysp;MB'), $size/1048576);
|
||||
}
|
||||
break;
|
||||
case 2: // medium
|
||||
if ($size < 1024) {
|
||||
$size_string = sprintf(_('%d&tinysp;Byte'), $size);
|
||||
} elseif ($size < 1048576) {
|
||||
$size_string = sprintf(_('%.1f&tinysp;kByte'), $size/1024);
|
||||
} else {
|
||||
$size_string = sprintf(_('%.1f&tinysp;MByte'), $size/1048576);
|
||||
}
|
||||
break;
|
||||
case 3: // long
|
||||
if ($size < 1024) {
|
||||
$size_string = sprintf(_('%d Byte'), $size);
|
||||
} elseif ($size < 1048576) {
|
||||
$size_string = sprintf(_('approx. %.1f kByte'), $size/1024);
|
||||
} else {
|
||||
$size_string = sprintf(_('approx. %.1f MByte'), $size/1048576);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$size_string = trim($size);
|
||||
}
|
||||
return $size_string;
|
||||
}
|
||||
|
||||
// ========== MENU FUNCTIONS ==================================================
|
||||
|
||||
$g_menu = Array (
|
||||
'equipment.php' => [_('Equipment')],
|
||||
'inventory.php' => [_('Inventory')],
|
||||
'provisions.php' => [_('Provisions')],
|
||||
'maintenance.php' => [_('Maintenance')],
|
||||
'projects.php' => [_('Projects')],
|
||||
'documents.php' => [_('Documents')],
|
||||
'manual.php' => ['<i class="bi-book"></i>'],
|
||||
'logout.php' => ['<i class="bi-door-open"></i>']
|
||||
);
|
||||
@@ -0,0 +1,44 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="<?=$g_lang?>">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="robots" content="noindex,nofollow">
|
||||
<title><?=APP_TITLE_SHORT?> - <?=$pagetitle?></title>
|
||||
<link href="bootstrap/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="bootstrap/bootstrap-icons.min.css" rel="stylesheet">
|
||||
<script src="bootstrap/js/bootstrap.bundle.min.js"></script>
|
||||
<link rel="stylesheet" href="default.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container-xxl">
|
||||
|
||||
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="index.php"><?php echo $user->vessel ?? _('Ghost'); ?></a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||
<ul class="navbar-nav">
|
||||
<?php
|
||||
foreach ($g_menu as $key => $value) {
|
||||
echo str_repeat(' ', 4);
|
||||
echo '<li class="nav-item">';
|
||||
$active = ($g_scriptname == $key) ? ' active' : '';
|
||||
echo '<a class="nav-link', $active,'" href="', $key, '">', $value[0], "</a>";
|
||||
echo "</li>\n";
|
||||
}
|
||||
?>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<?php
|
||||
// ========== SYSTEM FEEDBACK =================================================
|
||||
|
||||
$g_error->PrintOut();
|
||||
$g_warning->PrintOut();
|
||||
$g_message->PrintOut();
|
||||
$g_success->PrintOut();
|
||||
@@ -0,0 +1,392 @@
|
||||
<?php
|
||||
/******************************************************************************
|
||||
* YMS - Yacht Management Software
|
||||
* Copyright (C) 2024 Thomas Hooge
|
||||
*
|
||||
* SPDX-License-Identifier: WTFPL
|
||||
******************************************************************************/
|
||||
|
||||
require 'globals.inc';
|
||||
$pagetitle = _('Start');
|
||||
|
||||
// ========== ACTIONS START ===================================================
|
||||
|
||||
switch ($submit = form_get_action()) {
|
||||
|
||||
case NULL: break;
|
||||
|
||||
case 'add': $action = ACT_ADD; break;
|
||||
case 'view': $action = ACT_DEFAULT; break;
|
||||
case 'edit': $action = ACT_EDIT; break;
|
||||
|
||||
case 'select':
|
||||
$vid = gpc_get_int($_POST, 'vid', 1);
|
||||
$sql = "UPDATE settings SET valint=? WHERE userid=? AND sno=1";
|
||||
$sth = $pdo->prepare($sql);
|
||||
try {
|
||||
$sth->execute([$vid, $user->id]);
|
||||
} catch (PDOException $e) {
|
||||
$g_error->Add('SQL-Error: '. $e->getMessage());
|
||||
}
|
||||
$g_message->Add(sprintf(_('Selected vessel %d'), $vid));
|
||||
$user->load_vessel();
|
||||
break;
|
||||
|
||||
case 'insert':
|
||||
$action = ACT_DEFAULT;
|
||||
if ($user->role != 'captain') {
|
||||
$g_error->Add(_('Access denied. You are not the captain.'));
|
||||
break;
|
||||
}
|
||||
$p[':vesselname'] = gpc_get_string($_POST, 'vesselname');
|
||||
$p[':model'] = gpc_get_string($_POST, 'model');
|
||||
$p[':remarks'] = gpc_get_string($_POST, 'remarks', 150);
|
||||
$keys = array_keys($p);
|
||||
$fields = join(',', array_map(function($s) { return ltrim($s, ':'); }, $keys));
|
||||
$pnames = join(',', $keys);
|
||||
$sth = $pdo->prepare("INSERT INTO vessel ($fields) VALUES ($pnames)");
|
||||
try {
|
||||
$sth->execute($p);
|
||||
} catch (PDOException $e) {
|
||||
$g_error->Add('SQL-Error: '. $e->getMessage());
|
||||
}
|
||||
$id = $pdo->LastInsertId();
|
||||
// autoselect newly created vessel
|
||||
$sql = "UPDATE settings SET valint=? WHERE userid=? AND sno=1";
|
||||
$sth = $pdo->prepare($sql);
|
||||
try {
|
||||
$sth->execute([$id, $user->id]);
|
||||
} catch (PDOException $e) {
|
||||
$g_error->Add('SQL-Error: '. $e->getMessage());
|
||||
}
|
||||
$g_message->Add(sprintf(_('Selected new vessel %d'), $vid));
|
||||
$user->load_vessel();
|
||||
break;
|
||||
|
||||
case 'update':
|
||||
if ($user->role != 'captain') {
|
||||
$g_error->Add(_('Access denied. You are not the captain.'));
|
||||
break;
|
||||
}
|
||||
// $p[':vtype'] = gpc_get_string($_POST, 'vtype');
|
||||
$p[':vesselname'] = gpc_get_string($_POST, 'vesselname');
|
||||
$p[':model'] = gpc_get_string($_POST, 'model');
|
||||
$p[':loa'] = gpc_get_float($_POST, 'loa');
|
||||
$p[':lwl'] = gpc_get_float($_POST, 'lwl');
|
||||
$p[':beam'] = gpc_get_float($_POST, 'beam');
|
||||
$p[':draught'] = gpc_get_float($_POST, 'draught');
|
||||
$p[':draught_min'] = gpc_get_float($_POST, 'draught_min');
|
||||
$p[':displacement'] = gpc_get_int($_POST, 'displacement');
|
||||
$p[':ballast'] = gpc_get_int($_POST, 'ballast');
|
||||
$p[':remarks'] = gpc_get_string($_POST, 'remarks', 150);
|
||||
$fields = join(',', array_map(function($s) { return ltrim($s, ':') . '=' . $s; }, array_keys($p)));
|
||||
$sth = $pdo->prepare("UPDATE vessel SET $fields WHERE vid=:vid");
|
||||
$p[':vid'] = gpc_get_int($_POST, 'id');
|
||||
try {
|
||||
$sth->execute($p);
|
||||
} catch (PDOException $e) {
|
||||
$g_error->Add('SQL-Error: '. $e->getMessage());
|
||||
}
|
||||
$action = ACT_DEFAULT;
|
||||
break;
|
||||
|
||||
default:
|
||||
$g_error->Add(_('Unknown function!'));
|
||||
$valid = FALSE;
|
||||
|
||||
}
|
||||
|
||||
// ========== ACTIONS END =====================================================
|
||||
|
||||
require 'header.php';
|
||||
|
||||
// ========== PAGE CONTENT ====================================================
|
||||
|
||||
if ($action == ACT_DEFAULT):
|
||||
// ========== VARIANT: default behavior =======================================
|
||||
|
||||
|
||||
echo '<h1>', _('Yacht data'), "</h1>\n";
|
||||
|
||||
echo '<p>', _('User'), ': ', $user->displayname, ' (', $user->role, ')', "</p>\n";
|
||||
|
||||
// Fetch current selected vessel number
|
||||
$sql = "SELECT valint FROM settings WHERE userid=? AND sno=1";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$user->id]);
|
||||
$res = $sth->fetch(PDO::FETCH_NUM);
|
||||
$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" 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
|
||||
$sql = "SELECT vesselname, model, loa, lwl, beam, draught, draught_min,"
|
||||
. " displacement, ballast, remarks "
|
||||
. "FROM vessel "
|
||||
. "WHERE vid=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$vid]);
|
||||
$vessel = $sth->fetch();
|
||||
|
||||
?>
|
||||
|
||||
<?php /* <svg viewbox="0 0 1024 768">
|
||||
<circle cx="50" cy="50" r="40" stroke="green" stroke-width="4" fill="yellow" />
|
||||
<rect x="0" y="0" width="1024" height="768" stroke="black" fill="none" />
|
||||
<text x="0" y="20" font-size="12" fill="#ccc" text-anchor="start">Elizabethan 29</text>
|
||||
<line x1="0" y1="0" x2="100" y2="100" />
|
||||
</svg> */ ?>
|
||||
<br>
|
||||
<svg
|
||||
width="680.8349"
|
||||
height="205.42085"
|
||||
viewBox="0 0 180.13756 54.350934"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<g
|
||||
id="layer1"
|
||||
transform="translate(-18.454117,-34.670903)">
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 18.719809,61.846371 18.587517,51.734929 c 0,0 14.698452,-6.829606 22.491781,-8.894215 18.280597,-4.842895 36.646466,-7.606499 56.167649,-7.993756 29.649633,-0.588182 48.780143,4.813228 71.891193,12.372959 10.39946,3.401709 29.38622,14.626454 29.38622,14.626454"
|
||||
id="path245" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
xlink:href="#path245"
|
||||
id="use461"
|
||||
transform="matrix(1,0,0,-1,-4.9118388e-8,123.69274)" />
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row my-4">
|
||||
<div class="col">
|
||||
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title"><?=_('Boat data') ?></h5>
|
||||
<table class="table table-sm">
|
||||
<tr><td><?=_('Loa')?></td><td><?=format_float($vessel['loa'], 2, 'm')?></td></tr>
|
||||
<tr><td><?=_('Lwl')?></td><td><?=format_float($vessel['lwl'], 2, 'm')?></td></tr>
|
||||
<tr><td><?=_('Beam')?></td><td><?=format_float($vessel['beam'], 2, 'm')?></td></tr>
|
||||
<tr><td><?=_('Draught')?></td><td><?=format_float($vessel['draught'], 2, 'm')?></td></tr>
|
||||
<tr><td><?=_('Draught, min.')?></td><td><?=format_float($vessel['draught_min'], 2, 'm')?></td></tr>
|
||||
<tr><td><?=_('Displacement')?></td><td><?=$vessel['displacement']?> kg</td></tr>
|
||||
<tr><td><?=_('Ballast')?></td><td><?=$vessel['ballast']?> kg</td></tr>
|
||||
</table>
|
||||
<?php
|
||||
// Edit vessel only for captain
|
||||
if ($user->role == 'captain') {
|
||||
echo '<a href="', $script, '?f=edit&id=', $user->vid, '" class="btn btn-primary" role="button">', _('Edit'), "</a>\n";
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div><?php /* card */ ?>
|
||||
|
||||
</div>
|
||||
<div class="col">
|
||||
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title"><?=_('Statistics') ?></h5>
|
||||
<?php
|
||||
// Statistics
|
||||
|
||||
// Storage: 0 - default, 1 - tank
|
||||
$stype = [ 0 => _('Default'), 1 => _('Tank')];
|
||||
$sql = "SELECT stype, COUNT(stype) "
|
||||
. "FROM storage "
|
||||
. "WHERE vid=? "
|
||||
. "GROUP BY stype "
|
||||
. "ORDER BY stype";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$vid]);
|
||||
$res = $sth->fetchAll(PDO::FETCH_NUM);
|
||||
echo '<table class="table table-sm">', "\n";
|
||||
echo '<tr><td colspan="2">', _('Storage type') , "</td>";
|
||||
foreach ($res as $row) {
|
||||
echo "<tr><td>", $stype[$row[0]], "</td><td>", $row[1], "</td></tr>\n";
|
||||
}
|
||||
|
||||
// Boxes
|
||||
$sth = $pdo->prepare("SELECT COUNT(*) FROM box INNER JOIN storage USING (sid) WHERE vid=?");
|
||||
$sth->execute([$user->vid]);
|
||||
echo '<tr><td>', _('Boxes'), '</td><td>', $sth->fetchColumn(), "</td></tr>\n";
|
||||
|
||||
// Equipment
|
||||
$sth = $pdo->prepare("SELECT COUNT(*) FROM equipment WHERE vid=?");
|
||||
$sth->execute([$user->vid]);
|
||||
echo '<tr><td colspan="2">', _('Equipment') , "</td>";
|
||||
echo '<tr><td>', _('Count'), '</td><td>', $sth->fetchColumn(), "</td></tr>\n";
|
||||
|
||||
// Inventory
|
||||
// All items from vessel storage and all items from boxes in vessel storage
|
||||
$sql = "SELECT SUM(n) FROM ("
|
||||
. "SELECT COUNT(*) AS n FROM inventory JOIN storage USING (sid) WHERE boxtype='storage' AND vid=:vid "
|
||||
. "UNION "
|
||||
. "SELECT COUNT(*) AS n FROM inventory JOIN box USING (boxid) JOIN storage ON (box.sid=storage.sid) WHERE boxtype='box' AND vid=:vid"
|
||||
. ") AS x";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->bindValue(':vid', $user->vid, PDO::PARAM_INT);
|
||||
$sth->execute();
|
||||
|
||||
// Tasks
|
||||
echo '<tr><td colspan="2">', _('Inventory') , "</td>";
|
||||
echo '<tr><td>', _('Count'), '</td><td>', $sth->fetchColumn(), "</td></tr>\n";
|
||||
|
||||
|
||||
echo "</table>\n";
|
||||
|
||||
?>
|
||||
</div>
|
||||
</div><?php /* card */ ?>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="col">
|
||||
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title"><?=_('Base data')?></h5>
|
||||
<ul class="list-group list-group-flush">
|
||||
<li class="list-group-item"><a href="dropdown.php"><?=_('Selection lists')?></a></li>
|
||||
<li class="list-group-item"><a href="storage.php"><?=_('Storage')?></a></li>
|
||||
<li class="list-group-item"><a href="company.php"><?=_('Companies')?></a></li>
|
||||
</ul>
|
||||
<hr>
|
||||
<h5 class="card-title"><?=_('Additional modules')?></h5>
|
||||
<ul class="list-group list-group-flush">
|
||||
<li class="list-group-item"><a href="measurement.php"><?=_('Measurements')?></a></li>
|
||||
<li class="list-group-item"><a href="checklist.php"><?=_('Checklists')?></a></li>
|
||||
<li class="list-group-item"><a href="search.php"><?=_('Search')?></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div><?php /* col */ ?>
|
||||
</div><?php /* row */ ?>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
|
||||
elseif ($action == ACT_ADD):
|
||||
// ========== VARIANT: add record =============================================
|
||||
|
||||
echo '<h2>', _('Add additional yacht'), "</h2>\n";
|
||||
|
||||
?>
|
||||
<form method="post">
|
||||
<div class="mb-3">
|
||||
<label for="vesselname" class="form-label"><?=_('Name')?></label>
|
||||
<input type="text" class="form-control" id="vesselname" name="vesselname" required autofocus>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="model" class="form-label"><?=_('Model')?></label>
|
||||
<input type="text" class="form-control" id="model" name="model">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="remarks" class="form-label"><?=_('Remarks')?></label>
|
||||
<textarea class="form-control" id="remarks" name="remarks" rows="3"><?=$project->remarks ?></textarea>
|
||||
</div>
|
||||
<div class="container-fluid px-0 my-3">
|
||||
<button type="submit" name="submit[insert]" class="btn btn-primary"><?=_('Save')?></button>
|
||||
<a href="<?=$g_scriptname?>" class="btn btn-secondary"><?=_('Back')?></a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
|
||||
elseif ($action == ACT_EDIT):
|
||||
// ========== VARIANT: edit single record =====================================
|
||||
|
||||
$sql = "SELECT vesselname, vtype, model, loa, lwl, beam, draught, draught_min,"
|
||||
. " displacement, ballast, remarks "
|
||||
. "FROM vessel "
|
||||
. "WHERE vid=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$user->vid]);
|
||||
$vessel = $sth->fetch(PDO::FETCH_OBJ);
|
||||
?>
|
||||
<h2><?=_('Edit Yacht')?></h2>
|
||||
<form method="post" action="<?=$g_scriptname?>">
|
||||
<input type="hidden" name="id" value="<?=$user->vid?>">
|
||||
<div class="mb-3">
|
||||
<label for="vesselname" class="form-label"><?=_('Vesselname')?></label>
|
||||
<input type="text" class="form-control" id="vesselname" name="vesselname" value="<?=$vessel->vesselname ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="model" class="form-label"><?=_('Model')?></label>
|
||||
<input type="text" class="form-control" id="model" name="model" value="<?=$vessel->model ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="loa" class="form-label"><?=_('LoA')?></label>
|
||||
<input type="text" class="form-control" id="loa" name="loa" value="<?=format_float($vessel->loa, 2) ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="lwl" class="form-label"><?=_('LwL')?></label>
|
||||
<input type="text" class="form-control" id="lwl" name="lwl" value="<?=format_float($vessel->lwl, 2) ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="beam" class="form-label"><?=_('Beam')?></label>
|
||||
<input type="text" class="form-control" id="beam" name="beam" value="<?=format_float($vessel->beam, 2) ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="draught" class="form-label"><?=_('Draught')?></label>
|
||||
<input type="text" class="form-control" id="draught" name="draught" value="<?=format_float($vessel->draught, 2) ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="draught_min" class="form-label"><?=_('Draught, min.')?></label>
|
||||
<input type="text" class="form-control" id="draught_min" name="draught_min" value="<?=format_float($vessel->draught_min, 2) ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="displacement" class="form-label"><?=_('Displacement')?></label>
|
||||
<input type="number" input-mode="decimal" min="0" max="100000" step="1" class="form-control" id="displacement" name="displacement" value="<?=$vessel->displacement ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="ballast" class="form-label"><?=_('Ballast')?></label>
|
||||
<input type="number" input-mode="decimal" min="0" max="100000" step="1" class="form-control" id="ballast" name="ballast" value="<?=$vessel->ballast ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="remarks" class="form-label"><?=_('Remarks')?></label>
|
||||
<textarea class="form-control" id="remarks" name="remarks" rows="3"><?=$vessel->remarks ?></textarea>
|
||||
</div>
|
||||
<?php
|
||||
|
||||
form_edit_buttons($g_scriptname, $user->vid);
|
||||
echo "</form>\n";
|
||||
|
||||
else:
|
||||
// ========== ERROR UNKNOWN VARIANT ===========================================
|
||||
|
||||
echo '<p>', _('Unknown function call: Please report to system development!'), "</p>\n";
|
||||
|
||||
endif; // $action == ...
|
||||
// ========== END OF VARIANTS =================================================
|
||||
|
||||
include 'footer.php';
|
||||
@@ -0,0 +1,353 @@
|
||||
<?php
|
||||
/******************************************************************************
|
||||
* YMS - Yacht Management Software
|
||||
* Copyright (C) 2024 Thomas Hooge
|
||||
*
|
||||
* SPDX-License-Identifier: WTFPL
|
||||
******************************************************************************/
|
||||
|
||||
require 'globals.inc';
|
||||
$pagetitle=_('Inventory');
|
||||
|
||||
$id = gpc_get_int($_REQUEST, 'id', 0);
|
||||
|
||||
$opt_storage = db_get_opt_storage($user->vid);
|
||||
$opt_box = db_get_opt_box($user->vid);
|
||||
|
||||
// ========== 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 'insert':
|
||||
$invname = gpc_get_string($_POST, 'invname');
|
||||
$number = gpc_get_int($_POST, 'number');
|
||||
$boxtype = gpc_get_string($_POST, 'boxtype');
|
||||
$sid = gpc_get_int($_POST, 'sid');
|
||||
$boxid = gpc_get_int($_POST, 'boxid');
|
||||
$sql = "INSERT INTO inventory "
|
||||
. " (invname, invcond, number, boxtype, sid, boxid) "
|
||||
. "VALUES "
|
||||
. " (:invname, 'good', :number, :boxtype, :sid, :boxid)";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->bindValue(':invname', $invname, PDO::PARAM_STR);
|
||||
$sth->bindValue(':number', $number, PDO::PARAM_INT);
|
||||
$sth->bindValue(':boxtype', $boxtype, PDO::PARAM_STR);
|
||||
$sth->bindValue(':sid', $sid, PDO::PARAM_INT);
|
||||
$sth->bindValue(':boxid', $boxid, PDO::PARAM_INT);
|
||||
try {
|
||||
$sth->execute();
|
||||
} catch (PDOException $e) {
|
||||
$g_error->Add('SQL-Error: '. $e->getMessage());
|
||||
}
|
||||
$id = $pdo->LastInsertId();
|
||||
$action = ACT_VIEW;
|
||||
break;
|
||||
|
||||
case 'update':
|
||||
$invname = gpc_get_string($_POST, 'invname');
|
||||
$number = gpc_get_int($_POST, 'number');
|
||||
$boxtype = gpc_get_string($_POST, 'boxtype');
|
||||
$sid = gpc_get_int($_POST, 'sid');
|
||||
$boxid = gpc_get_int($_POST, 'boxid');
|
||||
$weight = min(gpc_get_float($_POST, 'weight'), 999.99); // limit max value
|
||||
$price = gpc_get_currency($_POST, 'price');
|
||||
$purchdate = gpc_get_date($_POST, 'purchdate');
|
||||
$invcond = gpc_get_string($_POST, 'invcond');
|
||||
$sql = "UPDATE inventory "
|
||||
. "SET invname=:invname,"
|
||||
. " number=:number,"
|
||||
. " boxtype=:boxtype,"
|
||||
. " sid=:sid,"
|
||||
. " boxid=:boxid,"
|
||||
. " weight=:weight,"
|
||||
. " price=:price,"
|
||||
. " purchdate=:purchdate,"
|
||||
. " invcond=:invcond "
|
||||
. "WHERE invid=:invid";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->bindValue(':invid', $id, PDO::PARAM_INT);
|
||||
$sth->bindValue(':invname', $invname, PDO::PARAM_STR);
|
||||
$sth->bindValue(':number', $number, PDO::PARAM_INT);
|
||||
$sth->bindValue(':boxtype', $boxtype, PDO::PARAM_STR);
|
||||
$sth->bindValue(':sid', $sid, PDO::PARAM_INT);
|
||||
$sth->bindValue(':boxid', $boxid, PDO::PARAM_INT);
|
||||
$sth->bindValue(':weight', $weight);
|
||||
$sth->bindValue(':price', $price);
|
||||
$sth->bindValue(':purchdate', $purchdate);
|
||||
$sth->bindValue(':invcond', $invcond, PDO::PARAM_STR);
|
||||
try {
|
||||
$sth->execute();
|
||||
} catch (PDOException $e) {
|
||||
$g_error->Add('SQL-Error: '. $e->getMessage());
|
||||
}
|
||||
$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;
|
||||
}
|
||||
unset($_SESSION['token']);
|
||||
$sth = $pdo->prepare("DELETE FROM inventory WHERE invid=?");
|
||||
$sth->execute([$id]);
|
||||
$g_message->Add(sprintf(_('Deleted inventory no. %d'), $id));
|
||||
$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 =======================================
|
||||
|
||||
/*
|
||||
The only way to find out whether the inventory is on the current boat is to use
|
||||
the box assignment. But this is also intentional to allow easy rearrangement.
|
||||
*/
|
||||
|
||||
echo "<h1>$pagetitle</h1>\n";
|
||||
|
||||
$sql = "SELECT i.invid, i.invname, i.number, i.invcond, s.sname AS container "
|
||||
. "FROM inventory AS i JOIN storage AS s ON (i.boxtype='storage' AND i.sid=s.sid)"
|
||||
. "WHERE s.vid=:vid "
|
||||
. "UNION "
|
||||
. "SELECT i.invid, i.invname, i.number, i.invcond, b.label AS container "
|
||||
. "FROM inventory AS i JOIN box AS b ON (i.boxtype='box' AND i.boxid=b.boxid) "
|
||||
. " JOIN storage AS s ON (b.sid=s.sid) "
|
||||
. "WHERE s.vid=:vid "
|
||||
. "ORDER BY invname";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->bindValue(':vid', $user->vid, PDO::PARAM_INT);
|
||||
$sth->execute();
|
||||
$res = $sth->fetchAll();
|
||||
echo '<table class="table table-striped">', "\n";
|
||||
echo "<thead>\n";
|
||||
echo "<tr>\n";
|
||||
echo "<th>" . _('Name') . "</th>\n";
|
||||
echo "<th>" . _('Container') . "</th>";
|
||||
echo "<th>" . _('Number') . "</th>";
|
||||
echo "<th>" . _('Condition') . "</th>";
|
||||
echo "</tr>\n";
|
||||
echo "</thead>\n";
|
||||
foreach ($res as $row) {
|
||||
echo "<tr>\n";
|
||||
echo '<td>', $row['invname'], "</td>\n";
|
||||
echo "<td>". $row['container'] ."</td>\n";
|
||||
echo "<td>". $row['number'] ."</td>\n";
|
||||
echo "<td>". $row['invcond'] ."</td>\n";
|
||||
form_action_buttons($g_scriptname, $row['invid']);
|
||||
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 Inventory'), "</h2>\n";
|
||||
?>
|
||||
<form method="post" action="<?=$g_scriptname?>">
|
||||
<div class="mb-3">
|
||||
<label for="invname" class="form-label"><?=_('Name')?></label>
|
||||
<input type="text" class="form-control" id="invname" name="invname">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="number" class="form-label"><?=_('Number')?></label>
|
||||
<input type="number" class="form-control" id="number" name="number" value="1">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="boxtype" class="form-label"><?=_('Boxtype')?></label>
|
||||
<select class="form-select" name="boxtype" id="boxtype">
|
||||
<option value="box"><?=_('Box')?></option>
|
||||
<option value="storage"><?=_('Storage')?></option>
|
||||
</select>
|
||||
</div>
|
||||
<?php
|
||||
form_create_select('sid', _('Storage'), $opt_storage);
|
||||
form_create_select('boxid', _('Box'), $opt_box);
|
||||
?>
|
||||
<div class="container-fluid px-0 my-3">
|
||||
<button type="submit" name="submit[insert]" class="btn btn-primary"><?=_('Save')?></button>
|
||||
<a href="<?=$g_scriptname?>" class="btn btn-secondary"><?=_('Back')?></a>
|
||||
</div>
|
||||
</form>
|
||||
<?php
|
||||
|
||||
elseif ($action == ACT_VIEW):
|
||||
// ========== VARIANT: view single record =====================================
|
||||
|
||||
$sql = "SELECT invname, boxtype, sid, boxid, number, weight, price, purchdate, invcond "
|
||||
. "FROM inventory "
|
||||
. "WHERE invid=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$id]);
|
||||
$inventory = $sth->fetch(PDO::FETCH_OBJ);
|
||||
|
||||
// boxtype can be storage or box
|
||||
switch ($inventory->boxtype) {
|
||||
case 'storage':
|
||||
$sql = "SELECT sname, vid FROM storage WHERE sid=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$inventory->sid]);
|
||||
$row = $sth->fetch();
|
||||
$storagename = $row['sname'];
|
||||
$vid = $row['vid'];
|
||||
break;
|
||||
case 'box':
|
||||
// Future: Boxes can also be nested!
|
||||
// Recursive Function "get_storage_for_box()"
|
||||
$sql = "SELECT sid, label FROM box WHERE boxid=?";
|
||||
// TODO Load additional box data
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$inventory->boxid]);
|
||||
$box = $sth->fetch();
|
||||
$sql = "SELECT sname, vid FROM storage WHERE sid=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$box['sid']]);
|
||||
$row = $sth->fetch();
|
||||
$storagename = $row['sname'];
|
||||
$vid = $row['vid'];
|
||||
break;
|
||||
}
|
||||
|
||||
echo '<h2>', $inventory->invname, "</h2>\n";
|
||||
|
||||
echo '<table class="table">', "\n";
|
||||
echo '<tr><th style="width:20%">', _('Box type'),"</th><td>", $inventory->boxtype, "</td></tr>\n";
|
||||
|
||||
// Container with link
|
||||
echo "<tr><th>", _('Container'),"</th><td>", sprintf(_('%s in %s'), $box['label'], $storagename);
|
||||
echo "</td></tr>\n";
|
||||
|
||||
echo "<tr><th>", _('Location ID'), "</th><td>", $inventory->locationid, "</td></tr>\n";
|
||||
echo "<tr><th>", _('Number'), "</th><td>", $inventory->number, "</td></tr>\n";
|
||||
echo "<tr><th>", _('Weight'), "</th><td>", format_float($inventory->weight, 2, 'kg'), "</td></tr>\n";
|
||||
echo "<tr><th>", _('Price'), "</th><td>", format_currency($inventory->price), "</td></tr>\n";
|
||||
echo "<tr><th>", _('Purchase date'), "</th><td>", $inventory->purchdate, "</td></tr>\n";
|
||||
echo "<tr><th>", _('Condition'), "</th><td>", $inventory->invcond, "</td></tr>\n";
|
||||
echo "</table>\n";
|
||||
|
||||
form_view_buttons($g_scriptname, $id);
|
||||
|
||||
elseif ($action == ACT_EDIT):
|
||||
// ========== VARIANT: edit single record =====================================
|
||||
|
||||
$sql = "SELECT invname, boxtype, sid, boxid, number, weight, price, purchdate, invcond "
|
||||
. "FROM inventory "
|
||||
. "WHERE invid=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$id]);
|
||||
$inventory = $sth->fetch(PDO::FETCH_OBJ);
|
||||
|
||||
?>
|
||||
<h2><?=_('Edit Inventory')?></h2>
|
||||
<form method="post" action="<?=$g_scriptname?>">
|
||||
<input type="hidden" name="id" value="<?=$id?>">
|
||||
<div class="mb-3">
|
||||
<label for="invname" class="form-label"><?=_('Name')?></label>
|
||||
<input type="text" class="form-control" id="invname" name="invname" value="<?=$inventory->invname ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="number" class="form-label"><?=_('Number')?></label>
|
||||
<input type="number" class="form-control" id="number" name="number" value="<?=$inventory->number ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="weight" class="form-label"><?=_('Weight, kg')?></label>
|
||||
<input type="text" class="form-control" id="weight" name="weight" value="<?=format_float($inventory->weight); ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="boxtype" class="form-label"><?=_('Boxtype')?></label>
|
||||
<select class="form-select" name="boxtype" id="boxtype">
|
||||
<option value="box"><?=_('Box')?></option>
|
||||
<option value="storage"><?=_('Storage')?></option>
|
||||
</select>
|
||||
</div>
|
||||
<?php
|
||||
form_create_select('sid', _('Storage'), $opt_storage);
|
||||
form_create_select('boxid', _('Box'), $opt_box);
|
||||
?>
|
||||
<div class="mb-3">
|
||||
<label for="price" class="form-label"><?=sprintf(_('Price, %s'), $g_lconv['currency_symbol']); ?></label>
|
||||
<input type="text" class="form-control" id="price" name="price" value="<?=format_float($inventory->price) ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="purchdate"><?=_('Purchase date')?></label>
|
||||
<input type="date" class="form-control" id="purchdate" name="purchdate" value="<?=$inventory->purchdate ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="invcond" class="form-label"><?=_('Condition')?></label>
|
||||
<select name="invcond" id="invcond" class="form-control">
|
||||
<?php
|
||||
$cond = array(
|
||||
'good' => _('Good'),
|
||||
'normal' => _('Normal'),
|
||||
'bad' => _('Bad'),
|
||||
'repairable' => _('Repairable'),
|
||||
'defect' => _('Defect'),
|
||||
'unknown' => _('Unknown')
|
||||
);
|
||||
foreach ($cond as $k => $v) {
|
||||
echo '<option value="', $k, '"';
|
||||
if ($k == $inventory->invcond) {
|
||||
echo ' selected';
|
||||
}
|
||||
echo '>', $v. "</option>\n";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
|
||||
form_edit_buttons($g_scriptname, $id);
|
||||
echo "</form>\n";
|
||||
|
||||
elseif ($action == ACT_DELETE):
|
||||
// ========== VARIANT: delete record ==========================================
|
||||
|
||||
$sql = "SELECT invname FROM inventory WHERE invid=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$id]);
|
||||
$inventory = $sth->fetch(PDO::FETCH_OBJ);
|
||||
|
||||
echo '<h2>', _('Delete Inventory'), "</h2>\n";
|
||||
echo '<p>', sprintf(_('Record no. %d'), $id), "</p>\n";
|
||||
echo '<p>Name: ', $inventory->invname, "</p>";
|
||||
|
||||
echo '<p>', _('Deleting an inventory item is final. There is no way back. Only delete if you are absolute sure.'), "</p>\n";
|
||||
$_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';
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
/******************************************************************************
|
||||
* YMS - Yacht Management Software
|
||||
* Copyright (C) 2024 Thomas Hooge
|
||||
*
|
||||
* SPDX-License-Identifier: WTFPL
|
||||
******************************************************************************/
|
||||
|
||||
// TODO Code to handle page call with already logged on user
|
||||
|
||||
require 'globals.inc';
|
||||
session_name(APP_SESSION);
|
||||
session_start();
|
||||
|
||||
if (isset($_POST['login'])) {
|
||||
$username = substr($_POST['username'], 0, 20);
|
||||
$password = substr($_POST['password'], 0, 32);
|
||||
if (!$user->login($username, $password)) {
|
||||
$err = $user->get_last_error();
|
||||
}
|
||||
} else {
|
||||
$username = '';
|
||||
}
|
||||
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="robots" content="noindex,nofollow">
|
||||
<title><?=APP_TITLE_SHORT?> - Login</title>
|
||||
<link href="bootstrap/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="bootstrap/bootstrap-icons.min.css" rel="stylesheet">
|
||||
<script src="bootstrap/js/bootstrap.bundle.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<section class="mx-auto my-5" style="max-width:32rem;">
|
||||
<div class="card card-form mt-2 mb-4">
|
||||
<div class="card-header">
|
||||
<?=APP_TITLE?>
|
||||
</div>
|
||||
<div class="row my-3">
|
||||
<div class="col">
|
||||
<img src="sailboat.svg" class="img-fluid rounded-start" alt="sailboat">
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title"><?=sprintf(_('Login to %s'), APP_TITLE_SHORT)?></h5>
|
||||
<form id="login" action="login.php" method="post">
|
||||
<div class="mb-3 mt-3">
|
||||
<label for="username" class="form-label"><?=_('Username:')?></label>
|
||||
<input type="text" class="form-control" required autofocus size="20" maxlength="20" name="username" id="username" value="<?=$username?>">
|
||||
</div>
|
||||
<div class="mb-3 mt-3">
|
||||
<label for="password" class="form-label"><?=_('Password:')?></label>
|
||||
<input type="password" class="form-control" required size="20" maxlength="32" name="password" id="password">
|
||||
</div>
|
||||
<?php
|
||||
if (isset($err)) {
|
||||
echo '<div class="alert alert-danger alert-dismissible fade show role="alert"">';
|
||||
echo '<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>';
|
||||
echo '<b>', _('Error'), ':</b> ', $err;
|
||||
echo "</div>\n";
|
||||
}
|
||||
?>
|
||||
<button type="submit" class="btn btn-primary" title="<?php printf(_('Logon to %s'), APP_TITLE_SHORT); ?>" name="login" value="1">
|
||||
<span class="bi bi-caret-right"></span>
|
||||
<?=_('Login')?>
|
||||
</button>
|
||||
</form>
|
||||
</div> <!-- card body -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
/******************************************************************************
|
||||
* YMS - Yacht Management Software
|
||||
* Copyright (C) 2024 Thomas Hooge
|
||||
*
|
||||
* SPDX-License-Identifier: WTFPL
|
||||
******************************************************************************/
|
||||
|
||||
require 'globals.inc';
|
||||
$user->logout();
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="robots" content="noindex,nofollow">
|
||||
<title><?=APP_TITLE_SHORT?> - Login</title>
|
||||
<link href="bootstrap/css/bootstrap.min.css" rel="stylesheet">
|
||||
<script src="bootstrap/js/bootstrap.bundle.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<section class="mx-auto my-5" style="max-width:23rem;">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<?=_('Logout')?>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<h5 class="card-title"><?=sprintf(_('<b>%s</b> is now logged out'), $user->displayname)?></h5>
|
||||
<p class="card-text"><?=sprintf(_('Thank you for using %s.'), APP_TITLE_SHORT)?></p>
|
||||
<p class="card-text"><?=sprintf(_('Always feel free to send improvements, suggestions, error messages or anything else to %s.'), $g_mailto_webmaster)?></p>
|
||||
<a class="btn btn-primary" href="login.php"><?=_('New login')?></a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,257 @@
|
||||
<?php
|
||||
/******************************************************************************
|
||||
* YMS - Yacht Management Software
|
||||
* Copyright (C) 2024 Thomas Hooge
|
||||
*
|
||||
* SPDX-License-Identifier: WTFPL
|
||||
******************************************************************************/
|
||||
|
||||
require 'globals.inc';
|
||||
$pagetitle = _('Maintenance');
|
||||
|
||||
$id = gpc_get_int($_REQUEST, 'id', 0);
|
||||
|
||||
// Equipment options
|
||||
$opt_equipment = array( 0 => _('*** unassigned ***'));
|
||||
$sql = "SELECT eid, ename FROM equipment WHERE vid=? ORDER BY ename";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$user->vid]);
|
||||
foreach ($sth->fetchAll() as $row) {
|
||||
$opt_equipment[$row['eid']] = $row['ename'];
|
||||
}
|
||||
|
||||
// ========== 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 'insert':
|
||||
$eid = gpc_get_int($_POST, 'eid');
|
||||
$activities = gpc_get_string($_POST, 'activities', 80);
|
||||
$sql = "INSERT INTO maintenance "
|
||||
. " (vid, eid, activities) "
|
||||
. "VALUES "
|
||||
. " (:vid, :eid, :activities)";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->bindValue(':vid', $user->vid, PDO::PARAM_INT);
|
||||
$sth->bindValue(':eid', $eid, PDO::PARAM_INT);
|
||||
$sth->bindValue(':activities', $activities, PDO::PARAM_STR);
|
||||
$sth->execute();
|
||||
$id = $pdo->LastInsertId();
|
||||
$action = ACT_VIEW;
|
||||
break;
|
||||
|
||||
case 'update':
|
||||
$eid = gpc_get_int($_POST, 'eid');
|
||||
$activities = gpc_get_string($_POST, 'activities', 80);
|
||||
$remarks = gpc_get_string($_POST, 'remarks', 150);
|
||||
$sql = "UPDATE maintenance "
|
||||
. "SET activities=:activities,"
|
||||
. " eid=:eid,"
|
||||
. " remarks=:remarks "
|
||||
. "WHERE maintid=:maintid";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->bindValue(':maintid', $id, PDO::PARAM_INT);
|
||||
$sth->bindValue(':eid', $eid, PDO::PARAM_INT);
|
||||
$sth->bindValue(':activities', $activities, PDO::PARAM_STR);
|
||||
$sth->bindValue(':remarks', $remarks, PDO::PARAM_STR);
|
||||
$sth->execute();
|
||||
$action = ACT_VIEW;
|
||||
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";
|
||||
|
||||
$sql = "SELECT m.maintid, m.activities, m.remarks, e.ename "
|
||||
. "FROM maintenance AS m LEFT OUTER JOIN equipment AS e USING (eid)"
|
||||
. "WHERE m.vid=? "
|
||||
. "ORDER BY m.maintid";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$user->vid]);
|
||||
$res = $sth->fetchAll();
|
||||
echo '<table class="table table-striped">', "\n";
|
||||
echo "<thead>\n";
|
||||
echo "<tr>";
|
||||
echo "<th>" . _('Activities') . "</th>";
|
||||
echo "<th>" . _('Equipment') . "</th>";
|
||||
echo "<th>" . _('Remarks') . "</th>";
|
||||
echo "</tr>\n";
|
||||
echo "</thead>\n";
|
||||
foreach ($res as $row) {
|
||||
echo "<tr>\n";
|
||||
echo "<td>". $row['activities'] ."</td>\n";
|
||||
echo "<td>". $row['ename'] ."</td>\n";
|
||||
echo "<td>". $row['remarks'] ."</td>\n";
|
||||
// Action buttons
|
||||
echo "<td>";
|
||||
echo '<a title="', _('View'), '" href="', $g_scriptname, '?f=view&id=', $row['maintid'], '"><i class="bi-eye"></i></a>', "\n";
|
||||
echo '<a title="', _('Edit'), '" href="', $g_scriptname, '?f=edit&id=', $row['maintid'], '"><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 Maintenance'), "</h2>\n";
|
||||
?>
|
||||
<form method="post" action="<?=$g_scriptname?>">
|
||||
<div class="mb-3">
|
||||
<label for="activities" class="form-label"><?=_('Activities')?></label>
|
||||
<input type="text" class="form-control" id="activities" name="activities">
|
||||
</div>
|
||||
<?php
|
||||
// TODO
|
||||
// Add link to equipment, perhaps later with modal dialog?
|
||||
?>
|
||||
<div class="mb-3">
|
||||
<label for="eid" class="form-label"><?=_('Equipment')?></label>
|
||||
<select name="eid" id="eid" class="form-control">
|
||||
<?php
|
||||
foreach ($opt_equipment as $k => $v) {
|
||||
echo '<option value="', $k, '">', $v, "</option>\n";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<div class="container-fluid px-0 my-3">
|
||||
<button type="submit" name="submit[insert]" class="btn btn-primary"><?=_('Save')?></button>
|
||||
<a href="<?=$g_scriptname?>" class="btn btn-secondary"><?=_('Back')?></a>
|
||||
</div>
|
||||
<?php
|
||||
elseif ($action == ACT_VIEW):
|
||||
// ========== VARIANT: view single record =====================================
|
||||
|
||||
echo '<h2>', _('View Maintenance'), "</h2>\n";
|
||||
|
||||
$sql = "SELECT m.activities, m.eid, m.remarks, e.ename "
|
||||
. "FROM maintenance AS m LEFT OUTER JOIN equipment AS e USING (eid) "
|
||||
. "WHERE m.maintid=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$id]);
|
||||
$maint = $sth->fetch(PDO::FETCH_OBJ);
|
||||
|
||||
if (isset($maint->eid)) {
|
||||
$sql = "SELECT r.docid, d.filename, d.title, d.hash, d.extension "
|
||||
. "FROM docref AS r INNER JOIN document AS d USING (docid) "
|
||||
. "WHERE r.reftype='equipment' AND r.refid=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$maint->eid]);
|
||||
$docs = $sth->fetchAll();
|
||||
} else {
|
||||
$maint->ename = _('n/a');
|
||||
}
|
||||
|
||||
// Bootstrap grid
|
||||
echo '<div class="container">';
|
||||
echo '<div class="row">';
|
||||
echo '<div class="col">';
|
||||
|
||||
echo '<table class="table">', "\n";
|
||||
echo '<tr><th>', _('Activities'),"</th><td>", $maint->activities, "</td></tr>\n";
|
||||
echo '<tr><th>', _('Equipment'),"</th><td>", $maint->ename, "</td></tr>\n";
|
||||
echo '<tr><th>', _('Remarks'),"</th><td>", $maint->remarks, "</td></tr>\n";
|
||||
echo "</table>\n";
|
||||
|
||||
echo '</div>'; // Column break
|
||||
echo '<div class="col">';
|
||||
|
||||
// TODO Show documents for equipment
|
||||
?>
|
||||
<p>Documents</p>
|
||||
<?php
|
||||
echo '<ul>', "\n";
|
||||
foreach ($docs as $d) {
|
||||
echo '<li>', $d['title'] ?? $d['filename'], ' (', $d['docid'], ")</li>\n";
|
||||
}
|
||||
echo "</ul>\n";
|
||||
|
||||
|
||||
echo '</div>'; // col
|
||||
echo '</div>'; // row
|
||||
echo '</div>'; // container
|
||||
|
||||
form_view_buttons($g_scriptname, $id);
|
||||
|
||||
elseif ($action == ACT_EDIT):
|
||||
// ========== VARIANT: edit single record =====================================
|
||||
|
||||
$sql = "SELECT activities, eid, remarks "
|
||||
. "FROM maintenance "
|
||||
. "WHERE maintid=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$id]);
|
||||
$maint = $sth->fetch(PDO::FETCH_OBJ);
|
||||
|
||||
echo '<h2>', _('Edit Maintenance'), "</h2>\n";
|
||||
|
||||
?>
|
||||
<form method="post" action="<?=$g_scriptname?>">
|
||||
<input type="hidden" name="id" value="<?=$id?>">
|
||||
<div class="mb-3">
|
||||
<label for="activities" class="form-label"><?=_('Activities')?></label>
|
||||
<input type="text" class="form-control" id="activities" name="activities" value="<?=$maint->activities ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="eid" class="form-label"><?=_('Equipment')?></label>
|
||||
<select name="eid" id="eid" class="form-control">
|
||||
<?php
|
||||
foreach ($opt_equipment as $k => $v) {
|
||||
echo '<option value="', $k;
|
||||
if ($maint->eid == $k) {
|
||||
echo ' selected';
|
||||
}
|
||||
echo '">', $v, "</option>\n";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<div class="mb-3">
|
||||
<label for="remarks" class="form-label"><?=_('Remarks')?></label>
|
||||
<textarea class="form-control" id="remarks" name="remarks" rows="3"><?=$maint->remarks ?></textarea>
|
||||
</div>
|
||||
<?php
|
||||
|
||||
form_edit_buttons($g_scriptname, $id);
|
||||
echo "</form>\n";
|
||||
|
||||
elseif ($action == ACT_DELETE):
|
||||
// ========== VARIANT: delete record ==========================================
|
||||
|
||||
echo '<h2>', _('Delete Maintenance'), "</h2>\n";
|
||||
|
||||
else:
|
||||
// ========== ERROR UNKNOWN VARIANT ===========================================
|
||||
|
||||
echo '<p>', _('Unknown function call: Please report to system development!'), "</p>\n";
|
||||
|
||||
endif; // $action == ...
|
||||
// ========== END OF VARIANTS =================================================
|
||||
|
||||
|
||||
include 'footer.php';
|
||||
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
/******************************************************************************
|
||||
* YMS - Yacht Management Software
|
||||
* Copyright (C) 2024 Thomas Hooge
|
||||
*
|
||||
* SPDX-License-Identifier: WTFPL
|
||||
******************************************************************************/
|
||||
|
||||
require 'globals.inc';
|
||||
$pagetitle=_('Manual');
|
||||
|
||||
require 'header.php';
|
||||
?>
|
||||
|
||||
<h1>Yacht Management System</h1>
|
||||
<h2>Integriertes Handbuch</h2>
|
||||
|
||||
<p>Es können mehrere Yachten mit dem Programm verwaltet werden.
|
||||
Die Umschaltung erfolgt über eine Auswahlliste auf der Übersichtsseite.</p>
|
||||
<p>Die Yachtdaten können nur mit de Berechtigungsebene <em>captain</em>
|
||||
verändert werden.</p>
|
||||
|
||||
<p>Bei Neuanlage eines Datensatzes werden nur die wichtigsten Felder
|
||||
angezeigt. Weitere Felder können im Anschluß über die Bearbeiten-Funktion
|
||||
ausgefüllt werden.</p>
|
||||
|
||||
<h3>Stauraum</h3>
|
||||
<p>Der Stauraum teilt sich in verschiedene Bereiche auf.
|
||||
Diese sind über eine fixe Position an Bord einstellbar.</p>
|
||||
|
||||
<p>Zusätzlich zum festen Stauraum können auch Kisten definiert werden.
|
||||
Eine Kiste kann in einen Stauraum gelegt werden. Da sie beweglich ist,
|
||||
kann sie auch als Ganzes auf eine andere Yacht übergeben werden.</p>
|
||||
|
||||
<p>Es existiert ein Koordinatensystem. Die Einheit ist Millimeter (mm).
|
||||
Der Ursprung ist achtern Mittschiffs. Die X-Achse verläuft in Längsrichtung
|
||||
der Yacht. Die Y-Achse verläuft zur Querrichtung, Koorinaten auf der Backbordseite
|
||||
sind negativ, auf der Steuerbordseite positiv.
|
||||
Die Z-Achse geht in Richtung Mastspitze. Der Nullpunkt liegt auf Höhe der
|
||||
Wasserlinie.</p>
|
||||
|
||||
<h3>Ausrüstung</h3>
|
||||
<p>Ausrüstung ist zumeist fest mit der Yacht verbunden, jeder Ausrüstungsgegenstand
|
||||
existiert nur ein mal und kann eine Seriennummer besitzen.</p>
|
||||
<p>Ausrüstung kann gewartet werden.</p>
|
||||
|
||||
<h3>Inventar</h3>
|
||||
<p>Unter Inventar sind bewegliche Dinge zusammengefaßt.
|
||||
Ein Inventargegenstand kann auch mehrfach vorkommen.
|
||||
Beispiel: <em>Winschkurbel, Anzahl: 3</em></p>
|
||||
<p>Inventar kann in einem Stauraum abgelegt werden oder aber in einer
|
||||
Kiste.</p>
|
||||
|
||||
<h3>Proviant</h3>
|
||||
<p>Proviant ist verderblich.
|
||||
Es wird das Einlagerungsdatum erfaßt und das Haltbarkeitsdatum</p>
|
||||
|
||||
<h3>Wartung</h3>
|
||||
<p>Es können einmalige und wiederkehrende Wartungen erfaßt werden</p>
|
||||
<p>Eine wiederkehrende Wartung kann aufgrund Zeit, z.B. 1x jährlich,
|
||||
oder nach Betriebsstunden definiert werden.</p>
|
||||
|
||||
<h3>Projekte</h3>
|
||||
<p>Einem Projekt werden Aufgaben zugeordnet, es hat einen Status wie
|
||||
z.B. <em>neu</em>, <em>laufend</em> oder <em>erledigt</em>.</p>
|
||||
|
||||
<h3>Firmen</h3>
|
||||
<p>Es können verschiedene Arten von Firmen hinterlegt werden, wie
|
||||
beispielsweise Hersteller, Lieferanten oder Dienstleister.</p>
|
||||
|
||||
<h3>Dokumente</h3>
|
||||
<p>Ein Dokument kann mehrfach zugeordnet werden. Z.B. einem
|
||||
Ausrüstungsgegenstand und gleichzeitig einem Projekt oder einer Aufgabe.</p>
|
||||
<p>Es stehen verschiedene Dokumentarten zur Verfügung:</p>
|
||||
<ul>
|
||||
<li>Fotos bzw. Bilder als png- oder jpg-Dateien</li>
|
||||
<li>Zeichnungen als svg-Dateien</li>
|
||||
<li>Dokumente als pdf-Dateien</li>
|
||||
</ul>
|
||||
|
||||
<h3>Checklisten</h3>
|
||||
<p>Es ist eine Historie vorgesehen.</p>
|
||||
|
||||
<h3>Ersatzteile</h3>
|
||||
<p>Die Verwaltung von Ersatzteilen erfolgt normalerweise über das Inventar.</p>
|
||||
|
||||
<h3>Maße / Messungen</h3>
|
||||
<p>Messungen können hier dokumentiert werden. Eine Zuordnung zur Ausrüstung
|
||||
ist vorgesehen.</p>
|
||||
<p>In einer Messung können ein bis drei Werte gespeichert werden. Damit
|
||||
ist es möglich Flächen <span style="white-space:nowrap">(L x B)</span> oder
|
||||
Volumen <span style="white-space:nowrap">(L x B x H)</span> zusammenhängend
|
||||
zu erfassen.</p>
|
||||
|
||||
<h3>Benutzer</h3>
|
||||
<p>Benutzer können nicht über die Web-GUI eingerichtet werden.</p>
|
||||
<p>Es gibt die Berechtigungsebenen <em>Kapitän (captain)</em>,
|
||||
<em>Steuermann (helmsman)</em> und <em>Matrose (sailor)</em>.
|
||||
|
||||
<h3>Stammdaten</h3>
|
||||
<p>Diese Daten ändern sich nicht sehr häufig, sind aber für den Betrieb
|
||||
essentiell. Stanndaten sind beispielsweise Firmen, Auswahllisten oder
|
||||
auch der Stauraum.</p>
|
||||
|
||||
<?php
|
||||
include 'footer.php';
|
||||
@@ -0,0 +1,284 @@
|
||||
<?php
|
||||
/******************************************************************************
|
||||
* YMS - Yacht Management Software
|
||||
* Copyright (C) 2024 Thomas Hooge
|
||||
*
|
||||
* SPDX-License-Identifier: WTFPL
|
||||
******************************************************************************/
|
||||
|
||||
require 'globals.inc';
|
||||
$pagetitle = _('Measurements');
|
||||
|
||||
$id = gpc_get_int($_REQUEST, 'id', 0);
|
||||
|
||||
$opt_unit = db_get_options(8);
|
||||
$opt_accuracy = array(
|
||||
'unknown' => _('Unknown'),
|
||||
'precise' => _('Precise'),
|
||||
'normal' => _('Normal'),
|
||||
'rough' => _('Rough'),
|
||||
'estimated' => _('Estimated')
|
||||
);
|
||||
$opt_dimensions = array(
|
||||
1 => _('1D'),
|
||||
2 => _('2D'),
|
||||
3 => _('3D')
|
||||
);
|
||||
$opt_equipment = array(-1 => _('unassigned'));
|
||||
$sth = $pdo->prepare("SELECT eid, ename FROM equipment WHERE vid=? ORDER BY ename");
|
||||
$sth->execute([$user->vid]);
|
||||
foreach ($sth->fetchAll() as $row) {
|
||||
$opt_equipment[$row['eid']] = $row['ename'];
|
||||
}
|
||||
|
||||
// ========== 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 'insert':
|
||||
$p[':mname'] = gpc_get_string($_POST, 'mname');
|
||||
$p[':note'] = gpc_get_string($_POST, 'note');
|
||||
$p[':nval'] = gpc_get_int($_POST, 'nval'); // 1 to 3 dimensions
|
||||
$p[':val1'] = gpc_get_int($_POST, 'val1');
|
||||
$p[':val2'] = NULL;
|
||||
$p[':val3'] = NULL;
|
||||
if ($p[':nval'] > 1) {
|
||||
$p[':val2'] = gpc_get_int($_POST, 'val2');
|
||||
}
|
||||
if ($p[':nval'] > 2) {
|
||||
$p[':val3'] = gpc_get_int($_POST, 'val3');
|
||||
}
|
||||
$p[':unit'] = gpc_get_int($_POST, 'unit');
|
||||
$p[':accuracy'] = gpc_get_string($_POST, 'accuracy');
|
||||
$p[':eid'] = gpc_get_int($_POST, 'eid');
|
||||
if ($p[':eid'] == -1) {
|
||||
$p[':eid'] = NULL;
|
||||
}
|
||||
$keys = array_keys($p);
|
||||
$fields = join(',', array_map(function($s) { return ltrim($s, ':'); }, $keys));
|
||||
$pnames = join(',', $keys);
|
||||
$sth = $pdo->prepare("INSERT INTO measurement ($fields) VALUES ($pnames)");
|
||||
try {
|
||||
$sth->execute($p);
|
||||
} catch (PDOexception $e) {
|
||||
$g_error->Add('SQL-Error: '. $e->getMessage());
|
||||
}
|
||||
$id = $pdo->LastInsertId();
|
||||
$action = ACT_VIEW;
|
||||
break;
|
||||
|
||||
case 'update':
|
||||
$p[':mname'] = gpc_get_string($_POST, 'mname');
|
||||
$p[':nval'] = gpc_get_int($_POST, 'nval'); // 1 to 3 dimensions
|
||||
$p[':val1'] = gpc_get_int($_POST, 'val1');
|
||||
$p[':val2'] = NULL;
|
||||
$p[':val3'] = NULL;
|
||||
if ($p[':nval'] > 1) {
|
||||
$p[':val2'] = gpc_get_int($_POST, 'val2');
|
||||
}
|
||||
if ($p[':nval'] > 2) {
|
||||
$p[':val3'] = gpc_get_int($_POST, 'val3');
|
||||
}
|
||||
$p[':unit'] = gpc_get_int($_POST, 'unit');
|
||||
$p[':accuracy'] = gpc_get_string($_POST, 'accuracy');
|
||||
$p[':mdate'] = gpc_get_date($_POST, 'mdate');
|
||||
$p[':note'] = gpc_get_string($_POST, 'note');
|
||||
$p[':eid'] = gpc_get_int($_POST, 'eid');
|
||||
if ($p[':eid'] == -1) {
|
||||
$p[':eid'] = NULL;
|
||||
}
|
||||
$fields = join(',', array_map(function($s) { return ltrim($s, ':') . '=' . $s; }, array_keys($p)));
|
||||
$sth = $pdo->prepare("UPDATE measurement SET $fields WHERE mid=:mid");
|
||||
$p[':mid'] = $id;
|
||||
try {
|
||||
$sth->execute($p);
|
||||
} catch (PDOexception $e) {
|
||||
$g_error->Add('SQL-Error: '. $e->getMessage());
|
||||
}
|
||||
$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;
|
||||
}
|
||||
$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 =======================================
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
echo "<h1>$pagetitle</h1>\n";
|
||||
|
||||
$sql = "SELECT mid, mname, nval, val1, val2, val3, unit, accuracy, mdate, note, eid "
|
||||
. "FROM measurement "
|
||||
. "ORDER BY mname";
|
||||
$sth = $pdo->query($sql);
|
||||
$res = $sth->fetchAll();
|
||||
echo '<table class="table table-striped">', "\n";
|
||||
echo "<thead>\n";
|
||||
echo "<tr>\n";
|
||||
echo '<th>', _('Measurement'), "</th>";
|
||||
echo '<th>', _('Note'), "</th>";
|
||||
echo '<th class="text-end">', _('Measured'), "</th>";
|
||||
echo '<th>', _('Unit'), "</th>";
|
||||
echo '<th>', _('Accuracy'), "</th>";
|
||||
echo "<th></th>";
|
||||
echo "</tr>\n";
|
||||
echo "</thead>\n";
|
||||
foreach ($res as $row) {
|
||||
echo "<tr>\n";
|
||||
echo "<td>", $row['mname'], "</td>\n";
|
||||
echo "<td>", $row['note'], "</td>\n";
|
||||
echo '<td class="text-end">', format_vals($row['nval'], $row['val1'], $row['val2'], $row['val3']), "</td>\n";
|
||||
echo "<td>", $opt_unit[$row['unit']], "</td>\n";
|
||||
echo "<td>", $opt_accuracy[$row['accuracy']], "</td>\n";
|
||||
echo "<td>";
|
||||
// Action buttons
|
||||
form_action_buttons($g_scriptname, $row['mid']);
|
||||
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 measurement'), "</h2>\n";
|
||||
|
||||
?>
|
||||
<form method="post">
|
||||
<div class="mb-3">
|
||||
<label for="mname" class="form-label"><?=_('Name')?></label>
|
||||
<input type="text" class="form-control" id="mname" name="mname" required autofocus>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="note" class="form-label"><?=_('Note')?></label>
|
||||
<input type="text" class="form-control" id="note" name="note">
|
||||
</div>
|
||||
<?php
|
||||
form_create_select('nval', _('Dimensions'), $opt_dimensions);
|
||||
?>
|
||||
<div class="mb-3">
|
||||
<label for="val1" class="form-label"><?=_('Value 1')?></label>
|
||||
<input type="text" class="form-control" id="val1" name="val1">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="val2" class="form-label"><?=_('Value 2')?></label>
|
||||
<input type="text" class="form-control" id="val1" name="val2">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="val3" class="form-label"><?=_('Value 3')?></label>
|
||||
<input type="text" class="form-control" id="val3" name="val3">
|
||||
</div>
|
||||
<?php
|
||||
form_create_select('unit', _('Unit'), $opt_unit);
|
||||
form_create_select('accuracy', _('Accuracy'), $opt_accuracy);
|
||||
form_create_select('eid', _('Equipment'), $opt_equipment);
|
||||
?>
|
||||
<div class="container-fluid px-0 my-3">
|
||||
<button type="submit" name="submit[insert]" class="btn btn-primary"><?=_('Save')?></button>
|
||||
<a href="<?=$g_scriptname?>" class="btn btn-secondary"><?=_('Back')?></a>
|
||||
</div>
|
||||
</form>
|
||||
<?php
|
||||
|
||||
elseif ($action == ACT_VIEW):
|
||||
// ========== VARIANT: view single record =====================================
|
||||
|
||||
elseif ($action == ACT_EDIT):
|
||||
// ========== VARIANT: edit single record =====================================
|
||||
|
||||
$sql = "SELECT mname, nval, val1, val2, val3, unit, accuracy, note "
|
||||
. "FROM measurement "
|
||||
. "WHERE mid=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$id]);
|
||||
$measurement = $sth->fetch(PDO::FETCH_OBJ);
|
||||
|
||||
echo '<h2>', _('Edit measurement'), "</h2>\n";
|
||||
?>
|
||||
<form method="post">
|
||||
<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="name" name="mname" value="<?=$measurement->mname ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="note" class="form-label"><?=_('Note')?></label>
|
||||
<input type="text" class="form-control" id="note" name="note" value="<?=$measurement->note ?>">
|
||||
</div>
|
||||
<?php
|
||||
form_create_select('nval', _('Dimensions'), $opt_dimensions, $measurement->nval);
|
||||
?>
|
||||
<div class="mb-3">
|
||||
<label for="val1"><?=_('Value 1')?></label>
|
||||
<input type="number" min="0" class="form-control" id="val1" name="val1" value="<?=$measurement->val1 ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="val2"><?=_('Value 2')?></label>
|
||||
<input type="number" min="0" class="form-control" id="val2" name="val2" value="<?=$measurement->val2 ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="val3"><?=_('Value 3')?></label>
|
||||
<input type="number" min="0" class="form-control" id="val3" name="val3" value="<?=$measurement->val3 ?>">
|
||||
</div>
|
||||
<?php
|
||||
form_create_select('unit', _('Unit'), $opt_unit, $measurement->unit);
|
||||
form_create_select('accuracy', _('Accuracy'), $opt_accuracy, $measurement->accuracy);
|
||||
form_create_select('eid', _('Equipment'), $opt_equipment, $measurement->eid);
|
||||
|
||||
form_edit_buttons($g_scriptname, $id);
|
||||
echo "</form>\n";
|
||||
|
||||
elseif ($action == ACT_DELETE):
|
||||
// ========== VARIANT: delete record ==========================================
|
||||
|
||||
else:
|
||||
// ========== ERROR UNKNOWN VARIANT ===========================================
|
||||
|
||||
echo '<p>', _('Unknown function call: Please report to system development!'), "</p>\n";
|
||||
|
||||
endif; // $action == ...
|
||||
// ========== END OF VARIANTS =================================================
|
||||
|
||||
include 'footer.php';
|
||||
@@ -0,0 +1,288 @@
|
||||
<?php
|
||||
/******************************************************************************
|
||||
* YMS - Yacht Management Software
|
||||
* Copyright (C) 2024 Thomas Hooge
|
||||
*
|
||||
* SPDX-License-Identifier: WTFPL
|
||||
******************************************************************************/
|
||||
|
||||
require 'globals.inc';
|
||||
$pagetitle = _('Projects');
|
||||
|
||||
$id = gpc_get_int($_REQUEST, 'id', 0);
|
||||
|
||||
$sql = "SELECT userid, displayname FROM user WHERE userid>0";
|
||||
$sth = $pdo->query($sql);
|
||||
$opt_user = array();
|
||||
foreach ($sth->fetchAll() as $row) {
|
||||
$opt_user[$row['userid']] = $row['displayname'];
|
||||
}
|
||||
|
||||
// ========== 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 'insert':
|
||||
$projname = gpc_get_string($_POST, 'projname');
|
||||
$responsible = gpc_get_int($_POST, 'responsible');
|
||||
$remarks = gpc_get_string($_POST, 'remarks', 150);
|
||||
$sql = "INSERT INTO project "
|
||||
. " (vid, projname, responsible, remarks) "
|
||||
. "VALUES "
|
||||
. " (:vid, :projname, :responsible, :remarks)";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->bindValue(':vid', $user->vid, PDO::PARAM_INT);
|
||||
$sth->bindValue(':projname', $projname, PDO::PARAM_STR);
|
||||
$sth->bindValue(':responsible', $responsible, PDO::PARAM_INT);
|
||||
$sth->bindValue(':remarks', $remarks, PDO::PARAM_STR);
|
||||
$sth->execute();
|
||||
$id = $pdo->lastInsertId();
|
||||
$action = ACT_VIEW;
|
||||
break;
|
||||
|
||||
case 'update':
|
||||
$projname = gpc_get_string($_POST, 'projname');
|
||||
$startdate = gpc_get_date($_POST, 'startdate');
|
||||
$duration = gpc_get_int($_POST, 'duration');
|
||||
$remarks = gpc_get_string($_POST, 'remarks', 150);
|
||||
$sql = "UPDATE project "
|
||||
. "SET projname=:projname,"
|
||||
. " startdate=:startdate,"
|
||||
. " duration=:duration,"
|
||||
. " remarks=:remarks "
|
||||
. "WHERE projid=:projid";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->bindValue(':projid', $id, PDO::PARAM_INT);
|
||||
$sth->bindValue(':projname', $projname, PDO::PARAM_STR);
|
||||
$sth->bindValue(':startdate', $startdate, PDO::PARAM_STR);
|
||||
$sth->bindValue(':duration', $duration, PDO::PARAM_INT);
|
||||
$sth->bindValue(':remarks', $remarks, PDO::PARAM_STR);
|
||||
$sth->execute();
|
||||
$action = ACT_VIEW;
|
||||
break;
|
||||
|
||||
case 'delete':
|
||||
$action = ACT_DEFAULT;
|
||||
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";
|
||||
|
||||
$sql = "SELECT projid, projname, startdate, duration, remarks "
|
||||
. "FROM project "
|
||||
. "WHERE vid=? "
|
||||
. "ORDER BY projid";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$user->vid]);
|
||||
$res = $sth->fetchAll();
|
||||
echo '<table class="table table-striped">'. "\n";
|
||||
echo "<thead>\n";
|
||||
echo "<tr>";
|
||||
echo "<th>" . _('Name') . "</th>";
|
||||
echo "<th>" . _('Start date') . "</th>";
|
||||
echo "<th>" . _('Duration') . "</th>";
|
||||
echo "<th>" . _('Remarks') . "</th>";
|
||||
echo "<th> </th>";
|
||||
echo "</tr>\n";
|
||||
echo "</thead>\n";
|
||||
foreach ($res as $row) {
|
||||
echo "<tr>\n";
|
||||
echo "<td>". $row['projname'] ."</td>\n";
|
||||
echo "<td>". $row['startdate'] ."</td>\n";
|
||||
echo "<td>". $row['duration'] ."</td>\n";
|
||||
echo "<td>". $row['remarks'] ."</td>\n";
|
||||
// Action buttons
|
||||
form_action_buttons($g_scriptname, $row['projid']);
|
||||
echo "</tr>\n";
|
||||
}
|
||||
echo "<tfoot>\n";
|
||||
echo '<tr><td colspan="5">', sprintf(_('%d records'), count($res)), '</td></tr>', "\n";
|
||||
echo "</tfoot>\n";
|
||||
echo "</table>\n";
|
||||
|
||||
form_add_button($g_scriptname);
|
||||
|
||||
echo "<h1>", _('Generic Tasks'), "</h1>\n";
|
||||
echo "<p>", _('Tasks not assigned to any project'), "</p>\n";
|
||||
$sql = "SELECT taskid, taskname "
|
||||
. "FROM task "
|
||||
. "WHERE projid IS NULL "
|
||||
. "ORDER BY taskid";
|
||||
$sth = $pdo->query($sql);
|
||||
$res = $sth->fetchAll();
|
||||
echo '<table class="table table-striped">', "\n";
|
||||
echo "<thead>\n";
|
||||
echo "<tr>";
|
||||
echo "<th>" . _('Name') . "</th>";
|
||||
echo "</tr>\n";
|
||||
echo "</thead>\n";
|
||||
foreach ($res as $row) {
|
||||
echo "<tr>\n";
|
||||
echo "<td>". $row['taskname'] ."</td>\n";
|
||||
form_action_buttons('task.php', $row['taskid']);
|
||||
echo "</tr>\n";
|
||||
}
|
||||
// Table summary
|
||||
echo "<tfoot>\n";
|
||||
echo '<tr><td colspan="2">', sprintf(_('%d records'), count($res)), '</td></tr>', "\n";
|
||||
echo "</tfoot>\n";
|
||||
echo "</table>\n";
|
||||
|
||||
form_add_button('task.php');
|
||||
|
||||
elseif ($action == ACT_ADD):
|
||||
// ========== VARIANT: add record =============================================
|
||||
|
||||
|
||||
echo '<h2>', _('Add Project'), "</h2>\n";
|
||||
?>
|
||||
<form method="post" action="<?=$g_scriptname?>">
|
||||
<div class="mb-3">
|
||||
<label for="projname" class="form-label"><?=_('Name')?></label>
|
||||
<input type="text" class="form-control" id="projname" name="projname">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="responsible" class="form-label"><?=_('Responsible')?></label>
|
||||
<select name="responsible" class="form-control">
|
||||
<?php
|
||||
foreach ($opt_user as $k => $v) {
|
||||
echo '<option value="', $k ,'">', $v, "</option>\n";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="remarks" class="form-label"><?=_('Remarks')?></label>
|
||||
<textarea class="form-control" id="remarks" name="remarks" rows="3"></textarea>
|
||||
</div>
|
||||
<button type="submit" name="submit[insert]" class="btn btn-primary"><?=_('Save')?></button>
|
||||
<a href="<?=$g_scriptname?>" class="btn btn-secondary"><?=_('Back')?></a>
|
||||
</form>
|
||||
<?php
|
||||
|
||||
elseif ($action == ACT_VIEW):
|
||||
// ========== VARIANT: view single record =====================================
|
||||
|
||||
$sql = "SELECT projname, startdate, duration, responsible, remarks "
|
||||
. "FROM project "
|
||||
. "WHERE projid=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$id]);
|
||||
$project = $sth->fetch(PDO::FETCH_OBJ);
|
||||
echo "<h2>", $project->projname, "</h2>\n";
|
||||
echo '<table class="table">', "\n";
|
||||
echo '<tr><th scope="row" style="width:20%">', _('Name'),"</th><td>", $project->projname, "</td></tr>\n";
|
||||
echo '<tr><th scope="row">', _('Responsible'),"</th><td>", $opt_user[$project->responsible], "</td></tr>\n";
|
||||
echo '<tr><th scope="row">', _('Start date'),"</th><td>", $project->startdate, "</td></tr>\n";
|
||||
echo '<tr><th scope="row">', _('Duration'),"</th><td>", $project->duration, "</td></tr>\n";
|
||||
echo '<tr><th scope="row">', _('Remarks'),"</th><td>", $project->remarks, "</td></tr>\n";
|
||||
echo "</table>\n";
|
||||
|
||||
form_view_buttons($g_scriptname, $id);
|
||||
|
||||
// assigned tasks
|
||||
echo "<h2>", _('Assigned tasks'), "</h2>\n";
|
||||
|
||||
$sql = "SELECT taskid, taskname FROM task WHERE projid=? ORDER BY taskname";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$id]);
|
||||
?>
|
||||
<table class="table table-sm">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?=_('Task')?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<?php foreach ($sth->fetchAll() as $row):?>
|
||||
<tr>
|
||||
<td><?=$row['taskname']?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</table>
|
||||
<?php
|
||||
form_add_button('task.php', $id, 'projid');
|
||||
|
||||
elseif ($action == ACT_EDIT):
|
||||
// ========== VARIANT: edit single record =====================================
|
||||
|
||||
echo '<h2>', _('Edit Project'), "</h2>\n";
|
||||
|
||||
$sql = "SELECT projname, responsible, startdate, duration, remarks "
|
||||
. "FROM project "
|
||||
. "WHERE projid=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$id]);
|
||||
$project = $sth->fetch(PDO::FETCH_OBJ);
|
||||
|
||||
?>
|
||||
<form method="post" action="<?=$g_scriptname?>">
|
||||
<input type="hidden" name="id" value="<?=$id?>">
|
||||
<div class="mb-3">
|
||||
<label for="projname" class="form-label"><?=_('Name')?></label>
|
||||
<input type="text" class="form-control" id="projname" name="projname" value="<?=$project->projname ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="responsible" class="form-label"><?=_('Responsible')?></label>
|
||||
<select name="responsible" class="form-control">
|
||||
<?php
|
||||
foreach ($opt_user as $k => $v) {
|
||||
echo '<option value="', $k ,'"';
|
||||
if ($project->responsible == $k) {
|
||||
echo ' selected';
|
||||
}
|
||||
echo '>', $v, "</option>\n";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="startdate"><?=_('Startdate')?></label>
|
||||
<input type="date" class="form-control" id="startdate" name="startdate" value="<?=$project->startdate ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="duration"><?=_('Duration, days')?></label>
|
||||
<input type="number" class="form-control" id="duration" name="duration" min="1" value="<?=$project->duration ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="remarks" class="form-label"><?=_('Remarks')?></label>
|
||||
<textarea class="form-control" id="remarks" name="remarks" rows="3"><?=$project->remarks ?></textarea>
|
||||
</div>
|
||||
<button type="submit" name="submit[update]" class="btn btn-primary"><?=_('Save')?></button>
|
||||
<a href="<?=$g_scriptname?>?f=view&id=<?=$id?>" class="btn btn-secondary"><?=_('Back')?></a>
|
||||
</form>
|
||||
<?php
|
||||
|
||||
elseif ($action == ACT_DELETE):
|
||||
// ========== VARIANT: delete record ==========================================
|
||||
|
||||
echo '<h2>', _('Delete Project'), "</h2>\n";
|
||||
|
||||
else:
|
||||
// ========== ERROR UNKNOWN VARIANT ===========================================
|
||||
|
||||
echo '<p>', _('Unknown function call: Please report to system development!'), "</p>\n";
|
||||
|
||||
endif; // $action == ...
|
||||
// ========== END OF VARIANTS =================================================
|
||||
|
||||
include 'footer.php';
|
||||
@@ -0,0 +1,238 @@
|
||||
<?php
|
||||
/******************************************************************************
|
||||
* YMS - Yacht Management Software
|
||||
* Copyright (C) 2024 Thomas Hooge
|
||||
*
|
||||
* SPDX-License-Identifier: WTFPL
|
||||
******************************************************************************/
|
||||
|
||||
require 'globals.inc';
|
||||
$pagetitle=_('Provisions');
|
||||
|
||||
$id = gpc_get_int($_REQUEST, 'id', 0);
|
||||
|
||||
$opt_storage = db_get_opt_storage($user->vid);
|
||||
$opt_catgory = db_get_options(5);
|
||||
$opt_unit = db_get_options(6);
|
||||
|
||||
// ========== 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 'insert':
|
||||
$p[':provname'] = gpc_get_string($_POST, 'provname');
|
||||
$p[':number'] = gpc_get_int($_POST, 'number');
|
||||
$p[':unit'] = gpc_get_int($_POST, 'unit');
|
||||
$p[':storedate'] = gpc_get_string($_POST, 'storedate');
|
||||
$p[':shelflife'] = gpc_get_string($_POST, 'shelflife');
|
||||
$keys = array_keys($p);
|
||||
$fields = join(',', array_map(function($s) { return ltrim($s, ':'); }, $keys));
|
||||
$pnames = join(',', $keys);
|
||||
$sth = $pdo->prepare("INSERT INTO provisions ($fields) VALUES ($pnames)");
|
||||
try {
|
||||
$sth->execute($p);
|
||||
} catch (PDOexception $e) {
|
||||
$g_error->Add('SQL-Error: '. $e->getMessage());
|
||||
}
|
||||
$id = $pdo->LastInsertId();
|
||||
$action = ACT_VIEW;
|
||||
break;
|
||||
|
||||
case 'update':
|
||||
$p[':provname'] = gpc_get_string($_POST, 'provname');
|
||||
$p[':number'] = gpc_get_int($_POST, 'number');
|
||||
$p[':unit'] = gpc_get_int($_POST, 'unit');
|
||||
$p[':storedate'] = gpc_get_string($_POST, 'storedate');
|
||||
$p[':shelflife'] = gpc_get_string($_POST, 'shelflife');
|
||||
$p[':sid'] = gpc_get_int($_POST, 'sid');
|
||||
$fields = join(',', array_map(function($s) { return ltrim($s, ':') . '=' . $s; }, array_keys($p)));
|
||||
$sth = $pdo->prepare("UPDATE provisions SET $fields WHERE provid=:provid");
|
||||
$p[':provid'] = $id;
|
||||
try {
|
||||
$sth->execute($p);
|
||||
} catch (PDOexception $e) {
|
||||
$g_error->Add('SQL-Error: '. $e->getMessage());
|
||||
}
|
||||
$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;
|
||||
}
|
||||
$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 =======================================
|
||||
|
||||
echo "<h1>", $pagetitle, "</h1>\n";
|
||||
|
||||
$sql = "SELECT provid, provname, number, unit, storedate, shelflife, "
|
||||
. " DATEDIFF(shelflife, storedate) AS d0, DATEDIFF (CURDATE(), storedate) AS d1 "
|
||||
. "FROM provisions "
|
||||
. "ORDER BY provid";
|
||||
$sth = $pdo->query($sql);
|
||||
$res = $sth->fetchAll();
|
||||
echo '<table class="table table-striped">', "\n";
|
||||
echo "<thead>\n";
|
||||
echo "<tr>\n";
|
||||
echo '<th>', _('Description'), "</th>";
|
||||
echo '<th>', _('Number'), "</th>";
|
||||
echo '<th>', _('Unit'), "</th>";
|
||||
echo '<th>', _('Stored'), "</th>";
|
||||
echo '<th>', _('Best before'), "</th>";
|
||||
echo "<th></th>";
|
||||
echo "<th></th>\n";
|
||||
echo "</tr>\n";
|
||||
echo "</thead>\n";
|
||||
foreach ($res as $row) {
|
||||
echo "<tr>\n";
|
||||
echo "<td>". $row['provname'] ."</td>\n";
|
||||
echo "<td>". $row['number'] ."</td>\n";
|
||||
echo "<td>". $opt_unit[$row['unit']] ."</td>\n";
|
||||
echo "<td>". $row['storedate'] ."</td>\n";
|
||||
echo "<td>". $row['shelflife'] ."</td>\n";
|
||||
echo "<td>";
|
||||
echo '<meter min="0" max="', $row['d0'], '" value="', $row['d1'], '">';
|
||||
// Action buttons
|
||||
form_action_buttons($g_scriptname, $row['provid']);
|
||||
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 provisions'), "</h2>\n";
|
||||
?>
|
||||
<form method="post">
|
||||
<div class="mb-3">
|
||||
<label for="provname" class="form-label"><?=_('Name')?></label>
|
||||
<input type="text" class="form-control" id="provname" name="provname" required autofocus>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="number"><?=_('Number')?></label>
|
||||
<input type="number" min="0" max="1000" class="form-control" id="number" name="number" value="1">
|
||||
</div>
|
||||
<?php form_create_select('unit', _('Unit'), $opt_unit); ?>
|
||||
<div class="mb-3">
|
||||
<label for="storedate"><?=_('Storedate')?></label>
|
||||
<input type="date" class="form-control" id="storedate" name="storedate" value="<?php echo date('Y-m-d'); ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="shelflife"><?=_('Shelflife')?></label>
|
||||
<input type="date" class="form-control" id="shelflife" name="shelflife">
|
||||
</div>
|
||||
<?php form_create_select('sid', _('Storage'), $opt_storage); ?>
|
||||
<div class="container-fluid px-0 my-3">
|
||||
<button type="submit" name="submit[insert]" class="btn btn-primary"><?=_('Save')?></button>
|
||||
<a href="<?=$g_scriptname?>" class="btn btn-secondary"><?=_('Back')?></a>
|
||||
</div>
|
||||
</form>
|
||||
<?php
|
||||
|
||||
elseif ($action == ACT_VIEW):
|
||||
// ========== VARIANT: view single record =====================================
|
||||
|
||||
$sql = "SELECT provname, number, unit, storedate, shelflife, sid "
|
||||
. "FROM provisions "
|
||||
. "WHERE provid=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$id]);
|
||||
$prov = $sth->fetch(PDO::FETCH_OBJ);
|
||||
|
||||
echo '<h2>', $prov->provname, "</h2>\n";
|
||||
|
||||
echo '<table class="table">', "\n";
|
||||
echo '<tr><th style="width:20%">', _('Number'),"</th><td>", $prov->number, "</td></tr>\n";
|
||||
echo '<tr><th>', _('Unit'),"</th><td>", $opt_unit[$prov->unit], "</td></tr>\n";
|
||||
echo '<tr><th>', _('Storedate'),"</th><td>", $prov->storedate, "</td></tr>\n";
|
||||
echo '<tr><th>', _('Shelflife'),"</th><td>", $prov->shelflife, "</td></tr>\n";
|
||||
echo '<tr><th>', _('Storage'),"</th><td>", $opt_storage[$prov->sid], "</td></tr>\n";
|
||||
echo "</table>\n";
|
||||
|
||||
form_view_buttons($g_scriptname, $id);
|
||||
|
||||
elseif ($action == ACT_EDIT):
|
||||
// ========== VARIANT: edit single record =====================================
|
||||
|
||||
$sql = "SELECT provname, number, unit, storedate, shelflife, sid "
|
||||
. "FROM provisions "
|
||||
. "WHERE provid=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$id]);
|
||||
$prov = $sth->fetch(PDO::FETCH_OBJ);
|
||||
|
||||
echo '<h2>', _('Edit provision'), "</h2>\n";
|
||||
?>
|
||||
<form method="post">
|
||||
<input type="hidden" name="id" value="<?=$id?>">
|
||||
<div class="mb-3">
|
||||
<label for="provname" class="form-label"><?=_('Name')?></label>
|
||||
<input type="text" class="form-control" id="provname" name="provname" value="<?=$prov->provname ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="number"><?=_('Number')?></label>
|
||||
<input type="number" min="0" max="1000" class="form-control" id="number" name="number" value="<?=$prov->number ?>">
|
||||
</div>
|
||||
<?php form_create_select('unit', _('Unit'), $opt_unit, $prov->unit); ?>
|
||||
<div class="mb-3">
|
||||
<label for="storedate"><?=_('Storedate')?></label>
|
||||
<input type="date" class="form-control" id="storedate" name="storedate" value="<?=$prov->storedate ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="shelflife"><?=_('Shelflife')?></label>
|
||||
<input type="date" class="form-control" id="shelflife" name="shelflife" value="<?=$prov->shelflife ?>">
|
||||
</div>
|
||||
<?php
|
||||
form_create_select('sid', _('Storage'), $opt_storage, $prov->sid);
|
||||
|
||||
form_edit_buttons($g_scriptname, $id);
|
||||
echo "</form>\n";
|
||||
|
||||
|
||||
elseif ($action == ACT_DELETE):
|
||||
// ========== VARIANT: delete record ==========================================
|
||||
|
||||
echo '<h2>', _('Delete provisions'), "</h2>\n";
|
||||
|
||||
else:
|
||||
// ========== ERROR UNKNOWN VARIANT ===========================================
|
||||
|
||||
echo '<p>', _('Unknown function call: Please report to system development!'), "</p>\n";
|
||||
|
||||
endif; // $action == ...
|
||||
// ========== END OF VARIANTS =================================================
|
||||
|
||||
include 'footer.php';
|
||||
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 122 KiB |
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
/******************************************************************************
|
||||
* YMS - Yacht Management Software
|
||||
* Copyright (C) 2024 Thomas Hooge
|
||||
*
|
||||
* SPDX-License-Identifier: WTFPL
|
||||
******************************************************************************/
|
||||
|
||||
require 'globals.inc';
|
||||
$pagetitle = _('Search');
|
||||
|
||||
$needle = gpc_get_string($_REQUEST, 'needle', 40);
|
||||
|
||||
require 'header.php';
|
||||
|
||||
echo "<h1>$pagetitle</h1>\n";
|
||||
?>
|
||||
|
||||
<p>Search will be implemented later.
|
||||
This page is currently just a placeholder.</p>
|
||||
|
||||
<form method="post">
|
||||
<div>
|
||||
<label for="needle">Suche nach:</label>
|
||||
<input type="text" id="needle" name="needle" value="<?=$needle?>" autofocus>
|
||||
</div>
|
||||
<div>
|
||||
<input type="checkbox" id="remarks" name="ck_remarks">
|
||||
<label for="remarks">Bemerkungsfelder Berücksichtigen</label>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary" name="submit[search]"><?=_('Search')?></button>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
|
||||
if (isset($needle)) {
|
||||
$sqlneedle = '%'.$needle.'%';
|
||||
}
|
||||
|
||||
include 'footer.php';
|
||||
@@ -0,0 +1,325 @@
|
||||
<?php
|
||||
/******************************************************************************
|
||||
* YMS - Yacht Management Software
|
||||
* Copyright (C) 2024 Thomas Hooge
|
||||
*
|
||||
* SPDX-License-Identifier: WTFPL
|
||||
******************************************************************************/
|
||||
|
||||
require 'globals.inc';
|
||||
$pagetitle = _('Storage');
|
||||
|
||||
$id = gpc_get_int($_REQUEST, 'id', 0);
|
||||
|
||||
$stype = db_get_options(3);
|
||||
|
||||
// ========== 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 'insert':
|
||||
$sname = gpc_get_string($_POST, 'sname');
|
||||
$stype = gpc_get_int($_POST, 'stype');
|
||||
$sql = "INSERT INTO storage "
|
||||
. " (vid, sname, stype) "
|
||||
. "VALUES "
|
||||
. " (:vid, :sname, :stype)";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->bindValue(':vid', $user->vid, PDO::PARAM_INT);
|
||||
$sth->bindValue(':sname', $sname, PDO::PARAM_STR);
|
||||
$sth->bindValue(':stype', $stype, PDO::PARAM_INT);
|
||||
$sth->execute();
|
||||
$id = $pdo->lastInsertId();
|
||||
$action = ACT_VIEW;
|
||||
break;
|
||||
|
||||
case 'update':
|
||||
$sname = gpc_get_string($_POST, 'sname');
|
||||
$x = gpc_get_int($_POST, 'x');
|
||||
$y = gpc_get_int($_POST, 'y');
|
||||
$z = gpc_get_int($_POST, 'z');
|
||||
$remarks = gpc_get_string($_POST, 'remarks', 150);
|
||||
$sql = "UPDATE storage "
|
||||
. "SET sname=:sname,"
|
||||
. " x=:x, y=:y, z=:z,"
|
||||
. " remarks=:remarks "
|
||||
. "WHERE sid=:sid";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->bindValue(':sid', $id, PDO::PARAM_INT);
|
||||
$sth->bindValue(':sname', $sname, PDO::PARAM_STR);
|
||||
$sth->bindValue(':x', $x, PDO::PARAM_INT);
|
||||
$sth->bindValue(':y', $y, PDO::PARAM_INT);
|
||||
$sth->bindValue(':z', $z, PDO::PARAM_INT);
|
||||
$sth->bindValue(':remarks', $remarks, PDO::PARAM_STR);
|
||||
$sth->execute();
|
||||
$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;
|
||||
}
|
||||
unset($_SESSION['token']);
|
||||
// check if storage is empty
|
||||
// - no assigned boxes
|
||||
$sth = $pdo->prepare("SELECT COUNT(*) FROM box WHERE sid=?");
|
||||
$sth->execute([$id]);
|
||||
if ($sth->fetchColumn() > 0) {
|
||||
$g_error->Add(_('Delete failed, assigned boxes detected!'));
|
||||
$action = ACT_VIEW;
|
||||
break;
|
||||
}
|
||||
// - no assigned equipment
|
||||
$sth = $pdo->prepare("SELECT COUNT(*) FROM inventory WHERE boxtype='storage' AND sid=?");
|
||||
$sth->execute([$id]);
|
||||
if ($sth->fetchColumn() > 0) {
|
||||
$g_error->Add(_('Delete failed, assigned equipment detected!'));
|
||||
$action = ACT_VIEW;
|
||||
break;
|
||||
}
|
||||
$sth = $pdo->prepare("DELETE FROM storage WHERE sid=?");
|
||||
$sth->execute([$id]);
|
||||
$g_message->Add(sprintf(_('Deleted storage no. %d'), $id));
|
||||
$action = ACT_DEFAULT;
|
||||
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";
|
||||
|
||||
// Storage
|
||||
// stype from dropdown
|
||||
$sql = "SELECT sid, sname, remarks "
|
||||
. "FROM storage "
|
||||
. "WHERE vid=? "
|
||||
. "ORDER BY sid";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$user->vid]);
|
||||
$res = $sth->fetchAll();
|
||||
echo '<table class="table table-striped">', "\n";
|
||||
echo "<thead>\n";
|
||||
echo "<tr>";
|
||||
echo "<th>" . _('Name') . "</th>";
|
||||
echo "<th>" . _('Remarks') . "</th>";
|
||||
echo "<th> </th>";
|
||||
echo "</tr>\n";
|
||||
echo "</thead>\n";
|
||||
foreach ($res as $row) {
|
||||
echo "<tr>\n";
|
||||
echo "<td>". $row['sname'] ."</td>\n";
|
||||
echo "<td>". $row['remarks'] ."</td>\n";
|
||||
form_action_buttons($g_scriptname, $row['sid']);
|
||||
echo "</tr>\n";
|
||||
}
|
||||
echo "<tfoot>\n";
|
||||
echo '<tr><td colspan="3">', sprintf(_('%d records'), count($res)), '</td></tr>', "\n";
|
||||
echo "</tfoot>\n";
|
||||
echo "</table>\n";
|
||||
|
||||
form_add_button($g_scriptname);
|
||||
|
||||
// Boxes
|
||||
echo "<h1>", _('Box'), "</h1>\n";
|
||||
$sql = "SELECT boxid, sid, label, color, content, remarks "
|
||||
. "FROM box "
|
||||
. "ORDER BY label";
|
||||
$sth = $pdo->query($sql);
|
||||
$res = $sth->fetchAll();
|
||||
echo '<table class="table table-striped">', "\n";
|
||||
echo "<thead>\n";
|
||||
echo "<tr>";
|
||||
echo "<th>" . _('Label') . "</th>";
|
||||
echo "<th>" . _('Color') . "</th>";
|
||||
echo "<th>" . _('Content') . "</th>";
|
||||
echo "<td></td>";
|
||||
echo "</tr>\n";
|
||||
foreach ($res as $row) {
|
||||
echo "<tr>\n";
|
||||
echo "<td>". $row['label'] ."</td>\n";
|
||||
echo '<td><span style="background-color:#', $row['color'],'">'. $row['color'] ."</span></td>\n";
|
||||
echo "<td>". $row['content'] ."</td>\n";
|
||||
form_action_buttons('box.php', $row['boxid']);
|
||||
echo "</tr>\n";
|
||||
}
|
||||
// Table summary
|
||||
echo "<tfoot>\n";
|
||||
echo '<tr><td colspan="4">', sprintf(_('%d records'), count($res)), '</td></tr>', "\n";
|
||||
echo "</tfoot>\n";
|
||||
echo "</table>\n";
|
||||
|
||||
form_add_button('box.php');
|
||||
|
||||
elseif ($action == ACT_ADD):
|
||||
// ========== VARIANT: add record =============================================
|
||||
|
||||
echo '<h2>', _('Add Storage'), "</h2>\n";
|
||||
|
||||
?>
|
||||
|
||||
<form method="post">
|
||||
<div class="mb-3">
|
||||
<label for="sname" class="form-label"><?=_('Name')?></label>
|
||||
<input type="text" class="form-control" id="sname" name="sname">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<select name="stype" class="form-control">
|
||||
<?php
|
||||
foreach ($stype as $k => $v) {
|
||||
echo '<option value="', $k ,'">', $v, "</option>\n";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
</div>
|
||||
<button type="submit" name="submit[insert]" class="btn btn-primary"><?=_('Save')?></button>
|
||||
<a href="<?=$g_scriptname?>" class="btn btn-secondary"><?=_('Back')?></a>
|
||||
</form>
|
||||
|
||||
|
||||
<?php
|
||||
|
||||
elseif ($action == ACT_VIEW):
|
||||
// ========== VARIANT: view single record =====================================
|
||||
|
||||
$opt_unit = db_get_options(6);
|
||||
$sql = "SELECT sid, sname, stype, capacity, capaunit, x, y, z, remarks "
|
||||
. "FROM storage "
|
||||
. "WHERE sid=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$id]);
|
||||
$storage = $sth->fetch(PDO::FETCH_OBJ);
|
||||
echo '<h2>', $storage->sname, "</h2>\n";
|
||||
|
||||
echo '<table class="table">', "\n";
|
||||
echo '<tr><th style="width:20%">', _('Typ'),"</th><td>", $stype[$storage->stype], "</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>', _('Remarks'),"</th><td>", $storage->remarks, "</td></tr>\n";
|
||||
echo "</table>\n";
|
||||
|
||||
form_view_buttons($g_scriptname, $id);
|
||||
|
||||
// Zugeordnete Kisten hier anzeigen
|
||||
echo '<h3>', _('Boxes in storage'), "</h3>\n";
|
||||
|
||||
$sql = "SELECT boxid, label, color FROM box WHERE sid=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$id]);
|
||||
$res = $sth->fetchall();
|
||||
if (count($res) > 0) {
|
||||
foreach ($res as $row) {
|
||||
echo "$boxid $label $color";
|
||||
}
|
||||
} else {
|
||||
echo '<p>', _('No boxes contained'), "</p>\n";
|
||||
}
|
||||
|
||||
echo '<h3>', _('Provisions in storage'), "</h3>\n";
|
||||
|
||||
$sql = "SELECT provid, provname, number, unit, storedate, shelflife FROM provisions WHERE sid=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$id]);
|
||||
$res = $sth->fetchall();
|
||||
if (count($res) > 0) {
|
||||
echo '<table class="table table-sm">';
|
||||
foreach ($res as $row) {
|
||||
echo "<tr>";
|
||||
echo "<td>", $row['provname'], "</td>";
|
||||
echo "<td>", $row['number'], ' ', $opt_unit[$row['unit']], "</td>";
|
||||
echo "<td>", $row['storedate'], ' - ', $row['shelflife'], "</td>";
|
||||
echo "</tr>\n";
|
||||
}
|
||||
echo "</table>\n";
|
||||
} else {
|
||||
echo '<p>', _('No provisions contained'), "</p>\n";
|
||||
}
|
||||
|
||||
elseif ($action == ACT_EDIT):
|
||||
// ========== VARIANT: edit single record =====================================
|
||||
|
||||
echo '<h2>', _('Edit Storage'), "</h2>\n";
|
||||
|
||||
$sql = "SELECT sid, sname, stype, remarks "
|
||||
. "FROM storage "
|
||||
. "WHERE sid=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$id]);
|
||||
$storage = $sth->fetch(PDO::FETCH_OBJ);
|
||||
|
||||
?>
|
||||
<form method="post" action="<?=$g_scriptname?>">
|
||||
<input type="hidden" name="id" value="<?=$id?>">
|
||||
<div class="mb-3">
|
||||
<label for="sname" class="form-label"><?=_('Name')?></label>
|
||||
<input type="text" class="form-control" id="sname" name="sname" value="<?=$storage->sname ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="x" class="form-label"><?=_('Position x')?></label>
|
||||
<input type="number" class="form-control" id="x" name="x" value="<?=$storage->x ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="y" class="form-label"><?=_('Position y')?></label>
|
||||
<input type="number" class="form-control" id="y" name="y" value="<?=$storage->y ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="z" class="form-label"><?=_('Position z')?></label>
|
||||
<input type="number" class="form-control" id="z" name="z" value="<?=$storage->z ?>">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="remarks" class="form-label"><?=_('Remarks')?></label>
|
||||
<textarea class="form-control" id="remarks" name="remarks" rows="3"><?=$storage->remarks ?></textarea>
|
||||
</div>
|
||||
<button type="submit" name="submit[update]" class="btn btn-primary"><?=_('Save')?></button>
|
||||
<a href="<?=$g_scriptname?>?f=view&id=<?=$id?>" class="btn btn-secondary"><?=_('Back')?></a>
|
||||
</form>
|
||||
<?php
|
||||
|
||||
elseif ($action == ACT_DELETE):
|
||||
// ========== VARIANT: delete record ==========================================
|
||||
|
||||
$_SESSION['token'] = bin2hex(random_bytes(8));
|
||||
$sql = "SELECT sname, remarks FROM storage WHERE sid=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$id]);
|
||||
$storage = $sth->fetch(PDO::FETCH_OBJ);
|
||||
|
||||
echo '<h2>', _('Delete Storage'), "</h2>\n";
|
||||
|
||||
echo '<p>', sprintf(_('Record no. %d'), $id), "</p>\n";
|
||||
echo '<p>Name: ', $storage->sname, "</p>";
|
||||
echo '<p>Remarks: ', $storage->remarks, "</p>";
|
||||
|
||||
echo '<p>', _('Deleting a storage is final. There is no way back. Only delete if you are absolute sure.'), "</p>\n";
|
||||
|
||||
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';
|
||||
+192
@@ -0,0 +1,192 @@
|
||||
<?php
|
||||
/******************************************************************************
|
||||
* YMS - Yacht Management Software
|
||||
* Copyright (C) 2024 Thomas Hooge
|
||||
*
|
||||
* SPDX-License-Identifier: WTFPL
|
||||
******************************************************************************/
|
||||
|
||||
require 'globals.inc';
|
||||
$pagetitle = _('Task');
|
||||
|
||||
$id = gpc_get_int($_REQUEST, 'id', 0);
|
||||
|
||||
$opt_projects = db_get_opt_proj($user->vid, array(-1 => _('unassigned')));
|
||||
|
||||
// ========== 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 'insert':
|
||||
$p[':projid'] = gpc_get_int($_POST, 'projid');
|
||||
if ($p[':projid'] == -1) {
|
||||
$p[':projid'] = NULL;
|
||||
}
|
||||
$p[':taskname'] = gpc_get_string($_POST, 'taskname');
|
||||
$keys = array_keys($p);
|
||||
$fields = join(',', array_map(function($s) { return ltrim($s, ':'); }, $keys));
|
||||
$pnames = join(',', $keys);
|
||||
$sth = $pdo->prepare("INSERT INTO task ($fields) VALUES ($pnames)");
|
||||
try {
|
||||
$sth->execute($p);
|
||||
} catch (PDOexception $e) {
|
||||
$g_error->Add('SQL-Error: '. $e->getMessage());
|
||||
}
|
||||
break;
|
||||
|
||||
case 'update':
|
||||
$p[':taskname'] = gpc_get_string($_POST, 'taskname');
|
||||
$p[':projid'] = gpc_get_int($_POST, 'projid');
|
||||
if ($p[':projid'] == -1) {
|
||||
$p[':projid'] = NULL;
|
||||
}
|
||||
$fields = join(',', array_map(function($s) { return ltrim($s, ':') . '=' . $s; }, array_keys($p)));
|
||||
$sth = $pdo->prepare("UPDATE task SET $fields WHERE taskid=:taskid");
|
||||
$p[':taskid'] = $id;
|
||||
try {
|
||||
$sth->execute($p);
|
||||
} catch (PDOexception $e) {
|
||||
$g_error->Add('SQL-Error: '. $e->getMessage());
|
||||
}
|
||||
$action = ACT_VIEW;
|
||||
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";
|
||||
|
||||
$sql = "SELECT t.taskid, t.projid, t.taskname, p.projname "
|
||||
. "FROM task AS t LEFT JOIN project AS p USING (projid) "
|
||||
. "WHERE p.projid IS NULL OR p.vid=? "
|
||||
. "ORDER BY t.taskid";
|
||||
$sth = $pdo->prepare($sql);
|
||||
try {
|
||||
$sth->execute([$user->vid]);
|
||||
} catch (PDOexception $e) {
|
||||
$g_error->Add('SQL-Error: '. $e->getMessage());
|
||||
}
|
||||
$res = $sth->fetchAll();
|
||||
|
||||
echo '<table class="table table-striped">', "\n";
|
||||
echo "<thead>\n";
|
||||
echo "<tr>\n";
|
||||
echo '<th>#</th>';
|
||||
echo '<th>', _('Task'), "</th>";
|
||||
echo '<th>', _('Project'), "</th>";
|
||||
echo "<th></th>";
|
||||
echo "<th></th>\n";
|
||||
echo "</tr>\n";
|
||||
echo "</thead>\n";
|
||||
foreach ($res as $row) {
|
||||
echo "<tr>\n";
|
||||
echo "<td>" . $row['taskid'] . "</td>\n";
|
||||
echo "<td>" . $row['taskname'] . "</td>\n";
|
||||
echo "<td>" . $row['projname'] . "</td>\n";
|
||||
// Action buttons
|
||||
form_action_buttons($g_scriptname, $row['taskid']);
|
||||
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";
|
||||
|
||||
elseif ($action == ACT_ADD):
|
||||
// ========== VARIANT: add record =============================================
|
||||
|
||||
echo '<h2>', _('Add Task'), "</h2>\n";
|
||||
?>
|
||||
<form method="post">
|
||||
<?php
|
||||
// preselect project if parameter is set
|
||||
$projid = gpc_get_int($_REQUEST, 'projid');
|
||||
form_create_select('projid', _('Project'), $opt_projects, $projid);
|
||||
?>
|
||||
<div class="mb-3">
|
||||
<label for="taskname" class="form-label"><?=_('Task')?></label>
|
||||
<input type="text" class="form-control" id="taskname" name="taskname" required autofocus>
|
||||
</div>
|
||||
<div class="container-fluid px-0 my-3">
|
||||
<button type="submit" name="submit[insert]" class="btn btn-primary"><?=_('Save')?></button>
|
||||
<a href="<?=$g_scriptname?>" class="btn btn-secondary"><?=_('Back')?></a>
|
||||
</div>
|
||||
</form>
|
||||
<?php
|
||||
|
||||
elseif ($action == ACT_VIEW):
|
||||
// ========== VARIANT: view single record =====================================
|
||||
|
||||
$sql = "SELECT t.taskname, p.projname "
|
||||
. "FROM task AS t LEFT JOIN project AS p USING (projid) "
|
||||
. "WHERE taskid=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$id]);
|
||||
$task = $sth->fetch(PDO::FETCH_OBJ);
|
||||
|
||||
echo '<h2>', _('View Task'), "</h2>\n";
|
||||
echo '<table class="table">', "\n";
|
||||
echo '<tr><th>', _('Task'),"</th><td>", $task->taskname, "</td></tr>\n";
|
||||
echo '<tr><th>', _('Project'),"</th><td>", $task->projname ?? _('unassigned'), "</td></tr>\n";
|
||||
echo "</table>\n";
|
||||
|
||||
form_view_buttons($g_scriptname, $id);
|
||||
|
||||
elseif ($action == ACT_EDIT):
|
||||
// ========== VARIANT: edit single record =====================================
|
||||
|
||||
$sql = "SELECT taskname "
|
||||
. "FROM task "
|
||||
. "WHERE taskid=?";
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([$id]);
|
||||
$task = $sth->fetch(PDO::FETCH_OBJ);
|
||||
|
||||
echo '<h2>', _('Edit Task'), "</h2>\n";
|
||||
|
||||
?>
|
||||
<form method="post">
|
||||
<input type="hidden" name="id" value="<?=$id?>">
|
||||
<div class="mb-3">
|
||||
<label for="taskname" class="form-label"><?=_('Name')?></label>
|
||||
<input type="text" class="form-control" id="taskname" name="taskname" value="<?=$task->taskname ?>">
|
||||
</div>
|
||||
<?php
|
||||
form_create_select('projid', _('Project'), $opt_projects);
|
||||
form_edit_buttons($g_scriptname, $id);
|
||||
echo "</form>\n";
|
||||
|
||||
elseif ($action == ACT_DELETE):
|
||||
// ========== VARIANT: delete record ==========================================
|
||||
|
||||
echo '<h2>', _('Delete Task'), "</h2>\n";
|
||||
|
||||
else:
|
||||
// ========== ERROR UNKNOWN VARIANT ===========================================
|
||||
|
||||
echo '<p>', _('Unknown function call: Please report to system development!'), "</p>\n";
|
||||
|
||||
endif; // $action == ...
|
||||
// ========== END OF VARIANTS =================================================
|
||||
|
||||
include 'footer.php';
|
||||
Reference in New Issue
Block a user