2626use Modules \Anagrafiche \Tipo as TipoAnagrafica ;
2727use Modules \Articoli \Articolo as ArticoloOriginale ;
2828use Modules \Preventivi \Components \Articolo ;
29+ use Modules \Preventivi \Components \Riga ;
2930use Modules \Preventivi \Preventivo ;
3031use Modules \Preventivi \Stato ;
3132use Modules \TipiIntervento \Tipo as TipoSessione ;
33+ use Modules \Iva \Aliquota ;
3234
3335/**
3436 * Struttura per la gestione delle operazioni di importazione (da CSV) dei Preventivi.
@@ -65,6 +67,10 @@ public function getAvailableFields()
6567 'label ' => 'Cliente ' ,
6668 'required ' => true ,
6769 ],
70+ [
71+ 'field ' => 'partita_iva ' ,
72+ 'label ' => 'Partita IVA Cliente ' ,
73+ ],
6874 [
6975 'field ' => 'idtipointervento ' ,
7076 'label ' => 'Tipo attività ' ,
@@ -77,12 +83,18 @@ public function getAvailableFields()
7783 [
7884 'field ' => 'codice ' ,
7985 'label ' => 'Codice articolo ' ,
80- 'required ' => true ,
86+ ],
87+ [
88+ 'field ' => 'descrizione_riga ' ,
89+ 'label ' => 'Descrizione riga generica ' ,
90+ ],
91+ [
92+ 'field ' => 'aliquota_iva ' ,
93+ 'label ' => 'Aliquota IVA riga (%) ' ,
8194 ],
8295 [
8396 'field ' => 'qta ' ,
8497 'label ' => 'Quantità riga ' ,
85- 'required ' => true ,
8698 ],
8799 [
88100 'field ' => 'data_evasione ' ,
@@ -112,8 +124,12 @@ public function import($record, $update_record = true, $add_record = true)
112124
113125 // Validazione dei campi obbligatori
114126 if (empty ($ record ['numero ' ]) || empty ($ record ['nome ' ]) || empty ($ record ['ragione_sociale ' ])
115- || empty ($ record ['data_bozza ' ]) || empty ($ record ['codice ' ]) || empty ($ record ['qta ' ])
116- || empty ($ record ['prezzo_unitario ' ])) {
127+ || empty ($ record ['data_bozza ' ]) || empty ($ record ['prezzo_unitario ' ])) {
128+ return false ;
129+ }
130+
131+ // Validazione per righe: deve essere presente codice articolo O descrizione riga
132+ if (empty ($ record ['codice ' ]) && empty ($ record ['descrizione_riga ' ])) {
117133 return false ;
118134 }
119135
@@ -133,8 +149,8 @@ public function import($record, $update_record = true, $add_record = true)
133149 }
134150 }
135151
136- // Aggiunta dell'articolo al preventivo
137- $ this ->aggiungiArticoloAlPreventivo ($ preventivo , $ record );
152+ // Aggiunta della riga al preventivo (articolo o riga generica)
153+ $ this ->aggiungiRigaAlPreventivo ($ preventivo , $ record );
138154
139155 return true ;
140156 } catch (\Exception $ e ) {
@@ -153,9 +169,10 @@ public function import($record, $update_record = true, $add_record = true)
153169 public static function getExample ()
154170 {
155171 return [
156- ['Numero ' , 'Nome Preventivo ' , 'Descrizione Preventivo ' , 'Cliente ' , 'Tipo Attività ' , 'Data ' , 'Codice Articolo ' , 'Quantità riga ' , 'Data prevista evasione riga ' , 'Prezzo unitario riga ' ],
157- ['15 ' , 'Preventivo Materiali ' , 'Preventivo iniziale ' , 'Rossi ' , 'Generico ' , '27/04/2024 ' , '001 ' , '2 ' , '30/04/2024 ' , '50 ' ],
158- ['15 ' , 'Preventivo Materiali ' , 'Preventivo iniziale ' , 'Rossi ' , 'Generico ' , '27/04/2024 ' , '043 ' , '1 ' , '10/05/2024 ' , '100 ' ],
172+ ['Numero ' , 'Nome Preventivo ' , 'Descrizione Preventivo ' , 'Cliente ' , 'Partita IVA Cliente ' , 'Tipo Attività ' , 'Data ' , 'Codice Articolo ' , 'Descrizione riga generica ' , 'Aliquota IVA riga (%) ' , 'Quantità riga ' , 'Data prevista evasione riga ' , 'Prezzo unitario riga ' ],
173+ ['15 ' , 'Preventivo Materiali ' , 'Preventivo iniziale ' , 'Rossi ' , '12345678901 ' , 'Generico ' , '27/04/2024 ' , '001 ' , '' , '' , '2 ' , '30/04/2024 ' , '50 ' ],
174+ ['15 ' , 'Preventivo Materiali ' , 'Preventivo iniziale ' , 'Rossi ' , '12345678901 ' , 'Generico ' , '27/04/2024 ' , '043 ' , '' , '' , '1 ' , '10/05/2024 ' , '100 ' ],
175+ ['16 ' , 'Preventivo Servizi ' , 'Preventivo servizi ' , 'Bianchi ' , '98765432109 ' , 'Generico ' , '28/04/2024 ' , '' , 'Consulenza tecnica ' , '22 ' , '1 ' , '05/05/2024 ' , '150 ' ],
159176 ];
160177 }
161178
@@ -225,10 +242,27 @@ protected function trovaOCreaAnagrafica($record)
225242 return null ;
226243 }
227244
228- $ anagrafica = Anagrafica::where ('ragione_sociale ' , $ record ['ragione_sociale ' ])->first ();
245+ $ anagrafica = null ;
246+
247+ // Prima ricerca per partita IVA se presente
248+ if (!empty ($ record ['partita_iva ' ])) {
249+ $ anagrafica = Anagrafica::where ('piva ' , $ record ['partita_iva ' ])->first ();
250+ }
251+
252+ // Se non trovata per partita IVA, ricerca per ragione sociale
253+ if (empty ($ anagrafica )) {
254+ $ anagrafica = Anagrafica::where ('ragione_sociale ' , $ record ['ragione_sociale ' ])->first ();
255+ }
229256
257+ // Se non trovata, crea nuova anagrafica
230258 if (empty ($ anagrafica )) {
231259 $ anagrafica = Anagrafica::build ($ record ['ragione_sociale ' ]);
260+
261+ // Imposta la partita IVA se fornita
262+ if (!empty ($ record ['partita_iva ' ])) {
263+ $ anagrafica ->partita_iva = $ record ['partita_iva ' ];
264+ }
265+
232266 $ tipo_cliente = TipoAnagrafica::where ('name ' , 'Cliente ' )->first ()->id ;
233267 $ anagrafica ->tipologie = [$ tipo_cliente ];
234268 $ anagrafica ->save ();
@@ -250,22 +284,49 @@ protected function trovaTipoIntervento($record)
250284 }
251285
252286 /**
253- * Aggiunge un articolo al preventivo.
287+ * Aggiunge una riga al preventivo (articolo o riga generica) .
254288 *
255289 * @param Preventivo $preventivo Preventivo
256290 * @param array $record Record da importare
257291 *
258292 * @return bool
259293 */
260- protected function aggiungiArticoloAlPreventivo ($ preventivo , $ record )
294+ protected function aggiungiRigaAlPreventivo ($ preventivo , $ record )
261295 {
262296 try {
263- // Individuazione articolo
264- $ articolo_orig = ArticoloOriginale::where ('codice ' , $ record ['codice ' ])->first ();
265- if (empty ($ articolo_orig )) {
266- return false ;
297+ // Se è presente il codice articolo, prova a creare una riga articolo
298+ if (!empty ($ record ['codice ' ])) {
299+ $ articolo_orig = ArticoloOriginale::where ('codice ' , $ record ['codice ' ])->first ();
300+ if (!empty ($ articolo_orig )) {
301+ return $ this ->aggiungiArticoloAlPreventivo ($ preventivo , $ record , $ articolo_orig );
302+ }
267303 }
268304
305+ // Se non è un articolo o l'articolo non è stato trovato, crea una riga generica
306+ if (!empty ($ record ['descrizione_riga ' ])) {
307+ return $ this ->aggiungiRigaGenericaAlPreventivo ($ preventivo , $ record );
308+ }
309+
310+ return false ;
311+ } catch (\Exception $ e ) {
312+ error_log ('Errore durante l \'aggiunta della riga al preventivo: ' .$ e ->getMessage ());
313+
314+ return false ;
315+ }
316+ }
317+
318+ /**
319+ * Aggiunge un articolo al preventivo.
320+ *
321+ * @param Preventivo $preventivo Preventivo
322+ * @param array $record Record da importare
323+ * @param ArticoloOriginale $articolo_orig Articolo originale
324+ *
325+ * @return bool
326+ */
327+ protected function aggiungiArticoloAlPreventivo ($ preventivo , $ record , $ articolo_orig )
328+ {
329+ try {
269330 $ riga_articolo = Articolo::build ($ preventivo , $ articolo_orig );
270331 $ riga_articolo ->um = $ articolo_orig ->um ?: null ;
271332
@@ -280,7 +341,7 @@ protected function aggiungiArticoloAlPreventivo($preventivo, $record)
280341
281342 $ riga_articolo ->descrizione = $ articolo_orig ->getTranslation ('title ' );
282343 $ riga_articolo ->setPrezzoUnitario ($ record ['prezzo_unitario ' ], $ idiva );
283- $ riga_articolo ->qta = $ record ['qta ' ];
344+ $ riga_articolo ->qta = ! empty ( $ record ['qta ' ]) ? $ record [ ' qta ' ] : 1 ;
284345
285346 $ riga_articolo ->save ();
286347
@@ -292,6 +353,64 @@ protected function aggiungiArticoloAlPreventivo($preventivo, $record)
292353 }
293354 }
294355
356+ /**
357+ * Aggiunge una riga generica al preventivo.
358+ *
359+ * @param Preventivo $preventivo Preventivo
360+ * @param array $record Record da importare
361+ *
362+ * @return bool
363+ */
364+ protected function aggiungiRigaGenericaAlPreventivo ($ preventivo , $ record )
365+ {
366+ try {
367+ $ riga = Riga::build ($ preventivo );
368+
369+ // Gestione della data di evasione
370+ if (!empty ($ record ['data_evasione ' ])) {
371+ $ riga ->data_evasione = $ this ->parseData ($ record ['data_evasione ' ]);
372+ }
373+
374+ // Gestione dell'IVA
375+ $ idiva = $ this ->trovaAliquotaIva ($ record , $ preventivo );
376+
377+ $ riga ->descrizione = $ record ['descrizione_riga ' ];
378+ $ riga ->setPrezzoUnitario ($ record ['prezzo_unitario ' ], $ idiva );
379+ $ riga ->qta = !empty ($ record ['qta ' ]) ? $ record ['qta ' ] : 1 ;
380+
381+ $ riga ->save ();
382+
383+ return true ;
384+ } catch (\Exception $ e ) {
385+ error_log ('Errore durante l \'aggiunta della riga generica al preventivo: ' .$ e ->getMessage ());
386+
387+ return false ;
388+ }
389+ }
390+
391+ /**
392+ * Trova l'aliquota IVA da utilizzare per la riga.
393+ *
394+ * @param array $record Record da importare
395+ * @param Preventivo $preventivo Preventivo
396+ *
397+ * @return int ID dell'aliquota IVA
398+ */
399+ protected function trovaAliquotaIva ($ record , $ preventivo )
400+ {
401+ // Se è specificata un'aliquota IVA nel record, cerca per percentuale
402+ if (!empty ($ record ['aliquota_iva ' ])) {
403+ $ aliquota = Aliquota::where ('percentuale ' , $ record ['aliquota_iva ' ])->first ();
404+ if (!empty ($ aliquota )) {
405+ return $ aliquota ->id ;
406+ }
407+ }
408+
409+ // Fallback: usa l'IVA dell'anagrafica o quella predefinita
410+ $ anagrafica = $ preventivo ->anagrafica ;
411+ return $ anagrafica ->idiva_vendite ?: setting ('Iva predefinita ' );
412+ }
413+
295414 /**
296415 * Converte una stringa data in un oggetto Carbon.
297416 *
0 commit comments