Browse Source

[ADD] margin_percent field on pos_order ;

[ADD] margin and margin_percent on pos_order tree view ;
[IMP] make faster installation on database with many pos_orders, using pre_init_hook
[FIX] remove compute method for pos_order_line.purchase_price, cortesy @sebastienbeau
[fix] description
pull/422/head
Sylvain LE GAL 7 years ago
parent
commit
416fc6b3d6
  1. 30
      pos_margin/README.rst
  2. 1
      pos_margin/__init__.py
  3. 6
      pos_margin/__openerp__.py
  4. 25
      pos_margin/hooks.py
  5. 16
      pos_margin/i18n/fr.po
  6. 16
      pos_margin/models/pos_order.py
  7. 43
      pos_margin/models/pos_order_line.py
  8. BIN
      pos_margin/static/description/pos_order_form.png
  9. BIN
      pos_margin/static/description/pos_order_form_view.png
  10. BIN
      pos_margin/static/description/pos_order_tree_view.png
  11. 20
      pos_margin/views/view_pos_order.xml

30
pos_margin/README.rst

@ -1,15 +1,10 @@
=============================================
This module adds the 'Margin' on sales order.
=============================================
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
Margin on PoS order
===================
====================
Margin on PoS Orders
====================
This module extends the functionality of point of sale to support margin on
pos orders.
@ -17,16 +12,29 @@ pos orders.
This gives the profitability by calculating the difference between the Unit
Price and Cost Price.
Configuration
=============
this module create a new Decimal precision for the field 'Margin (%)' of the
pos.order model, with two digits, by default. you can change the precision,
going to 'Settings' / 'Technical' / 'Database Structure' / 'Decimal Accuracy'
Usage
=====
To use this module, you need to:
#. Go to 'Point Of Sale' / 'Daily Operations' / 'Orders'
#. Open an order
* Go to 'Point Of Sale' / 'Daily Operations' / 'Orders'
* View Orders
.. figure:: static/description/pos_order_tree_view.png
:width: 800px
* Open an Order
.. figure:: ./pos_margin/static/description/pos_order_form.png
.. figure:: static/description/pos_order_form_view.png
:width: 800px
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas

1
pos_margin/__init__.py

@ -1,2 +1,3 @@
# -#- coding: utf-8 -#-
from . import models
from .hooks import pre_init_hook

6
pos_margin/__openerp__.py

@ -5,12 +5,11 @@
{
'name': 'POS Margin',
'version': '8.0.1.0.0',
'version': '8.0.1.0.1',
'category': 'Point Of Sale',
'sequence': 1,
'author': "GRAP,"
"Odoo Community Association (OCA)",
'summary': 'Margin on PoS Order',
'summary': 'Margin on PoS Orders',
'depends': [
'point_of_sale',
],
@ -18,4 +17,5 @@
'views/view_pos_order.xml',
],
'installable': True,
'pre_init_hook': 'pre_init_hook',
}

