@@ -1,4 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import sale_margin
|
||||
import models
|
||||
import report
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
{
|
||||
@@ -11,11 +12,7 @@ This module adds the 'Margin' on sales order.
|
||||
This gives the profitability by calculating the difference between the Unit
|
||||
Price and Cost Price.
|
||||
""",
|
||||
'author':'OpenERP SA',
|
||||
'depends':['sale'],
|
||||
'demo':['sale_margin_demo.xml'],
|
||||
'test': ['test/sale_margin.yml'],
|
||||
'data':['security/ir.model.access.csv','sale_margin_view.xml'],
|
||||
'auto_install': False,
|
||||
'installable': True,
|
||||
'demo':['data/sale_margin_demo.xml'],
|
||||
'data':['security/ir.model.access.csv','views/sale_margin_view.xml'],
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<odoo>
|
||||
<data noupdate="1">
|
||||
|
||||
<record id="sale.sale_order_line_1" model="sale.order.line">
|
||||
@@ -43,4 +43,4 @@
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</odoo>
|
||||
@@ -0,0 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import sale_order
|
||||
@@ -0,0 +1,44 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models
|
||||
import odoo.addons.decimal_precision as dp
|
||||
|
||||
|
||||
class SaleOrderLine(models.Model):
|
||||
_inherit = "sale.order.line"
|
||||
|
||||
margin = fields.Float(compute='_product_margin', digits=dp.get_precision('Product Price'), store=True)
|
||||
purchase_price = fields.Float(string='Cost', digits=dp.get_precision('Product Price'))
|
||||
|
||||
@api.multi
|
||||
@api.onchange('product_id', 'product_uom_qty')
|
||||
def product_id_change_margin(self):
|
||||
for line in self:
|
||||
if line.order_id.pricelist_id:
|
||||
frm_cur = self.env.user.company_id.currency_id
|
||||
to_cur = line.order_id.pricelist_id.currency_id
|
||||
purchase_price = line.product_id.standard_price
|
||||
if line.product_uom != line.product_id.uom_id:
|
||||
purchase_price = self.env['product.uom']._compute_price(line.product_id.uom_id.id, purchase_price, to_uom_id=line.product_uom.id)
|
||||
ctx = self.env.context.copy()
|
||||
ctx['date'] = line.order_id.date_order
|
||||
price = frm_cur.with_context(ctx).compute(purchase_price, to_cur, round=False)
|
||||
line.purchase_price = price
|
||||
|
||||
@api.depends('product_id', 'purchase_price', 'product_uom_qty', 'price_unit')
|
||||
def _product_margin(self):
|
||||
for line in self:
|
||||
currency = line.order_id.pricelist_id.currency_id
|
||||
line.margin = currency.round(line.price_subtotal - ((line.purchase_price or line.product_id.standard_price) * line.product_uom_qty))
|
||||
|
||||
|
||||
class SaleOrder(models.Model):
|
||||
_inherit = "sale.order"
|
||||
|
||||
margin = fields.Monetary(compute='_product_margin', help="It gives profitability by calculating the difference between the Unit Price and the cost.", currency_field='currency_id', digits=dp.get_precision('Product Price'), store=True)
|
||||
|
||||
@api.depends('order_line.margin')
|
||||
def _product_margin(self):
|
||||
for order in self:
|
||||
order.margin = sum(order.order_line.filtered(lambda r: r.state != 'cancel').mapped('margin'))
|
||||
@@ -1,3 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import sale_report
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from openerp import models, fields
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class sale_report(models.Model):
|
||||
class SaleReport(models.Model):
|
||||
_inherit = 'sale.report'
|
||||
|
||||
margin = fields.Float('Margin')
|
||||
|
||||
def _select(self):
|
||||
return super(sale_report, self)._select() + ", SUM(l.margin) AS margin"
|
||||
return super(SaleReport, self)._select() + ", SUM(l.margin) AS margin"
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from openerp import api
|
||||
from openerp.osv import fields, osv
|
||||
import openerp.addons.decimal_precision as dp
|
||||
|
||||
class sale_order_line(osv.osv):
|
||||
_inherit = "sale.order.line"
|
||||
|
||||
@api.multi
|
||||
@api.onchange('product_id', 'product_uom_qty')
|
||||
def product_id_change_margin(self):
|
||||
for line in self:
|
||||
if line.order_id.pricelist_id:
|
||||
frm_cur = self.env.user.company_id.currency_id
|
||||
to_cur = line.order_id.pricelist_id.currency_id
|
||||
purchase_price = line.product_id.standard_price
|
||||
if line.product_uom != line.product_id.uom_id:
|
||||
purchase_price = self.env['product.uom']._compute_price(line.product_id.uom_id.id, purchase_price, to_uom_id=line.product_uom.id)
|
||||
ctx = self.env.context.copy()
|
||||
ctx['date'] = line.order_id.date_order
|
||||
price = frm_cur.with_context(ctx).compute(purchase_price, to_cur, round=False)
|
||||
line.purchase_price = price
|
||||
|
||||
def _product_margin(self, cr, uid, ids, field_name, arg, context=None):
|
||||
cur_obj = self.pool.get('res.currency')
|
||||
res = {}
|
||||
for line in self.browse(cr, uid, ids, context=context):
|
||||
cur = line.order_id.pricelist_id.currency_id
|
||||
res[line.id] = 0
|
||||
if line.product_id:
|
||||
tmp_margin = line.price_subtotal - ((line.purchase_price or line.product_id.standard_price) * line.product_uom_qty)
|
||||
res[line.id] = cur_obj.round(cr, uid, cur, tmp_margin)
|
||||
return res
|
||||
|
||||
_columns = {
|
||||
'margin': fields.function(_product_margin, string='Margin', digits_compute= dp.get_precision('Product Price'),
|
||||
store = True),
|
||||
'purchase_price': fields.float('Cost', digits_compute= dp.get_precision('Product Price'))
|
||||
}
|
||||
|
||||
|
||||
class sale_order(osv.osv):
|
||||
_inherit = "sale.order"
|
||||
|
||||
def _product_margin(self, cr, uid, ids, field_name, arg, context=None):
|
||||
result = {}
|
||||
for sale in self.browse(cr, uid, ids, context=context):
|
||||
result[sale.id] = 0.0
|
||||
for line in sale.order_line:
|
||||
if line.state == 'cancel':
|
||||
continue
|
||||
result[sale.id] += line.margin or 0.0
|
||||
return result
|
||||
|
||||
def _get_order(self, cr, uid, ids, context=None):
|
||||
result = {}
|
||||
for line in self.pool.get('sale.order.line').browse(cr, uid, ids, context=context):
|
||||
result[line.order_id.id] = True
|
||||
return result.keys()
|
||||
|
||||
_columns = {
|
||||
'margin': fields.function(_product_margin, string='Margin', help="It gives profitability by calculating the difference between the Unit Price and the cost.", store={
|
||||
'sale.order.line': (_get_order, ['margin', 'purchase_price'], 20),
|
||||
'sale.order': (lambda self, cr, uid, ids, c={}: ids, ['order_line'], 20),
|
||||
}, digits_compute= dp.get_precision('Product Price')),
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
-
|
||||
In order to test the sale_margin module in OpenERP,
|
||||
I create a sale order and verify its margin
|
||||
-
|
||||
I place a sale order for product keyboard, quantity 50
|
||||
-
|
||||
!record {model: sale.order, id: sale_order_so11}:
|
||||
date_order: !eval time.strftime('%Y-%m-%d')
|
||||
name: Test_SO011
|
||||
order_line:
|
||||
- name: '[CARD] Graphics Card'
|
||||
price_unit: 7.0
|
||||
product_uom: product.product_uom_unit
|
||||
product_uom_qty: 100.0
|
||||
state: draft
|
||||
product_id: product.product_product_24
|
||||
partner_id: base.res_partner_4
|
||||
partner_invoice_id: base.res_partner_address_7
|
||||
partner_shipping_id: base.res_partner_address_7
|
||||
pricelist_id: product.list0
|
||||
-
|
||||
I confirm the sale order
|
||||
-
|
||||
!python {model: sale.order}: |
|
||||
self.action_confirm(cr, uid, [ref("sale_order_so11")], context=context)
|
||||
-
|
||||
I verify that margin field gets bind with the value
|
||||
-
|
||||
!python {model: sale.order}: |
|
||||
so = self.browse(cr, uid, ref("sale_order_so11"))
|
||||
assert so.margin, "No margin !"
|
||||
@@ -0,0 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import test_sale_margin
|
||||
@@ -0,0 +1,41 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.tests import common
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class TestSaleMargin(common.TransactionCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestSaleMargin, self).setUp()
|
||||
self.SaleOrder = self.env['sale.order']
|
||||
|
||||
self.product_uom_id = self.ref('product.product_uom_unit')
|
||||
self.product_id = self.ref('product.product_product_24')
|
||||
self.partner_id = self.ref('base.res_partner_4')
|
||||
self.partner_invoice_address_id = self.ref('base.res_partner_address_7')
|
||||
self.pricelist_id = self.ref('product.list0')
|
||||
|
||||
def test_sale_margin(self):
|
||||
""" Test the sale_margin module in Odoo. """
|
||||
# Create a sale order for product Graphics Card.
|
||||
sale_order_so11 = self.SaleOrder.create({
|
||||
'date_order': datetime.today(),
|
||||
'name': 'Test_SO011',
|
||||
'order_line': [(0, 0, {
|
||||
'name': '[CARD] Graphics Card',
|
||||
'purchase_price': 700.0,
|
||||
'price_unit': 1000.0,
|
||||
'product_uom': self.product_uom_id,
|
||||
'product_uom_qty': 10.0,
|
||||
'state': 'draft',
|
||||
'product_id': self.product_id})],
|
||||
'partner_id': self.partner_id,
|
||||
'partner_invoice_id': self.partner_invoice_address_id,
|
||||
'partner_shipping_id': self.partner_invoice_address_id,
|
||||
'pricelist_id': self.pricelist_id})
|
||||
# Confirm the sale order.
|
||||
sale_order_so11.action_confirm()
|
||||
# Verify that margin field gets bind with the value.
|
||||
self.assertEqual(sale_order_so11.margin, 3000.00, "Sale order margin should be 3000.00")
|
||||
+3
-5
@@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<odoo>
|
||||
|
||||
<record model="ir.ui.view" id="sale_margin_sale_order">
|
||||
<field name="name">sale.order.margin.view.form</field>
|
||||
@@ -9,7 +8,7 @@
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//group[@name='sale_total']" position="after">
|
||||
<group name="sale_margin_grp">
|
||||
<field name="margin" widget='monetary' options="{'currency_field': 'currency_id'}" groups="base.group_user"/>
|
||||
<field name="margin" groups="base.group_user"/>
|
||||
</group>
|
||||
</xpath>
|
||||
</field>
|
||||
@@ -37,5 +36,4 @@
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user