Skip to content

Commit 8c2dbd8

Browse files
committed
refactor: ottimizzazione invio fatture elettroniche da coda di invio con campo fe_failed_at
1 parent d26b445 commit 8c2dbd8

2 files changed

Lines changed: 124 additions & 107 deletions

File tree

plugins/exportFE/src/InvoiceHookTask.php

Lines changed: 120 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525

2626
class InvoiceHookTask extends Manager
2727
{
28+
private const MAX_ATTEMPTS = 3;
29+
2830
public function execute()
2931
{
3032
$result = [
@@ -51,126 +53,138 @@ public function execute()
5153

5254
foreach ($fatture as $fattura) {
5355
try {
54-
// Verifica che la fattura elettronica sia ancora valida
55-
$fattura_elettronica = new FatturaElettronica($fattura->id);
56-
if (!$fattura_elettronica->isGenerated()) {
57-
// Fattura elettronica non più valida, rimuovi dalla coda
58-
$fattura->hook_send = false;
59-
$fattura->codice_stato_fe = 'GEN';
60-
$fattura->data_stato_fe = date('Y-m-d H:i:s');
61-
$fattura->fe_retry_count = 0;
62-
$fattura->save();
63-
continue;
64-
}
65-
66-
$response_invio = Interaction::sendInvoice($fattura->id);
67-
68-
if ($response_invio['code'] == 200 || $response_invio['code'] == 301) {
69-
// Invio riuscito
70-
$fattura->hook_send = false;
71-
$fattura->fe_retry_count = 0;
72-
$fattura->save();
73-
++$inviate;
74-
} else {
75-
// Incrementa il contatore dei tentativi
76-
$fattura->fe_retry_count = ($fattura->fe_retry_count ?? 0) + 1;
77-
78-
// Verifica se sono stati raggiunti i 3 tentativi
79-
if ($fattura->fe_retry_count >= 3) {
80-
// Rimuovi dalla coda e imposta errore definitivo
81-
$fattura->hook_send = false;
82-
$fattura->codice_stato_fe = 'ERR';
83-
$fattura->save();
84-
++$errori;
85-
$fatture_errore[] = $fattura->numero_esterno.' ('.$response_invio['message'].')';
86-
} else {
87-
// Mantieni nella coda per un nuovo tentativo
88-
$fattura->codice_stato_fe = 'QUEUE';
89-
$fattura->data_stato_fe = date('Y-m-d H:i:s');
90-
$fattura->save();
91-
++$in_attesa;
92-
}
93-
}
56+
$this->processInvoice($fattura, $inviate, $errori, $in_attesa, $fatture_errore);
9457
} catch (\UnexpectedValueException) {
95-
// Fattura elettronica non valida, rimuovi dalla coda
96-
$fattura->hook_send = false;
97-
$fattura->codice_stato_fe = 'GEN';
98-
$fattura->fe_retry_count = 0;
99-
$fattura->save();
58+
$this->resetInvoice($fattura);
10059
} catch (\Exception $e) {
101-
// Incrementa il contatore dei tentativi
102-
$fattura->fe_retry_count = ($fattura->fe_retry_count ?? 0) + 1;
103-
104-
// Verifica se sono stati raggiunti i 3 tentativi
105-
if ($fattura->fe_retry_count >= 3) {
106-
// Errore generico, rimuovi dalla coda e imposta errore definitivo
107-
$fattura->hook_send = false;
108-
$fattura->codice_stato_fe = 'ERR';
109-
$fattura->save();
110-
++$errori;
111-
$fatture_errore[] = $fattura->numero_esterno.' (errore: '.$e->getMessage().')';
112-
113-
// Log dell'errore per debugging
114-
logger_osm()->error('Errore invio FE per fattura '.$fattura->numero_esterno.': '.$e->getMessage());
115-
} else {
116-
// Mantieni nella coda per un nuovo tentativo
117-
$fattura->codice_stato_fe = 'QUEUE';
118-
$fattura->data_stato_fe = date('Y-m-d H:i:s');
119-
$fattura->save();
120-
++$in_attesa;
121-
122-
// Log dell'errore per debugging
123-
logger_osm()->warning('Tentativo '.$fattura->fe_retry_count.'/3 per fattura '.$fattura->numero_esterno.': '.$e->getMessage());
124-
}
60+
$this->handleInvoiceException($fattura, $e, $errori, $in_attesa, $fatture_errore);
12561
}
12662
}
12763

128-
// Costruzione messaggio di risposta
129-
if ($inviate > 0 && $errori == 0 && $in_attesa == 0) {
130-
$result['message'] = tr('_NUM_ fatture elettroniche inviate correttamente!', ['_NUM_' => $inviate]);
131-
} elseif ($inviate > 0 && $errori == 0 && $in_attesa > 0) {
132-
$result['response'] = 2;
133-
$result['message'] = tr('_SENT_ fatture inviate correttamente, _WAIT_ in attesa di nuovo tentativo (max 3)', [
134-
'_SENT_' => $inviate,
135-
'_WAIT_' => $in_attesa,
136-
]);
137-
} elseif ($inviate > 0 && $errori > 0) {
138-
$result['response'] = 2;
139-
$result['message'] = tr('_SENT_ fatture inviate, _ERR_ con errori, _WAIT_ in attesa di nuovo tentativo (max 3): _LIST_', [
140-
'_SENT_' => $inviate,
141-
'_ERR_' => $errori,
142-
'_WAIT_' => $in_attesa,
143-
'_LIST_' => implode(', ', $fatture_errore),
144-
]);
145-
} elseif ($errori > 0 && $in_attesa > 0) {
146-
$result['response'] = 2;
147-
$result['message'] = tr('Errori nell\'invio di _ERR_ fatture, _WAIT_ in attesa di nuovo tentativo (max 3): _LIST_', [
148-
'_ERR_' => $errori,
149-
'_WAIT_' => $in_attesa,
150-
'_LIST_' => implode(', ', $fatture_errore),
151-
]);
152-
} elseif ($errori > 0) {
153-
$result['response'] = 2;
154-
$result['message'] = tr('Errori nell\'invio di _ERR_ fatture: _LIST_', [
155-
'_ERR_' => $errori,
156-
'_LIST_' => implode(', ', $fatture_errore),
157-
]);
158-
} elseif ($in_attesa > 0) {
159-
$result['response'] = 2;
160-
$result['message'] = tr('_WAIT_ fatture in attesa di nuovo tentativo (max 3)', [
161-
'_WAIT_' => $in_attesa,
162-
]);
163-
}
64+
$this->buildResultMessage($result, $inviate, $errori, $in_attesa, $fatture_errore);
16465
} catch (\Exception $e) {
16566
$result['response'] = 2;
16667
$result['message'] = tr('Errore durante l\'invio delle fatture elettroniche: _ERR_', [
16768
'_ERR_' => $e->getMessage(),
16869
]).'<br>';
16970

170-
// Log dell'errore critico
17171
logger_osm()->error('Errore critico nel task invio FE: '.$e->getMessage());
17272
}
17373

17474
return $result;
17575
}
76+
77+
private function processInvoice($fattura, &$inviate, &$errori, &$in_attesa, &$fatture_errore)
78+
{
79+
$fattura_elettronica = new FatturaElettronica($fattura->id);
80+
if (!$fattura_elettronica->isGenerated()) {
81+
$this->resetInvoice($fattura);
82+
return;
83+
}
84+
85+
$response_invio = Interaction::sendInvoice($fattura->id);
86+
87+
if ($response_invio['code'] == 200 || $response_invio['code'] == 301) {
88+
$fattura->hook_send = false;
89+
$fattura->fe_attempt = 0;
90+
$fattura->save();
91+
++$inviate;
92+
} else {
93+
$this->handleFailedAttempt($fattura, $response_invio['message'], $errori, $in_attesa, $fatture_errore);
94+
}
95+
}
96+
97+
private function resetInvoice($fattura)
98+
{
99+
$fattura->hook_send = false;
100+
$fattura->codice_stato_fe = 'GEN';
101+
$fattura->data_stato_fe = date('Y-m-d H:i:s');
102+
$fattura->fe_attempt = 0;
103+
$fattura->save();
104+
}
105+
106+
private function handleFailedAttempt($fattura, $message, &$errori, &$in_attesa, &$fatture_errore)
107+
{
108+
$fattura->fe_attempt = ($fattura->fe_attempt ?? 0) + 1;
109+
110+
if ($fattura->fe_attempt >= self::MAX_ATTEMPTS) {
111+
$this->markAsFailed($fattura, $message, $errori, $fatture_errore);
112+
} else {
113+
$this->keepInQueue($fattura, $in_attesa);
114+
}
115+
}
116+
117+
private function markAsFailed($fattura, $message, &$errori, &$fatture_errore)
118+
{
119+
$fattura->hook_send = false;
120+
$fattura->codice_stato_fe = 'ERR';
121+
$fattura->fe_failed_at = date('Y-m-d H:i:s');
122+
$fattura->save();
123+
++$errori;
124+
$fatture_errore[] = $fattura->numero_esterno.' ('.$message.')';
125+
}
126+
127+
private function keepInQueue($fattura, &$in_attesa)
128+
{
129+
$fattura->codice_stato_fe = 'QUEUE';
130+
$fattura->data_stato_fe = date('Y-m-d H:i:s');
131+
$fattura->save();
132+
++$in_attesa;
133+
}
134+
135+
private function handleInvoiceException($fattura, \Exception $e, &$errori, &$in_attesa, &$fatture_errore)
136+
{
137+
$fattura->fe_attempt = ($fattura->fe_attempt ?? 0) + 1;
138+
139+
if ($fattura->fe_attempt >= self::MAX_ATTEMPTS) {
140+
$this->markAsFailed($fattura, 'errore: '.$e->getMessage(), $errori, $fatture_errore);
141+
logger_osm()->error('Errore invio FE per fattura '.$fattura->numero_esterno.': '.$e->getMessage());
142+
} else {
143+
$this->keepInQueue($fattura, $in_attesa);
144+
logger_osm()->warning('Tentativo '.$fattura->fe_attempt.'/'.self::MAX_ATTEMPTS.' per fattura '.$fattura->numero_esterno.': '.$e->getMessage());
145+
}
146+
}
147+
148+
private function buildResultMessage(&$result, $inviate, $errori, $in_attesa, $fatture_errore)
149+
{
150+
if ($inviate > 0 && $errori == 0 && $in_attesa == 0) {
151+
$result['message'] = tr('_NUM_ fatture elettroniche inviate correttamente!', ['_NUM_' => $inviate]);
152+
} elseif ($inviate > 0 && $errori == 0 && $in_attesa > 0) {
153+
$result['response'] = 2;
154+
$result['message'] = tr('_SENT_ fatture inviate correttamente, _WAIT_ in attesa di nuovo tentativo (max _MAX_)', [
155+
'_SENT_' => $inviate,
156+
'_WAIT_' => $in_attesa,
157+
'_MAX_' => self::MAX_ATTEMPTS,
158+
]);
159+
} elseif ($inviate > 0 && $errori > 0) {
160+
$result['response'] = 2;
161+
$result['message'] = tr('_SENT_ fatture inviate, _ERR_ con errori, _WAIT_ in attesa di nuovo tentativo (max _MAX_): _LIST_', [
162+
'_SENT_' => $inviate,
163+
'_ERR_' => $errori,
164+
'_WAIT_' => $in_attesa,
165+
'_MAX_' => self::MAX_ATTEMPTS,
166+
'_LIST_' => implode(', ', $fatture_errore),
167+
]);
168+
} elseif ($errori > 0 && $in_attesa > 0) {
169+
$result['response'] = 2;
170+
$result['message'] = tr('Errori nell\'invio di _ERR_ fatture, _WAIT_ in attesa di nuovo tentativo (max _MAX_): _LIST_', [
171+
'_ERR_' => $errori,
172+
'_WAIT_' => $in_attesa,
173+
'_MAX_' => self::MAX_ATTEMPTS,
174+
'_LIST_' => implode(', ', $fatture_errore),
175+
]);
176+
} elseif ($errori > 0) {
177+
$result['response'] = 2;
178+
$result['message'] = tr('Errori nell\'invio di _ERR_ fatture: _LIST_', [
179+
'_ERR_' => $errori,
180+
'_LIST_' => implode(', ', $fatture_errore),
181+
]);
182+
} elseif ($in_attesa > 0) {
183+
$result['response'] = 2;
184+
$result['message'] = tr('_WAIT_ fatture in attesa di nuovo tentativo (max _MAX_)', [
185+
'_WAIT_' => $in_attesa,
186+
'_MAX_' => self::MAX_ATTEMPTS,
187+
]);
188+
}
189+
}
176190
}

update/2_10_1.sql

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,7 @@ UPDATE `zz_plugins` SET `idmodule_from` = (SELECT `id` FROM `zz_modules` WHERE `
4848
UPDATE `zz_plugins` SET `idmodule_from` = (SELECT `id` FROM `zz_modules` WHERE `name` = "Anagrafiche") WHERE (`zz_plugins`.`name` = "Dichiarazioni d'intento");
4949

5050
-- Aggiunta campo per tracciare il numero di tentativi di invio FE
51-
ALTER TABLE `co_documenti` ADD `fe_retry_count` INT NOT NULL DEFAULT '0' AFTER `hook_send`;
51+
ALTER TABLE `co_documenti` ADD `fe_attempt` INT NOT NULL DEFAULT '0' AFTER `hook_send`;
52+
53+
-- Aggiunta campo per tracciare la data di fallimento definitivo dopo 3 tentativi
54+
ALTER TABLE `co_documenti` ADD `fe_failed_at` TIMESTAMP NULL AFTER `fe_attempt`;

0 commit comments

Comments
 (0)