[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:
Carlos Roca
2024-07-09 13:36:22 +02:00
committed by Pedro M. Baeza
parent 0ca8110827
commit 0ea4e392c8
26 changed files with 1461 additions and 0 deletions

View File

@@ -0,0 +1 @@
from . import stock_move_distribution_wiz

View File

@@ -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")

View File

@@ -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>