[IMP] mrp: Produce wizard save and produce another
When a user produces multiple finished products with SN/lots, he has to save the wizard go back to the production order and click again on produce button for the second SN/lot. It could be annoying with a huge number of SN/lots to encode. This commit adds a 'Continue' button that saves the wizard and directly opens a new with the new lot/SN.
This commit is contained in:
committed by
Arnold Moyaux
parent
38b1debece
commit
2590cf2e6d
@@ -19,14 +19,11 @@ class MrpProductProduce(models.TransientModel):
|
||||
production = self.env['mrp.production'].browse(self._context['active_id'])
|
||||
serial_finished = (production.product_id.tracking == 'serial')
|
||||
todo_uom = production.product_uom_id.id
|
||||
todo_quantity = self._get_todo(production)
|
||||
if serial_finished:
|
||||
todo_quantity = 1.0
|
||||
if production.product_uom_id.uom_type != 'reference':
|
||||
todo_uom = self.env['uom.uom'].search([('category_id', '=', production.product_uom_id.category_id.id), ('uom_type', '=', 'reference')]).id
|
||||
else:
|
||||
main_product_moves = production.move_finished_ids.filtered(lambda x: x.product_id.id == production.product_id.id)
|
||||
todo_quantity = production.product_qty - sum(main_product_moves.mapped('quantity_done'))
|
||||
todo_quantity = todo_quantity if (todo_quantity > 0) else 0
|
||||
if 'production_id' in fields:
|
||||
res['production_id'] = production.id
|
||||
if 'product_id' in fields:
|
||||
@@ -47,6 +44,25 @@ class MrpProductProduce(models.TransientModel):
|
||||
lot_id = fields.Many2one('stock.production.lot', string='Lot/Serial Number')
|
||||
produce_line_ids = fields.One2many('mrp.product.produce.line', 'product_produce_id', string='Product to Track')
|
||||
product_tracking = fields.Selection(related="product_id.tracking", readonly=False)
|
||||
is_pending_production = fields.Boolean(compute='_compute_pending_production')
|
||||
|
||||
@api.depends('product_qty')
|
||||
def _compute_pending_production(self):
|
||||
""" Compute if it exits remaining quantity once the quantity on the
|
||||
current wizard will be processed. The purpose is to display or not
|
||||
button 'continue'.
|
||||
"""
|
||||
for product_produce in self:
|
||||
remaining_qty = product_produce._get_todo(product_produce.production_id)
|
||||
product_produce.is_pending_production = remaining_qty - product_produce.product_qty > 0.0
|
||||
|
||||
def continue_production(self):
|
||||
""" Save current wizard and directly opens a new. """
|
||||
self.ensure_one()
|
||||
self._record_production()
|
||||
action = self.production_id.open_produce_product()
|
||||
action['context'] = {'active_id': self.production_id.id}
|
||||
return action
|
||||
|
||||
def action_generate_serial(self):
|
||||
self.ensure_one()
|
||||
@@ -67,23 +83,9 @@ class MrpProductProduce(models.TransientModel):
|
||||
|
||||
@api.multi
|
||||
def do_produce(self):
|
||||
# Nothing to do for lots since values are created using default data (stock.move.lots)
|
||||
quantity = self.product_qty
|
||||
if float_compare(quantity, 0, precision_rounding=self.product_uom_id.rounding) <= 0:
|
||||
raise UserError(_("The production order for '%s' has no quantity specified.") % self.product_id.display_name)
|
||||
for move in self.production_id.move_finished_ids:
|
||||
if move.product_id.tracking == 'none' and move.state not in ('done', 'cancel'):
|
||||
rounding = move.product_uom.rounding
|
||||
if move.product_id.id == self.production_id.product_id.id:
|
||||
move.quantity_done += float_round(quantity, precision_rounding=rounding)
|
||||
elif move.unit_factor:
|
||||
# byproducts handling
|
||||
move.quantity_done += float_round(quantity * move.unit_factor, precision_rounding=rounding)
|
||||
self.check_finished_move_lots()
|
||||
if self.production_id.state == 'confirmed':
|
||||
self.production_id.write({
|
||||
'date_start': datetime.now(),
|
||||
})
|
||||
""" Save the current wizard and go back to the MO. """
|
||||
self.ensure_one()
|
||||
self._record_production()
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
@api.multi
|
||||
@@ -138,6 +140,32 @@ class MrpProductProduce(models.TransientModel):
|
||||
pl.move_id._generate_consumed_move_line(pl.qty_done, self.lot_id, lot=pl.lot_id)
|
||||
return True
|
||||
|
||||
def _get_todo(self, production):
|
||||
""" This method will return remaining todo quantity of production. """
|
||||
main_product_moves = production.move_finished_ids.filtered(lambda x: x.product_id.id == production.product_id.id)
|
||||
todo_quantity = production.product_qty - sum(main_product_moves.mapped('quantity_done'))
|
||||
todo_quantity = todo_quantity if (todo_quantity > 0) else 0
|
||||
return todo_quantity
|
||||
|
||||
def _record_production(self):
|
||||
# Nothing to do for lots since values are created using default data (stock.move.lots)
|
||||
quantity = self.product_qty
|
||||
if float_compare(quantity, 0, precision_rounding=self.product_uom_id.rounding) <= 0:
|
||||
raise UserError(_("The production order for '%s' has no quantity specified.") % self.product_id.display_name)
|
||||
for move in self.production_id.move_finished_ids:
|
||||
if move.product_id.tracking == 'none' and move.state not in ('done', 'cancel'):
|
||||
rounding = move.product_uom.rounding
|
||||
if move.product_id.id == self.production_id.product_id.id:
|
||||
move.quantity_done += float_round(quantity, precision_rounding=rounding)
|
||||
elif move.unit_factor:
|
||||
# byproducts handling
|
||||
move.quantity_done += float_round(quantity * move.unit_factor, precision_rounding=rounding)
|
||||
self.check_finished_move_lots()
|
||||
if self.production_id.state == 'confirmed':
|
||||
self.production_id.write({
|
||||
'date_start': datetime.now(),
|
||||
})
|
||||
|
||||
@api.onchange('product_qty')
|
||||
def _onchange_product_qty(self):
|
||||
lines = []
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
<field name="serial" invisible="1"/>
|
||||
<field name="production_id" invisible="1"/>
|
||||
<field name="product_id" readonly="1"/>
|
||||
<field name="is_pending_production" invisible="1"/>
|
||||
<label for="product_qty"/>
|
||||
<div class="o_row">
|
||||
<field name="product_qty" attrs="{'readonly': [('serial', '=', True)]}"/>
|
||||
@@ -39,8 +40,10 @@
|
||||
</field>
|
||||
</group>
|
||||
<footer>
|
||||
<button name="do_produce" type="object" string="Record Production" class="btn-primary"/>
|
||||
<button string="Cancel" class="btn-secondary" special="cancel" />
|
||||
<button name="continue_production" attrs="{'invisible':[('is_pending_production', '=', False)]}" type="object" string="Continue" class="btn-primary"/>
|
||||
<button name="do_produce" type="object" string="Save" class="btn-default btn-secondary" attrs="{'invisible':[('is_pending_production', '=', False)]}"/>
|
||||
<button name="do_produce" type="object" string="Save" class="btn-primary" attrs="{'invisible':[('is_pending_production', '=', True)]}"/>
|
||||
<button string="Discard" class="btn-default btn-secondary" special="cancel"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
|
||||
@@ -559,7 +559,7 @@ tour.register('main_flow_tour', {
|
||||
content: _t("Produce"),
|
||||
position: "bottom",
|
||||
}, {
|
||||
trigger: ".modal-footer .btn-primary:first",
|
||||
trigger: ".modal-footer .btn-primary:nth-child(3)",
|
||||
content: _t('Record Production'),
|
||||
position: 'bottom',
|
||||
}, {
|
||||
|
||||
Reference in New Issue
Block a user