diff --git a/.vscode/launch.json b/.vscode/launch.json
index 16c1cd5..874d31d 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -2,7 +2,7 @@
"version": "0.2.0",
"configurations": [
{
- "name": "odoo-dev-16.0",
+ "name": "odoo-dev",
"type": "python",
"request": "launch",
"cwd": "${workspaceRoot}",
@@ -17,6 +17,24 @@
// "--update=",
"--dev=xml"
]
+ },
+ {
+ "name": "odoo-scratch",
+ "type": "python",
+ "request": "launch",
+ "cwd": "${workspaceRoot}",
+ "program": "${config:odoo.path}/odoo-bin",
+ "console": "integratedTerminal",
+ "args": [
+ "--database=odoo-scratch",
+ "--http-port=9069",
+ "--addons-path=${config:odoo.addons_path}",
+ "--limit-time-real=0",
+ "--limit-time-cpu=0",
+ "--init=sale_order_batch",
+ // "--update=",
+ "--dev=xml"
+ ]
}
]
}
diff --git a/sale_order_batch/__manifest__.py b/sale_order_batch/__manifest__.py
index e796887..2c1b66b 100644
--- a/sale_order_batch/__manifest__.py
+++ b/sale_order_batch/__manifest__.py
@@ -5,7 +5,7 @@
"website": "https://www.bakeup.org",
"category": "Sale",
"version": "16.0.0.0.1",
- "depends": ["sale"],
+ "depends": ["sale", "product"],
"data": [
"data/ir_sequence_data.xml",
"views/sale_order_batch_views.xml",
diff --git a/sale_order_batch/models/__init__.py b/sale_order_batch/models/__init__.py
index da2267a..03035b7 100644
--- a/sale_order_batch/models/__init__.py
+++ b/sale_order_batch/models/__init__.py
@@ -1,3 +1,5 @@
+from . import product_product
from . import sale_order
from . import sale_order_batch
-from . import product_product
+from . import sale_order_batch_product
+from . import sale_order_line
diff --git a/sale_order_batch/models/sale_order.py b/sale_order_batch/models/sale_order.py
index 8205447..91f9a77 100644
--- a/sale_order_batch/models/sale_order.py
+++ b/sale_order_batch/models/sale_order.py
@@ -18,15 +18,16 @@ class SaleOrder(models.Model):
if not sale_order.batch_id and sale_order.state in ["draft", "sent"]:
sale_order.batch_id = batch
- def write(self, vals):
- if "batch_id" in vals:
- invalid_orders = []
- for order in self:
- if order.state not in ["draft", "sent"]:
- invalid_orders.append(order.name)
- if invalid_orders:
- raise UserError(_(f"Sale Order not in State Draft or Sent: {', '.join(invalid_orders)}"))
- return super().write(vals)
+ def action_view_sale_order_batch(self):
+ return {
+ "name": _("Sale Order Batch"),
+ "type": "ir.actions.act_window",
+ "view_type": "form",
+ "view_mode": "form",
+ "res_model": "sale.order.batch",
+ "res_id": self.batch_id.id,
+ # 'target': '',
+ }
def action_confirm(self):
invalid_orders = []
@@ -38,13 +39,15 @@ class SaleOrder(models.Model):
raise UserError(_(f"Sale Order belongs to a Batch: {', '.join(invalid_orders)}"))
return super().action_confirm()
- def action_view_sale_order_batch(self):
- return {
- "name": _("Sale Order Batch"),
- "type": "ir.actions.act_window",
- "view_type": "form",
- "view_mode": "form",
- "res_model": "sale.order.batch",
- "res_id": self.batch_id.id,
- # 'target': '',
- }
+ def write(self, vals):
+ if "batch_id" in vals:
+ invalid_orders = []
+ for order in self:
+ if order.state not in ["draft", "sent"]:
+ invalid_orders.append(order.name)
+ if invalid_orders:
+ raise UserError(_(f"Sale Order not in State Draft or Sent: {', '.join(invalid_orders)}"))
+ res = super().write(vals)
+ if "batch_id" in vals:
+ self.order_line._update_batch_products()
+ return res
diff --git a/sale_order_batch/models/sale_order_batch.py b/sale_order_batch/models/sale_order_batch.py
index bb2069a..dd80479 100644
--- a/sale_order_batch/models/sale_order_batch.py
+++ b/sale_order_batch/models/sale_order_batch.py
@@ -12,6 +12,11 @@ class SaleOrderBatch(models.Model):
_inherit = "mail.thread"
_order = "date_order desc, id desc"
+ # TODO: add company_id to sale order batch
+ # company_id = fields.Many2one(
+ # related='order_id.company_id',
+ # store=True, index=True, precompute=True)
+
name = fields.Char(
string="Order Batch Reference",
required=True,
@@ -43,7 +48,7 @@ class SaleOrderBatch(models.Model):
sale_order_count = fields.Integer(compute="_compute_sale_order_count")
sale_order_line_ids = fields.Many2many("sale.order.line", compute="_compute_sale_order_line_ids", store=True)
amount_total = fields.Float(compute="_compute_amount_total", string="Total")
- product_ids = fields.Many2many("product.product", compute="_compute_product_ids")
+ product_ids = fields.One2many("sale.order.batch.product", "batch_id")
product_count = fields.Integer(compute="_compute_product_count")
@api.depends("sale_order_ids.validity_date")
@@ -59,15 +64,11 @@ class SaleOrderBatch(models.Model):
for batch in self:
batch.sale_order_count = len(batch.sale_order_ids)
- @api.depends("sale_order_ids.order_line")
- def _compute_product_ids(self):
- for sale_order in self:
- sale_order.product_ids = sale_order.sale_order_ids.mapped("order_line").mapped("product_id")
-
@api.depends("sale_order_ids.order_line")
def _compute_sale_order_line_ids(self):
- for sale_order in self:
- sale_order.sale_order_line_ids = sale_order.sale_order_ids.mapped("order_line")
+ for batch in self:
+ order_lines = self.env["sale.order.line"].search([("order_id", "in", batch.sale_order_ids.ids)])
+ batch.sale_order_line_ids = order_lines
@api.depends("sale_order_ids.amount_total")
def _compute_amount_total(self):
diff --git a/sale_order_batch/models/sale_order_batch_product.py b/sale_order_batch/models/sale_order_batch_product.py
new file mode 100644
index 0000000..60a7d86
--- /dev/null
+++ b/sale_order_batch/models/sale_order_batch_product.py
@@ -0,0 +1,46 @@
+from odoo import api, fields, models
+
+
+class SaleOrderBatchProduct(models.Model):
+ """Show Products available in Sale Order Batch"""
+
+ _name = "sale.order.batch.product"
+ _description = "Sale Order Batch Product"
+
+ batch_id = fields.Many2one(
+ comodel_name="sale.order.batch",
+ string="Batch Reference",
+ required=True,
+ ondelete="cascade",
+ index=True,
+ copy=False,
+ )
+
+ product_id = fields.Many2one(comodel_name="product.product", required=True, readonly=False)
+
+ product_template_id = fields.Many2one(
+ "product.template", related="product_id.product_tmpl_id", string="Product Template"
+ )
+ sale_order_line_ids = fields.Many2many("sale.order.line", compute="_compute_sale_order_line_ids")
+ product_uom_category_id = fields.Many2one(related="product_id.uom_id.category_id", depends=["product_id"])
+ product_uom_qty = fields.Float(compute="_compute_uom_qty")
+ product_uom = fields.Many2one(related="product_id.uom_id")
+ product_packaging_id = fields.Many2one("product.packaging")
+ product_packaging_qty = fields.Float(compute="_compute_product_packaging_qty")
+
+ @api.depends("batch_id.sale_order_line_ids")
+ def _compute_sale_order_line_ids(self):
+ for product in self:
+ product.sale_order_line_ids = product.batch_id.sale_order_line_ids.filtered(
+ lambda o: o.product_id == product.product_id
+ )
+
+ @api.depends("batch_id.sale_order_line_ids")
+ def _compute_uom_qty(self):
+ for product in self:
+ product.product_uom_qty = sum(product.sale_order_line_ids.mapped("product_uom_qty"))
+
+ @api.depends("product_packaging_id")
+ def _compute_product_packaging_qty(self):
+ for product in self:
+ product.product_packaging_qty = product.product_packaging_id.qty if product.product_packaging_id else 1
diff --git a/sale_order_batch/models/sale_order_line.py b/sale_order_batch/models/sale_order_line.py
new file mode 100644
index 0000000..1c0c5ae
--- /dev/null
+++ b/sale_order_batch/models/sale_order_line.py
@@ -0,0 +1,21 @@
+from odoo import api, models
+
+
+class SaleOrderLine(models.Model):
+ _inherit = "sale.order.line"
+
+ def _update_batch_products(self):
+ for order_line in self:
+ batch_id = order_line.order_id.batch_id
+ if batch_id:
+ registered_products = batch_id.mapped("product_ids").mapped("product_id")
+ if order_line.product_id not in registered_products:
+ self.env["sale.order.batch.product"].create(
+ {"batch_id": batch_id.id, "product_id": order_line.product_id.id}
+ )
+
+ @api.model_create_multi
+ def create(self, vals_list):
+ res = super().create(vals_list)
+ res._update_batch_products()
+ return res
diff --git a/sale_order_batch/security/ir.model.access.csv b/sale_order_batch/security/ir.model.access.csv
index f8b01b9..899c9f1 100644
--- a/sale_order_batch/security/ir.model.access.csv
+++ b/sale_order_batch/security/ir.model.access.csv
@@ -1,3 +1,4 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_sale_order_batch,sale.order.batch,model_sale_order_batch,sales_team.group_sale_salesman,1,1,1,0
access_sale_order_batch_manager,sale.order.batch.manager,model_sale_order,sales_team.group_sale_manager,1,1,1,1
+access_sale_order_batch_product,sale.order.batch.product,model_sale_order_batch_product,sales_team.group_sale_salesman,1,1,1,1
diff --git a/sale_order_batch/views/sale_order_batch_views.xml b/sale_order_batch/views/sale_order_batch_views.xml
index e324f84..3f7752b 100644
--- a/sale_order_batch/views/sale_order_batch_views.xml
+++ b/sale_order_batch/views/sale_order_batch_views.xml
@@ -70,11 +70,17 @@