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 @@ - - - + + + + + @@ -89,6 +95,18 @@
+ + + + + + + + + + + +