# -*- coding: utf-8 -*- # Part of Odoo, Flectra. See LICENSE file for full copyright and licensing details. from flectra import api, fields, models from flectra.tools import float_compare class SaleOrderLine(models.Model): _inherit = 'sale.order.line' @api.multi def _get_delivered_qty(self): self.ensure_one() # In the case of a kit, we need to check if all components are shipped. Since the BOM might # have changed, we don't compute the quantities but verify the move state. bom = self.env['mrp.bom']._bom_find(product=self.product_id) if bom and bom.type == 'phantom': bom_delivered = all([move.state == 'done' for move in self.move_ids]) if bom_delivered: return self.product_uom_qty else: return 0.0 return super(SaleOrderLine, self)._get_delivered_qty() @api.multi def _get_bom_component_qty(self, bom): bom_quantity = self.product_uom._compute_quantity(self.product_uom_qty, bom.product_uom_id) boms, lines = bom.explode(self.product_id, bom_quantity) components = {} for line, line_data in lines: product = line.product_id.id uom = line.product_uom_id qty = line.product_qty if components.get(product, False): if uom.id != components[product]['uom']: from_uom = uom to_uom = self.env['product.uom'].browse(components[product]['uom']) qty = from_uom._compute_quantity(qty, to_uom) components[product]['qty'] += qty else: # To be in the uom reference of the product to_uom = self.env['product.product'].browse(product).uom_id if uom.id != to_uom.id: from_uom = uom qty = from_uom._compute_quantity(qty, to_uom) components[product] = {'qty': qty, 'uom': to_uom.id} return components class AccountInvoiceLine(models.Model): # TDE FIXME: what is this code ?? _inherit = "account.invoice.line" def _get_anglo_saxon_price_unit(self): price_unit = super(AccountInvoiceLine, self)._get_anglo_saxon_price_unit() # in case of anglo saxon with a product configured as invoiced based on delivery, with perpetual # valuation and real price costing method, we must find the real price for the cost of good sold if self.product_id.invoice_policy == "delivery": for s_line in self.sale_line_ids: # qtys already invoiced qty_done = sum([x.uom_id._compute_quantity(x.quantity, x.product_id.uom_id) for x in s_line.invoice_lines if x.invoice_id.state in ('open', 'paid')]) quantity = self.uom_id._compute_quantity(self.quantity, self.product_id.uom_id) # Put moves in fixed order by date executed moves = s_line.move_ids.sorted(lambda x: x.date) # Go through all the moves and do nothing until you get to qty_done # Beyond qty_done we need to calculate the average of the price_unit # on the moves we encounter. bom = s_line.product_id.product_tmpl_id.bom_ids and s_line.product_id.product_tmpl_id.bom_ids[0] if bom.type == 'phantom': average_price_unit = 0 components = s_line._get_bom_component_qty(bom) for product_id in components: factor = components[product_id]['qty'] prod_moves = [m for m in moves if m.product_id.id == product_id] prod_qty_done = factor * qty_done prod_quantity = factor * quantity average_price_unit += factor * self._compute_average_price(prod_qty_done, prod_quantity, prod_moves) price_unit = average_price_unit or price_unit price_unit = self.product_id.uom_id._compute_price(price_unit, self.uom_id) return price_unit