← Back to team overview

openerp-community-reviewer team mailing list archive

[Merge] lp:~camptocamp/sale-wkfl/7.0-add-last_sale_price-yvr into lp:sale-wkfl

 

Yannick Vaucher @ Camptocamp has proposed merging lp:~camptocamp/sale-wkfl/7.0-add-last_sale_price-yvr into lp:sale-wkfl.

Commit message:
[ADD] module last_sale_price - This module provides new columns in sale order line in order to let the sellerman know if a customer already ordrered a product
to give him hint of what price he should propose, those information will be
shown next to the price in sale order line Form.


Requested reviews:
  Sale Core Editors (sale-core-editors)

For more details, see:
https://code.launchpad.net/~camptocamp/sale-wkfl/7.0-add-last_sale_price-yvr/+merge/223704

Add a module to show last price defined for customer on sale order line
-- 
https://code.launchpad.net/~camptocamp/sale-wkfl/7.0-add-last_sale_price-yvr/+merge/223704
Your team Sale Core Editors is requested to review the proposed merge of lp:~camptocamp/sale-wkfl/7.0-add-last_sale_price-yvr into lp:sale-wkfl.
=== added directory 'last_sale_price'
=== added file 'last_sale_price/__init__.py'
--- last_sale_price/__init__.py	1970-01-01 00:00:00 +0000
+++ last_sale_price/__init__.py	2014-06-19 09:54:47 +0000
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    Author: Yannick Vaucher
+#    Copyright 2014 Camptocamp SA
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+from . import sale

=== added file 'last_sale_price/__openerp__.py'
--- last_sale_price/__openerp__.py	1970-01-01 00:00:00 +0000
+++ last_sale_price/__openerp__.py	2014-06-19 09:54:47 +0000
@@ -0,0 +1,47 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    Author: Yannick Vaucher
+#    Copyright 2014 Camptocamp SA
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+{'name': 'Last Sale Price',
+ 'summary': 'Show last price defined for customer on sale order line',
+ 'version': '1.0',
+ 'category': 'Sales',
+ 'description': """
+Last Sale Price
+===============
+
+Add price and date of a product of the last time it was sold to a partner.
+
+Those information will be shown next to the price in sale order Form.
+
+Only confirmed and done sale orders are considered.
+
+If multiple sale order lines for the same partner where made on the same
+date, the mean will be displayed.
+""",
+ 'author': 'Camptocamp',
+ 'maintainer': 'Camptocamp',
+ 'website': 'http://www.camptocamp.com/',
+ 'depends': ['base', 'sale'],
+ 'data': ['sale_view.xml'],
+ 'test': ['test/last_sale_price.yml'],
+ 'installable': True,
+ 'auto_install': False,
+ 'application': True,
+ }

=== added directory 'last_sale_price/i18n'
=== added file 'last_sale_price/i18n/last_sale_price.pot'
--- last_sale_price/i18n/last_sale_price.pot	1970-01-01 00:00:00 +0000
+++ last_sale_price/i18n/last_sale_price.pot	2014-06-19 09:54:47 +0000
@@ -0,0 +1,43 @@
+# Translation of OpenERP Server.
+# This file contains the translation of the following modules:
+#	* last_sale_price
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: OpenERP Server 7.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2014-06-18 15:28+0000\n"
+"PO-Revision-Date: 2014-06-18 15:28+0000\n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: last_sale_price:
+#: field:sale.order.line,last_sale_date:0
+msgid "Last Sale Date"
+msgstr ""
+
+#. module: last_sale_price
+#: field:sale.order.line,last_sale_price:0
+msgid "Last Sale Price"
+msgstr ""
+
+#. module: last_sale_price
+#: field:sale.order.line,last_sale_qty:0
+msgid "Last Sale Quantity"
+msgstr ""
+
+#. module: last_sale_price
+#: model:ir.model,name:last_sale_price.model_sale_order_line
+msgid "Sale Order line"
+msgstr ""
+
+#. module: last_sale_price
+#: code:_description:0
+#, python-format
+msgid "Sales Order Line"
+msgstr ""
+

