[MIG] sale_margin_no_onchange from v12 to v14

This commit is contained in:
Alexis de Lattre
2025-01-16 17:32:46 +01:00
parent d973ca6740
commit 699ebd5893
6 changed files with 53 additions and 44 deletions

View File

@@ -1,2 +1 @@
from . import sale from . import models
from . import sale_report

View File

@@ -4,12 +4,12 @@
{ {
'name': 'Sale Margin No Onchange', "name": "Sale Margin No Onchange",
'version': '12.0.1.0.0', "version": "14.0.1.0.0",
'category': 'Sales', "category": "Sales",
'license': 'AGPL-3', "license": "AGPL-3",
'summary': 'Copy standard price on sale order line and compute margins', "summary": "Copy standard price on sale order line and compute margins",
'description': """ "description": """
This module copies the field *standard_price* of the product on the sale order line when the sale order line is created and then computes the margin of the sale order and the sale order line (in the currency of the quotation, in the currency of the company and the margin rate). This module copies the field *standard_price* of the product on the sale order line when the sale order line is created and then computes the margin of the sale order and the sale order line (in the currency of the quotation, in the currency of the company and the margin rate).
I decided to develop this module as an alternative to the OCA sale margin modules because I wanted a small and simple module. The module *account_invoice_margin*, available in the same Github repository, do the same thing on customer invoices. I decided to develop this module as an alternative to the OCA sale margin modules because I wanted a small and simple module. The module *account_invoice_margin*, available in the same Github repository, do the same thing on customer invoices.
@@ -17,9 +17,9 @@ I decided to develop this module as an alternative to the OCA sale margin module
This module has been written by Alexis de Lattre from Akretion This module has been written by Alexis de Lattre from Akretion
<alexis.delattre@akretion.com>. <alexis.delattre@akretion.com>.
""", """,
'author': 'Akretion', "author": "Akretion",
'website': 'http://www.akretion.com', "website": "http://www.akretion.com",
'depends': ['sale'], "depends": ["sale"],
'data': ['sale_view.xml'], "data": ["views/sale_view.xml"],
'installable': False, "installable": False,
} }

View File

@@ -0,0 +1,2 @@
from . import sale
from . import sale_report

View File

