Skip to content

Commit 60a1dfa

Browse files
committed
Introduzione di nuovi unit test con mocking
1 parent 5c31fe0 commit 60a1dfa

File tree

10 files changed

+265
-36
lines changed

10 files changed

+265
-36
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,4 +101,5 @@ settings.json
101101
codeception.yml
102102
!.gitkeep
103103
.vscode
104-
.php-cs-fixer.cache
104+
.php-cs-fixer.cache
105+
.phpunit.*

.php-cs-fixer.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
->exclude('.couscous')
66
->exclude('node_modules')
77
->exclude('vendor')
8-
->exclude('tests')
98
->ignoreDotFiles(true)
109
->ignoreVCS(true)
1110
->in(__DIR__);

composer.json

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@
6868
},
6969
"require-dev": {
7070
"friendsofphp/php-cs-fixer": "^3.53",
71-
"phpunit/phpunit": "^11.5",
71+
"mockery/mockery": "^1.6",
72+
"phpunit/phpunit": "^10|^11",
7273
"rector/rector": "^1.0"
7374
},
7475
"autoload": {
@@ -150,11 +151,12 @@
150151
"minimum-stability": "dev",
151152
"prefer-stable": true,
152153
"platform-check": false,
153-
"platform": {
154-
"php": "8.3.7"
155-
},
156154
"allow-plugins": {
157155
"kylekatarnls/update-helper": true
158156
}
157+
},
158+
"scripts": {
159+
"unit-tests": "phpunit --configuration phpunit.xml",
160+
"format": "php-cs-fixer fix"
159161
}
160162
}

modules/fatture/src/Gestori/Scadenze.php