=== added file 'last_sale_price/sale.py'
--- last_sale_price/sale.py	1970-01-01 00:00:00 +0000
+++ last_sale_price/sale.py	2014-06-19 09:54:47 +0000
@@ -0,0 +1,94 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    Author: Yannick Vaucher
+#    Copyright 2014 Camptocamp SA
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+from openerp.osv import orm, fields
+
+
+class SaleOrderLine(orm.Model):
+    _inherit = 'sale.order.line'
+
+    def _get_last_sale_sums(self, cr, uid, last_lines, context=None):
+        """ Get last price from sale order lines
+
+        If multiple lines exists at the same date we do an average
+        """
+        if len(last_lines) == 1:
+            return last_lines[0].price_unit, last_lines[0].product_uom_qty
+        else:
+            sum_price = 0.0
+            sum_qty = 0.0
+            for line in last_lines:
+                sum_qty += line.product_uom_qty
+                sum_price += line.price_unit * line.product_uom_qty
+            return sum_price / float(sum_qty), sum_qty
+
+    def _get_last_sale(self, cr, uid, ids, field_name, arg, context=None):
+        """ Get last sale price and last sale date
+        """
+        res = {}
+        for res_id in ids:
+            res[res_id] = {'last_sale_price': False,
+                           'last_sale_qty': False,
+                           'last_sale_date': False}
+        for line in self.browse(cr, uid, ids, context=context):
+            if not line.product_id:
+                continue
+
+            line_ids = self.search(
+                cr, uid,
+                [('order_partner_id', '=', line.order_partner_id.id),
+                 ('product_id', '=', line.product_id.id),
+                 ('state', 'in', ['confirmed', 'done'])],
+                context=context)
+
+            if not line_ids:
+                continue
+
+            old_lines = self.browse(cr, uid, line_ids, context=context)
+            old_lines.sort(key=lambda l: l.order_id.date_order, reverse=True)
+
+            last_date = old_lines[0].order_id.date_order
+            last_lines = [l for l in old_lines
+                          if l.order_id.date_order == last_date]
+            res[line.id]['last_sale_date'] = last_date
+
+            (last_price, last_qty) = self._get_last_sale_sums(
+                cr, uid, last_lines, context=context)
+            res[line.id]['last_sale_price'] = last_price
+            res[line.id]['last_sale_qty'] = last_qty
+        return res
+
+    _columns = {
+        'last_sale_price': fields.function(
+            _get_last_sale,
+            type="float",
+            string='Last Sale Price',
+            multi='last_sale'),
+        'last_sale_qty': fields.function(
+            _get_last_sale,
+            type="float",
+            string='Last Sale Quantity',
+            multi='last_sale'),
+        'last_sale_date': fields.function(
+            _get_last_sale,
+            type="date",
+            string='Last Sale Date',
+            multi='last_sale'),
+    }

=== added file 'last_sale_price/sale_view.xml'
--- last_sale_price/sale_view.xml	1970-01-01 00:00:00 +0000
+++ last_sale_price/sale_view.xml	2014-06-19 09:54:47 +0000
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+  <data>
+    <record id="view_order_form" model="ir.ui.view">
+      <field name="name">sale.order.form.last_sale</field>
+      <field name="model">sale.order</field>
+      <field name="inherit_id" ref="sale.view_order_form"/>
+      <field name="arch" type="xml">
+        <xpath expr="//field[@name='order_line']/form//field[@name='price_unit']" position="after">
+          <field name="last_sale_date"/>
+          <field name="last_sale_price"/>
+          <field name="last_sale_qty"/>
+        </xpath>
+        <xpath expr="//field[@name='order_line']/tree//field[@name='price_unit']" position="after">
+          <field name="last_sale_date"/>
+          <field name="last_sale_price"/>
+          <field name="last_sale_qty"/>
+        </xpath>
+      </field>
+    </record>
+
+  </data>
+</openerp>

=== added directory 'last_sale_price/test'
=== added file 'last_sale_price/test/__init__.py'
--- last_sale_price/test/__init__.py	1970-01-01 00:00:00 +0000
+++ last_sale_price/test/__init__.py	2014-06-19 09:54:47 +0000
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    Author: Yannick Vaucher
+#    Copyright 2013 Camptocamp SA
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+from . import test_generate_labels