@@ -4,7 +4,6 @@
from odoo import api, fields, models from odoo import api, fields, models
import odoo.addons.decimal_precision as dp
class SaleOrderLine(models.Model): class SaleOrderLine(models.Model):
@@ -16,23 +15,23 @@ class SaleOrderLine(models.Model):
store=True, string='Company Currency') store=True, string='Company Currency')
standard_price_company_currency = fields.Float( standard_price_company_currency = fields.Float(
string='Cost Price in Company Currency', readonly=True, string='Cost Price in Company Currency', readonly=True,
digits=dp.get_precision('Product Price'), digits="Product Price",
help="Cost price in company currency in the unit of measure " help="Cost price in company currency in the unit of measure "
"of the sale order line") "of the sale order line")
standard_price_sale_currency = fields.Float( standard_price_sale_currency = fields.Float(
string='Cost Price in Sale Currency', readonly=True, string='Cost Price in Sale Currency',
compute='_compute_margin', store=True, compute='_compute_margin', store=True,
digits=dp.get_precision('Product Price'), digits="Product Price",
help="Cost price in sale currency in the unit of measure " help="Cost price in sale currency in the unit of measure "
"of the sale order line") "of the sale order line")
margin_sale_currency = fields.Monetary( margin_sale_currency = fields.Monetary(
string='Margin in Sale Currency', readonly=True, store=True, string='Margin in Sale Currency', store=True,
compute='_compute_margin', currency_field='currency_id') compute='_compute_margin', currency_field='currency_id')
margin_company_currency = fields.Monetary( margin_company_currency = fields.Monetary(
string='Margin in Company Currency', readonly=True, store=True, string='Margin in Company Currency', store=True,
compute='_compute_margin', currency_field='company_currency_id') compute='_compute_margin', currency_field='company_currency_id')
margin_rate = fields.Float( margin_rate = fields.Float(
string="Margin Rate", readonly=True, store=True, string="Margin Rate", store=True,
compute='_compute_margin', compute='_compute_margin',
digits=(16, 2), help="Margin rate in percentage of the sale price") digits=(16, 2), help="Margin rate in percentage of the sale price")
@@ -68,19 +67,20 @@ class SaleOrderLine(models.Model):
line.margin_rate = margin_rate line.margin_rate = margin_rate
# We want to copy standard_price on sale order line # We want to copy standard_price on sale order line
@api.model @api.model_create_multi
def create(self, vals): def create(self, vals_list):
if vals.get('product_id'): for vals in vals_list:
pp = self.env['product.product'].browse(vals['product_id']) if vals.get('product_id'):
std_price = pp.standard_price pp = self.env['product.product'].browse(vals['product_id'])
sale_uom_id = vals.get('product_uom') std_price = pp.standard_price
if sale_uom_id and sale_uom_id != pp.uom_id.id: sale_uom_id = vals.get('product_uom')
sale_uom = self.env['uom.uom'].browse(sale_uom_id) if sale_uom_id and sale_uom_id != pp.uom_id.id:
# convert from product UoM to sale UoM sale_uom = self.env['uom.uom'].browse(sale_uom_id)
std_price = pp.uom_id._compute_price( # convert from product UoM to sale UoM
pp.standard_price, sale_uom) std_price = pp.uom_id._compute_price(
vals['standard_price_company_currency'] = std_price pp.standard_price, sale_uom)
return super(SaleOrderLine, self).create(vals) vals['standard_price_company_currency'] = std_price
return super().create(vals_list)
def write(self, vals): def write(self, vals):
if not vals: if not vals:
@@ -101,7 +101,7 @@ class SaleOrderLine(models.Model):
if sale_uom != pp.uom_id: if sale_uom != pp.uom_id:
std_price = pp.uom_id._compute_price(std_price, sale_uom) std_price = pp.uom_id._compute_price(std_price, sale_uom)
sol.write({'standard_price_company_currency': std_price}) sol.write({'standard_price_company_currency': std_price})
return super(SaleOrderLine, self).write(vals) return super().write(vals)
class SaleOrder(models.Model): class SaleOrder(models.Model):
@@ -114,21 +114,27 @@ class SaleOrder(models.Model):
margin_sale_currency = fields.Monetary( margin_sale_currency = fields.Monetary(
string='Margin in Sale Currency', string='Margin in Sale Currency',
currency_field='currency_id', currency_field='currency_id',
readonly=True, compute='_compute_margin', store=True) compute='_compute_margin', store=True)
margin_company_currency = fields.Monetary( margin_company_currency = fields.Monetary(
string='Margin in Company Currency', string='Margin in Company Currency',
currency_field='company_currency_id', currency_field='company_currency_id',
readonly=True, compute='_compute_margin', store=True) compute='_compute_margin', store=True)
@api.depends( @api.depends(
'order_line.margin_sale_currency', 'order_line.margin_sale_currency',
'order_line.margin_company_currency') 'order_line.margin_company_currency')
def _compute_margin(self): def _compute_margin(self):
rg_res = self.env['sale.order.line'].read_group(
[('order_id', 'in', self.ids)],
['order_id', 'margin_sale_currency:sum', 'margin_company_currency:sum'],
['order_id'])
mapped_data = dict([
(x['order_id'][0], {
'margin_sale_currency': x['margin_sale_currency'],
'margin_company_currency': x['margin_company_currency'],
}) for x in rg_res])
for order in self: for order in self:
margin_sale_cur = 0.0 order.margin_sale_currency = mapped_data.get(
margin_comp_cur = 0.0 order.id, {}).get('margin_sale_currency')
for sol in order.order_line: order.margin_company_currency = mapped_data.get(
margin_sale_cur += sol.margin_sale_currency order.id, {}).get('margin_company_currency')
margin_comp_cur += sol.margin_company_currency
order.margin_sale_currency = margin_sale_cur
order.margin_company_currency = margin_comp_cur

View File

@@ -20,7 +20,8 @@
groups="account.group_account_user"/> groups="account.group_account_user"/>
<field name="company_currency_id" invisible="1"/> <field name="company_currency_id" invisible="1"/>
</group> </group>
<xpath expr="//field[@name='order_line']/form//field[@name='analytic_tag_ids']/.." position="after"> <xpath expr="//field[@name='order_line']/form/group/group//field[@name='analytic_tag_ids']/.." position="after">
<group>
<field name="standard_price_sale_currency" groups="base.group_no_one"/> <field name="standard_price_sale_currency" groups="base.group_no_one"/>
<field name="standard_price_company_currency" groups="base.group_no_one"/> <field name="standard_price_company_currency" groups="base.group_no_one"/>
<field name="margin_sale_currency" groups="base.group_no_one"/> <field name="margin_sale_currency" groups="base.group_no_one"/>
@@ -31,6 +32,7 @@
</div> </div>
<field name="company_currency_id" invisible="1"/> <field name="company_currency_id" invisible="1"/>
<field name="currency_id" invisible="1"/> <field name="currency_id" invisible="1"/>
</group>
</xpath> </xpath>
</field> </field>
</record> </record>