Skip to content

Commit 5a9517a

Browse files
committed
feat: Implementazione plugin Barcode per articoli e miglioramento gestione codici a barre
1 parent a0349bd commit 5a9517a

8 files changed

Lines changed: 281 additions & 30 deletions

File tree

modules/articoli/actions.php

Lines changed: 77 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,42 @@
9393
$iva = post('idiva_vendita') ? Aliquota::find(post('idiva_vendita')) : null;
9494

9595
if (post('genera_barcode')) {
96-
$codice = '200'.str_pad((string) $articolo->id, 9, '0', STR_PAD_LEFT);
97-
$barcode = (new Picqer\Barcode\Types\TypeEan13())->getBarcode($codice)->getBarcode();
96+
// Genera un barcode unico controllando sia la tabella mg_articoli che mg_articoli_barcode
97+
// per evitare conflitti con barcode esistenti sia principali che aggiuntivi
98+
$tentativi = 0;
99+
$max_tentativi = 1000; // Limite massimo di tentativi per evitare loop infiniti
100+
101+
do {
102+
// Genera il codice EAN-13 basato sull'ID dell'articolo più il numero di tentativi
103+
$codice = '200'.str_pad((string) ($articolo->id + $tentativi), 9, '0', STR_PAD_LEFT);
104+
$barcode = (new Picqer\Barcode\Types\TypeEan13())->getBarcode($codice)->getBarcode();
105+
106+
// Controlla se il barcode è già presente nella tabella mg_articoli (barcode principali)
107+
$esistente_articoli = Articolo::where('barcode', $barcode)->count() > 0;
108+
109+
// Controlla se il barcode è già presente nella tabella mg_articoli_barcode (barcode aggiuntivi)
110+
$esistente_barcode = $dbo->table('mg_articoli_barcode')
111+
->where('barcode', $barcode)
112+
->count() > 0;
113+
114+
// Controlla se il barcode coincide con un codice articolo esistente
115+
// per evitare conflitti tra barcode e codici articolo
116+
$coincide_codice = Articolo::where([
117+
['codice', $barcode],
118+
['barcode', '=', '']
119+
])->count() > 0;
120+
121+
$tentativi++;
122+
123+
} while (($esistente_articoli || $esistente_barcode || $coincide_codice) && $tentativi < $max_tentativi);
124+
125+
// Se dopo tutti i tentativi non è stato trovato un barcode unico, non genera il barcode
126+
if ($tentativi >= $max_tentativi) {
127+
$barcode = null;
128+
flash()->warning(tr('Impossibile generare un barcode unico dopo _NUM_ tentativi', [
129+
'_NUM_' => $max_tentativi
130+
]));
131+
}
98132
}
99133

100134
$barcode = ($barcode ? $barcode : post('barcode'));
@@ -472,12 +506,48 @@
472506
break;
473507

474508
case 'generate-barcode':
475-
$codice = '200'.str_pad((string) $id_record, 9, '0', STR_PAD_LEFT);
476-
$barcode = (new Picqer\Barcode\Types\TypeEan13())->getBarcode($codice)->getBarcode();
509+
// Genera un barcode unico controllando sia la tabella mg_articoli che mg_articoli_barcode
510+
// per garantire l'unicità anche considerando i barcode aggiuntivi degli articoli
511+
$tentativi = 0;
512+
$max_tentativi = 1000; // Limite massimo di tentativi per evitare loop infiniti
513+
514+
do {
515+
// Genera il codice EAN-13 basato sull'ID dell'articolo più il numero di tentativi
516+
$codice = '200'.str_pad((string) ($id_record + $tentativi), 9, '0', STR_PAD_LEFT);
517+
$barcode = (new Picqer\Barcode\Types\TypeEan13())->getBarcode($codice)->getBarcode();
477518

478-
echo json_encode([
479-
'barcode' => $barcode,
480-
]);
519+
// Controlla se il barcode è già presente nella tabella mg_articoli (barcode principali)
520+
$esistente_articoli = Articolo::where('barcode', $barcode)->count() > 0;
521+
522+
// Controlla se il barcode è già presente nella tabella mg_articoli_barcode (barcode aggiuntivi)
523+
$esistente_barcode = $dbo->table('mg_articoli_barcode')
524+
->where('barcode', $barcode)
525+
->count() > 0;
526+
527+
// Controlla se il barcode coincide con un codice articolo esistente
528+
// per evitare conflitti tra barcode e codici articolo
529+
$coincide_codice = Articolo::where([
530+
['codice', $barcode],
531+
['barcode', '=', '']
532+
])->count() > 0;
533+
534+
$tentativi++;
535+
536+
} while (($esistente_articoli || $esistente_barcode || $coincide_codice) && $tentativi < $max_tentativi);
537+
538+
// Se dopo tutti i tentativi non è stato trovato un barcode unico, restituisce un errore
539+
if ($tentativi >= $max_tentativi) {
540+
echo json_encode([
541+
'error' => tr('Impossibile generare un barcode unico dopo _NUM_ tentativi', [
542+
'_NUM_' => $max_tentativi
543+
])
544+
]);
545+
} else {
546+
// Restituisce il barcode generato con successo
547+
echo json_encode([
548+
'barcode' => $barcode,
549+
]);
550+
}
481551

