2006-12-07 13:41:40 +00:00
# -*- encoding: utf-8 -*-
##############################################################################
#
2008-11-06 07:29:50 +00:00
# OpenERP, Open Source Management Solution
2009-01-04 22:12:50 +00:00
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
2008-11-03 19:18:56 +00:00
# $Id$
2006-12-07 13:41:40 +00:00
#
2008-11-03 19:18:56 +00:00
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
2006-12-07 13:41:40 +00:00
#
2008-11-03 19:18:56 +00:00
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
2006-12-07 13:41:40 +00:00
#
2008-11-03 19:18:56 +00:00
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
2006-12-07 13:41:40 +00:00
#
##############################################################################
import time
import netsvc
from osv import fields , osv
import ir
2006-12-19 13:49:50 +00:00
import pooler
2007-01-03 08:37:33 +00:00
import mx . DateTime
from mx . DateTime import RelativeDateTime
2007-05-11 11:52:16 +00:00
from tools import config
2008-07-08 08:13:12 +00:00
from tools . translate import _
2007-05-11 11:52:16 +00:00
2009-01-16 06:21:02 +00:00
class fiscalyear_seq ( osv . osv ) :
_name = " fiscalyear.seq "
_description = " Maintains Invoice sequences with Fiscal Year "
_rec_name = ' fiscalyear_id '
_columns = {
' journal_id ' : fields . many2one ( ' account.journal ' , ' Journal ' ) ,
' fiscalyear_id ' : fields . many2one ( ' account.fiscalyear ' , ' Fiscal Year ' , required = True ) ,
' sequence_id ' : fields . many2one ( ' ir.sequence ' , ' Sequence ' , required = True ) ,
}
fiscalyear_seq ( )
2006-12-07 13:41:40 +00:00
class account_invoice ( osv . osv ) :
2009-01-06 13:31:53 +00:00
def _amount_all ( self , cr , uid , ids , name , args , context = None ) :
2008-07-22 15:11:28 +00:00
res = { }
2008-12-08 07:56:41 +00:00
for invoice in self . browse ( cr , uid , ids , context = context ) :
2008-12-07 02:15:41 +00:00
res [ invoice . id ] = {
' amount_untaxed ' : 0.0 ,
' amount_tax ' : 0.0 ,
' amount_total ' : 0.0
}
for line in invoice . invoice_line :
res [ invoice . id ] [ ' amount_untaxed ' ] + = line . price_subtotal
for line in invoice . tax_line :
res [ invoice . id ] [ ' amount_tax ' ] + = line . amount
res [ invoice . id ] [ ' amount_total ' ] = res [ invoice . id ] [ ' amount_tax ' ] + res [ invoice . id ] [ ' amount_untaxed ' ]
2008-07-22 15:11:28 +00:00
return res
def _get_journal ( self , cr , uid , context ) :
2009-01-06 13:31:53 +00:00
if context is None :
context = { }
2008-07-22 15:11:28 +00:00
type_inv = context . get ( ' type ' , ' out_invoice ' )
type2journal = { ' out_invoice ' : ' sale ' , ' in_invoice ' : ' purchase ' , ' out_refund ' : ' sale ' , ' in_refund ' : ' purchase ' }
journal_obj = self . pool . get ( ' account.journal ' )
res = journal_obj . search ( cr , uid , [ ( ' type ' , ' = ' , type2journal . get ( type_inv , ' sale ' ) ) ] , limit = 1 )
if res :
return res [ 0 ]
else :
return False
def _get_currency ( self , cr , uid , context ) :
user = pooler . get_pool ( cr . dbname ) . get ( ' res.users ' ) . browse ( cr , uid , [ uid ] ) [ 0 ]
if user . company_id :
return user . company_id . currency_id . id
else :
return pooler . get_pool ( cr . dbname ) . get ( ' res.currency ' ) . search ( cr , uid , [ ( ' rate ' , ' = ' , 1.0 ) ] ) [ 0 ]
2009-01-06 13:31:53 +00:00
def _get_journal_analytic ( self , cr , uid , type_inv , context = None ) :
2008-07-22 15:11:28 +00:00
type2journal = { ' out_invoice ' : ' sale ' , ' in_invoice ' : ' purchase ' , ' out_refund ' : ' sale ' , ' in_refund ' : ' purchase ' }
tt = type2journal . get ( type_inv , ' sale ' )
2008-10-31 22:43:31 +00:00
result = self . pool . get ( ' account.analytic.journal ' ) . search ( cr , uid , [ ( ' type ' , ' = ' , tt ) ] , context = context )
2008-07-22 15:11:28 +00:00
if not result :
2009-01-27 11:15:46 +00:00
raise osv . except_osv ( _ ( ' No Analytic Journal ! ' ) , _ ( " You must define an analytic journal of type ' %s ' ! " ) % ( tt , ) )
2008-07-22 15:11:28 +00:00
return result [ 0 ]
2009-01-06 13:31:53 +00:00
def _get_type ( self , cr , uid , context = None ) :
if context is None :
context = { }
2008-07-22 15:11:28 +00:00
type = context . get ( ' type ' , ' out_invoice ' )
return type
def _reconciled ( self , cr , uid , ids , name , args , context ) :
res = { }
for id in ids :
res [ id ] = self . test_paid ( cr , uid , [ id ] )
return res
2008-12-08 17:08:40 +00:00
def _get_reference_type ( self , cr , uid , context = None ) :
return [ ( ' none ' , _ ( ' Free Reference ' ) ) ]
2008-07-22 15:11:28 +00:00
2009-01-06 13:31:53 +00:00
def _amount_residual ( self , cr , uid , ids , name , args , context = None ) :
2008-09-12 07:21:22 +00:00
res = { }
data_inv = self . browse ( cr , uid , ids )
for inv in data_inv :
paid_amt = 0.0
to_pay = inv . amount_total
for lines in inv . move_lines :
2009-01-17 19:09:00 +00:00
paid_amt = paid_amt - lines . credit + lines . debit
res [ inv . id ] = to_pay - abs ( paid_amt )
2008-09-12 07:21:22 +00:00
return res
def _get_lines ( self , cr , uid , ids , name , arg , context = None ) :
res = { }
for id in ids :
move_lines = self . move_line_id_payment_get ( cr , uid , [ id ] )
if not move_lines :
res [ id ] = [ ]
continue
data_lines = self . pool . get ( ' account.move.line ' ) . browse ( cr , uid , move_lines )
for line in data_lines :
ids_line = [ ]
if line . reconcile_id :
ids_line = line . reconcile_id . line_id
elif line . reconcile_partial_id :
ids_line = line . reconcile_partial_id . line_partial_ids
l = map ( lambda x : x . id , ids_line )
res [ id ] = [ x for x in l if x < > line . id ]
return res
2008-09-18 13:32:58 +00:00
2009-01-06 13:31:53 +00:00
def _get_invoice_line ( self , cr , uid , ids , context = None ) :
2008-12-07 12:45:27 +00:00
result = { }
2008-12-08 07:56:41 +00:00
for line in self . pool . get ( ' account.invoice.line ' ) . browse ( cr , uid , ids , context = context ) :
result [ line . invoice_id . id ] = True
2008-12-07 12:45:27 +00:00
return result . keys ( )
2009-01-06 13:31:53 +00:00
def _get_invoice_tax ( self , cr , uid , ids , context = None ) :
2008-12-07 02:15:41 +00:00
result = { }
for tax in self . pool . get ( ' account.invoice.tax ' ) . browse ( cr , uid , ids , context = context ) :
result [ tax . invoice_id . id ] = True
return result . keys ( )
2009-01-06 13:31:53 +00:00
def _compute_lines ( self , cr , uid , ids , name , args , context = None ) :
2008-09-16 11:45:13 +00:00
result = { }
for invoice in self . browse ( cr , uid , ids , context ) :
moves = self . move_line_id_payment_get ( cr , uid , [ invoice . id ] )
src = [ ]
lines = [ ]
for m in self . pool . get ( ' account.move.line ' ) . browse ( cr , uid , moves , context ) :
if m . reconcile_id :
lines + = map ( lambda x : x . id , m . reconcile_id . line_id )
elif m . reconcile_partial_id :
lines + = map ( lambda x : x . id , m . reconcile_partial_id . line_partial_ids )
src . append ( m . id )
lines = filter ( lambda x : x not in src , lines )
result [ invoice . id ] = lines
return result
2008-09-12 07:21:22 +00:00
2009-01-16 09:44:05 +00:00
def _get_invoice_from_line ( self , cr , uid , ids , context = { } ) :
move = { }
for line in self . pool . get ( ' account.move.line ' ) . browse ( cr , uid , ids ) :
2009-01-16 10:02:34 +00:00
if line . reconcile_partial_id :
for line2 in line . reconcile_partial_id . line_partial_ids :
move [ line2 . move_id . id ] = True
if line . reconcile_id :
for line2 in line . reconcile_id . line_id :
move [ line2 . move_id . id ] = True
2009-01-16 09:44:05 +00:00
invoice_ids = [ ]
if move :
invoice_ids = self . pool . get ( ' account.invoice ' ) . search ( cr , uid , [ ( ' move_id ' , ' in ' , move . keys ( ) ) ] , context = context )
return invoice_ids
def _get_invoice_from_reconcile ( self , cr , uid , ids , context = { } ) :
move = { }
for r in self . pool . get ( ' account.move.reconcile ' ) . browse ( cr , uid , ids ) :
for line in r . line_partial_ids :
move [ line . move_id . id ] = True
for line in r . line_id :
move [ line . move_id . id ] = True
2009-02-27 07:04:59 +00:00
2009-01-16 09:44:05 +00:00
invoice_ids = [ ]
if move :
invoice_ids = self . pool . get ( ' account.invoice ' ) . search ( cr , uid , [ ( ' move_id ' , ' in ' , move . keys ( ) ) ] , context = context )
return invoice_ids
2008-07-22 15:11:28 +00:00
_name = " account.invoice "
_description = ' Invoice '
_order = " number "
_columns = {
' name ' : fields . char ( ' Description ' , size = 64 , select = True , readonly = True , states = { ' draft ' : [ ( ' readonly ' , False ) ] } ) ,
2008-09-22 06:06:56 +00:00
' origin ' : fields . char ( ' Origin ' , size = 64 , help = " Reference of the document that produced this invoice. " ) ,
2008-07-22 15:11:28 +00:00
' type ' : fields . selection ( [
( ' out_invoice ' , ' Customer Invoice ' ) ,
( ' in_invoice ' , ' Supplier Invoice ' ) ,
( ' out_refund ' , ' Customer Refund ' ) ,
( ' in_refund ' , ' Supplier Refund ' ) ,
] , ' Type ' , readonly = True , select = True ) ,
2009-01-21 08:33:11 +00:00
' number ' : fields . char ( ' Invoice Number ' , size = 32 , readonly = True , help = " Unique number of the invoice, computed automatically when the invoice is created. " ) ,
2008-09-22 06:06:56 +00:00
' reference ' : fields . char ( ' Invoice Reference ' , size = 64 , help = " The partner reference of this invoice. " ) ,
2008-07-22 15:11:28 +00:00
' reference_type ' : fields . selection ( _get_reference_type , ' Reference Type ' ,
required = True ) ,
2009-01-21 08:33:11 +00:00
' comment ' : fields . text ( ' Additional Information ' ) ,
2008-07-22 15:11:28 +00:00
' state ' : fields . selection ( [
( ' draft ' , ' Draft ' ) ,
( ' proforma ' , ' Pro-forma ' ) ,
2008-10-07 10:02:21 +00:00
( ' proforma2 ' , ' Pro-forma ' ) ,
2008-07-22 15:11:28 +00:00
( ' open ' , ' Open ' ) ,
2008-08-14 13:49:58 +00:00
( ' paid ' , ' Done ' ) ,
2009-01-21 08:33:11 +00:00
( ' cancel ' , ' Cancelled ' )
2008-07-22 15:11:28 +00:00
] , ' State ' , select = True , readonly = True ) ,
2009-04-17 14:57:40 +00:00
' date_invoice ' : fields . date ( ' Date Invoiced ' , states = { ' open ' : [ ( ' readonly ' , True ) ] , ' close ' : [ ( ' readonly ' , True ) ] } , help = " Keep empty to use the current date " ) ,
2009-01-16 09:44:05 +00:00
' date_due ' : fields . date ( ' Due Date ' , states = { ' open ' : [ ( ' readonly ' , True ) ] , ' close ' : [ ( ' readonly ' , True ) ] } ,
help = " If you use payment terms, the due date will be computed automatically at the generation " \
2009-04-17 14:57:40 +00:00
" of accounting entries. If you keep the payment term and the due date empty, it means direct payment. The payment term may compute several due dates, for example 50 % now, 50 % i n one month. " ) ,
2008-07-22 15:11:28 +00:00
' partner_id ' : fields . many2one ( ' res.partner ' , ' Partner ' , change_default = True , readonly = True , required = True , states = { ' draft ' : [ ( ' readonly ' , False ) ] } ) ,
' address_contact_id ' : fields . many2one ( ' res.partner.address ' , ' Contact Address ' , readonly = True , states = { ' draft ' : [ ( ' readonly ' , False ) ] } ) ,
' address_invoice_id ' : fields . many2one ( ' res.partner.address ' , ' Invoice Address ' , readonly = True , required = True , states = { ' draft ' : [ ( ' readonly ' , False ) ] } ) ,
2009-01-16 09:44:05 +00:00
' payment_term ' : fields . many2one ( ' account.payment.term ' , ' Payment Term ' , readonly = True , states = { ' draft ' : [ ( ' readonly ' , False ) ] } ,
help = " If you use payment terms, the due date will be computed automatically at the generation " \
" of accounting entries. If you keep the payment term and the due date empty, it means direct payment. " \
2009-01-27 11:15:46 +00:00
" The payment term may compute several due dates, for example 50 % now, 50 % i n one month. " ) ,
2009-07-06 18:59:08 +00:00
' period_id ' : fields . many2one ( ' account.period ' , ' Force Period ' , domain = [ ( ' state ' , ' <> ' , ' done ' ) ] , help = " Keep empty to use the period of the validation(invoice) date. " , readonly = True , states = { ' draft ' : [ ( ' readonly ' , False ) ] } ) ,
2008-07-22 15:11:28 +00:00
2008-09-22 06:06:56 +00:00
' account_id ' : fields . many2one ( ' account.account ' , ' Account ' , required = True , readonly = True , states = { ' draft ' : [ ( ' readonly ' , False ) ] } , help = " The partner account used for this invoice. " ) ,
2008-07-22 15:11:28 +00:00
' invoice_line ' : fields . one2many ( ' account.invoice.line ' , ' invoice_id ' , ' Invoice Lines ' , readonly = True , states = { ' draft ' : [ ( ' readonly ' , False ) ] } ) ,
' tax_line ' : fields . one2many ( ' account.invoice.tax ' , ' invoice_id ' , ' Tax Lines ' , readonly = True , states = { ' draft ' : [ ( ' readonly ' , False ) ] } ) ,
2008-09-22 06:06:56 +00:00
' move_id ' : fields . many2one ( ' account.move ' , ' Invoice Movement ' , readonly = True , help = " Link to the automatically generated account moves. " ) ,
2008-12-07 02:15:41 +00:00
' amount_untaxed ' : fields . function ( _amount_all , method = True , digits = ( 16 , 2 ) , string = ' Untaxed ' ,
store = {
2008-12-14 16:46:57 +00:00
' account.invoice ' : ( lambda self , cr , uid , ids , c = { } : ids , None , 20 ) ,
' account.invoice.tax ' : ( _get_invoice_tax , None , 20 ) ,
' account.invoice.line ' : ( _get_invoice_line , None , 20 ) ,
2008-12-07 02:15:41 +00:00
} ,
multi = ' all ' ) ,
' amount_tax ' : fields . function ( _amount_all , method = True , digits = ( 16 , 2 ) , string = ' Tax ' ,
store = {
2008-12-14 16:46:57 +00:00
' account.invoice ' : ( lambda self , cr , uid , ids , c = { } : ids , None , 20 ) ,
' account.invoice.tax ' : ( _get_invoice_tax , None , 20 ) ,
' account.invoice.line ' : ( _get_invoice_line , None , 20 ) ,
2008-12-07 02:15:41 +00:00
} ,
multi = ' all ' ) ,
' amount_total ' : fields . function ( _amount_all , method = True , digits = ( 16 , 2 ) , string = ' Total ' ,
store = {
2008-12-14 16:46:57 +00:00
' account.invoice ' : ( lambda self , cr , uid , ids , c = { } : ids , None , 20 ) ,
' account.invoice.tax ' : ( _get_invoice_tax , None , 20 ) ,
' account.invoice.line ' : ( _get_invoice_line , None , 20 ) ,
2008-12-07 02:15:41 +00:00
} ,
multi = ' all ' ) ,
2008-07-22 15:11:28 +00:00
' currency_id ' : fields . many2one ( ' res.currency ' , ' Currency ' , required = True , readonly = True , states = { ' draft ' : [ ( ' readonly ' , False ) ] } ) ,
' journal_id ' : fields . many2one ( ' account.journal ' , ' Journal ' , required = True , readonly = True , states = { ' draft ' : [ ( ' readonly ' , False ) ] } ) ,
' company_id ' : fields . many2one ( ' res.company ' , ' Company ' , required = True ) ,
' check_total ' : fields . float ( ' Total ' , digits = ( 16 , 2 ) , states = { ' open ' : [ ( ' readonly ' , True ) ] , ' close ' : [ ( ' readonly ' , True ) ] } ) ,
2008-12-07 02:15:41 +00:00
' reconciled ' : fields . function ( _reconciled , method = True , string = ' Paid/Reconciled ' , type = ' boolean ' ,
2009-01-26 22:22:32 +00:00
store = {
' account.invoice ' : ( lambda self , cr , uid , ids , c = { } : ids , None , 50 ) ,
' account.move.line ' : ( _get_invoice_from_line , None , 50 ) ,
' account.move.reconcile ' : ( _get_invoice_from_reconcile , None , 50 ) ,
} , help = " The account moves of the invoice have been reconciled with account moves of the payment(s). " ) ,
2008-07-22 15:11:28 +00:00
' partner_bank ' : fields . many2one ( ' res.partner.bank ' , ' Bank Account ' ,
2008-08-14 13:49:58 +00:00
help = ' The bank account to pay to or to be paid from ' ) ,
2008-09-12 07:21:22 +00:00
' move_lines ' : fields . function ( _get_lines , method = True , type = ' many2many ' , relation = ' account.move.line ' , string = ' Move Lines ' ) ,
2008-12-07 02:45:43 +00:00
' residual ' : fields . function ( _amount_residual , method = True , digits = ( 16 , 2 ) , string = ' Residual ' ,
store = {
2008-12-14 16:46:57 +00:00
' account.invoice ' : ( lambda self , cr , uid , ids , c = { } : ids , None , 50 ) ,
' account.invoice.tax ' : ( _get_invoice_tax , None , 50 ) ,
' account.invoice.line ' : ( _get_invoice_line , None , 50 ) ,
2009-01-16 09:44:05 +00:00
' account.move.line ' : ( _get_invoice_from_line , None , 50 ) ,
' account.move.reconcile ' : ( _get_invoice_from_reconcile , None , 50 ) ,
2008-12-07 02:45:43 +00:00
} ,
help = " Remaining amount due. " ) ,
2008-09-16 11:45:13 +00:00
' payment_ids ' : fields . function ( _compute_lines , method = True , relation = ' account.move.line ' , type = " many2many " , string = ' Payments ' ) ,
2008-11-06 14:29:10 +00:00
' move_name ' : fields . char ( ' Account Move ' , size = 64 ) ,
2009-01-19 13:59:11 +00:00
' fiscal_position ' : fields . many2one ( ' account.fiscal.position ' , ' Fiscal Position ' )
2008-07-22 15:11:28 +00:00
}
_defaults = {
' type ' : _get_type ,
2008-10-14 15:05:12 +00:00
#'date_invoice': lambda *a: time.strftime('%Y-%m-%d'),
2008-07-22 15:11:28 +00:00
' state ' : lambda * a : ' draft ' ,
' journal_id ' : _get_journal ,
' currency_id ' : _get_currency ,
' company_id ' : lambda self , cr , uid , context : \
self . pool . get ( ' res.users ' ) . browse ( cr , uid , uid ,
context = context ) . company_id . id ,
' reference_type ' : lambda * a : ' none ' ,
}
2009-01-21 11:21:21 +00:00
def unlink ( self , cr , uid , ids , context = None ) :
2009-04-07 12:15:46 +00:00
invoices = self . read ( cr , uid , ids , [ ' state ' ] )
unlink_ids = [ ]
for t in invoices :
if t [ ' state ' ] in ( ' draft ' , ' cancel ' ) :
unlink_ids . append ( t [ ' id ' ] )
else :
raise osv . except_osv ( _ ( ' Invalid action ! ' ) , _ ( ' Cannot delete invoice(s) that are already opened or paid ! ' ) )
osv . osv . unlink ( self , cr , uid , unlink_ids , context = context )
return True
2008-07-22 15:11:28 +00:00
# def get_invoice_address(self, cr, uid, ids):
# res = self.pool.get('res.partner').address_get(cr, uid, [part], ['invoice'])
# return [{}]
def onchange_partner_id ( self , cr , uid , ids , type , partner_id ,
date_invoice = False , payment_term = False , partner_bank_id = False ) :
invoice_addr_id = False
contact_addr_id = False
partner_payment_term = False
acc_id = False
bank_id = False
2009-01-19 13:59:11 +00:00
fiscal_position = False
2008-07-22 15:11:28 +00:00
opt = [ ( ' uid ' , str ( uid ) ) ]
if partner_id :
opt . insert ( 0 , ( ' id ' , partner_id ) )
res = self . pool . get ( ' res.partner ' ) . address_get ( cr , uid , [ partner_id ] , [ ' contact ' , ' invoice ' ] )
contact_addr_id = res [ ' contact ' ]
invoice_addr_id = res [ ' invoice ' ]
p = self . pool . get ( ' res.partner ' ) . browse ( cr , uid , partner_id )
if type in ( ' out_invoice ' , ' out_refund ' ) :
acc_id = p . property_account_receivable . id
else :
acc_id = p . property_account_payable . id
2009-01-19 16:49:29 +00:00
fiscal_position = p . property_account_position and p . property_account_position . id or False
2008-07-22 15:11:28 +00:00
partner_payment_term = p . property_payment_term and p . property_payment_term . id or False
if p . bank_ids :
bank_id = p . bank_ids [ 0 ] . id
result = { ' value ' : {
' address_contact_id ' : contact_addr_id ,
' address_invoice_id ' : invoice_addr_id ,
' account_id ' : acc_id ,
' payment_term ' : partner_payment_term ,
2009-01-19 13:59:11 +00:00
' fiscal_position ' : fiscal_position
2008-07-22 15:11:28 +00:00
}
}
if type in ( ' in_invoice ' , ' in_refund ' ) :
result [ ' value ' ] [ ' partner_bank ' ] = bank_id
if partner_bank_id != bank_id :
to_update = self . onchange_partner_bank ( cr , uid , ids , bank_id )
result [ ' value ' ] . update ( to_update [ ' value ' ] )
return result
def onchange_currency_id ( self , cr , uid , ids , curr_id ) :
return { }
def onchange_payment_term_date_invoice ( self , cr , uid , ids , payment_term_id , date_invoice ) :
if not payment_term_id :
return { }
res = { }
pt_obj = self . pool . get ( ' account.payment.term ' )
if not date_invoice :
2008-10-22 10:16:03 +00:00
date_invoice = time . strftime ( ' % Y- % m- %d ' )
2008-07-22 15:11:28 +00:00
2009-03-17 13:28:02 +00:00
pterm_list = pt_obj . compute ( cr , uid , payment_term_id , value = 1 , date_ref = date_invoice )
2008-07-22 15:11:28 +00:00
if pterm_list :
pterm_list = [ line [ 0 ] for line in pterm_list ]
pterm_list . sort ( )
res = { ' value ' : { ' date_due ' : pterm_list [ - 1 ] } }
2009-03-17 13:28:02 +00:00
else :
raise osv . except_osv ( _ ( ' Data Insufficient ! ' ) , _ ( ' The Payment Term of Supplier does not have Payment Term Lines(Computation) defined ! ' ) )
2009-04-09 10:02:19 +00:00
2008-07-22 15:11:28 +00:00
return res
def onchange_invoice_line ( self , cr , uid , ids , lines ) :
return { }
def onchange_partner_bank ( self , cursor , user , ids , partner_bank_id ) :
return { ' value ' : { } }
# go from canceled state to draft state
def action_cancel_draft ( self , cr , uid , ids , * args ) :
self . write ( cr , uid , ids , { ' state ' : ' draft ' } )
wf_service = netsvc . LocalService ( " workflow " )
for inv_id in ids :
wf_service . trg_create ( uid , ' account.invoice ' , inv_id , cr )
return True
# Workflow stuff
#################
# return the ids of the move lines which has the same account than the invoice
# whose id is in ids
def move_line_id_payment_get ( self , cr , uid , ids , * args ) :
ml = self . pool . get ( ' account.move.line ' )
res = [ ]
for inv in self . read ( cr , uid , ids , [ ' move_id ' , ' account_id ' ] ) :
if inv [ ' move_id ' ] :
move_line_ids = ml . search ( cr , uid , [ ( ' move_id ' , ' = ' , inv [ ' move_id ' ] [ 0 ] ) ] )
for line in ml . read ( cr , uid , move_line_ids , [ ' account_id ' ] ) :
if line [ ' account_id ' ] == inv [ ' account_id ' ] :
res . append ( line [ ' id ' ] )
return res
def copy ( self , cr , uid , id , default = None , context = None ) :
if default is None :
default = { }
default = default . copy ( )
2008-11-06 14:29:10 +00:00
default . update ( { ' state ' : ' draft ' , ' number ' : False , ' move_id ' : False , ' move_name ' : False , } )
2008-07-22 15:11:28 +00:00
if ' date_invoice ' not in default :
2008-10-14 15:05:12 +00:00
default [ ' date_invoice ' ] = False
2008-07-22 15:11:28 +00:00
if ' date_due ' not in default :
default [ ' date_due ' ] = False
return super ( account_invoice , self ) . copy ( cr , uid , id , default , context )
def test_paid ( self , cr , uid , ids , * args ) :
res = self . move_line_id_payment_get ( cr , uid , ids )
if not res :
return False
ok = True
for id in res :
2008-12-10 14:29:55 +00:00
cr . execute ( ' select reconcile_id from account_move_line where id= %s ' , ( id , ) )
2008-07-22 15:11:28 +00:00
ok = ok and bool ( cr . fetchone ( ) [ 0 ] )
return ok
2009-01-06 13:31:53 +00:00
def button_reset_taxes ( self , cr , uid , ids , context = None ) :
2009-02-02 07:10:01 +00:00
if not context :
context = { }
2008-07-22 15:11:28 +00:00
ait_obj = self . pool . get ( ' account.invoice.tax ' )
for id in ids :
2008-12-10 14:29:55 +00:00
cr . execute ( " DELETE FROM account_invoice_tax WHERE invoice_id= %s " , ( id , ) )
2009-01-28 14:41:13 +00:00
partner = self . browse ( cr , uid , id ) . partner_id
context . update ( { ' lang ' : partner . lang } )
for taxe in ait_obj . compute ( cr , uid , id , context = context ) . values ( ) :
2008-07-22 15:11:28 +00:00
ait_obj . create ( cr , uid , taxe )
2009-01-12 06:44:44 +00:00
# Update the stored value (fields.function), so we write to trigger recompute
2009-01-21 08:33:11 +00:00
self . pool . get ( ' account.invoice ' ) . write ( cr , uid , ids , { } , context = context )
2009-01-22 08:20:02 +00:00
# self.pool.get('account.invoice').write(cr, uid, ids, {}, context=context)
2008-07-22 15:11:28 +00:00
return True
2009-01-06 13:31:53 +00:00
def button_compute ( self , cr , uid , ids , context = None , set_total = False ) :
2008-12-31 12:58:51 +00:00
self . button_reset_taxes ( cr , uid , ids , context )
2008-07-22 15:11:28 +00:00
for inv in self . browse ( cr , uid , ids ) :
if set_total :
self . pool . get ( ' account.invoice ' ) . write ( cr , uid , [ inv . id ] , { ' check_total ' : inv . amount_total } )
return True
def _convert_ref ( self , cr , uid , ref ) :
return ( ref or ' ' ) . replace ( ' / ' , ' ' )
2008-12-02 18:06:01 +00:00
def _get_analytic_lines ( self , cr , uid , id ) :
2008-07-22 15:11:28 +00:00
inv = self . browse ( cr , uid , [ id ] ) [ 0 ]
cur_obj = self . pool . get ( ' res.currency ' )
company_currency = inv . company_id . currency_id . id
if inv . type in ( ' out_invoice ' , ' in_refund ' ) :
sign = 1
else :
sign = - 1
iml = self . pool . get ( ' account.invoice.line ' ) . move_line_get ( cr , uid , inv . id )
for il in iml :
if il [ ' account_analytic_id ' ] :
if inv . type in ( ' in_invoice ' , ' in_refund ' ) :
ref = inv . reference
else :
ref = self . _convert_ref ( cr , uid , inv . number )
il [ ' analytic_lines ' ] = [ ( 0 , 0 , {
' name ' : il [ ' name ' ] ,
' date ' : inv [ ' date_invoice ' ] ,
' account_id ' : il [ ' account_analytic_id ' ] ,
' unit_amount ' : il [ ' quantity ' ] ,
' amount ' : cur_obj . compute ( cr , uid , inv . currency_id . id , company_currency , il [ ' price ' ] , context = { ' date ' : inv . date_invoice } ) * sign ,
' product_id ' : il [ ' product_id ' ] ,
' product_uom_id ' : il [ ' uos_id ' ] ,
' general_account_id ' : il [ ' account_id ' ] ,
' journal_id ' : self . _get_journal_analytic ( cr , uid , inv . type ) ,
' ref ' : ref ,
} ) ]
return iml
2009-03-15 16:29:55 +00:00
def action_date_assign ( self , cr , uid , ids , * args ) :
for inv in self . browse ( cr , uid , ids ) :
res = self . onchange_payment_term_date_invoice ( cr , uid , inv . id , inv . payment_term . id , inv . date_invoice )
if res and res [ ' value ' ] :
self . write ( cr , uid , [ inv . id ] , res [ ' value ' ] )
return True
2008-07-22 15:11:28 +00:00
def action_move_create ( self , cr , uid , ids , * args ) :
ait_obj = self . pool . get ( ' account.invoice.tax ' )
cur_obj = self . pool . get ( ' res.currency ' )
2009-01-28 14:41:13 +00:00
context = { }
2008-07-22 15:11:28 +00:00
for inv in self . browse ( cr , uid , ids ) :
if inv . move_id :
continue
2009-01-16 10:37:17 +00:00
2008-10-14 15:05:12 +00:00
if not inv . date_invoice :
self . write ( cr , uid , [ inv . id ] , { ' date_invoice ' : time . strftime ( ' % Y- % m- %d ' ) } )
2008-07-22 15:11:28 +00:00
company_currency = inv . company_id . currency_id . id
# create the analytical lines
line_ids = self . read ( cr , uid , [ inv . id ] , [ ' invoice_line ' ] ) [ 0 ] [ ' invoice_line ' ]
# one move line per invoice line
2008-12-02 18:06:01 +00:00
iml = self . _get_analytic_lines ( cr , uid , inv . id )
2008-07-22 15:11:28 +00:00
# check if taxes are all computed
2009-01-28 14:41:13 +00:00
context . update ( { ' lang ' : inv . partner_id . lang } )
compute_taxes = ait_obj . compute ( cr , uid , inv . id , context = context )
2008-07-22 15:11:28 +00:00
if not inv . tax_line :
for tax in compute_taxes . values ( ) :
ait_obj . create ( cr , uid , tax )
else :
tax_key = [ ]
for tax in inv . tax_line :
if tax . manual :
continue
key = ( tax . tax_code_id . id , tax . base_code_id . id , tax . account_id . id )
tax_key . append ( key )
if not key in compute_taxes :
2009-01-27 11:15:46 +00:00
raise osv . except_osv ( _ ( ' Warning ! ' ) , _ ( ' Global taxes defined, but are not in invoice lines ! ' ) )
2008-07-22 15:11:28 +00:00
base = compute_taxes [ key ] [ ' base ' ]
if abs ( base - tax . base ) > inv . company_id . currency_id . rounding :
raise osv . except_osv ( _ ( ' Warning ! ' ) , _ ( ' Tax base different ! \n Click on compute to update tax base ' ) )
for key in compute_taxes :
if not key in tax_key :
raise osv . except_osv ( _ ( ' Warning ! ' ) , _ ( ' Taxes missing ! ' ) )
2009-01-27 10:06:08 +00:00
if inv . type in ( ' in_invoice ' , ' in_refund ' ) and abs ( inv . check_total - inv . amount_total ) > = ( inv . currency_id . rounding / 2.0 ) :
raise osv . except_osv ( _ ( ' Bad total ! ' ) , _ ( ' Please verify the price of the invoice ! \n The real total does not match the computed total. ' ) )
2008-07-22 15:11:28 +00:00
# one move line per tax line
iml + = ait_obj . move_line_get ( cr , uid , inv . id )
if inv . type in ( ' in_invoice ' , ' in_refund ' ) :
ref = inv . reference
else :
ref = self . _convert_ref ( cr , uid , inv . number )
diff_currency_p = inv . currency_id . id < > company_currency
# create one move line for the total and possibly adjust the other lines amount
total = 0
total_currency = 0
for i in iml :
if inv . currency_id . id != company_currency :
i [ ' currency_id ' ] = inv . currency_id . id
i [ ' amount_currency ' ] = i [ ' price ' ]
i [ ' price ' ] = cur_obj . compute ( cr , uid , inv . currency_id . id ,
company_currency , i [ ' price ' ] ,
2008-10-14 15:05:12 +00:00
context = { ' date ' : inv . date_invoice or time . strftime ( ' % Y- % m- %d ' ) } )
2008-07-22 15:11:28 +00:00
else :
i [ ' amount_currency ' ] = False
i [ ' currency_id ' ] = False
i [ ' ref ' ] = ref
if inv . type in ( ' out_invoice ' , ' in_refund ' ) :
total + = i [ ' price ' ]
total_currency + = i [ ' amount_currency ' ] or i [ ' price ' ]
i [ ' price ' ] = - i [ ' price ' ]
else :
total - = i [ ' price ' ]
total_currency - = i [ ' amount_currency ' ] or i [ ' price ' ]
acc_id = inv . account_id . id
name = inv [ ' name ' ] or ' / '
totlines = False
if inv . payment_term :
totlines = self . pool . get ( ' account.payment.term ' ) . compute ( cr ,
uid , inv . payment_term . id , total , inv . date_invoice or False )
if totlines :
res_amount_currency = total_currency
i = 0
for t in totlines :
if inv . currency_id . id != company_currency :
amount_currency = cur_obj . compute ( cr , uid ,
company_currency , inv . currency_id . id , t [ 1 ] )
else :
amount_currency = False
# last line add the diff
res_amount_currency - = amount_currency or 0
i + = 1
if i == len ( totlines ) :
amount_currency + = res_amount_currency
iml . append ( {
' type ' : ' dest ' ,
' name ' : name ,
' price ' : t [ 1 ] ,
' account_id ' : acc_id ,
' date_maturity ' : t [ 0 ] ,
' amount_currency ' : diff_currency_p \
and amount_currency or False ,
' currency_id ' : diff_currency_p \
and inv . currency_id . id or False ,
' ref ' : ref ,
} )
else :
iml . append ( {
' type ' : ' dest ' ,
' name ' : name ,
' price ' : total ,
' account_id ' : acc_id ,
' date_maturity ' : inv . date_due or False ,
' amount_currency ' : diff_currency_p \
and total_currency or False ,
' currency_id ' : diff_currency_p \
and inv . currency_id . id or False ,
' ref ' : ref
} )
2008-10-14 15:05:12 +00:00
date = inv . date_invoice or time . strftime ( ' % Y- % m- %d ' )
2008-07-22 15:11:28 +00:00
part = inv . partner_id . id
2008-12-26 18:11:02 +00:00
2008-07-22 15:11:28 +00:00
line = map ( lambda x : ( 0 , 0 , self . line_get_convert ( cr , uid , x , part , date , context = { } ) ) , iml )
2008-12-26 18:11:02 +00:00
if inv . journal_id . group_invoice_lines :
line2 = { }
for x , y , l in line :
tmp = str ( l [ ' account_id ' ] )
tmp + = ' - ' + str ( ' tax_code_id ' in l and l [ ' tax_code_id ' ] or " False " )
tmp + = ' - ' + str ( ' product_id ' in l and l [ ' product_id ' ] or " False " )
tmp + = ' - ' + str ( ' analytic_account_id ' in l and l [ ' analytic_account_id ' ] or " False " )
if tmp in line2 :
am = line2 [ tmp ] [ ' debit ' ] - line2 [ tmp ] [ ' credit ' ] + ( l [ ' debit ' ] - l [ ' credit ' ] )
line2 [ tmp ] [ ' debit ' ] = ( am > 0 ) and am or 0.0
line2 [ tmp ] [ ' credit ' ] = ( am < 0 ) and - am or 0.0
line2 [ tmp ] [ ' tax_amount ' ] + = l [ ' tax_amount ' ]
line2 [ tmp ] [ ' analytic_lines ' ] + = l [ ' analytic_lines ' ]
else :
line2 [ tmp ] = l
line = [ ]
for key , val in line2 . items ( ) :
line . append ( ( 0 , 0 , val ) )
2008-07-22 15:11:28 +00:00
journal_id = inv . journal_id . id #self._get_journal(cr, uid, {'type': inv['type']})
journal = self . pool . get ( ' account.journal ' ) . browse ( cr , uid , journal_id )
if journal . centralisation :
raise osv . except_osv ( _ ( ' UserError ' ) ,
2009-02-05 07:05:49 +00:00
_ ( ' Cannot create invoice move on centralised journal ' ) )
2008-12-14 19:37:38 +00:00
move = { ' ref ' : inv . number , ' line_id ' : line , ' journal_id ' : journal_id , ' date ' : date }
2008-08-25 12:25:04 +00:00
period_id = inv . period_id and inv . period_id . id or False
if not period_id :
2008-10-14 15:05:12 +00:00
period_ids = self . pool . get ( ' account.period ' ) . search ( cr , uid , [ ( ' date_start ' , ' <= ' , inv . date_invoice or time . strftime ( ' % Y- % m- %d ' ) ) , ( ' date_stop ' , ' >= ' , inv . date_invoice or time . strftime ( ' % Y- % m- %d ' ) ) ] )
2008-08-25 12:25:04 +00:00
if len ( period_ids ) :
period_id = period_ids [ 0 ]
if period_id :
move [ ' period_id ' ] = period_id
2008-07-22 15:11:28 +00:00
for i in line :
2008-08-25 12:25:04 +00:00
i [ 2 ] [ ' period_id ' ] = period_id
2008-12-15 10:41:24 +00:00
2008-07-22 15:11:28 +00:00
move_id = self . pool . get ( ' account.move ' ) . create ( cr , uid , move )
2008-11-06 14:29:10 +00:00
new_move_name = self . pool . get ( ' account.move ' ) . browse ( cr , uid , move_id ) . name
2008-07-22 15:11:28 +00:00
# make the invoice point to that move
2008-11-06 14:29:10 +00:00
self . write ( cr , uid , [ inv . id ] , { ' move_id ' : move_id , ' period_id ' : period_id , ' move_name ' : new_move_name } )
2008-07-22 15:11:28 +00:00
self . pool . get ( ' account.move ' ) . post ( cr , uid , [ move_id ] )
self . _log_event ( cr , uid , ids )
return True
2009-01-06 13:31:53 +00:00
def line_get_convert ( self , cr , uid , x , part , date , context = None ) :
2008-07-22 15:11:28 +00:00
return {
' date_maturity ' : x . get ( ' date_maturity ' , False ) ,
' partner_id ' : part ,
' name ' : x [ ' name ' ] [ : 64 ] ,
2009-01-28 18:33:27 +00:00
' date ' : date ,
2008-07-22 15:11:28 +00:00
' debit ' : x [ ' price ' ] > 0 and x [ ' price ' ] ,
' credit ' : x [ ' price ' ] < 0 and - x [ ' price ' ] ,
' account_id ' : x [ ' account_id ' ] ,
' analytic_lines ' : x . get ( ' analytic_lines ' , [ ] ) ,
' amount_currency ' : x [ ' price ' ] > 0 and abs ( x . get ( ' amount_currency ' , False ) ) or - abs ( x . get ( ' amount_currency ' , False ) ) ,
' currency_id ' : x . get ( ' currency_id ' , False ) ,
' tax_code_id ' : x . get ( ' tax_code_id ' , False ) ,
' tax_amount ' : x . get ( ' tax_amount ' , False ) ,
2008-11-06 07:29:50 +00:00
' ref ' : x . get ( ' ref ' , False ) ,
' quantity ' : x . get ( ' quantity ' , 1.00 ) ,
2008-11-26 17:04:17 +00:00
' product_id ' : x . get ( ' product_id ' , False ) ,
' product_uom_id ' : x . get ( ' uos_id ' , False ) ,
2008-11-21 15:17:45 +00:00
' analytic_account_id ' : x . get ( ' account_analytic_id ' , False ) ,
2008-07-22 15:11:28 +00:00
}
def action_number ( self , cr , uid , ids , * args ) :
cr . execute ( ' SELECT id, type, number, move_id, reference ' \
' FROM account_invoice ' \
' WHERE id IN ( ' + ' , ' . join ( map ( str , ids ) ) + ' ) ' )
2009-01-16 06:21:02 +00:00
obj_inv = self . browse ( cr , uid , ids ) [ 0 ]
2008-07-22 15:11:28 +00:00
for ( id , invtype , number , move_id , reference ) in cr . fetchall ( ) :
if not number :
2009-01-26 21:28:04 +00:00
if obj_inv . journal_id . invoice_sequence_id :
sid = obj_inv . journal_id . invoice_sequence_id . id
2009-01-27 00:17:53 +00:00
number = self . pool . get ( ' ir.sequence ' ) . get_id ( cr , uid , sid , ' id= %s ' , { ' fiscalyear_id ' : obj_inv . period_id . fiscalyear_id . id } )
2009-01-26 21:28:04 +00:00
else :
2009-01-16 06:21:02 +00:00
number = self . pool . get ( ' ir.sequence ' ) . get ( cr , uid ,
' account.invoice. ' + invtype )
2008-07-22 15:11:28 +00:00
if invtype in ( ' in_invoice ' , ' in_refund ' ) :
ref = reference
else :
ref = self . _convert_ref ( cr , uid , number )
cr . execute ( ' UPDATE account_invoice SET number= %s ' \
2008-12-10 14:29:55 +00:00
' WHERE id= %s ' , ( number , id ) )
2008-12-14 19:37:38 +00:00
cr . execute ( ' UPDATE account_move SET ref= %s ' \
' WHERE id= %s AND (ref is null OR ref = \' \' ) ' ,
( ref , move_id ) )
2008-07-22 15:11:28 +00:00
cr . execute ( ' UPDATE account_move_line SET ref= %s ' \
2008-12-10 14:29:55 +00:00
' WHERE move_id= %s AND (ref is null OR ref = \' \' ) ' ,
2008-07-22 15:11:28 +00:00
( ref , move_id ) )
cr . execute ( ' UPDATE account_analytic_line SET ref= %s ' \
' FROM account_move_line ' \
2008-12-10 14:29:55 +00:00
' WHERE account_move_line.move_id = %s ' \
2008-07-22 15:11:28 +00:00
' AND account_analytic_line.move_id = account_move_line.id ' ,
( ref , move_id ) )
return True
def action_cancel ( self , cr , uid , ids , * args ) :
account_move_obj = self . pool . get ( ' account.move ' )
invoices = self . read ( cr , uid , ids , [ ' move_id ' ] )
for i in invoices :
if i [ ' move_id ' ] :
account_move_obj . button_cancel ( cr , uid , [ i [ ' move_id ' ] [ 0 ] ] )
# delete the move this invoice was pointing to
# Note that the corresponding move_lines and move_reconciles
# will be automatically deleted too
account_move_obj . unlink ( cr , uid , [ i [ ' move_id ' ] [ 0 ] ] )
self . write ( cr , uid , ids , { ' state ' : ' cancel ' , ' move_id ' : False } )
self . _log_event ( cr , uid , ids , - 1.0 , ' Cancel Invoice ' )
return True
###################
def list_distinct_taxes ( self , cr , uid , ids ) :
invoices = self . browse ( cr , uid , ids )
taxes = { }
for inv in invoices :
for tax in inv . tax_line :
if not tax [ ' name ' ] in taxes :
taxes [ tax [ ' name ' ] ] = { ' name ' : tax [ ' name ' ] }
return taxes . values ( )
def _log_event ( self , cr , uid , ids , factor = 1.0 , name = ' Open Invoice ' ) :
invs = self . read ( cr , uid , ids , [ ' type ' , ' partner_id ' , ' amount_untaxed ' ] )
for inv in invs :
part = inv [ ' partner_id ' ] and inv [ ' partner_id ' ] [ 0 ]
pc = pr = 0.0
2008-12-10 14:29:55 +00:00
cr . execute ( ' select sum(quantity*price_unit) from account_invoice_line where invoice_id= %s ' , ( inv [ ' id ' ] , ) )
2008-07-22 15:11:28 +00:00
total = inv [ ' amount_untaxed ' ]
if inv [ ' type ' ] in ( ' in_invoice ' , ' in_refund ' ) :
partnertype = ' supplier '
eventtype = ' purchase '
pc = total * factor
else :
partnertype = ' customer '
eventtype = ' sale '
pr = total * factor
if self . pool . get ( ' res.partner.event.type ' ) . check ( cr , uid , ' invoice_open ' ) :
self . pool . get ( ' res.partner.event ' ) . create ( cr , uid , { ' name ' : ' Invoice: ' + name , ' som ' : False , ' description ' : name + ' ' + str ( inv [ ' id ' ] ) , ' document ' : name , ' partner_id ' : part , ' date ' : time . strftime ( ' % Y- % m- %d % H: % M: % S ' ) , ' canal_id ' : False , ' user_id ' : uid , ' partner_type ' : partnertype , ' probability ' : 1.0 , ' planned_revenue ' : pr , ' planned_cost ' : pc , ' type ' : eventtype } )
return len ( invs )
2009-01-06 13:31:53 +00:00
def name_get ( self , cr , uid , ids , context = None ) :
2008-07-22 15:11:28 +00:00
if not len ( ids ) :
return [ ]
types = {
' out_invoice ' : ' CI: ' ,
' in_invoice ' : ' SI: ' ,
' out_refund ' : ' OR: ' ,
' in_refund ' : ' SR: ' ,
}
return [ ( r [ ' id ' ] , types [ r [ ' type ' ] ] + ( r [ ' number ' ] or ' ' ) + ' ' + ( r [ ' name ' ] or ' ' ) ) for r in self . read ( cr , uid , ids , [ ' type ' , ' number ' , ' name ' ] , context , load = ' _classic_write ' ) ]
def name_search ( self , cr , user , name , args = None , operator = ' ilike ' , context = None , limit = 80 ) :
if not args :
args = [ ]
2009-01-06 13:31:53 +00:00
if context is None :
2008-07-22 15:11:28 +00:00
context = { }
ids = [ ]
if name :
ids = self . search ( cr , user , [ ( ' number ' , ' = ' , name ) ] + args , limit = limit , context = context )
if not ids :
ids = self . search ( cr , user , [ ( ' name ' , operator , name ) ] + args , limit = limit , context = context )
return self . name_get ( cr , user , ids , context )
2009-07-31 10:55:16 +00:00
def _refund_cleanup_lines ( self , cr , uid , lines ) :
2008-07-22 15:11:28 +00:00
for line in lines :
del line [ ' id ' ]
del line [ ' invoice_id ' ]
if ' account_id ' in line :
line [ ' account_id ' ] = line . get ( ' account_id ' , False ) and line [ ' account_id ' ] [ 0 ]
if ' product_id ' in line :
line [ ' product_id ' ] = line . get ( ' product_id ' , False ) and line [ ' product_id ' ] [ 0 ]
if ' uos_id ' in line :
line [ ' uos_id ' ] = line . get ( ' uos_id ' , False ) and line [ ' uos_id ' ] [ 0 ]
if ' invoice_line_tax_id ' in line :
line [ ' invoice_line_tax_id ' ] = [ ( 6 , 0 , line . get ( ' invoice_line_tax_id ' , [ ] ) ) ]
if ' account_analytic_id ' in line :
line [ ' account_analytic_id ' ] = line . get ( ' account_analytic_id ' , False ) and line [ ' account_analytic_id ' ] [ 0 ]
2008-11-11 06:57:10 +00:00
if ' tax_code_id ' in line :
if isinstance ( line [ ' tax_code_id ' ] , tuple ) and len ( line [ ' tax_code_id ' ] ) > 0 :
line [ ' tax_code_id ' ] = line [ ' tax_code_id ' ] [ 0 ]
if ' base_code_id ' in line :
if isinstance ( line [ ' base_code_id ' ] , tuple ) and len ( line [ ' base_code_id ' ] ) > 0 :
line [ ' base_code_id ' ] = line [ ' base_code_id ' ] [ 0 ]
2008-07-22 15:11:28 +00:00
return map ( lambda x : ( 0 , 0 , x ) , lines )
2008-11-11 06:57:10 +00:00
def refund ( self , cr , uid , ids , date = None , period_id = None , description = None ) :
2008-07-22 15:11:28 +00:00
invoices = self . read ( cr , uid , ids , [ ' name ' , ' type ' , ' number ' , ' reference ' , ' comment ' , ' date_due ' , ' partner_id ' , ' address_contact_id ' , ' address_invoice_id ' , ' partner_contact ' , ' partner_insite ' , ' partner_ref ' , ' payment_term ' , ' account_id ' , ' currency_id ' , ' invoice_line ' , ' tax_line ' , ' journal_id ' ] )
new_ids = [ ]
for invoice in invoices :
del invoice [ ' id ' ]
type_dict = {
' out_invoice ' : ' out_refund ' , # Customer Invoice
' in_invoice ' : ' in_refund ' , # Supplier Invoice
' out_refund ' : ' out_invoice ' , # Customer Refund
' in_refund ' : ' in_invoice ' , # Supplier Refund
}
invoice_lines = self . pool . get ( ' account.invoice.line ' ) . read ( cr , uid , invoice [ ' invoice_line ' ] )
2009-07-31 10:55:16 +00:00
invoice_lines = self . _refund_cleanup_lines ( cr , uid , invoice_lines )
2008-07-22 15:11:28 +00:00
tax_lines = self . pool . get ( ' account.invoice.tax ' ) . read ( cr , uid , invoice [ ' tax_line ' ] )
tax_lines = filter ( lambda l : l [ ' manual ' ] , tax_lines )
2009-07-31 10:55:16 +00:00
tax_lines = self . _refund_cleanup_lines ( cr , uid , tax_lines )
2008-11-11 06:57:10 +00:00
if not date :
date = time . strftime ( ' % Y- % m- %d ' )
2008-07-22 15:11:28 +00:00
invoice . update ( {
' type ' : type_dict [ invoice [ ' type ' ] ] ,
2008-11-11 06:57:10 +00:00
' date_invoice ' : date ,
2008-07-22 15:11:28 +00:00
' state ' : ' draft ' ,
' number ' : False ,
' invoice_line ' : invoice_lines ,
' tax_line ' : tax_lines
} )
2008-11-11 06:57:10 +00:00
if period_id :
invoice . update ( {
' period_id ' : period_id ,
} )
if description :
invoice . update ( {
' name ' : description ,
} )
2008-07-22 15:11:28 +00:00
# take the id part of the tuple returned for many2one fields
for field in ( ' address_contact_id ' , ' address_invoice_id ' , ' partner_id ' ,
' account_id ' , ' currency_id ' , ' payment_term ' , ' journal_id ' ) :
invoice [ field ] = invoice [ field ] and invoice [ field ] [ 0 ]
# create the new invoice
new_ids . append ( self . create ( cr , uid , invoice ) )
return new_ids
2009-01-06 13:31:53 +00:00
def pay_and_reconcile ( self , cr , uid , ids , pay_amount , pay_account_id , period_id , pay_journal_id , writeoff_acc_id , writeoff_period_id , writeoff_journal_id , context = None , name = ' ' ) :
if context is None :
context = { }
2008-07-22 15:11:28 +00:00
#TODO check if we can use different period for payment and the writeoff line
assert len ( ids ) == 1 , " Can only pay one invoice at a time "
invoice = self . browse ( cr , uid , ids [ 0 ] )
src_account_id = invoice . account_id . id
2008-08-25 15:41:01 +00:00
# Take the seq as name for move
2008-07-22 15:11:28 +00:00
types = { ' out_invoice ' : - 1 , ' in_invoice ' : 1 , ' out_refund ' : 1 , ' in_refund ' : - 1 }
direction = types [ invoice . type ]
2008-08-25 15:41:01 +00:00
#take the choosen date
2008-12-15 12:15:02 +00:00
if ' date_p ' in context and context [ ' date_p ' ] :
2008-08-25 15:41:01 +00:00
date = context [ ' date_p ' ]
else :
date = time . strftime ( ' % Y- % m- %d ' )
2008-07-22 15:11:28 +00:00
l1 = {
' debit ' : direction * pay_amount > 0 and direction * pay_amount ,
' credit ' : direction * pay_amount < 0 and - direction * pay_amount ,
' account_id ' : src_account_id ,
' partner_id ' : invoice . partner_id . id ,
2008-08-25 15:41:01 +00:00
' ref ' : invoice . number ,
2009-06-25 13:34:42 +00:00
' date ' : date ,
2008-07-22 15:11:28 +00:00
}
l2 = {
' debit ' : direction * pay_amount < 0 and - direction * pay_amount ,
' credit ' : direction * pay_amount > 0 and direction * pay_amount ,
' account_id ' : pay_account_id ,
' partner_id ' : invoice . partner_id . id ,
2008-08-25 15:41:01 +00:00
' ref ' : invoice . number ,
2009-06-25 13:34:42 +00:00
' date ' : date ,
2008-07-22 15:11:28 +00:00
}
2009-01-26 17:57:57 +00:00
if not name :
name = invoice . invoice_line and invoice . invoice_line [ 0 ] . name or invoice . number
2008-12-15 11:41:34 +00:00
l1 [ ' name ' ] = name
l2 [ ' name ' ] = name
2008-07-22 15:11:28 +00:00
lines = [ ( 0 , 0 , l1 ) , ( 0 , 0 , l2 ) ]
2008-12-15 09:16:30 +00:00
move = { ' ref ' : invoice . number , ' line_id ' : lines , ' journal_id ' : pay_journal_id , ' period_id ' : period_id , ' date ' : date }
2009-07-24 06:17:35 +00:00
move_id = self . pool . get ( ' account.move ' ) . create ( cr , uid , move , context = context )
2008-07-22 15:11:28 +00:00
line_ids = [ ]
total = 0.0
line = self . pool . get ( ' account.move.line ' )
cr . execute ( ' select id from account_move_line where move_id in ( ' + str ( move_id ) + ' , ' + str ( invoice . move_id . id ) + ' ) ' )
lines = line . browse ( cr , uid , map ( lambda x : x [ 0 ] , cr . fetchall ( ) ) )
2009-01-26 22:22:32 +00:00
for l in lines + invoice . payment_ids :
2008-07-22 15:11:28 +00:00
if l . account_id . id == src_account_id :
line_ids . append ( l . id )
total + = ( l . debit or 0.0 ) - ( l . credit or 0.0 )
if ( not total ) or writeoff_acc_id :
self . pool . get ( ' account.move.line ' ) . reconcile ( cr , uid , line_ids , ' manual ' , writeoff_acc_id , writeoff_period_id , writeoff_journal_id , context )
else :
self . pool . get ( ' account.move.line ' ) . reconcile_partial ( cr , uid , line_ids , ' manual ' , context )
2008-12-20 04:57:05 +00:00
2009-01-02 09:03:46 +00:00
# Update the stored value (fields.function), so we write to trigger recompute
2008-12-20 04:57:05 +00:00
self . pool . get ( ' account.invoice ' ) . write ( cr , uid , ids , { } , context = context )
2008-07-22 15:11:28 +00:00
return True
2006-12-07 13:41:40 +00:00
account_invoice ( )
class account_invoice_line ( osv . osv ) :
2008-07-22 15:11:28 +00:00
def _amount_line ( self , cr , uid , ids , prop , unknow_none , unknow_dict ) :
res = { }
2009-03-19 13:02:14 +00:00
cur_obj = self . pool . get ( ' res.currency ' )
2008-07-22 15:11:28 +00:00
for line in self . browse ( cr , uid , ids ) :
2009-03-19 13:02:14 +00:00
if line . invoice_id :
res [ line . id ] = line . price_unit * line . quantity * ( 1 - ( line . discount or 0.0 ) / 100.0 )
cur = line . invoice_id . currency_id
res [ line . id ] = cur_obj . round ( cr , uid , cur , res [ line . id ] )
else :
res [ line . id ] = round ( line . price_unit * line . quantity * ( 1 - ( line . discount or 0.0 ) / 100.0 ) , 2 )
2008-07-22 15:11:28 +00:00
return res
2009-04-09 10:02:19 +00:00
2009-01-06 13:31:53 +00:00
def _price_unit_default ( self , cr , uid , context = None ) :
if context is None :
context = { }
2008-07-22 15:11:28 +00:00
if ' check_total ' in context :
t = context [ ' check_total ' ]
for l in context . get ( ' invoice_line ' , { } ) :
2009-07-02 07:41:25 +00:00
if isinstance ( l , ( list , tuple ) ) and len ( l ) > = 3 and l [ 2 ] :
2008-07-22 15:11:28 +00:00
tax_obj = self . pool . get ( ' account.tax ' )
p = l [ 2 ] . get ( ' price_unit ' , 0 ) * ( 1 - l [ 2 ] . get ( ' discount ' , 0 ) / 100.0 )
t = t - ( p * l [ 2 ] . get ( ' quantity ' ) )
taxes = l [ 2 ] . get ( ' invoice_line_tax_id ' )
if len ( taxes [ 0 ] ) > = 3 and taxes [ 0 ] [ 2 ] :
taxes = tax_obj . browse ( cr , uid , taxes [ 0 ] [ 2 ] )
for tax in tax_obj . compute ( cr , uid , taxes , p , l [ 2 ] . get ( ' quantity ' ) , context . get ( ' address_invoice_id ' , False ) , l [ 2 ] . get ( ' product_id ' , False ) , context . get ( ' partner_id ' , False ) ) :
t = t - tax [ ' amount ' ]
return t
return 0
_name = " account.invoice.line "
_description = " Invoice line "
_columns = {
' name ' : fields . char ( ' Description ' , size = 256 , required = True ) ,
2008-11-18 06:46:13 +00:00
' origin ' : fields . char ( ' Origin ' , size = 256 , help = " Reference of the document that produced this invoice. " ) ,
2008-07-22 15:11:28 +00:00
' invoice_id ' : fields . many2one ( ' account.invoice ' , ' Invoice Ref ' , ondelete = ' cascade ' , select = True ) ,
2008-09-22 06:06:56 +00:00
' uos_id ' : fields . many2one ( ' product.uom ' , ' Unit of Measure ' , ondelete = ' set null ' ) ,
2008-07-22 15:11:28 +00:00
' product_id ' : fields . many2one ( ' product.product ' , ' Product ' , ondelete = ' set null ' ) ,
2008-09-22 06:06:56 +00:00
' account_id ' : fields . many2one ( ' account.account ' , ' Account ' , required = True , domain = [ ( ' type ' , ' <> ' , ' view ' ) , ( ' type ' , ' <> ' , ' closed ' ) ] , help = " The income or expense account related to the selected product. " ) ,
2008-07-22 15:11:28 +00:00
' price_unit ' : fields . float ( ' Unit Price ' , required = True , digits = ( 16 , int ( config [ ' price_accuracy ' ] ) ) ) ,
' price_subtotal ' : fields . function ( _amount_line , method = True , string = ' Subtotal ' , store = True ) ,
' quantity ' : fields . float ( ' Quantity ' , required = True ) ,
' discount ' : fields . float ( ' Discount ( % ) ' , digits = ( 16 , 2 ) ) ,
' invoice_line_tax_id ' : fields . many2many ( ' account.tax ' , ' account_invoice_line_tax ' , ' invoice_line_id ' , ' tax_id ' , ' Taxes ' , domain = [ ( ' parent_id ' , ' = ' , False ) ] ) ,
' note ' : fields . text ( ' Notes ' ) ,
' account_analytic_id ' : fields . many2one ( ' account.analytic.account ' , ' Analytic Account ' ) ,
}
_defaults = {
' quantity ' : lambda * a : 1 ,
' discount ' : lambda * a : 0.0 ,
' price_unit ' : _price_unit_default ,
}
2009-01-06 13:31:53 +00:00
def product_id_change_unit_price_inv ( self , cr , uid , tax_id , price_unit , qty , address_invoice_id , product , partner_id , context = None ) :
2008-07-22 15:11:28 +00:00
tax_obj = self . pool . get ( ' account.tax ' )
if price_unit :
taxes = tax_obj . browse ( cr , uid , tax_id )
for tax in tax_obj . compute_inv ( cr , uid , taxes , price_unit , qty , address_invoice_id , product , partner_id ) :
price_unit = price_unit - tax [ ' amount ' ]
return { ' price_unit ' : price_unit , ' invoice_line_tax_id ' : tax_id }
2009-01-19 16:49:29 +00:00
def product_id_change ( self , cr , uid , ids , product , uom , qty = 0 , name = ' ' , type = ' out_invoice ' , partner_id = False , fposition_id = False , price_unit = False , address_invoice_id = False , context = None ) :
2009-01-06 13:31:53 +00:00
if context is None :
context = { }
2008-09-03 13:47:19 +00:00
if not partner_id :
raise osv . except_osv ( _ ( ' No Partner Defined ! ' ) , _ ( " You must first select a partner ! " ) )
2008-07-22 15:11:28 +00:00
if not product :
if type in ( ' in_invoice ' , ' in_refund ' ) :
return { ' domain ' : { ' product_uom ' : [ ] } }
else :
return { ' value ' : { ' price_unit ' : 0.0 } , ' domain ' : { ' product_uom ' : [ ] } }
2008-10-27 23:58:25 +00:00
part = self . pool . get ( ' res.partner ' ) . browse ( cr , uid , partner_id )
2009-01-19 16:49:29 +00:00
fpos = fposition_id and self . pool . get ( ' account.fiscal.position ' ) . browse ( cr , uid , fposition_id ) or False
2008-10-27 23:58:25 +00:00
lang = part . lang
2008-07-22 15:11:28 +00:00
context . update ( { ' lang ' : lang } )
2009-01-26 15:28:25 +00:00
result = { }
2008-07-22 15:11:28 +00:00
res = self . pool . get ( ' product.product ' ) . browse ( cr , uid , product , context = context )
if type in ( ' out_invoice ' , ' out_refund ' ) :
a = res . product_tmpl_id . property_account_income . id
if not a :
a = res . categ_id . property_account_income_categ . id
else :
a = res . product_tmpl_id . property_account_expense . id
if not a :
a = res . categ_id . property_account_expense_categ . id
2008-10-20 20:49:11 +00:00
2009-01-19 16:49:29 +00:00
a = self . pool . get ( ' account.fiscal.position ' ) . map_account ( cr , uid , fpos , a )
2008-07-22 15:11:28 +00:00
if a :
result [ ' account_id ' ] = a
2009-01-26 15:28:25 +00:00
taxep = None
tax_obj = self . pool . get ( ' account.tax ' )
if type in ( ' out_invoice ' , ' out_refund ' ) :
taxes = res . taxes_id and res . taxes_id or ( a and self . pool . get ( ' account.account ' ) . browse ( cr , uid , a ) . tax_ids or False )
tax_id = self . pool . get ( ' account.fiscal.position ' ) . map_tax ( cr , uid , fpos , taxes )
else :
2009-01-27 10:06:08 +00:00
taxes = res . supplier_taxes_id and res . supplier_taxes_id or ( a and self . pool . get ( ' account.account ' ) . browse ( cr , uid , a ) . tax_ids or False )
2009-01-26 15:28:25 +00:00
tax_id = self . pool . get ( ' account.fiscal.position ' ) . map_tax ( cr , uid , fpos , taxes )
if type in ( ' in_invoice ' , ' in_refund ' ) :
to_update = self . product_id_change_unit_price_inv ( cr , uid , tax_id , price_unit , qty , address_invoice_id , product , partner_id , context = context )
2009-01-26 15:39:56 +00:00
result . update ( to_update )
2009-01-26 15:28:25 +00:00
else :
result . update ( { ' price_unit ' : res . list_price , ' invoice_line_tax_id ' : tax_id } )
if not name :
result [ ' name ' ] = res . name
2008-07-22 15:11:28 +00:00
domain = { }
result [ ' uos_id ' ] = uom or res . uom_id . id or False
if result [ ' uos_id ' ] :
res2 = res . uom_id . category_id . id
if res2 :
domain = { ' uos_id ' : [ ( ' category_id ' , ' = ' , res2 ) ] }
return { ' value ' : result , ' domain ' : domain }
2009-01-06 13:31:53 +00:00
def move_line_get ( self , cr , uid , invoice_id , context = None ) :
2008-07-22 15:11:28 +00:00
res = [ ]
tax_grouped = { }
tax_obj = self . pool . get ( ' account.tax ' )
cur_obj = self . pool . get ( ' res.currency ' )
ait_obj = self . pool . get ( ' account.invoice.tax ' )
inv = self . pool . get ( ' account.invoice ' ) . browse ( cr , uid , invoice_id )
company_currency = inv . company_id . currency_id . id
cur = inv . currency_id
for line in inv . invoice_line :
mres = self . move_line_get_item ( cr , uid , line , context )
if not mres :
continue
res . append ( mres )
tax_code_found = False
for tax in tax_obj . compute ( cr , uid , line . invoice_line_tax_id ,
( line . price_unit * ( 1.0 - ( line [ ' discount ' ] or 0.0 ) / 100.0 ) ) ,
line . quantity , inv . address_invoice_id . id , line . product_id ,
inv . partner_id ) :
if inv . type in ( ' out_invoice ' , ' in_invoice ' ) :
tax_code_id = tax [ ' base_code_id ' ]
tax_amount = line . price_subtotal * tax [ ' base_sign ' ]
else :
tax_code_id = tax [ ' ref_base_code_id ' ]
tax_amount = line . price_subtotal * tax [ ' ref_base_sign ' ]
if tax_code_found :
if not tax_code_id :
continue
res . append ( self . move_line_get_item ( cr , uid , line , context ) )
res [ - 1 ] [ ' price ' ] = 0.0
res [ - 1 ] [ ' account_analytic_id ' ] = False
elif not tax_code_id :
continue
tax_code_found = True
res [ - 1 ] [ ' tax_code_id ' ] = tax_code_id
res [ - 1 ] [ ' tax_amount ' ] = cur_obj . compute ( cr , uid , inv . currency_id . id , company_currency , tax_amount , context = { ' date ' : inv . date_invoice } )
return res
2009-01-06 13:31:53 +00:00
def move_line_get_item ( self , cr , uid , line , context = None ) :
2008-07-22 15:11:28 +00:00
return {
' type ' : ' src ' ,
' name ' : line . name [ : 64 ] ,
' price_unit ' : line . price_unit ,
' quantity ' : line . quantity ,
' price ' : line . price_subtotal ,
' account_id ' : line . account_id . id ,
' product_id ' : line . product_id . id ,
' uos_id ' : line . uos_id . id ,
' account_analytic_id ' : line . account_analytic_id . id ,
2008-11-06 07:29:50 +00:00
' taxes ' : line . invoice_line_tax_id ,
2008-07-22 15:11:28 +00:00
}
#
2009-01-26 15:28:25 +00:00
# Set the tax field according to the account and the fiscal position
2008-07-22 15:11:28 +00:00
#
2009-01-19 16:49:29 +00:00
def onchange_account_id ( self , cr , uid , ids , fposition_id , account_id ) :
2009-01-26 15:28:25 +00:00
if not account_id :
2008-07-22 15:11:28 +00:00
return { }
taxes = self . pool . get ( ' account.account ' ) . browse ( cr , uid , account_id ) . tax_ids
2009-01-19 16:49:29 +00:00
fpos = fposition_id and self . pool . get ( ' account.fiscal.position ' ) . browse ( cr , uid , fposition_id ) or False
res = self . pool . get ( ' account.fiscal.position ' ) . map_tax ( cr , uid , fpos , taxes )
2008-07-22 15:11:28 +00:00
r = { ' value ' : { ' invoice_line_tax_id ' : res } }
return r
2006-12-07 13:41:40 +00:00
account_invoice_line ( )
class account_invoice_tax ( osv . osv ) :
2008-07-22 15:11:28 +00:00
_name = " account.invoice.tax "
_description = " Invoice Tax "
_columns = {
' invoice_id ' : fields . many2one ( ' account.invoice ' , ' Invoice Line ' , ondelete = ' cascade ' , select = True ) ,
2009-01-28 13:46:13 +00:00
' name ' : fields . char ( ' Tax Description ' , size = 64 , required = True ) ,
2008-07-22 15:11:28 +00:00
' account_id ' : fields . many2one ( ' account.account ' , ' Tax Account ' , required = True , domain = [ ( ' type ' , ' <> ' , ' view ' ) , ( ' type ' , ' <> ' , ' income ' ) , ( ' type ' , ' <> ' , ' closed ' ) ] ) ,
' base ' : fields . float ( ' Base ' , digits = ( 16 , 2 ) ) ,
' amount ' : fields . float ( ' Amount ' , digits = ( 16 , 2 ) ) ,
' manual ' : fields . boolean ( ' Manual ' ) ,
' sequence ' : fields . integer ( ' Sequence ' ) ,
2009-01-27 11:15:46 +00:00
' base_code_id ' : fields . many2one ( ' account.tax.code ' , ' Base Code ' , help = " The account basis of the tax declaration. " ) ,
2008-07-22 15:11:28 +00:00
' base_amount ' : fields . float ( ' Base Code Amount ' , digits = ( 16 , 2 ) ) ,
2009-01-27 11:15:46 +00:00
' tax_code_id ' : fields . many2one ( ' account.tax.code ' , ' Tax Code ' , help = " The tax basis of the tax declaration. " ) ,
2008-07-22 15:11:28 +00:00
' tax_amount ' : fields . float ( ' Tax Code Amount ' , digits = ( 16 , 2 ) ) ,
}
2009-03-19 09:47:23 +00:00
def base_change ( self , cr , uid , ids , base , currency_id = False , company_id = False , date_invoice = False ) :
cur_obj = self . pool . get ( ' res.currency ' )
company_obj = self . pool . get ( ' res.company ' )
company_currency = False
if company_id :
company_currency = company_obj . browse ( cr , uid , company_id ) . id
if currency_id and company_currency :
base = cur_obj . compute ( cr , uid , currency_id , company_currency , base , context = { ' date ' : date_invoice or time . strftime ( ' % Y- % m- %d ' ) } , round = False )
2008-07-22 15:11:28 +00:00
return { ' value ' : { ' base_amount ' : base } }
2009-03-19 09:47:23 +00:00
def amount_change ( self , cr , uid , ids , amount , currency_id = False , company_id = False , date_invoice = False ) :
cur_obj = self . pool . get ( ' res.currency ' )
company_obj = self . pool . get ( ' res.company ' )
company_currency = False
if company_id :
company_currency = company_obj . browse ( cr , uid , company_id ) . id
if currency_id and company_currency :
amount = cur_obj . compute ( cr , uid , currency_id , company_currency , amount , context = { ' date ' : date_invoice or time . strftime ( ' % Y- % m- %d ' ) } , round = False )
2008-07-22 15:11:28 +00:00
return { ' value ' : { ' tax_amount ' : amount } }
_order = ' sequence '
_defaults = {
' manual ' : lambda * a : 1 ,
' base_amount ' : lambda * a : 0.0 ,
' tax_amount ' : lambda * a : 0.0 ,
}
2009-01-28 14:41:13 +00:00
def compute ( self , cr , uid , invoice_id , context = { } ) :
2008-07-22 15:11:28 +00:00
tax_grouped = { }
tax_obj = self . pool . get ( ' account.tax ' )
cur_obj = self . pool . get ( ' res.currency ' )
2009-01-28 14:41:13 +00:00
inv = self . pool . get ( ' account.invoice ' ) . browse ( cr , uid , invoice_id , context )
2008-07-22 15:11:28 +00:00
cur = inv . currency_id
company_currency = inv . company_id . currency_id . id
for line in inv . invoice_line :
for tax in tax_obj . compute ( cr , uid , line . invoice_line_tax_id , ( line . price_unit * ( 1 - ( line . discount or 0.0 ) / 100.0 ) ) , line . quantity , inv . address_invoice_id . id , line . product_id , inv . partner_id ) :
val = { }
val [ ' invoice_id ' ] = inv . id
val [ ' name ' ] = tax [ ' name ' ]
2008-11-20 19:46:20 +00:00
val [ ' amount ' ] = tax [ ' amount ' ]
2008-07-22 15:11:28 +00:00
val [ ' manual ' ] = False
val [ ' sequence ' ] = tax [ ' sequence ' ]
val [ ' base ' ] = tax [ ' price_unit ' ] * line [ ' quantity ' ]
if inv . type in ( ' out_invoice ' , ' in_invoice ' ) :
val [ ' base_code_id ' ] = tax [ ' base_code_id ' ]
val [ ' tax_code_id ' ] = tax [ ' tax_code_id ' ]
2009-02-19 17:32:34 +00:00
val [ ' base_amount ' ] = cur_obj . compute ( cr , uid , inv . currency_id . id , company_currency , val [ ' base ' ] * tax [ ' base_sign ' ] , context = { ' date ' : inv . date_invoice or time . strftime ( ' % Y- % m- %d ' ) } , round = False )
val [ ' tax_amount ' ] = cur_obj . compute ( cr , uid , inv . currency_id . id , company_currency , val [ ' amount ' ] * tax [ ' tax_sign ' ] , context = { ' date ' : inv . date_invoice or time . strftime ( ' % Y- % m- %d ' ) } , round = False )
2008-07-22 15:11:28 +00:00
val [ ' account_id ' ] = tax [ ' account_collected_id ' ] or line . account_id . id
else :
val [ ' base_code_id ' ] = tax [ ' ref_base_code_id ' ]
val [ ' tax_code_id ' ] = tax [ ' ref_tax_code_id ' ]
2009-02-19 17:32:34 +00:00
val [ ' base_amount ' ] = cur_obj . compute ( cr , uid , inv . currency_id . id , company_currency , val [ ' base ' ] * tax [ ' ref_base_sign ' ] , context = { ' date ' : inv . date_invoice or time . strftime ( ' % Y- % m- %d ' ) } , round = False )
val [ ' tax_amount ' ] = cur_obj . compute ( cr , uid , inv . currency_id . id , company_currency , val [ ' amount ' ] * tax [ ' ref_tax_sign ' ] , context = { ' date ' : inv . date_invoice or time . strftime ( ' % Y- % m- %d ' ) } , round = False )
2008-07-22 15:11:28 +00:00
val [ ' account_id ' ] = tax [ ' account_paid_id ' ] or line . account_id . id
key = ( val [ ' tax_code_id ' ] , val [ ' base_code_id ' ] , val [ ' account_id ' ] )
if not key in tax_grouped :
tax_grouped [ key ] = val
else :
tax_grouped [ key ] [ ' amount ' ] + = val [ ' amount ' ]
tax_grouped [ key ] [ ' base ' ] + = val [ ' base ' ]
tax_grouped [ key ] [ ' base_amount ' ] + = val [ ' base_amount ' ]
tax_grouped [ key ] [ ' tax_amount ' ] + = val [ ' tax_amount ' ]
2008-11-20 19:46:20 +00:00
for t in tax_grouped . values ( ) :
t [ ' amount ' ] = cur_obj . round ( cr , uid , cur , t [ ' amount ' ] )
2009-02-19 17:32:34 +00:00
t [ ' base_amount ' ] = cur_obj . round ( cr , uid , cur , t [ ' base_amount ' ] )
t [ ' tax_amount ' ] = cur_obj . round ( cr , uid , cur , t [ ' tax_amount ' ] )
2008-07-22 15:11:28 +00:00
return tax_grouped
def move_line_get ( self , cr , uid , invoice_id ) :
res = [ ]
2008-12-10 14:29:55 +00:00
cr . execute ( ' SELECT * FROM account_invoice_tax WHERE invoice_id= %s ' , ( invoice_id , ) )
2008-07-22 15:11:28 +00:00
for t in cr . dictfetchall ( ) :
if not t [ ' amount ' ] \
and not t [ ' tax_code_id ' ] \
and not t [ ' tax_amount ' ] :
continue
res . append ( {
' type ' : ' tax ' ,
' name ' : t [ ' name ' ] ,
' price_unit ' : t [ ' amount ' ] ,
' quantity ' : 1 ,
' price ' : t [ ' amount ' ] or 0.0 ,
' account_id ' : t [ ' account_id ' ] ,
' tax_code_id ' : t [ ' tax_code_id ' ] ,
' tax_amount ' : t [ ' tax_amount ' ]
} )
return res
2006-12-07 13:41:40 +00:00
account_invoice_tax ( )
2008-07-23 14:41:47 +00:00
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: