188 lines
8.1 KiB
Python
188 lines
8.1 KiB
Python
##############################################################################
|
|
#
|
|
# Copyright (c) 2004-2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
|
#
|
|
# $Id: sale.py 1005 2005-07-25 08:41:42Z nicoe $
|
|
#
|
|
# WARNING: This program as such is intended to be used by professional
|
|
# programmers who take the whole responsability of assessing all potential
|
|
# consequences resulting from its eventual inadequacies and bugs
|
|
# End users who are looking for a ready-to-use solution with commercial
|
|
# garantees and support are strongly adviced to contract a Free Software
|
|
# Service Company
|
|
#
|
|
# 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 2
|
|
# of the License, or (at your option) any later version.
|
|
#
|
|
# 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.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, write to the Free Software
|
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
#
|
|
##############################################################################
|
|
|
|
from osv import fields, osv
|
|
import ir
|
|
|
|
class partner_wh_rebate(osv.osv):
|
|
_name = "res.partner"
|
|
_inherit = "res.partner"
|
|
_columns = {
|
|
'rebate': fields.float('Rebate (%)', digits=(5, 2)),
|
|
}
|
|
partner_wh_rebate()
|
|
|
|
class sale_order_rebate(osv.osv):
|
|
_name = "sale.order"
|
|
_inherit = "sale.order"
|
|
|
|
def _amount_wo_rebate(self, cr, uid, ids, field_name, arg, context):
|
|
return super(sale_order_rebate, self)._amount_untaxed(cr, uid, ids, field_name, arg, context)
|
|
|
|
def _amount_rebate(self, cr, uid, ids, field_name, arg, context):
|
|
wo_rebate = self._amount_wo_rebate(cr, uid, ids, field_name, arg, context)
|
|
orders = self.read(cr, uid, ids, ['rebate_percent'], context)
|
|
rebates = dict([(o['id'], o['rebate_percent']) for o in orders])
|
|
res = {}
|
|
for id in ids:
|
|
res[id] = wo_rebate.get(id, 0.0) * (rebates.get(id, 0.0) / 100.0)
|
|
return res
|
|
|
|
def _amount_untaxed(self, cr, uid, ids, field_name, arg, context):
|
|
wo_rebate = self._amount_wo_rebate(cr, uid, ids, field_name, arg, context)
|
|
rebate = self._amount_rebate(cr, uid, ids, field_name, arg, context)
|
|
res = {}
|
|
for id in ids:
|
|
res[id] = wo_rebate.get(id, 0.0) - rebate.get(id, 0.0)
|
|
return res
|
|
|
|
def _amount_tax(self, cr, uid, ids, field_name, arg, context):
|
|
res = {}
|
|
cur_obj=self.pool.get('res.currency')
|
|
for order in self.browse(cr, uid, ids):
|
|
val = 0.0
|
|
cur=order.pricelist_id.currency_id
|
|
for line in order.order_line:
|
|
for c in self.pool.get('account.tax').compute(cr, uid, line.tax_id, line.price_unit, line.product_uom_qty, order.partner_invoice_id.id):
|
|
val += cur_obj.round(cr, uid, cur, (c['amount'] * (100.0 - order.rebate_percent) / 100.0))
|
|
res[order.id] = cur_obj.round(cr, uid, cur, val)
|
|
return res
|
|
|
|
_columns = {
|
|
'rebate_percent': fields.float('Rebate (%)', digits=(5, 2), readonly=True, states={'draft':[('readonly',False)]}),
|
|
# 'rebate_account': fields.many2one('account.account', 'Rebate account', required=True, readonly=True, states={'draft':[('readonly',False)]}),
|
|
'amount_wo_rebate': fields.function(_amount_wo_rebate, method=True, string='Intermediate sum'),
|
|
'amount_rebate': fields.function(_amount_rebate, method=True, string='Rebate'),
|
|
'amount_untaxed': fields.function(_amount_untaxed, method=True, string='Untaxed Amount'),
|
|
'amount_tax': fields.function(_amount_tax, method=True, string='Taxes'),
|
|
}
|
|
_defaults = {
|
|
'rebate_percent': lambda *a: 0.0,
|
|
}
|
|
|
|
#
|
|
# Why not using super().onchange_partner_id ?
|
|
#
|
|
def onchange_partner_id(self, cr, uid, ids, partner_id):
|
|
if not partner_id:
|
|
return {'value': {'partner_invoice_id': False, 'partner_shipping_id': False, 'partner_order_id': False}}
|
|
partner = self.pool.get('res.partner').browse(cr, uid, partner_id)
|
|
addr = self.pool.get('res.partner').address_get(cr, uid, [partner_id], ['delivery', 'invoice', 'contact'])
|
|
pricelist = partner.property_product_pricelist[0]
|
|
return {
|
|
'value': {
|
|
'rebate_percent': partner.rebate or 0.0,
|
|
'partner_invoice_id': addr['invoice'],
|
|
'partner_order_id': addr['contact'],
|
|
'partner_shipping_id': addr['delivery'],
|
|
'pricelist_id': pricelist
|
|
}
|
|
}
|
|
|
|
def action_invoice_create(self, cr, uid, ids, grouped=False, states=['confirmed','done']):
|
|
assert len(ids)==1, "Can only invoice one sale order at a time"
|
|
invoice_id = super(sale_order_rebate, self).action_invoice_create(cr, uid, ids, grouped, states)
|
|
if invoice_id:
|
|
order = self.browse(cr, uid, ids[0])
|
|
inv_obj = self.pool.get('account.invoice')
|
|
inv_obj.write(cr, uid, [invoice_id], {'rebate_percent': order.rebate_percent})
|
|
inv_obj.button_compute(cr, uid, [invoice_id])
|
|
return invoice_id
|
|
sale_order_rebate()
|
|
|
|
class account_invoice_wh_rebate(osv.osv):
|
|
_name = "account.invoice"
|
|
_inherit = "account.invoice"
|
|
|
|
def _amount_wo_rebate(self, cr, uid, ids, field_name, arg, context):
|
|
return super(account_invoice_wh_rebate, self)._amount_untaxed(cr, uid, ids, field_name, arg, context)
|
|
|
|
def _amount_untaxed(self, cr, uid, ids, field_name, arg, context):
|
|
un_taxed = super(account_invoice_wh_rebate, self)._amount_untaxed(cr, uid, ids, field_name, arg, context)
|
|
res = {}
|
|
for invoice in self.browse(cr, uid, ids):
|
|
res[invoice.id] = un_taxed[invoice.id] - invoice.rebate_amount
|
|
return res
|
|
|
|
_columns = {
|
|
'amount_wo_rebate': fields.function(_amount_wo_rebate, method=True, string='Intermediate sum'),
|
|
'amount_untaxed': fields.function(_amount_untaxed, method=True, string='Untaxed Amount'),
|
|
'rebate_percent': fields.float('Rebate (%)', digits=(5, 2), readonly=True),
|
|
'rebate_amount': fields.float('Rebate amount', digits=(14, 2), readonly=True)
|
|
}
|
|
account_invoice_wh_rebate()
|
|
|
|
class account_invoice_line_wh_rebate(osv.osv):
|
|
_name = "account.invoice.line"
|
|
_inherit = "account.invoice.line"
|
|
|
|
def move_line_get(self, cr, uid, invoice_id):
|
|
invoice = self.pool.get('account.invoice').browse(cr, uid, invoice_id)
|
|
res = []
|
|
tax_grouped = {}
|
|
tax_obj = self.pool.get('account.tax')
|
|
#TODO: rewrite using browse instead of the manual SQL queries
|
|
cr.execute('SELECT * FROM account_invoice_line WHERE invoice_id=%d', (invoice_id,))
|
|
lines = cr.dictfetchall()
|
|
rebate_percent = invoice.rebate_percent
|
|
rebate_amount = 0.0
|
|
for line in lines:
|
|
price_unit = line['price_unit'] * (100.0 - rebate_percent) / 100.0
|
|
res.append({'type':'src', 'name':line['name'], 'price_unit':price_unit, 'quantity':line['quantity'], 'price':round(line['quantity']*price_unit, 2), 'account_id':line['account_id']})
|
|
cr.execute('SELECT tax_id FROM account_invoice_line_tax WHERE invoice_line_id=%d', (line['id'],))
|
|
rebate_amount += (line['price_unit'] * rebate_percent / 100.0) * line['quantity']
|
|
for (tax_id,) in cr.fetchall():
|
|
# even though we pass only one tax id at a time to compute, it can return several results
|
|
# in case a tax has a parent tax
|
|
sequence = tax_obj.read(cr, uid, [tax_id], ['sequence'])[0]['sequence']
|
|
for tax in tax_obj.compute(cr, uid, [tax_id], price_unit, line['quantity'], invoice.address_invoice_id.id):
|
|
tax['sequence'] = sequence
|
|
if invoice.type in ('out_invoice','in_refund'):
|
|
tax['account_id'] = tax['account_collected_id']
|
|
else:
|
|
tax['account_id'] = tax['account_paid_id']
|
|
key = tax['account_id']
|
|
if not key in tax_grouped:
|
|
tax_grouped[key] = tax
|
|
else:
|
|
tax_grouped[key]['amount'] += 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,))
|
|
|
|
# (re)create them
|
|
ait = self.pool.get('account.invoice.tax')
|
|
for t in tax_grouped.values():
|
|
ait.create(cr, uid, {'invoice_id':invoice_id, 'name':t['name'], 'account_id':t['account_id'], 'amount':t['amount'], 'manual':False, 'sequence':t['sequence']})
|
|
|
|
# update rebate amount for this invoice
|
|
self.pool.get('account.invoice').write(cr, uid, [invoice_id], {'rebate_amount': rebate_amount})
|
|
return res
|
|
account_invoice_line_wh_rebate()
|
|
|