summaryrefslogtreecommitdiff
path: root/addons/mrp_account/models/product.py
diff options
context:
space:
mode:
Diffstat (limited to 'addons/mrp_account/models/product.py')
-rw-r--r--addons/mrp_account/models/product.py87
1 files changed, 87 insertions, 0 deletions
diff --git a/addons/mrp_account/models/product.py b/addons/mrp_account/models/product.py
new file mode 100644
index 00000000..8eb1e010
--- /dev/null
+++ b/addons/mrp_account/models/product.py
@@ -0,0 +1,87 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import api, models, _
+from odoo.exceptions import UserError
+
+
+class ProductTemplate(models.Model):
+ _name = 'product.template'
+ _inherit = 'product.template'
+
+ def action_bom_cost(self):
+ templates = self.filtered(lambda t: t.product_variant_count == 1 and t.bom_count > 0)
+ if templates:
+ return templates.mapped('product_variant_id').action_bom_cost()
+
+ def button_bom_cost(self):
+ templates = self.filtered(lambda t: t.product_variant_count == 1 and t.bom_count > 0)
+ if templates:
+ return templates.mapped('product_variant_id').button_bom_cost()
+
+
+class ProductProduct(models.Model):
+ _name = 'product.product'
+ _inherit = 'product.product'
+ _description = 'Product'
+
+ def button_bom_cost(self):
+ self.ensure_one()
+ self._set_price_from_bom()
+
+ def action_bom_cost(self):
+ boms_to_recompute = self.env['mrp.bom'].search(['|', ('product_id', 'in', self.ids), '&', ('product_id', '=', False), ('product_tmpl_id', 'in', self.mapped('product_tmpl_id').ids)])
+ for product in self:
+ product._set_price_from_bom(boms_to_recompute)
+
+ def _set_price_from_bom(self, boms_to_recompute=False):
+ self.ensure_one()
+ bom = self.env['mrp.bom']._bom_find(product=self)
+ if bom:
+ self.standard_price = self._compute_bom_price(bom, boms_to_recompute=boms_to_recompute)
+
+ def _compute_average_price(self, qty_invoiced, qty_to_invoice, stock_moves):
+ self.ensure_one()
+ if stock_moves.product_id == self:
+ return super()._compute_average_price(qty_invoiced, qty_to_invoice, stock_moves)
+ bom = self.env['mrp.bom']._bom_find(product=self, company_id=stock_moves.company_id.id, bom_type='phantom')
+ if not bom:
+ return super()._compute_average_price(qty_invoiced, qty_to_invoice, stock_moves)
+ dummy, bom_lines = bom.explode(self, 1)
+ bom_lines = {line: data for line, data in bom_lines}
+ value = 0
+ for move in stock_moves:
+ bom_line = move.bom_line_id
+ if bom_line:
+ bom_line_data = bom_lines[bom_line]
+ line_qty = bom_line_data['qty']
+ else:
+ # bom was altered (i.e. bom line removed) after being used
+ line_qty = move.product_qty
+ value += line_qty * move.product_id._compute_average_price(qty_invoiced * line_qty, qty_to_invoice * line_qty, move)
+ return value
+
+ def _compute_bom_price(self, bom, boms_to_recompute=False):
+ self.ensure_one()
+ if not bom:
+ return 0
+ if not boms_to_recompute:
+ boms_to_recompute = []
+ total = 0
+ for opt in bom.operation_ids:
+ duration_expected = (
+ opt.workcenter_id.time_start +
+ opt.workcenter_id.time_stop +
+ opt.time_cycle)
+ total += (duration_expected / 60) * opt.workcenter_id.costs_hour
+ for line in bom.bom_line_ids:
+ if line._skip_bom_line(self):
+ continue
+
+ # Compute recursive if line has `child_line_ids`
+ if line.child_bom_id and line.child_bom_id in boms_to_recompute:
+ child_total = line.product_id._compute_bom_price(line.child_bom_id, boms_to_recompute=boms_to_recompute)
+ total += line.product_id.uom_id._compute_price(child_total, line.product_uom_id) * line.product_qty
+ else:
+ total += line.product_id.uom_id._compute_price(line.product_id.standard_price, line.product_uom_id) * line.product_qty
+ return bom.product_uom_id._compute_price(total / bom.product_qty, self.uom_id)