Skip to content

Commit 32c2a51

Browse files
committed
[FIX] l10n_it_split_payment: fix compute of split payment writeoff when creating two lines at once with different vat amount
This PR fix the case of creating two different invoice lines with two different SP Taxes. Now it does not create the write off with the correct amount
1 parent ff1a218 commit 32c2a51

File tree

6 files changed

+164
-93
lines changed

6 files changed

+164
-93
lines changed

l10n_it_split_payment/README.rst

Lines changed: 37 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -52,34 +52,34 @@ Configuration
5252

5353
Per configurare questo modulo è necessario:
5454

55-
- andare in Contabilità → Configurazione → Impostazioni e configura
56-
"Conto storno scissione pagamenti" (es. 'IVA n/debito sospesa SP'). Il
57-
conto storno dovrebbe essere diverso dall'IVA a debito standard, in
58-
modo da aggiungerlo separatamente nella dichiarazione IVA.
55+
- andare in Contabilità → Configurazione → Impostazioni e configura
56+
"Conto storno scissione pagamenti" (es. 'IVA n/debito sospesa SP').
57+
Il conto storno dovrebbe essere diverso dall'IVA a debito standard,
58+
in modo da aggiungerlo separatamente nella dichiarazione IVA.
5959

6060
**English**
6161

6262
To configure this module, you need to:
6363

64-
- go to Accounting → Configuration → Settings and configure 'Split
65-
Payment Write-off account' (like 'IVA n/debito sospesa SP'). Write-off
66-
account should be different from standard debit VAT, in order to
67-
separately add it in VAT statement.
64+
- go to Accounting → Configuration → Settings and configure 'Split
65+
Payment Write-off account' (like 'IVA n/debito sospesa SP').
66+
Write-off account should be different from standard debit VAT, in
67+
order to separately add it in VAT statement.
6868

6969
|image1|
7070

7171
--------------
7272

7373
**Italiano**
7474

75-
- aggiungere una nuova imposta (Contabilità → Configurazione →
76-
Contabilità → Imposte). IVA al 22% SPL deve essere configurata nel
77-
modo seguente:
75+
- aggiungere una nuova imposta (Contabilità → Configurazione →
76+
Contabilità → Imposte). IVA al 22% SPL deve essere configurata nel
77+
modo seguente:
7878

7979
**English**
8080

81-
- add a new tax (Accounting → Configuration → Accounting → Taxes). IVA
82-
al 22% SPL should be configured like the following:
81+
- add a new tax (Accounting → Configuration → Accounting → Taxes). IVA
82+
al 22% SPL should be configured like the following:
8383

8484
|image2|
8585

@@ -89,17 +89,18 @@ To configure this module, you need to:
8989

9090
**Italiano**
9191

92-
- configurare la posizione fiscale (Contabilità → Configurazione →
93-
Contabilità → Posizioni fiscali) usata per la scissione dei pagamenti,
94-
selezionando la casella "Scissione pagamenti". Nella posizione fiscale
95-
mappare l'IVA standard con l'IVA SP, come indicato di seguito:
92+
- configurare la posizione fiscale (Contabilità → Configurazione →
93+
Contabilità → Posizioni fiscali) usata per la scissione dei
94+
pagamenti, selezionando la casella "Scissione pagamenti". Nella
95+
posizione fiscale mappare l'IVA standard con l'IVA SP, come indicato
96+
di seguito:
9697

9798
**English**
9899

99-
- configure the fiscal position (Accounting → Configuration → Accounting
100-
→ Fiscal Positions) used for split payment, setting 'Split Payment'
101-
flag. In fiscal position, map standard VAT with SP VAT, like the
102-
following:
100+
- configure the fiscal position (Accounting → Configuration →
101+
Accounting → Fiscal Positions) used for split payment, setting 'Split
102+
Payment' flag. In fiscal position, map standard VAT with SP VAT, like
103+
the following:
103104

104105
|image4|
105106

@@ -143,17 +144,21 @@ Authors
143144
Contributors
144145
------------
145146

