added matrici to orders
This commit is contained in:
@@ -332,6 +332,21 @@ class MagoProduction
|
||||
return rtrim(rtrim(number_format((float)$v, 3, ',', '.'), '0'), ',');
|
||||
}
|
||||
|
||||
/** Riconosce la matrice di un valore Matrice/Misura (indice caricato una volta per richiesta). [idmatrice|null, match_status, match_info] */
|
||||
public static function lookup(PDO $pdo, $raw)
|
||||
{
|
||||
static $idx = null;
|
||||
if ($idx === null) {
|
||||
try {
|
||||
$idx = self::matriceIndex($pdo);
|
||||
} catch (Throwable $e) {
|
||||
$idx = ['exact' => [], 'base' => [], 'num' => [], 'map' => []];
|
||||
}
|
||||
}
|
||||
[$id, $ms, $mi] = self::resolve($idx, $raw);
|
||||
return [$id, $ms, $mi];
|
||||
}
|
||||
|
||||
private static function dt($v)
|
||||
{
|
||||
return $v ? date('d/m/Y', strtotime($v)) : '—';
|
||||
|
||||
@@ -226,19 +226,98 @@ if ($action === 'order') {
|
||||
$raw = json_decode((string)$o['raw_json'], true) ?: [];
|
||||
unset($o['raw_json']);
|
||||
|
||||
$stL = $pdo->prepare("
|
||||
SELECT d.line, d.item, d.description, d.uom, d.qty, d.delivered_qty, d.invoiced_qty, d.unit_value,
|
||||
GREATEST(d.qty - d.delivered_qty, 0) AS residual_qty,
|
||||
d.taxable_amount, d.delivered, d.invoiced, d.cancelled, d.notes,
|
||||
" . MagoSalesStats::ziboDate('d') . " AS zibo_date,
|
||||
" . MagoSalesStats::clientDate('d') . " AS client_date
|
||||
FROM mago_sale_ord_detail d
|
||||
WHERE d.sale_ord_id = ?
|
||||
ORDER BY d.position, d.line, d.sub_id
|
||||
");
|
||||
// righe + (se presenti) matrice, coda "Nuovi da Mago" e lavoro di produzione collegato
|
||||
$has = function ($t) use ($pdo) {
|
||||
$q = $pdo->prepare("SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?");
|
||||
$q->execute([$t]);
|
||||
return (bool)$q->fetchColumn();
|
||||
};
|
||||
$colQ = $pdo->prepare("SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'mago_sale_ord_detail' AND COLUMN_NAME = 'matrice_misura'");
|
||||
$colQ->execute();
|
||||
$hasMM = (bool)$colQ->fetchColumn();
|
||||
$hasQ = $hasMM && $has('mago_prod_queue') && $has('productiondata');
|
||||
|
||||
$sel = "d.sub_id, d.line, d.item, d.description, d.uom, d.qty, d.delivered_qty, d.invoiced_qty, d.unit_value,
|
||||
GREATEST(d.qty - d.delivered_qty, 0) AS residual_qty,
|
||||
d.taxable_amount, d.delivered, d.invoiced, d.cancelled, d.notes,
|
||||
" . MagoSalesStats::ziboDate('d') . " AS zibo_date,
|
||||
" . MagoSalesStats::clientDate('d') . " AS client_date";
|
||||
$join = '';
|
||||
if ($hasMM) $sel .= ", d.matrice_misura, d.cod_art_cli";
|
||||
if ($hasQ) {
|
||||
$sel .= ", q.queue_status, q.match_status, q.match_info, q.discard_reason, q.mago_changed, q.mago_changes,
|
||||
q.productiondata_id, COALESCE(p.idmatrice, q.idmatrice) AS idmatrice,
|
||||
m.nome AS matrice, m.photo AS matrice_photo,
|
||||
p.id_status AS prod_status, s.nome AS prod_status_name, COALESCE(s.badge_color, '#6c757d') AS prod_status_color,
|
||||
p.id_linea, l.name AS linea, l.color AS linea_color, p.metri AS prod_metri, p.data_produzione,
|
||||
(SELECT GROUP_CONCAT(ms.nome ORDER BY ms.nome SEPARATOR ', ') FROM productiondata_mescole pm
|
||||
JOIN mescole ms ON ms.id = pm.id_mescola WHERE pm.id_productiondata = p.id) AS mescole";
|
||||
$join = "LEFT JOIN mago_prod_queue q ON q.sale_ord_id = d.sale_ord_id AND q.sub_id = d.sub_id
|
||||
LEFT JOIN productiondata p ON p.id = q.productiondata_id
|
||||
LEFT JOIN matrice m ON m.id = COALESCE(p.idmatrice, q.idmatrice)
|
||||
LEFT JOIN production_status s ON s.id = p.id_status
|
||||
LEFT JOIN production_lines l ON l.id = p.id_linea";
|
||||
}
|
||||
$stL = $pdo->prepare("SELECT $sel FROM mago_sale_ord_detail d $join WHERE d.sale_ord_id = ? ORDER BY d.position, d.line, d.sub_id");
|
||||
$stL->execute([$id]);
|
||||
$lines = $stL->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// righe non (ancora) in coda: provo comunque a riconoscere la matrice dal valore Mago
|
||||
if ($hasMM) {
|
||||
if (!class_exists('MagoProduction') && is_file(__DIR__ . '/class/MagoProduction.php')) require_once __DIR__ . '/class/MagoProduction.php';
|
||||
foreach ($lines as &$l) {
|
||||
$l['mm'] = null;
|
||||
if (!class_exists('MagoProduction') || trim((string)$l['matrice_misura']) === '') continue;
|
||||
$l['mm'] = MagoProduction::parse($l['matrice_misura']);
|
||||
$l['mm']['tipo_label'] = MagoProduction::TIPI[$l['mm']['tipo']] ?? '';
|
||||
if (empty($l['idmatrice'])) {
|
||||
[$idm, $ms, $mi] = MagoProduction::lookup($pdo, $l['matrice_misura']);
|
||||
if ($idm) {
|
||||
$mt = $pdo->prepare("SELECT nome, photo FROM matrice WHERE id = ?");
|
||||
$mt->execute([$idm]);
|
||||
$r = $mt->fetch(PDO::FETCH_ASSOC) ?: [];
|
||||
$l['idmatrice'] = $idm;
|
||||
$l['matrice'] = $r['nome'] ?? '';
|
||||
$l['matrice_photo'] = $r['photo'] ?? '';
|
||||
}
|
||||
if (empty($l['match_status'])) {
|
||||
$l['match_status'] = $ms;
|
||||
$l['match_info'] = $mi;
|
||||
}
|
||||
}
|
||||
}
|
||||
unset($l);
|
||||
|
||||
// linee e mescole associate alla matrice in anagrafica (scheda di lavoro attiva, altrimenti matrici_mescole)
|
||||
if ($has('matrici_lines') && class_exists('MagoProduction')) {
|
||||
$lq = $pdo->prepare("SELECT l.name, l.color FROM matrici_lines ml JOIN production_lines l ON l.id = ml.idlinea WHERE ml.idmatrice = ? ORDER BY l.line_number, l.id");
|
||||
$mq = $pdo->prepare("SELECT nome FROM mescole WHERE id = ?");
|
||||
$cache = [];
|
||||
foreach ($lines as &$l) {
|
||||
$l['matrice_lines'] = [];
|
||||
$l['matrice_mescole'] = [];
|
||||
$idm = (int)($l['idmatrice'] ?? 0);
|
||||
if (!$idm) continue;
|
||||
if (!isset($cache[$idm])) {
|
||||
$lq->execute([$idm]);
|
||||
$ml = $lq->fetchAll(PDO::FETCH_ASSOC);
|
||||
$mx = [];
|
||||
try {
|
||||
$info = MagoProduction::matriceInfo($pdo, $idm);
|
||||
foreach ($info['mescole'] as $idmx) {
|
||||
$mq->execute([$idmx]);
|
||||
if (($n = $mq->fetchColumn()) !== false) $mx[] = $n;
|
||||
}
|
||||
} catch (Throwable $e) {
|
||||
}
|
||||
$cache[$idm] = [$ml, array_values(array_unique($mx))];
|
||||
}
|
||||
[$l['matrice_lines'], $l['matrice_mescole']] = $cache[$idm];
|
||||
}
|
||||
unset($l);
|
||||
}
|
||||
}
|
||||
|
||||
MagoSalesStats::jsonOut([
|
||||
'success' => true,
|
||||
'lines' => $lines,
|
||||
@@ -877,6 +956,272 @@ if ($action === 'order') {
|
||||
}
|
||||
}
|
||||
|
||||
/* modale larga: quasi tutto lo schermo su PC, a tutto schermo su tablet in verticale e telefono */
|
||||
.od-dialog.modal-xl {
|
||||
--bs-modal-width: min(1480px, 96vw);
|
||||
}
|
||||
|
||||
@media (max-width: 991.98px) {
|
||||
.od-dialog .modal-content {
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.od-dialog .ro-grid {
|
||||
grid-template-columns: 150px 1fr 150px 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
.od-dialog .ro-grid {
|
||||
grid-template-columns: 170px 1fr 170px 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
/* righe ordine */
|
||||
.ol-head,
|
||||
.ol-row {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(190px, 1.6fr) minmax(200px, 1.5fr) minmax(150px, 1fr) minmax(150px, 1fr) minmax(120px, .8fr) minmax(200px, 1.4fr);
|
||||
gap: 10px 16px;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.ol-head {
|
||||
background: #f1f5f9;
|
||||
border-radius: 10px;
|
||||
padding: 8px 14px;
|
||||
font-size: .78rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .03em;
|
||||
color: #475569;
|
||||
}
|
||||
|
||||
.ol-row {
|
||||
border: 1px solid #e2e8f0;
|
||||
border-left: 5px solid #3b82f6;
|
||||
border-radius: 12px;
|
||||
padding: 12px 14px;
|
||||
margin-top: 8px;
|
||||
background: #fff;
|
||||
font-size: .9rem;
|
||||
}
|
||||
|
||||
.ol-row.done {
|
||||
border-left-color: #22c55e;
|
||||
}
|
||||
|
||||
.ol-row.cancel {
|
||||
border-left-color: #94a3b8;
|
||||
opacity: .7;
|
||||
}
|
||||
|
||||
.ol-row.late {
|
||||
border-left-color: #dc3545;
|
||||
background: #fff7f7;
|
||||
}
|
||||
|
||||
.ol-k {
|
||||
display: none;
|
||||
font-size: .7rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
color: #64748b;
|
||||
letter-spacing: .03em;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.ol-n {
|
||||
display: inline-block;
|
||||
min-width: 26px;
|
||||
padding: 1px 6px;
|
||||
margin-right: 6px;
|
||||
border-radius: 6px;
|
||||
background: #e2e8f0;
|
||||
color: #334155;
|
||||
font-size: .75rem;
|
||||
font-weight: 700;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.ol-item {
|
||||
font-weight: 800;
|
||||
color: #0f172a;
|
||||
font-size: .98rem;
|
||||
}
|
||||
|
||||
.ol-sub {
|
||||
font-size: .8rem;
|
||||
color: #64748b;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.ol-mat {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.ol-mat img {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
object-fit: cover;
|
||||
border-radius: 10px;
|
||||
border: 1px solid #e2e8f0;
|
||||
background: #f8fafc;
|
||||
cursor: zoom-in;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.ol-mname {
|
||||
font-weight: 800;
|
||||
color: #0f172a;
|
||||
}
|
||||
|
||||
.ol-raw {
|
||||
display: inline-block;
|
||||
font-family: ui-monospace, Menlo, Consolas, monospace;
|
||||
font-size: .78rem;
|
||||
background: #f1f5f9;
|
||||
border-radius: 6px;
|
||||
padding: 1px 6px;
|
||||
color: #334155;
|
||||
}
|
||||
|
||||
.ol-chip {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
border-radius: 999px;
|
||||
padding: 2px 9px;
|
||||
font-size: .74rem;
|
||||
font-weight: 700;
|
||||
line-height: 1.5;
|
||||
margin-top: 3px;
|
||||
background: color-mix(in srgb, var(--c, #64748b) 14%, #fff);
|
||||
color: var(--c, #64748b);
|
||||
border: 1px solid color-mix(in srgb, var(--c, #64748b) 35%, #fff);
|
||||
}
|
||||
|
||||
.ol-qty b {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.ol-bar {
|
||||
height: 6px;
|
||||
border-radius: 99px;
|
||||
background: #e2e8f0;
|
||||
overflow: hidden;
|
||||
margin: 5px 0 3px;
|
||||
}
|
||||
|
||||
.ol-bar>span {
|
||||
display: block;
|
||||
height: 100%;
|
||||
background: #22c55e;
|
||||
border-radius: 99px;
|
||||
}
|
||||
|
||||
.ol-amt {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.ol-amt .amount {
|
||||
font-weight: 800;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.ol-lpill {
|
||||
display: inline-block;
|
||||
border-radius: 8px;
|
||||
padding: 2px 8px;
|
||||
margin: 2px 4px 0 0;
|
||||
font-size: .76rem;
|
||||
font-weight: 700;
|
||||
background: color-mix(in srgb, var(--c, #64748b) 18%, #fff);
|
||||
color: #1e293b;
|
||||
border: 1px solid color-mix(in srgb, var(--c, #64748b) 45%, #fff);
|
||||
}
|
||||
|
||||
.ol-mrow {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 2px 0;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.ol-mrow>span:first-child {
|
||||
font-size: .68rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
color: #64748b;
|
||||
letter-spacing: .03em;
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
.ol-mx {
|
||||
display: inline-block;
|
||||
border-radius: 8px;
|
||||
padding: 2px 8px;
|
||||
margin: 2px 4px 0 0;
|
||||
font-size: .76rem;
|
||||
font-weight: 600;
|
||||
background: #f5f3ff;
|
||||
color: #5b21b6;
|
||||
border: 1px solid #ddd6fe;
|
||||
}
|
||||
|
||||
.ol-note {
|
||||
grid-column: 1 / -1;
|
||||
background: #fffbeb;
|
||||
border: 1px solid #fde68a;
|
||||
border-radius: 8px;
|
||||
padding: 6px 10px;
|
||||
font-size: .84rem;
|
||||
white-space: pre-wrap;
|
||||
color: #713f12;
|
||||
}
|
||||
|
||||
.ol-warn {
|
||||
grid-column: 1 / -1;
|
||||
font-size: .82rem;
|
||||
color: #b45309;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
@media (max-width: 1199.98px) {
|
||||
.ol-head {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ol-row {
|
||||
grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
|
||||
.ol-k {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.ol-art,
|
||||
.ol-mat,
|
||||
.ol-prod {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.ol-amt {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 575.98px) {
|
||||
.ol-row {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
.sc-link {
|
||||
color: #198754;
|
||||
margin-left: 6px;
|
||||
@@ -1179,7 +1524,7 @@ if ($action === 'order') {
|
||||
|
||||
<!-- MODALE DETTAGLIO ORDINE -->
|
||||
<div class="modal fade" id="orderModal" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered modal-lg modal-dialog-scrollable">
|
||||
<div class="modal-dialog modal-dialog-centered modal-xl modal-fullscreen-lg-down modal-dialog-scrollable od-dialog">
|
||||
<div class="modal-content" style="border-radius:16px;">
|
||||
<div class="modal-header" style="background-color:#b9ebc7;">
|
||||
<h5 class="modal-title">Dettaglio ordine cliente</h5>
|
||||
@@ -2167,11 +2512,61 @@ if ($action === 'order') {
|
||||
});
|
||||
}
|
||||
|
||||
const MATCH = {
|
||||
esatta: ['Matrice riconosciuta', '#15803d'],
|
||||
revisione: ['Altra revisione in anagrafica', '#b45309'],
|
||||
mappa: ['Abbinata a mano', '#0f766e'],
|
||||
manuale: ['Scelta a mano', '#0f766e'],
|
||||
da_creare: ['Da creare in anagrafica', '#dc2626'],
|
||||
profilo: ['Profilo: matrice da scegliere', '#7c3aed'],
|
||||
anomalia: ['Da verificare', '#dc2626']
|
||||
};
|
||||
|
||||
function lineMatrix(l) {
|
||||
const raw = (l.matrice_misura || '').trim();
|
||||
const mm = l.mm || {};
|
||||
if (!raw && !l.matrice) return '<span class="text-muted">—</span>';
|
||||
const misura = mm.misura ? `${esc(mm.tipo_label || '')} ${esc(mm.misura)}`.trim() : '';
|
||||
const m = MATCH[l.match_status];
|
||||
const img = l.matrice_photo ? `<img src="photos/matrici/${encodeURIComponent(l.matrice_photo)}" alt="" loading="lazy" class="ol-photo" title="Ingrandisci">` : '';
|
||||
return `${img}<div>
|
||||
${l.matrice ? `<div class="ol-mname">${esc(l.matrice)}</div>` : ''}
|
||||
${raw ? `<div class="ol-sub">Mago <span class="ol-raw">${esc(raw)}</span>${misura ? ' · ' + misura : ''}</div>` : ''}
|
||||
${m ? `<span class="ol-chip" style="--c:${m[1]};" title="${esc(l.match_info || '')}">${m[0]}</span>` : ''}
|
||||
${(l.matrice_lines || []).length ? `<div class="ol-mrow"><span>Linee</span>${l.matrice_lines.map(x => `<span class="ol-lpill" style="--c:${esc(x.color || '#64748b')};">${esc(x.name)}</span>`).join('')}</div>` : ''}
|
||||
${(l.matrice_mescole || []).length ? `<div class="ol-mrow"><span>Mescole</span>${l.matrice_mescole.map(x => `<span class="ol-mx">${esc(x)}</span>`).join('')}</div>` : ''}
|
||||
</div>`;
|
||||
}
|
||||
|
||||
function lineProduction(l, open) {
|
||||
const pills = arr => arr.map(x => `<span class="ol-lpill" style="--c:${esc(x.color || '#64748b')};">${esc(x.name)}</span>`).join('');
|
||||
let h = '';
|
||||
if (l.prod_status) {
|
||||
h += `<span class="ol-chip" style="--c:${esc(l.prod_status_color)};"><i class="fa-solid fa-industry"></i> ${esc(l.prod_status_name)}</span>`;
|
||||
if (l.linea) h += `<div>${pills([{ name: l.linea, color: l.linea_color }])}</div>`;
|
||||
const bits = [];
|
||||
if (+l.prod_metri) bits.push(fmtNum(Math.round(+l.prod_metri)) + ' m');
|
||||
if (l.data_produzione) bits.push('prod. ' + fmtDate(l.data_produzione));
|
||||
if (l.mescole) bits.push(esc(l.mescole));
|
||||
if (bits.length) h += `<div class="ol-sub">${bits.join(' · ')}</div>`;
|
||||
} else if (l.queue_status === 'scartato') {
|
||||
h += `<span class="ol-chip" style="--c:#64748b;">Non da produrre</span>${l.discard_reason ? `<div class="ol-sub">${esc(l.discard_reason)}</div>` : ''}`;
|
||||
} else if (l.queue_status === 'chiuso_mago') {
|
||||
h += `<span class="ol-chip" style="--c:#64748b;">Chiusa in Mago</span>`;
|
||||
} else if (l.queue_status === 'importato') {
|
||||
h += `<span class="ol-chip" style="--c:#64748b;">Importata, lavoro non più presente</span>`;
|
||||
} else {
|
||||
h += `<span class="ol-sub">${open ? 'Non ancora in produzione' : '—'}</span>`;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
function renderLines(lines) {
|
||||
if (!lines.length) {
|
||||
return '<div class="warn-strip">Righe non ancora sincronizzate: premi <b>Aggiorna da Mago</b>.</div>';
|
||||
}
|
||||
const today = iso(new Date());
|
||||
const qtyTxt = n => fmtNum(Math.round(+n * 100) / 100);
|
||||
const rows = lines.map(l => {
|
||||
const open = !+l.delivered && !+l.cancelled;
|
||||
const due = l.zibo_date ? ziboEnd(l.zibo_date) : l.client_date;
|
||||
@@ -2180,32 +2575,48 @@ if ($action === 'order') {
|
||||
const st = +l.cancelled ? '<span class="st-badge st-annullato">Annullata</span>' :
|
||||
(+l.delivered ? '<span class="st-badge st-evaso">Consegnata</span>' :
|
||||
'<span class="st-badge st-aperto">Aperta</span>' + (late ? `<span class="late-badge">+${days} gg</span>` : ''));
|
||||
const qtyTxt = n => fmtNum(Math.round(+n * 100) / 100);
|
||||
return `<tr>
|
||||
<td><b>${esc(l.item)}</b><div class="small text-muted" style="white-space:normal;max-width:320px;">${esc(l.description)}</div></td>
|
||||
<td class="text-end amount">${qtyTxt(l.qty)} ${esc(l.uom)}</td>
|
||||
<td class="text-end amount">${qtyTxt(l.delivered_qty)}</td>
|
||||
<td class="text-end amount">${open ? '<b>' + qtyTxt(l.residual_qty) + '</b>' : '<span class="text-muted">—</span>'}</td>
|
||||
<td>${dateCell(l.zibo_date, l.client_date, {open: open})}</td>
|
||||
<td class="text-end amount">${fmtEur(l.taxable_amount, 2)}</td>
|
||||
<td>${st}</td>
|
||||
</tr>`;
|
||||
const pct = +l.qty > 0 ? Math.min(100, Math.round(+l.delivered_qty / +l.qty * 100)) : 0;
|
||||
const cls = +l.cancelled ? 'cancel' : (+l.delivered ? 'done' : (late ? 'late' : ''));
|
||||
return `<div class="ol-row ${cls}">
|
||||
<div class="ol-art">
|
||||
<div><span class="ol-n">${esc(l.line)}</span><span class="ol-item">${esc(l.item)}</span></div>
|
||||
<div class="ol-sub">${esc(l.description)}</div>
|
||||
${l.cod_art_cli ? `<div class="ol-sub">Cod. cliente <b>${esc(l.cod_art_cli)}</b></div>` : ''}
|
||||
</div>
|
||||
<div><div class="ol-k">Matrice</div><div class="ol-mat">${lineMatrix(l)}</div></div>
|
||||
<div class="ol-qty">
|
||||
<div class="ol-k">Quantità</div>
|
||||
<b class="amount">${qtyTxt(l.qty)}</b> ${esc(l.uom)}
|
||||
<div class="ol-bar"><span style="width:${pct}%;"></span></div>
|
||||
<div class="ol-sub">consegnati ${qtyTxt(l.delivered_qty)}${open ? ` · residuo <b>${qtyTxt(l.residual_qty)}</b>` : ''}</div>
|
||||
</div>
|
||||
<div><div class="ol-k">Consegna</div>${dateCell(l.zibo_date, l.client_date, {open: open})}</div>
|
||||
<div class="ol-amt"><div class="ol-k">Imponibile</div><div class="amount">${fmtEur(l.taxable_amount, 2)}</div><div class="mt-1">${st}</div></div>
|
||||
<div class="ol-prod"><div class="ol-k">Produzione</div>${lineProduction(l, open)}</div>
|
||||
${+l.mago_changed ? `<div class="ol-warn"><i class="fa-solid fa-triangle-exclamation me-1"></i>Cambiata in Mago dopo l'invio in produzione${l.mago_changes ? ': ' + esc(l.mago_changes) : ''}</div>` : ''}
|
||||
${l.notes ? `<div class="ol-note"><b>Note riga:</b> ${esc(l.notes)}</div>` : ''}
|
||||
</div>`;
|
||||
}).join('');
|
||||
return `
|
||||
<div class="fw-bold mb-2" style="color:var(--c-ink);">Righe ordine (${lines.length})</div>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-sm align-middle" style="font-size:.9rem;">
|
||||
<thead style="background:#f1f5f9;">
|
||||
<tr>
|
||||
<th>Articolo</th><th class="text-end">Qtà</th><th class="text-end">Consegnata</th><th class="text-end">Residuo</th>
|
||||
<th>Consegna (ZIBO / cliente)</th><th class="text-end">Imponibile</th><th>Stato</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>${rows}</tbody>
|
||||
</table>
|
||||
</div>`;
|
||||
<div class="ol-head"><div>Articolo</div><div>Matrice</div><div>Quantità</div><div>Consegna (ZIBO / cliente)</div><div class="text-end">Imponibile · stato</div><div>Produzione</div></div>
|
||||
${rows}`;
|
||||
}
|
||||
|
||||
// foto matrice a tutto schermo
|
||||
$(document).on('click', '#orderModalBody .ol-photo', function() {
|
||||
Swal.fire({
|
||||
imageUrl: this.src,
|
||||
imageAlt: 'Matrice',
|
||||
showConfirmButton: false,
|
||||
showCloseButton: true,
|
||||
width: 'auto',
|
||||
customClass: {
|
||||
image: 'm-0'
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
/* ---------------- SINCRONIZZAZIONE ---------------- */
|
||||
function runSync(mode) {
|
||||
const labels = {
|
||||
|
||||
Reference in New Issue
Block a user