account_tax_include : Now the module manage correctly the case when the taxes defined on the product differ from the taxes defined on the invoice line (eg : exportations).

bzr revid: bch-7f11eb4249bb5674a50e9a2b9ad72e3829604621
This commit is contained in:
bch 2007-04-24 12:35:11 +00:00
parent 6bff06bdf3
commit 34bb7bda4f
2 changed files with 119 additions and 30 deletions

View File

@ -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']

View File

@ -27,6 +27,18 @@
</field>
</record>
<record model="ir.ui.view" id="view_invoice_line_tree">
<field name="name">account.invoice.line.tree</field>
<field name="model">account.invoice.line</field>
<field name="type">tree</field>
<field name="inherit_id" ref="account.view_invoice_line_tree" />
<field name="arch" type="xml">
<field name="price_subtotal" position="after">
<field name="price_subtotal_incl"/>
</field>
</field>
</record>
</data>
</terp>