mago probe purchase update e mescole

This commit is contained in:
2026-10-24 10:30:37 +02:00
parent 1193785151
commit cdcff42677
2 changed files with 384 additions and 64 deletions
+74 -64
View File
@@ -10,6 +10,9 @@
* php mago_probe_purchases.php --months=36 periodo diverso
* php mago_probe_purchases.php --pages=60 righe lette al massimo = pagine × 200 (default 40)
* php mago_probe_purchases.php --fields stampa anche tutti i campi con un valore d'esempio
* php mago_probe_purchases.php --types=9830401,9830402 tipi documento da leggere (default fattura fornitore)
*
* L'avanzamento (pagina per pagina) esce a video anche se l'output va in un file.
*
* Stampa:
* 1. quali tabelle d'acquisto esistono, quanti record hanno e i loro campi
@@ -28,10 +31,12 @@ if (PHP_SAPI !== 'cli') {
require_once __DIR__ . '/class/MagoClient.php';
/* ---------------- opzioni ---------------- */
$opt = getopt('', ['months::', 'pages::', 'fields']);
$opt = getopt('', ['months::', 'pages::', 'fields', 'types::']);
$months = max(1, (int)($opt['months'] ?? 24));
$maxPages = max(1, (int)($opt['pages'] ?? 40));
$showFields = isset($opt['fields']);
// tipi documento da leggere: 9830401 = fattura fornitore (dal primo test). Più tipi separati da virgola.
$docTypes = array_values(array_filter(array_map('trim', explode(',', (string)($opt['types'] ?? '9830401'))), 'strlen'));
$since = date('Y-m-d', strtotime("-$months months"));
/* ---------------- .env ---------------- */
@@ -127,13 +132,11 @@ try {
}
}
foreach ($found as $t => $f) {
if (!$f['keys']) continue;
echo "\n-- $t: campi --\n";
if ($showFields) {
if ($showFields) {
foreach ($found as $t => $f) {
if (!$f['keys']) continue;
echo "\n-- $t: campi --\n";
foreach ($f['sample'] as $k => $v) echo ' ' . pad($k, 32) . cut(is_scalar($v) ? (string)$v : json_encode($v), 60) . "\n";
} else {
echo ' ' . wordwrap(implode(', ', $f['keys']), 74, "\n ") . "\n";
}
}
@@ -170,80 +173,87 @@ try {
echo "\nFonte usata: $srcLabel ($headT + $detT)\n";
echo "Campi riconosciuti: id=$hId/$dId data=$hDate n°=$hNo fornitore=$hSupp tipo=" . ($hType ?: '-') .
" | articolo=$dItem UM=$dUom qtà=$dQty imponibile=" . ($dVal ?: '-') . " prezzo=" . ($dUnit ?: '-') . "\n";
if (!$hId || !$dId || !$hDate || !$dItem || !$dQty) {
if (!$dId || !$dItem || !$dQty) {
h('Mancano campi indispensabili (id, data, articolo, quantità): rilancia con --fields e mandami l\'output');
exit(0);
}
/* =========================================================
* 2. TESTATE DEL PERIODO
* 2. TIPI DI DOCUMENTO DEL PERIODO
* ========================================================= */
$heads = [];
$types = [];
foreach ($mago->iterate($headT, ['filters' => [['key' => $hDate, 'value' => $since, 'operator' => '>=']]], $maxPages) as $rec) {
$id = (string)$rec[$hId];
$heads[$id] = [
'date' => MagoClient::toMysqlDate($rec[$hDate] ?? null),
'no' => $hNo ? (string)$rec[$hNo] : '',
'supp' => $hSupp ? (string)$rec[$hSupp] : '',
'type' => $hType ? (string)$rec[$hType] : '',
];
if ($hType) {
$tp = (string)$rec[$hType];
$types[$tp]['n'] = ($types[$tp]['n'] ?? 0) + 1;
$types[$tp]['ex'] = $types[$tp]['ex'] ?? ($hNo ? $rec[$hNo] : '');
$dType = field($dk, ['DocumentType']);
$dDate = field($dk, ['DocumentDate', 'OrderDate']);
$dNo = field($dk, ['DocNo', 'PurchaseOrdNo']);
$dSupp = field($dk, ['Supplier']);
h('2. TIPI DI DOCUMENTO DEL PERIODO');
$known = ['9830400' => 'DDT fornitore?', '9830401' => 'Fattura fornitore?', '9830402' => 'Nota di credito?'];
if ($hType && $hDate) {
foreach ($known as $tp => $lbl) {
try {
$n = $mago->count($headT, [['key' => $hDate, 'value' => $since, 'operator' => '>='], ['key' => $hType, 'value' => $tp, 'operator' => '=']]);
echo pad($tp, 12) . pad($lbl, 22) . pad(num($n), 10, true) . "\n";
} catch (Throwable $e) {
echo pad($tp, 12) . " errore: " . cut($e->getMessage(), 60) . "\n";
}
}
}
h("2. DOCUMENTI DEL PERIODO: " . num(count($heads)));
if ($types) {
echo pad('Tipo documento', 16) . pad('Quanti', 10, true) . " Esempio n°\n";
arsort($types);
foreach ($types as $tp => $x) echo pad($tp, 16) . pad(num($x['n']), 10, true) . ' ' . $x['ex'] . "\n";
echo "(Per le vendite: 3407874 fattura, 3407883 acconto, 3407876 nota credito, 3407873 DDT. Gli acquisti hanno codici simili.)\n";
}
if (!$heads) {
echo "Nessun documento nel periodo.\n";
exit(0);
}
echo "Righe lette solo dai tipi: " . implode(', ', $docTypes) . " (cambia con --types=…)\n";
/* =========================================================
* 3. RIGHE
* 3. RIGHE (solo i campi che servono, filtro su data e tipo documento)
* ========================================================= */
$filters = $dMod ? [['key' => $dMod, 'value' => $since, 'operator' => '>=']] : [];
if (!$dDate) {
h('Nella tabella righe manca la data documento: rilancia con --fields e mandami l\'output');
exit(0);
}
$fields = array_values(array_filter([$dId, $dDate, $dNo, $dSupp, $dType, $dItem, $dDesc, $dUom, $dQty, $dVal, $dUnit, field($dk, ['LineType'])]));
$items = [];
$last = [];
$lines = 0;
$skipped = 0;
foreach ($mago->iterate($detT, ['filters' => $filters], $maxPages) as $rec) {
$id = (string)$rec[$dId];
if (!isset($heads[$id])) {
$skipped++;
continue;
}
$item = trim((string)($rec[$dItem] ?? ''));
$qty = MagoClient::toDecimal($rec[$dQty] ?? 0);
if ($item === '' || $qty == 0) continue;
$val = $dVal ? MagoClient::toDecimal($rec[$dVal]) : 0;
if ($val == 0 && $dUnit) $val = $qty * MagoClient::toDecimal($rec[$dUnit]);
$hd = $heads[$id];
$lines++;
$read = 0;
$total = null;
foreach ($docTypes as $tp) {
$flt = [['key' => $dDate, 'value' => $since, 'operator' => '>=']];
if ($dType && $tp !== '') $flt[] = ['key' => $dType, 'value' => $tp, 'operator' => '='];
for ($page = 1; $page <= $maxPages; $page++) {
$tq = microtime(true);
$r = $mago->getDataTable($detT, ['fields' => $fields, 'filters' => $flt, 'recordsPerPage' => 200, 'pageNumber' => $page]);
$total = $r['total'];
fwrite(STDERR, sprintf(" tipo %s · pagina %d: %d righe su %s (%.1f s)\n", $tp, $page, $r['count'], num($total), microtime(true) - $tq));
if (!$r['records']) break;
foreach ($r['records'] as $rec) {
$read++;
$item = trim((string)($rec[$dItem] ?? ''));
$qty = MagoClient::toDecimal($rec[$dQty] ?? 0);
if ($item === '' || $qty == 0) continue;
$val = $dVal ? MagoClient::toDecimal($rec[$dVal]) : 0;
if ($val == 0 && $dUnit) $val = $qty * MagoClient::toDecimal($rec[$dUnit]);
$date = MagoClient::toMysqlDate($rec[$dDate] ?? null);
$supp = $dSupp ? (string)$rec[$dSupp] : '';
$lines++;
$it = &$items[$item];
$it['item'] = $item;
$it['desc'] = $it['desc'] ?? ($dDesc ? (string)$rec[$dDesc] : '');
$it['uom'][$dUom ? strtoupper(trim((string)$rec[$dUom])) : '?'] = 1;
$it['n'] = ($it['n'] ?? 0) + 1;
$it['qty'] = ($it['qty'] ?? 0) + $qty;
$it['val'] = ($it['val'] ?? 0) + $val;
$it['supp'][$hd['supp']] = 1;
if (($it['last'] ?? '') <= $hd['date']) {
$it['last'] = $hd['date'];
$it['last_price'] = $qty ? $val / $qty : 0;
}
unset($it);
$it = &$items[$item];
$it['item'] = $item;
$it['desc'] = $it['desc'] ?? ($dDesc ? (string)$rec[$dDesc] : '');
$it['uom'][$dUom ? strtoupper(trim((string)$rec[$dUom])) : '?'] = 1;
$it['n'] = ($it['n'] ?? 0) + 1;
$it['qty'] = ($it['qty'] ?? 0) + $qty;
$it['val'] = ($it['val'] ?? 0) + $val;
$it['supp'][$supp] = 1;
if (($it['last'] ?? '') <= $date) {
$it['last'] = $date;
$it['last_price'] = $qty ? $val / $qty : 0;
}
unset($it);
$last[] = [$hd['date'], $hd['no'], $hd['supp'], $hd['type'], $item, $dDesc ? $rec[$dDesc] : '', $dUom ? $rec[$dUom] : '', $qty, $qty ? $val / $qty : 0, $val];
$last[] = [$date, $dNo ? $rec[$dNo] : '', $supp, $tp, $item, $dDesc ? $rec[$dDesc] : '', $dUom ? $rec[$dUom] : '', $qty, $qty ? $val / $qty : 0, $val];
}
if ($page * 200 >= $total) break;
}
if ($total !== null && $total > $maxPages * 200) echo "ATTENZIONE tipo $tp: lette " . num($maxPages * 200) . " righe su " . num($total) . " (aumenta --pages)\n";
}
$skipped = 0;
uasort($items, fn($a, $b) => $b['val'] <=> $a['val']);
/* nomi fornitori */