matrici sales update
This commit is contained in:
@@ -7,6 +7,7 @@
|
|||||||
* Fonte: righe ordine Mago (mago_sale_ord_detail), solo lettura. Prezzo = imponibile riga ÷ quantità.
|
* Fonte: righe ordine Mago (mago_sale_ord_detail), solo lettura. Prezzo = imponibile riga ÷ quantità.
|
||||||
*/
|
*/
|
||||||
require_once __DIR__ . '/MagoSalesStats.php';
|
require_once __DIR__ . '/MagoSalesStats.php';
|
||||||
|
require_once __DIR__ . '/MagoMixPurchases.php';
|
||||||
|
|
||||||
class MagoMatriceStats
|
class MagoMatriceStats
|
||||||
{
|
{
|
||||||
@@ -292,6 +293,75 @@ class MagoMatriceStats
|
|||||||
return ['status' => ($info['gm_total'] > 0 && $info['gm_missing']) ? 'gm_part' : 'ok', 'kg' => $kg];
|
return ['status' => ($info['gm_total'] > 0 && $info['gm_missing']) ? 'gm_part' : 'ok', 'kg' => $kg];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ============================================================
|
||||||
|
* COSTO GREZZO (solo mescola)
|
||||||
|
* ============================================================ */
|
||||||
|
|
||||||
|
/** Prezzi €/kg delle mescole (vuoto se gli acquisti non sono ancora sincronizzati) */
|
||||||
|
public static function mixPrices(PDO $pdo): array
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return MagoMixPurchases::prices($pdo);
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Costo della mescola per unità venduta.
|
||||||
|
* - Metri: €/m = somma di g/m × €/kg ÷ 1000 per ogni mescola della scheda di lavoro.
|
||||||
|
* - Chili: €/kg = media dei €/kg delle mescole pesata sui g/m (in parti uguali se mancano i g/m).
|
||||||
|
* - Pezzi: non calcolabile (manca la conversione pezzi → metri).
|
||||||
|
* $ym: costo in un mese passato (prezzi di quel mese, altrimenti l'ultimo noto prima).
|
||||||
|
* status: ok | partial (manca g/m o prezzo di qualche mescola: costo sottostimato) | price (nessun prezzo) | gm | none | pz | altro
|
||||||
|
*/
|
||||||
|
public static function costOf(?array $mi, string $kind, array $prices, ?string $ym = null): array
|
||||||
|
{
|
||||||
|
$out = ['status' => 'none', 'cost' => null, 'parts' => [], 'missing' => [], 'check' => []];
|
||||||
|
if ($kind === 'pz' || $kind === 'altro') return ['status' => $kind] + $out;
|
||||||
|
if (!$mi || !$mi['mix']) return $out;
|
||||||
|
if ($kind === 'm' && $mi['gm_total'] <= 0) return ['status' => 'gm'] + $out;
|
||||||
|
|
||||||
|
$n = count($mi['mix']);
|
||||||
|
$cost = 0.0;
|
||||||
|
$priced = 0;
|
||||||
|
$gmMissing = false;
|
||||||
|
foreach ($mi['mix'] as $x) {
|
||||||
|
$p = $prices[$x['id']] ?? null;
|
||||||
|
$eur = $p ? ($ym ? MagoMixPurchases::priceAt($p, $ym) : $p['price']) : null;
|
||||||
|
$gm = $x['gm'] !== null && $x['gm'] > 0 ? (float)$x['gm'] : null;
|
||||||
|
if ($gm === null) $gmMissing = true;
|
||||||
|
if ($kind === 'm') {
|
||||||
|
$part = ($gm !== null && $eur !== null) ? $gm / 1000 * $eur : null;
|
||||||
|
} else {
|
||||||
|
$share = $mi['gm_total'] > 0 ? ($gm ?? 0) / $mi['gm_total'] : 1 / $n;
|
||||||
|
$part = $eur !== null ? $share * $eur : null;
|
||||||
|
}
|
||||||
|
if ($eur === null) $out['missing'][] = $x['name'];
|
||||||
|
if ($part !== null) {
|
||||||
|
$cost += $part;
|
||||||
|
$priced++;
|
||||||
|
}
|
||||||
|
if ($p && $p['check']) $out['check'][$p['check']] = $p['check'];
|
||||||
|
$out['parts'][] = [
|
||||||
|
'id' => $x['id'],
|
||||||
|
'name' => $x['name'],
|
||||||
|
'gm' => $gm,
|
||||||
|
'eur_kg' => $eur !== null ? round($eur, 4) : null,
|
||||||
|
'part' => $part !== null ? round($part, 4) : null,
|
||||||
|
'old' => $p ? $p['old'] : null,
|
||||||
|
'last_date' => $p['last_date'] ?? null,
|
||||||
|
'supplier' => $p['last_supplier'] ?? null,
|
||||||
|
'check' => $p['check'] ?? null,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
$out['check'] = array_values($out['check']);
|
||||||
|
if ($priced === 0) return ['status' => 'price'] + $out;
|
||||||
|
$out['cost'] = round($cost, 4);
|
||||||
|
$out['status'] = ($out['missing'] || ($kind === 'm' && $gmMissing) || ($kind === 'kg' && $mi['gm_total'] > 0 && $gmMissing)) ? 'partial' : 'ok';
|
||||||
|
return $out;
|
||||||
|
}
|
||||||
|
|
||||||
/* ============================================================
|
/* ============================================================
|
||||||
* DATI
|
* DATI
|
||||||
* ============================================================ */
|
* ============================================================ */
|
||||||
@@ -367,6 +437,7 @@ class MagoMatriceStats
|
|||||||
}
|
}
|
||||||
$mix = self::mixInfo($pdo, $ids);
|
$mix = self::mixInfo($pdo, $ids);
|
||||||
$ix = self::index($pdo);
|
$ix = self::index($pdo);
|
||||||
|
$prices = self::mixPrices($pdo);
|
||||||
|
|
||||||
$spark = [];
|
$spark = [];
|
||||||
for ($i = 11; $i >= 0; $i--) $spark[] = date('Y-m', strtotime("first day of -$i months"));
|
for ($i = 11; $i >= 0; $i--) $spark[] = date('Y-m', strtotime("first day of -$i months"));
|
||||||
@@ -398,6 +469,11 @@ class MagoMatriceStats
|
|||||||
'gm_missing_lines' => 0,
|
'gm_missing_lines' => 0,
|
||||||
'gm_missing_value' => 0,
|
'gm_missing_value' => 0,
|
||||||
'matrici' => 0,
|
'matrici' => 0,
|
||||||
|
'cost_value' => 0,
|
||||||
|
'cost_cover_value' => 0,
|
||||||
|
'cost_rows' => 0,
|
||||||
|
'cost_partial_rows' => 0,
|
||||||
|
'check_rows' => 0,
|
||||||
];
|
];
|
||||||
$linkedIds = [];
|
$linkedIds = [];
|
||||||
|
|
||||||
@@ -553,6 +629,18 @@ class MagoMatriceStats
|
|||||||
$pp = $a['qp'] > 0 ? $a['vp'] / $a['qp'] : null;
|
$pp = $a['qp'] > 0 ? $a['vp'] / $a['qp'] : null;
|
||||||
$sp = [];
|
$sp = [];
|
||||||
for ($i = 0; $i < 12; $i++) $sp[] = $a['sq'][$i] > 0 ? round($a['sv'][$i] / $a['sq'][$i], 4) : null;
|
for ($i = 0; $i < 12; $i++) $sp[] = $a['sq'][$i] > 0 ? round($a['sv'][$i] / $a['sq'][$i], 4) : null;
|
||||||
|
$c = self::costOf($a['id'] ? ($mix[$a['id']] ?? null) : null, $a['kind'], $prices);
|
||||||
|
$margin = ($c['cost'] !== null && $price) ? $price - $c['cost'] : null;
|
||||||
|
if ($c['cost'] !== null && $price && $a['n'] > 0) {
|
||||||
|
if ($c['status'] === 'ok') {
|
||||||
|
$kpi['cost_value'] += $a['pq'] * $c['cost'];
|
||||||
|
$kpi['cost_cover_value'] += $a['value'];
|
||||||
|
$kpi['cost_rows']++;
|
||||||
|
} else {
|
||||||
|
$kpi['cost_partial_rows']++;
|
||||||
|
}
|
||||||
|
if ($c['check']) $kpi['check_rows']++;
|
||||||
|
}
|
||||||
$rows[] = [
|
$rows[] = [
|
||||||
'key' => $a['key'],
|
'key' => $a['key'],
|
||||||
'id' => $a['id'],
|
'id' => $a['id'],
|
||||||
@@ -586,6 +674,12 @@ class MagoMatriceStats
|
|||||||
'mix_status' => $a['mix_status'],
|
'mix_status' => $a['mix_status'],
|
||||||
'mix_n' => $a['mix_n'],
|
'mix_n' => $a['mix_n'],
|
||||||
'gm_total' => $a['gm_total'],
|
'gm_total' => $a['gm_total'],
|
||||||
|
'cost' => $c['cost'],
|
||||||
|
'cost_status' => $c['status'],
|
||||||
|
'cost_missing' => $c['missing'],
|
||||||
|
'cost_check' => $c['check'],
|
||||||
|
'margin' => $margin !== null ? round($margin, 4) : null,
|
||||||
|
'margin_pct' => $margin !== null ? round($margin / $price * 100, 1) : null,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
usort($rows, fn($x, $y) => $y['value'] <=> $x['value']);
|
usort($rows, fn($x, $y) => $y['value'] <=> $x['value']);
|
||||||
@@ -618,6 +712,8 @@ class MagoMatriceStats
|
|||||||
'mescole' => $mescole,
|
'mescole' => $mescole,
|
||||||
'types' => self::TYPE_LABELS,
|
'types' => self::TYPE_LABELS,
|
||||||
'cats' => self::CAT_LABELS,
|
'cats' => self::CAT_LABELS,
|
||||||
|
'price_months' => MagoMixPurchases::PRICE_MONTHS,
|
||||||
|
'has_prices' => !empty($prices),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -648,6 +744,8 @@ class MagoMatriceStats
|
|||||||
$lines = self::fetchLines($pdo, $from, $customers, $raws, $uom);
|
$lines = self::fetchLines($pdo, $from, $customers, $raws, $uom);
|
||||||
$ix = self::index($pdo);
|
$ix = self::index($pdo);
|
||||||
$mi = $first['id'] ? (self::mixInfo($pdo, [$first['id']])[$first['id']] ?? null) : null;
|
$mi = $first['id'] ? (self::mixInfo($pdo, [$first['id']])[$first['id']] ?? null) : null;
|
||||||
|
$prices = self::mixPrices($pdo);
|
||||||
|
$costNow = self::costOf($mi, $kind, $prices);
|
||||||
|
|
||||||
$prodLines = [];
|
$prodLines = [];
|
||||||
if ($first['id']) {
|
if ($first['id']) {
|
||||||
@@ -778,6 +876,8 @@ class MagoMatriceStats
|
|||||||
'last_price' => $x['last_price'] !== null ? round($x['last_price'], 4) : null,
|
'last_price' => $x['last_price'] !== null ? round($x['last_price'], 4) : null,
|
||||||
'var' => ($p12 !== null && $pp) ? round(($p12 - $pp) / $pp * 100, 1) : null,
|
'var' => ($p12 !== null && $pp) ? round(($p12 - $pp) / $pp * 100, 1) : null,
|
||||||
'open_qty' => round($x['open_qty'], 3),
|
'open_qty' => round($x['open_qty'], 3),
|
||||||
|
'margin_pct' => ($p && $costNow['cost'] !== null) ? round(($p - $costNow['cost']) / $p * 100, 1) : null,
|
||||||
|
'last_margin_pct' => ($x['last_price'] && $costNow['cost'] !== null) ? round(($x['last_price'] - $costNow['cost']) / $x['last_price'] * 100, 1) : null,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
usort($clients, fn($a, $b) => $b['value'] <=> $a['value']);
|
usort($clients, fn($a, $b) => $b['value'] <=> $a['value']);
|
||||||
@@ -786,6 +886,17 @@ class MagoMatriceStats
|
|||||||
$mrows = [];
|
$mrows = [];
|
||||||
foreach ($months as $ym => $m) $mrows[] = ['ym' => $ym, 'price' => $m['q'] > 0 ? round($m['v'] / $m['q'], 4) : null, 'qty' => round($m['q'], 3)];
|
foreach ($months as $ym => $m) $mrows[] = ['ym' => $ym, 'price' => $m['q'] > 0 ? round($m['v'] / $m['q'], 4) : null, 'qty' => round($m['q'], 3)];
|
||||||
|
|
||||||
|
// costo mese per mese (prezzi mescole di quel mese) dal primo mese con vendite a oggi
|
||||||
|
$costMonths = [];
|
||||||
|
if ($costNow['cost'] !== null) {
|
||||||
|
$start = $mrows ? $mrows[0]['ym'] : substr($from, 0, 7);
|
||||||
|
for ($t = strtotime($start . '-01'); date('Y-m', $t) <= date('Y-m'); $t = strtotime('+1 month', $t)) {
|
||||||
|
$ym = date('Y-m', $t);
|
||||||
|
$c = self::costOf($mi, $kind, $prices, $ym);
|
||||||
|
if ($c['cost'] !== null) $costMonths[] = ['ym' => $ym, 'cost' => $c['cost']];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$mixRows = [];
|
$mixRows = [];
|
||||||
if ($mi) {
|
if ($mi) {
|
||||||
foreach ($mi['mix'] as $x) {
|
foreach ($mi['mix'] as $x) {
|
||||||
@@ -824,6 +935,11 @@ class MagoMatriceStats
|
|||||||
'gm_total' => $mi['gm_total'] ?? 0,
|
'gm_total' => $mi['gm_total'] ?? 0,
|
||||||
'mix_status' => $status,
|
'mix_status' => $status,
|
||||||
],
|
],
|
||||||
|
'cost' => $costNow + [
|
||||||
|
'months' => $costMonths,
|
||||||
|
'price_months' => MagoMixPurchases::PRICE_MONTHS,
|
||||||
|
'margin_pct' => ($avg && $costNow['cost'] !== null) ? round(($avg - $costNow['cost']) / $avg * 100, 1) : null
|
||||||
|
],
|
||||||
'tot' => [
|
'tot' => [
|
||||||
'n' => $tot['n'],
|
'n' => $tot['n'],
|
||||||
'qty' => round($tot['qty'], 3),
|
'qty' => round($tot['qty'], 3),
|
||||||
|
|||||||
@@ -21,6 +21,9 @@ class MagoMixPurchases
|
|||||||
/** Sync incrementale: rilegge le fatture degli ultimi N giorni */
|
/** Sync incrementale: rilegge le fatture degli ultimi N giorni */
|
||||||
const SYNC_DAYS = 90;
|
const SYNC_DAYS = 90;
|
||||||
|
|
||||||
|
/** Fornitori il cui prezzo va verificato (es. conto lavoro: il prezzo non comprende le materie prime) */
|
||||||
|
const CHECK_SUPPLIERS = ['D022' => 'Der-Gom'];
|
||||||
|
|
||||||
/** Righe che non sono una mescola da prezzare */
|
/** Righe che non sono una mescola da prezzare */
|
||||||
const EXCLUDE_RE = '/RECUPER|RITAGLI|\bMIX\b|\bREC\b|DA FILTRARE|RILAVORAR|RESO NON LAVORATO|NON STANDARD|SCADENZA|VARIE|ACCELERANTI|\bPROVA\b/i';
|
const EXCLUDE_RE = '/RECUPER|RITAGLI|\bMIX\b|\bREC\b|DA FILTRARE|RILAVORAR|RESO NON LAVORATO|NON STANDARD|SCADENZA|VARIE|ACCELERANTI|\bPROVA\b/i';
|
||||||
|
|
||||||
@@ -149,7 +152,8 @@ class MagoMixPurchases
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* €/kg per mescola.
|
* €/kg per mescola.
|
||||||
* @return array [idmescola => price, last_price, last_date, kg_window, kg_total, old (bool), months [ym => €/kg], suppliers [nome => €/kg]]
|
* @return array [idmescola => price, last_price, last_date, kg_window, kg_total, old (bool), months [ym => €/kg], suppliers [nome => €/kg],
|
||||||
|
* last_supplier, check (nome fornitore da verificare o null)]
|
||||||
*/
|
*/
|
||||||
public static function prices(PDO $pdo, int $months = self::PRICE_MONTHS, ?array $lines = null): array
|
public static function prices(PDO $pdo, int $months = self::PRICE_MONTHS, ?array $lines = null): array
|
||||||
{
|
{
|
||||||
@@ -172,6 +176,8 @@ class MagoMixPurchases
|
|||||||
if (($a['last_date'] ?? '') <= $l['doc_date']) {
|
if (($a['last_date'] ?? '') <= $l['doc_date']) {
|
||||||
$a['last_date'] = $l['doc_date'];
|
$a['last_date'] = $l['doc_date'];
|
||||||
$a['last_price'] = $l['value'] / $l['qty'];
|
$a['last_price'] = $l['value'] / $l['qty'];
|
||||||
|
$a['last_sc'] = (string)$l['supplier_code'];
|
||||||
|
$a['last_sn'] = (string)($l['supplier_name'] ?: $l['supplier_code']);
|
||||||
}
|
}
|
||||||
$ym = substr((string)$l['doc_date'], 0, 7);
|
$ym = substr((string)$l['doc_date'], 0, 7);
|
||||||
$a['m'][$ym]['kg'] = ($a['m'][$ym]['kg'] ?? 0) + $l['qty'];
|
$a['m'][$ym]['kg'] = ($a['m'][$ym]['kg'] ?? 0) + $l['qty'];
|
||||||
@@ -195,11 +201,24 @@ class MagoMixPurchases
|
|||||||
'old' => !$win,
|
'old' => !$win,
|
||||||
'months' => $ms,
|
'months' => $ms,
|
||||||
'suppliers' => $sup,
|
'suppliers' => $sup,
|
||||||
|
'last_supplier' => $a['last_sn'],
|
||||||
|
'check' => self::CHECK_SUPPLIERS[$a['last_sc']] ?? null,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
return $out;
|
return $out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Prezzo di una mescola in un mese: quello del mese, altrimenti l'ultimo dei mesi precedenti */
|
||||||
|
public static function priceAt(array $p, string $ym): ?float
|
||||||
|
{
|
||||||
|
$best = null;
|
||||||
|
foreach ($p['months'] as $m => $v) {
|
||||||
|
if ($m > $ym) break;
|
||||||
|
$best = $v;
|
||||||
|
}
|
||||||
|
return $best;
|
||||||
|
}
|
||||||
|
|
||||||
/** Descrizioni d'acquisto non abbinate (o ambigue), raggruppate per parole, ordinate per valore */
|
/** Descrizioni d'acquisto non abbinate (o ambigue), raggruppate per parole, ordinate per valore */
|
||||||
public static function unmatched(PDO $pdo, ?array $lines = null): array
|
public static function unmatched(PDO $pdo, ?array $lines = null): array
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -467,6 +467,23 @@
|
|||||||
b: `<p>Quanta parte del venduto è collegata a una <b>matrice dell'anagrafica</b> (verde), quanta è tubi, rettangoli, diametri e altri profili (viola), quanta resta da sistemare (arancio).</p>
|
b: `<p>Quanta parte del venduto è collegata a una <b>matrice dell'anagrafica</b> (verde), quanta è tubi, rettangoli, diametri e altri profili (viola), quanta resta da sistemare (arancio).</p>
|
||||||
<p class="sh-note">Cosa fare: clic sul box per la lista "Da sistemare" e completare l'anagrafica matrici o le corrispondenze.</p>`,
|
<p class="sh-note">Cosa fare: clic sul box per la lista "Da sistemare" e completare l'anagrafica matrici o le corrispondenze.</p>`,
|
||||||
},
|
},
|
||||||
|
"mx.k.margin": {
|
||||||
|
t: "Margine sul grezzo",
|
||||||
|
b: `<p>Quanto resta del prezzo di vendita dopo il <b>costo della sola mescola</b>, sulle matrici dove il costo è completo.</p>
|
||||||
|
<ul>
|
||||||
|
<li>Costo mescola = g/m della scheda di lavoro × €/kg pagato in Mago (media degli ultimi 3 mesi).</li>
|
||||||
|
<li><b>Calcolato sul</b>: quota del venduto che ha un costo completo (scheda con g/m e prezzo di tutte le mescole).</li>
|
||||||
|
<li><span class="sh-chip sh-orange">da verificare</span> mescole il cui prezzo potrebbe non comprendere le materie prime (es. Der-Gom).</li>
|
||||||
|
</ul>
|
||||||
|
<p class="sh-note">Non comprende scarto, lavorazione, energia e trasporto: è il margine "lordo di mescola".</p>`,
|
||||||
|
},
|
||||||
|
"mx.margin": {
|
||||||
|
t: "Margine sul costo mescola",
|
||||||
|
b: `<p><b>Margine più basso</b>: le matrici dove il prezzo copre meno il costo della mescola. Sono le prime da rivedere nei listini.</p>
|
||||||
|
<p><b>Più margine in euro</b>: le matrici che portano più margine nel periodo (margine unitario × quantità).</p>
|
||||||
|
<p>🟢 da 60% · 🟡 da 40 a 60% · 🔴 sotto 40%.</p>
|
||||||
|
<p class="sh-note">Contano solo le matrici con costo completo. Clic su una matrice per il dettaglio con la linea del costo nel grafico.</p>`,
|
||||||
|
},
|
||||||
"mx.map": {
|
"mx.map": {
|
||||||
t: "Mappa dei prezzi",
|
t: "Mappa dei prezzi",
|
||||||
b: `<p>Ogni bolla è una matrice venduta nel periodo (le prime 150 per valore).</p>
|
b: `<p>Ogni bolla è una matrice venduta nel periodo (le prime 150 per valore).</p>
|
||||||
@@ -488,6 +505,8 @@
|
|||||||
<li><b>Prezzo medio</b>: imponibile ÷ quantità del periodo.</li>
|
<li><b>Prezzo medio</b>: imponibile ÷ quantità del periodo.</li>
|
||||||
<li><b>Forbice</b>: prezzo minimo e massimo praticato. Barra <span class="sh-chip sh-green">verde</span> fino al 10% di differenza, <span class="sh-chip sh-amber">gialla</span> fino al 25%, <span class="sh-chip sh-red">rossa</span> oltre.</li>
|
<li><b>Forbice</b>: prezzo minimo e massimo praticato. Barra <span class="sh-chip sh-green">verde</span> fino al 10% di differenza, <span class="sh-chip sh-amber">gialla</span> fino al 25%, <span class="sh-chip sh-red">rossa</span> oltre.</li>
|
||||||
<li><b>12 mesi</b>: prezzo mese per mese e variazione sui 12 mesi precedenti.</li>
|
<li><b>12 mesi</b>: prezzo mese per mese e variazione sui 12 mesi precedenti.</li>
|
||||||
|
<li><b>Costo mescola</b>: €/m o €/kg della sola mescola. <span class="sh-chip sh-red">parziale</span> = manca il prezzo o il g/m di qualche mescola (costo sottostimato).</li>
|
||||||
|
<li><b>Margine</b>: (prezzo − costo mescola) ÷ prezzo.</li>
|
||||||
<li><b>Mescola</b>: kg stimati, oppure il motivo per cui mancano (<span class="sh-chip sh-amber">a pezzi</span>, <span class="sh-chip sh-red">g/m mancante</span>).</li>
|
<li><b>Mescola</b>: kg stimati, oppure il motivo per cui mancano (<span class="sh-chip sh-amber">a pezzi</span>, <span class="sh-chip sh-red">g/m mancante</span>).</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p class="sh-note">La stessa matrice venduta a metri e a chili compare su due righe.</p>`,
|
<p class="sh-note">La stessa matrice venduta a metri e a chili compare su due righe.</p>`,
|
||||||
@@ -512,7 +531,8 @@
|
|||||||
t: "Prezzo nel tempo",
|
t: "Prezzo nel tempo",
|
||||||
b: `<p>Ogni punto è una <b>riga d'ordine</b>: altezza = prezzo, colore = cliente (i primi 8 per valore, gli altri insieme).</p>
|
b: `<p>Ogni punto è una <b>riga d'ordine</b>: altezza = prezzo, colore = cliente (i primi 8 per valore, gli altri insieme).</p>
|
||||||
<p>La linea scura è il <b>prezzo medio del mese</b>. Punti sotto la linea = clienti che pagano meno della media.</p>
|
<p>La linea scura è il <b>prezzo medio del mese</b>. Punti sotto la linea = clienti che pagano meno della media.</p>
|
||||||
<p class="sh-note">Nella tabella Clienti, "Rispetto alla media" mostra di quanto ognuno paga più o meno.</p>`,
|
<p>La <b>linea rossa tratteggiata</b> è il costo della mescola mese per mese (prezzi pagati in quel mese): la distanza dalla linea dei prezzi è il margine.</p>
|
||||||
|
<p class="sh-note">Nella tabella Clienti, "Rispetto alla media" mostra di quanto ognuno paga più o meno, "Margine" quanto resta dopo la mescola.</p>`,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+1178
-981
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user