[IMP] mrp,mrp_*,repair: MRP back to basics 6
mrp === - no time has been recorded on operations then give warning with apply button - do not allow to mass edit UOM in any manufacturing state - set value of lot/serial from MO and set read only on unbuild from MO - remove "archive operation" icon repair ====== Currently it is not possible to select a return on a repair order unless save it first. so after this commit user can able to select it without save it. only show picking related to selected product closes odoo/odoo#106571 Task: 2845380 X-original-commit: dd60647ce41547ecd00bbde45ddf564a7ada91c7 Related: odoo/enterprise#34403 Signed-off-by: William Henrotin (whe) <whe@odoo.com>
This commit is contained in:
committed by
William Henrotin
parent
34fabe5469
commit
82c1443254
@@ -1791,8 +1791,11 @@ class MrpProduction(models.Model):
|
||||
'state': 'done',
|
||||
'product_uom_qty': 0.0,
|
||||
})
|
||||
|
||||
diff_per_production = {}
|
||||
for production in self:
|
||||
diff_per_production[production] = 1
|
||||
if production.qty_produced != production.product_qty:
|
||||
diff_per_production[production] = production.qty_produced/production.product_qty
|
||||
production.write({
|
||||
'date_finished': fields.Datetime.now(),
|
||||
'product_qty': production.qty_produced,
|
||||
@@ -1801,8 +1804,11 @@ class MrpProduction(models.Model):
|
||||
'state': 'done',
|
||||
})
|
||||
|
||||
for workorder in self.workorder_ids.filtered(lambda w: w.state not in ('done', 'cancel')):
|
||||
workorder.duration_expected = workorder._get_duration_expected()
|
||||
for workorder in self.workorder_ids:
|
||||
if workorder.state not in ('done', 'cancel'):
|
||||
workorder.duration_expected = workorder._get_duration_expected()
|
||||
if workorder.duration == 0.0:
|
||||
workorder.duration = workorder.duration_expected * diff_per_production[workorder.production_id]
|
||||
|
||||
if not backorders:
|
||||
if self.env.context.get('from_workorder'):
|
||||
@@ -1968,6 +1974,7 @@ class MrpProduction(models.Model):
|
||||
'view_id': self.env.ref('mrp.mrp_unbuild_form_view_simplified').id,
|
||||
'type': 'ir.actions.act_window',
|
||||
'context': {'default_product_id': self.product_id.id,
|
||||
'default_lot_id': self.lot_producing_id.id,
|
||||
'default_mo_id': self.id,
|
||||
'default_company_id': self.company_id.id,
|
||||
'default_location_id': self.location_dest_id.id,
|
||||
|
||||
@@ -53,8 +53,7 @@ class MrpUnbuild(models.Model):
|
||||
mo_bom_id = fields.Many2one('mrp.bom', 'Bill of Material used on the Production Order', related='mo_id.bom_id')
|
||||
lot_id = fields.Many2one(
|
||||
'stock.lot', 'Lot/Serial Number',
|
||||
domain="[('product_id', '=', product_id), ('company_id', '=', company_id)]", check_company=True,
|
||||
states={'done': [('readonly', True)]})
|
||||
domain="[('product_id', '=', product_id), ('company_id', '=', company_id)]", check_company=True)
|
||||
has_tracking=fields.Selection(related='product_id.tracking', readonly=True)
|
||||
location_id = fields.Many2one(
|
||||
'stock.location', 'Source Location',
|
||||
@@ -102,23 +101,12 @@ class MrpUnbuild(models.Model):
|
||||
self.product_id = self.mo_id.product_id.id
|
||||
self.bom_id = self.mo_id.bom_id
|
||||
self.product_uom_id = self.mo_id.product_uom_id
|
||||
self.lot_id = self.mo_id.lot_producing_id
|
||||
if self.has_tracking == 'serial':
|
||||
self.product_qty = 1
|
||||
else:
|
||||
self.product_qty = self.mo_id.product_qty
|
||||
if self.lot_id and self.lot_id not in self.mo_id.move_finished_ids.move_line_ids.lot_id:
|
||||
return {'warning': {
|
||||
'title': _("Warning"),
|
||||
'message': _("The selected serial number does not correspond to the one used in the manufacturing order, please select another one.")
|
||||
}}
|
||||
|
||||
@api.onchange('lot_id')
|
||||
def _onchange_lot_id(self):
|
||||
if self.mo_id and self.lot_id and self.lot_id not in self.mo_id.move_finished_ids.move_line_ids.lot_id:
|
||||
return {'warning': {
|
||||
'title': _("Warning"),
|
||||
'message': _("The selected serial number does not correspond to the one used in the manufacturing order, please select another one.")
|
||||
}}
|
||||
|
||||
@api.onchange('product_id')
|
||||
def _onchange_product_id(self):
|
||||
|
||||
@@ -349,7 +349,6 @@ class TestTraceability(TestMrpCommon):
|
||||
|
||||
unbuild_form = Form(self.env['mrp.unbuild'])
|
||||
unbuild_form.mo_id = mo
|
||||
unbuild_form.lot_id = lot
|
||||
unbuild_form.save().action_unbuild()
|
||||
|
||||
mo_form = Form(self.env['mrp.production'])
|
||||
|
||||
@@ -305,13 +305,6 @@ class TestUnbuild(TestMrpCommon):
|
||||
|
||||
self.assertEqual(self.env['stock.quant']._get_available_quantity(p_final, self.stock_location, lot_id=lot_final), 5, 'You should have consumed 3 final product in stock')
|
||||
|
||||
with self.assertRaises(AssertionError):
|
||||
x.product_id = p_final
|
||||
x.bom_id = bom
|
||||
x.mo_id = mo
|
||||
x.product_qty = 3
|
||||
x.save()
|
||||
|
||||
self.assertEqual(self.env['stock.quant']._get_available_quantity(p_final, self.stock_location, lot_id=lot_final), 5, 'You should have consumed 3 final product in stock')
|
||||
|
||||
x = Form(self.env['mrp.unbuild'])
|
||||
@@ -319,7 +312,6 @@ class TestUnbuild(TestMrpCommon):
|
||||
x.bom_id = bom
|
||||
x.mo_id = mo
|
||||
x.product_qty = 3
|
||||
x.lot_id = lot_final
|
||||
x.save().action_unbuild()
|
||||
|
||||
self.assertEqual(self.env['stock.quant']._get_available_quantity(p_final, self.stock_location, lot_id=lot_final), 2, 'You should have consumed 3 final product in stock')
|
||||
@@ -331,7 +323,6 @@ class TestUnbuild(TestMrpCommon):
|
||||
x.bom_id = bom
|
||||
x.mo_id = mo
|
||||
x.product_qty = 2
|
||||
x.lot_id = lot_final
|
||||
x.save().action_unbuild()
|
||||
|
||||
self.assertEqual(self.env['stock.quant']._get_available_quantity(p_final, self.stock_location, lot_id=lot_final), 0, 'You should have 0 finalproduct in stock')
|
||||
@@ -343,7 +334,6 @@ class TestUnbuild(TestMrpCommon):
|
||||
x.bom_id = bom
|
||||
x.mo_id = mo
|
||||
x.product_qty = 5
|
||||
x.lot_id = lot_final
|
||||
x.save().action_unbuild()
|
||||
|
||||
self.assertEqual(self.env['stock.quant']._get_available_quantity(p_final, self.stock_location, lot_id=lot_final, allow_negative=True), -5, 'You should have negative quantity for final product in stock')
|
||||
@@ -814,7 +804,6 @@ class TestUnbuild(TestMrpCommon):
|
||||
#unbuild order
|
||||
unbuild_form = Form(self.env['mrp.unbuild'])
|
||||
unbuild_form.mo_id = mo
|
||||
unbuild_form.lot_id = product_1_sn
|
||||
unbuild_form.save().action_unbuild()
|
||||
|
||||
#mo2
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<field name="priority" optional="show" widget="priority" nolabel="1"/>
|
||||
<field name="message_needaction" invisible="1"/>
|
||||
<field name="name" decoration-bf="1"/>
|
||||
<field name="date_planned_start" readonly="1" optional="show" widget="remaining_days"/>
|
||||
<field name="date_planned_start" optional="show" widget="remaining_days"/>
|
||||
<field name="date_deadline" widget="remaining_days" attrs="{'invisible': [('state', 'in', ['done', 'cancel'])]}" optional="hide"/>
|
||||
<field name="product_id" readonly="1" optional="show"/>
|
||||
<field name="lot_producing_id" optional="hide"/>
|
||||
@@ -34,7 +34,7 @@
|
||||
decoration-danger="reservation_state != 'assigned' and components_availability_state == 'late'"/>
|
||||
<field name="reservation_state" optional="hide" decoration-danger="reservation_state == 'confirmed'" decoration-success="reservation_state == 'assigned'"/>
|
||||
<field name="product_qty" sum="Total Qty" string="Quantity" readonly="1" optional="show"/>
|
||||
<field name="product_uom_id" string="UoM" options="{'no_open':True,'no_create':True}" groups="uom.group_uom" optional="show"/>
|
||||
<field name="product_uom_id" string="UoM" readonly="1" options="{'no_open':True,'no_create':True}" groups="uom.group_uom" optional="show"/>
|
||||
<field name="production_duration_expected" attrs="{'invisible': [('production_duration_expected', '=', 0)]}" groups="mrp.group_mrp_routings" widget="float_time" sum="Total expected duration" optional="show"/>
|
||||
<field name="production_real_duration" attrs="{'invisible': [('production_real_duration', '=', 0)]}" groups="mrp.group_mrp_routings" widget="float_time" sum="Total real duration" optional="show"/>
|
||||
<field name="company_id" readonly="1" groups="base.group_multi_company" optional="show"/>
|
||||
@@ -348,11 +348,11 @@
|
||||
<field name="manual_consumption" invisible="1" force_save="1"/>
|
||||
<field name="show_details_visible" invisible="1"/>
|
||||
<field name="lot_ids" widget="many2many_tags"
|
||||
optional="hide"
|
||||
optional="hide"
|
||||
readonly="1"
|
||||
string="Lot/Serial Numbers"
|
||||
help="Displays the consumed Lot/Serial Numbers."
|
||||
groups="stock.group_production_lot"
|
||||
groups="stock.group_production_lot"
|
||||
attrs="{'invisible': ['|', ('show_details_visible', '=', False), ('parent.state', '=', 'draft')],
|
||||
'column_invisible': [('parent.show_lot_ids', '=', False)]}"
|
||||
options="{'create': [('parent.use_create_components_lots', '!=', False)]}"
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
<attribute name="attrs">{'column_invisible': [('parent.product_id', '!=', False)]}</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='bom_product_template_attribute_value_ids']" position="after">
|
||||
<button name="action_archive" class="btn-link" type="object" string="Archive Operation" icon="fa-times"/>
|
||||
<button name="action_archive" class="oe_right" type="object" string="Archive Operation"/>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='blocked_by_operation_ids']" position="replace">
|
||||
</xpath>
|
||||
|
||||
@@ -117,7 +117,7 @@
|
||||
<field name="location_id" options="{'no_create': True}" groups="stock.group_stock_multi_locations"/>
|
||||
<field name="location_dest_id" options="{'no_create': True}" groups="stock.group_stock_multi_locations"/>
|
||||
<field name="has_tracking" invisible="1"/>
|
||||
<field name="lot_id" attrs="{'invisible': [('has_tracking', '=', 'none')], 'required': [('has_tracking', '!=', 'none')]}" groups="stock.group_production_lot"/>
|
||||
<field name="lot_id" attrs="{'invisible': [('has_tracking', '=', 'none')], 'required': [('has_tracking', '!=', 'none')], 'readonly':['|', ('mo_id','!=',False), ('state', '=', 'done')]}" groups="stock.group_production_lot" force_save="1"/>
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
</group>
|
||||
</group>
|
||||
@@ -156,7 +156,7 @@
|
||||
<field name="location_id" options="{'no_create': True}" groups="stock.group_stock_multi_locations"/>
|
||||
<field name="location_dest_id" options="{'no_create': True}" groups="stock.group_stock_multi_locations"/>
|
||||
<field name="has_tracking" invisible="1"/>
|
||||
<field name="lot_id" attrs="{'invisible': [('has_tracking', '=', 'none')], 'required': [('has_tracking', '!=', 'none')]}" groups="stock.group_production_lot"/>
|
||||
<field name="lot_id" readonly="1" attrs="{'invisible': [('has_tracking', '=', 'none')], 'required': [('has_tracking', '!=', 'none')]}" groups="stock.group_production_lot"/>
|
||||
<field name="company_id" groups="base.group_multi_company" readonly="1"/>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
@@ -131,13 +131,15 @@ class Repair(models.Model):
|
||||
invoice_state = fields.Selection(string='Invoice State', related='invoice_id.state')
|
||||
priority = fields.Selection([('0', 'Normal'), ('1', 'Urgent')], default='0', string="Priority")
|
||||
|
||||
@api.depends('product_id')
|
||||
def _compute_allowed_picking_type_ids(self):
|
||||
'''
|
||||
computes the ids of return picking types
|
||||
'''
|
||||
out_picking_types = self.env['stock.picking.type'].search_read(domain=[('code', '=', 'outgoing')],
|
||||
fields=['return_picking_type_id'], load='')
|
||||
self.allowed_picking_type_ids = [pick_type['return_picking_type_id'] for pick_type in out_picking_types]
|
||||
self.allowed_picking_type_ids = [
|
||||
pt['return_picking_type_id'] for pt in out_picking_types if pt['return_picking_type_id']]
|
||||
|
||||
@api.depends('partner_id')
|
||||
def _compute_default_address_id(self):
|
||||
|
||||
@@ -89,7 +89,7 @@
|
||||
<field name="address_id" groups="account.group_delivery_invoice_address"/>
|
||||
<field name="sale_order_id"/>
|
||||
<field name="allowed_picking_type_ids" invisible="1"/>
|
||||
<field name="picking_id" domain="[('picking_type_id','in', allowed_picking_type_ids)]" options="{'no_create': True}"/>
|
||||
<field name="picking_id" domain="[('picking_type_id','in', allowed_picking_type_ids), ('product_id','=',product_id)]" options="{'no_create': True}"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="schedule_date"/>
|
||||
|
||||
Reference in New Issue
Block a user