146-
- Davide Corio <davide.corio@abstract.it>
147-
- Lorenzo Battistini <lorenzo.battistini@agilebg.com>
148-
- Alessio Gerace <alessio.gerace@agilebg.com>
149-
- Giacomo Grasso <giacomo.grasso.82@gmail.com>
150-
- Ruben Tonetto <https://github.com/ruben-tonetto>
151-
- Giuseppe Borruso - Dinamiche Aziendali srl
152-
<gborruso@dinamicheaziendali.it>
153-
- Alex Comba <alex.comba@agilebg.com>
154-
- `Ooops <https://www.ooops404.com>`__:
155-
156-
- Giovanni Serra <giovanni@gslab.it>
147+
- Davide Corio <davide.corio@abstract.it>
148+
- Lorenzo Battistini <lorenzo.battistini@agilebg.com>
149+
- Alessio Gerace <alessio.gerace@agilebg.com>
150+
- Giacomo Grasso <giacomo.grasso.82@gmail.com>
151+
- Ruben Tonetto <https://github.com/ruben-tonetto>
152+
- Giuseppe Borruso - Dinamiche Aziendali srl
153+
<gborruso@dinamicheaziendali.it>
154+
- Alex Comba <alex.comba@agilebg.com>
155+
- `Ooops <https://www.ooops404.com>`__:
156+
157+
- Giovanni Serra <giovanni@gslab.it>
158+
159+
- `Stesi Consulting <https://www.stesi.consulting>`__:
160+
161+
- Michele Di Croce <dicroce.m@stesi.consulting>
157162

158163
Maintainers
159164
-----------

l10n_it_split_payment/models/account_move.py

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,6 @@ def write(self, vals):
4949
if self.env.context.get("skip_split_payment_computation"):
5050
return res
5151
self.compute_split_payment()
52-
container = {"records": self}
53-
self._check_balanced(container)
5452
return res
5553

5654
def copy(self, default=None):
@@ -64,26 +62,30 @@ def copy(self, default=None):
6462
return res
6563

6664
def compute_split_payment(self):
67-
for move in self:
68-
if move.split_payment:
69-
line_sp = fields.first(
70-
move.line_ids.filtered(lambda move_line: move_line.is_split_payment)
71-
)
72-
for line in move.line_ids:
73-
if line.display_type == "tax" and not line.is_split_payment:
74-
write_off_line_vals = line._build_writeoff_line()
75-
if line_sp:
76-
if (
77-
float_compare(
78-
line_sp.price_unit,
79-
write_off_line_vals["price_unit"],
80-
precision_rounding=move.currency_id.rounding,
81-
)
82-
!= 0
83-
):
84-
line_sp.write(write_off_line_vals)
85-
else:
86-
if move.amount_sp:
87-
move.with_context(
88-
skip_split_payment_computation=True
89-
).line_ids = [Command.create(write_off_line_vals)]
65+
move_ids = self.filtered("split_payment")
66+
for move in move_ids:
67+
line_sp = fields.first(
68+
move.line_ids.filtered(lambda move_line: move_line.is_split_payment)
69+
)
70+
lines = move.line_ids.filtered(
71+
lambda line: line.display_type == "tax" and not line.is_split_payment
72+
)
73+
if lines:
74+
write_off_line_vals = lines._build_writeoff_line()
75+
if line_sp:
76+
if (
77+
float_compare(
78+
line_sp.price_unit,
79+
write_off_line_vals["price_unit"],
80+
precision_rounding=move.currency_id.rounding,
81+
)
82+
!= 0
83+
):
84+
line_sp.write(write_off_line_vals)
85+
else:
86+
if move.amount_sp:
87+
move.with_context(
88+
skip_split_payment_computation=True
89+
).line_ids = [Command.create(write_off_line_vals)]
90+
container = {"records": move_ids}
91+
self._check_balanced(container)

l10n_it_split_payment/models/account_move_line.py

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@ def _compute_is_split_payment(self):
2121
line.is_split_payment = True
2222

