[IMP] mrp: lock/unlock mode and show final lot
We apply a lock/unlock mode for the mo as was done for the picking. In locked mode, the user can do all the regular things, but not change the quantities done given by the work order or produce wizard. In unlocked mode, only allowed by the mrp manager, the user can change those quantities. We opted to remove the 4 lines and just use a check box to indicate there are lots behind a line. For the finished products tab, we opted to show the move lines instead of the moves as this way, you don't need to click further. If nothing has been produced yet, a message indicates to produce something first.
This commit is contained in:
@@ -106,6 +106,9 @@ class MrpProduction(models.Model):
|
||||
'stock.move', 'production_id', 'Finished Products',
|
||||
copy=False, states={'done': [('readonly', True)], 'cancel': [('readonly', True)]},
|
||||
domain=[('scrapped', '=', False)])
|
||||
finished_move_line_ids = fields.One2many(
|
||||
'stock.move.line', compute='_compute_lines', inverse='_inverse_lines',
|
||||
)
|
||||
workorder_ids = fields.One2many(
|
||||
'mrp.workorder', 'production_id', 'Work Orders',
|
||||
copy=False, oldname='workcenter_lines', readonly=True)
|
||||
@@ -157,6 +160,23 @@ class MrpProduction(models.Model):
|
||||
scrap_count = fields.Integer(compute='_compute_scrap_move_count', string='Scrap Move')
|
||||
priority = fields.Selection([('0', 'Not urgent'), ('1', 'Normal'), ('2', 'Urgent'), ('3', 'Very Urgent')], 'Priority',
|
||||
readonly=True, states={'confirmed': [('readonly', False)]}, default='1')
|
||||
is_locked = fields.Boolean('Is Locked', default=True)
|
||||
show_final_lots = fields.Boolean('Show Final Lots', compute='_compute_show_lots')
|
||||
production_location_id = fields.Many2one('stock.location', "Production Location", related='product_id.property_stock_production')
|
||||
|
||||
@api.depends('product_id.tracking')
|
||||
def _compute_show_lots(self):
|
||||
for production in self:
|
||||
production.show_final_lots = production.product_id.tracking != 'none'
|
||||
|
||||
def _inverse_lines(self):
|
||||
""" Little hack to make sure that when you change something on these objects, it gets saved"""
|
||||
pass
|
||||
|
||||
@api.depends('move_finished_ids.move_line_ids')
|
||||
def _compute_lines(self):
|
||||
for production in self:
|
||||
production.finished_move_line_ids = production.move_finished_ids.mapped('move_line_ids')
|
||||
|
||||
@api.multi
|
||||
@api.depends('bom_id.routing_id', 'bom_id.routing_id.operation_ids')
|
||||
@@ -199,18 +219,21 @@ class MrpProduction(models.Model):
|
||||
assigned_list = [x.state in ('assigned', 'done', 'cancel') for x in order.move_raw_ids]
|
||||
order.availability = (all(assigned_list) and 'assigned') or (any(partial_list) and 'partially_available') or 'waiting'
|
||||
|
||||
@api.depends('move_raw_ids', 'is_locked', 'state', 'move_raw_ids.quantity_done')
|
||||
def _compute_unreserve_visible(self):
|
||||
return True
|
||||
for order in self:
|
||||
already_reserved = order.is_locked and order.state not in ('done', 'cancel') and order.mapped('move_raw_ids.move_line_ids')
|
||||
any_quantity_done = any([m.quantity_done > 0 for m in order.move_raw_ids])
|
||||
order.unreserve_visible = not any_quantity_done and already_reserved
|
||||
|
||||
@api.multi
|
||||
@api.depends('move_raw_ids.quantity_done', 'move_finished_ids.quantity_done')
|
||||
@api.depends('move_raw_ids.quantity_done', 'move_finished_ids.quantity_done', 'is_locked')
|
||||
def _compute_post_visible(self):
|
||||
for order in self:
|
||||
if order.product_tmpl_id._is_cost_method_standard():
|
||||
order.post_visible = any((x.quantity_done > 0 and x.state not in ['done', 'cancel']) for x in order.move_raw_ids) or \
|
||||
any((x.quantity_done > 0 and x.state not in ['done' 'cancel']) for x in order.move_finished_ids)
|
||||
order.post_visible = order.is_locked and any((x.quantity_done > 0 and x.state not in ['done', 'cancel']) for x in order.move_raw_ids | order.move_finished_ids)
|
||||
else:
|
||||
order.post_visible = any((x.quantity_done > 0 and x.state not in ['done', 'cancel']) for x in order.move_finished_ids)
|
||||
order.post_visible = order.is_locked and any((x.quantity_done > 0 and x.state not in ['done', 'cancel']) for x in order.move_finished_ids)
|
||||
|
||||
@api.multi
|
||||
@api.depends('move_raw_ids.quantity_done', 'move_raw_ids.product_uom_qty')
|
||||
@@ -223,7 +246,7 @@ class MrpProduction(models.Model):
|
||||
)
|
||||
|
||||
@api.multi
|
||||
@api.depends('workorder_ids.state', 'move_finished_ids')
|
||||
@api.depends('workorder_ids.state', 'move_finished_ids', 'is_locked')
|
||||
def _get_produced_qty(self):
|
||||
for production in self:
|
||||
done_moves = production.move_finished_ids.filtered(lambda x: x.state != 'cancel' and x.product_id.id == production.product_id.id)
|
||||
@@ -231,7 +254,7 @@ class MrpProduction(models.Model):
|
||||
wo_done = True
|
||||
if any([x.state not in ('done', 'cancel') for x in production.workorder_ids]):
|
||||
wo_done = False
|
||||
production.check_to_done = done_moves and (qty_produced >= production.product_qty) and (production.state not in ('done', 'cancel')) and wo_done
|
||||
production.check_to_done = production.is_locked and done_moves and (qty_produced >= production.product_qty) and (production.state not in ('done', 'cancel')) and wo_done
|
||||
production.qty_produced = qty_produced
|
||||
return True
|
||||
|
||||
@@ -293,6 +316,11 @@ class MrpProduction(models.Model):
|
||||
raise UserError(_('Cannot delete a manufacturing order not in cancel state'))
|
||||
return super(MrpProduction, self).unlink()
|
||||
|
||||
def action_toggle_is_locked(self):
|
||||
self.ensure_one()
|
||||
self.is_locked = not self.is_locked
|
||||
return True
|
||||
|
||||
@api.multi
|
||||
def _generate_moves(self):
|
||||
for production in self:
|
||||
|
||||
@@ -66,7 +66,31 @@ class StockMove(models.Model):
|
||||
'Done', compute='_compute_is_done',
|
||||
store=True,
|
||||
help='Technical Field to order moves')
|
||||
|
||||
needs_lots = fields.Boolean('Tracking', compute='_compute_needs_lots')
|
||||
order_finished_lot_ids = fields.Many2many('stock.production.lot', compute='_compute_order_finished_lot_ids')
|
||||
|
||||
@api.depends('active_move_line_ids.qty_done', 'active_move_line_ids.product_uom_id')
|
||||
def _compute_done_quantity(self):
|
||||
super(StockMove, self)._compute_done_quantity()
|
||||
|
||||
@api.depends('raw_material_production_id.move_finished_ids.move_line_ids.lot_id')
|
||||
def _compute_order_finished_lot_ids(self):
|
||||
for move in self:
|
||||
if move.product_id.tracking != 'none' and move.raw_material_production_id:
|
||||
move.order_finished_lot_ids = move.raw_material_production_id.move_finished_ids.mapped('move_line_ids.lot_id').ids
|
||||
|
||||
@api.depends('product_id.tracking')
|
||||
def _compute_needs_lots(self):
|
||||
for move in self:
|
||||
move.needs_lots = move.product_id.tracking != 'none'
|
||||
|
||||
@api.depends('raw_material_production_id.is_locked', 'picking_id.is_locked')
|
||||
def _compute_is_locked(self):
|
||||
super(StockMove, self)._compute_is_locked()
|
||||
for move in self:
|
||||
if move.raw_material_production_id:
|
||||
move.is_locked = move.raw_material_production_id.is_locked
|
||||
|
||||
def _get_move_lines(self):
|
||||
self.ensure_one()
|
||||
if self.raw_material_production_id:
|
||||
@@ -93,40 +117,6 @@ class StockMove(models.Model):
|
||||
If you want to cancel this MO, please change the consumed quantities to 0.'))
|
||||
return super(StockMove, self)._action_cancel()
|
||||
|
||||
@api.multi
|
||||
# Could use split_move_operation from stock here
|
||||
def split_move_lot(self):
|
||||
ctx = dict(self.env.context)
|
||||
self.ensure_one()
|
||||
view = self.env.ref('mrp.view_stock_move_lots')
|
||||
serial = (self.has_tracking == 'serial')
|
||||
only_create = False # Check operation type in theory
|
||||
show_reserved = any([x for x in self.move_line_ids if x.product_qty > 0.0])
|
||||
ctx.update({
|
||||
'serial': serial,
|
||||
'only_create': only_create,
|
||||
'create_lots': True,
|
||||
'state_done': self.is_done,
|
||||
'show_reserved': show_reserved,
|
||||
})
|
||||
if ctx.get('w_production'):
|
||||
action = self.env.ref('mrp.act_mrp_product_produce').read()[0]
|
||||
action['context'] = ctx
|
||||
return action
|
||||
result = {
|
||||
'name': _('Register Lots'),
|
||||
'type': 'ir.actions.act_window',
|
||||
'view_type': 'form',
|
||||
'view_mode': 'form',
|
||||
'res_model': 'stock.move',
|
||||
'views': [(view.id, 'form')],
|
||||
'view_id': view.id,
|
||||
'target': 'new',
|
||||
'res_id': self.id,
|
||||
'context': ctx,
|
||||
}
|
||||
return result
|
||||
|
||||
def _action_confirm(self, merge=True):
|
||||
moves = self
|
||||
for move in self.filtered(lambda m: m.production_id):
|
||||
|
||||
@@ -38,18 +38,21 @@
|
||||
<field name="consumed_less_than_planned" invisible="1"/>
|
||||
<button name="button_mark_done" attrs="{'invisible': ['|', ('check_to_done', '=', False), ('consumed_less_than_planned', '=', True)]}" string="Mark as Done" type="object" class="oe_highlight"/>
|
||||
<button name="button_mark_done" attrs="{'invisible': ['|', ('check_to_done', '=', False), ('consumed_less_than_planned', '=', False)]}" string="Mark as Done" type="object" class="oe_highlight" confirm="You have consumed less material than what was planned. Are you sure you want to close this MO?"/>
|
||||
<button name="action_assign" attrs="{'invisible': [('availability', 'in', ('assigned', 'none'))]}" string="Check availability" type="object" class="oe_highlight"/>
|
||||
<button name="button_plan" attrs="{'invisible': ['|', ('state', '!=', 'confirmed'), ('routing_id', '=', False)]}" type="object" string="Create Workorders" class="oe_highlight"/>
|
||||
<button name="open_produce_product" attrs="{'invisible': ['|', '|', '|', ('check_to_done', '=', True), ('availability', 'not in', ['partially_available', 'assigned']), ('state', 'not in', ('confirmed','progress')), ('routing_id', '!=', False)]}" string="Produce" type="object" class="oe_highlight"/>
|
||||
<button name="open_produce_product" attrs="{'invisible': ['|', '|', '|', ('check_to_done', '=', True), ('availability', '!=', 'waiting'), ('state', 'not in', ('confirmed','progress')), ('routing_id', '!=', False)]}" string="Produce" type="object"/>
|
||||
<button name="action_assign" attrs="{'invisible': ['|', ('availability', 'in', ('assigned', 'none')), ('is_locked', '=', False)]}" string="Check availability" type="object" class="oe_highlight"/>
|
||||
<button name="button_plan" attrs="{'invisible': ['|', '|', ('state', '!=', 'confirmed'), ('routing_id', '=', False), ('is_locked', '=', False)]}" type="object" string="Create Workorders" class="oe_highlight"/>
|
||||
<button name="open_produce_product" attrs="{'invisible': ['|', '|', '|', '|', ('is_locked', '=', False), ('check_to_done', '=', True), ('availability', 'not in', ['partially_available', 'assigned']), ('state', 'not in', ('confirmed','progress')), ('routing_id', '!=', False)]}" string="Produce" type="object" class="oe_highlight"/>
|
||||
<button name="open_produce_product" attrs="{'invisible': ['|', '|', '|', '|', ('is_locked', '=', False), ('check_to_done', '=', True), ('availability', '!=', 'waiting'), ('state', 'not in', ('confirmed','progress')), ('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': ['|', ('state', 'in', ('done','cancel')), ('check_to_done', '=', True)]}"/>
|
||||
<button name="button_scrap" type="object" string="Scrap" attrs="{'invisible': ['|', ('availability', '=', 'none'), ('state', 'in', ('cancel'))]}"/>
|
||||
<button name="action_cancel" type="object" string="Cancel" attrs="{'invisible': ['|', '|', ('is_locked', '=', False), ('state', 'in', ('done','cancel')), ('check_to_done', '=', True)]}"/>
|
||||
<button name="button_scrap" type="object" string="Scrap" attrs="{'invisible': ['|', '|', ('availability', '=', 'none'), ('state', 'in', ('cancel')), ('is_locked', '=', False)]}"/>
|
||||
<button name="button_unreserve" type="object" string="Unreserve" attrs="{'invisible': [('unreserve_visible', '=', False)]}"/>
|
||||
<span class="label label-danger" attrs="{'invisible': ['|', ('availability', 'in', ('assigned', 'none')), ('state', 'not in', ('confirmed','progress'))]}">Raw materials not available!</span>
|
||||
<span class="label label-danger" attrs="{'invisible': ['|',('availability', 'in', ('assigned', 'none')), ('state', 'not in', ('confirmed','progress'))]}">Raw materials not available!</span>
|
||||
<field name="state" widget="statusbar" statusbar_visible="confirmed,progress,done"/>
|
||||
<button name="action_toggle_is_locked" attrs="{'invisible': ['|', ('id', '=', False), ('is_locked', '=', False)]}" string="Unlock" groups="mrp.group_mrp_manager" type="object" help="If the manufacturing order is unlocked you can add to the initial demand."/>
|
||||
<button name="action_toggle_is_locked" attrs="{'invisible': [('is_locked', '=', True)]}" string="Lock" class="oe_highlight" groups="mrp.group_mrp_manager" type="object"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<field name="is_locked" invisible="1"/>
|
||||
<field name="post_visible" invisible="1"/>
|
||||
<field name="unreserve_visible" invisible="1"/>
|
||||
<div class="oe_button_box" name="button_box">
|
||||
@@ -102,45 +105,46 @@
|
||||
<field name="user_id"/>
|
||||
<field name="origin" groups="base.group_no_one"/>
|
||||
<field name="company_id" groups="base.group_multi_company" options="{'no_create': True}" attrs="{'readonly': [('has_moves', '=', True)]}"/>
|
||||
<field name="show_final_lots" invisible="1"/>
|
||||
<field name="production_location_id" invisible="1" readonly="1"/>
|
||||
</group>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Consumed Materials">
|
||||
<field name="move_raw_ids" options="{'reload_on_button': True}" context="{'default_location_id': location_src_id, 'default_location_dest_id': location_dest_id}">
|
||||
<tree editable="bottom" delete="0" default_order="is_done desc,sequence" decoration-muted="is_done" decoration-warning="quantity_done>product_uom_qty" decoration-success="quantity_done==product_uom_qty" decoration-danger="reserved_availability < product_uom_qty" create="0">
|
||||
<field name="move_raw_ids" context="{'final_lots': show_final_lots, 'form_view_ref': 'mrp.view_stock_move_lots', 'default_location_id': location_src_id, 'default_location_dest_id': production_location_id, 'default_state': 'confirmed', 'default_raw_material_production_id': id}" attrs="{'readonly': [('is_locked', '=', True)]}">
|
||||
<tree delete="0" default_order="is_done,sequence" decoration-muted="is_done" decoration-warning="quantity_done>product_uom_qty" decoration-success="quantity_done==product_uom_qty" decoration-danger="reserved_availability < product_uom_qty">
|
||||
<field name="product_id" required="1"/>
|
||||
<field name="name" invisible="1"/>
|
||||
<field name="unit_factor" invisible="1"/>
|
||||
<field name="product_uom" groups="product.group_uom"/>
|
||||
<field name="has_tracking" invisible="1"/>
|
||||
<field name="needs_lots" readonly="1" groups="stock.group_production_lot"/>
|
||||
<field name="is_done" invisible="1"/>
|
||||
<field name="sequence" invisible="1"/>
|
||||
<field name="location_id" domain="[('id', 'child_of', parent.location_id)]" invisible="1"/>
|
||||
<field name="location_dest_id" domain="[('id', 'child_of', parent.location_dest_id)]" invisible="1"/>
|
||||
<field name="state" invisible="1"/>
|
||||
<field name="product_uom_qty" readonly="1" attrs="{'required': [('product_id', '!=', False)]}" string="To Consume"/>
|
||||
<field name="product_uom_qty" string="To Consume"/>
|
||||
<field name="reserved_availability" attrs="{'invisible': [('is_done', '=', True)]}" string="Reserved"/>
|
||||
<field name="quantity_done" attrs="{'readonly': ['|', ('is_done', '=', True), ('has_tracking', 'in', ['lot','serial'])]}" string="Consumed"/>
|
||||
<button name="split_move_lot" string="Register lots" type="object" icon="fa-list"
|
||||
attrs="{'invisible': [('has_tracking', 'not in', ['lot','serial'])]}"/>
|
||||
<field name="quantity_done" string="Consumed"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
<page string="Finished Products">
|
||||
<field name="move_finished_ids" options="{'reload_on_button': True}" context="{'default_location_id': location_src_id, 'default_location_dest_id': location_dest_id}">
|
||||
<tree editable="bottom" delete="0" default_order="is_done desc,sequence" decoration-muted="is_done" decoration-warning="quantity_done>product_uom_qty" decoration-success="quantity_done==product_uom_qty" create="0">
|
||||
<field name="product_id" required="1"/>
|
||||
<field name="product_uom" groups="product.group_uom"/>
|
||||
<field name="is_done" invisible="1"/>
|
||||
<field name="sequence" invisible="1"/>
|
||||
<field name="has_tracking" invisible="1"/>
|
||||
<field name="location_id" domain="[('id', 'child_of', parent.location_id)]" invisible="1"/>
|
||||
<field name="location_dest_id" domain="[('id', 'child_of', parent.location_dest_id)]" invisible="1"/>
|
||||
<field name="finished_move_line_ids" attrs="{'readonly': [('is_locked', '=', True)], 'invisible': [('finished_move_line_ids', '=', [])]}">
|
||||
<tree default_order="done_move" editable="bottom" create="0" delete="0" decoration-muted="state in ('done', 'cancel')">
|
||||
<field name="product_id" readonly="1"/>
|
||||
<field name="lot_id" groups="stock.group_production_lot" domain="[('product_id', '=', product_id)]" context="{'default_product_id': product_id}" attrs="{'invisible': [('lots_visible', '=', False)]}"/>
|
||||
<field name="product_uom_id" groups="product.group_uom"/>
|
||||
<field name="qty_done"/>
|
||||
<field name="lots_visible" invisible="1"/>
|
||||
<field name="done_move" invisible="1"/>
|
||||
<field name="state" invisible="1"/>
|
||||
<field name="product_uom_qty" readonly="1" attrs="{'required': [('product_id', '!=', False)]}" string="To Produce"/>
|
||||
<field name="quantity_done" attrs="{'readonly': ['|', ('is_done', '=', True), ('has_tracking', 'in', ['lot','serial'])]}" string="Produced"/>
|
||||
<button name="split_move_lot" string="Register lots" type="object" icon="fa-list"
|
||||
attrs="{'invisible': [('has_tracking', 'not in', ['lot','serial'])]}"/>
|
||||
</tree>
|
||||
</field>
|
||||
<p attrs="{'invisible': [('finished_move_line_ids', '!=', [])]}">
|
||||
Use the Produce button or process the work orders to create some finished products.
|
||||
</p>
|
||||
</page>
|
||||
<page string="Miscellaneous">
|
||||
<group>
|
||||
|
||||
@@ -18,11 +18,18 @@
|
||||
<field name="state" invisible="1"/>
|
||||
<group>
|
||||
<group>
|
||||
<field name="product_id" readonly="1"/>
|
||||
<field name="product_id" attrs="{'readonly': [('id', '!=', False)]}"/>
|
||||
<label for="product_uom_qty"/>
|
||||
<div class="o_row">
|
||||
<span><field name="product_uom_qty" readonly="1" nolabel="1"/></span>
|
||||
<span><field name="product_uom" attrs="{'readonly': [('id', '!=', False)]}" nolabel="1"/></span>
|
||||
</div>
|
||||
<label for="quantity_done"/>
|
||||
<div>
|
||||
<field name="quantity_done" readonly="1" class="oe_inline"/>
|
||||
<field name="product_uom" readonly="1" class="oe_inline" groups="product.group_uom"/>
|
||||
<div class="o_row">
|
||||
<span><field name="quantity_done" attrs="{'readonly': ['|', ('is_locked', '=', True), ('has_tracking', '!=', 'none')]}" nolabel="1"/></span>
|
||||
<span> / </span>
|
||||
<span><field name="reserved_availability" nolabel="1"/></span>
|
||||
<!-- <span><field name="product_uom" readonly="1" nolabel="1"/></span>-->
|
||||
</div>
|
||||
<field name="is_done" invisible="1"/>
|
||||
<field name="workorder_id" invisible="1"/>
|
||||
@@ -30,12 +37,17 @@
|
||||
<field name="location_dest_id" invisible="1"/>
|
||||
<field name="production_id" invisible="1"/>
|
||||
<field name="raw_material_production_id" invisible="1"/>
|
||||
<field name="is_locked" invisible="1"/>
|
||||
<field name="name" invisible="1"/>
|
||||
<field name="has_tracking" invisible="1"/>
|
||||
<field name="order_finished_lot_ids" invisible="1"/>
|
||||
</group>
|
||||
</group>
|
||||
<field name="active_move_line_ids" attrs="{'readonly': [('is_done', '=', True)]}" context="{'default_workorder_id': workorder_id, 'default_product_uom_id': product_uom, 'default_product_id': product_id, 'default_location_id': location_id, 'default_location_dest_id': location_dest_id, 'default_production_id': production_id or raw_material_production_id}">
|
||||
<field name="active_move_line_ids" attrs="{'readonly': [('is_locked', '=', True)], 'invisible': [('has_tracking', '=', 'none')]}" context="{'default_workorder_id': workorder_id, 'default_product_uom_id': product_uom, 'default_product_id': product_id, 'default_location_id': location_id, 'default_location_dest_id': location_dest_id, 'default_production_id': production_id or raw_material_production_id}">
|
||||
<tree editable="bottom" decoration-success="product_qty==qty_done" decoration-danger="(product_qty > 0) and (qty_done>product_qty)">
|
||||
<field name="lot_id" domain="[('product_id', '=', parent.product_id)]" context="{'default_product_id': parent.product_id}"/>
|
||||
<field name="product_qty" invisible="not context.get('show_reserved') or context.get('serial') or context.get('state_done')" readonly="1"/>
|
||||
<field name="lot_produced_id" options="{'no_open': True, 'no_create': True}" domain="[('id', 'in', parent.order_finished_lot_ids)]" invisible="not context.get('final_lots')"/>
|
||||
<field name="product_qty" string="Reserved" readonly="1"/>
|
||||
<field name="qty_done"/>
|
||||
<field name="workorder_id" invisible="1"/>
|
||||
<field name="product_id" invisible="1"/>
|
||||
@@ -43,13 +55,9 @@
|
||||
<field name="location_id" invisible="1"/>
|
||||
<field name="location_dest_id" invisible="1"/>
|
||||
<field name="done_wo" invisible="1"/>
|
||||
<field name="production_id" invisible="1" />
|
||||
<field name="production_id" invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
<footer class="oe_edit_only">
|
||||
<button special="save" type="object" string="Save" class="oe_highlight"/>
|
||||
<button string="Discard" special="cancel"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -154,11 +154,18 @@ class StockMove(models.Model):
|
||||
picking_code = fields.Selection(related='picking_id.picking_type_id.code', readonly=True)
|
||||
product_type = fields.Selection(related='product_id.type', readonly=True)
|
||||
additional = fields.Boolean("Whether the move was added after the picking's confirmation", default=False)
|
||||
is_locked = fields.Boolean(related='picking_id.is_locked', readonly=True)
|
||||
is_locked = fields.Boolean(compute='_compute_is_locked', readonly=True)
|
||||
is_initial_demand_editable = fields.Boolean('Is initial demand editable', compute='_compute_is_initial_demand_editable')
|
||||
is_quantity_done_editable = fields.Boolean('Is quantity done editable', compute='_compute_is_quantity_done_editable')
|
||||
reference = fields.Char(compute='_compute_reference', string="Reference", store=True)
|
||||
|
||||
@api.depends('picking_id.is_locked')
|
||||
def _compute_is_locked(self):
|
||||
for move in self:
|
||||
if move.picking_id:
|
||||
move.is_locked = move.picking_id.is_locked
|
||||
|
||||
|
||||
@api.depends('product_id', 'has_tracking', 'move_line_ids', 'location_id', 'location_dest_id')
|
||||
def _compute_show_details_visible(self):
|
||||
""" According to this field, the button that calls `action_show_details` will be displayed
|
||||
|
||||
Reference in New Issue
Block a user