Skip to content

Commit 7456022

Browse files
committed
[ADD] put_in_pack_stock: Created custom put in pack module
- **Custom Put in Pack Button:** - Added a button in stock move list to package the full line quantity. - Removed existing move lines before creating a new packaged one. - **Detailed Operations Wizard Update:** - Updated the detailed operations wizard from the hamburger button. - Added fields for package quantity, package size, and package type. - Integrated a "Generate Packages" button inside the wizard. - **Lot Number Handling:** - Implemented logic for both **quantity-tracked** and **lot-tracked** products. - Assigned packages correctly for each lot while distributing quantities.. - **Inventory View Enhancements:** - Added a **Group By Packaging** filter in Inventory Locations view. - Allows users to view stock grouped by packaging type.
1 parent 4c650f3 commit 7456022

9 files changed

+182
-0
lines changed

Diff for: put_in_pack_stock/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from . import models

Diff for: put_in_pack_stock/__manifest__.py

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
'name': 'Put In Pack -Stock',
3+
'category': 'Stock/PutInPack2',
4+
'summary': 'Full Traceability Report Demo Data',
5+
'author': 'Odoo S.A.',
6+
'depends': ['stock','purchase'],
7+
'description': "Custom put in pack button for Inventory Transfer",
8+
'license': 'LGPL-3',
9+
'installable': True,
10+
'data': [
11+
'views/view_custom_put_in_pack.xml',
12+
'views/view_stock_move_put_in_pack.xml',
13+
'views/stock_move_views.xml',
14+
'views/stock_quant_views.xml',
15+
]
16+
}

Diff for: put_in_pack_stock/models/__init__.py

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from . import stock_picking
2+
from . import stock_move

Diff for: put_in_pack_stock/models/stock_move.py

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
from odoo import api, models, fields
2+
3+
4+
class StockMove(models.Model):
5+
_inherit = 'stock.move'
6+
7+
put_in_pack_toggle = fields.Boolean(
8+
string="Put In Pack",
9+
related="picking_type_id.put_in_pack_toggle"
10+
)
11+
package_qty = fields.Integer(
12+
string = "Package Qty:",
13+
help="Package Quantity",
14+
default=1
15+
)
16+
package_type = fields.Selection(
17+
selection = [
18+
('box', "Box"),
19+
('carton', "Carton")
20+
],
21+
string="Package Type",
22+
help="Package Type for the Product to be kept in the package."
23+
)
24+
package_size = fields.Integer(
25+
string="Package Size",
26+
help="How many quantity of the particular product will go into the package",
27+
default=0
28+
)
29+
30+
def action_custom_put_in_pack(self):
31+
self.ensure_one()
32+
if self.product_uom_qty <= 0:
33+
raise UserError("No quantity available to package.")
34+
self.move_line_ids.unlink()
35+
package = self.env['stock.quant.package'].create({
36+
'name': f"{self.product_id.name} Package"
37+
})
38+
self.env['stock.move.line'].create({
39+
'move_id': self.id,
40+
'result_package_id': package.id,
41+
'qty_done': self.product_uom_qty,
42+
'product_id': self.product_id.id,
43+
'product_uom_id': self.product_id.uom_id.id,
44+
})
45+
def action_generate_package(self):
46+
self.ensure_one()
47+
self.move_line_ids.unlink()
48+
if self.has_tracking == 'none':
49+
demand = self.product_uom_qty
50+
correct_uom = self.product_id.uom_id.id
51+
if not correct_uom:
52+
raise ValueError(f"Product {self.product_id.name} does not have a valid UoM set!")
53+
for _ in range(self.package_qty):
54+
if demand <= 0:
55+
break
56+
package = self.env['stock.quant.package'].create({'name': f"{self.product_id.name} Package"})
57+
qty_to_pack = min(demand, self.package_size)
58+
move_line = self.env['stock.move.line'].create({
59+
'move_id': self.id,
60+
'result_package_id': package.id,
61+
'qty_done': qty_to_pack,
62+
'product_id': self.product_id.id,
63+
'product_uom_id': correct_uom,
64+
})
65+
demand -= qty_to_pack
66+
elif self.has_tracking=='lot':
67+
correct_uom = self.product_id.uom_id.id
68+
for line in self.move_line_ids:
69+
lot_quantity = line.quantity
70+
while lot_quantity:
71+
package = self.env['stock.quant.package'].create({'name': f"{self.product_id.name} Package"})
72+
qty_to_pack = min(lot_quantity, self.package_size)
73+
move_line = self.env['stock.move.line'].create({
74+
'move_id': self.id,
75+
'lot_id': line.lot_id.id,
76+
'lot_name': line.lot_name,
77+
'result_package_id': package.id,
78+
'qty_done': qty_to_pack,
79+
'product_id': self.product_id.id,
80+
'product_uom_id': correct_uom,
81+
})
82+
lot_quantity -= qty_to_pack

