diff --git a/addons/account_tax_include/invoice_tax_incl.py b/addons/account_tax_include/invoice_tax_incl.py index 994f508b6db..1866dc79e68 100644 --- a/addons/account_tax_include/invoice_tax_incl.py +++ b/addons/account_tax_include/invoice_tax_incl.py @@ -35,38 +35,35 @@ import ir class account_invoice(osv.osv): def _amount_untaxed(self, cr, uid, ids, prop, unknow_none,unknow_dict): - ti = [] - for inv in self.read(cr, uid, ids, ['price_type']): - if inv['price_type']=='tax_included': - ti.append(inv['id']) - id_set=",".join(map(str,ids)) - cr.execute("SELECT s.id,COALESCE(SUM(l.price_unit*l.quantity*(100.0-l.discount))/100.0,0)::decimal(16,2) AS amount FROM account_invoice s LEFT OUTER JOIN account_invoice_line l ON (s.id=l.invoice_id) WHERE s.id IN ("+id_set+") GROUP BY s.id ") - res=dict(cr.fetchall()) - if len(ti): - tax = self._amount_tax(cr, uid, ti, prop, unknow_none,unknow_dict) - for id in ti: - res[id] = res[id] - tax.get(id,0.0) + res = {} + for invoice in self.browse(cr,uid,ids): + res[invoice.id]= reduce( lambda x, y: x+y.price_subtotal, + invoice.invoice_line,0) return res def _amount_total(self, cr, uid, ids, prop, unknow_none,unknow_dict): - ti = [] - for inv in self.read(cr, uid, ids, ['price_type']): - if inv['price_type']=='tax_excluded': - ti.append(inv['id']) - id_set=",".join(map(str,ids)) - cr.execute("SELECT s.id,COALESCE(SUM(l.price_unit*l.quantity*(100.0-l.discount))/100.0,0)::decimal(16,2) AS amount FROM account_invoice s LEFT OUTER JOIN account_invoice_line l ON (s.id=l.invoice_id) WHERE s.id IN ("+id_set+") GROUP BY s.id ") - res=dict(cr.fetchall()) - if len(ti): - tax = self._amount_tax(cr, uid, ti, prop, unknow_none,unknow_dict) - for id in ti: - res[id] = res[id] + tax.get(id,0.0) + res = {} + for invoice in self.browse(cr,uid,ids): + res[invoice.id]= reduce( lambda x, y: x+y.price_subtotal_incl, + invoice.invoice_line,0) + return res + + def _amount_tax(self, cr, uid, ids, prop, unknow_none,unknow_dict): + res = {} + for invoice in self.browse(cr,uid,ids): + res[invoice.id]= reduce( lambda x, y: x+y.amount, + invoice.tax_line,0) return res _inherit = "account.invoice" _columns = { - 'price_type': fields.selection([('tax_included','Tax included'), ('tax_excluded','Tax excluded')], 'Price method', required=True, readonly=True, states={'draft':[('readonly',False)]}), - 'amount_untaxed': fields.function(_amount_untaxed, method=True, string='Untaxed Amount'), - 'amount_total': fields.function(_amount_total, method=True, string='Total', store=True), + 'price_type': fields.selection([('tax_included','Tax included'), + ('tax_excluded','Tax excluded')], + 'Price method', required=True, readonly=True, + states={'draft':[('readonly',False)]}), + 'amount_untaxed': fields.function(_amount_untaxed, digits=(16,2), method=True,string='Untaxed Amount'), + 'amount_tax': fields.function(_amount_tax, method=True, string='Tax'), + 'amount_total': fields.function(_amount_total, method=True, string='Total'), } _defaults = { 'price_type': lambda *a: 'tax_excluded', @@ -75,9 +72,70 @@ account_invoice() class account_invoice_line(osv.osv): _inherit = "account.invoice.line" + def _amount_line(self, cr, uid, ids, prop, unknow_none,unknow_dict): + """ + Return the subtotal excluding taxes with respect to price_type. + """ + #cur_obj = self.pool.get('res.currency') + cur = False + res = {} + tax_obj = self.pool.get('account.tax') + for line in self.browse(cr, uid, ids): + res[line.id] = line.price_unit * line.quantity * (1-(line.discount or 0.0)/100.0) + + if line.product_id and line.invoice_id.price_type == 'tax_included': + taxes = tax_obj.compute_inv(cr, uid,line.product_id.taxes_id, + res[line.id], + line.quantity) + amount = 0 + for t in taxes : amount = amount + t['amount'] + cur = cur or line.invoice_id.currency_id + res[line.id]= cur.round(cr, uid, cur, res[line.id] - amount) + return res + + def _amount_line_incl(self, cr, uid, ids, prop, unknow_none,unknow_dict): + """ + Return the subtotal including taxes with respect to price_type. + """ + res = {} + cur = False + tax_obj = self.pool.get('account.tax') + for line in self.browse(cr, uid, ids): + res[line.id] = line.price_unit * line.quantity * (1-(line.discount or 0.0)/100.0) + if line.product_id: + prod_taxe_ids = line.product_id and [t.id for t in line.product_id.taxes_id ] or [] + prod_taxe_ids.sort() + line_taxe_ids = [ t.id for t in line.invoice_line_tax_id if t] + line_taxe_ids.sort() + if prod_taxe_ids == line_taxe_ids : + continue + else : continue + + res[line.id] = line.price_unit * line.quantity * (1-(line.discount or 0.0)/100.0) + if line.invoice_id.price_type == 'tax_included': + # remove product taxes + taxes = tax_obj.compute_inv(cr, uid,line.product_id.taxes_id, + res[line.id], + line.quantity) + amount = 0 + for t in taxes : amount = amount + t['amount'] + res[line.id]= res[line.id] - amount + ## Add line taxes + taxes = tax_obj.compute(cr, uid,line.invoice_line_tax_id, res[line.id], line.quantity) + amount = 0 + for t in taxes : amount = amount + t['amount'] + cur = cur or line.invoice_id.currency_id + res[line.id]= cur.round(cr, uid, cur, res[line.id] + amount) + return res + + + _columns = { + 'price_subtotal': fields.function(_amount_line, method=True, string='Subtotal w/o vat'), + 'price_subtotal_incl': fields.function(_amount_line_incl, method=True, string='Subtotal'), + } # - # Compute with VAT invluded in the price + # Compute a tax amount for each kind of tax : # def move_line_get(self, cr, uid, invoice_id, context={}): inv = self.pool.get('account.invoice').browse(cr, uid, invoice_id) @@ -92,18 +150,37 @@ class account_invoice_line(osv.osv): cur = inv.currency_id for line in inv.invoice_line: + price_unit = line.price_unit + if line.product_id: + prod_taxe_ids = [ t.id for t in line.product_id.taxes_id ] + prod_taxe_ids.sort() + line_taxe_ids = [ t.id for t in line.invoice_line_tax_id] + line_taxe_ids.sort() + if line.product_id and prod_taxe_ids != line_taxe_ids : + price_unit= reduce( lambda x, y: x-y['amount'], + tax_obj.compute_inv(cr, uid,line.product_id.taxes_id, + line.price_unit * (1-(line.discount or 0.0)/100.0), line.quantity), + price_unit) + taxes =tax_obj.compute(cr, uid, line.invoice_line_tax_id, + (price_unit *(1.0-(line['discount'] or 0.0)/100.0)), + line.quantity, inv.address_invoice_id.id) + else: + taxes= tax_obj.compute_inv(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) + res.append( { 'type':'src', 'name':line.name, - 'price_unit':line.price_unit, + 'price_unit':price_unit, 'quantity':line.quantity, - 'price':line.quantity*line.price_unit * (1.0- (line.discount or 0.0)/100.0), + 'price':line.quantity*price_unit * (1.0- (line.discount or 0.0)/100.0), 'account_id':line.account_id.id, - 'product_id':line.product_id.id, + 'product_id': line.product_id.id, 'uos_id':line.uos_id.id, 'account_analytic_id':line.account_analytic_id.id, }) - for tax in tax_obj.compute_inv(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): + for tax in taxes: val={} val['invoice_id'] = inv.id val['name'] = tax['name'] diff --git a/addons/account_tax_include/invoice_tax_incl.xml b/addons/account_tax_include/invoice_tax_incl.xml index e99ecc572d4..fefed46b0cf 100644 --- a/addons/account_tax_include/invoice_tax_incl.xml +++ b/addons/account_tax_include/invoice_tax_incl.xml @@ -27,6 +27,18 @@ + + account.invoice.line.tree + account.invoice.line + tree + + + + + + + +