=== added file 'last_sale_price/test/last_sale_price.yml'
--- last_sale_price/test/last_sale_price.yml	1970-01-01 00:00:00 +0000
+++ last_sale_price/test/last_sale_price.yml	2014-06-19 09:54:47 +0000
@@ -0,0 +1,169 @@
+-
+  In order to test module last_sale_price I will create
+  multiple orders on different dates with different products
+  and for different partners
+
+  I test the following with user admin
+-
+  !context
+    uid: 'base.user_root'
+-
+  I create a screwdriver product
+-
+  !record {model: product.product, id: product_product_a}:
+    categ_id: product.product_category_1
+    name: Blue Screwdriver A
+    cost_method: standard
+    uom_id: product.product_uom_unit
+    uom_po_id: product.product_uom_unit
+    company_id: 0
+    standard_price: 5.0
+    list_price: 25.0
+-
+  I create a hammer product
+-
+  !record {model: product.product, id: product_product_b}:
+    categ_id: product.product_category_1
+    name: Red Hammer B
+    cost_method: standard
+    uom_id: product.product_uom_unit
+    uom_po_id: product.product_uom_unit
+    company_id: 0
+    standard_price: 10.0
+    list_price: 30.0
+
+-
+  I create a sale order buying screwdriver
+-
+  !record {model: sale.order, id: sale_order_p1_1}:
+    name: My first order
+    partner_id: base.res_partner_12
+    date_order: 2000-01-01
+    order_line:
+      - name: Screwdrivers
+        product_id: product_product_a
+        product_uom_qty: 5
+        price_unit: 21.0
+
+-
+  I verify no last price is set as there was no previous sale for this partner
+-
+  !assert {model: sale.order, id: sale_order_p1_1, string: last_sale_price is not empty}:
+    - order_line[0].last_sale_price == False
+    - order_line[0].last_sale_qty == False
+    - order_line[0].last_sale_date == False
+
+-
+  I confirm the first order
+-
+  !workflow {model: sale.order, action: order_confirm, ref: sale_order_p1_1}
+
+-
+  I verify confirming the order changed previous data for this product
+-
+  !assert {model: sale.order, id: sale_order_p1_1, string: last_sale_price is not correctly set}:
+    - order_line[0].last_sale_price == 21.0
+    - order_line[0].last_sale_qty == 5
+    - order_line[0].last_sale_date == '2000-01-01'
+
+-
+  In order to test different product doesn't impact each other
+  and test if with multiple order the last one is the one we use
+  Create a second sale order buying screwdriver and hammers
+-
+  !record {model: sale.order, id: sale_order_p1_2}:
+    name: My second order
+    partner_id: base.res_partner_12
+    date_order: 2001-01-01
+    order_line:
+      - name: Screwdrivers
+        product_id: product_product_a
+        product_uom_qty: 6
+        price_unit: 20.0
+      - name: Hammers
+        product_id: product_product_b
+        product_uom_qty: 25
+        price_unit: 25.0
+
+-
+  I verify nothing changed after creating the unconfirmed order
+-
+  !assert {model: sale.order, id: sale_order_p1_2, string: last_sale data are not correctly set}:
+    - order_line[0].last_sale_price == 21.0
+    - order_line[0].last_sale_qty == 5
+    - order_line[0].last_sale_date == '2000-01-01'
+
+-
+  I verify product B is not impacted by product A
+-
+  !assert {model: sale.order, id: sale_order_p1_2, string: last_sale_price of second line is not empty}:
+    - order_line[1].last_sale_price == False
+    - order_line[1].last_sale_qty == False
+    - order_line[1].last_sale_date == False
+
+-
+  I confirm the second first order
+-
+  !workflow {model: sale.order, action: order_confirm, ref: sale_order_p1_2}
+
+-
+  I verify the newest sale changed lase Sale data
+-
+  !assert {model: sale.order, id: sale_order_p1_2, string: last_sale data is not set with last data}:
+    - order_line[0].last_sale_price == 20.0
+    - order_line[0].last_sale_qty == 6
+    - order_line[0].last_sale_date == '2001-01-01'
+-
+  I verify second customer has no impact on product B
+-
+  !assert {model: sale.order, id: sale_order_p1_2, string: last_sale data is wrongly set with multiple products}:
+    - order_line[1].last_sale_price == 25.0
+    - order_line[1].last_sale_qty == 25
+    - order_line[1].last_sale_date == '2001-01-01'
+-
+  In order sales from a partner doesn't impact sales for other partners
+  and in order to impact of multiple order line from same partner on same product
+  Create another order buying hammers in 2 times for another customer
+-
+  !record {model: sale.order, id: sale_order_p2_1}:
+    name: Another order from another customer
+    partner_id: base.res_partner_11
+    date_order: 2001-01-01
+    order_line:
+      - name: Hammers
+        product_id: product_product_b
+        product_uom_qty: 100
+        price_unit: 5.0
+      - name: Hammers
+        product_id: product_product_b
+        product_uom_qty: 100
+        price_unit: 15.0
+
+-
+  I verify nothing is set for second customer
+-
+  !assert {model: sale.order, id: sale_order_p2_1, string: last_sale data is not empty}:
+    - order_line[0].last_sale_price == False
+    - order_line[0].last_sale_qty == False
+    - order_line[0].last_sale_date == False
+
+-
+  I confirm the third order
+-
+  !workflow {model: sale.order, action: order_confirm, ref: sale_order_p2_1}
+
+-
+  I verify that for first customer, the sale to second customer has no impact on product B
+-
+  !assert {model: sale.order, id: sale_order_p1_2, string: last_sale data is wrongly shared by partner}:
+    - order_line[1].last_sale_price == 25.0
+    - order_line[1].last_sale_qty == 25
+    - order_line[1].last_sale_date == '2001-01-01'
+
+-
+  I verify that for second customer product B last sale price is the mean of all sales of same date
+-
+  !assert {model: sale.order, id: sale_order_p2_1, string: last_sale data didn't change for hammers}:
+    - order_line[0].last_sale_price == 10.0
+    - order_line[0].last_sale_qty == 200
+    - order_line[0].last_sale_date == '2001-01-01'


References