Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[16.0] account_move_line_reconcile_manual: add write-off models #597

Merged
merged 1 commit into from
Oct 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions account_move_line_reconcile_manual/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
from . import models
from . import wizards
1 change: 1 addition & 0 deletions account_move_line_reconcile_manual/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions account_move_line_reconcile_manual/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import account_reconcile_manual_model
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Copyright 2023 Akretion France (http://www.akretion.com/)
# @author: Alexis de Lattre <[email protected]>
# 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(

Check warning on line 75 in account_move_line_reconcile_manual/models/account_reconcile_manual_model.py

View check run for this annotation

Codecov / codecov/patch

account_move_line_reconcile_manual/models/account_reconcile_manual_model.py#L73-L75

Added lines #L73 - L75 were not covered by tests
[("company_id", "=", res["company_id"]), ("type", "=", "general")]
)
if len(journals) == 1:
res["journal_id"] = journals.id
return res

Check warning on line 80 in account_move_line_reconcile_manual/models/account_reconcile_manual_model.py

View check run for this annotation

Codecov / codecov/patch

account_move_line_reconcile_manual/models/account_reconcile_manual_model.py#L79-L80

Added lines #L79 - L80 were not covered by tests

@api.depends("expense_account_id", "income_account_id")
def _compute_analytic_distribution(self):
aadmo = self.env["account.analytic.distribution.model"]

Check warning on line 84 in account_move_line_reconcile_manual/models/account_reconcile_manual_model.py

View check run for this annotation

Codecov / codecov/patch

account_move_line_reconcile_manual/models/account_reconcile_manual_model.py#L84