482552
break;
483553
}

modules/articoli/bulk.php

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -444,16 +444,63 @@
444444
break;
445445

446446
case 'generate_barcode_bulk':
447+
// Contatori per tenere traccia dei risultati della generazione
448+
$barcode_generati = 0;
449+
$barcode_falliti = 0;
450+
451+
// Itera attraverso tutti gli articoli selezionati per la generazione barcode
447452
foreach ($id_records as $id) {
448-
$codice = '200'.str_pad((string) $id, 9, '0', STR_PAD_LEFT);
449-
$barcode = (new Picqer\Barcode\Types\TypeEan13())->getBarcode($codice)->getBarcode();
453+
// Genera un barcode unico controllando sia la tabella mg_articoli che mg_articoli_barcode
454+
// per garantire l'unicità anche considerando i barcode aggiuntivi degli articoli
455+
$tentativi = 0;
456+
$max_tentativi = 1000; // Limite massimo di tentativi per evitare loop infiniti
457+
$barcode = null;
458+
459+
do {
460+
// Genera il codice EAN-13 basato sull'ID dell'articolo più il numero di tentativi
461+
$codice = '200'.str_pad((string) ($id + $tentativi), 9, '0', STR_PAD_LEFT);
462+
$barcode = (new Picqer\Barcode\Types\TypeEan13())->getBarcode($codice)->getBarcode();
463+
464+
// Controlla se il barcode è già presente nella tabella mg_articoli (barcode principali)
465+
$esistente_articoli = Articolo::where('barcode', $barcode)->count() > 0;
466+
467+
// Controlla se il barcode è già presente nella tabella mg_articoli_barcode (barcode aggiuntivi)
468+
$esistente_barcode = $dbo->table('mg_articoli_barcode')
469+
->where('barcode', $barcode)
470+
->count() > 0;
471+
472+
// Controlla se il barcode coincide con un codice articolo esistente
473+
// per evitare conflitti tra barcode e codici articolo
474+
$coincide_codice = Articolo::where([
475+
['codice', $barcode],
476+
['barcode', '=', '']
477+
])->count() > 0;
478+
479+
$tentativi++;
480+
481+
} while (($esistente_articoli || $esistente_barcode || $coincide_codice) && $tentativi < $max_tentativi);
482+
483+
// Se è stato trovato un barcode unico, lo assegna all'articolo come barcode principale
484+
if ($tentativi < $max_tentativi) {
485+
$dbo->insert('mg_articoli_barcode', [
486+
'idarticolo' => $id,
487+
'barcode' => $barcode,
488+
]);
489+
$barcode_generati++;
490+
} else {
491+
// Se non è stato possibile generare un barcode unico, incrementa il contatore dei fallimenti
492+
$barcode_falliti++;
493+
}
494+
}
450495

451-
$articolo = Articolo::find($id);
452-
$articolo->barcode = $barcode;
453-
$articolo->save();
496+
// Mostra i messaggi di feedback all'utente
497+
if ($barcode_generati > 0) {
498+
flash()->info(tr('_NUM_ barcode generati correttamente!', ['_NUM_' => $barcode_generati]));
454499
}
455500

456-
flash()->info(tr('Barcode generati correttamente!'));
501+
if ($barcode_falliti > 0) {
502+
flash()->warning(tr('Impossibile generare _NUM_ barcode per conflitti con barcode esistenti', ['_NUM_' => $barcode_falliti]));
503+
}
457504

458505
break;
459506

modules/articoli/validation.php

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,24 @@
4242
break;
4343

