fixed stats
This commit is contained in:
@@ -9,6 +9,60 @@ class MagoSalesStats
|
||||
{
|
||||
const CUSTOMER_TYPE = 3211264;
|
||||
|
||||
/*
|
||||
* MAPPATURA DATE DI CONSEGNA (righe e testata usano gli stessi nomi colonna)
|
||||
*
|
||||
* Data ZIBO = data comunicata da Zibo al cliente → è la SCADENZA che conta (ritardo in rosso)
|
||||
* Data cliente = data desiderata dal cliente → riferimento (ritardo in arancione)
|
||||
*
|
||||
* Per invertirle basta scambiare i due valori qui sotto.
|
||||
*/
|
||||
const ZIBO_DATE_COL = 'confirmed_delivery_date'; // Mago: ConfirmedDeliveryDate
|
||||
const CLIENT_DATE_COL = 'expected_delivery_date'; // Mago: ExpectedDeliveryDate
|
||||
|
||||
/** Data ZIBO "valida" di una riga/testata: in Mago, se non compilata, resta uguale alla data ordine. */
|
||||
public static function ziboDate($a)
|
||||
{
|
||||
$c = $a . '.' . self::ZIBO_DATE_COL;
|
||||
return "CASE WHEN $c > $a.order_date THEN $c END";
|
||||
}
|
||||
|
||||
public static function clientDate($a)
|
||||
{
|
||||
$c = $a . '.' . self::CLIENT_DATE_COL;
|
||||
return "CASE WHEN $c > $a.order_date THEN $c END";
|
||||
}
|
||||
|
||||
/** Scadenza effettiva di una riga: data ZIBO, se manca la data cliente. */
|
||||
public static function lineDue($a)
|
||||
{
|
||||
return "COALESCE(" . self::ziboDate($a) . ", " . self::clientDate($a) . ")";
|
||||
}
|
||||
|
||||
/** Aggregati per ordine calcolati dalle righe (alias l). */
|
||||
public static function lineAggregates()
|
||||
{
|
||||
$open = "(d.delivered = 0 AND d.cancelled = 0)";
|
||||
$due = self::lineDue('d');
|
||||
return "(
|
||||
SELECT d.sale_ord_id,
|
||||
COUNT(*) AS lines_total,
|
||||
SUM($open) AS open_lines,
|
||||
MIN(CASE WHEN $open THEN " . self::ziboDate('d') . " END) AS next_zibo,
|
||||
MIN(CASE WHEN $open THEN " . self::clientDate('d') . " END) AS next_client,
|
||||
MIN(" . self::ziboDate('d') . ") AS first_zibo,
|
||||
MIN(" . self::clientDate('d') . ") AS first_client,
|
||||
MIN(CASE WHEN $open THEN $due END) AS next_due,
|
||||
MIN($due) AS first_due,
|
||||
COUNT(DISTINCT CASE WHEN $open THEN $due END) AS open_dates,
|
||||
SUM($open AND $due < CURDATE()) AS late_lines,
|
||||
SUM($open AND " . self::clientDate('d') . " < CURDATE()) AS late_lines_client
|
||||
FROM mago_sale_ord_detail d
|
||||
WHERE d.item <> '' OR d.qty <> 0
|
||||
GROUP BY d.sale_ord_id
|
||||
) l";
|
||||
}
|
||||
|
||||
/** Risposta JSON e fine script (pulisce l'output di headscript). */
|
||||
public static function jsonOut(array $data)
|
||||
{
|
||||
@@ -36,8 +90,13 @@ class MagoSalesStats
|
||||
}
|
||||
|
||||
/**
|
||||
* Vista base: ordini + nome cliente + stato calcolato + data consegna di riferimento.
|
||||
* Le statistiche filtrano su questa vista (alias x).
|
||||
* Vista base: ordini + nome cliente + stato + date di consegna (alias x).
|
||||
*
|
||||
* zibo_date = prima data ZIBO tra le righe ancora da consegnare (se tutte consegnate: la prima in assoluto);
|
||||
* senza righe: data ZIBO di testata
|
||||
* client_date = stessa logica con la data cliente
|
||||
* due_date = scadenza dell'ordine: la più vicina tra le righe aperte (riga: data ZIBO, se manca data cliente)
|
||||
* late_lines / open_lines = righe aperte in ritardo / righe aperte (per il "ritardo parziale")
|
||||
*/
|
||||
public static function baseFrom()
|
||||
{
|
||||
@@ -45,13 +104,19 @@ class MagoSalesStats
|
||||
SELECT
|
||||
o.*,
|
||||
COALESCE(NULLIF(c.company_name, ''), o.customer) AS company_name,
|
||||
-- Data consegna di riferimento: prevista; la 'confermata' solo se successiva all'ordine
|
||||
-- (in Mago spesso coincide con la data ordine e farebbe risultare tutto in ritardo)
|
||||
COALESCE(l.next_zibo, l.first_zibo, " . self::ziboDate('o') . ") AS zibo_date,
|
||||
COALESCE(l.next_client, l.first_client, " . self::clientDate('o') . ") AS client_date,
|
||||
-- scadenza = la più vicina tra le righe aperte, dove ogni riga scade alla sua data ZIBO
|
||||
-- (o alla data cliente se la data ZIBO non è compilata)
|
||||
COALESCE(
|
||||
o.expected_delivery_date,
|
||||
CASE WHEN o.confirmed_delivery_date > o.order_date THEN o.confirmed_delivery_date END,
|
||||
o.compulsory_delivery_date
|
||||
l.next_due, l.first_due,
|
||||
" . self::ziboDate('o') . ", " . self::clientDate('o') . ", o.compulsory_delivery_date
|
||||
) AS due_date,
|
||||
COALESCE(l.lines_total, 0) AS lines_total,
|
||||
COALESCE(l.open_lines, 0) AS open_lines,
|
||||
COALESCE(l.open_dates, 0) AS open_dates,
|
||||
COALESCE(l.late_lines, 0) AS late_lines,
|
||||
COALESCE(l.late_lines_client, 0) AS late_lines_client,
|
||||
CASE
|
||||
WHEN o.cancelled = 1 THEN 'annullato'
|
||||
WHEN o.delivered = 1 THEN 'evaso'
|
||||
@@ -61,9 +126,36 @@ class MagoSalesStats
|
||||
FROM mago_sale_ord o
|
||||
LEFT JOIN mago_cust_supp c
|
||||
ON c.cust_supp_type = " . self::CUSTOMER_TYPE . " AND c.cust_supp = o.customer
|
||||
LEFT JOIN " . self::lineAggregates() . " ON l.sale_ord_id = o.sale_ord_id
|
||||
) x";
|
||||
}
|
||||
|
||||
/**
|
||||
* Vista righe aperte (alias r) per la pagina Consegne: riga + ordine + date effettive.
|
||||
*/
|
||||
public static function openLinesFrom()
|
||||
{
|
||||
return "(
|
||||
SELECT
|
||||
d.sale_ord_id, d.sub_id, d.line, d.position, d.item, d.description, d.uom,
|
||||
d.qty, d.delivered_qty,
|
||||
GREATEST(d.qty - d.delivered_qty, 0) AS residual_qty,
|
||||
CASE WHEN d.qty > 0 THEN ROUND(d.taxable_amount * GREATEST(d.qty - d.delivered_qty, 0) / d.qty, 2)
|
||||
ELSE d.taxable_amount END AS residual_value,
|
||||
d.taxable_amount,
|
||||
" . self::ziboDate('d') . " AS zibo_date,
|
||||
" . self::clientDate('d') . " AS client_date,
|
||||
" . self::lineDue('d') . " AS due_date,
|
||||
x.internal_ord_no, x.order_date, x.customer, x.company_name,
|
||||
x.salesperson, x.area, x.status, x.your_reference, x.external_ord_no
|
||||
FROM mago_sale_ord_detail d
|
||||
JOIN " . self::baseFrom() . " ON x.sale_ord_id = d.sale_ord_id
|
||||
WHERE d.delivered = 0 AND d.cancelled = 0
|
||||
AND x.status IN ('aperto','bloccato')
|
||||
AND (d.item <> '' OR d.qty <> 0)
|
||||
) r";
|
||||
}
|
||||
|
||||
/**
|
||||
* WHERE + parametri dai filtri in querystring.
|
||||
* $override sostituisce from/to (stringa vuota = nessun filtro data).
|
||||
@@ -108,6 +200,7 @@ class MagoSalesStats
|
||||
'annullato' => "x.status = 'annullato'",
|
||||
'bloccato' => "x.status = 'bloccato'",
|
||||
'ritardo' => "(x.status IN ('aperto','bloccato') AND x.due_date < CURDATE())",
|
||||
'ritardo_cliente' => "(x.status IN ('aperto','bloccato') AND x.client_date < CURDATE())",
|
||||
'da_fatturare' => "(x.delivered = 1 AND x.invoiced = 0 AND x.cancelled = 0)",
|
||||
'fatturato' => "x.invoiced = 1",
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user