diff --git a/addons/account/account.py b/addons/account/account.py index bdab7633d69..46bd901d6b3 100644 --- a/addons/account/account.py +++ b/addons/account/account.py @@ -669,7 +669,7 @@ class account_move(osv.osv): code = getattr(tax,field_base+'base_code_id').id amount = getattr(tax, field_base+'base_sign') * (line.debit + line.credit) break - if code: + if code and not (line.tax_code_id or line.tax_amount): self.pool.get('account.move.line').write(cr, uid, [line.id], { 'tax_code_id': code, 'tax_amount': amount @@ -685,7 +685,7 @@ class account_move(osv.osv): elif line.account_id.id in account: code = account[line.account_id.id][0] amount = account[line.account_id.id][1] * (line.debit + line.credit) - if code or amount: + if (code or amount) and not (line.tax_code_id or line.tax_amount): self.pool.get('account.move.line').write(cr, uid, [line.id], { 'tax_code_id': code, 'tax_amount': amount @@ -802,8 +802,8 @@ class account_tax(osv.osv): 'type': fields.selection( [('percent','Percent'), ('fixed','Fixed'), ('none','None'), ('code','Python Code')], 'Tax Type', required=True), 'applicable_type': fields.selection( [('true','True'), ('code','Python Code')], 'Applicable Type', required=True), 'domain':fields.char('Domain', size=32, help="This field is only used if you develop your own module allowing developpers to create specific taxes in a custom domain."), - 'account_collected_id':fields.many2one('account.account', 'Collected Tax Account'), - 'account_paid_id':fields.many2one('account.account', 'Paid Tax Account'), + 'account_collected_id':fields.many2one('account.account', 'Invoice Tax Account'), + 'account_paid_id':fields.many2one('account.account', 'Refund Tax Account'), 'parent_id':fields.many2one('account.tax', 'Parent Tax Account', select=True), 'child_ids':fields.one2many('account.tax', 'parent_id', 'Childs Tax Account'), 'child_depend':fields.boolean('Tax on Childs', help="Indicate if the tax computation is based on the value computed for the computation of child taxes or based on the total amount."), @@ -865,9 +865,9 @@ class account_tax(osv.osv): # we compute the amount for the current tax object and append it to the result if tax.type=='percent': amount = cur_price_unit * tax.amount - res.append({'id':tax.id, 'name':tax.name, 'amount':amount, 'account_collected_id':tax.account_collected_id.id, 'account_paid_id':tax.account_paid_id.id, 'base_code_id': tax.base_code_id.id, 'ref_base_code_id': tax.ref_base_code_id.id, 'sequence': tax.sequence, 'base_sign': tax.base_sign, 'ref_base_sign': tax.ref_base_sign, 'price_unit': cur_price_unit, 'tax_code_id': tax.tax_code_id.id,}) + res.append({'id':tax.id, 'name':tax.name, 'amount':amount, 'account_collected_id':tax.account_collected_id.id, 'account_paid_id':tax.account_paid_id.id, 'base_code_id': tax.base_code_id.id, 'ref_base_code_id': tax.ref_base_code_id.id, 'sequence': tax.sequence, 'base_sign': tax.base_sign, 'tax_sign': tax.tax_sign, 'ref_base_sign': tax.ref_base_sign, 'ref_tax_sign': tax.ref_tax_sign, 'price_unit': cur_price_unit, 'tax_code_id': tax.tax_code_id.id, 'ref_tax_code_id': tax.ref_tax_code_id.id,}) elif tax.type=='fixed': - res.append({'id':tax.id, 'name':tax.name, 'amount':tax.amount, 'account_collected_id':tax.account_collected_id.id, 'account_paid_id':tax.account_paid_id.id, 'base_code_id': tax.base_code_id.id, 'ref_base_code_id': tax.ref_base_code_id.id, 'sequence': tax.sequence, 'base_sign': tax.base_sign, 'ref_base_sign': tax.ref_base_sign, 'price_unit': 1, 'tax_code_id': tax.tax_code_id.id,}) + res.append({'id':tax.id, 'name':tax.name, 'amount':tax.amount, 'account_collected_id':tax.account_collected_id.id, 'account_paid_id':tax.account_paid_id.id, 'base_code_id': tax.base_code_id.id, 'ref_base_code_id': tax.ref_base_code_id.id, 'sequence': tax.sequence, 'base_sign': tax.base_sign, 'tax_sign': tax.tax_sign, 'ref_base_sign': tax.ref_base_sign, 'ref_tax_sign': tax.ref_tax_sign, 'price_unit': 1, 'tax_code_id': tax.tax_code_id.id, 'ref_tax_code_id': tax.ref_tax_code_id.id,}) elif tax.type=='code': address = address_id and self.pool.get('res.partner.address').browse(cr, uid, address_id) or None localdict = {'price_unit':cur_price_unit, 'address':address} @@ -883,9 +883,12 @@ class account_tax(osv.osv): 'ref_base_code_id': tax.ref_base_code_id.id, 'sequence': tax.sequence, 'base_sign': tax.base_sign, + 'tax_sign': tax.tax_sign, 'ref_base_sign': tax.ref_base_sign, + 'ref_tax_sign': tax.ref_tax_sign, 'price_unit': cur_price_unit, 'tax_code_id': tax.tax_code_id.id, + 'ref_tax_code_id': tax.ref_tax_code_id.id, }) amount2 = res[-1]['amount'] if len(tax.child_ids): diff --git a/addons/account/invoice.py b/addons/account/invoice.py index eea68926246..afc55335099 100644 --- a/addons/account/invoice.py +++ b/addons/account/invoice.py @@ -292,6 +292,7 @@ class account_invoice(osv.osv): # one move line per tax line iml += self.pool.get('account.invoice.tax').move_line_get(cr, uid, inv['id']) + # create one move line for the total and possibly adjust the other lines amount total = 0 @@ -552,7 +553,11 @@ class account_invoice_line(osv.osv): lang=self.pool.get('res.partner').read(cr, uid, [partner_id])[0]['lang'] context={'lang': lang} res = self.pool.get('product.product').browse(cr, uid, product, context=context) - result = {'price_unit': res.list_price, 'invoice_line_tax_id':map(lambda x: x.id, res.taxes_id)} + + if type in ('out_invoice', 'out_refund'): + result = {'price_unit': res.list_price, 'invoice_line_tax_id':map(lambda x: x.id, res.taxes_id)} + else: + result = {'price_unit': res.list_price, 'invoice_line_tax_id':map(lambda x: x.id, res.supplier_taxes_id)} if not name: result['name'] = res.name @@ -580,6 +585,7 @@ class account_invoice_line(osv.osv): tax_grouped = {} tax_obj = self.pool.get('account.tax') cur_obj = self.pool.get('res.currency') + ait_obj = self.pool.get('account.invoice.tax') #TODO: rewrite using browse instead of the manual SQL queries # cr.execute('SELECT id FROM account_invoice_line WHERE invoice_id=%d', (invoice_id,)) inv = self.pool.get('account.invoice').browse(cr, uid, invoice_id) @@ -595,78 +601,46 @@ class account_invoice_line(osv.osv): 'account_id':line.account_id.id }) 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): - tax['amount'] = cur_obj.round(cr, uid, cur, tax['amount']) - tax['sequence'] = tax['sequence'] + val={} + val['invoice_id'] = inv.id + val['name'] = tax['name'] + val['amount'] = cur_obj.round(cr, uid, cur, tax['amount']) + val['manual'] = False + val['sequence'] = tax['sequence'] + val['base'] = tax['price_unit'] * line['quantity'] # # Setting the tax account and amount for the line # - if inv.type in ('out_invoice','out_refund'): - res[-1]['tax_code_id'] = tax['base_code_id'] - res[-1]['tax_amount'] = tax['amount'] * tax['base_sign'] + if inv.type in ('out_invoice','in_invoice'): + val['base_code_id'] = tax['base_code_id'] + val['tax_code_id'] = tax['tax_code_id'] + val['base_amount'] = val['base'] * tax['base_sign'] + val['tax_amount'] = val['amount'] * tax['tax_sign'] + val['account_id'] = tax['account_collected_id'] or line.account_id.id else: - res[-1]['tax_code_id'] = tax['ref_base_code_id'] - res[-1]['tax_amount'] = tax['amount'] * tax['ref_base_sign'] - if inv.type in ('out_refund','in_refund'): - res[-1]['tax_amount'] = -res[-1]['tax_amount'] + val['base_code_id'] = tax['ref_base_code_id'] + val['tax_code_id'] = tax['ref_tax_code_id'] + val['base_amount'] = val['base'] * tax['ref_base_sign'] + val['tax_amount'] = val['amount'] * tax['ref_tax_sign'] + val['account_id'] = tax['account_paid_id'] or line.account_id.id - if inv.type in ('out_invoice','out_refund'): - tax['account_id'] = tax['account_collected_id'] or line.account_id.id - else: - tax['account_id'] = tax['account_paid_id'] or line.account_id.id - # - # Revoir la clé: tax.id ? - # - key = (res[-1]['tax_code_id'], tax['account_id']) + res[-1]['tax_code_id'] = val['base_code_id'] + res[-1]['tax_amount'] = val['base_amount'] + + key = (val['tax_code_id'], val['base_code_id'], val['account_id']) if not key in tax_grouped: - tax_grouped[key] = tax - tax_grouped[key]['base'] = tax['price_unit'] * line['quantity'] + tax_grouped[key] = val else: - tax_grouped[key]['amount'] += tax['amount'] - tax_grouped[key]['base'] += tax['price_unit'] * line['quantity'] + 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'] # delete automatic tax lines for this invoice cr.execute("DELETE FROM account_invoice_tax WHERE NOT manual AND invoice_id=%d", (invoice_id,)) - self.move_line_tax_create(cr, uid, inv, tax_grouped, context) - return res - - def move_line_tax_create(self, cr, uid, inv, tax_grouped, context={}): - - # (re)create them - ait = self.pool.get('account.invoice.tax') for t in tax_grouped.values(): - tax = self.pool.get('account.tax').browse(cr, uid, t['id']) - val = { - 'invoice_id':inv.id, - 'name':t['name'], - 'account_id':t['account_id'], - 'amount':t['amount'], - 'manual':False, - 'sequence':t['sequence'], - 'base': t['base'], - } - if inv.type in ('out_invoice','out_refund'): - val.update({ - 'base_code_id': tax.base_code_id.id or False, - 'tax_code_id': tax.tax_code_id.id or False, - 'base_amount': tax.base_sign * t['base'], - 'tax_amount': tax.tax_sign * t['amount'] - }) - elif inv.type in ('in_invoice','in_refund'): - val.update({ - 'base_code_id': tax.ref_base_code_id.id or False, - 'tax_code_id': tax.ref_tax_code_id.id or False, - 'base_amount': tax.ref_base_sign * t['base'], - 'tax_amount': tax.ref_tax_sign * t['amount'] - }) - if inv.type in ('out_refund','in_refund'): - val.update({ - 'base_amount': -val['base_amount'], - 'tax_amount': -val['tax_amount'] - }) - - ait.create(cr, uid, val) - #ait.create(cr, uid, {'invoice_id':invoice_id, 'name':t['name'], 'account_id':t['account_id'], 'amount':t['amount'], 'manual':False, 'sequence':t['sequence'], 'base':t['base']}) - return True + ait_obj.create(cr, uid, t) + return res # # Set the tax field according to the account and the partner diff --git a/addons/account/product.py b/addons/account/product.py index 05382c30053..1d42ea15cba 100644 --- a/addons/account/product.py +++ b/addons/account/product.py @@ -62,24 +62,25 @@ product_category() class product_template(osv.osv): _inherit = "product.template" _columns = { - 'taxes_id': fields.many2many('account.tax', 'product_taxes_rel', 'prod_id', 'tax_id', 'Product Taxes', domain=[('parent_id','=',False)]), + 'taxes_id': fields.many2many('account.tax', 'product_taxes_rel', 'prod_id', 'tax_id', 'Customer Taxes', domain=[('parent_id','=',False)]), + 'supplier_taxes_id': fields.many2many('account.tax', 'product_supplier_taxes_rel', 'prod_id', 'tax_id', 'Supplier Taxes', domain=[('parent_id', '=', False)]), 'property_account_income': fields.property( - 'account.account', - type='many2one', - relation='account.account', - string="Income Account", - method=True, - view_load=True, - group_name="Accounting Properties", - help="This account will be used, instead of the default one, to value incoming stock for the current product"), + 'account.account', + type='many2one', + relation='account.account', + string="Income Account", + method=True, + view_load=True, + group_name="Accounting Properties", + help="This account will be used, instead of the default one, to value incoming stock for the current product"), 'property_account_expense': fields.property( - 'account.account', - type='many2one', - relation='account.account', - string="Expense Account", - method=True, - view_load=True, - group_name="Accounting Properties", - help="This account will be used, instead of the default one, to value outgoing stock for the current product"), + 'account.account', + type='many2one', + relation='account.account', + string="Expense Account", + method=True, + view_load=True, + group_name="Accounting Properties", + help="This account will be used, instead of the default one, to value outgoing stock for the current product"), } product_template() diff --git a/addons/account/product_view.xml b/addons/account/product_view.xml index 90fe401a888..d3bfb229bc1 100644 --- a/addons/account/product_view.xml +++ b/addons/account/product_view.xml @@ -9,6 +9,7 @@ + @@ -22,6 +23,7 @@ + diff --git a/addons/account_tax_include/account.py b/addons/account_tax_include/account.py index 78b2d630111..ec98504cd7b 100644 --- a/addons/account_tax_include/account.py +++ b/addons/account_tax_include/account.py @@ -50,9 +50,9 @@ class account_tax(osv.osv): # we compute the amount for the current tax object and append it to the result if tax.type=='percent': amount = cur_price_unit - (cur_price_unit / (1 + tax.amount)) - res.append({'id':tax.id, 'name':tax.name, 'amount':amount, 'account_collected_id':tax.account_collected_id.id, 'account_paid_id':tax.account_paid_id.id, 'base_code_id': tax.base_code_id.id, 'ref_base_code_id': tax.ref_base_code_id.id, 'sequence': tax.sequence, 'base_sign': tax.base_sign, 'ref_base_sign': tax.ref_base_sign, 'price_unit': cur_price_unit - amount,}) + res.append({'id':tax.id, 'name':tax.name, 'amount':amount, 'account_collected_id':tax.account_collected_id.id, 'account_paid_id':tax.account_paid_id.id, 'base_code_id': tax.base_code_id.id, 'ref_base_code_id': tax.ref_base_code_id.id, 'sequence': tax.sequence, 'base_sign': tax.base_sign, 'tax_sign': tax.tax_sign, 'ref_base_sign': tax.ref_base_sign, 'ref_tax_sign': tax.ref_tax_sign, 'price_unit': cur_price_unit - amount, 'tax_code_id': tax.tax_code_id.id, 'ref_tax_code_id': tax.ref_tax_code_id.id,}) elif tax.type=='fixed': - res.append({'id':tax.id, 'name':tax.name, 'amount':tax.amount, 'account_collected_id':tax.account_collected_id.id, 'account_paid_id':tax.account_paid_id.id, 'base_code_id': tax.base_code_id.id, 'ref_base_code_id': tax.ref_base_code_id.id, 'sequence': tax.sequence, 'base_sign': tax.base_sign, 'ref_base_sign': tax.ref_base_sign, 'price_unit': 1,}) + res.append({'id':tax.id, 'name':tax.name, 'amount':tax.amount, 'account_collected_id':tax.account_collected_id.id, 'account_paid_id':tax.account_paid_id.id, 'base_code_id': tax.base_code_id.id, 'ref_base_code_id': tax.ref_base_code_id.id, 'sequence': tax.sequence, 'base_sign': tax.base_sign, 'tax_sign': tax.tax_sign, 'ref_base_sign': tax.ref_base_sign, 'ref_tax_sign': tax.ref_tax_sign, 'price_unit': 1, 'tax_code_id': tax.tax_code_id.id, 'ref_tax_code_id': tax.ref_tax_code_id.id,}) elif tax.type=='code': address = address_id and self.pool.get('res.partner.address').browse(cr, uid, address_id) or None localdict = {'price_unit':cur_price_unit, 'address':address, 'product':product,} @@ -68,8 +68,12 @@ class account_tax(osv.osv): 'ref_base_code_id': tax.ref_base_code_id.id, 'sequence': tax.sequence, 'base_sign': tax.base_sign, + 'tax_sign': tax.tax_sign, 'ref_base_sign': tax.ref_base_sign, + 'ref_tax_sign': tax.ref_tax_sign, 'price_unit': cur_price_unit - amount, + 'tax_code_id': tax.tax_code_id.id, + 'ref_tax_code_id': tax.ref_tax_code_id.id, }) amount2 = res[-1]['amount'] if len(tax.child_ids): diff --git a/addons/account_tax_include/invoice_tax_incl.py b/addons/account_tax_include/invoice_tax_incl.py index 3577f1e2c51..175b7fa4642 100644 --- a/addons/account_tax_include/invoice_tax_incl.py +++ b/addons/account_tax_include/invoice_tax_incl.py @@ -91,7 +91,9 @@ class account_invoice_line(osv.osv): tax_grouped = {} tax_obj = self.pool.get('account.tax') cur_obj = self.pool.get('res.currency') + ait_obj = self.pool.get('account.invoice.tax') cur = inv.currency_id + for line in inv.invoice_line: res.append( { 'type':'src', @@ -100,45 +102,46 @@ class account_invoice_line(osv.osv): 'quantity':line.quantity, 'price':round(line.quantity*line.price_unit * (1.0- (line.discount or 0.0)/100.0),2), 'account_id':line.account_id.id, - 'tax_amount': 0.0 }) 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): - tax['amount'] = cur_obj.round(cr, uid, cur, tax['amount']) - tax['sequence'] = tax['sequence'] + val={} + val['invoice_id'] = inv.id + val['name'] = tax['name'] + val['amount'] = cur_obj.round(cr, uid, cur, tax['amount']) + val['manual'] = False + val['sequence'] = tax['sequence'] + val['base'] = tax['price_unit'] * line['quantity'] - #res[-1]['tax_amount'] += (line['price_unit'] * line['quantity'] * (1.0- (line['discount'] or 0.0)/100.0) * tax2.base_sign) # # Setting the tax account and amount for the line # - if inv.type in ('out_invoice','out_refund'): - res[-1]['tax_code_id'] = tax['base_code_id'] - res[-1]['tax_amount'] = tax['amount'] * tax['base_sign'] + if inv.type in ('out_invoice','in_invoice'): + val['base_code_id'] = tax['base_code_id'] + val['tax_code_id'] = tax['tax_code_id'] + val['base_amount'] = tax['base'] * tax['base_sign'] + val['tax_amount'] = tax['amount'] * tax['tax_sign'] + val['account_id'] = tax['account_collected_id'] or line.account_id.id else: - res[-1]['tax_code_id'] = tax['ref_base_code_id'] - res[-1]['tax_amount'] = tax['amount'] * tax['ref_base_sign'] - if inv.type in ('out_refund','in_refund'): - res[-1]['tax_amount'] = -res[-1]['tax_amount'] + val['base_code_id'] = tax['ref_base_code_id'] + val['tax_code_id'] = tax['ref_tax_code_id'] + val['base_amount'] = val['base'] * tax['ref_base_sign'] + val['tax_amount'] = val['amount'] * tax['ref_tax_sign'] + val['account_id'] = tax['account_paid_id'] or line.account_id.id - if inv.type in ('out_invoice','out_refund'): - tax['account_id'] = tax['account_collected_id'] or line.account_id.id - else: - tax['account_id'] = tax['account_paid_id'] or line.account_id.id - # - # Revoir la clé: tax.id ? - # - key = (res[-1]['tax_code_id'], tax['account_id']) - #res[-1]['price'] -= tax['amount'] - #res[-1]['tax_amount'] -= (tax['amount']* tax2.base_sign) + res[-1]['tax_code_id'] = val['base_code_id'] + res[-1]['tax_amount'] = val['base_amount'] + + key = (val['tax_code_id'], val['base_code_id'], val['account_id']) if not key in tax_grouped: - tax_grouped[key] = tax - #tax_grouped[key]['base'] = res[-1]['price'] - tax_grouped[key]['base'] = tax['price_unit'] * line['quantity'] + tax_grouped[key] = val else: - tax_grouped[key]['amount'] += tax['amount'] - #tax_grouped[key]['base'] += res[-1]['price'] - tax_grouped[key]['base'] += tax['price_unit'] * line['quantity'] + 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'] # delete automatic tax lines for this invoice cr.execute("DELETE FROM account_invoice_tax WHERE NOT manual AND invoice_id=%d", (invoice_id,)) - self.move_line_tax_create(cr, uid, inv, tax_grouped, context) + for t in tax_grouped.values(): + ait_obj.create(cr, uid, t) return res account_invoice_line() diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py index 1b44dd2a648..4e0e348ce4b 100644 --- a/addons/purchase/purchase.py +++ b/addons/purchase/purchase.py @@ -328,10 +328,10 @@ class purchase_order_line(osv.osv): lang=self.pool.get('res.partner').read(cr, uid, [partner_id])[0]['lang'] context={'lang':lang} price = self.pool.get('product.pricelist').price_get(cr,uid,[pricelist], product, qty or 1.0, partner_id, {'uom': uom})[pricelist] - prod = self.pool.get('product.product').read(cr, uid, [product], ['taxes_id','name','seller_delay','uom_po_id','description_purchase'])[0] + prod = self.pool.get('product.product').read(cr, uid, [product], ['supplier_taxes_id','name','seller_delay','uom_po_id','description_purchase'])[0] dt = (DateTime.now() + DateTime.RelativeDateTime(days=prod['seller_delay'] or 0.0)).strftime('%Y-%m-%d') prod_name = self.pool.get('product.product').name_get(cr, uid, [product], context=context)[0][1] - res = {'value': {'price_unit': price, 'name':prod_name, 'taxes_id':prod['taxes_id'], 'date_planned': dt,'notes':prod['description_purchase']}} + res = {'value': {'price_unit': price, 'name':prod_name, 'taxes_id':prod['supplier_taxes_id'], 'date_planned': dt,'notes':prod['description_purchase']}} domain = {} if not uom: res['value']['product_uom'] = prod['uom_po_id'][0]