fixed import foglio di lavoro

This commit is contained in:
2026-10-26 13:56:01 +01:00
parent 2bac5d5b86
commit 0b9d5f5b40
3 changed files with 250 additions and 3 deletions
+99 -3
View File
@@ -177,6 +177,97 @@ function dotdec_to_comma($v)
return preg_replace('/(\d)\.(\d)/', '$1,$2', (string)$v);
}
/* ---- sezione "Imballo e confezionamento" ---- */
/** primo numero intero della cella ("80", "160 m", "12 o 14" -> 12) */
function first_int($v)
{
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 ha più numeri alternativi? ("12 o 14") */
function has_multi_num($v)
{
return preg_match_all('/\d+/', (string)$v) > 1;
}
function is_tolerance_txt($v)
{
$v = strtolower((string)$v);
return strpos($v, 'toll') !== false || preg_match('/[+-]\s*\d/', $v);
}
function fmt_num($n)
{
$f = (float)$n;
return (floor($f) == $f) ? (string)(int)$f : rtrim(rtrim(number_format($f, 2, '.', ''), '0'), '.');
}
/** "Toll Metrat. + 1,5m/-0" -> "-0/+1.5m" "+/- 4m" -> "+/- 4m" */
function parse_tolerance($v)
{
$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 '+/- ' . fmt_num($m[1]) . 'm';
}
$plus = preg_match('/\+\s*' . $num . '/', $s, $mp) ? fmt_num($mp[1]) : null;
$minus = preg_match('/-\s*' . $num . '/', $s, $mm) ? fmt_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 extract_packaging($grid)
{
$out = [
'meters_per_package' => null,
'meters_per_package_tolerance' => '',
'meters_per_package_notes' => '',
'packages_or_pieces_per_box' => null,
'meters_per_box' => null,
'boxes_or_packages_per_pallet' => null,
];
$notes = [];
// metri/confezione: valore in D, note in E, tolleranza in E o nelle righe sotto senza etichetta
$r = row_by_label($grid, 'metri/confezione');
if ($r) {
$d = cell($grid, $r, 'D');
$out['meters_per_package'] = first_int($d);
$cand = [cell($grid, $r, 'E')];
for ($i = $r + 1; $i <= $r + 3 && norm(cell($grid, $i, 'A')) === ''; $i++) {
$cand[] = cell($grid, $i, 'D');
$cand[] = cell($grid, $i, 'E');
}
if (is_tolerance_txt($d) && has_multi_num($d)) $cand[] = $d; // "80 +1,5/-0" nella stessa cella
foreach ($cand as $c) {
if ($c === '') continue;
if ($out['meters_per_package_tolerance'] === '' && is_tolerance_txt($c)) {
$out['meters_per_package_tolerance'] = parse_tolerance($c);
} elseif (!is_tolerance_txt($c)) {
$notes[] = $c; // es. "40x2"
}
}
}
$v = val_at_label($grid, 'n confezioni o pezzi per scatola', 'D');
$out['packages_or_pieces_per_box'] = first_int($v);
if (has_multi_num($v)) $notes[] = 'Conf. x scatola ' . $v;
$out['meters_per_box'] = first_int(val_at_label($grid, 'metri/scatola', 'D'));
// "12 o 14": nel campo numerico va 12, il testo completo nelle note
$v = val_at_label($grid, 'n confezioni o scatole per bancale', 'D');
$out['boxes_or_packages_per_pallet'] = first_int($v);
if (has_multi_num($v)) $notes[] = 'Scatole x Bancale ' . $v;
$out['meters_per_package_notes'] = implode('. ', array_unique($notes));
return $out;
}
function extract_fields($grid)
{
$out = [];
@@ -229,8 +320,8 @@ function extract_fields($grid)
$out['pkg_scatola_raw'] = val_at_label($grid, 'tipo scatola', 'D');
$out['pkg_bancale_raw'] = val_at_label($grid, 'tipo di bancale', 'D');
$out['packages_or_pieces_per_box'] = num_or_null(val_at_label($grid, 'n confezioni o pezzi per scatola', 'D'));
$out['boxes_or_packages_per_pallet'] = num_or_null(val_at_label($grid, 'n confezioni o scatole per bancale', 'D'));
// metri/confezione, tolleranza, note, pezzi per scatola, metri/scatola, scatole per bancale
$out = array_merge($out, extract_packaging($grid));
// velocità
$out['speed_expected_kg_h'] = null;
@@ -250,7 +341,8 @@ function extract_fields($grid)
// note: annotazioni libere colonna E + righe istruzione in fondo
$noteBits = [];
foreach (['confezione richiesta', 'metri/confezione', 'metri/scatola'] as $lbl) {
// (metri/confezione colonna E ora va in "Note metri/confezione")
foreach (['confezione richiesta', 'metri/scatola'] as $lbl) {
$rr = row_by_label($grid, $lbl);
if ($rr && cell($grid, $rr, 'E') !== '') $noteBits[] = cell($grid, $rr, 'E');
}
@@ -523,6 +615,10 @@ try {
'profile_type_code' => $fields['profile_type_code'],
'marking' => $fields['marking'],
'prod_control_measure_settings' => $fields['prod_control_measure_settings'],
'meters_per_package' => $fields['meters_per_package'],
'meters_per_package_tolerance' => $fields['meters_per_package_tolerance'],
'meters_per_package_notes' => $fields['meters_per_package_notes'],
'meters_per_box' => $fields['meters_per_box'],
'packages_or_pieces_per_box' => $fields['packages_or_pieces_per_box'],
'boxes_or_packages_per_pallet' => $fields['boxes_or_packages_per_pallet'],
'speed_expected_kg_h' => $fields['speed_expected_kg_h'],
+8
View File
@@ -2207,6 +2207,14 @@ $isEdit = ($worksheet_id > 0);
setVal('profile_type_code', h.profile_type_code);
setVal('marking', h.marking);
setVal('prod_control_measure_settings', h.prod_control_measure_settings);
setVal('meters_per_package', h.meters_per_package);
setVal('meters_per_package_tolerance', h.meters_per_package_tolerance);
setVal('meters_per_package_notes', h.meters_per_package_notes);
setVal('meters_per_box', h.meters_per_box);
setVal('meters_per_package', h.meters_per_package);
setVal('meters_per_package_tolerance', h.meters_per_package_tolerance);
setVal('meters_per_package_notes', h.meters_per_package_notes);
setVal('meters_per_box', h.meters_per_box);
setVal('packages_or_pieces_per_box', h.packages_or_pieces_per_box);
setVal('boxes_or_packages_per_pallet', h.boxes_or_packages_per_pallet);
setVal('speed_expected_kg_h', h.speed_expected_kg_h);
+143
View File
@@ -0,0 +1,143 @@
<?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'), '.');
}