From d76796bfa757623df9b80a94c6f93829d5bcb348 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phan=20Sainl=C3=A9ger?= Date: Tue, 28 Jun 2022 21:11:05 +0200 Subject: [PATCH] [UPD] Use analytic tags to link incomes/expenses to budget lines instead of a direct budget_forecast field --- account_budget_forecast/__manifest__.py | 1 - account_budget_forecast/models/__init__.py | 1 - .../models/account_analytic_line.py | 14 ++- .../models/account_move.py | 24 ----- .../models/budget_forecast.py | 100 +++++++++++++----- .../views/account_invoice.xml | 13 --- .../views/budget_forecast.xml | 7 +- account_budget_forecast/views/hr_employee.xml | 2 +- .../views/project_views.xml | 2 +- 9 files changed, 94 insertions(+), 70 deletions(-) delete mode 100644 account_budget_forecast/models/account_move.py delete mode 100644 account_budget_forecast/views/account_invoice.xml diff --git a/account_budget_forecast/__manifest__.py b/account_budget_forecast/__manifest__.py index 4d625a4..894f1d3 100644 --- a/account_budget_forecast/__manifest__.py +++ b/account_budget_forecast/__manifest__.py @@ -77,7 +77,6 @@ This module is maintained by ELABORE. "wizard/budget_forecast_model_choice.xml", "views/account_analytic_account.xml", "views/account_analytic_account_categories.xml", - "views/account_invoice.xml", "views/sale_order.xml", "views/budget_forecast.xml", "views/budget_coefficient.xml", diff --git a/account_budget_forecast/models/__init__.py b/account_budget_forecast/models/__init__.py index 8f4db78..cc4dd4b 100644 --- a/account_budget_forecast/models/__init__.py +++ b/account_budget_forecast/models/__init__.py @@ -2,7 +2,6 @@ from . import account_analytic_account from . import account_analytic_line -from . import account_move from . import budget_forecast from . import budget_forecast_model from . import sale_order diff --git a/account_budget_forecast/models/account_analytic_line.py b/account_budget_forecast/models/account_analytic_line.py index be493a7..9223d0a 100644 --- a/account_budget_forecast/models/account_analytic_line.py +++ b/account_budget_forecast/models/account_analytic_line.py @@ -6,4 +6,16 @@ from odoo import models, fields, api class AccountAnalyticLine(models.Model): _inherit = "account.analytic.line" - budget_forecast_id = fields.Many2one("budget.forecast", store=True) + timesheet_entry = fields.Boolean( + help="Technical field to identify analytic lines created from timesheet vies", + store=True, + default=False, + ) + + @api.model_create_multi + def create(self, vals_list): + lines = super(AccountAnalyticLine, self).create(vals_list) + for line, values in zip(lines, vals_list): + if line.project_id: # applied only for timesheet + line.timesheet_entry = True + return lines diff --git a/account_budget_forecast/models/account_move.py b/account_budget_forecast/models/account_move.py deleted file mode 100644 index 212958f..0000000 --- a/account_budget_forecast/models/account_move.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- coding: utf-8 -*- - -from odoo import models, fields, api - - -class AccountMoveLine(models.Model): - _inherit = "account.move.line" - - budget_forecast_id = fields.Many2one( - "budget.forecast", - string="Budget line", - index=True, - store=True, - readonly=False, - copy=False, - ) - - @api.depends("budget_forecast_id") - def _transfer_budget_forecast_line(self): - for record in self: - import pdb - - pdb.set_trace() - record.analytic_line_ids.budget_forecast_id = record.budget_forecast_id.id diff --git a/account_budget_forecast/models/budget_forecast.py b/account_budget_forecast/models/budget_forecast.py index 304005a..0d4182c 100644 --- a/account_budget_forecast/models/budget_forecast.py +++ b/account_budget_forecast/models/budget_forecast.py @@ -19,6 +19,13 @@ class BudgetForecast(models.Model): index=True, copy=True, ) + analytic_tag = fields.Many2one( + "account.analytic.tag", + "Analytic tag", + index=True, + copy=False, + ondelete="cascade", + ) budget_category = fields.Selection( [ @@ -61,9 +68,6 @@ class BudgetForecast(models.Model): copy=False, ) - analytic_line_ids = fields.One2many( - "account.analytic.line", "budget_forecast_id", copy=False - ) actual_qty = fields.Float( "Actual Quantity", compute="_calc_actual", @@ -114,6 +118,9 @@ class BudgetForecast(models.Model): "line_subsection", ]: record._create_category_sections() + record.analytic_tag = self.env["account.analytic.tag"].create( + {"name": record._calculate_name()} + ) return records def _create_category_sections(self): @@ -193,6 +200,12 @@ class BudgetForecast(models.Model): values = {"name": record._calculate_name()} record.write(values, False) + @api.onchange("name") + def _compute_analytic_tag_name(self): + for record in self: + if record.analytic_tag: + record.analytic_tag.name = record.name + def _sync_sections_data(self): for record in self: if record.display_type in ["line_section", "line_subsection"]: @@ -329,29 +342,66 @@ class BudgetForecast(models.Model): elif record.display_type == "line_note": record.plan_price = 0.00 + def _find_analytic_lines(self, move_type, with_timesheets=False): + self.ensure_one() + if with_timesheets: + domain = [ + "|", + ( + "move_id.move_id.move_type", + "in", + move_type, + ), + ("timesheet_entry", "=", True), + ] + else: + domain = [ + ( + "move_id.move_id.move_type", + "in", + move_type, + ) + ] + analytic_lines = ( + self.env["account.analytic.line"] + .search(domain) + .filtered(lambda x: self.analytic_tag in x.tag_ids) + ) + return analytic_lines + + def _find_draft_invoice_lines(self, move_type): + self.ensure_one() + domain = [ + ("analytic_account_id", "=", self.analytic_id.id), + ("parent_state", "in", ["draft"]), + ("move_id.move_type", "in", move_type), + ] + invoice_lines = ( + self.env["account.move.line"] + .search(domain) + .filtered(lambda x: self.analytic_tag in x.analytic_tag_ids) + ) + return invoice_lines + @api.depends("analytic_id.line_ids.amount") def _calc_actual(self): for record in self: + # Section or Sub-section if record.display_type in ["line_section", "line_subsection"]: if record.child_ids: # Actual expenses are calculated with the child lines record.actual_qty = sum(record.mapped("child_ids.actual_qty")) record.actual_amount = sum(record.mapped("child_ids.actual_amount")) + # Incomes are calculated with the analytic lines - line_ids = record.analytic_line_ids.filtered( - lambda x: x.move_id.move_id.move_type - in ["out_invoice", "out_refund"] + line_ids = record._find_analytic_lines( + ["out_invoice", "out_refund", "out_receipt"] ) record.incomes = sum(line_ids.mapped("amount")) - - # Add Invoice lines ids - domain = [ - ("analytic_account_id", "=", record.analytic_id.id), - ("parent_state", "in", ["draft", "posted"]), - ("budget_forecast_id", "=", record.id), - ("move_id.move_type", "in", ["out_invoice", "out_refund"]), - ] - invoice_lines = self.env["account.move.line"].search(domain) + # Add Draft Invoice lines ids to incomes + invoice_lines = record._find_draft_invoice_lines( + ["out_invoice", "out_refund"] + ) for invoice_line in invoice_lines: if invoice_line.move_id.move_type == "out_invoice": record.incomes = ( @@ -363,25 +413,23 @@ class BudgetForecast(models.Model): ) record.balance = record.incomes - record.actual_amount + # Note elif record.display_type == "line_note": record.actual_qty = 0 record.actual_amount = 0.00 + + # Product else: - line_ids = record.analytic_line_ids.filtered( - lambda x: x.move_id.move_id.move_type - not in ["out_invoice", "out_refund"] + line_ids = record._find_analytic_lines( + ["in_invoice", "in_refund", "in_receipt"], True ) record.actual_qty = abs(sum(line_ids.mapped("unit_amount"))) record.actual_amount = -sum(line_ids.mapped("amount")) - # Add Invoice lines ids - domain = [ - ("analytic_account_id", "=", record.analytic_id.id), - ("parent_state", "in", ["draft", "posted"]), - ("budget_forecast_id", "=", record.id), - ("move_id.move_type", "in", ["in_invoice", "in_refund"]), - ] - invoice_lines = self.env["account.move.line"].search(domain) + # Add Draft Invoice lines ids + invoice_lines = record._find_draft_invoice_lines( + ["in_invoice", "in_refund"] + ) for invoice_line in invoice_lines: if invoice_line.move_id.move_type == "in_invoice": record.actual_qty = record.actual_qty + invoice_line.quantity diff --git a/account_budget_forecast/views/account_invoice.xml b/account_budget_forecast/views/account_invoice.xml deleted file mode 100644 index 45c83bf..0000000 --- a/account_budget_forecast/views/account_invoice.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - account.invoice.budget.form - account.move - - - - - - - - \ No newline at end of file diff --git a/account_budget_forecast/views/budget_forecast.xml b/account_budget_forecast/views/budget_forecast.xml index c2159c9..7534ee4 100644 --- a/account_budget_forecast/views/budget_forecast.xml +++ b/account_budget_forecast/views/budget_forecast.xml @@ -9,8 +9,10 @@ + + @@ -36,7 +38,8 @@ - + + diff --git a/account_budget_forecast/views/hr_employee.xml b/account_budget_forecast/views/hr_employee.xml index b5b6c61..8186c99 100644 --- a/account_budget_forecast/views/hr_employee.xml +++ b/account_budget_forecast/views/hr_employee.xml @@ -8,7 +8,7 @@ - + diff --git a/account_budget_forecast/views/project_views.xml b/account_budget_forecast/views/project_views.xml index 9d33407..caa5acd 100644 --- a/account_budget_forecast/views/project_views.xml +++ b/account_budget_forecast/views/project_views.xml @@ -6,7 +6,7 @@ - +