25
pos_margin/hooks.py

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2017 - Today: GRAP (http://www.grap.coop)
# @author: Sylvain LE GAL (https://twitter.com/legalsylvain)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import logging
_logger = logging.getLogger(__name__)
def _create_column(cr, table_name, column_name, column_type):
_logger.info("Fast creation of the column %s.%s" % (
table_name, column_name))
req = "ALTER TABLE %s ADD COLUMN %s %s" % (
table_name, column_name, column_type)
cr.execute(req)
def pre_init_hook(cr):
_create_column(cr, 'pos_order_line', 'purchase_price', 'numeric')
_create_column(cr, 'pos_order_line', 'margin', 'numeric')
_create_column(cr, 'pos_order_line', 'margin_percent', 'numeric')
_create_column(cr, 'pos_order', 'margin', 'numeric')
_create_column(cr, 'pos_order', 'margin_percent', 'numeric')

16
pos_margin/i18n/fr.po

@ -38,17 +38,19 @@ msgid "Lines of Point of Sale"
msgstr "Lignes de Points de Vente"
#. module: pos_margin
#: field:pos.order,margin:0 field:pos.order.line,margin:0
#: view:pos.order:pos_margin.view_pos_order_form
#: field:pos.order,margin:0
#: field:pos.order.line,margin:0
msgid "Margin"
msgstr "Marge"
#. module: pos_margin
#: field:pos.order,margin_percent:0
#: field:pos.order.line,margin_percent:0
msgid "Margin (%)"
msgstr "Marge (%)"
#. module: pos_margin
#: model:ir.model,name:pos_margin.model_pos_order
msgid "Point of Sale"
msgstr "Point de Vente"
#~ msgid "Margin (%)"
#~ msgstr "Marge (%)"
#~ msgid "Total"
#~ msgstr "Total"

16
pos_margin/models/pos_order.py

@ -12,14 +12,24 @@ class PosOrder(models.Model):
# Columns Section
margin = fields.Float(
'Margin', compute='_compute_margin', store=True,
'Margin', compute='_compute_margin', store=True, multi='margin',
digits_compute=dp.get_precision('Product Price'),
help="It gives profitability by calculating the difference between"
" the Unit Price and the cost price.")
margin_percent = fields.Float(
'Margin (%)', compute='_compute_margin', store=True, multi='margin',
digits_compute=dp.get_precision('Product Price'))
# Compute Section
@api.multi
@api.depends('lines.margin')
@api.depends('lines.margin', 'lines.price_subtotal')
def _compute_margin(self):
for order in self:
order.margin = sum(order.mapped('lines.margin'))
tmp_margin = sum(order.mapped('lines.margin'))
tmp_subtotal = sum(order.mapped('lines.price_subtotal'))
order.update({
'margin': tmp_margin,
'margin_percent': tmp_margin / tmp_subtotal * 100 if
tmp_subtotal else 0.0,
})

43
pos_margin/models/pos_order_line.py

@ -17,19 +17,44 @@ class PosOrderLine(models.Model):
digits_compute=dp.get_precision('Product Price'))
purchase_price = fields.Float(
'Cost Price', compute='_compute_multi_margin', store=True,
'Cost Price', digits_compute=dp.get_precision('Product Price'))
margin_percent = fields.Float(
'Margin (%)', compute='_compute_multi_margin', store=True,
multi='multi_margin',
digits_compute=dp.get_precision('Product Price'))
# Onchange Section
@api.multi
def onchange_product_id(
self, pricelist, product_id, qty=0, partner_id=False):
product_obj = self.env['product.product']
res = super(PosOrderLine, self).onchange_product_id(
pricelist, product_id, qty=qty, partner_id=partner_id)
if product_id:
product = product_obj.browse(product_id)
res['value']['purchase_price'] = product.standard_price
return res
# Compute Section
@api.multi
@api.depends('product_id', 'qty', 'price_subtotal')
@api.depends('purchase_price', 'qty', 'price_subtotal')
def _compute_multi_margin(self):
for line in self:
if not line.product_id:
line.purchase_price = 0
line.margin = 0
else:
line.purchase_price = line.product_id.standard_price
line.margin = line.price_subtotal - (
line.product_id.standard_price * line.qty)
tmp_margin = line.price_subtotal - (line.purchase_price * line.qty)
line.update({
'margin': tmp_margin,
'margin_percent': (
tmp_margin / line.price_subtotal * 100.0 if
line.price_subtotal else 0.0),
})
# Overload Section. necessary, to manage pos order line creation from
# create_from_ui, because onchange section is not raised
@api.model
def create(self, vals):
if not vals.get('purchase_price', False):
product_obj = self.env['product.product']
product = product_obj.browse(vals.get('product_id'))
vals['purchase_price'] = product.standard_price
return super(PosOrderLine, self).create(vals)

BIN
pos_margin/static/description/pos_order_form.png

Before

Width: 776  |  Height: 419  |  Size: 28 KiB

BIN
pos_margin/static/description/pos_order_form_view.png

After

Width: 926  |  Height: 537  |  Size: 37 KiB

BIN
pos_margin/static/description/pos_order_tree_view.png

After

Width: 1139  |  Height: 105  |  Size: 19 KiB

20
pos_margin/views/view_pos_order.xml

@ -12,12 +12,26 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
<field name="inherit_id" ref="point_of_sale.view_pos_pos_form"/>
<field name="arch" type="xml">
<xpath expr="//group[@name='order_total']" position="after">
<group name="margin">
<field name="margin" widget='monetary'/>
<group name="margin" string="Margin">
<field name="margin" widget="monetary"/>
<field name="margin_percent"/>
</group>
</xpath>
<xpath expr="//field[@name='lines']/tree/field[@name='price_unit']" position="after">
<xpath expr="//field[@name='lines']/tree/field[@name='price_subtotal']" position="before">
<field name="purchase_price"/>
<field name="margin"/>
<field name="margin_percent"/>
</xpath>
</field>
</record>
<record id="view_pos_order_tree" model="ir.ui.view">
<field name="model">pos.order</field>
<field name="inherit_id" ref="point_of_sale.view_pos_order_tree"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='invoice_id']" position="after">
<field name="margin" widget="monetary" sum="Total"/>
<field name="margin_percent"/>
</xpath>
</field>
</record>

Loading…
Cancel
Save