2323
def _build_writeoff_line(self):
24-
self.ensure_one()
25-
24+
if len(self.mapped("move_id")) != 1:
25+
raise UserError(
26+
_("Cannot create a split payment write-off line for multiple moves.")
27+
)
2628
if not self.move_id.company_id.sp_account_id:
2729
raise UserError(
2830
_(
@@ -37,32 +39,27 @@ def _build_writeoff_line(self):
3739
"journal_id": self.move_id.journal_id.id,
3840
"date": self.move_id.invoice_date,
3941
"date_maturity": self.move_id.invoice_date,
40-
"price_unit": -self.credit,
41-
"amount_currency": self.credit,
42-
"debit": self.credit,
43-
"credit": self.debit,
42+
"price_unit": -sum(self.mapped("credit")),
43+
"amount_currency": sum(self.mapped("credit")),
44+
"debit": sum(self.mapped("credit")),
45+
"credit": sum(self.mapped("debit")),
4446
"display_type": "tax",
4547
}
4648
if self.move_id.move_type == "out_refund":
47-
vals["amount_currency"] = -self.debit
48-
vals["debit"] = self.credit
49-
vals["credit"] = self.debit
49+
vals["amount_currency"] = -sum(self.mapped("debit"))
50+
vals["debit"] = sum(self.mapped("credit"))
51+
vals["credit"] = sum(self.mapped("debit"))
5052
return vals
5153

5254
@api.model_create_multi
5355
def create(self, vals_list):
5456
lines = super().create(vals_list)
55-
for line in lines:
56-
if (
57-
line.display_type == "tax"
58-
and line.move_id.split_payment
59-
and line.move_id.is_sale_document(include_receipts=True)
60-
and not line.is_split_payment
61-
and not any(ml.is_split_payment for ml in line.move_id.line_ids)
62-
):
63-
write_off_line_vals = line._build_writeoff_line()
64-
line.move_id.line_ids = [(0, 0, write_off_line_vals)]
65-
line.move_id._sync_dynamic_lines(
66-
container={"records": line.move_id, "self": line.move_id}
67-
)
57+
move_ids = lines.filtered(
58+
lambda line: line.display_type == "tax"
59+
and line.move_id.split_payment
60+
and line.move_id.is_sale_document(include_receipts=True)
61+
and not line.is_split_payment
62+
and not any(ml.is_split_payment for ml in line.move_id.line_ids)
63+
).mapped("move_id")
64+
move_ids.compute_split_payment()
6865
return lines

l10n_it_split_payment/readme/CONTRIBUTORS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@
88
- Alex Comba \<<alex.comba@agilebg.com>\>
99
- [Ooops](https://www.ooops404.com):
1010
- Giovanni Serra \<<giovanni@gslab.it>\>
11+
- [Stesi Consulting](https://www.stesi.consulting):
12+
- Michele Di Croce \<<dicroce.m@stesi.consulting>\>

l10n_it_split_payment/static/description/index.html

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -396,17 +396,17 @@ <h1><a class="toc-backref" href="#toc-entry-1">Configuration</a></h1>
396396
<p>Per configurare questo modulo è necessario:</p>
397397
<ul class="simple">
398398
<li>andare in Contabilità → Configurazione → Impostazioni e configura
399-
“Conto storno scissione pagamenti” (es. ‘IVA n/debito sospesa SP’). Il
400-
conto storno dovrebbe essere diverso dall’IVA a debito standard, in
401-
modo da aggiungerlo separatamente nella dichiarazione IVA.</li>
399+
“Conto storno scissione pagamenti” (es. ‘IVA n/debito sospesa SP’).
400+
Il conto storno dovrebbe essere diverso dall’IVA a debito standard,
401+
in modo da aggiungerlo separatamente nella dichiarazione IVA.</li>
402402
</ul>
403403
<p><strong>English</strong></p>
404404
<p>To configure this module, you need to:</p>
405405
<ul class="simple">
406406
<li>go to Accounting → Configuration → Settings and configure ‘Split
407-
Payment Write-off account’ (like ‘IVA n/debito sospesa SP’). Write-off
408-
account should be different from standard debit VAT, in order to
409-
separately add it in VAT statement.</li>
407+
Payment Write-off account’ (like ‘IVA n/debito sospesa SP’).
408+
Write-off account should be different from standard debit VAT, in
409+
order to separately add it in VAT statement.</li>
410410
</ul>
411411
<p><img alt="image1" src="https://raw.githubusercontent.com/OCA/l10n-italy/16.0/l10n_it_split_payment/static/settings.png" /></p>
412412
<hr class="docutils" />
@@ -427,16 +427,17 @@ <h1><a class="toc-backref" href="#toc-entry-1">Configuration</a></h1>
427427
<p><strong>Italiano</strong></p>
428428
<ul class="simple">
429429
<li>configurare la posizione fiscale (Contabilità → Configurazione →
430-
Contabilità → Posizioni fiscali) usata per la scissione dei pagamenti,
431-
selezionando la casella “Scissione pagamenti”. Nella posizione fiscale
432-
mappare l’IVA standard con l’IVA SP, come indicato di seguito:</li>
430+
Contabilità → Posizioni fiscali) usata per la scissione dei
431+
pagamenti, selezionando la casella “Scissione pagamenti”. Nella
432+
posizione fiscale mappare l’IVA standard con l’IVA SP, come indicato
433+
di seguito:</li>
433434
</ul>
434435
<p><strong>English</strong></p>
435436
<ul class="simple">
436-
<li>configure the fiscal position (Accounting → Configuration → Accounting
437-
→ Fiscal Positions) used for split payment, setting ‘Split Payment’
438-
flag. In fiscal position, map standard VAT with SP VAT, like the
439-
following:</li>
437+
<li>configure the fiscal position (Accounting → Configuration →
438+
Accounting → Fiscal Positions) used for split payment, setting ‘Split
439+
Payment’ flag. In fiscal position, map standard VAT with SP VAT, like
440+
the following:</li>
440441
</ul>
441442
<p><img alt="image4" src="https://raw.githubusercontent.com/OCA/l10n-italy/16.0/l10n_it_split_payment/static/fiscal_position.png" /></p>
442443
</div>
@@ -481,6 +482,10 @@ <h2><a class="toc-backref" href="#toc-entry-6">Contributors</a></h2>
481482
<li>Giovanni Serra &lt;<a class="reference external" href="mailto:giovanni&#64;gslab.it">giovanni&#64;gslab.it</a>&gt;</li>
482483
</ul>
483484
</li>
485+
<li><a class="reference external" href="https://www.stesi.consulting">Stesi Consulting</a>:<ul>
486+
<li>Michele Di Croce &lt;<a class="reference external" href="mailto:dicroce.m&#64;stesi.consulting">dicroce.m&#64;stesi.consulting</a>&gt;</li>
487+
</ul>
488+
</li>
484489
</ul>
485490
</div>
486491
<div class="section" id="maintainers">

l10n_it_split_payment/tests/test_splitpayment.py

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,24 @@ def setUp(self):
2727
"amount": 22,
2828
}
2929
)
30+
self.tax10sp = self.tax_model.create(
31+
{
32+
"name": "10% SP",
33+
"amount": 10,
34+
}
35+
)
3036
self.tax22 = self.tax_model.create(
3137
{
3238
"name": "22%",
3339
"amount": 22,
3440
}
3541
)
42+
self.tax10 = self.tax_model.create(
43+
{
44+
"name": "10%",
45+
"amount": 10,
46+
}
47+
)
3648
self.sp_fp = self.fp_model.create(
3749
{
3850
"name": "Split payment",
@@ -42,7 +54,12 @@ def setUp(self):
4254
0,
4355
0,
4456
{"tax_src_id": self.tax22.id, "tax_dest_id": self.tax22sp.id},
45-
)
57+
),
58+
(
59+
0,
60+
0,
61+
{"tax_src_id": self.tax10.id, "tax_dest_id": self.tax10sp.id},
62+
),
4663
],
4764
}
4865
)
@@ -272,3 +289,46 @@ def test_balanced_lines(self):
272289
self.assertEqual(invoice.amount_total, 200)
273290
self.assertEqual(invoice.amount_residual, 200)
274291
self.assertEqual(invoice.amount_tax, 0)
292+
293+
def test_invoice_two_sp_taxes(self):
294+
self.assertTrue(self.tax22sp.is_split_payment)
295+
self.assertTrue(self.tax10sp.is_split_payment)
296+
invoice = self.move_model.with_context(default_move_type="out_invoice").create(
297+
{
298+
"invoice_date": self.recent_date,
299+
"partner_id": self.env.ref("base.res_partner_3").id,
300+
"journal_id": self.sales_journal.id,
301+
"fiscal_position_id": self.sp_fp.id,
302+
"move_type": "out_refund",
303+
"invoice_line_ids": [
304+
(
305+
0,
306+
0,
307+
{
308+
"name": "service",
309+
"account_id": self.a_sale.id,
310+
"quantity": 1,
311+
"price_unit": 100,
312+
"tax_ids": [(6, 0, {self.tax22sp.id})],
313+
},
314+
),
315+
(
316+
0,
317+
0,
318+
{
319+
"name": "service2",
320+
"account_id": self.a_sale.id,
321+
"quantity": 1,
322+
"price_unit": 100,
323+
"tax_ids": [(6, 0, {self.tax10sp.id})],
324+
},
325+
),
326+
],
327+
}
328+
)
329+
line_sp = invoice.line_ids.filtered(
330+
lambda line: line.account_id.id == self.company.sp_account_id.id
331+
)
332+
333+
self.assertTrue(len(line_sp) == 1)
334+
self.assertEqual(line_sp.credit, 32)

0 commit comments

Comments
 (0)