Skip to content

Commit 1f232b8

Browse files
feat: registrazione contabile automatica in base al pagamento
1 parent 946f062 commit 1f232b8

6 files changed

Lines changed: 247 additions & 3 deletions

File tree

modules/fatture/src/Gestori/Scadenze.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
namespace Modules\Fatture\Gestori;
2222

2323
use Modules\Fatture\Fattura;
24+
use Modules\PrimaNota\Movimento;
2425
use Modules\Scadenzario\Scadenza;
2526
use Plugins\AssicurazioneCrediti\AssicurazioneCrediti;
2627
use Plugins\ImportFE\FatturaElettronica as FatturaElettronicaImport;
@@ -127,6 +128,26 @@ protected function registraScadenza(Fattura $fattura, $importo, $data_scadenza,
127128
$assicurazione_crediti->fixTotale();
128129
$assicurazione_crediti->save();
129130
}
131+
132+
// Pagamento automatico se scadenza = data fattura e flag attivo
133+
if (!$is_pagato && $scadenza->scadenza->format('Y-m-d') == $fattura->data->format('Y-m-d')) {
134+
$pagamento = \Modules\Pagamenti\Pagamento::find($id_pagamento);
135+
if (!empty($pagamento) && $pagamento->registra_pagamento_automatico) {
136+
$importo_da_registrare = abs($importo);
137+
$dir = $fattura->tipo->dir;
138+
139+
// Recupero conto anagrafica
140+
$id_conto_anagrafica = database()->selectOne('an_anagrafiche', $dir == 'entrata' ? 'idconto_cliente' : 'idconto_fornitore', ['idanagrafica' => $idanagrafica]);
141+
$id_conto_anagrafica = $id_conto_anagrafica[$dir == 'entrata' ? 'idconto_cliente' : 'idconto_fornitore'];
142+
143+
// Recupero conto contropartita
144+
$id_conto_contropartita = $dir == 'entrata' ? $pagamento->idconto_vendite : $pagamento->idconto_acquisti;
145+
146+
if (!empty($id_conto_anagrafica) && !empty($id_conto_contropartita)) {
147+
Movimento::registraPagamentoAutomatico($scadenza->id, $importo_da_registrare, $id_conto_anagrafica, $id_conto_contropartita, $dir);
148+
}
149+
}
150+
}
130151
}
131152

