From f9416858b77f3a3c58488ec08b8eae7ad2db9569 Mon Sep 17 00:00:00 2001 From: rde <> Date: Thu, 18 Jan 2007 16:56:51 +0000 Subject: [PATCH] purchase diuscount (doesn't work) bzr revid: rde-8d74ed8c35efcc66a819fc5b14c5623316e02131 --- addons/purchase_discount/__init__.py | 1 + addons/purchase_discount/__terp__.py | 11 + addons/purchase_discount/purchase_discount.py | 73 +++++ .../purchase_discount_report.xml | 11 + .../purchase_discount_view.xml | 27 ++ addons/purchase_discount/report/__init__.py | 29 ++ addons/purchase_discount/report/order.py | 87 ++++++ addons/purchase_discount/report/order.rml | 287 ++++++++++++++++++ 8 files changed, 526 insertions(+) create mode 100644 addons/purchase_discount/__init__.py create mode 100644 addons/purchase_discount/__terp__.py create mode 100644 addons/purchase_discount/purchase_discount.py create mode 100644 addons/purchase_discount/purchase_discount_report.xml create mode 100644 addons/purchase_discount/purchase_discount_view.xml create mode 100644 addons/purchase_discount/report/__init__.py create mode 100644 addons/purchase_discount/report/order.py create mode 100644 addons/purchase_discount/report/order.rml diff --git a/addons/purchase_discount/__init__.py b/addons/purchase_discount/__init__.py new file mode 100644 index 00000000000..705298eed00 --- /dev/null +++ b/addons/purchase_discount/__init__.py @@ -0,0 +1 @@ +import purchase_discount diff --git a/addons/purchase_discount/__terp__.py b/addons/purchase_discount/__terp__.py new file mode 100644 index 00000000000..8be12f08e23 --- /dev/null +++ b/addons/purchase_discount/__terp__.py @@ -0,0 +1,11 @@ +{ + "name" : "Purchase Order Lines With Discounts", + "author" : "Tiny", + "version" : "1.0", + "category" : "Generic Modules/Sales & Purchases", + "depends" : ["base", "account", "stock"], + "demo_xml" : [], + "update_xml" : ["purchase_discount_view.xml", "purchase_discount_report.xml"], + "active": False, + "installable": True +} diff --git a/addons/purchase_discount/purchase_discount.py b/addons/purchase_discount/purchase_discount.py new file mode 100644 index 00000000000..b4f98d5d0e3 --- /dev/null +++ b/addons/purchase_discount/purchase_discount.py @@ -0,0 +1,73 @@ +############################################################################## +# +# Copyright (c) 2004-2006 TINY SPRL. (http://tiny.be) All Rights Reserved. +# +# 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 +from osv import osv +import time +import netsvc + +import ir +from mx import DateTime +import pooler + +class purchase_order_line(osv.osv): + _name = "purchase.order.line" + _inherit = "purchase.order.line" + _columns = { + 'discount': fields.float('Discount (%)', digits=(16,2)), + } + _defaults = { + 'discount': lambda *a: 0.0, + } +purchase_order_line() + +class purchase_order(osv.osv): + _name = "purchase.order" + _inherit = "purchase.order" + + def _amount_untaxed(self, cr, uid, ids, field_name, arg, context): + id_set = ",".join(map(str, ids)) + sql_req="SELECT s.id,COALESCE(SUM(l.price_unit*l.product_qty*(100-l.discount))/100.0,0)::decimal(16,2) AS amount FROM purchase_order s LEFT OUTER JOIN purchase_order_line l ON (s.id=l.order_id) WHERE s.id IN ("+id_set+") GROUP BY s.id" + cr.execute(sql_req) + res = dict(cr.fetchall()) + print "_amount_untaxed : res = "+str(res) + return res + + def _amount_tax(self, cr, uid, ids, field_name, arg, context): + print "_amount_tax(self, cr, uid, ids, field_name, arg, context):" + res = {} + for order in self.browse(cr, uid, ids): + val = 0.0 + for line in order.order_line: + for tax in line.taxes_id: + for c in self.pool.get('account.tax').compute(cr, uid, [tax.id], line.price_unit * (1-(line.discount or 0.0)/100.0), line.product_qty, order.partner_address_id.id): + val+=c['amount'] + res[order.id]=round(val,2) + + print "_amount_tax : res = "+str(res) + return res +purchase_order() diff --git a/addons/purchase_discount/purchase_discount_report.xml b/addons/purchase_discount/purchase_discount_report.xml new file mode 100644 index 00000000000..20e2a137b9c --- /dev/null +++ b/addons/purchase_discount/purchase_discount_report.xml @@ -0,0 +1,11 @@ + + + + + + diff --git a/addons/purchase_discount/purchase_discount_view.xml b/addons/purchase_discount/purchase_discount_view.xml new file mode 100644 index 00000000000..ecd9449137a --- /dev/null +++ b/addons/purchase_discount/purchase_discount_view.xml @@ -0,0 +1,27 @@ + + + + purchase_discount.order.line.form + purchase.order.line + form + + + + + + + + + purchase_discount.order.line.tree + purchase.order.line + tree + + + + + + + + + + \ No newline at end of file diff --git a/addons/purchase_discount/report/__init__.py b/addons/purchase_discount/report/__init__.py new file mode 100644 index 00000000000..af013832d7c --- /dev/null +++ b/addons/purchase_discount/report/__init__.py @@ -0,0 +1,29 @@ +############################################################################## +# +# Copyright (c) 2004-2006 TINY SPRL. (http://tiny.be) All Rights Reserved. +# +# 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. +# +############################################################################## + +import order + diff --git a/addons/purchase_discount/report/order.py b/addons/purchase_discount/report/order.py new file mode 100644 index 00000000000..d3879eafa82 --- /dev/null +++ b/addons/purchase_discount/report/order.py @@ -0,0 +1,87 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright (c) 2006 TINY SPRL. (http://tiny.be) All Rights Reserved. +# +# 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. +# +############################################################################## + +import time +from report import report_sxw +from osv import osv +import pooler + +class order(report_sxw.rml_parse): + def __init__(self, cr, uid, name, context): + super(order, self).__init__(cr, uid, name, context) + self.localcontext.update({ + 'time': time, + 'get_line_tax': self._get_line_tax, + 'get_tax': self._get_tax, + 'get_product_code': self._get_product_code, + }) + def _get_line_tax(self, line_obj): + self.cr.execute("SELECT tax_id FROM purchase_order_taxe WHERE order_line_id=%d" % (line_obj.id)) + res = self.cr.fetchall() or None + if not res: + return "" + if isinstance(res, list): + tax_ids = [t[0] for t in res] + else: + tax_ids = res[0] + res = [tax.name for tax in pooler.get_pool(cr.dbname).get('account.tax').browse(self.cr, self.uid, tax_ids)] + return ",\n ".join(res) + + def _get_tax(self, order_obj): + self.cr.execute("SELECT DISTINCT tax_id FROM purchase_order_taxe, purchase_order_line, purchase_order \ + WHERE (purchase_order_line.order_id=purchase_order.id) AND (purchase_order.id=%d)" % (order_obj.id)) + res = self.cr.fetchall() or None + if not res: + return [] + if isinstance(res, list): + tax_ids = [t[0] for t in res] + else: + tax_ids = res[0] + tax_obj = pooler.get_pool(cr.dbname).get('account.tax') + res = [] + for tax in tax_obj.browse(self.cr, self.uid, tax_ids): + self.cr.execute("SELECT DISTINCT order_line_id FROM purchase_order_line, purchase_order_taxe \ + WHERE (purchase_order_taxe.tax_id=%d) AND (purchase_order_line.order_id=%d)" % (tax.id, order_obj.id)) + lines = self.cr.fetchall() or None + if lines: + if isinstance(lines, list): + line_ids = [l[0] for l in lines] + else: + line_ids = lines[0] + base = 0 + for line in pooler.get_pool(cr.dbname).get('purchase.order.line').browse(self.cr, self.uid, line_ids): + base += line.price_subtotal + res.append({'code':tax.name, + 'base':base, + 'amount':base*tax.amount}) + return res + def _get_product_code(self, product_id, partner_id): + product_obj=pooler.get_pool(self.cr.dbname).get('product.product') + return product_obj._product_code(self.cr, self.uid, [product_id], name=None, arg=None, context={'partner_id': partner_id})[product_id] + +report_sxw.report_sxw('report.purchase.order','purchase.order','addons/purchase/report/order.rml',parser=order) diff --git a/addons/purchase_discount/report/order.rml b/addons/purchase_discount/report/order.rml new file mode 100644 index 00000000000..48c39057da1 --- /dev/null +++ b/addons/purchase_discount/report/order.rml @@ -0,0 +1,287 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [[ repeatIn(objects,'o') ]] + + + + + + + + + + Shipping address : + + + + + [[ repeatIn(o.dest_address_id and [o.dest_address_id] or [],'addr') ]] + [[ o.partner_id.title or '' ]] [[ o.partner_id.name ]] + [[ addr.title or '' ]] [[ addr.name ]] + [[ addr.street ]] + [[ addr.street2 or '' ]] + [[ addr.zip or '' ]] [[ addr.city or '' ]] + [[ addr.state_id and addr.state_id.name or '' ]] + [[ addr.country_id and addr.country_id.name or '' ]] + + + + + + + + + + + + + + [[ o.partner_id.title or '' ]] [[ o.partner_id.name ]] + [[ o.partner_address_id.title or '' ]] [[ o.partner_address_id.name ]] + [[ o.partner_address_id.street ]] + [[ o.partner_address_id.street2 or '' ]] + [[ o.partner_address_id.zip or '' ]] [[ o.partner_address_id.city or '' ]] + [[ o.partner_address_id.state_id and o.partner_address_id.state_id.name or '' ]] + [[ o.partner_address_id.country_id and o.partner_address_id.country_id.name or '' ]] + + + + Tél. : [[ o.partner_address_id.phone or '' ]] + Fax : [[ o.partner_address_id.fax or '' ]] + TVA : [[ o.partner_id.vat or '' ]] + + + + + + + [[ o.state=='draft' and 'Quotation ' or 'Order ' ]] N° : [[ o.name ]] + + + + Our order reference : [[ o.ref or '' ]] + Your order reference : [[ o.partner_ref or '' ]] + Date ordered : [[ time.strftime('%d/%m/%Y', time.strptime(o.date_order, '%Y-%m-%d')) ]] + Validated by : [[ o.validator and o.validator.name or '' ]] + + + + + + + Product Description + + + Applicable Taxes + + + Date Promised + + + Qty + + + UoM + + + Unit Price + + + Discount (%) + + + Net Price + + + +
+ [[ repeatIn(o.order_line,'line') ]] + + + + [[ line.name ]] + + + [[ ', '.join(map(lambda x: x.name, line.taxes_id))]] + + + [[ time.strftime('%d/%m/%Y', time.strptime( line.date_planned, '%Y-%m-%d')) ]] + + + [[ line.product_qty ]] + + + [[ line.product_uom.name ]] + + + [[ '%.2f' % line.price_unit ]] + + + [[ '%.2f'%line.discount ]] + + + [[ '%.2f' % line.price_subtotal ]] + + + + + + + [[ repeatIn((line.notes and [line.notes]) or [], 'l') ]] + + + [[ l or removeParentNode('table') ]] + + + + + + + + +
+ + + + + + + + + + + + Net Total : + + + [[ '%.2f' % o.amount_untaxed ]] [[ o.pricelist_id.currency_id.name ]] + + + + + + + + + + Taxes : + + + [[ '%.2f' % o.amount_tax ]] [[ o.pricelist_id.currency_id.name ]] + + + + + + + + + + TOTAL : + + + [[ '%.2f' % o.amount_total ]] [[ o.pricelist_id.currency_id.name ]] + + + + + + + + + + [[ o.notes or '' ]] [[ setTag('para','xpre') ]] + + + + + + +
+
+