241 lines
13 KiB
Python
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.')
|