132153
/**

modules/pagamenti/actions.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
$pagamento->importo_fisso_incasso = (float) post('importo_fisso_incasso');
6464
$pagamento->importo_percentuale_incasso = (float) post('importo_percentuale_incasso');
6565
$pagamento->codice_modalita_pagamento_fe = post('codice_modalita_pagamento_fe');
66+
$pagamento->registra_pagamento_automatico = post('registra_pagamento_automatico');
6667
$pagamento->save();
6768
$pagamento->setTranslation('title', $descrizione);
6869
}

modules/pagamenti/edit.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,17 @@
4141
</div>
4242

4343
<div class="row">
44-
<div class="col-md-6">
44+
<div class="col-md-4">
4545
{[ "type": "select", "label": "<?php echo tr('Conto predefinito per le vendite'); ?>", "name": "idconto_vendite", "value": "$idconto_vendite$", "ajax-source": "conti" ]}
4646
</div>
4747

48-
<div class="col-md-6">
48+
<div class="col-md-4">
4949
{[ "type": "select", "label": "<?php echo tr('Conto predefinito per gli acquisti'); ?>", "name": "idconto_acquisti", "value": "$idconto_acquisti$", "ajax-source": "conti" ]}
5050
</div>
51+
52+
<div class="col-md-4">
53+
{[ "type": "checkbox", "label": "<?php echo tr('Registra contabile automaticamente'); ?>", "name": "registra_pagamento_automatico", "value": "$registra_pagamento_automatico$", "help": "<?php echo tr('Attiva la registrazione automatica dei pagamenti in prima nota alla data di scadenza delle fatture. Il task viene eseguito dallo scheduler e utilizza i conti predefiniti configurati (Conto predefinito per le vendite/acquisti devono essere impostati) insieme al conto cliente/fornitore dell\'anagrafica.'); ?>" ]}
54+
</div>
5155
</div>
5256
</div>
5357
</div>

modules/primanota/src/Movimento.php

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,4 +118,69 @@ public function documento()
118118
{
119119
return $this->belongsTo(Fattura::class, 'iddocumento');
120120
}
121+
122+
/**
123+
* Registra automaticamente un pagamento di prima nota per una scadenza.
124+
*
125+
* @param int $id_scadenza ID della scadenza
126+
* @param float $importo Importo da registrare
127+
* @param int $id_conto_anagrafica ID del conto cliente/fornitore
128+
* @param int $id_conto_contropartita ID del conto di contropartita
129+
* @param string $dir Direzione (entrata/uscita)
130+
* @return bool
131+
*/
132+
public static function registraPagamentoAutomatico($id_scadenza, $importo, $id_conto_anagrafica, $id_conto_contropartita, $dir)
133+
{
134+
// Recupero la scadenza
135+
$scadenza = Scadenza::find($id_scadenza);
136+
if (empty($scadenza)) {
137+
return false;
138+
}
139+
140+
// Recupero il documento associato
141+
$documento = $scadenza->documento;
142+
if (empty($documento)) {
143+
return false;
144+
}
145+
146+
// Determino la data del pagamento (oggi o data scadenza se precedente)
147+
$data_scadenza = !empty($scadenza->data_concordata) ? $scadenza->data_concordata : $scadenza->scadenza;
148+
$data_pagamento = new \DateTime();
149+
if ($data_pagamento > $data_scadenza) {
150+
$data_pagamento = $data_scadenza;
151+
}
152+
153+
// Creo la descrizione del movimento
154+
$descrizione = tr('Pagamento automatico _DESC_', [
155+
'_DESC_' => $documento->getReference(),
156+
]);
157+
158+
// Creo il mastrino
159+
$mastrino = Mastrino::build($descrizione, $data_pagamento, false, true, $documento->idanagrafica);
160+
$mastrino->save();
161+
162+
// Determino dare/avere in base alla direzione
163+
if ($dir == 'entrata') {
164+
// Fattura di vendita: Dare sul conto cliente, Avere sul conto contropartita
165+
$movimento_cliente = self::build($mastrino, $id_conto_anagrafica, $documento, $scadenza);
166+
$movimento_cliente->totale = $importo;
167+
$movimento_cliente->save();
168+
169+
$movimento_contropartita = self::build($mastrino, $id_conto_contropartita, $documento, null);
170+
$movimento_contropartita->totale = -$importo;
171+
$movimento_contropartita->save();
172+
} else {
173+
// Fattura di acquisto: Avere sul conto fornitore, Dare sul conto contropartita
174+
$movimento_fornitore = self::build($mastrino, $id_conto_anagrafica, $documento, $scadenza);
175+
$movimento_fornitore->totale = -$importo;
176+
$movimento_fornitore->save();
177+
178+
$movimento_contropartita = self::build($mastrino, $id_conto_contropartita, $documento, null);
179+
$movimento_contropartita->totale = $importo;
180+
$movimento_contropartita->save();
181+
}
182+
$mastrino->aggiornaScadenzario();
183+
184+
return true;
185+
}
121186
}
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
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+
namespace Modules\PrimaNota;
22+
23+
use Tasks\Manager;
24+
25+
/**
26+
* Task dedicato alla registrazione automatica dei pagamenti alla scadenza delle fatture.
27+
*/
28+
class PagamentoAutomaticoTask extends Manager
29+
{
30+
public function needsExecution()
31+
{
32+
// Il task viene eseguito sempre dallo scheduler
33+
return true;
34+
}
35+
36+
public function execute()
37+
{
38+
$result = [
39+
'response' => 1,
40+
'message' => tr('Pagamenti registrati correttamente!'),
41+
];
42+
43+
$database = database();
44+
45+
// Recupero le scadenze scadute o in scadenza oggi con flag registra_pagamento attivo
46+
$scadenze = $database->fetchArray("
47+
SELECT
48+
`co_scadenziario`.*,
49+
`co_documenti`.`idanagrafica`,
50+
`co_documenti`.`idtipodocumento`,
51+
`co_tipidocumento`.`dir`,
52+
`co_pagamenti`.`idconto_vendite`,
53+
`co_pagamenti`.`idconto_acquisti`
54+
FROM
55+
`co_scadenziario`
56+
INNER JOIN `co_documenti` ON `co_scadenziario`.`iddocumento` = `co_documenti`.`id`
57+
INNER JOIN `co_tipidocumento` ON `co_documenti`.`idtipodocumento` = `co_tipidocumento`.`id`
58+
INNER JOIN `co_pagamenti` ON `co_documenti`.`idpagamento` = `co_pagamenti`.`id`
59+
WHERE
60+
`co_pagamenti`.`registra_pagamento_automatico` = 1
61+
AND ABS(`co_scadenziario`.`pagato`) < ABS(`co_scadenziario`.`da_pagare`)
62+
AND (
63+
IF(`co_scadenziario`.`data_concordata`, `co_scadenziario`.`data_concordata`, `co_scadenziario`.`scadenza`) <= CURDATE()
64+
)
65+
");
66+
67+
$conta_registrati = 0;
68+
$conta_errori = 0;
69+
70+
foreach ($scadenze as $scadenza) {
71+
try {
72+
// Calcolo l'importo da registrare
73+
$importo_da_pagare = abs($scadenza['da_pagare']);
74+
$importo_gia_pagato = abs($scadenza['pagato']);
75+
$importo_da_registrare = $importo_da_pagare - $importo_gia_pagato;
76+
77+
if ($importo_da_registrare <= 0) {
78+
continue;
79+
}
80+
81+
// Determino il conto cliente/fornitore
82+
$id_conto_anagrafica = null;
83+
if ($scadenza['dir'] == 'entrata') {
84+
// Fattura di vendita: conto cliente
85+
$id_conto_anagrafica = $database->selectOne('an_anagrafiche', 'idconto_cliente', ['idanagrafica' => $scadenza['idanagrafica']])['idconto_cliente'];
86+
} else {
87+
// Fattura di acquisto: conto fornitore
88+
$id_conto_anagrafica = $database->selectOne('an_anagrafiche', 'idconto_fornitore', ['idanagrafica' => $scadenza['idanagrafica']])['idconto_fornitore'];
89+
}
90+
91+
// Determino il conto di contropartita
92+
$id_conto_contropartita = null;
93+
if ($scadenza['dir'] == 'entrata') {
94+
$id_conto_contropartita = $scadenza['idconto_vendite'];
95+
} else {
96+
$id_conto_contropartita = $scadenza['idconto_acquisti'];
97+
}
98+
99+
// Verifica che i conti siano valorizzati
100+
if (empty($id_conto_anagrafica)) {
101+
$conta_errori++;
102+
continue;
103+
}
104+
105+
if (empty($id_conto_contropartita)) {
106+
$conta_errori++;
107+
continue;
108+
}
109+
110+
// Crea il movimento di prima nota
111+
Movimento::registraPagamentoAutomatico(
112+
$scadenza['id'],
113+
$importo_da_registrare,
114+
$id_conto_anagrafica,
115+
$id_conto_contropartita,
116+
$scadenza['dir']
117+
);
118+
119+
$conta_registrati++;
120+
} catch (\Exception $e) {
121+
$conta_errori++;
122+
}
123+
}
124+
125+
if ($conta_registrati == 0 && $conta_errori == 0) {
126+
$result = [
127+
'response' => 1,
128+
'message' => tr('Nessun pagamento da registrare'),
129+
];
130+
} elseif ($conta_errori > 0) {
131+
$result = [
132+
'response' => 2,
133+
'message' => tr('Pagamenti registrati: _REGISTRATI_, Errori: _ERRORI_', [
134+
'_REGISTRATI_' => $conta_registrati,
135+
'_ERRORI_' => $conta_errori,
136+
]),
137+
];
138+
} else {
139+
$result = [
140+
'response' => 1,
141+
'message' => tr('_NUM_ pagamenti registrati correttamente!', [
142+
'_NUM_' => $conta_registrati,
143+
]),
144+
];
145+
}
146+
147+
return $result;
148+
}
149+
}

update/2_10.sql

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -453,4 +453,8 @@ INSERT INTO `zz_settings_lang` (`id_lang`, `id_record`, `title`, `help`) VALUES
453453
-- Fix stampa registro viaggi
454454
UPDATE `zz_prints` SET `predefined` = '1' WHERE `zz_prints`.`name` = 'Registro viaggio';
455455
UPDATE `zz_prints_lang` SET `filename` = 'Registro viaggio {nome} {targa}' WHERE `zz_prints_lang`.`title` = 'Registro viaggio';
456-
UPDATE `zz_prints_lang` SET `filename` = 'Travel register {nome} {targa}' WHERE `zz_prints_lang`.`title` = 'Travel register';
456+
UPDATE `zz_prints_lang` SET `filename` = 'Travel register {nome} {targa}' WHERE `zz_prints_lang`.`title` = 'Travel register';
457+
458+
-- Aggiunta gestione delle scadenze per il pagamento automatico
459+
ALTER TABLE `co_pagamenti` ADD `registra_pagamento_automatico` BOOLEAN NOT NULL;
460+
INSERT INTO `zz_tasks` (`id`, `name`, `class`, `expression`, `next_execution_at`, `last_executed_at`, `created_at`, `updated_at`, `enabled`) VALUES (NULL, 'Pagamento automatico', 'Modules\\PrimaNota\\PagamentoAutomaticoTask', '0 */24 * * *', NULL, NULL, NULL, NULL, '1');

0 commit comments

Comments
 (0)