4444
case 'barcode':
45+
// Controllo duplicati nella tabella principale mg_articoli (campo barcode)
46+
// Verifica che il barcode non sia già utilizzato come barcode principale di un altro articolo
4547
$disponibile = Articolo::where([
4648
['barcode', $value],
4749
['id', '<>', $id_record],
4850
])->count() == 0;
4951

52+
// Controllo duplicati nella tabella mg_articoli_barcode (barcode multipli)
53+
// Verifica che il barcode non sia già presente tra i barcode aggiuntivi di altri articoli
54+
if ($disponibile) {
55+
$disponibile = $dbo->table('mg_articoli_barcode')
56+
->where('barcode', $value)
57+
->where('idarticolo', '<>', $id_record)
58+
->count() == 0;
59+
}
60+
61+
// Controllo se il barcode coincide con un codice articolo esistente
62+
// Evita conflitti tra barcode e codici articolo per articoli senza barcode principale
5063
if ($disponibile) {
5164
$disponibile = Articolo::where([
5265
['codice', $value],
@@ -55,7 +68,7 @@
5568
])->count() == 0;
5669
}
5770

58-
$message = $disponibile ? tr('Il barcode è disponbile') : tr('Il barcode è già utilizzato in un altro articolo');
71+
$message = $disponibile ? tr('Il barcode è disponibile') : tr('Il barcode è già utilizzato in un altro articolo o nei suoi barcode aggiuntivi');
5972

