1- # -*- coding: utf-8 -*-
21# Copyright 2016 Davide Corio
32# Copyright 2017 Alex Comba - Agile Business Group
43# Copyright 2017 Lorenzo Battistini - Agile Business Group
@@ -35,22 +34,43 @@ class AccountInvoice(models.Model):
3534 comodel_name = 'account.invoice' ,
3635 string = 'RC Self Purchase Invoice' , copy = False , readonly = True )
3736
37+ rc_partner_supplier_id = fields .Many2one (
38+ 'res.partner' , string = 'Partner RC' , change_default = True ,
39+ required = False , readonly = True ,
40+ states = {'draft' : [('readonly' , False )]},
41+ track_visibility = 'always' )
42+
43+ rc_debit_credit_transfer_id = fields .Many2one (
44+ 'account.move' , required = False , readonly = True )
45+ company_partner = fields .Boolean (compute = '_compute_company_partner' )
46+
47+ rc_payment_move_id = fields .Many2one (
48+ string = "Reconciliation move" , comodel_name = 'account.move' ,
49+ required = False , readonly = True ,
50+ help = "Move that reconciles the purchase and sale invoice" )
51+
52+ @api .depends ('partner_id' )
53+ def _compute_company_partner (self ):
54+ for el in self :
55+ if el .partner_id == el .company_id .partner_id :
56+ el .company_partner = True
57+
3858 def rc_inv_line_vals (self , line ):
3959 return {
4060 'product_id' : line .product_id .id ,
4161 'name' : line .name ,
4262 'uom_id' : line .product_id .uom_id .id ,
4363 'price_unit' : line .price_unit ,
4464 'quantity' : line .quantity ,
45- }
65+ }
4666
4767 def rc_inv_vals (self , partner , account , rc_type , lines ):
4868 if self .type == 'in_invoice' :
4969 type = 'out_invoice'
5070 else :
5171 type = 'out_refund'
5272
53- return {
73+ vals = {
5474 'partner_id' : partner .id ,
5575 'type' : type ,
5676 'account_id' : account .id ,
@@ -61,9 +81,22 @@ def rc_inv_vals(self, partner, account, rc_type, lines):
6181 'origin' : self .number ,
6282 'rc_purchase_invoice_id' : self .id ,
6383 'name' : rc_type .self_invoice_text ,
64- 'fiscal_position_id' : None
84+ 'fiscal_position_id' : None ,
85+ 'rc_partner_supplier_id' : None
6586 }
6687
88+ # controllare se rc_type è other e se partner è la company
89+ # setto rc_partner_supplier con il partner di partenza
90+ if (rc_type .partner_type == 'other' and
91+ partner == self .company_id .partner_id ):
92+ # CREAZIONE DI UN'AUTOFATTURA
93+ vals ['rc_partner_supplier_id' ] = (
94+ self .rc_partner_supplier_id .id or
95+ self .partner_id .id
96+ )
97+
98+ return vals
99+
67100 def get_inv_line_to_reconcile (self ):
68101 for inv_line in self .move_id .line_ids :
69102 if (self .type == 'in_invoice' ) and inv_line .credit :
@@ -85,7 +118,7 @@ def rc_payment_vals(self, rc_type):
85118 'journal_id' : rc_type .payment_journal_id .id ,
86119 # 'period_id': self.period_id.id,
87120 'date' : self .date ,
88- }
121+ }
89122
90123 def rc_credit_line_vals (self , journal ):
91124 credit = debit = 0.0
@@ -100,7 +133,7 @@ def rc_credit_line_vals(self, journal):
100133 'debit' : debit ,
101134 'account_id' : journal .default_credit_account_id .id ,
102135 'company_id' : self .company_id .id ,
103- }
136+ }
104137
105138 def rc_debit_line_vals (self , amount = None ):
106139 credit = debit = 0.0
@@ -121,14 +154,14 @@ def rc_debit_line_vals(self, amount=None):
121154 'account_id' : self .get_inv_line_to_reconcile ().account_id .id ,
122155 'partner_id' : self .partner_id .id ,
123156 'company_id' : self .company_id .id
124- }
157+ }
125158
126159 def rc_invoice_payment_vals (self , rc_type ):
127160 return {
128161 'journal_id' : rc_type .payment_journal_id .id ,
129162 # 'period_id': self.period_id.id,
130163 'date' : self .date ,
131- }
164+ }
132165
133166 def rc_payment_credit_line_vals (self , invoice ):
134167 credit = debit = 0.0
@@ -144,7 +177,7 @@ def rc_payment_credit_line_vals(self, invoice):
144177 invoice ).account_id .id ,
145178 'partner_id' : invoice .partner_id .id ,
146179 'company_id' : self .company_id .id
147- }
180+ }
148181
149182 def rc_payment_debit_line_vals (self , invoice , journal ):
150183 credit = debit = 0.0
@@ -158,7 +191,7 @@ def rc_payment_debit_line_vals(self, invoice, journal):
158191 'credit' : credit ,
159192 'account_id' : journal .default_credit_account_id .id ,
160193 'company_id' : self .company_id .id
161- }
194+ }
162195
163196 def reconcile_supplier_invoice (self ):
164197 rc_type = self .fiscal_position_id .rc_type_id
@@ -206,24 +239,32 @@ def prepare_reconcile_supplier_invoice(self):
206239 rc_type .payment_journal_id )
207240
208241 payment_debit_line_data = self .rc_debit_line_vals ()
209- rc_payment .line_ids = [
210- (0 , 0 , payment_debit_line_data ),
211- (0 , 0 , payment_credit_line_data ),
212- ]
242+ # Avoid payment lines without amounts
243+ if (payment_credit_line_data ['debit' ] or
244+ payment_credit_line_data ['credit' ]):
245+ rc_payment .line_ids = [
246+ (0 , 0 , payment_debit_line_data ),
247+ (0 , 0 , payment_credit_line_data ),
248+ ]
213249 return rc_payment
214250
215251 def partially_reconcile_supplier_invoice (self , rc_payment ):
216252 move_line_model = self .env ['account.move.line' ]
253+ inv_line_to_reconcile = self .get_inv_line_to_reconcile ()
254+ payment_debit_line = False
217255 for move_line in rc_payment .line_ids :
256+ if (inv_line_to_reconcile .account_id .id !=
257+ move_line .account_id .id ):
258+ continue
218259 # testa se nota credito o debito
219- if ( self .type == 'in_invoice' ) and move_line .debit :
260+ if self .type == 'in_invoice' and move_line .debit :
220261 payment_debit_line = move_line
221- elif ( self .type == 'in_refund' ) and move_line .credit :
262+ elif self .type == 'in_refund' and move_line .credit :
222263 payment_debit_line = move_line
223- inv_lines_to_rec = move_line_model . browse (
224- [ self . get_inv_line_to_reconcile (). id ,
225- payment_debit_line .id ])
226- inv_lines_to_rec .reconcile ()
264+ if payment_debit_line :
265+ inv_lines_to_rec = move_line_model . browse (
266+ [ inv_line_to_reconcile . id , payment_debit_line .id ])
267+ inv_lines_to_rec .reconcile ()
227268
228269 def reconcile_rc_invoice (self , rc_payment ):
229270 rc_type = self .fiscal_position_id .rc_type_id
@@ -286,6 +327,7 @@ def generate_self_invoice(self):
286327 inv_vals = self .rc_inv_vals (
287328 rc_partner , rc_account , rc_type , rc_invoice_lines )
288329
330+ inv_vals ['comment' ] = self .fiscal_position_id .note
289331 # create or write the self invoice
290332 if self .rc_self_invoice_id :
291333 # this is needed when user takes back to draft supplier
@@ -304,6 +346,7 @@ def generate_self_invoice(self):
304346 self .reconcile_supplier_invoice ()
305347 else :
306348 rc_payment = self .prepare_reconcile_supplier_invoice ()
349+ self .write ({'rc_payment_move_id' : rc_payment .id })
307350 self .reconcile_rc_invoice (rc_payment )
308351 self .partially_reconcile_supplier_invoice (rc_payment )
309352
@@ -339,10 +382,20 @@ def generate_supplier_self_invoice(self):
339382 supplier_invoice .action_invoice_open ()
340383 supplier_invoice .fiscal_position_id = self .fiscal_position_id .id
341384
385+ self ._set_rc_partner_supplier_id (rc_type , supplier_invoice )
386+
387+ def _set_rc_partner_supplier_id (self , rc_type , supplier_invoice ):
388+ if (rc_type .partner_type == 'other' and
389+ rc_type .partner_id == self .company_id .partner_id ):
390+ partner_ref = self .rc_partner_supplier_id or self .partner_id
391+ # ref del partner da cui si stanno generando le autofatture
392+ supplier_invoice .rc_partner_supplier_id = partner_ref
393+
342394 @api .multi
343395 def invoice_validate (self ):
344396 self .ensure_one ()
345397 res = super (AccountInvoice , self ).invoice_validate ()
398+
346399 fp = self .fiscal_position_id
347400 rc_type = fp and fp .rc_type_id
348401 if rc_type and rc_type .method == 'selfinvoice' \
@@ -353,8 +406,84 @@ def invoice_validate(self):
353406 # See with_supplier_self_invoice field help
354407 self .generate_supplier_self_invoice ()
355408 self .rc_self_purchase_invoice_id .generate_self_invoice ()
409+
410+ if (rc_type and
411+ rc_type .method == 'selfinvoice' and
412+ self .amount_total and
413+ self .type in ('in_invoice' , 'in_refund' ) and
414+ self .company_partner is True
415+ ):
416+ self .transfer_debit_partner_supplier ()
356417 return res
357418
419+ def transfer_debit_partner_supplier (self ):
420+ """
421+ Se il partner della fattura di partenza (no RC) è la company ed
422+ è una fattura di acquisto, deve essere aperto un debito vs il
423+ parnter di partenza e chiuso quello del partner
424+ """
425+ # Credit/debit logic refund
426+ ml_company = False
427+ for ml in self .move_id .line_ids :
428+ if ml .account_id .user_type_id .type in ['receivable' , 'payable' ]:
429+ ml_company = ml
430+ break
431+
432+ if ml_company :
433+ move_lines = []
434+ # Refund my company
435+ if ml_company .debit :
436+ desc = _ ('Credit transfer for reverse charge' )
437+ else :
438+ desc = _ ('Debit transfer for reverse charge' )
439+ company_line = {
440+ 'partner_id' : self .partner_id .id ,
441+ 'account_id' : ml_company .account_id .id ,
442+ 'credit' : (ml_company and
443+ ml_company .debit and
444+ self .residual or 0 ),
445+ 'debit' : (ml_company and
446+ ml_company .credit and
447+ self .residual or 0 ),
448+ 'name' : desc ,
449+ }
450+ move_lines .append ((0 , 0 , company_line ))
451+ # Add debit/credit to RC partner
452+ partner_rc_line = {
453+ 'partner_id' : self .rc_partner_supplier_id .id ,
454+ 'account_id' : ml_company .account_id .id ,
455+ 'credit' : (ml_company and
456+ ml_company .credit and
457+ self .residual or 0 ),
458+ 'debit' : (ml_company and
459+ ml_company .debit and
460+ self .residual or 0 ),
461+ 'name' : desc ,
462+ }
463+ move_lines .append ((0 , 0 , partner_rc_line ))
464+
465+ move_val = {
466+ 'date' : self .move_id .date ,
467+ 'company_id' : self .move_id .company_id .id ,
468+ 'journal_id' :
469+ self .fiscal_position_id .rc_type_id .payment_journal_id .id ,
470+ 'line_ids' : move_lines
471+ }
472+ move_transfer = self .env ['account.move' ].create (move_val )
473+ self .write ({'rc_debit_credit_transfer_id' : move_transfer .id })
474+
475+ # Reconcile supplier invoice with transfer
476+ lines_to_reconcile = []
477+ domain = [('move_id' , '=' , move_transfer .id ),
478+ ('partner_id' , '=' , self .partner_id .id )]
479+ ml_transfer_company = self .env ['account.move.line' ]\
480+ .search (domain , order = 'id' , limit = 1 )
481+ if ml_transfer_company :
482+ lines_to_reconcile = ml_transfer_company + ml_company
483+ lines_to_reconcile .reconcile ()
484+
485+ return move_transfer
486+
358487 def remove_rc_payment (self ):
359488 inv = self
360489 if inv .payment_move_line_ids :
0 commit comments