diff --git a/account_move_line_reconcile_manual/__init__.py b/account_move_line_reconcile_manual/__init__.py index 5cb1c491..aee8895e 100644 --- a/account_move_line_reconcile_manual/__init__.py +++ b/account_move_line_reconcile_manual/__init__.py @@ -1 +1,2 @@ +from . import models from . import wizards diff --git a/account_move_line_reconcile_manual/__manifest__.py b/account_move_line_reconcile_manual/__manifest__.py index 16550a8f..2be466c7 100644 --- a/account_move_line_reconcile_manual/__manifest__.py +++ b/account_move_line_reconcile_manual/__manifest__.py @@ -15,6 +15,7 @@ "data": [ "security/ir.model.access.csv", "wizards/account_move_line_reconcile_manual_view.xml", + "views/account_reconcile_manual_model.xml", "views/account_move_line.xml", ], "installable": True, diff --git a/account_move_line_reconcile_manual/models/__init__.py b/account_move_line_reconcile_manual/models/__init__.py new file mode 100644 index 00000000..d7359db7 --- /dev/null +++ b/account_move_line_reconcile_manual/models/__init__.py @@ -0,0 +1 @@ +from . import account_reconcile_manual_model diff --git a/account_move_line_reconcile_manual/models/account_reconcile_manual_model.py b/account_move_line_reconcile_manual/models/account_reconcile_manual_model.py new file mode 100644 index 00000000..1df95362 --- /dev/null +++ b/account_move_line_reconcile_manual/models/account_reconcile_manual_model.py @@ -0,0 +1,99 @@ +# Copyright 2023 Akretion France (http://www.akretion.com/) +# @author: Alexis de Lattre +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import api, fields, models + + +class AccountReconcileManualModel(models.Model): + _name = "account.reconcile.manual.model" + _description = "Models for Manual Reconcile Write-off" + _check_company_auto = True + _rec_name = "ref" + _order = "sequence, id" + + sequence = fields.Integer() + company_id = fields.Many2one( + "res.company", ondelete="cascade", required=True, index=True + ) + ref = fields.Char(string="Write-off Reference", required=True) + expense_account_id = fields.Many2one( + "account.account", + string="Expense Write-off Account", + required=True, + domain="[('company_id', '=', company_id), ('deprecated', '=', False), " + "('internal_group', '=', 'expense')]", + check_company=True, + ) + income_account_id = fields.Many2one( + "account.account", + string="Income Write-off Account", + required=True, + domain="[('company_id', '=', company_id), ('deprecated', '=', False), " + "('internal_group', '=', 'income')]", + check_company=True, + ) + expense_analytic_distribution = fields.Json( + string="Analytic for Expense", + compute="_compute_analytic_distribution", + store=True, + readonly=False, + precompute=True, + ) + income_analytic_distribution = fields.Json( + string="Analytic for Income", + compute="_compute_analytic_distribution", + store=True, + readonly=False, + precompute=True, + ) + analytic_precision = fields.Integer( + default=lambda self: self.env["decimal.precision"].precision_get( + "Percentage Analytic" + ), + ) + journal_id = fields.Many2one( + "account.journal", + string="Write-off Journal", + required=True, + domain="[('type', '=', 'general'), ('company_id', '=', company_id)]", + check_company=True, + ) + + _sql_constraints = [ + ( + "ref_company_uniq", + "unique(ref, company_id)", + "This write-off model already exists in this company!", + ) + ] + + @api.model + def default_get(self, fields_list): + res = super().default_get(fields_list) + res["company_id"] = self.env.company.id + journals = self.env["account.journal"].search( + [("company_id", "=", res["company_id"]), ("type", "=", "general")] + ) + if len(journals) == 1: + res["journal_id"] = journals.id + return res + + @api.depends("expense_account_id", "income_account_id") + def _compute_analytic_distribution(self): + aadmo = self.env["account.analytic.distribution.model"] + for model in self: + expense_distri = aadmo._get_distribution( + { + "account_prefix": model.expense_account_id.code, + "company_id": model.company_id.id, + } + ) + income_distri = aadmo._get_distribution( + { + "account_prefix": model.income_account_id.code, + "company_id": model.company_id.id, + } + ) + model.expense_analytic_distribution = expense_distri + model.income_analytic_distribution = income_distri diff --git a/account_move_line_reconcile_manual/security/ir.model.access.csv b/account_move_line_reconcile_manual/security/ir.model.access.csv index 8f52a05f..cec140b6 100644 --- a/account_move_line_reconcile_manual/security/ir.model.access.csv +++ b/account_move_line_reconcile_manual/security/ir.model.access.csv @@ -1,2 +1,4 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_account_reconcile_manual_model_full,Full access on account.reconcile.manual.model,model_account_reconcile_manual_model,account.group_account_manager,1,1,1,1 +access_account_reconcile_manual_model_read,Read access on account.reconcile.manual.model,model_account_reconcile_manual_model,account.group_account_user,1,0,0,0 access_account_move_line_reconcile_manual,Full access on account.move.line.reconcile.manual wizard,model_account_move_line_reconcile_manual,account.group_account_user,1,1,1,1 diff --git a/account_move_line_reconcile_manual/views/account_reconcile_manual_model.xml b/account_move_line_reconcile_manual/views/account_reconcile_manual_model.xml new file mode 100644 index 00000000..326dce13 --- /dev/null +++ b/account_move_line_reconcile_manual/views/account_reconcile_manual_model.xml @@ -0,0 +1,98 @@ + + + + + + account.reconcile.manual.model + +
+ + + + + + + + + + +
+
+
+ + + account.reconcile.manual.model + + + + + + + + + + + + + + + + account.reconcile.manual.model + + + + + + + + + + + + + + Write-off Models + account.reconcile.manual.model + tree,form + + + + +
diff --git a/account_move_line_reconcile_manual/wizards/account_move_line_reconcile_manual.py b/account_move_line_reconcile_manual/wizards/account_move_line_reconcile_manual.py index 2621b2b6..c6c91b60 100644 --- a/account_move_line_reconcile_manual/wizards/account_move_line_reconcile_manual.py +++ b/account_move_line_reconcile_manual/wizards/account_move_line_reconcile_manual.py @@ -14,7 +14,6 @@ class AccountMoveLineReconcileManual(models.TransientModel): _name = "account.move.line.reconcile.manual" _description = "Manual Reconciliation Wizard" _check_company_auto = True - _inherit = "analytic.mixin" account_id = fields.Many2one( "account.account", required=True, readonly=True, check_company=True @@ -38,14 +37,31 @@ class AccountMoveLineReconcileManual(models.TransientModel): default="start", ) # START WRITE-OFF FIELDS + writeoff_model_id = fields.Many2one( + "account.reconcile.manual.model", + string="Model", + domain="[('company_id', '=', company_id)]", + check_company=True, + ) writeoff_journal_id = fields.Many2one( "account.journal", + compute="_compute_writeoff", + readonly=False, + store=True, + precompute=True, string="Journal", domain="[('type', '=', 'general'), ('company_id', '=', company_id)]", check_company=True, ) writeoff_date = fields.Date(string="Date", default=fields.Date.context_today) - writeoff_ref = fields.Char(string="Reference", default=lambda self: _("Write-off")) + writeoff_ref = fields.Char( + compute="_compute_writeoff", + readonly=False, + store=True, + precompute=True, + string="Reference", + default=lambda self: _("Write-off"), + ) writeoff_type = fields.Selection( [ ("income", "Income"), @@ -60,28 +76,64 @@ class AccountMoveLineReconcileManual(models.TransientModel): ) writeoff_account_id = fields.Many2one( "account.account", + compute="_compute_writeoff", + readonly=False, + store=True, + precompute=True, string="Write-off Account", domain="[('company_id', '=', company_id), ('deprecated', '=', False)]", check_company=True, ) + writeoff_analytic_distribution = fields.Json( + string="Analytic", + compute="_compute_writeoff_analytic_distribution", + readonly=False, + store=True, + precompute=True, + ) + analytic_precision = fields.Integer( + default=lambda self: self.env["decimal.precision"].precision_get( + "Percentage Analytic" + ), + ) - @api.depends("writeoff_account_id", "partner_id") - def _compute_analytic_distribution(self): + @api.depends("writeoff_model_id") + def _compute_writeoff(self): + for wiz in self: + if wiz.writeoff_model_id: + model = wiz.writeoff_model_id + wiz.writeoff_journal_id = model.journal_id + wiz.writeoff_ref = model.ref + if wiz.writeoff_type == "expense": + wiz.writeoff_account_id = model.expense_account_id.id + if model.expense_analytic_distribution: + wiz.writeoff_analytic_distribution = ( + model.expense_analytic_distribution + ) + elif wiz.writeoff_type == "income": + wiz.writeoff_account_id = model.income_account_id.id + if model.income_analytic_distribution: + wiz.writeoff_analytic_distribution = ( + model.income_analytic_distribution + ) + else: + journals = self.env["account.journal"].search( + [("type", "=", "general"), ("company_id", "=", wiz.company_id.id)] + ) + if len(journals) == 1: + wiz.writeoff_journal_id = journals.id + + @api.depends("writeoff_account_id") + def _compute_writeoff_analytic_distribution(self): aadmo = self.env["account.analytic.distribution.model"] for wiz in self: - if wiz.writeoff_account_id: - partner = wiz.partner_id - distribution = aadmo._get_distribution( + if wiz.writeoff_account_id and not wiz.writeoff_analytic_distribution: + wiz.writeoff_analytic_distribution = aadmo._get_distribution( { - "partner_id": partner and partner.id or False, - "partner_category_id": partner - and partner.category_id.ids - or False, "account_prefix": wiz.writeoff_account_id.code, "company_id": wiz.company_id.id, } ) - wiz.analytic_distribution = distribution or wiz.analytic_distribution @api.model def default_get(self, fields_list): @@ -141,12 +193,6 @@ class AccountMoveLineReconcileManual(models.TransientModel): writeoff_type = "income" else: writeoff_type = "none" - general_journals = self.env["account.journal"].search( - [("type", "=", "general"), ("company_id", "=", company.id)] - ) - writeoff_journal_id = False - if len(general_journals) == 1: - writeoff_journal_id = general_journals.id res.update( { "count": count, @@ -159,7 +205,6 @@ class AccountMoveLineReconcileManual(models.TransientModel): "move_line_ids": move_lines.ids, "writeoff_type": writeoff_type, "writeoff_amount": writeoff_amount, - "writeoff_journal_id": writeoff_journal_id, } ) return res @@ -233,7 +278,7 @@ class AccountMoveLineReconcileManual(models.TransientModel): "partner_id": self.partner_id and self.partner_id.id or False, "debit": credit, "credit": debit, - "analytic_distribution": self.analytic_distribution, + "analytic_distribution": self.writeoff_analytic_distribution, }, ), ], diff --git a/account_move_line_reconcile_manual/wizards/account_move_line_reconcile_manual_view.xml b/account_move_line_reconcile_manual/wizards/account_move_line_reconcile_manual_view.xml index ebd8b73a..0640f959 100644 --- a/account_move_line_reconcile_manual/wizards/account_move_line_reconcile_manual_view.xml +++ b/account_move_line_reconcile_manual/wizards/account_move_line_reconcile_manual_view.xml @@ -31,6 +31,7 @@ +