[IMP] mrp, sale_mrp: planned date on MO
The purpose of this commit is to simplify the `mrp.production` model in
reducing the number of date field.
The following fields was kept:
- `date_planned_start`: the planned date for the beginning of the MO
- `date_planned_finished`: the planned date for the ending of the MO
- `date_start_wo`: the preferred date to start a Work Order in case
the MO will plan one.
- `date_deadline`: is only indicative and is automatically set when
the manufacturing order is needed for a sale order.
- `date_start` and `date_finished`: no changes.
Task #1935229
Co-authored-by: Whenrow <whe@odoo.com>
This commit is contained in:
@@ -51,6 +51,12 @@ class MrpProduction(models.Model):
|
||||
location = self.env['stock.warehouse'].search([('company_id', '=', self.env.company.id)], limit=1).lot_stock_id
|
||||
return location and location.id or False
|
||||
|
||||
@api.model
|
||||
def _get_default_date_planned_finished(self):
|
||||
if self.env.context.get('default_date_planned_start'):
|
||||
return fields.Datetime.to_datetime(self.env.context.get('default_date_planned_start')) + datetime.timedelta(hours=1)
|
||||
return datetime.datetime.now() + datetime.timedelta(hours=1)
|
||||
|
||||
name = fields.Char(
|
||||
'Reference', copy=False, readonly=True, default=lambda x: _('New'))
|
||||
origin = fields.Char(
|
||||
@@ -89,28 +95,24 @@ class MrpProduction(models.Model):
|
||||
states={'draft': [('readonly', False)]},
|
||||
help="Location where the system will stock the finished products.")
|
||||
date_planned_start = fields.Datetime(
|
||||
'Deadline Start', copy=False, default=fields.Datetime.now,
|
||||
index=True, required=True,
|
||||
states={'draft': [('readonly', False)]})
|
||||
'Planned Date', copy=False, default=fields.Datetime.now,
|
||||
help="Date at which you plan to start the production.",
|
||||
index=True, required=True, store=True)
|
||||
date_planned_finished = fields.Datetime(
|
||||
'Deadline End', copy=False, default=fields.Datetime.now,
|
||||
index=True,
|
||||
states={'draft': [('readonly', False)]})
|
||||
date_planned_start_wo = fields.Datetime(
|
||||
'Scheduled Start Date', compute='_compute_date_planned',
|
||||
copy=False, store=True,
|
||||
states={'done': [('readonly', True)], 'cancel': [('readonly', True)]})
|
||||
date_planned_finished_wo = fields.Datetime(
|
||||
'Scheduled End Date', compute='_compute_date_planned',
|
||||
copy=False, store=True,
|
||||
states={'done': [('readonly', True)], 'cancel': [('readonly', True)]})
|
||||
'Planned End Date',
|
||||
default=_get_default_date_planned_finished,
|
||||
help="Date at which you plan to finish the production.",
|
||||
copy=False, store=True)
|
||||
date_deadline = fields.Datetime(
|
||||
'Deadline', copy=False, index=True,
|
||||
help="Informative date allowing to define when the manufacturing order should be processed at the latest to fulfill delivery on time.")
|
||||
date_start = fields.Datetime('Start Date', copy=False, index=True, readonly=True)
|
||||
date_finished = fields.Datetime('End Date', copy=False, index=True, readonly=True)
|
||||
date_start_wo = fields.Datetime(
|
||||
'Planned Start Date', copy=False, readonly=True,
|
||||
states={'draft': [('readonly', False)], 'confirmed': [('readonly', False)]},
|
||||
help="The work orders will be planned based on the availability of the work centers starting from "
|
||||
"this date. If emtpy, the work orders are planned as soon as possible.")
|
||||
'Plan From', copy=False, readonly=True,
|
||||
help="Work orders will be planned based on the availability of the work centers\
|
||||
starting from this date. If empty, the work orders will be planned as soon as possible.",
|
||||
)
|
||||
bom_id = fields.Many2one(
|
||||
'mrp.bom', 'Bill of Material',
|
||||
readonly=True, states={'draft': [('readonly', False)]},
|
||||
@@ -370,18 +372,6 @@ class MrpProduction(models.Model):
|
||||
for production in self:
|
||||
production.scrap_count = count_data.get(production.id, 0)
|
||||
|
||||
@api.depends('workorder_ids.date_planned_start', 'workorder_ids.date_planned_finished')
|
||||
def _compute_date_planned(self):
|
||||
for order in self:
|
||||
date_planned_start_wo = date_planned_finished_wo = False
|
||||
if order.workorder_ids:
|
||||
start_dates = order.workorder_ids.filtered(lambda r: r.date_planned_start is not False).sorted(key=lambda r: r.date_planned_start)
|
||||
date_planned_start_wo = start_dates[0].date_planned_start if start_dates else False
|
||||
finished_dates = order.workorder_ids.filtered(lambda r: r.date_planned_finished is not False).sorted(key=lambda r: r.date_planned_finished)
|
||||
date_planned_finished_wo = finished_dates[-1].date_planned_finished if finished_dates else False
|
||||
order.date_planned_start_wo = date_planned_start_wo
|
||||
order.date_planned_finished_wo = date_planned_finished_wo
|
||||
|
||||
_sql_constraints = [
|
||||
('name_uniq', 'unique(name, company_id)', 'Reference must be unique per Company!'),
|
||||
('qty_positive', 'check (product_qty > 0)', 'The quantity to produce must be positive!'),
|
||||
@@ -414,6 +404,8 @@ class MrpProduction(models.Model):
|
||||
'date': self.date_planned_start,
|
||||
'date_expected': self.date_planned_start,
|
||||
})
|
||||
if not self.routing_id:
|
||||
self.date_planned_finished = self.date_planned_start + datetime.timedelta(hours=1)
|
||||
|
||||
@api.onchange('bom_id', 'product_id', 'product_qty', 'product_uom_id')
|
||||
def _onchange_move_raw(self):
|
||||
@@ -451,6 +443,11 @@ class MrpProduction(models.Model):
|
||||
'date_expected': vals['date_planned_start'],
|
||||
})
|
||||
for production in self:
|
||||
if 'date_planned_start' in vals:
|
||||
if production.state in ['done', 'cancel']:
|
||||
raise UserError(_('You cannot move a manufacturing order once it is cancelled or done.'))
|
||||
if production.workorder_ids and not self.env.context.get('force_date', False):
|
||||
raise UserError(_('You cannot move a planned manufacturing order.'))
|
||||
if 'move_raw_ids' in vals and production.state != 'draft':
|
||||
production.move_raw_ids.filtered(lambda m: m.state == 'draft')._action_confirm()
|
||||
return res
|
||||
@@ -715,6 +712,10 @@ class MrpProduction(models.Model):
|
||||
})
|
||||
vals['leave_id'] = leave.id
|
||||
workorder.write(vals)
|
||||
self.with_context(force_date=True).write({
|
||||
'date_planned_start': self.workorder_ids[0].date_planned_start,
|
||||
'date_planned_finished': self.workorder_ids[-1].date_planned_finished
|
||||
})
|
||||
|
||||
def button_unplan(self):
|
||||
if any(wo.state == 'done' for wo in self.workorder_ids):
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timedelta
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from collections import defaultdict
|
||||
|
||||
@@ -146,6 +146,14 @@ class MrpWorkorder(models.Model):
|
||||
'date_to': date_to,
|
||||
})
|
||||
|
||||
@api.onchange('date_planned_start')
|
||||
def _onchange_date_planned_start(self):
|
||||
if self.duration_expected:
|
||||
time_delta = timedelta(minutes=self.duration_expected)
|
||||
else:
|
||||
time_delta = timedelta(hours=1)
|
||||
self.update({'date_planned_finished': self.date_planned_start + time_delta})
|
||||
|
||||
@api.onchange('finished_lot_id')
|
||||
def _onchange_finished_lot_id(self):
|
||||
"""When the user changes the lot being currently produced, suggest
|
||||
@@ -256,6 +264,16 @@ class MrpWorkorder(models.Model):
|
||||
end_date = fields.Datetime.to_datetime(values.get('date_planned_finished')) or workorder.date_planned_finished
|
||||
if start_date and end_date and start_date > end_date:
|
||||
raise UserError(_('The planned end date of the work order cannot be prior to the planned start date, please correct this to save the work order.'))
|
||||
# Update MO dates if the start date of the first WO or the
|
||||
# finished date of the last WO is update.
|
||||
if workorder == workorder.production_id.workorder_ids[0] and 'date_planned_start' in values:
|
||||
workorder.production_id.with_context(force_date=True).write({
|
||||
'date_planned_start': values['date_planned_start']
|
||||
})
|
||||
if workorder == workorder.production_id.workorder_ids[-1] and 'date_planned_finished' in values:
|
||||
workorder.production_id.with_context(force_date=True).write({
|
||||
'date_planned_finished': values['date_planned_finished']
|
||||
})
|
||||
return super(MrpWorkorder, self).write(values)
|
||||
|
||||
def _generate_wo_lines(self):
|
||||
|
||||
@@ -82,7 +82,7 @@ class StockRule(models.Model):
|
||||
'location_src_id': self.location_src_id.id or self.picking_type_id.default_location_src_id.id or location_id.id,
|
||||
'location_dest_id': location_id.id,
|
||||
'bom_id': bom.id,
|
||||
'date_planned_start': fields.Datetime.to_string(self._get_date_planned(product_id, company_id, values)),
|
||||
'date_deadline': fields.Datetime.to_string(self._get_date_planned(product_id, company_id, values)),
|
||||
'date_planned_finished': values['date_planned'],
|
||||
'procurement_group_id': False,
|
||||
'propagate_cancel': self.propagate_cancel,
|
||||
|
||||
@@ -908,6 +908,7 @@ class TestWorkOrderProcess(TestMrpCommon):
|
||||
- calendar wc1 :[mo1][mo4]
|
||||
- calendar wc2 :[mo2 ][mo5 ]
|
||||
- calendar wc3 :[mo3 ][mo6 ]"""
|
||||
planned_date = datetime(2019, 5, 13, 9, 0)
|
||||
self.workcenter_1.alternative_workcenter_ids = self.wc_alt_1 | self.wc_alt_2
|
||||
workcenters = [self.wc_alt_2, self.wc_alt_1, self.workcenter_1]
|
||||
for i in range(3):
|
||||
@@ -916,11 +917,14 @@ class TestWorkOrderProcess(TestMrpCommon):
|
||||
mo_form.product_id = self.product_4
|
||||
mo_form.bom_id = self.planning_bom
|
||||
mo_form.product_qty = 1
|
||||
mo_form.date_start_wo = planned_date
|
||||
mo = mo_form.save()
|
||||
mo.action_confirm()
|
||||
mo.button_plan()
|
||||
# Check that workcenters change
|
||||
self.assertEqual(mo.workorder_ids.workcenter_id, workcenters[i], "wrong workcenter %d" % i)
|
||||
self.assertAlmostEqual(mo.date_planned_start, planned_date, delta=timedelta(seconds=10))
|
||||
self.assertAlmostEqual(mo.date_planned_start, mo.workorder_ids.date_planned_start, delta=timedelta(seconds=10))
|
||||
|
||||
for i in range(3):
|
||||
# Planning 3 more should choose workcenters in opposite order as
|
||||
@@ -931,11 +935,14 @@ class TestWorkOrderProcess(TestMrpCommon):
|
||||
mo_form.product_id = self.product_4
|
||||
mo_form.bom_id = self.planning_bom
|
||||
mo_form.product_qty = 1
|
||||
mo_form.date_start_wo = planned_date
|
||||
mo = mo_form.save()
|
||||
mo.action_confirm()
|
||||
mo.button_plan()
|
||||
# Check that workcenters change
|
||||
self.assertEqual(mo.workorder_ids.workcenter_id, workcenters[i], "wrong workcenter %d" % i)
|
||||
self.assertNotEqual(mo.date_planned_start, planned_date)
|
||||
self.assertAlmostEqual(mo.date_planned_start, mo.workorder_ids.date_planned_start, delta=timedelta(seconds=10))
|
||||
|
||||
def test_planning_2(self):
|
||||
""" Plan some manufacturing orders with 2 workorders each
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
<tree decoration-bf="message_needaction==True" default_order="date_planned_start desc" decoration-info="state=='confirmed'" decoration-danger="date_planned_start<current_date and state not in ('done','cancel')" decoration-muted="state in ('done','cancel')" string="Manufacturing Orders">
|
||||
<field name="message_needaction" invisible="1"/>
|
||||
<field name="name"/>
|
||||
<field name="date_start_wo" optional="hide"/>
|
||||
<field name="date_planned_start" optional="show"/>
|
||||
<field name="product_id" optional="show"/>
|
||||
<field name="product_qty" sum="Total Qty" string="Quantity" optional="show"/>
|
||||
@@ -46,15 +45,15 @@
|
||||
<button name="button_mark_done" attrs="{'invisible': [('state', '!=', 'to_close')]}" string="Mark as Done" type="object" class="oe_highlight"/>
|
||||
<button name="action_confirm" attrs="{'invisible': ['|', ('state', '!=', 'draft'), ('is_locked', '=', False)]}" string="Mark as Todo" type="object" class="oe_highlight"/>
|
||||
<button name="action_assign" attrs="{'invisible': ['|', '|', ('is_locked', '=', False), ('state', 'in', ('draft', 'done', 'cancel')), ('reservation_state', '=', 'assigned')]}" string="Check availability" type="object" class="oe_highlight"/>
|
||||
<button name="button_plan" attrs="{'invisible': ['|', ('state', 'not in', ('confirmed', 'planned')), '|', ('routing_id', '=', False), '|', ('date_planned_start_wo', '!=', False), ('date_planned_finished_wo', '!=', False)]}" type="object" string="Plan" class="oe_highlight"/>
|
||||
<button name="button_unplan" type="object" string="Unplan" attrs="{'invisible': ['|', '|', ('state', '!=', 'planned'), ('date_planned_start_wo', '=', False), ('date_planned_finished_wo', '=', False)]}"/>
|
||||
<button name="button_plan" attrs="{'invisible': ['|', ('state', '!=', 'confirmed'), ('routing_id', '=', False)]}" type="object" string="Plan" class="oe_highlight"/>
|
||||
<button name="button_unplan" type="object" string="Unplan" attrs="{'invisible': ['|', '|', ('state', '!=', 'planned'), ('date_planned_start', '=', False), ('date_planned_finished', '=', False)]}"/>
|
||||
<button name="open_produce_product" attrs="{'invisible': ['|', '|', '|', ('state', '=', 'to_close'), ('is_locked', '=', False), ('reservation_state', '!=', 'assigned'), ('routing_id', '!=', False)]}" string="Produce" type="object" class="oe_highlight"/>
|
||||
<button name="open_produce_product" attrs="{'invisible': ['|', '|', '|', ('state', '=', 'to_close'), ('is_locked', '=', False), ('reservation_state', 'not in', ('confirmed', 'waiting')), ('routing_id', '!=', False)]}" string="Produce" type="object"/>
|
||||
<button name="post_inventory" string="Post Inventory" type="object" attrs="{'invisible': [('post_visible', '=', False)]}" groups="base.group_no_one"/>
|
||||
<button name="action_cancel" type="object" string="Cancel"
|
||||
attrs="{'invisible': ['|', '|', ('is_locked', '=', False), ('state', 'in', ('done','cancel')), ('confirm_cancel', '=', True)]}"/>
|
||||
attrs="{'invisible': ['|', '|', '|', ('id', '=', False), ('is_locked', '=', False), ('state', 'in', ('done','cancel')), ('confirm_cancel', '=', True)]}"/>
|
||||
<button name="action_cancel" type="object" string="Cancel"
|
||||
attrs="{'invisible': ['|', '|', ('is_locked', '=', False), ('state', 'in', ('done','cancel')), ('confirm_cancel', '=', False)]}"
|
||||
attrs="{'invisible': ['|', '|', '|', ('id', '=', False), ('is_locked', '=', False), ('state', 'in', ('done','cancel')), ('confirm_cancel', '=', False)]}"
|
||||
confirm="Some product moves have already been confirmed, this manufacturing order can't be completely cancelled. Are you still sure you want to process ?"/>
|
||||
<button name="button_scrap" type="object" string="Scrap" attrs="{'invisible': ['|', ('state', 'in', ('cancel', 'draft')), ('is_locked', '=', False)]}"/>
|
||||
<button name="button_unreserve" type="object" string="Unreserve" attrs="{'invisible': [('unreserve_visible', '=', False)]}"/>
|
||||
@@ -114,14 +113,56 @@
|
||||
<field name="routing_id" groups="mrp.group_mrp_routings"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="date_planned_start"/>
|
||||
<field name="date_planned_finished" invisible="1"/>
|
||||
<field name="date_start_wo" attrs="{'invisible': ['|', ('routing_id', '=', False), ('state', 'not in', ['draft', 'confirmed'])]}"/>
|
||||
<label for="date_planned_start_wo" string="Scheduled Date" attrs="{'invisible': [('date_planned_start_wo', '=', False)]}"/>
|
||||
<div class="o_row" attrs="{'invisible': [('date_planned_start_wo', '=', False)]}">
|
||||
<field name="date_planned_start_wo" attrs="{'readonly': [('move_raw_ids', '!=', [])]}"/>
|
||||
<label for="date_planned_finished_wo" string="to" attrs="{'invisible': [('date_planned_finished_wo', '=', False)]}"/>
|
||||
<field name="date_planned_finished_wo" attrs="{'readonly': [('move_raw_ids', '!=', [])]}"/>
|
||||
<field name="date_deadline" attrs="{'readonly': [('state', 'in', ['done', 'cancel'])]}"/>
|
||||
<field name="date_start_wo"
|
||||
attrs="{'invisible': [
|
||||
'|',
|
||||
'&',
|
||||
('routing_id', '!=', False),
|
||||
('state', 'not in', ['draft', 'confirmed']),
|
||||
('routing_id', '=', False),
|
||||
], 'readonly': [
|
||||
('routing_id', '!=', False),
|
||||
('state', 'not in', ['draft', 'confirmed']),
|
||||
]}"/>
|
||||
<div class="o_row o_td_label">
|
||||
<label for="date_planned_start" string="Planned Date"
|
||||
attrs="{'invisible': [
|
||||
('routing_id', '!=', False),
|
||||
('state', 'in', ['draft', 'confirmed'])
|
||||
]}"/>
|
||||
</div>
|
||||
<div class="o_row">
|
||||
<field name="date_planned_start"
|
||||
attrs="{'invisible': [
|
||||
('routing_id', '!=', False),
|
||||
('state', 'in', ['draft', 'confirmed']),
|
||||
], 'readonly': [
|
||||
'|',
|
||||
'&',
|
||||
('routing_id', '=', False),
|
||||
('state', 'in', ['done', 'cancel']),
|
||||
'&',
|
||||
('routing_id', '!=', False),
|
||||
('state', 'not in', ['draft', 'confirmed'])]}"/>
|
||||
<label for="date_planned_finished" string="to" attrs="{'invisible': [
|
||||
'|',
|
||||
('id', '=', False),
|
||||
'&',
|
||||
('routing_id', '!=', False),
|
||||
('state', 'in', ['draft', 'confirmed'])
|
||||
]}"/>
|
||||
<field name="date_planned_finished" required="1"
|
||||
attrs="{'readonly': [
|
||||
'|',
|
||||
'&',
|
||||
('routing_id', '=', False),
|
||||
('state', 'in', ['done', 'cancel']),
|
||||
('routing_id', '!=', False)
|
||||
], 'invisible': [
|
||||
('routing_id', '!=', False),
|
||||
('state', 'in', ['draft', 'confirmed'])
|
||||
]}"/>
|
||||
</div>
|
||||
<field name="user_id"/>
|
||||
<field name="origin"/>
|
||||
@@ -204,8 +245,8 @@
|
||||
<field name="name"/>
|
||||
<field name="product_id"/>
|
||||
<field name="product_qty"/>
|
||||
<field name="product_uom_id" options="{'no_open':True,'no_create':True}"/>
|
||||
<field name="date_planned_start"/>
|
||||
<field name="product_uom_id" options="{'no_open':True,'no_create':True}"/>
|
||||
<field name="date_deadline"/>
|
||||
<field name="state"/>
|
||||
<field name="activity_state"/>
|
||||
<progressbar field="activity_state" colors='{"planned": "success", "today": "warning", "overdue": "danger"}'/>
|
||||
@@ -220,7 +261,7 @@
|
||||
</div>
|
||||
<div class="o_kanban_record_bottom">
|
||||
<div class="oe_kanban_bottom_left text-muted">
|
||||
<span><t t-esc="record.name.value"/> <t t-esc="record.date_planned_start.value and record.date_planned_start.value.split(' ')[0] or False"/></span>
|
||||
<span><t t-esc="record.name.value"/> <t t-esc="record.date_deadline.value and record.date_deadline.value.split(' ')[0] or False"/></span>
|
||||
<field name="activity_ids" widget="kanban_activity"/>
|
||||
</div>
|
||||
<div class="oe_kanban_bottom_right">
|
||||
@@ -238,7 +279,8 @@
|
||||
<field name="model">mrp.production</field>
|
||||
<field eval="2" name="priority"/>
|
||||
<field name="arch" type="xml">
|
||||
<calendar date_start="date_planned_start" string="Manufacturing Orders" color="routing_id" event_limit="5">
|
||||
<calendar date_start="date_planned_start" date_stop="date_planned_finished"
|
||||
string="Manufacturing Orders" color="routing_id" event_limit="5">
|
||||
<field name="routing_id"/>
|
||||
<field name="user_id" avatar_field="image_small"/>
|
||||
<field name="product_id"/>
|
||||
@@ -259,7 +301,7 @@
|
||||
<field name="model">mrp.production</field>
|
||||
<field name="arch" type="xml">
|
||||
<pivot string="Manufacturing Orders">
|
||||
<field name="date_planned_start" type="row"/>
|
||||
<field name="date_deadline" type="row"/>
|
||||
</pivot>
|
||||
</field>
|
||||
</record>
|
||||
@@ -268,7 +310,7 @@
|
||||
<field name="model">mrp.production</field>
|
||||
<field name="arch" type="xml">
|
||||
<graph string="Manufacturing Orders">
|
||||
<field name="date_planned_start"/>
|
||||
<field name="date_deadline"/>
|
||||
</graph>
|
||||
</field>
|
||||
</record>
|
||||
@@ -292,7 +334,7 @@
|
||||
<filter string="Waiting for Material" name="waiting" domain="[('reservation_state', 'in', ('waiting', 'confirmed'))]"/>
|
||||
<filter string="Material Available" name="filter_ready" domain="[('reservation_state', '=', 'assigned')]"/>
|
||||
<separator/>
|
||||
<filter string="Late" domain="['&', ('date_planned_start', '<', current_date), ('state', '=', 'confirmed')]"
|
||||
<filter string="Late" domain="['&', ('date_deadline', '<', current_date), ('state', '=', 'confirmed')]"
|
||||
name="late" help="Production started late"/>
|
||||
<separator/>
|
||||
<field name="product_id"/>
|
||||
@@ -312,7 +354,7 @@
|
||||
<group expand="0" string="Group By...">
|
||||
<filter string="Product" name="product" domain="[]" context="{'group_by':'product_id'}"/>
|
||||
<filter string="Routing" name="routing" domain="[]" context="{'group_by':'routing_id'}" groups="mrp.group_mrp_routings"/>
|
||||
<filter string="Scheduled Date" name="scheduled_date" domain="[]" context="{'group_by':'date_planned_start'}" help="Scheduled Date by Month"/>
|
||||
<filter string="Scheduled Date" name="scheduled_date" domain="[]" context="{'group_by':'date_deadline'}" help="Scheduled Date by Month"/>
|
||||
<filter string="Status" name="status" domain="[]" context="{'group_by': 'state'}"/>
|
||||
<filter string="Material Availability" name="groupby_reservation_state" domain="[]" context="{'group_by': 'reservation_state'}"/>
|
||||
</group>
|
||||
|
||||
@@ -71,9 +71,9 @@ class TestSaleMrpLeadTime(TestStockCommon):
|
||||
|
||||
# Check schedule date of manufacturing order
|
||||
mo_date = out_date - timedelta(days=self.product_1.produce_delay) - timedelta(days=company.manufacturing_lead)
|
||||
date_planned_start = fields.Datetime.from_string(manufacturing_order.date_planned_start)
|
||||
date_deadline = fields.Datetime.from_string(manufacturing_order.date_deadline)
|
||||
self.assertAlmostEqual(
|
||||
date_planned_start, mo_date,
|
||||
date_deadline, mo_date,
|
||||
delta=timedelta(seconds=1),
|
||||
msg="Schedule date of manufacturing order should be equal to: Schedule date of picking - product's Manufacturing Lead Time - company's Manufacturing Lead Time."
|
||||
)
|
||||
@@ -141,9 +141,9 @@ class TestSaleMrpLeadTime(TestStockCommon):
|
||||
|
||||
# Check schedule date of manufacturing order
|
||||
mo_date = pack_date - timedelta(days=self.product_1.produce_delay)
|
||||
date_planned_start = fields.Datetime.from_string(manufacturing_order.date_planned_start)
|
||||
date_deadline = fields.Datetime.from_string(manufacturing_order.date_deadline)
|
||||
self.assertAlmostEqual(
|
||||
date_planned_start, mo_date,
|
||||
date_deadline, mo_date,
|
||||
delta=timedelta(seconds=10),
|
||||
msg="Schedule date of manufacturing order should be equal to: Schedule date of pack type picking - product's Manufacturing Lead Time."
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user