144 lines
5.1 KiB
PHP
144 lines
5.1 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Lettura sezione "Imballo e confezionamento" dal foglio di lavoro Excel (mod. 7.5.1-5).
|
|
*
|
|
* $rows = foglio come array di righe, indici numerici da 0
|
|
* (es. PhpSpreadsheet: $sheet->toArray(null, true, false, false)).
|
|
* Restituisce solo le chiavi trovate:
|
|
* meters_per_package, meters_per_package_tolerance, meters_per_package_notes,
|
|
* packages_or_pieces_per_box, meters_per_box, boxes_or_packages_per_pallet
|
|
*/
|
|
function ws_parse_packaging(array $rows): array
|
|
{
|
|
$out = [];
|
|
$notes = [];
|
|
|
|
// indicizza le righe: etichetta (colonne A-C) + valori (dalla colonna D)
|
|
$list = [];
|
|
foreach ($rows as $r) {
|
|
$r = array_values((array)$r);
|
|
$label = ws_pk_norm(implode(' ', array_map('strval', array_slice($r, 0, 3))));
|
|
$vals = [];
|
|
foreach (array_slice($r, 3) as $v) {
|
|
$v = trim((string)$v);
|
|
if ($v !== '') $vals[] = $v;
|
|
}
|
|
$list[] = ['label' => $label, 'vals' => $vals];
|
|
}
|
|
|
|
$n = count($list);
|
|
for ($i = 0; $i < $n; $i++) {
|
|
$label = $list[$i]['label'];
|
|
$vals = $list[$i]['vals'];
|
|
if ($label === '') continue;
|
|
|
|
// righe successive senza etichetta (continuazione: tolleranze, note)
|
|
$extra = [];
|
|
for ($j = $i + 1; $j < $n && $list[$j]['label'] === ''; $j++) {
|
|
$extra = array_merge($extra, $list[$j]['vals']);
|
|
}
|
|
|
|
// --- metri / confezione ---
|
|
if (preg_match('/^metri\s*\/?\s*confezion/', $label)) {
|
|
$first = $vals[0] ?? '';
|
|
$num = ws_pk_int($first);
|
|
if ($num !== null) $out['meters_per_package'] = $num;
|
|
|
|
$tol = null;
|
|
foreach (array_merge(array_slice($vals, 1), $extra) as $v) {
|
|
if ($tol === null && ws_pk_is_tolerance($v)) {
|
|
$tol = ws_pk_tolerance($v);
|
|
} elseif (!ws_pk_is_tolerance($v)) {
|
|
$notes[] = $v; // es. "40x2"
|
|
}
|
|
}
|
|
// la tolleranza a volte è nella stessa cella del valore
|
|
if ($tol === null && ws_pk_is_tolerance($first)) $tol = ws_pk_tolerance($first);
|
|
if ($tol !== null) $out['meters_per_package_tolerance'] = $tol;
|
|
continue;
|
|
}
|
|
|
|
// --- n° confezioni o pezzi per scatola ---
|
|
if (strpos($label, 'per scatola') !== false && strpos($label, 'confezion') !== false) {
|
|
$num = ws_pk_int($vals[0] ?? '');
|
|
if ($num !== null) $out['packages_or_pieces_per_box'] = $num;
|
|
if (ws_pk_multi($vals[0] ?? '')) $notes[] = 'Conf. x scatola ' . $vals[0];
|
|
continue;
|
|
}
|
|
|
|
// --- metri / scatola ---
|
|
if (preg_match('/^metri\s*\/?\s*scatol/', $label)) {
|
|
$num = ws_pk_int($vals[0] ?? '');
|
|
if ($num !== null) $out['meters_per_box'] = $num;
|
|
continue;
|
|
}
|
|
|
|
// --- n° confezioni o scatole per bancale ---
|
|
if (strpos($label, 'bancale') !== false && strpos($label, 'tipo') === false) {
|
|
$num = ws_pk_int($vals[0] ?? '');
|
|
if ($num !== null) $out['boxes_or_packages_per_pallet'] = $num;
|
|
// "12 o 14": nel campo numerico va 12, il testo completo nelle note
|
|
if (ws_pk_multi($vals[0] ?? '')) $notes[] = 'Scatole x Bancale ' . $vals[0];
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if ($notes) {
|
|
$out['meters_per_package_notes'] = implode('. ', array_unique($notes));
|
|
}
|
|
return $out;
|
|
}
|
|
|
|
function ws_pk_norm($s): string
|
|
{
|
|
$s = mb_strtolower(trim((string)$s), 'UTF-8');
|
|
$s = str_replace(['°', 'º'], '', $s);
|
|
return trim(preg_replace('/\s+/', ' ', $s));
|
|
}
|
|
|
|
/** primo numero intero della cella ("80", "80.0", "12 o 14", "160 m") */
|
|
function ws_pk_int($v): ?int
|
|
{
|
|
if (is_int($v) || is_float($v)) return (int)round($v);
|
|
if (preg_match('/\d+(?:[.,]\d+)?/', (string)$v, $m)) {
|
|
return (int)round((float)str_replace(',', '.', $m[0]));
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/** la cella contiene più numeri alternativi? ("12 o 14", "12/14") */
|
|
function ws_pk_multi($v): bool
|
|
{
|
|
return preg_match_all('/\d+/', (string)$v) > 1;
|
|
}
|
|
|
|
function ws_pk_is_tolerance($v): bool
|
|
{
|
|
$v = mb_strtolower((string)$v, 'UTF-8');
|
|
return strpos($v, 'toll') !== false || preg_match('/[+-]\s*\d/', $v) || strpos($v, '+/-') !== false;
|
|
}
|
|
|
|
/** "Toll Metrat. + 1,5m/-0" → "-0/+1.5m" "+/- 4m" → "+/- 4m" */
|
|
function ws_pk_tolerance($v): string
|
|
{
|
|
$s = str_replace(',', '.', (string)$v);
|
|
$num = '(\d+(?:\.\d+)?)';
|
|
|
|
if (preg_match('/\+\s*\/\s*-\s*' . $num . '/', $s, $m) || preg_match('/±\s*' . $num . '/u', $s, $m)) {
|
|
return '+/- ' . ws_pk_num($m[1]) . 'm';
|
|
}
|
|
$plus = preg_match('/\+\s*' . $num . '/', $s, $mp) ? ws_pk_num($mp[1]) : null;
|
|
$minus = preg_match('/-\s*' . $num . '/', $s, $mm) ? ws_pk_num($mm[1]) : null;
|
|
if ($plus !== null || $minus !== null) {
|
|
return '-' . ($minus ?? '0') . '/+' . ($plus ?? '0') . 'm';
|
|
}
|
|
return trim((string)$v); // formato non riconosciuto: testo originale
|
|
}
|
|
|
|
function ws_pk_num($n): string
|
|
{
|
|
$f = (float)$n;
|
|
return (floor($f) == $f) ? (string)(int)$f : rtrim(rtrim(number_format($f, 2, '.', ''), '0'), '.');
|
|
}
|