mirror of
https://github.com/OCA/manufacture.git
synced 2025-01-28 16:37:15 +02:00
[ADD] purchase_mrp_distribution: New module to distribute qty of move in diferent products
This module aims to address the need to receive a generic product, but until the moment of reception, we do not know the quantity that we might receive of its specific products. Using kits was not suitable for us, because to account for a unit of the kit product, the quantity specified in the BoM must be received. Therefore, we opted to define a new type of BoM called distribution. In this way, upon receiving a unit of any product added to the BoM, it will be accounted for as a unit of the generic product and will be reflected in the svls as separate products, but they will be accounted for in the purchase line as part of the product.
This commit is contained in:
committed by
Pedro M. Baeza
parent
0ca8110827
commit
0ea4e392c8
1
purchase_mrp_distribution/wizards/__init__.py
Normal file
1
purchase_mrp_distribution/wizards/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from . import stock_move_distribution_wiz
|
||||
@@ -0,0 +1,98 @@
|
||||
# Copyright 2024 Tecnativa - Carlos Roca
|
||||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
|
||||
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
class StockMoveDistributionWiz(models.TransientModel):
|
||||
_name = "stock.move.distribution.wiz"
|
||||
_description = "Wizard to distribute product qty to diferent products"
|
||||
|
||||
@api.model
|
||||
def default_get(self, fields):
|
||||
ctx = self.env.context.copy()
|
||||
res = super().default_get(fields)
|
||||
if ctx.get("active_id") and ctx.get("active_model") == "stock.move":
|
||||
move = self.env["stock.move"].browse(ctx["active_id"])
|
||||
lines = []
|
||||
for bom_line in move.distribution_bom_id.bom_line_ids:
|
||||
if move_lines := move.move_line_ids.filtered(
|
||||
lambda ml, bom_line=bom_line: ml.product_id == bom_line.product_id
|
||||
):
|
||||
for sml in move_lines:
|
||||
lines.append(
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"product_id": bom_line.product_id.id,
|
||||
"quantity": sml.qty_done,
|
||||
"uom_id": bom_line.product_uom_id.id,
|
||||
"lot_id": sml.lot_id.id,
|
||||
"package_id": sml.result_package_id.id,
|
||||
"company_id": sml.company_id.id,
|
||||
},
|
||||
)
|
||||
)
|
||||
else:
|
||||
lines.append(
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"product_id": bom_line.product_id.id,
|
||||
"quantity": 0,
|
||||
"uom_id": bom_line.product_uom_id.id,
|
||||
"company_id": move.company_id.id,
|
||||
},
|
||||
)
|
||||
)
|
||||
res.update(
|
||||
{
|
||||
"move_id": move.id,
|
||||
"line_ids": lines,
|
||||
}
|
||||
)
|
||||
return res
|
||||
|
||||
move_id = fields.Many2one("stock.move")
|
||||
line_ids = fields.One2many("stock.move.distribution.wiz.line", "wizard_id")
|
||||
demand_quantity = fields.Float(related="move_id.product_uom_qty")
|
||||
move_uom_id = fields.Many2one(related="move_id.product_uom")
|
||||
|
||||
def button_distribute_qty(self):
|
||||
self.ensure_one()
|
||||
# Clean actual move lines
|
||||
self.move_id.move_line_ids.sudo().unlink()
|
||||
for line in self.line_ids:
|
||||
# Create new move_lines
|
||||
if line.quantity:
|
||||
self.env["stock.move.line"].create(
|
||||
{
|
||||
"move_id": self.move_id.id,
|
||||
"product_id": line.product_id.id,
|
||||
"qty_done": line.quantity,
|
||||
"product_uom_id": line.uom_id.id,
|
||||
"location_id": self.move_id.location_id.id,
|
||||
"location_dest_id": self.move_id.location_dest_id.id,
|
||||
"picking_id": self.move_id.picking_id.id,
|
||||
"company_id": self.move_id.company_id.id,
|
||||
"lot_id": line.lot_id.id,
|
||||
"result_package_id": line.package_id.id,
|
||||
}
|
||||
)
|
||||
if self.move_id.move_line_ids:
|
||||
self.move_id.state = "assigned"
|
||||
|
||||
|
||||
class StockMoveDistributionWizLine(models.TransientModel):
|
||||
_name = "stock.move.distribution.wiz.line"
|
||||
_description = "Lines of wizard to distribute product qty to diferent products"
|
||||
|
||||
wizard_id = fields.Many2one("stock.move.distribution.wiz")
|
||||
product_id = fields.Many2one("product.product")
|
||||
quantity = fields.Float(digits="Product Unit of Measure")
|
||||
uom_id = fields.Many2one("uom.uom")
|
||||
lot_id = fields.Many2one("stock.production.lot")
|
||||
package_id = fields.Many2one("stock.production.lot")
|
||||
company_id = fields.Many2one("res.company")
|
||||
@@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
<record id="stock_move_distribution_wiz_form" model="ir.ui.view">
|
||||
<field name="name">Stock Move Distribution Wiz Form</field>
|
||||
<field name="model">stock.move.distribution.wiz</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="move_id" invisible="1" />
|
||||
<label for="demand_quantity" />
|
||||
<div>
|
||||
<field name="demand_quantity" />
|
||||
<field name="move_uom_id" groups="uom.group_uom" />
|
||||
</div>
|
||||
</group>
|
||||
<group>
|
||||
<field name="line_ids" nolabel="1">
|
||||
<tree editable="bottom" create="0" delete="0">
|
||||
<field name="company_id" invisible="1" />
|
||||
<field name="product_id" readonly="1" force_save="1" />
|
||||
<field
|
||||
name="lot_id"
|
||||
groups="stock.group_production_lot"
|
||||
domain="[('product_id', '=', product_id), ('company_id', '=', company_id)]"
|
||||
context="{
|
||||
'default_company_id': company_id,
|
||||
'default_product_id': product_id,
|
||||
}"
|
||||
/>
|
||||
<field
|
||||
name="package_id"
|
||||
groups="stock.group_tracking_lot"
|
||||
/>
|
||||
<field name="quantity" />
|
||||
<field name="uom_id" groups="uom.group_uom" />
|
||||
</tree>
|
||||
</field>
|
||||
</group>
|
||||
|
||||
</sheet>
|
||||
<footer>
|
||||
<button
|
||||
name="button_distribute_qty"
|
||||
string="Distribute"
|
||||
type="object"
|
||||
class="oe_highlight"
|
||||
/>
|
||||
<button string="Cancel" class="oe_link" special="cancel" />
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user