diff --git a/put_in_pack_stock/__init__.py b/put_in_pack_stock/__init__.py
new file mode 100644
index 00000000000..0650744f6bc
--- /dev/null
+++ b/put_in_pack_stock/__init__.py
@@ -0,0 +1 @@
+from . import models
diff --git a/put_in_pack_stock/__manifest__.py b/put_in_pack_stock/__manifest__.py
new file mode 100644
index 00000000000..705d4d44048
--- /dev/null
+++ b/put_in_pack_stock/__manifest__.py
@@ -0,0 +1,16 @@
+{
+ 'name': 'Put In Pack -Stock',
+ 'category': 'Stock/PutInPack2',
+ 'summary': 'Full Traceability Report Demo Data',
+ 'author': 'Odoo S.A.',
+ 'depends': ['stock','purchase'],
+ 'description': "Custom put in pack button for Inventory Transfer",
+ 'license': 'LGPL-3',
+ 'installable': True,
+ 'data': [
+ 'views/view_custom_put_in_pack.xml',
+ 'views/view_stock_move_put_in_pack.xml',
+ 'views/stock_move_views.xml',
+ 'views/stock_quant_views.xml',
+ ]
+}
diff --git a/put_in_pack_stock/models/__init__.py b/put_in_pack_stock/models/__init__.py
new file mode 100644
index 00000000000..3c71fd1b863
--- /dev/null
+++ b/put_in_pack_stock/models/__init__.py
@@ -0,0 +1,2 @@
+from . import stock_picking
+from . import stock_move
diff --git a/put_in_pack_stock/models/stock_move.py b/put_in_pack_stock/models/stock_move.py
new file mode 100644
index 00000000000..961db392b21
--- /dev/null
+++ b/put_in_pack_stock/models/stock_move.py
@@ -0,0 +1,82 @@
+from odoo import api, models, fields
+
+
+class StockMove(models.Model):
+ _inherit = 'stock.move'
+
+ put_in_pack_toggle = fields.Boolean(
+ string="Put In Pack",
+ related="picking_type_id.put_in_pack_toggle"
+ )
+ package_qty = fields.Integer(
+ string = "Package Qty:",
+ help="Package Quantity",
+ default=1
+ )
+ package_type = fields.Selection(
+ selection = [
+ ('box', "Box"),
+ ('carton', "Carton")
+ ],
+ string="Package Type",
+ help="Package Type for the Product to be kept in the package."
+ )
+ package_size = fields.Integer(
+ string="Package Size",
+ help="How many quantity of the particular product will go into the package",
+ default=0
+ )
+
+ def action_custom_put_in_pack(self):
+ self.ensure_one()
+ if self.product_uom_qty <= 0:
+ raise UserError("No quantity available to package.")
+ self.move_line_ids.unlink()
+ package = self.env['stock.quant.package'].create({
+ 'name': f"{self.product_id.name} Package"
+ })
+ self.env['stock.move.line'].create({
+ 'move_id': self.id,
+ 'result_package_id': package.id,
+ 'qty_done': self.product_uom_qty,
+ 'product_id': self.product_id.id,
+ 'product_uom_id': self.product_id.uom_id.id,
+ })
+ def action_generate_package(self):
+ self.ensure_one()
+ self.move_line_ids.unlink()
+ if self.has_tracking == 'none':
+ demand = self.product_uom_qty
+ correct_uom = self.product_id.uom_id.id
+ if not correct_uom:
+ raise ValueError(f"Product {self.product_id.name} does not have a valid UoM set!")
+ for _ in range(self.package_qty):
+ if demand <= 0:
+ break
+ package = self.env['stock.quant.package'].create({'name': f"{self.product_id.name} Package"})
+ qty_to_pack = min(demand, self.package_size)
+ move_line = self.env['stock.move.line'].create({
+ 'move_id': self.id,
+ 'result_package_id': package.id,
+ 'qty_done': qty_to_pack,
+ 'product_id': self.product_id.id,
+ 'product_uom_id': correct_uom,
+ })
+ demand -= qty_to_pack
+ elif self.has_tracking=='lot':
+ correct_uom = self.product_id.uom_id.id
+ for line in self.move_line_ids:
+ lot_quantity = line.quantity
+ while lot_quantity:
+ package = self.env['stock.quant.package'].create({'name': f"{self.product_id.name} Package"})
+ qty_to_pack = min(lot_quantity, self.package_size)
+ move_line = self.env['stock.move.line'].create({
+ 'move_id': self.id,
+ 'lot_id': line.lot_id.id,
+ 'lot_name': line.lot_name,
+ 'result_package_id': package.id,
+ 'qty_done': qty_to_pack,
+ 'product_id': self.product_id.id,
+ 'product_uom_id': correct_uom,
+ })
+ lot_quantity -= qty_to_pack
diff --git a/put_in_pack_stock/models/stock_picking.py b/put_in_pack_stock/models/stock_picking.py
new file mode 100644
index 00000000000..47ab5f5f9e2
--- /dev/null
+++ b/put_in_pack_stock/models/stock_picking.py
@@ -0,0 +1,16 @@
+from odoo import fields, models
+
+
+class PickingType(models.Model):
+ _inherit = "stock.picking.type"
+
+ put_in_pack_toggle = fields.Boolean(
+ string = "Put In Pack"
+ )
+
+class Picking(models.Model):
+ _inherit = "stock.picking"
+
+ put_in_pack_toggle = fields.Boolean(
+ related="picking_type_id.put_in_pack_toggle"
+ )
diff --git a/put_in_pack_stock/views/stock_move_views.xml b/put_in_pack_stock/views/stock_move_views.xml
new file mode 100644
index 00000000000..895b8d9479e
--- /dev/null
+++ b/put_in_pack_stock/views/stock_move_views.xml
@@ -0,0 +1,17 @@
+
+
+ Detailed Operation Inherit
+ stock.move
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/put_in_pack_stock/views/stock_quant_views.xml b/put_in_pack_stock/views/stock_quant_views.xml
new file mode 100644
index 00000000000..5bcba2af54d
--- /dev/null
+++ b/put_in_pack_stock/views/stock_quant_views.xml
@@ -0,0 +1,12 @@
+
+
+ stock.quant.tree.inherit
+ stock.quant
+
+
+
+
+
+
+
+
diff --git a/put_in_pack_stock/views/view_custom_put_in_pack.xml b/put_in_pack_stock/views/view_custom_put_in_pack.xml
new file mode 100644
index 00000000000..fff44e6eab9
--- /dev/null
+++ b/put_in_pack_stock/views/view_custom_put_in_pack.xml
@@ -0,0 +1,12 @@
+
+
+ Operation types Inherit
+ stock.picking.type
+
+
+
+
+
+
+
+
diff --git a/put_in_pack_stock/views/view_stock_move_put_in_pack.xml b/put_in_pack_stock/views/view_stock_move_put_in_pack.xml
new file mode 100644
index 00000000000..80a155edaa3
--- /dev/null
+++ b/put_in_pack_stock/views/view_stock_move_put_in_pack.xml
@@ -0,0 +1,24 @@
+
+
+ stock.picking.form.inherit
+ stock.picking
+
+
+
+
+
+
+
+ parent.put_in_pack_toggle
+
+
+ state in ('draft', 'done', 'cancel') or put_in_pack_toggle
+
+
+
+