354 lines
12 KiB
PHP
354 lines
12 KiB
PHP
<?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';
|