diff --git a/sale_sourced_by_line/__manifest__.py b/sale_sourced_by_line/__manifest__.py index ba372277..3281fd86 100644 --- a/sale_sourced_by_line/__manifest__.py +++ b/sale_sourced_by_line/__manifest__.py @@ -1,7 +1,7 @@ { 'name': 'Sale Sourced by Line', 'summary': 'Multiple warehouse source locations for Sale order', - 'version': '13.0.1.0.0', + 'version': '14.0.1.0.0', 'author': "Hibou Corp.,Odoo Community Association (OCA)", 'category': 'Warehouse', 'license': 'AGPL-3', diff --git a/sale_sourced_by_line/models/sale.py b/sale_sourced_by_line/models/sale.py index 29c903ad..63d58386 100644 --- a/sale_sourced_by_line/models/sale.py +++ b/sale_sourced_by_line/models/sale.py @@ -12,10 +12,10 @@ class SaleOrder(models.Model): class SaleOrderLine(models.Model): _inherit = 'sale.order.line' - # In 13, this field exists, but isn't stored and is computed during - # computation for available inventory (set to order's warehouse) + # In 14, this field exists, but isn't stored and is merely related to the + # order's warehouse_id, it is only used in computation of availability warehouse_id = fields.Many2one('stock.warehouse', string='Warehouse', - compute=None, store=True) + compute=None, related=None, store=True) date_planned = fields.Datetime('Planned Date') def _prepare_procurement_values(self, group_id=False): @@ -29,30 +29,41 @@ class SaleOrderLine(models.Model): return vals # Needs modifications to not actually set a warehouse on the line as it is now stored - @api.depends('product_id', 'customer_lead', 'product_uom_qty', 'product_uom', 'order_id.warehouse_id', 'order_id.commitment_date') + @api.depends( + 'product_id', 'customer_lead', 'product_uom_qty', 'product_uom', 'order_id.commitment_date', + 'move_ids', 'move_ids.forecast_expected_date', 'move_ids.forecast_availability') def _compute_qty_at_date(self): """ Compute the quantity forecasted of product at delivery date. There are two cases: 1. The quotation has a commitment_date, we take it as delivery date 2. The quotation hasn't commitment_date, we compute the estimated delivery date based on lead time""" + treated = self.browse() + # If the state is already in sale the picking is created and a simple forecasted quantity isn't enough + # Then used the forecasted data of the related stock.move + for line in self.filtered(lambda l: l.state == 'sale'): + if not line.display_qty_widget: + continue + moves = line.move_ids + line.forecast_expected_date = max(moves.filtered("forecast_expected_date").mapped("forecast_expected_date"), default=False) + line.qty_available_today = 0 + line.virtual_available_at_date = 0 + for move in moves: + line.qty_available_today += move.product_uom._compute_quantity(move.reserved_availability, line.product_uom) + line.virtual_available_at_date += move.product_id.uom_id._compute_quantity(move.forecast_availability, line.product_uom) + line.scheduled_date = line.order_id.commitment_date or line._expected_date() + line.free_qty_today = False + treated |= line + qty_processed_per_product = defaultdict(lambda: 0) grouped_lines = defaultdict(lambda: self.env['sale.order.line']) # We first loop over the SO lines to group them by warehouse and schedule # date in order to batch the read of the quantities computed field. - for line in self: + for line in self.filtered(lambda l: l.state in ('draft', 'sent')): if not (line.product_id and line.display_qty_widget): continue - # use warehouse from line or order - warehouse = line.warehouse_id or line.order_id.warehouse_id - # line.warehouse_id = line.order_id.warehouse_id - if line.order_id.commitment_date: - date = line.order_id.commitment_date - else: - date = line._expected_date() - grouped_lines[(warehouse, date)] |= line + grouped_lines[(line.warehouse_id.id or line.order_id.warehouse_id.id, line.order_id.commitment_date or line._expected_date())] |= line - treated = self.browse() for (warehouse, scheduled_date), lines in grouped_lines.items(): product_qties = lines.mapped('product_id').with_context(to_date=scheduled_date, warehouse=warehouse).read([ 'qty_available', @@ -69,6 +80,7 @@ class SaleOrderLine(models.Model): line.qty_available_today = qty_available_today - qty_processed_per_product[line.product_id.id] line.free_qty_today = free_qty_today - qty_processed_per_product[line.product_id.id] line.virtual_available_at_date = virtual_available_at_date - qty_processed_per_product[line.product_id.id] + line.forecast_expected_date = False if line.product_uom and line.product_id.uom_id and line.product_uom != line.product_id.uom_id: line.qty_available_today = line.product_id.uom_id._compute_quantity(line.qty_available_today, line.product_uom) line.free_qty_today = line.product_id.uom_id._compute_quantity(line.free_qty_today, line.product_uom) @@ -78,7 +90,6 @@ class SaleOrderLine(models.Model): remaining = (self - treated) remaining.virtual_available_at_date = False remaining.scheduled_date = False + remaining.forecast_expected_date = False remaining.free_qty_today = False remaining.qty_available_today = False - # don't unset warehouse as it may be set by hand - # remaining.warehouse_id = False