load("scrap");
if (!$user->rights->scrap->read) accessforbidden();
$action = GETPOST('action', 'alpha');
$id = (int) GETPOST('id', 'int');
/* ---------------------------------------------------------------------
DELETE SCRAP + RESTORE STOCK
--------------------------------------------------------------------- */
if ($action === 'delete' && $id > 0) {
$token = GETPOST('token', 'alpha');
if (empty($token) || $token !== $_SESSION['newtoken']) accessforbidden('Invalid CSRF token');
$sqlCheck = "SELECT
s.rowid,
s.fk_product,
s.fk_warehouse,
s.qty,
s.cost,
s.reason,
p.ref AS product_ref,
p.label AS product_label
FROM " . MAIN_DB_PREFIX . "scrap s
LEFT JOIN " . MAIN_DB_PREFIX . "product p ON s.fk_product = p.rowid
WHERE s.rowid = " . ((int)$id);
$resCheck = $db->query($sqlCheck);
$objCheck = $db->fetch_object($resCheck);
if ($objCheck) {
$db->begin();
$movement = new MouvementStock($db);
$movement->origin_type = 'scrap';
$movement->origin_id = $id;
$movement->setOrigin('scrap', $id);
// $desc = $langs->trans('ScrapDeletedAndStockRestored') . ' (' . $objCheck->product_ref . ' - ' . $objCheck->product_label . ')';
$userInitials = strtoupper(substr($user->firstname, 0, 1) . substr($user->lastname, 0, 1));
$dateStr = dol_print_date(dol_now(), 'dayhour');
$qtyStr = (fmod($objCheck->qty, 1) == 0) ? intval($objCheck->qty) : number_format($objCheck->qty, 2);
$totalCost = price2num($objCheck->cost * $objCheck->qty, 'MU');
$desc = sprintf(
"ScrapDeletedAndStockRestored: %s | Product: %s - %s | Qty Restored: %s | UnitCost: %s | TotalCost: %s | Reason: %s | By: %s",
$dateStr,
$objCheck->product_ref,
$objCheck->product_label,
$qtyStr,
price2num($objCheck->cost, 'MU'),
$totalCost,
(!empty($objCheck->reason) ? $objCheck->reason : 'N/A'),
$userInitials
);
$result = $movement->reception(
$user,
(int)$objCheck->fk_product,
(int)$objCheck->fk_warehouse,
abs((float)$objCheck->qty),
(float)$objCheck->cost,
$desc
);
if ($result > 0) {
// โ
Delete scrap record
$db->query("DELETE FROM " . MAIN_DB_PREFIX . "scrap WHERE rowid = " . ((int)$id));
$db->commit();
// ๐ฐ Compute total cost (qty ร unit cost)
$total_cost = (float)$objCheck->qty * (float)$objCheck->cost;
// ๐งฉ Load product & warehouse details
require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
require_once DOL_DOCUMENT_ROOT . '/product/stock/class/entrepot.class.php';
$product = new Product($db);
$warehouse = new Entrepot($db);
$product->fetch($objCheck->fk_product);
$warehouse->fetch($objCheck->fk_warehouse);
// ๐งพ Detailed confirmation message
setEventMessages(
$langs->trans("ScrapDeletedAndStockRestored") . "
" .
$langs->trans("Product") . ": " . dol_escape_htmltag($product->ref . " - " . $product->label) . "
" .
$langs->trans("Warehouse") . ": " . dol_escape_htmltag($warehouse->ref) . "
" .
$langs->trans("Qty") . ": " . number_format($objCheck->qty, 0) . "
" .
$langs->trans("Unit Cost") . ": " . price($objCheck->cost, 0, $langs, 0, 0, -1) . "
" .
$langs->trans("Total Cost") . ": " . price($total_cost, 0, $langs, 0, 0, -1) . "
" .
$langs->trans("Reason") . ": " . (!empty($objCheck->reason) ? dol_escape_htmltag($objCheck->reason) : $langs->trans("NoReasonProvided")),
null,
'mesgs'
);
} else {
$db->rollback();
// โ Detailed error message
$total_cost = (float)$objCheck->qty * (float)$objCheck->cost;
setEventMessages(
$langs->trans("StockRestoreFailed") . "
" .
$langs->trans("Product") . ": " . dol_escape_htmltag($product->ref . " - " . $product->label) . "
" .
$langs->trans("Qty") . ": " . number_format($objCheck->qty, 0) . "
" .
$langs->trans("Unit Cost") . ": " . price($objCheck->cost, 0, $langs, 0, 0, -1) . "
" .
$langs->trans("Total Cost") . ": " . price($total_cost, 0, $langs, 0, 0, -1) . "
" .
$langs->trans("Error") . ": " . dol_escape_htmltag($movement->error),
null,
'errors'
);
}
} else {
setEventMessages($langs->trans("ScrapNotFound"), null, 'errors');
}
}
/* ---------------------------------------------------------------------
SEARCH + PAGINATION
--------------------------------------------------------------------- */
$search = trim(GETPOST('search', 'alpha'));
$page = max(0, (int) GETPOST('page', 'int'));
$limit = 20;
$offset = $page * $limit;
$sql = "SELECT s.rowid, s.qty, s.cost, s.reason, s.scrap_date,
p.rowid as prod_id, p.ref as product_ref, p.label as product_label,
e.ref as warehouse_ref,
u.firstname, u.lastname
FROM " . MAIN_DB_PREFIX . "scrap s
LEFT JOIN " . MAIN_DB_PREFIX . "product p ON s.fk_product = p.rowid
LEFT JOIN " . MAIN_DB_PREFIX . "entrepot e ON s.fk_warehouse = e.rowid
LEFT JOIN " . MAIN_DB_PREFIX . "user u ON s.fk_user_scrap = u.rowid
WHERE s.entity = " . ((int)$conf->entity);
if ($search) {
$sql .= " AND (p.ref LIKE '%" . $db->escape($search) . "%'
OR p.label LIKE '%" . $db->escape($search) . "%'
OR s.reason LIKE '%" . $db->escape($search) . "%')";
}
$sql .= " ORDER BY s.scrap_date DESC LIMIT $limit OFFSET $offset";
$resql = $db->query($sql);
llxHeader('', $langs->trans("ScrapManagement"));
print load_fiche_titre($langs->trans("ScrapManagement"));
/* ---------------------------------------------------------------------
ACTION BUTTONS BAR
--------------------------------------------------------------------- */
print '
| ' . $langs->trans('Product') . ' | '; print '' . $langs->trans('Warehouse') . ' | '; print '' . $langs->trans('Qty') . ' | '; print '' . $langs->trans('Unit Cost') . ' | '; print '' . $langs->trans('Total Cost') . ' | '; print '' . $langs->trans('Reason') . ' | '; print '' . $langs->trans("Date") . ' | '; print '' . $langs->trans("AddedBy") . ' | '; print '' . $langs->trans("Events") . ' | '; print '
|---|---|---|---|---|---|---|---|---|
| ' . dol_escape_htmltag($obj->product_ref) . ' | '; print '' . dol_escape_htmltag($obj->warehouse_ref) . ' | '; print '' . $qtyDisplay . ' | '; print '' . price($obj->cost, 0, $langs, 0, 0, 0, $conf->currency) . ' | '; $totalCost = price2num($obj->qty * $obj->cost, 'MU'); print '' . price($totalCost, 0, $langs, 0, 0, 0, $conf->currency) . ' | '; print '' . dol_escape_htmltag($obj->reason) . ' | '; print '' . dol_print_date(dol_stringtotime($obj->scrap_date), 'dayhour') . ' | '; print '' . $userInitials . ' | '; print '' . $langs->trans("Delete") . ' | '; print '
| ' . $langs->trans("NoScrapFound") . ' | ||||||||
| ' . $langs->trans('Total Cost') . ' | '; print '' . price($sumTotalCost, 0, $langs, 0, 0, 0, $conf->currency) . ' | '; print ''; print ' | ||||||