mirror of
https://github.com/OCA/account-reconcile.git
synced 2025-01-20 12:27:39 +02:00
@@ -1 +1,2 @@
|
||||
from . import models
|
||||
from . import wizards
|
||||
|
||||
@@ -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,
|
||||
|
||||
1
account_move_line_reconcile_manual/models/__init__.py
Normal file
1
account_move_line_reconcile_manual/models/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from . import account_reconcile_manual_model
|
||||
@@ -0,0 +1,99 @@
|
||||
# Copyright 2023 Akretion France (http://www.akretion.com/)
|
||||
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
# 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
|
||||
@@ -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
|
||||
|
||||
|
@@ -0,0 +1,98 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!--
|
||||
Copyright 2023 Akretion France (http://www.akretion.com/)
|
||||
@author: Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
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>
|
||||
@@ -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,
|
||||
},
|
||||
),
|
||||
],
|
||||
|
||||
@@ -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"
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user