Diff for: put_in_pack_stock/models/stock_picking.py

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from odoo import fields, models
2+
3+
4+
class PickingType(models.Model):
5+
_inherit = "stock.picking.type"
6+
7+
put_in_pack_toggle = fields.Boolean(
8+
string = "Put In Pack"
9+
)
10+
11+
class Picking(models.Model):
12+
_inherit = "stock.picking"
13+
14+
put_in_pack_toggle = fields.Boolean(
15+
related="picking_type_id.put_in_pack_toggle"
16+
)

Diff for: put_in_pack_stock/views/stock_move_views.xml

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<odoo>
2+
<record id="view_detailed_operation_custom" model="ir.ui.view">
3+
<field name="name">Detailed Operation Inherit</field>
4+
<field name="model">stock.move</field>
5+
<field name="inherit_id" ref="stock.view_stock_move_operations"/>
6+
<field name="arch" type="xml">
7+
<xpath expr="//form/group/group" position="after">
8+
<group invisible="not put_in_pack_toggle">
9+
<field name="package_qty" invisible="has_tracking not in ('none')"/>
10+
<field name="package_size"/>
11+
<field name="package_type"/>
12+
<button name="action_generate_package" type="object" class="btn-primary" string="Generate Packages"/>
13+
</group>
14+
</xpath>
15+
</field>
16+
</record>
17+
</odoo>

Diff for: put_in_pack_stock/views/stock_quant_views.xml

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<odoo>
2+
<record id="view_stock_quant_tree_inherit" model="ir.ui.view">
3+
<field name="name">stock.quant.tree.inherit</field>
4+
<field name="model">stock.quant</field>
5+
<field name="inherit_id" ref="stock.quant_search_view"/>
6+
<field name="arch" type="xml">
7+
<xpath expr="//filter[@name='company']" position="after">
8+
<filter name="group_by_packaging" string="Packaging" domain="[]" context="{'group_by': 'package_id'}"/>
9+
</xpath>
10+
</field>
11+
</record>
12+
</odoo>

Diff for: put_in_pack_stock/views/view_custom_put_in_pack.xml

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<odoo>
2+
<record id="view_picking_type_tree_inherit" model="ir.ui.view">
3+
<field name="name">Operation types Inherit</field>
4+
<field name="model">stock.picking.type</field>
5+
<field name="inherit_id" ref="stock.view_picking_type_tree" />
6+
<field name="arch" type="xml">
7+
<xpath expr="//field[@name='company_id']" position="before">
8+
<field name="put_in_pack_toggle" string="Put in Pack" widget="boolean_toggle"/>
9+
</xpath>
10+
</field>
11+
</record>
12+
</odoo>
+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<odoo>
2+
<record id="view_picking_form_inherit" model="ir.ui.view">
3+
<field name="name">stock.picking.form.inherit</field>
4+
<field name="model">stock.picking</field>
5+
<field name="inherit_id" ref="stock.view_picking_form" />
6+
<field name="arch" type="xml">
7+
<xpath expr="//page[@name='operations']//field[@name='quantity']" position="before">
8+
<field name="put_in_pack_toggle"/>
9+
<button
10+
name="action_custom_put_in_pack"
11+
class="btn-secondary"
12+
string="Put in pack"
13+
type="object"
14+
invisible="put_in_pack_toggle != True"/>
15+
</xpath>
16+
<xpath expr="//page[@name='operations']//field[@name='product_packaging_id']" position="attributes">
17+
<attribute name="column_invisible">parent.put_in_pack_toggle</attribute>
18+
</xpath>
19+
<xpath expr="//page[@name='operations']//button[@name='action_put_in_pack']" position="attributes">
20+
<attribute name="invisible">state in ('draft', 'done', 'cancel') or put_in_pack_toggle</attribute>
21+
</xpath>
22+
</field>
23+
</record>
24+
</odoo>

0 commit comments

Comments
 (0)