Lines changed: 39 additions & 13 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\Pagamenti\Pagamento;
2425
use Modules\Scadenzario\Scadenza;
2526
use Plugins\AssicurazioneCrediti\AssicurazioneCrediti;
2627
use Plugins\ImportFE\FatturaElettronica as FatturaElettronicaImport;
@@ -33,8 +34,9 @@
3334
*/
3435
class Scadenze
3536
{
36-
public function __construct(private readonly Fattura $fattura)
37+
public function __construct(private readonly Fattura $fattura, $database = null)
3738
{
39+
$this->database = $database ?: database(); // Allow mocking
3840
}
3941

4042
/**
@@ -49,11 +51,11 @@ public function registra($is_pagato = false, $ignora_fe = false)
4951
$this->rimuovi();
5052

5153
if (!$ignora_fe && $this->fattura->module == 'Fatture di acquisto' && $this->fattura->isFE()) {
52-
$scadenze_fe = $this->registraScadenzeFE($is_pagato);
54+
$scadenze = $this->registraScadenzeFE($is_pagato);
5355
}
5456

55-
if (empty($scadenze_fe)) {
56-
$this->registraScadenzeTradizionali($is_pagato);
57+
if (empty($scadenze)) {
58+
$scadenze = $this->registraScadenzeTradizionali($is_pagato);
5759
}
5860

5961
// Registrazione scadenza per Ritenuta d'Acconto
@@ -78,8 +80,10 @@ public function registra($is_pagato = false, $ignora_fe = false)
7880
$id_banca_controparte = $this->fattura->id_banca_controparte;
7981
$importo = -$ritenuta_acconto;
8082

81-
self::registraScadenza($this->fattura, $importo, $scadenza, $is_pagato, $id_pagamento, $id_banca_azienda, $id_banca_controparte, 'ritenutaacconto');
83+
$scadenze[] = self::registraScadenza($this->fattura, $importo, $scadenza, $is_pagato, $id_pagamento, $id_banca_azienda, $id_banca_controparte, 'ritenutaacconto');
8284
}
85+
86+
return $scadenze;
8387
}
8488

8589
/**
@@ -88,14 +92,15 @@ public function registra($is_pagato = false, $ignora_fe = false)
8892
public function rimuovi()
8993
{
9094
$scadenze = $this->fattura->scadenze;
95+
$assicurazioni = [];
9196
foreach ($scadenze as $scadenza) {
92-
$assicurazione_crediti = AssicurazioneCrediti::where('id_anagrafica', $scadenza->idanagrafica)->where('data_inizio', '<=', $scadenza->scadenza)->where('data_fine', '>=', $scadenza->scadenza)->first();
97+
$assicurazione_crediti = this->trovaAssicurazioneCrediti($scadenza->idanagrafica, $scadenza->scadenza);
9398
if (!empty($assicurazione_crediti)) {
9499
$assicurazioni[] = $assicurazione_crediti;
95100
}
96101
}
97102

98-
database()->delete('co_scadenziario', ['iddocumento' => $this->fattura->id]);
103+
$this->database->delete('co_scadenziario', ['iddocumento' => $this->fattura->id]);
99104

100105
foreach ($assicurazioni as $assicurazione) {
101106
$assicurazione->fixTotale();
@@ -117,18 +122,35 @@ protected function registraScadenza(Fattura $fattura, $importo, $data_scadenza,
117122
$descrizione = $fattura->tipo->getTranslation('title').' numero '.$numero;
118123
$idanagrafica = $fattura->idanagrafica;
119124

120-
$scadenza = Scadenza::build($idanagrafica, $descrizione, $importo, $data_scadenza, $id_pagamento, $id_banca_azienda, $id_banca_controparte, $type, $is_pagato);
125+
$scadenza = $this->generaScadenza($idanagrafica, $descrizione, $importo, $data_scadenza, $id_pagamento, $id_banca_azienda, $id_banca_controparte, $type, $is_pagato);
121126

122127
$scadenza->documento()->associate($fattura);
123128
$scadenza->data_emissione = $fattura->data;
124129

125130
$scadenza->save();
126131

127-
$assicurazione_crediti = AssicurazioneCrediti::where('id_anagrafica', $scadenza->idanagrafica)->where('data_inizio', '<=', $scadenza->scadenza)->where('data_fine', '>=', $scadenza->scadenza)->first();
132+
$assicurazione_crediti = $this->trovaAssicurazioneCrediti($scadenza->idanagrafica, $scadenza->scadenza);
128133
if (!empty($assicurazione_crediti)) {
129134
$assicurazione_crediti->fixTotale();
130135
$assicurazione_crediti->save();
131136
}
137+
138+
return $scadenza;
139+
}
140+
141+
protected function trovaPagamento($idpagamento): ?Pagamento
142+
{
143+
return Pagamento::where('id', $idpagamento)->first();
144+
}
145+
146+
protected function trovaAssicurazioneCrediti($idanagrafica, $data_scadenza): ?AssicurazioneCrediti
147+
{
148+
return AssicurazioneCrediti::where('id_anagrafica', $idanagrafica)->where('data_inizio', '<=', $data_scadenza)->where('data_fine', '>=', $data_scadenza)->first();
149+
}
150+
151+
protected function generaScadenza($idanagrafica, $descrizione, $importo, $data_scadenza, $id_pagamento, $id_banca_azienda, $id_banca_controparte, $type, $is_pagato): Scadenza
152+
{
153+
return Scadenza::build($idanagrafica, $descrizione, $importo, $data_scadenza, $id_pagamento, $id_banca_azienda, $id_banca_controparte, $type, $is_pagato);
132154
}
133155

134156
/**
@@ -151,6 +173,7 @@ protected function registraScadenzeFE($is_pagato = false)
151173
$pagamenti = isset($pagamenti[0]) ? $pagamenti : [$pagamenti];
152174
}
153175

176+
$results = [];
154177
foreach ($pagamenti as $pagamento) {
155178
$rate = $pagamento['DettaglioPagamento'];
156179
$rate = isset($rate[0]) ? $rate : [$rate];
@@ -162,11 +185,11 @@ protected function registraScadenzeFE($is_pagato = false)
162185
$scadenza = !empty($rata['DataScadenzaPagamento']) ? FatturaElettronicaImport::parseDate($rata['DataScadenzaPagamento']) : $this->fattura->data;
163186
$importo = $this->fattura->isNota() ? $rata['ImportoPagamento'] : -$rata['ImportoPagamento'];
164187

165-
self::registraScadenza($this->fattura, $importo, $scadenza, $is_pagato, $id_pagamento, $id_banca_azienda, $id_banca_controparte);
188+
$results[] = self::registraScadenza($this->fattura, $importo, $scadenza, $is_pagato, $id_pagamento, $id_banca_azienda, $id_banca_controparte);
166189
}
167190
}
168191

169-
return !empty($pagamenti);
192+
return $results;
170193
}
171194

172195
/**
@@ -181,17 +204,20 @@ protected function registraScadenzeTradizionali($is_pagato = false)
181204
$netto = $this->fattura->isNota() ? -$netto : $netto;
182205

183206
// Calcolo delle rate
184-
$rate = ($this->fattura->pagamento ?: \Modules\Pagamenti\Pagamento::where('id', $this->fattura->idpagamento)->first())->calcola($netto, $this->fattura->data, $this->fattura->idanagrafica);
207+
$rate = ($this->fattura->pagamento ?: $this->trovaPagamento($this->fattura->idpagamento))->calcola($netto, $this->fattura->data, $this->fattura->idanagrafica, $this->database);
185208
$direzione = $this->fattura->tipo->dir;
186209

210+
$results = [];
187211
foreach ($rate as $rata) {
188212
$scadenza = $rata['scadenza'];
189213
$importo = $direzione == 'uscita' ? -$rata['importo'] : $rata['importo'];
190214
$id_pagamento = $this->fattura->idpagamento;
191215
$id_banca_azienda = $this->fattura->id_banca_azienda;
192216
$id_banca_controparte = $this->fattura->id_banca_controparte;
193217

194-
self::registraScadenza($this->fattura, $importo, $scadenza, $is_pagato, $id_pagamento, $id_banca_azienda, $id_banca_controparte);
218+
$results[] = self::registraScadenza($this->fattura, $importo, $scadenza, $is_pagato, $id_pagamento, $id_banca_azienda, $id_banca_controparte);
195219
}
220+
221+
return $results;
196222
}
197223
}
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
<?php
2+
3+
use Illuminate\Support\Str;
4+
use Modules\Fatture\Fattura;
5+
use Modules\Fatture\Gestori\Scadenze;
6+
use Modules\Fatture\Tipo;
7+
use Modules\Pagamenti\Pagamento;
8+
use Modules\Scadenzario\Scadenza;
9+
10+
class GenerazioneScadenzeTest extends PHPUnit\Framework\TestCase
11+
{
12+
public function testRimessaDiretta90Giorni()
13+
{
14+
$fattura = $this->getFatturaConRate('2025-03-30', 500, [
15+
$this->mockModel(Pagamento::class, [
16+
'giorno' => 0,
17+
'num_giorni' => 90,
18+
'prc' => 100,
19+
]),
20+
]);
21+
22+
$gestore = $this->getGestore($fattura);
23+
$gestore->shouldReceive('trovaPagamento')->andReturn(null);
24+
$gestore->shouldReceive('trovaAssicurazioneCrediti')->andReturn(null);
25+
26+
$scadenze = $gestore->registra(false, true);
27+
28+
$this->assertEquals(1, count($scadenze));
29+
30+
$this->assertEquals('2025-03-30', $scadenze[0]->data_emissione);
31+
$this->assertEquals('2025-06-28', $scadenze[0]->scadenza);
32+
$this->assertEquals(500, $scadenze[0]->da_pagare);
33+
}
34+
35+
public function testRimessaDiretta90GiorniAl15()
36+
{
37+
$fattura = $this->getFatturaConRate('2025-03-30', 500, [
38+
$this->mockModel(Pagamento::class, [
39+
'giorno' => 15,
40+
'num_giorni' => 90,
41+
'prc' => 100,
42+
]),
43+
]);
44+
45+
$gestore = $this->getGestore($fattura);
46+
$gestore->shouldReceive('trovaPagamento')->andReturn(null);
47+
$gestore->shouldReceive('trovaAssicurazioneCrediti')->andReturn(null);
48+
49+
$scadenze = $gestore->registra(false, true);
50+
51+
$this->assertEquals(1, count($scadenze));
52+
53+
$this->assertEquals('2025-03-30', $scadenze[0]->data_emissione);
54+
$this->assertEquals('2025-06-15', $scadenze[0]->scadenza);
55+
$this->assertEquals(500, $scadenze[0]->da_pagare);
56+
}
57+
58+
public function test3RateStatiche()
59+
{
60+
$fattura = $this->getFatturaConRate('2025-03-30', 600, [
61+
$this->mockModel(Pagamento::class, [
62+
'giorno' => 0,
63+
'num_giorni' => 90,
64+
'prc' => 33,
65+
]),
66+
$this->mockModel(Pagamento::class, [
67+
'giorno' => 0,
68+
'num_giorni' => 180,
69+
'prc' => 33,
70+
]),
71+
$this->mockModel(Pagamento::class, [
72+
'giorno' => 0,
73+
'num_giorni' => 270,
74+
'prc' => 34,
75+
]),
76+
]);
77+
78+
$gestore = $this->getGestore($fattura);
79+
$gestore->shouldReceive('trovaPagamento')->andReturn(null);
80+
$gestore->shouldReceive('trovaAssicurazioneCrediti')->andReturn(null);
81+
82+
$scadenze = $gestore->registra(false, true);
83+
84+
$this->assertEquals(3, count($scadenze));
85+
86+
$this->assertEquals('2025-03-30', $scadenze[0]->data_emissione);
87+
$this->assertEquals('2025-06-28', $scadenze[0]->scadenza);
88+
$this->assertEquals(198, $scadenze[0]->da_pagare);
89+
90+
$this->assertEquals('2025-03-30', $scadenze[1]->data_emissione);
91+
$this->assertEquals('2025-09-26', $scadenze[1]->scadenza);
92+
$this->assertEquals(198, $scadenze[1]->da_pagare);
93+
94+
$this->assertEquals('2025-03-30', $scadenze[2]->data_emissione);
95+
$this->assertEquals('2025-12-25', $scadenze[2]->scadenza);
96+
$this->assertEquals(204, $scadenze[2]->da_pagare);
97+
}
98+
99+
protected function mockModel($class, $attributes = null)
100+
{
101+
$ref = Mockery::mock($class)->shouldAllowMockingProtectedMethods()->makePartial();
102+
103+
$ref->shouldReceive('save')->andReturn(null);
104+
$ref->shouldReceive('delete')->andReturn(null);
105+
$ref->shouldReceive('getDateFormat')->andReturn('Y-m-d');
106+
107+
// Fix per gestione attributi su modello mocked di Eloquent
108+
$ref->shouldReceive('getMutatedAttributes')->andReturnUsing(function () use ($class) {
109+
preg_match_all('/(?<=^|;)get([^;]+?)Attribute(;|$)/', implode(';', get_class_methods($class)), $matches);
110+
111+
$ref = $matches[1];
112+
113+
return collect($ref)
114+
->merge($attributeMutatorMethods)
115+
->map(function ($match) {
116+
return lcfirst(static::$snakeAttributes ? Str::snake($match) : $match);
117+
})->all();
118+
});
119+
120+
if (!empty($attributes)) {
121+
foreach ($attributes as $key => $value) {
122+
$ref->shouldReceive('getAttribute')->with($key)->andReturn($value);
123+
}
124+
}
125+
126+
return $ref;
127+
}
128+
129+
protected function getFatturaConRate($data, $netto, $rate): Fattura
130+
{
131+
$tipo = $this->mockModel(Tipo::class);
132+
$tipo->shouldReceive('getAttribute')->with('dir')->andReturn('entrata');
133+
$tipo->shouldReceive('getTranslation')->andReturn('Fattura di vendita');
134+
135+
$pagamento = $this->mockModel(Pagamento::class);
136+
$pagamento->shouldReceive('trovaRate')->andReturn($rate);
137+
138+
$fattura = $this->mockModel(Fattura::class, [
139+
'numero_esterno' => '2025-01',
140+
'idpagamento' => null,
141+
'id_banca_controparte' => null,
142+
'id_banca_azienda' => null,
143+
'idanagrafica' => 'test-an-1',
144+
'data' => $data,
145+
'id' => 'test-1',
146+
'netto' => $netto,
147+
'scadenze' => [],
148+
'pagamento' => $pagamento,
149+
'tipo' => $tipo,
150+
'ritenuta_acconto' => null,
151+
]);
152+
$fattura->shouldReceive('associate')->andReturn(null);
153+
$fattura->shouldReceive('isNota')->andReturn(false);
154+
155+
return $fattura;
156+
}
157+
158+
protected function getGestore($fattura): Scadenze
159+
{
160+
$database = $this->mockModel(Database::class);
161+
$database->shouldReceive('delete')->andReturn(null);
162+
$database->shouldReceive('selectOne')->andReturn(null);
163+
164+
$gestore = Mockery::mock(Scadenze::class, [$fattura, $database])->shouldAllowMockingProtectedMethods()->makePartial();
165+
$gestore->shouldReceive('generaScadenza')->andReturnUsing(function ($idanagrafica, $descrizione, $importo, $data_scadenza, $id_pagamento, $id_banca_azienda, $id_banca_controparte, $type, $is_pagato) use ($fattura) {
166+
$scadenza = $this->mockModel(Scadenza::class, [
167+
'idanagrafica' => $idanagrafica,
168+
'descrizione' => $descrizione,
169+
'scadenza' => $data_scadenza,
170+
'da_pagare' => $importo,
171+
'tipo' => $type,
172+
'id_pagamento' => $id_pagamento,
173+
'id_banca_azienda' => $id_banca_azienda,
174+
'id_banca_controparte' => $id_banca_controparte,
175+
176+
'pagato' => $is_pagato ? $importo : 0,
177+
'data_pagamento' => $is_pagato ? $data_scadenza : null,
178+
]);
179+
180+
$scadenza->shouldReceive('documento')->andReturn($fattura);
181+
182+
return $scadenza;
183+
});
184+
185+
return $gestore;
186+
}
187+
}

0 commit comments

Comments
 (0)