6073
$response = [
6174
'result' => $disponibile,

plugins/barcode_articoli/actions.php

Lines changed: 62 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,30 +19,80 @@
1919

2020
include_once __DIR__.'/../../core.php';
2121

22+
use Modules\Articoli\Articolo;
23+
2224
$operazione = filter('op');
2325

2426
switch ($operazione) {
2527
case 'addbarcode':
2628
if (!empty(post('barcode'))) {
27-
$dbo->insert('mg_articoli_barcode', [
28-
'idarticolo' => $id_parent,
29-
'barcode' => post('barcode'),
30-
]);
31-
$id_record = $dbo->lastInsertedID();
32-
33-
flash()->info(tr('Aggiunto un nuovo barcode!'));
29+
// Controllo aggiuntivo per verificare l'unicità del barcode prima dell'inserimento
30+
// anche se la validazione dovrebbe già averlo controllato
31+
$barcode_value = post('barcode');
32+
33+
// Verifica che il barcode non sia già presente nella tabella mg_articoli
34+
$esistente_articoli = Articolo::where('barcode', $barcode_value)->count() > 0;
35+
36+
// Verifica che il barcode non sia già presente nella tabella mg_articoli_barcode
37+
$esistente_barcode = $dbo->table('mg_articoli_barcode')
38+
->where('barcode', $barcode_value)
39+
->count() > 0;
40+
41+
// Verifica che il barcode non coincida con un codice articolo esistente
42+
$coincide_codice = Articolo::where([
43+
['codice', $barcode_value],
44+
['barcode', '=', '']
45+
])->count() > 0;
46+
47+
// Se il barcode è unico, procede con l'inserimento
48+
if (!$esistente_articoli && !$esistente_barcode && !$coincide_codice) {
49+
$dbo->insert('mg_articoli_barcode', [
50+
'idarticolo' => $id_parent,
51+
'barcode' => $barcode_value,
52+
]);
53+
$id_record = $dbo->lastInsertedID();
54+
55+
flash()->info(tr('Aggiunto un nuovo barcode!'));
56+
} else {
57+
flash()->error(tr('Il barcode è già utilizzato in un altro articolo o nei suoi barcode aggiuntivi'));
58+
}
3459
} else {
3560
flash()->warning(tr('Errore durante aggiunta del barcode'));
3661
}
3762

3863
break;
3964

4065
case 'updatebarcode':
41-
$dbo->update('mg_articoli_barcode', [
42-
'barcode' => post('barcode'),
43-
], ['id' => $id_record]);
44-
45-
flash()->info(tr('Salvataggio completato!'));
66+
// Controllo aggiuntivo per verificare l'unicità del barcode prima dell'aggiornamento
67+
// anche se la validazione dovrebbe già averlo controllato
68+
$barcode_value = post('barcode');
69+
70+
// Verifica che il barcode non sia già presente nella tabella mg_articoli
71+
$esistente_articoli = Articolo::where('barcode', $barcode_value)->count() > 0;
72+
73+
// Verifica che il barcode non sia già presente nella tabella mg_articoli_barcode
74+
// escludendo il record corrente che stiamo modificando
75+
$esistente_barcode = $dbo->table('mg_articoli_barcode')
76+
->where('barcode', $barcode_value)
77+
->where('id', '<>', $id_record)
78+
->count() > 0;
79+
80+
// Verifica che il barcode non coincida con un codice articolo esistente
81+
$coincide_codice = Articolo::where([
82+
['codice', $barcode_value],
83+
['barcode', '=', '']
84+
])->count() > 0;
85+
86+
// Se il barcode è unico, procede con l'aggiornamento
87+
if (!$esistente_articoli && !$esistente_barcode && !$coincide_codice) {
88+
$dbo->update('mg_articoli_barcode', [
89+
'barcode' => $barcode_value,
90+
], ['id' => $id_record]);
91+
92+
flash()->info(tr('Salvataggio completato!'));
93+
} else {
94+
flash()->error(tr('Il barcode è già utilizzato in un altro articolo o nei suoi barcode aggiuntivi'));
95+
}
4696

4797
break;
4898

plugins/barcode_articoli/add.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
<div class="row">
3232
<div class="col-md-12">
3333
<button type="button" class="btn btn-default btn-xs tip pull-right" id="generaBarcode"><i class="fa fa-refresh"></i> '.tr('Genera').'</button>
34-
{[ "type": "text", "label": "'.tr('Barcode').'", "name": "barcode", "validation": "barcode", "class": "text-center", "value": "" ]}
34+
{[ "type": "text", "label": "'.tr('Barcode').'", "name": "barcode", "validation": "barcode|'.$id_module.'|0", "class": "text-center", "value": "" ]}
3535
</div>
3636
</div>
3737

plugins/barcode_articoli/edit.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
<div class="row">
3838
<div class="col-md-12">
3939
<button type="button" class="btn btn-default btn-xs tip pull-right" id="generaBarcode"><i class="fa fa-refresh"></i> '.tr('Genera').'</button>
40-
{[ "type": "text", "label": "'.tr('Barcode').'", "name": "barcode", "required": 1, "value": "'.$barcode->barcode.'" ]}
40+
{[ "type": "text", "label": "'.tr('Barcode').'", "name": "barcode", "required": 1, "value": "'.$barcode->barcode.'", "validation": "barcode|'.$id_module.'|'.$id_record.'" ]}
4141
</div>
4242
</div>
4343
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
3+
/*
4+
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
5+
* Copyright (C) DevCode s.r.l.
6+
*
7+
* This program is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation, either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
19+
*/
20+
21+
include_once __DIR__.'/../../core.php';
22+
23+
use Modules\Articoli\Articolo;
24+
25+
$name = filter('name');
26+
$value = filter('value');
27+
28+
switch ($name) {
29+
case 'barcode':
30+
// Controllo duplicati nella tabella principale mg_articoli (campo barcode)
31+
// Verifica che il barcode non sia già utilizzato come barcode principale di un altro articolo
32+
$disponibile = Articolo::where([
33+
['barcode', $value],
34+
])->count() == 0;
35+
36+
// Controllo duplicati nella tabella mg_articoli_barcode (barcode multipli)
37+
// Verifica che il barcode non sia già presente tra i barcode aggiuntivi di altri articoli
38+
// Esclude il record corrente se stiamo modificando un barcode esistente
39+
if ($disponibile) {
40+
$query = $dbo->table('mg_articoli_barcode')
41+
->where('barcode', $value);
42+
43+
// Se stiamo modificando un barcode esistente, escludiamo il record corrente dalla verifica
44+
if (!empty($id_record) && $id_record != 0) {
45+
$query->where('id', '<>', $id_record);
46+
}
47+
48+
$disponibile = $query->count() == 0;
49+
}
50+
51+
// Controllo se il barcode coincide con un codice articolo esistente
52+
// Evita conflitti tra barcode e codici articolo per articoli senza barcode principale
53+
if ($disponibile) {
54+
$disponibile = Articolo::where([
55+
['codice', $value],
56+
['barcode', '=', ''],
57+
])->count() == 0;
58+
}
59+
60+
$message = $disponibile ? tr('Il barcode è disponibile') : tr('Il barcode è già utilizzato in un altro articolo o nei suoi barcode aggiuntivi');
61+
62+
$response = [
63+
'result' => $disponibile,
64+
'message' => $message,
65+
];
66+
67+
break;
68+
}

0 commit comments

Comments
 (0)