Added line #L84 was not covered by tests
for model in self:
expense_distri = aadmo._get_distribution(

Check warning on line 86 in account_move_line_reconcile_manual/models/account_reconcile_manual_model.py

View check run for this annotation

Codecov / codecov/patch

account_move_line_reconcile_manual/models/account_reconcile_manual_model.py#L86

Added line #L86 was not covered by tests
{
"account_prefix": model.expense_account_id.code,
"company_id": model.company_id.id,
}
)
income_distri = aadmo._get_distribution(

Check warning on line 92 in account_move_line_reconcile_manual/models/account_reconcile_manual_model.py

View check run for this annotation

Codecov / codecov/patch

account_move_line_reconcile_manual/models/account_reconcile_manual_model.py#L92

Added line #L92 was not covered by tests
{
"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

Check warning on line 99 in account_move_line_reconcile_manual/models/account_reconcile_manual_model.py

View check run for this annotation

Codecov / codecov/patch

account_move_line_reconcile_manual/models/account_reconcile_manual_model.py#L98-L99

Added lines #L98 - L99 were not covered by tests
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
Copyright 2023 Akretion France (http://www.akretion.com/)
@author: Alexis de Lattre <[email protected]>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo>

<record id="account_reconcile_manual_model_form" model="ir.ui.view">
<field name="model">account.reconcile.manual.model</field>
<field name="arch" type="xml">
<form>
<group name="main">
<field name="company_id" invisible="1" />
<field name="ref" />
<field name="expense_account_id" />
<field
name="expense_analytic_distribution"
widget="analytic_distribution"
groups="analytic.group_analytic_accounting"
options="{'account_field': 'expense_account_id', 'business_domain': 'general'}"
/>
<field name="income_account_id" />
<field
name="income_analytic_distribution"
widget="analytic_distribution"
groups="analytic.group_analytic_accounting"
options="{'account_field': 'expense_account_id', 'business_domain': 'general'}"
/>
<field name="journal_id" />
<field name="company_id" groups="base.group_multi_company" />
</group>
</form>
</field>
</record>

<record id="account_reconcile_manual_model_tree" model="ir.ui.view">
<field name="model">account.reconcile.manual.model</field>
<field name="arch" type="xml">
<tree>
<field name="sequence" widget="handle" />
<field name="ref" decoration-bf="1" />
<field name="expense_account_id" />
<field
name="expense_analytic_distribution"
widget="analytic_distribution"
optional="show"
groups="analytic.group_analytic_accounting"
/>
<field name="income_account_id" />
<field
name="income_analytic_distribution"
widget="analytic_distribution"
optional="show"
groups="analytic.group_analytic_accounting"
/>
<field name="journal_id" optional="show" />
<field
name="company_id"
groups="base.group_multi_company"
optional="hide"
/>
</tree>
</field>
</record>

<record id="account_reconcile_manual_model_search" model="ir.ui.view">
<field name="model">account.reconcile.manual.model</field>
<field name="arch" type="xml">
<search>
<field name="ref" />
<field name="expense_account_id" />
<field name="income_account_id" />
<group name="groupby">
<filter
name="journal_groupby"
string="Journal"
context="{'group_by': 'journal_id'}"
/>
</group>
</search>
</field>
</record>

<record id="account_reconcile_manual_model_action" model="ir.actions.act_window">
<field name="name">Write-off Models</field>
<field name="res_model">account.reconcile.manual.model</field>
<field name="view_mode">tree,form</field>
</record>

<menuitem
id="account_reconcile_manual_model_menu"
action="account_reconcile_manual_model_action"
parent="account.account_account_menu"
sequence="500"
/>

</odoo>
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
_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
Expand All @@ -38,14 +37,31 @@
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"),
Expand All @@ -60,28 +76,64 @@
)
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_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

Check warning on line 106 in account_move_line_reconcile_manual/wizards/account_move_line_reconcile_manual.py

View check run for this annotation

Codecov / codecov/patch

account_move_line_reconcile_manual/wizards/account_move_line_reconcile_manual.py#L104-L106

Added lines #L104 - L106 were not covered by tests
if wiz.writeoff_type == "expense":
wiz.writeoff_account_id = model.expense_account_id.id

Check warning on line 108 in account_move_line_reconcile_manual/wizards/account_move_line_reconcile_manual.py

View check run for this annotation

Codecov / codecov/patch

account_move_line_reconcile_manual/wizards/account_move_line_reconcile_manual.py#L108

Added line #L108 was not covered by tests
if model.expense_analytic_distribution:
wiz.writeoff_analytic_distribution = (

Check warning on line 110 in account_move_line_reconcile_manual/wizards/account_move_line_reconcile_manual.py

View check run for this annotation

Codecov / codecov/patch

account_move_line_reconcile_manual/wizards/account_move_line_reconcile_manual.py#L110

Added line #L110 was not covered by tests
model.expense_analytic_distribution
)
elif wiz.writeoff_type == "income":
wiz.writeoff_account_id = model.income_account_id.id

Check warning on line 114 in account_move_line_reconcile_manual/wizards/account_move_line_reconcile_manual.py

View check run for this annotation

Codecov / codecov/patch

account_move_line_reconcile_manual/wizards/account_move_line_reconcile_manual.py#L114

Added line #L114 was not covered by tests
if model.income_analytic_distribution:
wiz.writeoff_analytic_distribution = (

Check warning on line 116 in account_move_line_reconcile_manual/wizards/account_move_line_reconcile_manual.py

View check run for this annotation

Codecov / codecov/patch

account_move_line_reconcile_manual/wizards/account_move_line_reconcile_manual.py#L116

Added line #L116 was not covered by tests
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

Check warning on line 124 in account_move_line_reconcile_manual/wizards/account_move_line_reconcile_manual.py

View check run for this annotation

Codecov / codecov/patch

account_move_line_reconcile_manual/wizards/account_move_line_reconcile_manual.py#L124

Added line #L124 was not covered by tests

@api.depends("writeoff_account_id", "partner_id")
def _compute_analytic_distribution(self):
@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):
Expand Down Expand Up @@ -141,12 +193,6 @@
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,
Expand All @@ -159,7 +205,6 @@
"move_line_ids": move_lines.ids,
"writeoff_type": writeoff_type,
"writeoff_amount": writeoff_amount,
"writeoff_journal_id": writeoff_journal_id,
}
)
return res
Expand Down Expand Up @@ -233,7 +278,7 @@
"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,
},
),
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
<field name="partner_id" invisible="1" />
</group>
<group name="writeoff" string="Write-off" states="writeoff">
<field name="writeoff_model_id" widget="selection" />
<field
name="writeoff_journal_id"
widget="selection"
Expand All @@ -49,9 +50,10 @@
attrs="{'required': [('state', '=', 'writeoff')]}"
/>
<field
name="analytic_distribution"
name="writeoff_analytic_distribution"
widget="analytic_distribution"
groups="analytic.group_analytic_accounting"
options="{'account_field': 'writeoff_account_id', 'business_domain': 'general'}"
/>
</group>
<footer>
Expand Down
Loading