summaryrefslogtreecommitdiff
path: root/addons/sale_margin/models
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/sale_margin/models
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/sale_margin/models')
-rw-r--r--addons/sale_margin/models/__init__.py4
-rw-r--r--addons/sale_margin/models/sale_order.py84
2 files changed, 88 insertions, 0 deletions
diff --git a/addons/sale_margin/models/__init__.py b/addons/sale_margin/models/__init__.py
new file mode 100644
index 00000000..00b62d54
--- /dev/null
+++ b/addons/sale_margin/models/__init__.py
@@ -0,0 +1,4 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from . import sale_order
diff --git a/addons/sale_margin/models/sale_order.py b/addons/sale_margin/models/sale_order.py
new file mode 100644
index 00000000..4749b088
--- /dev/null
+++ b/addons/sale_margin/models/sale_order.py
@@ -0,0 +1,84 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+from odoo import api, fields, models
+
+
+class SaleOrderLine(models.Model):
+ _inherit = "sale.order.line"
+
+ margin = fields.Float(
+ "Margin", compute='_compute_margin',
+ digits='Product Price', store=True, groups="base.group_user")
+ margin_percent = fields.Float(
+ "Margin (%)", compute='_compute_margin', store=True, groups="base.group_user")
+ purchase_price = fields.Float(
+ string='Cost', compute="_compute_purchase_price",
+ digits='Product Price', store=True, readonly=False,
+ groups="base.group_user")
+
+ @api.depends('product_id', 'company_id', 'currency_id', 'product_uom')
+ def _compute_purchase_price(self):
+ for line in self:
+ if not line.product_id:
+ line.purchase_price = 0.0
+ continue
+ line = line.with_company(line.company_id)
+ product = line.product_id
+ product_cost = product.standard_price
+ if not product_cost:
+ # If the standard_price is 0
+ # Avoid unnecessary computations
+ # and currency conversions
+ if not line.purchase_price:
+ line.purchase_price = 0.0
+ continue
+ fro_cur = product.cost_currency_id
+ to_cur = line.currency_id or line.order_id.currency_id
+ if line.product_uom and line.product_uom != product.uom_id:
+ product_cost = product.uom_id._compute_price(
+ product_cost,
+ line.product_uom,
+ )
+ line.purchase_price = fro_cur._convert(
+ from_amount=product_cost,
+ to_currency=to_cur,
+ company=line.company_id or self.env.company,
+ date=line.order_id.date_order or fields.Date.today(),
+ round=False,
+ ) if to_cur and product_cost else product_cost
+ # The pricelist may not have been set, therefore no conversion
+ # is needed because we don't know the target currency..
+
+ @api.depends('price_subtotal', 'product_uom_qty', 'purchase_price')
+ def _compute_margin(self):
+ for line in self:
+ line.margin = line.price_subtotal - (line.purchase_price * line.product_uom_qty)
+ line.margin_percent = line.price_subtotal and line.margin/line.price_subtotal
+
+
+class SaleOrder(models.Model):
+ _inherit = "sale.order"
+
+ margin = fields.Monetary("Margin", compute='_compute_margin', store=True)
+ margin_percent = fields.Float("Margin (%)", compute='_compute_margin', store=True)
+
+ @api.depends('order_line.margin', 'amount_untaxed')
+ def _compute_margin(self):
+ if not all(self._ids):
+ for order in self:
+ order.margin = sum(order.order_line.mapped('margin'))
+ order.margin_percent = order.amount_untaxed and order.margin/order.amount_untaxed
+ else:
+ self.env["sale.order.line"].flush(['margin'])
+ # On batch records recomputation (e.g. at install), compute the margins
+ # with a single read_group query for better performance.
+ # This isn't done in an onchange environment because (part of) the data
+ # may not be stored in database (new records or unsaved modifications).
+ grouped_order_lines_data = self.env['sale.order.line'].read_group(
+ [
+ ('order_id', 'in', self.ids),
+ ], ['margin', 'order_id'], ['order_id'])
+ mapped_data = {m['order_id'][0]: m['margin'] for m in grouped_order_lines_data}
+ for order in self:
+ order.margin = mapped_data.get(order.id, 0.0)
+ order.margin_percent = order.amount_untaxed and order.margin/order.amount_untaxed