From 83b67577120e85120298f6cc41e9d65676327715 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?NIels=20G=C3=B6ttsch?= Date: Tue, 4 Mar 2025 22:25:11 +0100 Subject: [PATCH] [WIP] sale_order_batch: restructure batch product --- .vscode/launch.json | 40 +++++++++++++++++++ sale_order_batch/models/__init__.py | 1 - sale_order_batch/models/product_product.py | 7 ---- sale_order_batch/models/sale_order.py | 20 ++++------ sale_order_batch/models/sale_order_batch.py | 8 +--- .../models/sale_order_batch_product.py | 14 +++---- sale_order_batch/models/sale_order_line.py | 23 +++++++---- 7 files changed, 70 insertions(+), 43 deletions(-) create mode 100644 .vscode/launch.json delete mode 100644 sale_order_batch/models/product_product.py diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..bdc540b --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,40 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "odoo-dev", + "type": "debugpy", + "request": "launch", + "cwd": "${workspaceRoot}", + "program": "${config:odoo.path}/odoo-bin", + "console": "integratedTerminal", + "args": [ + "--database=nfu_cleanup", + "--addons-path=${config:odoo.addons_path},${workspaceFolder}", + "--limit-time-real=0", + "--limit-time-cpu=0", + // "--init=stock", + "--update=sale_order_batch,sale_order_batch_stock", + "--dev=xml" + ] + }, + { + "name": "odoo-scratch", + "type": "debugpy", + "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=", + // "--update=", + "--dev=xml" + ] + } + ] +} diff --git a/sale_order_batch/models/__init__.py b/sale_order_batch/models/__init__.py index 03035b7..53efcfd 100644 --- a/sale_order_batch/models/__init__.py +++ b/sale_order_batch/models/__init__.py @@ -1,4 +1,3 @@ -from . import product_product from . import sale_order from . import sale_order_batch from . import sale_order_batch_product diff --git a/sale_order_batch/models/product_product.py b/sale_order_batch/models/product_product.py deleted file mode 100644 index 37735c0..0000000 --- a/sale_order_batch/models/product_product.py +++ /dev/null @@ -1,7 +0,0 @@ -from odoo import fields, models - - -class ProductProduct(models.Model): - _inherit = "product.product" - - batch_ids = fields.Many2many("sale.order.batch", "product_ids") diff --git a/sale_order_batch/models/sale_order.py b/sale_order_batch/models/sale_order.py index abeab6c..c6fa7de 100644 --- a/sale_order_batch/models/sale_order.py +++ b/sale_order_batch/models/sale_order.py @@ -11,14 +11,15 @@ class SaleOrder(models.Model): """ TODO: Add Wizard to choose between batches if more than one existis. Picking the first one for now. """ - self = self.with_company(self.company_id) - batch = self.env["sale.order.batch"].search( - [("state", "=", "open"), ("company_id", "=", self.company_id.id)], limit=1 - ) - if not batch: - batch = self.env["sale.order.batch"].create({}) for sale_order in self: + company = sale_order.company_id + sale_order = sale_order.with_company(company) + batch = self.env["sale.order.batch"].search( + [("state", "=", "open"), ("company_id", "=", company.id)], limit=1 + ) if not sale_order.batch_id and sale_order.state in ["draft", "sent"]: + if not batch: + batch = sale_order.env["sale.order.batch"].create({}) sale_order.batch_id = batch def action_view_sale_order_batch(self): @@ -29,7 +30,6 @@ class SaleOrder(models.Model): "view_mode": "form", "res_model": "sale.order.batch", "res_id": self.batch_id.id, - # 'target': '', } def action_confirm(self): @@ -41,9 +41,3 @@ class SaleOrder(models.Model): if invalid_orders: raise UserError(_(f"Sale Order belongs to a Batch: {', '.join(invalid_orders)}")) return super().action_confirm() - - def write(self, vals): - res = super().write(vals) - if vals.get("batch_id"): - self.order_line._update_batch_product() - return res diff --git a/sale_order_batch/models/sale_order_batch.py b/sale_order_batch/models/sale_order_batch.py index 22e509e..b368dfc 100644 --- a/sale_order_batch/models/sale_order_batch.py +++ b/sale_order_batch/models/sale_order_batch.py @@ -46,7 +46,7 @@ class SaleOrderBatch(models.Model): ) sale_order_ids = fields.One2many("sale.order", "batch_id") 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) + sale_order_line_ids = fields.One2many("sale.order.line", "batch_id") invoice_ids = fields.Many2many("account.move", compute="_compute_invoice_ids") invoice_count = fields.Integer(compute="_compute_invoice_ids") amount_total = fields.Float(compute="_compute_amount_total", string="Total") @@ -54,12 +54,6 @@ class SaleOrderBatch(models.Model): product_count = fields.Integer(compute="_compute_product_count") partner_credit_warning = fields.Text(compute="_compute_partner_credit_warning") - @api.depends("sale_order_ids.order_line") - def _compute_sale_order_line_ids(self): - 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") def _compute_sale_order_count(self): for batch in self: diff --git a/sale_order_batch/models/sale_order_batch_product.py b/sale_order_batch/models/sale_order_batch_product.py index a259a84..a6fae16 100644 --- a/sale_order_batch/models/sale_order_batch_product.py +++ b/sale_order_batch/models/sale_order_batch_product.py @@ -17,26 +17,24 @@ class SaleOrderBatchProduct(models.Model): readonly=True, ) + # TODO: compute and store product_id = fields.Many2one(comodel_name="product.product", required=True, readonly=True) 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", store=True, readonly=False - ) + sale_order_line_ids = fields.One2many("sale.order.line", "batch_product_id") 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", string="Quantity") 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): + @api.depends("sale_order_line_ids") + def _update_batch_products(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 - ) + if not product.sale_order_line_ids: + product.unlink() @api.depends("sale_order_line_ids.product_uom_qty") def _compute_uom_qty(self): diff --git a/sale_order_batch/models/sale_order_line.py b/sale_order_batch/models/sale_order_line.py index 85ceb75..c1740b0 100644 --- a/sale_order_batch/models/sale_order_line.py +++ b/sale_order_batch/models/sale_order_line.py @@ -5,19 +5,28 @@ class SaleOrderLine(models.Model): _inherit = "sale.order.line" batch_id = fields.Many2one(related="order_id.batch_id") + batch_product_id = fields.Many2one("sale.order.batch.product") + # TODO: + # - recompute values on batchproduct + # - check for last item on unlink or removal ob batch_id and remove batch_product_id + @api.depends("batch_id", "batch_product_id") def _update_batch_product(self): - for order_line in self: - batch_id = order_line.order_id.batch_id + for line in self: + batch_id = line.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} + batch_product = line.env["sale.order.batch.product"].search( + [("product_id", "=", line.product_id.id), ("batch_id", "=", batch_id.id)] + ) + if not batch_product: + batch_product = line.env["sale.order.batch.product"].create( + {"batch_id": batch_id.id, "product_id": line.product_id.id} ) @api.model_create_multi def create(self, vals_list): res = super().create(vals_list) - res._update_batch_product() + for line in res: + if line.batch_id: + res._update_batch_product() return res