sale_stock/tests/test_sale_stock_lead_time.py

241 lines
13 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo.addons.stock_account.tests.test_anglo_saxon_valuation_reconciliation_common import ValuationReconciliationTestCommon
from odoo.addons.sale.tests.common import TestSaleCommon
from odoo import fields
from odoo.tests import tagged
from datetime import timedelta
@tagged('post_install', '-at_install')
class TestSaleStockLeadTime(TestSaleCommon, ValuationReconciliationTestCommon):
@classmethod
def setUpClass(cls, chart_template_ref=None):
super().setUpClass(chart_template_ref=chart_template_ref)
# Update the product_1 with type and Customer Lead Time
cls.test_product_order.sale_delay = 5.0
def test_00_product_company_level_delays(self):
""" In order to check schedule date, set product's Customer Lead Time
and company's Sales Safety Days."""
# Update company with Sales Safety Days
self.env.company.security_lead = 3.00
# Create sale order of product_1
order = self.env['sale.order'].create({
'partner_id': self.partner_a.id,
'pricelist_id': self.company_data['default_pricelist'].id,
'picking_policy': 'direct',
'warehouse_id': self.company_data['default_warehouse'].id,
'order_line': [(0, 0, {
'product_id': self.test_product_order.id,
'product_uom_qty': 10,
'product_uom': self.env.ref('uom.product_uom_unit').id,
})]
})
self.assertEqual(order.order_line.customer_lead, self.test_product_order.sale_delay)
# Confirm our standard sale order
order.action_confirm()
# Check the picking crated or not
self.assertTrue(order.picking_ids, "Picking should be created.")
# Check schedule date of picking
out_date = order.date_order + timedelta(days=self.test_product_order.sale_delay) - timedelta(days=self.env.company.security_lead)
min_date = order.picking_ids[0].scheduled_date
self.assertTrue(abs(min_date - out_date) <= timedelta(seconds=1), 'Schedule date of picking should be equal to: order date + Customer Lead Time - Sales Safety Days.')
def test_01_product_route_level_delays(self):
""" In order to check schedule dates, set product's Customer Lead Time
and warehouse route's delay."""
# Update warehouse_1 with Outgoing Shippings pick + pack + ship
self.company_data['default_warehouse'].write({'delivery_steps': 'pick_pack_ship'})
# Set delay on pull rule
for pull_rule in self.company_data['default_warehouse'].delivery_route_id.rule_ids:
pull_rule.write({'delay': 2})
# Create sale order of product_1
order = self.env['sale.order'].create({
'partner_id': self.partner_a.id,
'partner_invoice_id': self.partner_a.id,
'partner_shipping_id': self.partner_a.id,
'pricelist_id': self.company_data['default_pricelist'].id,
'picking_policy': 'direct',
'warehouse_id': self.company_data['default_warehouse'].id,
'order_line': [(0, 0, {'name': self.test_product_order.name,
'product_id': self.test_product_order.id,
'product_uom_qty': 5,
'product_uom': self.env.ref('uom.product_uom_unit').id,
'customer_lead': self.test_product_order.sale_delay})]})
# Confirm our standard sale order
order.action_confirm()
# Check the picking crated or not
self.assertTrue(order.picking_ids, "Pickings should be created.")
# Check schedule date of ship type picking
out = order.picking_ids.filtered(lambda r: r.picking_type_id == self.company_data['default_warehouse'].out_type_id)
out_min_date = fields.Datetime.from_string(out.scheduled_date)
out_date = fields.Datetime.from_string(order.date_order) + timedelta(days=self.test_product_order.sale_delay) - timedelta(days=out.move_ids[0].rule_id.delay)
self.assertTrue(abs(out_min_date - out_date) <= timedelta(seconds=1), 'Schedule date of ship type picking should be equal to: order date + Customer Lead Time - pull rule delay.')
# Check schedule date of pack type picking
pack = order.picking_ids.filtered(lambda r: r.picking_type_id == self.company_data['default_warehouse'].pack_type_id)
pack_min_date = fields.Datetime.from_string(pack.scheduled_date)
pack_date = out_date - timedelta(days=pack.move_ids[0].rule_id.delay)
self.assertTrue(abs(pack_min_date - pack_date) <= timedelta(seconds=1), 'Schedule date of pack type picking should be equal to: Schedule date of ship type picking - pull rule delay.')
# Check schedule date of pick type picking
pick = order.picking_ids.filtered(lambda r: r.picking_type_id == self.company_data['default_warehouse'].pick_type_id)
pick_min_date = fields.Datetime.from_string(pick.scheduled_date)
pick_date = pack_date - timedelta(days=pick.move_ids[0].rule_id.delay)
self.assertTrue(abs(pick_min_date - pick_date) <= timedelta(seconds=1), 'Schedule date of pick type picking should be equal to: Schedule date of pack type picking - pull rule delay.')
def test_02_delivery_date_propagation(self):
""" In order to check deadline date propagation, set product's Customer Lead Time
and warehouse route's delay in stock rules"""
# Example :
# -> Set Warehouse with Outgoing Shipments : pick + pack + ship
# -> Set Delay : 5 days on stock rules
# -> Set Customer Lead Time on product : 30 days
# -> Set Sales Safety Days : 2 days
# -> Create an SO and confirm it with confirmation Date : 12/18/2018
# -> Pickings : OUT -> Scheduled Date : 01/12/2019, Deadline Date: 01/14/2019
# PACK -> Scheduled Date : 01/07/2019, Deadline Date: 01/09/2019
# PICK -> Scheduled Date : 01/02/2019, Deadline Date: 01/04/2019
# -> Now, change commitment_date in the sale order = out_deadline_date + 5 days
# -> Deadline Date should be changed and Scheduled date should be unchanged:
# OUT -> Deadline Date : 01/19/2019
# PACK -> Deadline Date : 01/14/2019
# PICK -> Deadline Date : 01/09/2019
# Update company with Sales Safety Days
self.env.company.security_lead = 2.00
# Update warehouse_1 with Outgoing Shippings pick + pack + ship
self.company_data['default_warehouse'].write({'delivery_steps': 'pick_pack_ship'})
# Set delay on pull rule
self.company_data['default_warehouse'].delivery_route_id.rule_ids.write({'delay': 5})
# Update the product_1 with type and Customer Lead Time
self.test_product_order.write({'type': 'product', 'sale_delay': 30.0})
# Now, create sale order of product_1 with customer_lead set on product
order = self.env['sale.order'].create({
'partner_id': self.partner_a.id,
'partner_invoice_id': self.partner_a.id,
'partner_shipping_id': self.partner_a.id,
'pricelist_id': self.company_data['default_pricelist'].id,
'picking_policy': 'direct',
'warehouse_id': self.company_data['default_warehouse'].id,
'order_line': [(0, 0, {'name': self.test_product_order.name,
'product_id': self.test_product_order.id,
'product_uom_qty': 5,
'product_uom': self.env.ref('uom.product_uom_unit').id,
'customer_lead': self.test_product_order.sale_delay})]})
# Confirm our standard sale order
order.action_confirm()
# Check the picking crated or not
self.assertTrue(order.picking_ids, "Pickings should be created.")
# Check schedule/deadline date of ship type picking
out = order.picking_ids.filtered(lambda r: r.picking_type_id == self.company_data['default_warehouse'].out_type_id)
deadline_date = order.date_order + timedelta(days=self.test_product_order.sale_delay) - timedelta(days=out.move_ids[0].rule_id.delay)
self.assertAlmostEqual(
out.date_deadline, deadline_date, delta=timedelta(seconds=1),
msg='Deadline date of ship type picking should be equal to: order date + Customer Lead Time - pull rule delay.')
out_scheduled_date = deadline_date - timedelta(days=self.env.company.security_lead)
self.assertAlmostEqual(
out.scheduled_date, out_scheduled_date, delta=timedelta(seconds=1),
msg='Schedule date of ship type picking should be equal to: order date + Customer Lead Time - pull rule delay - security_lead')
# Check schedule/deadline date of pack type picking
pack = order.picking_ids.filtered(lambda r: r.picking_type_id == self.company_data['default_warehouse'].pack_type_id)
pack_scheduled_date = out_scheduled_date - timedelta(days=pack.move_ids[0].rule_id.delay)
self.assertAlmostEqual(
pack.scheduled_date, pack_scheduled_date, delta=timedelta(seconds=1),
msg='Schedule date of pack type picking should be equal to: Schedule date of ship type picking - pull rule delay.')
deadline_date -= timedelta(days=pack.move_ids[0].rule_id.delay)
self.assertAlmostEqual(
pack.date_deadline, deadline_date, delta=timedelta(seconds=1),
msg='Deadline date of pack type picking should be equal to: Deadline date of ship type picking - pull rule delay.')
# Check schedule/deadline date of pick type picking
pick = order.picking_ids.filtered(lambda r: r.picking_type_id == self.company_data['default_warehouse'].pick_type_id)
pick_scheduled_date = pack_scheduled_date - timedelta(days=pick.move_ids[0].rule_id.delay)
self.assertAlmostEqual(
pick.scheduled_date, pick_scheduled_date, delta=timedelta(seconds=1),
msg='Schedule date of pack type picking should be equal to: Schedule date of ship type picking - pull rule delay.')
deadline_date -= timedelta(days=pick.move_ids[0].rule_id.delay)
self.assertAlmostEqual(
pick.date_deadline, deadline_date, delta=timedelta(seconds=1),
msg='Deadline date of pack type picking should be equal to: Deadline date of ship type picking - pull rule delay.')
# Now change the commitment date (Delivery Date) of the sale order
new_deadline = deadline_date + timedelta(days=5)
order.write({'commitment_date': new_deadline})
# Now check date_deadline of pick, pack and out are forced
# TODO : add note in case of change of deadline and check
self.assertEqual(out.date_deadline, new_deadline)
new_deadline -= timedelta(days=pack.move_ids[0].rule_id.delay)
self.assertEqual(pack.date_deadline, new_deadline)
new_deadline -= timedelta(days=pick.move_ids[0].rule_id.delay)
self.assertEqual(pick.date_deadline, new_deadline)
# Removes the SO deadline and checks the delivery deadline is updated accordingly.
order.commitment_date = False
new_deadline = order.expected_date
self.assertEqual(out.date_deadline, new_deadline)
new_deadline -= timedelta(days=pack.move_ids.rule_id.delay)
self.assertEqual(pack.date_deadline, new_deadline)
new_deadline -= timedelta(days=pick.move_ids.rule_id.delay)
self.assertEqual(pick.date_deadline, new_deadline)
def test_03_product_company_level_delays(self):
"""Partial duplicate of test_02 to make sure there is no default value specified in sale
that disables the computation of the customer_lead.
"""
order = self.env['sale.order'].create({
'partner_id': self.partner_a.id,
'pricelist_id': self.company_data['default_pricelist'].id,
'picking_policy': 'direct',
'warehouse_id': self.company_data['default_warehouse'].id,
})
order_line = self.env['sale.order.line'].create({
'product_id': self.test_product_order.id,
'product_uom_qty': 10,
'product_uom': self.env.ref('uom.product_uom_unit').id,
'order_id': order.id,
})
self.assertEqual(order_line.customer_lead, self.test_product_order.sale_delay)
# Confirm our standard sale order
order.action_confirm()
# Check the picking crated or not
self.assertTrue(order.picking_ids, "Picking should be created.")
# Check schedule date of picking
out_date = order.date_order + timedelta(days=self.test_product_order.sale_delay) - timedelta(days=self.env.company.security_lead)
min_date = order.picking_ids[0].scheduled_date
self.assertTrue(abs(min_date - out_date) <= timedelta(seconds=1), 'Schedule date of picking should be equal to: order date + Customer Lead Time - Sales Safety Days.')