[IMP] account_reconcile_oca: Allow aggregation for more parameters

pull/630/head
Enric Tobella 2024-04-22 13:24:16 +02:00
parent b64ffc6eda
commit f85338ffb0
11 changed files with 136 additions and 19 deletions

View File

@ -16,6 +16,7 @@
"base_sparse_field", "base_sparse_field",
], ],
"data": [ "data": [
"views/res_config_settings.xml",
"security/ir.model.access.csv", "security/ir.model.access.csv",
"views/account_account_reconcile.xml", "views/account_account_reconcile.xml",
"views/account_bank_statement_line.xml", "views/account_bank_statement_line.xml",

View File

@ -4,3 +4,5 @@ from . import account_bank_statement_line
from . import account_bank_statement from . import account_bank_statement
from . import account_account_reconcile from . import account_account_reconcile
from . import account_move_line from . import account_move_line
from . import res_company
from . import res_config_settings

View File

@ -3,6 +3,9 @@
from collections import defaultdict from collections import defaultdict
from dateutil import rrule
from dateutil.relativedelta import relativedelta
from odoo import Command, _, api, fields, models, tools from odoo import Command, _, api, fields, models, tools
from odoo.exceptions import UserError from odoo.exceptions import UserError
from odoo.tools import float_is_zero from odoo.tools import float_is_zero
@ -86,6 +89,43 @@ class AccountBankStatementLine(models.Model):
"account.move", default=False, store=False, prefetch=False, readonly=True "account.move", default=False, store=False, prefetch=False, readonly=True
) )
can_reconcile = fields.Boolean(sparse="reconcile_data_info") can_reconcile = fields.Boolean(sparse="reconcile_data_info")
reconcile_aggregate = fields.Char(compute="_compute_reconcile_aggregate")
aggregate_id = fields.Integer(compute="_compute_reconcile_aggregate")
aggregate_name = fields.Char(compute="_compute_reconcile_aggregate")
@api.model
def _reconcile_aggregate_map(self):
lang = self.env["res.lang"]._lang_get(self.env.user.lang)
week_start = rrule.weekday(int(lang.week_start) - 1)
return {
False: lambda s: (False, False),
"statement": lambda s: (s.statement_id.id, s.statement_id.name),
"day": lambda s: (s.date.toordinal(), s.date.strftime(lang.date_format)),
"week": lambda s: (
(s.date + relativedelta(weekday=week_start(-1))).toordinal(),
(s.date + relativedelta(weekday=week_start(-1))).strftime(
lang.date_format
),
),
"month": lambda s: (
s.date.replace(day=1).toordinal(),
s.date.replace(day=1).strftime(lang.date_format),
),
}
@api.depends("company_id", "journal_id")
def _compute_reconcile_aggregate(self):
reconcile_aggregate_map = self._reconcile_aggregate_map()
for record in self:
reconcile_aggregate = (
record.journal_id.reconcile_aggregate
or record.company_id.reconcile_aggregate
)
record.reconcile_aggregate = reconcile_aggregate
print(record.date, reconcile_aggregate_map[reconcile_aggregate](record))
record.aggregate_id, record.aggregate_name = reconcile_aggregate_map[
reconcile_aggregate
](record)
def save(self): def save(self):
return {"type": "ir.actions.act_window_close"} return {"type": "ir.actions.act_window_close"}

View File

@ -13,6 +13,16 @@ class AccountJournal(models.Model):
required=True, required=True,
) )
company_currency_id = fields.Many2one(related="company_id.currency_id") company_currency_id = fields.Many2one(related="company_id.currency_id")
reconcile_aggregate = fields.Selection(
[
("statement", "Statement"),
("day", "Day"),
("week", "Week"),
("month", "Month"),
],
string="Reconcile aggregation",
help="Aggregation to use on reconcile view",
)
def get_rainbowman_message(self): def get_rainbowman_message(self):
self.ensure_one() self.ensure_one()

View File

@ -0,0 +1,14 @@
# Copyright 2024 Dixmit
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import fields, models
class ResCompany(models.Model):
_inherit = "res.company"
reconcile_aggregate = fields.Selection(
selection=lambda self: self.env["account.journal"]
._fields["reconcile_aggregate"]
.selection
)

View File

@ -0,0 +1,12 @@
# Copyright 2024 Dixmit
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import fields, models
class ResConfigSettings(models.TransientModel):
_inherit = "res.config.settings"
reconcile_aggregate = fields.Selection(
related="company_id.reconcile_aggregate", readonly=False
)

View File

