Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[12.0][IMP] mrp_scheduled_products: quantity change #468

Open
wants to merge 1 commit into
base: 12.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions mrp_scheduled_products/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
from .hooks import post_init_hook
from . import models
from . import wizards
3 changes: 3 additions & 0 deletions mrp_scheduled_products/views/mrp_production_view.xml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@
<field name="inherit_id"
ref="mrp.mrp_production_form_view" />
<field name="arch" type="xml">
<button name="%(mrp.action_change_production_qty)d" position="attributes">
<attribute name="attrs">{'invisible': ['|', ('state', 'in', ('draft', 'done','cancel')), ('id', '=', False)]}</attribute>
</button>
<div name="button_box" position="inside">
<button name="open_table_location" icon="fa-arrow-up" class="oe_stat_button" string="Stock Report" type="object"/>
</div>
Expand Down
1 change: 1 addition & 0 deletions mrp_scheduled_products/wizards/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import change_production_qty
116 changes: 116 additions & 0 deletions mrp_scheduled_products/wizards/change_production_qty.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# Copyright 2024 Oihane Crucelaegui - AvanzOSC
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).

from odoo import api, fields, models, _
from odoo.addons import decimal_precision as dp
from odoo.exceptions import UserError
from odoo.tools import float_is_zero, float_round


class ChangeProductionQty(models.TransientModel):
_inherit = "change.production.qty"

@api.model
def default_get(self, fields):
res = super(ChangeProductionQty, self).default_get(fields)
if res.get("mo_id"):
production = self.env["mrp.production"].browse(res["mo_id"])
if production.state == "draft":
raise UserError(_("You can not use the wizard to change quantity in draft manufacturing orders."))
# if 'mo_id' in fields and not res.get('mo_id') and self._context.get('active_model') == 'mrp.production' and self._context.get('active_id'):
# res['mo_id'] = self._context['active_id']
# if 'product_qty' in fields and not res.get('product_qty') and res.get('mo_id'):
# res['product_qty'] = self.env['mrp.production'].browse(res['mo_id']).product_qty
return res

@api.model
def _update_product_to_produce(self, production, qty, old_qty):
return super()._update_product_to_produce(production, qty, old_qty)
# production_move = production.move_finished_ids.filtered(lambda x: x.product_id.id == production.product_id.id and x.state not in ('done', 'cancel'))
# if production_move:
# production_move._decrease_reserved_quanity(qty)
# production_move.with_context(do_not_unreserve=True).write({'product_uom_qty': qty})
# production_move._recompute_state()
# production_move._action_assign()
# else:
# production_move = production._generate_finished_moves()
# production_move = production.move_finished_ids.filtered(lambda x: x.state not in ('done', 'cancel') and production.product_id.id == x.product_id.id)
# production_move.write({'product_uom_qty': qty})
# return {production_move: (qty, old_qty)}

@api.multi
def change_prod_qty(self):
return super().change_prod_qty()
# precision = self.env['decimal.precision'].precision_get('Product Unit of Measure')
# for wizard in self:
# production = wizard.mo_id
# produced = sum(production.move_finished_ids.filtered(lambda m: m.product_id == production.product_id).mapped('quantity_done'))
# if wizard.product_qty < produced:
# format_qty = '%.{precision}f'.format(precision=precision)
# raise UserError(_("You have already processed %s. Please input a quantity higher than %s ") % (format_qty % produced, format_qty % produced))
# old_production_qty = production.product_qty
# production.write({'product_qty': wizard.product_qty})
# done_moves = production.move_finished_ids.filtered(lambda x: x.state == 'done' and x.product_id == production.product_id)
# qty_produced = production.product_id.uom_id._compute_quantity(sum(done_moves.mapped('product_qty')), production.product_uom_id)
# factor = production.product_uom_id._compute_quantity(production.product_qty - qty_produced, production.bom_id.product_uom_id) / production.bom_id.product_qty
# boms, lines = production.bom_id.explode(production.product_id, factor, picking_type=production.bom_id.picking_type_id)
# documents = {}
# for line, line_data in lines:
# move = production.move_raw_ids.filtered(lambda x: x.bom_line_id.id == line.id and x.state not in ('done', 'cancel'))
# if move:
# move = move[0]
# old_qty = move.product_uom_qty
# else:
# old_qty = 0
# iterate_key = production._get_document_iterate_key(move)
# if iterate_key:
# document = self.env['stock.picking']._log_activity_get_documents({move: (line_data['qty'], old_qty)}, iterate_key, 'UP')
# for key, value in document.items():
# if documents.get(key):
# documents[key] += [value]
# else:
# documents[key] = [value]
#
# production._update_raw_move(line, line_data)
#
# production._log_manufacture_exception(documents)
# operation_bom_qty = {}
# for bom, bom_data in boms:
# for operation in bom.routing_id.operation_ids:
# operation_bom_qty[operation.id] = bom_data['qty']
# finished_moves_modification = self._update_product_to_produce(production, production.product_qty - qty_produced, old_production_qty)
# production._log_downside_manufactured_quantity(finished_moves_modification)
# moves = production.move_raw_ids.filtered(lambda x: x.state not in ('done', 'cancel'))
# moves._action_assign()
# for wo in production.workorder_ids:
# operation = wo.operation_id
# if operation_bom_qty.get(operation.id):
# cycle_number = float_round(operation_bom_qty[operation.id] / operation.workcenter_id.capacity, precision_digits=0, rounding_method='UP')
# wo.duration_expected = (operation.workcenter_id.time_start +
# operation.workcenter_id.time_stop +
# cycle_number * operation.time_cycle * 100.0 / operation.workcenter_id.time_efficiency)
# quantity = wo.qty_production - wo.qty_produced
# if production.product_id.tracking == 'serial':
# quantity = 1.0 if not float_is_zero(quantity, precision_digits=precision) else 0.0
# else:
# quantity = quantity if (quantity > 0) else 0
# if float_is_zero(quantity, precision_digits=precision):
# wo.final_lot_id = False
# wo.active_move_line_ids.unlink()
# wo.qty_producing = quantity
# if wo.qty_produced < wo.qty_production and wo.state == 'done':
# wo.state = 'progress'
# if wo.qty_produced == wo.qty_production and wo.state == 'progress':
# wo.state = 'done'
# # assign moves; last operation receive all unassigned moves
# # TODO: following could be put in a function as it is similar as code in _workorders_create
# # TODO: only needed when creating new moves
# moves_raw = production.move_raw_ids.filtered(lambda move: move.operation_id == operation and move.state not in ('done', 'cancel'))
# if wo == production.workorder_ids[-1]:
# moves_raw |= production.move_raw_ids.filtered(lambda move: not move.operation_id)
# moves_finished = production.move_finished_ids.filtered(lambda move: move.operation_id == operation) #TODO: code does nothing, unless maybe by_products?
# moves_raw.mapped('move_line_ids').write({'workorder_id': wo.id})
# (moves_finished + moves_raw).write({'workorder_id': wo.id})
# if quantity > 0 and wo.move_raw_ids.filtered(lambda x: x.product_id.tracking != 'none') and not wo.active_move_line_ids:
# wo._generate_lot_ids()
# return {}