[IMP] stock, purchase_stock: remove security lead time from picking deadline

Remove the Purchase Security Lead Time from the computing of the
purchase order's picking deadline to better reflect that the shipment is
actually meant to arrive earlier than date + security lead time.

Also makes sure that receipts and subsequent pickings (multi-step
reception) are planned the earliest possible, not taking the purchase
security lead time into account.

Task-2656397

Part-of: odoo/odoo#79523
This commit is contained in:
clesgow
2021-11-09 14:46:13 +00:00
parent 1b6ac16f67
commit a2e706edf7
7 changed files with 27 additions and 21 deletions
@@ -346,7 +346,7 @@ msgstr ""
#. module: purchase_stock
#: model_terms:ir.ui.view,arch_db:purchase_stock.res_config_settings_view_form_stock
msgid "Move forward expected delivery dates by"
msgid "Move forward expected request creation date by"
msgstr ""
#. module: purchase_stock
@@ -545,7 +545,7 @@ msgstr ""
#. module: purchase_stock
#: model_terms:ir.ui.view,arch_db:purchase_stock.res_config_settings_view_form_stock
msgid "Schedule receivings earlier to avoid delays"
msgid "Schedule automatically generated request for quotations earlier to avoid delays"
msgstr ""
#. module: purchase_stock
+2 -2
View File
@@ -389,7 +389,7 @@ class PurchaseOrderLine(models.Model):
if not moves_to_update:
moves_to_update = self.move_dest_ids.filtered(lambda m: m.state not in ('done', 'cancel'))
for move in moves_to_update:
move.date_deadline = new_date + relativedelta(days=move.company_id.po_lead)
move.date_deadline = new_date
def _create_or_update_picking(self):
for line in self:
@@ -498,7 +498,7 @@ class PurchaseOrderLine(models.Model):
'name': (self.name or '')[:2000],
'product_id': self.product_id.id,
'date': date_planned,
'date_deadline': date_planned + relativedelta(days=self.order_id.company_id.po_lead),
'date_deadline': date_planned,
'location_id': self.order_id.partner_id.property_stock_supplier.id,
'location_dest_id': (self.orderpoint_id and not (self.move_ids | self.move_dest_ids)) and self.orderpoint_id.location_id.id or self.order_id._get_destination_location(),
'picking_id': picking.id,
+6 -1
View File
@@ -3,7 +3,7 @@
from odoo import api, fields, models, _
from odoo.tools.float_utils import float_round
from dateutil.relativedelta import relativedelta
class StockPicking(models.Model):
_inherit = 'stock.picking'
@@ -268,6 +268,11 @@ class Orderpoint(models.Model):
orderpoint_wh_supplier.route_id = route_id[0].id
return super()._set_default_route_id()
def _get_orderpoint_procurement_date(self):
date = super()._get_orderpoint_procurement_date()
date -= relativedelta(days=self.company_id.po_lead)
return date
class ProductionLot(models.Model):
_inherit = 'stock.production.lot'
+3 -5
View File
@@ -49,7 +49,6 @@ class StockRule(models.Model):
# Get the schedule date in order to find a valid seller
procurement_date_planned = fields.Datetime.from_string(procurement.values['date_planned'])
schedule_date = (procurement_date_planned - relativedelta(days=procurement.company_id.po_lead))
supplier = False
if procurement.values.get('supplierinfo_id'):
@@ -58,7 +57,7 @@ class StockRule(models.Model):
supplier = procurement.product_id.with_company(procurement.company_id.id)._select_seller(
partner_id=procurement.values.get("supplierinfo_name"),
quantity=procurement.product_qty,
date=schedule_date.date(),
date=procurement_date_planned.date(),
uom_id=procurement.product_uom)
# Fall back on a supplier for which no price may be defined. Not ideal, but better than
@@ -261,7 +260,6 @@ class StockRule(models.Model):
dates = [fields.Datetime.from_string(value['date_planned']) for value in values]
procurement_date_planned = min(dates)
schedule_date = (procurement_date_planned - relativedelta(days=company_id.po_lead))
supplier_delay = max([int(value['supplier'].delay) for value in values])
# Since the procurements are grouped if they share the same domain for
@@ -270,7 +268,7 @@ class StockRule(models.Model):
# arbitrary procurement. In this case the first.
values = values[0]
partner = values['supplier'].partner_id
purchase_date = schedule_date - relativedelta(days=supplier_delay)
purchase_date = procurement_date_planned - relativedelta(days=supplier_delay)
fpos = self.env['account.fiscal.position'].with_company(company_id).get_fiscal_position(partner.id)
@@ -305,7 +303,7 @@ class StockRule(models.Model):
('user_id', '=', False),
)
if values.get('orderpoint_id'):
procurement_date = fields.Date.to_date(values['date_planned']) - relativedelta(days=int(values['supplier'].delay) + company_id.po_lead)
procurement_date = fields.Date.to_date(values['date_planned']) - relativedelta(days=int(values['supplier'].delay))
delta_days = int(self.env['ir.config_parameter'].get_param('purchase_stock.delta_days_merge') or 0)
domain += (
('date_order', '<=', datetime.combine(procurement_date + relativedelta(days=delta_days), datetime.max.time())),
@@ -29,11 +29,11 @@ class TestPurchaseLeadTime(PurchaseTestCommon):
purchase.button_confirm()
# Check order date of purchase order
order_date = fields.Datetime.from_string(date_planned) - timedelta(days=company.po_lead) - timedelta(days=self.product_1.seller_ids.delay)
order_date = fields.Datetime.from_string(date_planned) - timedelta(days=self.product_1.seller_ids.delay)
self.assertEqual(purchase.date_order, order_date, 'Order date should be equal to: Date of the procurement order - Purchase Lead Time - Delivery Lead Time.')
# Check scheduled date of purchase order
schedule_date = datetime.combine(order_date + timedelta(days=self.product_1.seller_ids.delay), time.min).replace(tzinfo=None, hour=12)
schedule_date = order_date + timedelta(days=self.product_1.seller_ids.delay)
self.assertEqual(purchase.order_line.date_planned, schedule_date, 'Schedule date should be equal to: Order date of Purchase order + Delivery Lead Time.')
# check the picking created or not
@@ -41,7 +41,7 @@ class TestPurchaseLeadTime(PurchaseTestCommon):
# Check scheduled and deadline date of In Type shipment
self.assertEqual(purchase.picking_ids.scheduled_date, schedule_date, 'Schedule date of In type shipment should be equal to: schedule date of purchase order.')
self.assertEqual(purchase.picking_ids.date_deadline, schedule_date + timedelta(days=company.po_lead), 'Deadline date of should be equal to: schedule date of purchase order + lead_po.')
self.assertEqual(purchase.picking_ids.date_deadline, schedule_date, 'Deadline date of should be equal to: schedule date of purchase order.')
def test_01_product_level_delay(self):
""" To check schedule dates of multiple purchase order line of the same purchase order,
@@ -74,11 +74,11 @@ class TestPurchaseLeadTime(PurchaseTestCommon):
self.assertEqual(purchase2.date_order, order_date, 'Order date should be equal to: Date of the procurement order - Delivery Lead Time.')
# Check scheduled date of purchase order line for product_1
schedule_date_1 = datetime.combine(order_date + timedelta(days=self.product_1.seller_ids.delay), time.min).replace(tzinfo=None, hour=12)
schedule_date_1 = order_date + timedelta(days=self.product_1.seller_ids.delay)
self.assertEqual(order_line_pro_1.date_planned, schedule_date_1, 'Schedule date of purchase order line for product_1 should be equal to: Order date of purchase order + Delivery Lead Time of product_1.')
# Check scheduled date of purchase order line for product_2
schedule_date_2 = datetime.combine(order_date + timedelta(days=self.product_2.seller_ids.delay), time.min).replace(tzinfo=None, hour=12)
schedule_date_2 = order_date + timedelta(days=self.product_2.seller_ids.delay)
self.assertEqual(order_line_pro_2.date_planned, schedule_date_2, 'Schedule date of purchase order line for product_2 should be equal to: Order date of purchase order + Delivery Lead Time of product_2.')
# Check scheduled date of purchase order
@@ -133,11 +133,11 @@ class TestPurchaseLeadTime(PurchaseTestCommon):
purchase.button_confirm()
# Check order date of purchase order
order_date = fields.Datetime.from_string(date_planned) - timedelta(days=self.product_1.seller_ids.delay + rule_delay + company.po_lead)
order_date = fields.Datetime.from_string(date_planned) - timedelta(days=self.product_1.seller_ids.delay + rule_delay)
self.assertEqual(purchase.date_order, order_date, 'Order date should be equal to: Date of the procurement order - Delivery Lead Time(supplier and pull rules).')
# Check scheduled date of purchase order
schedule_date = order_date + timedelta(days=self.product_1.seller_ids.delay + rule_delay + company.po_lead)
schedule_date = order_date + timedelta(days=self.product_1.seller_ids.delay + rule_delay)
self.assertEqual(date_planned, str(schedule_date), 'Schedule date should be equal to: Order date of Purchase order + Delivery Lead Time(supplier and pull rules).')
# Check the picking crated or not
@@ -145,7 +145,7 @@ class TestPurchaseLeadTime(PurchaseTestCommon):
# Check scheduled date of Internal Type shipment
incoming_shipment1 = self.env['stock.picking'].search([('move_ids.product_id', 'in', (self.product_1.id, self.product_2.id)), ('picking_type_id', '=', self.warehouse_1.int_type_id.id), ('location_id', '=', self.warehouse_1.wh_input_stock_loc_id.id), ('location_dest_id', '=', self.warehouse_1.wh_qc_stock_loc_id.id)])
incoming_shipment1_date = order_date + timedelta(days=self.product_1.seller_ids.delay + company.po_lead)
incoming_shipment1_date = order_date + timedelta(days=self.product_1.seller_ids.delay)
self.assertEqual(incoming_shipment1.scheduled_date, incoming_shipment1_date, 'Schedule date of Internal Type shipment for input stock location should be equal to: schedule date of purchase order + push rule delay.')
self.assertEqual(incoming_shipment1.date_deadline, incoming_shipment1_date)
old_deadline1 = incoming_shipment1.date_deadline
@@ -48,11 +48,11 @@
<a href="https://www.odoo.com/documentation/15.0/applications/inventory_and_mrp/inventory/management/planning/scheduled_dates.html" title="Documentation" class="mr-2 o_doc_link" target="_blank"></a>
<span class="fa fa-lg fa-building-o" title="Values set here are company-specific." groups="base.group_multi_company"/>
<div class="text-muted">
Schedule receivings earlier to avoid delays
Schedule automatically generated request for quotations earlier to avoid delays
</div>
<div class="content-group">
<div class="mt16" attrs="{'invisible': [('use_po_lead','=',False)]}">
<span>Move forward expected delivery dates by <field name="po_lead" class="oe_inline"/> days</span>
<span>Move forward expected request creation date by <field name="po_lead" class="oe_inline"/> days</span>
</div>
</div>
</div>
+4 -1
View File
@@ -498,7 +498,7 @@ class StockWarehouseOrderpoint(models.Model):
else:
origin = orderpoint.name
if float_compare(orderpoint.qty_to_order, 0.0, precision_rounding=orderpoint.product_uom.rounding) == 1:
date = datetime.combine(orderpoint.lead_days_date, time.min)
date = orderpoint._get_orderpoint_procurement_date()
values = orderpoint._prepare_procurement_values(date=date)
procurements.append(self.env['procurement.group'].Procurement(
orderpoint.product_id, orderpoint.qty_to_order, orderpoint.product_uom,
@@ -551,3 +551,6 @@ class StockWarehouseOrderpoint(models.Model):
def _post_process_scheduler(self):
return True
def _get_orderpoint_procurement_date(self):
return datetime.combine(self.lead_days_date, time.min)