@ -11,23 +11,23 @@ export class ReconcileRenderer extends KanbanRenderer {
this.action = useService("action"); this.action = useService("action");
this.orm = useService("orm"); this.orm = useService("orm");
} }
getStatements() { getAggregates() {
if ( if (
this.env.parentController.props.resModel !== "account.bank.statement.line" this.env.parentController.props.resModel !== "account.bank.statement.line"
) { ) {
return []; return [];
} }
const {list} = this.props; const {list} = this.props;
const statements = []; const aggregates = [];
for (const record of list.records) { for (const record of list.records) {
const statementId = record.data.statement_id && record.data.statement_id[0]; const aggregateId = record.data.aggregate_id && record.data.aggregate_id;
if ( if (
statementId && aggregateId &&
(!statements.length || statements[0].id !== statementId) (!aggregates.length || aggregates[0].id !== aggregateId)
) { ) {
statements.push({ aggregates.push({
id: statementId, id: aggregateId,
name: record.data.statement_name, name: record.data.aggregate_name,
balance: record.data.statement_balance_end_real, balance: record.data.statement_balance_end_real,
balanceStr: formatMonetary(record.data.statement_balance_end_real, { balanceStr: formatMonetary(record.data.statement_balance_end_real, {
currencyId: record.data.currency_id[0], currencyId: record.data.currency_id[0],
@ -35,7 +35,7 @@ export class ReconcileRenderer extends KanbanRenderer {
}); });
} }
} }
return statements; return aggregates;
} }
async onClickStatement(statementId) { async onClickStatement(statementId) {
const action = await this.orm.call( const action = await this.orm.call(

View File

@ -9,29 +9,36 @@
<div class="m-2 d-flex w-100" t-if="env.parentController.journalId"> <div class="m-2 d-flex w-100" t-if="env.parentController.journalId">
<span <span
class="flex-fill text-900 text-start ps-0 fw-bold fs-4 align-self-center" class="flex-fill text-900 text-start ps-0 fw-bold fs-4 align-self-center"
>Balance</span> >Global Balance</span>
<span <span
class="pe-0 fw-bold fs-4 align-self-center" class="pe-0 fw-bold fs-4 align-self-center"
t-esc="env.parentController.journalBalanceStr" t-esc="env.parentController.journalBalanceStr"
/> />
</div> </div>
<t t-set="statements" t-value="getStatements()" /> <t t-set="aggregates" t-value="getAggregates()" />
</xpath> </xpath>
<xpath expr="//t[@t-else='']/KanbanRecord" position="before"> <xpath expr="//t[@t-else='']/KanbanRecord" position="before">
<t <t
t-if="statements.length and groupOrRecord.record.data.statement_id and statements[0].id == groupOrRecord.record.data.statement_id[0]" t-if="aggregates.length and groupOrRecord.record.data.aggregate_id and aggregates[0].id == groupOrRecord.record.data.aggregate_id"
> >
<t t-set="statement" t-value="statements.shift()" /> <t t-set="aggregate" t-value="aggregates.shift()" />
<div class="m-2 d-flex w-100" t-if="env.parentController.journalId"> <div class="m-2 d-flex w-100">
<span <span
class="flex-fill text-900 text-start ps-0 fw-bold fs-4 align-self-center" class="flex-fill text-900 text-start ps-0 fw-bold fs-4 align-self-center"
t-esc="statement.name" t-esc="aggregate.name"
/> />
<span <span
t-on-click="() => this.onClickStatement(statement.id)" t-if="groupOrRecord.record.data.reconcile_aggregate == 'statement'"
t-on-click="() => this.onClickStatement(aggregate.id)"
class="pe-0 fw-bold fs-4 align-self-center btn btn-link" class="pe-0 fw-bold fs-4 align-self-center btn btn-link"
t-esc="statement.balanceStr" t-esc="aggregate.balanceStr"
/> />
<!--
<span
t-if="groupOrRecord.record.data.reconcile_aggregate != 'statement'"
class="pe-0 fw-bold fs-4 align-self-center text-link"
t-esc="aggregate.balanceStr"
/>-->
</div> </div>
</t> </t>
</xpath> </xpath>

View File

@ -13,12 +13,14 @@
<field name="foreign_currency_id" /> <field name="foreign_currency_id" />
<field name="statement_id" /> <field name="statement_id" />
<field name="statement_balance_end_real" /> <field name="statement_balance_end_real" />
<field name="statement_name" />
<field name="to_check" /> <field name="to_check" />
<field name="reconcile_aggregate" />
<field name="aggregate_id" />
<field name="aggregate_name" />
<templates> <templates>
<t t-name="kanban-box"> <t t-name="kanban-box">
<div <div
t-if="!record.statement_id.raw_value" t-if="record.reconcile_aggregate.raw_value == 'statement' and !record.statement_id.raw_value"
class="o_reconcile_create_statement text-center" class="o_reconcile_create_statement text-center"
> >
<a <a

View File

@ -16,6 +16,11 @@
options="{'no_quick_create': True}" options="{'no_quick_create': True}"
groups="account.group_account_readonly" groups="account.group_account_readonly"
/> />
<field
name="reconcile_aggregate"
invisible="type not in ('bank', 'cash')"
groups="account.group_account_readonly"
/>
</field> </field>
</field> </field>
</record> </record>

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2024 Dixmit
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>
<record model="ir.ui.view" id="res_config_settings_form_view">
<field name="model">res.config.settings</field>
<field name="inherit_id" ref="account.res_config_settings_view_form" />
<field name="arch" type="xml">
<block id="bank_cash" position="inside">
<setting
id="reconcile_aggregate"
title="Standard aggregation to use on bank reconciliation"
string="Reconcile aggregation"
>
<field name="reconcile_aggregate" />
</setting>
</block>
</field>
</record>
</odoo>