44# Copyright 2023 Giuseppe Borruso <gborruso@dinamicheaziendali.it>
55# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
66
7- from odoo import Command , fields , models
7+ from odoo import Command , _ , fields , models
8+ from odoo .exceptions import UserError
89from odoo .tools import float_compare
910
1011
@@ -26,8 +27,6 @@ def _compute_amount(self):
2627 res = super ()._compute_amount ()
2728 for move in self :
2829 if move .split_payment :
29- if move .is_purchase_document ():
30- continue
3130 if move .tax_totals :
3231 move .amount_sp = (
3332 move .tax_totals ["amount_total" ]
@@ -43,14 +42,18 @@ def _compute_amount(self):
4342 return res
4443
4544 def write (self , vals ):
45+ if self .env .context .get ("skip_split_payment_computation" ):
46+ return super ().write (vals )
4647 res = super (AccountMove , self .with_context (check_move_validity = False )).write (
4748 vals
4849 )
49- if self .env .context .get ("skip_split_payment_computation" ):
50- return res
51- self .compute_split_payment ()
5250 container = {"records" : self }
53- self ._check_balanced (container )
51+ with self ._check_balanced (container ):
52+ if "fiscal_position_id" in vals :
53+ self ._compute_amount ()
54+ self .with_context (
55+ skip_split_payment_computation = True , check_move_validity = False
56+ ).compute_split_payment ()
5457 return res
5558
5659 def copy (self , default = None ):
@@ -63,15 +66,57 @@ def copy(self, default=None):
6366 res = super ().copy (default = default )
6467 return res
6568
69+ def _build_writeoff_line (self ):
70+ self .ensure_one ()
71+
72+ if not self .company_id .sp_account_id :
73+ raise UserError (
74+ _ (
75+ "Please set 'Split Payment Write-off Account' field in"
76+ " accounting configuration"
77+ )
78+ )
79+ debit = 0
80+ credit = 0
81+ move_tax_lines = self .line_ids .filtered (
82+ lambda line : ((line .display_type == "tax" ) and (not line .is_split_payment ))
83+ )
84+ for tax_line in move_tax_lines :
85+ debit += tax_line .credit
86+ credit += tax_line .debit
87+ if debit != 0 and credit != 0 :
88+ if debit >= credit :
89+ debit = debit - credit
90+ credit = 0
91+ else :
92+ credit = credit - debit
93+ debit = 0
94+
95+ vals = {
96+ "name" : _ ("Split Payment Write Off" ),
97+ "partner_id" : self .partner_id .id ,
98+ "account_id" : self .company_id .sp_account_id .id ,
99+ "journal_id" : self .journal_id .id ,
100+ "date" : self .invoice_date ,
101+ "date_maturity" : self .invoice_date ,
102+ "price_unit" : - debit + credit ,
103+ "amount_currency" : debit - credit ,
104+ "debit" : debit ,
105+ "credit" : credit ,
106+ "display_type" : "tax" ,
107+ "is_split_payment" : True ,
108+ }
109+ return vals
110+
66111 def compute_split_payment (self ):
67112 for move in self :
68- if move .split_payment :
113+ if move .is_sale_document ( include_receipts = True ) :
69114 line_sp = fields .first (
70115 move .line_ids .filtered (lambda move_line : move_line .is_split_payment )
71116 )
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 ()
117+ with move ._sync_dynamic_lines ( container = { "records" : move }) :
118+ if move . split_payment :
119+ write_off_line_vals = move ._build_writeoff_line ()
75120 if line_sp :
76121 if (
77122 float_compare (
@@ -81,9 +126,26 @@ def compute_split_payment(self):
81126 )
82127 != 0
83128 ):
84- line_sp .write (write_off_line_vals )
129+ line_sp .with_context (
130+ skip_split_payment_computation = True
131+ ).write (write_off_line_vals )
85132 else :
86- if move . amount_sp :
133+ if write_off_line_vals . get ( "price_unit" ) :
87134 move .with_context (
88135 skip_split_payment_computation = True
89136 ).line_ids = [Command .create (write_off_line_vals )]
137+ elif line_sp :
138+ neutralize_vals = {
139+ "debit" : 0.0 ,
140+ "credit" : 0.0 ,
141+ "amount_currency" : 0.0 ,
142+ "price_unit" : 0.0 ,
143+ "tax_base_amount" : 0.0 ,
144+ "tax_tag_ids" : [(6 , 0 , [])],
145+ }
146+ move .with_context (
147+ skip_split_payment_computation = True ,
148+ check_move_validity = False ,
149+ ).write (
150+ {"line_ids" : [Command .update (line_sp .id , neutralize_vals )]}
151+ )
0 commit comments