[IMP] account_reconcile_oca: Finish creation of module
* refactoring JS in order to add logic * Improve views * Minor fixes in Odoo code in order to fix all possible optionspull/500/head
parent
0ea9421d14
commit
8ad989920e
|
@ -27,17 +27,14 @@
|
|||
"post_init_hook": "post_init_hook",
|
||||
"assets": {
|
||||
"web.assets_backend": [
|
||||
"account_reconcile_oca/static/src/js/reconcile_manual_view.esm.js",
|
||||
"account_reconcile_oca/static/src/js/reconcile_data_widget.esm.js",
|
||||
"account_reconcile_oca/static/src/js/reconcile_chatter_field.esm.js",
|
||||
"account_reconcile_oca/static/src/js/selection_badge_uncheck.esm.js",
|
||||
"account_reconcile_oca/static/src/js/reconcile_move_line_view.esm.js",
|
||||
"account_reconcile_oca/static/src/js/reconcile_move_line_widget.esm.js",
|
||||
"account_reconcile_oca/static/src/js/reconcile_kanban_record.esm.js",
|
||||
"account_reconcile_oca/static/src/js/reconcile_renderer.esm.js",
|
||||
"account_reconcile_oca/static/src/js/reconcile_controller.esm.js",
|
||||
"account_reconcile_oca/static/src/js/reconcile_view.esm.js",
|
||||
"account_reconcile_oca/static/src/js/reconcile_form_view.esm.js",
|
||||
"account_reconcile_oca/static/src/js/widgets/reconcile_data_widget.esm.js",
|
||||
"account_reconcile_oca/static/src/js/widgets/reconcile_chatter_field.esm.js",
|
||||
"account_reconcile_oca/static/src/js/widgets/selection_badge_uncheck.esm.js",
|
||||
"account_reconcile_oca/static/src/js/widgets/reconcile_move_line_widget.esm.js",
|
||||
"account_reconcile_oca/static/src/js/reconcile_move_line/*.esm.js",
|
||||
"account_reconcile_oca/static/src/js/reconcile_form/*.esm.js",
|
||||
"account_reconcile_oca/static/src/js/reconcile_manual/*.esm.js",
|
||||
"account_reconcile_oca/static/src/js/reconcile/*.esm.js",
|
||||
"account_reconcile_oca/static/src/xml/reconcile.xml",
|
||||
"account_reconcile_oca/static/src/scss/reconcile.scss",
|
||||
],
|
||||
|
|
|
@ -17,11 +17,11 @@ class AccountAccountReconcile(models.Model):
|
|||
|
||||
reconcile_data_info = fields.Serialized(inverse="_inverse_reconcile_data_info")
|
||||
|
||||
partner_id = fields.Many2one("res.partner")
|
||||
account_id = fields.Many2one("account.account")
|
||||
name = fields.Char()
|
||||
is_reconciled = fields.Boolean()
|
||||
currency_id = fields.Many2one("res.currency")
|
||||
partner_id = fields.Many2one("res.partner", readonly=True)
|
||||
account_id = fields.Many2one("account.account", readonly=True)
|
||||
name = fields.Char(readonly=True)
|
||||
is_reconciled = fields.Boolean(readonly=True)
|
||||
currency_id = fields.Many2one("res.currency", readonly=True)
|
||||
|
||||
@property
|
||||
def _table_query(self):
|
||||
|
|
|
@ -40,12 +40,23 @@ class AccountBankStatementLine(models.Model):
|
|||
)
|
||||
manual_partner_id = fields.Many2one(
|
||||
"res.partner",
|
||||
domain=[('parent_id', '=', False)],
|
||||
domain=[("parent_id", "=", False)],
|
||||
check_company=True,
|
||||
store=False,
|
||||
default=False,
|
||||
prefetch=False,
|
||||
)
|
||||
analytic_distribution = fields.Json(
|
||||
store=False,
|
||||
default=False,
|
||||
prefetch=False,
|
||||
)
|
||||
analytic_precision = fields.Integer(
|
||||
store=False,
|
||||
default=lambda self: self.env["decimal.precision"].precision_get(
|
||||
"Percentage Analytic"
|
||||
),
|
||||
)
|
||||
manual_model_id = fields.Many2one(
|
||||
"account.reconcile.model",
|
||||
check_company=True,
|
||||
|
@ -54,13 +65,21 @@ class AccountBankStatementLine(models.Model):
|
|||
prefetch=False,
|
||||
domain=[("rule_type", "=", "writeoff_button")],
|
||||
)
|
||||
manual_delete = fields.Boolean(
|
||||
store=False,
|
||||
default=False,
|
||||
prefetch=False,
|
||||
)
|
||||
manual_name = fields.Char(store=False, default=False, prefetch=False)
|
||||
manual_amount = fields.Monetary(store=False, default=False, prefetch=False)
|
||||
manual_original_amount = fields.Monetary(
|
||||
default=False, store=False, prefetch=False, readonly=True
|
||||
)
|
||||
manual_move_type = fields.Selection(
|
||||
lambda r: r.env["account.move"]._fields["move_type"].selection,
|
||||
default=False,
|
||||
store=False,
|
||||
prefetch=False,
|
||||
readonly=True,
|
||||
)
|
||||
manual_move_id = fields.Many2one(
|
||||
"account.move", default=False, store=False, prefetch=False, readonly=True
|
||||
)
|
||||
can_reconcile = fields.Boolean(sparse="reconcile_data_info")
|
||||
|
||||
def save(self):
|
||||
|
@ -86,7 +105,8 @@ class AccountBankStatementLine(models.Model):
|
|||
data,
|
||||
self.manual_model_id,
|
||||
self.reconcile_data_info["reconcile_auxiliary_id"],
|
||||
)
|
||||
),
|
||||
self.manual_reference
|
||||
)
|
||||
else:
|
||||
# Refreshing data
|
||||
|
@ -116,12 +136,14 @@ class AccountBankStatementLine(models.Model):
|
|||
)
|
||||
)
|
||||
self.reconcile_data_info = self._recompute_suspense_line(
|
||||
new_data, self.reconcile_data_info["reconcile_auxiliary_id"]
|
||||
new_data,
|
||||
self.reconcile_data_info["reconcile_auxiliary_id"],
|
||||
self.manual_reference,
|
||||
)
|
||||
self.can_reconcile = self.reconcile_data_info.get("can_reconcile", False)
|
||||
self.add_account_move_line_id = False
|
||||
|
||||
def _recompute_suspense_line(self, data, reconcile_auxiliary_id):
|
||||
def _recompute_suspense_line(self, data, reconcile_auxiliary_id, manual_reference):
|
||||
can_reconcile = True
|
||||
total_amount = 0
|
||||
new_data = []
|
||||
|
@ -175,6 +197,7 @@ class AccountBankStatementLine(models.Model):
|
|||
"counterparts": counterparts,
|
||||
"reconcile_auxiliary_id": reconcile_auxiliary_id,
|
||||
"can_reconcile": can_reconcile,
|
||||
"manual_reference": manual_reference,
|
||||
}
|
||||
|
||||
def _check_line_changed(self, line):
|
||||
|
@ -208,7 +231,11 @@ class AccountBankStatementLine(models.Model):
|
|||
"manual_name": False,
|
||||
"manual_partner_id": False,
|
||||
"manual_line_id": False,
|
||||
"manual_move_id": False,
|
||||
"manual_move_type": False,
|
||||
"manual_kind": False,
|
||||
"manual_original_amount": False,
|
||||
"analytic_distribution": False,
|
||||
}
|
||||
)
|
||||
continue
|
||||
|
@ -220,10 +247,17 @@ class AccountBankStatementLine(models.Model):
|
|||
line.get("partner_id") and line["partner_id"][0]
|
||||
)
|
||||
self.manual_line_id = line["id"]
|
||||
self.analytic_distribution = line.get("analytic_distribution", {})
|
||||
if self.manual_line_id:
|
||||
self.manual_move_id = self.manual_line_id.move_id
|
||||
self.manual_move_type = self.manual_line_id.move_id.move_type
|
||||
self.manual_kind = line["kind"]
|
||||
self.manual_original_amount = line.get("original_amount", 0.0)
|
||||
new_data.append(line)
|
||||
self.reconcile_data_info = self._recompute_suspense_line(
|
||||
new_data, self.reconcile_data_info["reconcile_auxiliary_id"]
|
||||
new_data,
|
||||
self.reconcile_data_info["reconcile_auxiliary_id"],
|
||||
self.manual_reference,
|
||||
)
|
||||
self.can_reconcile = self.reconcile_data_info.get("can_reconcile", False)
|
||||
|
||||
|
@ -232,6 +266,7 @@ class AccountBankStatementLine(models.Model):
|
|||
"manual_partner_id",
|
||||
"manual_name",
|
||||
"manual_amount",
|
||||
"analytic_distribution",
|
||||
)
|
||||
def _onchange_manual_reconcile_vals(self):
|
||||
self.ensure_one()
|
||||
|
@ -256,6 +291,7 @@ class AccountBankStatementLine(models.Model):
|
|||
"debit": self.manual_amount
|
||||
if self.manual_amount > 0
|
||||
else 0.0,
|
||||
"analytic_distribution": self.analytic_distribution,
|
||||
"kind": line["kind"]
|
||||
if line["kind"] != "suspense"
|
||||
else "other",
|
||||
|
@ -265,7 +301,9 @@ class AccountBankStatementLine(models.Model):
|
|||
self._update_move_partner()
|
||||
new_data.append(line)
|
||||
self.reconcile_data_info = self._recompute_suspense_line(
|
||||
new_data, self.reconcile_data_info["reconcile_auxiliary_id"]
|
||||
new_data,
|
||||
self.reconcile_data_info["reconcile_auxiliary_id"],
|
||||
self.manual_reference,
|
||||
)
|
||||
self.can_reconcile = self.reconcile_data_info.get("can_reconcile", False)
|
||||
|
||||
|
@ -310,21 +348,26 @@ class AccountBankStatementLine(models.Model):
|
|||
for line in reconcile_model._apply_lines_for_bank_widget(
|
||||
-liquidity_amount, self._retrieve_partner(), self
|
||||
):
|
||||
amount = line["amount_currency"]
|
||||
new_line = {
|
||||
"reference": "reconcile_auxiliary;%s" % reconcile_auxiliary_id,
|
||||
"id": False,
|
||||
"amount": amount,
|
||||
"debit": amount if amount > 0 else 0.0,
|
||||
"credit": -amount if amount < 0 else 0.0,
|
||||
"kind": "other",
|
||||
"account_id": self.env["account.account"]
|
||||
.browse(line["account_id"])
|
||||
.name_get()[0],
|
||||
"date": fields.Date.to_string(self.date),
|
||||
"name": line.get("name"),
|
||||
"currency_id": line.get("currency_id"),
|
||||
}
|
||||
new_line = line.copy()
|
||||
amount = line.get("amount_currency")
|
||||
if self.foreign_currency_id:
|
||||
amount = self.foreign_currency_id.compute(
|
||||
amount, self.journal_id.currency_id or self.company_currency_id
|
||||
)
|
||||
new_line.update(
|
||||
{
|
||||
"reference": "reconcile_auxiliary;%s" % reconcile_auxiliary_id,
|
||||
"id": False,
|
||||
"amount": amount,
|
||||
"debit": amount if amount > 0 else 0,
|
||||
"credit": -amount if amount < 0 else 0,
|
||||
"kind": "other",
|
||||
"account_id": self.env["account.account"]
|
||||
.browse(line["account_id"])
|
||||
.name_get()[0],
|
||||
"date": fields.Date.to_string(self.date),
|
||||
}
|
||||
)
|
||||
reconcile_auxiliary_id += 1
|
||||
if line.get("partner_id"):
|
||||
new_line["partner_id"] = (
|
||||
|
@ -377,7 +420,8 @@ class AccountBankStatementLine(models.Model):
|
|||
return self._recompute_suspense_line(
|
||||
*self._reconcile_data_by_model(
|
||||
data, res["model"], reconcile_auxiliary_id
|
||||
)
|
||||
),
|
||||
self.manual_reference
|
||||
)
|
||||
elif res and res.get("amls"):
|
||||
amount = self.amount
|
||||
|
@ -387,10 +431,13 @@ class AccountBankStatementLine(models.Model):
|
|||
)
|
||||
amount -= line_data.get("amount")
|
||||
data.append(line_data)
|
||||
return self._recompute_suspense_line(data, reconcile_auxiliary_id)
|
||||
return self._recompute_suspense_line(
|
||||
data, reconcile_auxiliary_id, self.manual_reference
|
||||
)
|
||||
return self._recompute_suspense_line(
|
||||
data + [self._get_reconcile_line(line, "other") for line in other_lines],
|
||||
reconcile_auxiliary_id,
|
||||
self.manual_reference,
|
||||
)
|
||||
|
||||
def clean_reconcile(self):
|
||||
|
@ -414,7 +461,9 @@ class AccountBankStatementLine(models.Model):
|
|||
to_reconcile = []
|
||||
with move._check_balanced(container):
|
||||
move.with_context(
|
||||
skip_account_move_synchronization=True, force_delete=True
|
||||
skip_account_move_synchronization=True,
|
||||
force_delete=True,
|
||||
skip_invoice_sync=True,
|
||||
).write(
|
||||
{
|
||||
"line_ids": lines_to_remove,
|
||||
|
@ -425,7 +474,11 @@ class AccountBankStatementLine(models.Model):
|
|||
continue
|
||||
line = (
|
||||
self.env["account.move.line"]
|
||||
.with_context(check_move_validity=False)
|
||||
.with_context(
|
||||
check_move_validity=False,
|
||||
skip_sync_invoice=True,
|
||||
skip_invoice_sync=True,
|
||||
)
|
||||
.create(self._reconcile_move_line_vals(line_vals))
|
||||
)
|
||||
if line_vals.get("counterpart_line_id"):
|
||||
|
@ -461,7 +514,11 @@ class AccountBankStatementLine(models.Model):
|
|||
).copy_data({"move_id": move.id})[0]
|
||||
to_reconcile[line.account_id.id] |= (
|
||||
self.env["account.move.line"]
|
||||
.with_context(check_move_validity=False, skip_invoice_sync=True)
|
||||
.with_context(
|
||||
check_move_validity=False,
|
||||
skip_sync_invoice=True,
|
||||
skip_invoice_sync=True,
|
||||
)
|
||||
.create(line_data)
|
||||
)
|
||||
move.write(
|
||||
|
@ -509,17 +566,7 @@ class AccountBankStatementLine(models.Model):
|
|||
)
|
||||
|
||||
def _unreconcile_bank_line_edit(self, data):
|
||||
self.move_id.button_draft()
|
||||
self.move_id.line_ids.unlink()
|
||||
self.move_id.write(
|
||||
{
|
||||
"line_ids": [
|
||||
(0, 0, line_vals)
|
||||
for line_vals in self._prepare_move_line_default_vals()
|
||||
]
|
||||
}
|
||||
)
|
||||
self.move_id.action_post()
|
||||
self.action_undo_reconciliation()
|
||||
|
||||
def _unreconcile_bank_line_keep(self, data):
|
||||
raise UserError(_("Keep suspense move lines mode cannot be unreconciled"))
|
||||
|
@ -531,6 +578,13 @@ class AccountBankStatementLine(models.Model):
|
|||
"partner_id": line.get("partner_id") and line["partner_id"][0],
|
||||
"credit": line["credit"],
|
||||
"debit": line["debit"],
|
||||
"tax_ids": line.get("tax_ids", []),
|
||||
"tax_tag_ids": line.get("tax_tag_ids", []),
|
||||
"group_tax_id": line.get("group_tax_id"),
|
||||
"tax_repartition_line_id": line.get("tax_repartition_line_id"),
|
||||
"analytic_distribution": line.get("analytic_distribution"),
|
||||
"name": line.get("name"),
|
||||
"reconcile_model_id": line.get("reconcile_model_id"),
|
||||
}
|
||||
|
||||
@api.model_create_multi
|
||||
|
@ -556,7 +610,8 @@ class AccountBankStatementLine(models.Model):
|
|||
data = record._recompute_suspense_line(
|
||||
*record._reconcile_data_by_model(
|
||||
data, res["model"], reconcile_auxiliary_id
|
||||
)
|
||||
),
|
||||
self.manual_reference
|
||||
)
|
||||
elif res.get("amls"):
|
||||
amount = self.amount
|
||||
|
@ -566,10 +621,65 @@ class AccountBankStatementLine(models.Model):
|
|||
)
|
||||
amount -= line_data.get("amount")
|
||||
data.append(line_data)
|
||||
data = record._recompute_suspense_line(data, reconcile_auxiliary_id)
|
||||
data = record._recompute_suspense_line(
|
||||
data, reconcile_auxiliary_id, self.manual_reference
|
||||
)
|
||||
if not data.get("can_reconcile"):
|
||||
continue
|
||||
getattr(
|
||||
record, "_reconcile_bank_line_%s" % record.journal_id.reconcile_mode
|
||||
)(data["data"])
|
||||
return result
|
||||
|
||||
def button_manual_reference_full_paid(self):
|
||||
self.ensure_one()
|
||||
if not self.reconcile_data_info["manual_reference"]:
|
||||
return
|
||||
manual_reference = self.reconcile_data_info["manual_reference"]
|
||||
data = self.reconcile_data_info.get("data", [])
|
||||
new_data = []
|
||||
reconcile_auxiliary_id = self.reconcile_data_info["reconcile_auxiliary_id"]
|
||||
for line in data:
|
||||
if line["reference"] == manual_reference and line.get("id"):
|
||||
total_amount = -line["amount"] + line["original_amount_unsigned"]
|
||||
original_amount = line["original_amount_unsigned"]
|
||||
new_data.append(
|
||||
self._get_reconcile_line(
|
||||
self.env["account.move.line"].browse(line["id"]),
|
||||
"other",
|
||||
is_counterpart=True,
|
||||
max_amount=original_amount,
|
||||
)
|
||||
)
|
||||
new_data.append(
|
||||
{
|
||||
"reference": "reconcile_auxiliary;%s" % reconcile_auxiliary_id,
|
||||
"id": False,
|
||||
"account_id": line["account_id"],
|
||||
"partner_id": line.get("partner_id"),
|
||||
"date": line["date"],
|
||||
"name": line["name"],
|
||||
"amount": -total_amount,
|
||||
"credit": total_amount if total_amount > 0 else 0.0,
|
||||
"debit": -total_amount if total_amount < 0 else 0.0,
|
||||
"kind": "other",
|
||||
"currency_id": line["currency_id"],
|
||||
}
|
||||
)
|
||||
reconcile_auxiliary_id += 1
|
||||
else:
|
||||
new_data.append(line)
|
||||
self.reconcile_data_info = self._recompute_suspense_line(
|
||||
new_data, reconcile_auxiliary_id, self.manual_reference
|
||||
)
|
||||
self.can_reconcile = self.reconcile_data_info.get("can_reconcile", False)
|
||||
|
||||
def action_to_check(self):
|
||||
self.ensure_one()
|
||||
self.move_id.to_check = True
|
||||
if self.can_reconcile and self.journal_id.reconcile_mode == "edit":
|
||||
self.reconcile_bank_line()
|
||||
|
||||
def action_checked(self):
|
||||
self.ensure_one()
|
||||
self.move_id.to_check = False
|
||||
|
|
|
@ -13,14 +13,6 @@ class AccountJournal(models.Model):
|
|||
required=True,
|
||||
)
|
||||
|
||||
def action_open_reconcile_to_check(self):
|
||||
self.ensure_one()
|
||||
action = self.env["ir.actions.act_window"]._for_xml_id(
|
||||
"account_reconcile_oca.action_bank_statement_line_reconcile"
|
||||
)
|
||||
action["domain"] = [("id", "=", self.to_check_ids().ids)]
|
||||
return action
|
||||
|
||||
def get_rainbowman_message(self):
|
||||
self.ensure_one()
|
||||
if self.get_journal_dashboard_datas()["number_to_reconcile"] > 0:
|
||||
|
|
|
@ -53,12 +53,14 @@ class AccountReconcileAbstract(models.AbstractModel):
|
|||
"credit": -amount if amount < 0 else 0.0,
|
||||
"amount": amount,
|
||||
"currency_id": line.currency_id.id,
|
||||
"analytic_distribution": line.analytic_distribution,
|
||||
"kind": kind,
|
||||
}
|
||||
if not float_is_zero(
|
||||
amount - original_amount, precision_digits=line.currency_id.decimal_places
|
||||
):
|
||||
vals["original_amount"] = abs(original_amount)
|
||||
vals["original_amount_unsigned"] = original_amount
|
||||
if is_counterpart:
|
||||
vals["counterpart_line_id"] = line.id
|
||||
return vals
|
||||
|
|
|
@ -17,6 +17,7 @@ export class ReconcileController extends KanbanController {
|
|||
this.effect = useService("effect");
|
||||
this.orm = useService("orm");
|
||||
this.action = useService("action");
|
||||
this.router = useService("router");
|
||||
this.activeActions = this.props.archInfo.activeActions;
|
||||
this.model.addEventListener("update", () => this.selectRecord(), {once: true});
|
||||
}
|
||||
|
@ -55,7 +56,9 @@ export class ReconcileController extends KanbanController {
|
|||
}
|
||||
async selectRecord(record) {
|
||||
var resId = undefined;
|
||||
if (record === undefined) {
|
||||
if (record === undefined && this.props.resId) {
|
||||
resId = this.props.resId;
|
||||
} else if (record === undefined) {
|
||||
var records = this.model.root.records.filter(
|
||||
(modelRecord) =>
|
||||
!modelRecord.data.is_reconciled || modelRecord.data.to_check
|
||||
|
@ -85,10 +88,14 @@ export class ReconcileController extends KanbanController {
|
|||
if (!this.state.selectedRecordId || this.state.selectedRecordId !== resId) {
|
||||
this.state.selectedRecordId = resId;
|
||||
}
|
||||
this.updateURL(resId);
|
||||
}
|
||||
async openRecord(record) {
|
||||
this.selectRecord(record);
|
||||
}
|
||||
updateURL(resId) {
|
||||
this.router.pushState({id: resId});
|
||||
}
|
||||
}
|
||||
ReconcileController.components = {
|
||||
...ReconcileController.components,
|
|
@ -1,8 +1,6 @@
|
|||
/** @odoo-module */
|
||||
|
||||
import {FormController} from "@web/views/form/form_controller";
|
||||
import {formView} from "@web/views/form/form_view";
|
||||
import {registry} from "@web/core/registry";
|
||||
import {useService} from "@web/core/utils/hooks";
|
||||
import {useViewButtons} from "@web/views/view_button/view_button_hook";
|
||||
const {useRef} = owl;
|
||||
|
@ -42,10 +40,3 @@ export class ReconcileFormController extends FormController {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const ReconcileFormView = {
|
||||
...formView,
|
||||
Controller: ReconcileFormController,
|
||||
};
|
||||
|
||||
registry.category("views").add("reconcile_form", ReconcileFormView);
|
|
@ -0,0 +1,32 @@
|
|||
/** @odoo-module */
|
||||
import {Notebook} from "@web/core/notebook/notebook";
|
||||
import {onWillDestroy} from "@odoo/owl";
|
||||
|
||||
export class ReconcileFormNotebook extends Notebook {
|
||||
setup() {
|
||||
super.setup(...arguments);
|
||||
const onPageNavigate = this.onPageNavigate.bind(this);
|
||||
this.env.bus.addEventListener("RECONCILE_PAGE_NAVIGATE", onPageNavigate);
|
||||
|
||||
onWillDestroy(() => {
|
||||
this.env.bus.removeEventListener("RECONCILE_PAGE_NAVIGATE", onPageNavigate);
|
||||
});
|
||||
}
|
||||
onPageNavigate(ev) {
|
||||
for (const page of this.pages) {
|
||||
if (
|
||||
ev.detail.detail.name === page[1].name &&
|
||||
this.state.currentPage !== page[0]
|
||||
) {
|
||||
ev.preventDefault();
|
||||
ev.detail.detail.originalEv.preventDefault();
|
||||
this.state.currentPage = page[0];
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ReconcileFormNotebook.props = {
|
||||
...Notebook.props,
|
||||
};
|
|
@ -0,0 +1,11 @@
|
|||
/** @odoo-module */
|
||||
|
||||
import {FormRenderer} from "@web/views/form/form_renderer";
|
||||
import {ReconcileFormNotebook} from "./reconcile_form_notebook.esm.js";
|
||||
|
||||
export class ReconcileFormRenderer extends FormRenderer {}
|
||||
|
||||
ReconcileFormRenderer.components = {
|
||||
...ReconcileFormRenderer.components,
|
||||
Notebook: ReconcileFormNotebook,
|
||||
};
|
|
@ -0,0 +1,14 @@
|
|||
/** @odoo-module */
|
||||
|
||||
import {ReconcileFormController} from "./reconcile_form_controller.esm.js";
|
||||
import {ReconcileFormRenderer} from "./reconcile_form_renderer.esm.js";
|
||||
import {formView} from "@web/views/form/form_view";
|
||||
import {registry} from "@web/core/registry";
|
||||
|
||||
export const ReconcileFormView = {
|
||||
...formView,
|
||||
Controller: ReconcileFormController,
|
||||
Renderer: ReconcileFormRenderer,
|
||||
};
|
||||
|
||||
registry.category("views").add("reconcile_form", ReconcileFormView);
|
|
@ -1,14 +1,13 @@
|
|||
/** @odoo-module */
|
||||
|
||||
import {FormController} from "@web/views/form/form_controller";
|
||||
import {formView} from "@web/views/form/form_view";
|
||||
import {registry} from "@web/core/registry";
|
||||
import {useViewButtons} from "@web/views/view_button/view_button_hook";
|
||||
const {useRef} = owl;
|
||||
|
||||
export class FormManualReconcileController extends FormController {
|
||||
export class ReconcileManualController extends FormController {
|
||||
setup() {
|
||||
super.setup(...arguments);
|
||||
this.env.exposeController(this);
|
||||
const rootRef = useRef("root");
|
||||
useViewButtons(this.model, rootRef, {
|
||||
reload: this.reloadFormController.bind(this),
|
||||
|
@ -29,10 +28,3 @@ export class FormManualReconcileController extends FormController {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const FormManualReconcileView = {
|
||||
...formView,
|
||||
Controller: FormManualReconcileController,
|
||||
};
|
||||
|
||||
registry.category("views").add("reconcile_manual", FormManualReconcileView);
|
|
@ -0,0 +1,12 @@
|
|||
/** @odoo-module */
|
||||
|
||||
import {ReconcileManualController} from "./reconcile_manual_controller.esm.js";
|
||||
import {formView} from "@web/views/form/form_view";
|
||||
import {registry} from "@web/core/registry";
|
||||
|
||||
export const FormManualReconcileView = {
|
||||
...formView,
|
||||
Controller: ReconcileManualController,
|
||||
};
|
||||
|
||||
registry.category("views").add("reconcile_manual", FormManualReconcileView);
|
|
@ -0,0 +1,18 @@
|
|||
/** @odoo-module */
|
||||
|
||||
import {ListController} from "@web/views/list/list_controller";
|
||||
|
||||
export class ReconcileMoveLineController extends ListController {
|
||||
async openRecord(record) {
|
||||
var data = {};
|
||||
data[this.props.parentField] = [record.resId, record.display_name];
|
||||
this.props.parentRecord.update(data);
|
||||
}
|
||||
}
|
||||
|
||||
ReconcileMoveLineController.template = `account_reconcile_oca.ReconcileMoveLineController`;
|
||||
ReconcileMoveLineController.props = {
|
||||
...ListController.props,
|
||||
parentRecord: {type: Object, optional: true},
|
||||
parentField: {type: String, optional: true},
|
||||
};
|
|
@ -0,0 +1,22 @@
|
|||
/** @odoo-module */
|
||||
|
||||
import {ListRenderer} from "@web/views/list/list_renderer";
|
||||
|
||||
export class ReconcileMoveLineRenderer extends ListRenderer {
|
||||
getRowClass(record) {
|
||||
var classes = super.getRowClass(record);
|
||||
if (
|
||||
this.props.parentRecord.data.reconcile_data_info.counterparts.includes(
|
||||
record.resId
|
||||
)
|
||||
) {
|
||||
classes += " o_field_account_reconcile_oca_move_line_selected";
|
||||
}
|
||||
return classes;
|
||||
}
|
||||
}
|
||||
ReconcileMoveLineRenderer.props = [
|
||||
...ListRenderer.props,
|
||||
"parentRecord",
|
||||
"parentField",
|
||||
];
|
|
@ -0,0 +1,15 @@
|
|||
/** @odoo-module */
|
||||
|
||||
import {ReconcileMoveLineController} from "./reconcile_move_line_controller.esm.js";
|
||||
import {ReconcileMoveLineRenderer} from "./reconcile_move_line_renderer.esm.js";
|
||||
|
||||
import {listView} from "@web/views/list/list_view";
|
||||
import {registry} from "@web/core/registry";
|
||||
|
||||
export const ReconcileMoveLineView = {
|
||||
...listView,
|
||||
Controller: ReconcileMoveLineController,
|
||||
Renderer: ReconcileMoveLineRenderer,
|
||||
};
|
||||
|
||||
registry.category("views").add("reconcile_move_line", ReconcileMoveLineView);
|
|
@ -1,46 +0,0 @@
|
|||
/** @odoo-module */
|
||||
|
||||
import {ListController} from "@web/views/list/list_controller";
|
||||
import {ListRenderer} from "@web/views/list/list_renderer";
|
||||
import {listView} from "@web/views/list/list_view";
|
||||
import {registry} from "@web/core/registry";
|
||||
|
||||
export class ReconcileMoveLineRenderer extends ListRenderer {
|
||||
getRowClass(record) {
|
||||
var classes = super.getRowClass(record);
|
||||
if (
|
||||
this.props.parentRecord.data.reconcile_data_info.counterparts.includes(
|
||||
record.resId
|
||||
)
|
||||
) {
|
||||
classes += " o_field_account_reconcile_oca_move_line_selected";
|
||||
}
|
||||
return classes;
|
||||
}
|
||||
}
|
||||
ReconcileMoveLineRenderer.props = [
|
||||
...ListRenderer.props,
|
||||
"parentRecord",
|
||||
"parentField",
|
||||
];
|
||||
export class ReconcileMoveLineController extends ListController {
|
||||
async openRecord(record) {
|
||||
var data = {};
|
||||
data[this.props.parentField] = [record.resId, record.display_name];
|
||||
this.props.parentRecord.update(data);
|
||||
}
|
||||
}
|
||||
|
||||
ReconcileMoveLineController.template = `account_reconcile_oca.ReconcileMoveLineController`;
|
||||
ReconcileMoveLineController.props = {
|
||||
...ListController.props,
|
||||
parentRecord: {type: Object, optional: true},
|
||||
parentField: {type: String, optional: true},
|
||||
};
|
||||
export const ReconcileMoveLineView = {
|
||||
...listView,
|
||||
Controller: ReconcileMoveLineController,
|
||||
Renderer: ReconcileMoveLineRenderer,
|
||||
};
|
||||
|
||||
registry.category("views").add("reconcile_move_line", ReconcileMoveLineView);
|
|
@ -1,7 +1,7 @@
|
|||
/** @odoo-module **/
|
||||
|
||||
import {registry} from "@web/core/registry";
|
||||
import {ChatterContainer} from "@mail/components/chatter_container/chatter_container";
|
||||
import {registry} from "@web/core/registry";
|
||||
|
||||
const {Component} = owl;
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
/** @odoo-module **/
|
||||
|
||||
import fieldUtils from "web.field_utils";
|
||||
import session from "web.session";
|
||||
import {registry} from "@web/core/registry";
|
||||
import session from "web.session";
|
||||
|
||||
const {Component} = owl;
|
||||
|
||||
|
@ -56,6 +56,13 @@ export class AccountReconcileDataWidget extends Component {
|
|||
this.props.record.update({
|
||||
manual_reference: line.reference,
|
||||
});
|
||||
const triggerEv = new CustomEvent("reconcile-page-navigate", {
|
||||
detail: {
|
||||
name: "manual",
|
||||
originalEv: ev,
|
||||
},
|
||||
});
|
||||
this.env.bus.trigger("RECONCILE_PAGE_NAVIGATE", triggerEv);
|
||||
}
|
||||
}
|
||||
AccountReconcileDataWidget.template = "account_reconcile_oca.ReconcileDataWidget";
|
|
@ -63,6 +63,9 @@
|
|||
&.liquidity {
|
||||
font-weight: bold;
|
||||
}
|
||||
&.selected {
|
||||
background-color: rgba($o-brand-primary, 0.2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
>
|
||||
<tr
|
||||
t-on-click="(ev) => this.selectReconcileLine(ev, reconcile_line)"
|
||||
t-att-class="'o_reconcile_widget_line ' + reconcile_line.kind"
|
||||
t-att-class="'o_reconcile_widget_line ' + reconcile_line.kind + (props.record.data.manual_reference == reconcile_line.reference ? ' selected ' : ' ')"
|
||||
>
|
||||
<td t-esc="reconcile_line.account_id[1]" />
|
||||
<td>
|
||||
|
|
|
@ -64,6 +64,87 @@ class TestReconciliationWidget(TestAccountReconciliationCommon):
|
|||
|
||||
# Testing reconcile action
|
||||
|
||||
def test_reconcile_invoice_currency(self):
|
||||
inv1 = self.create_invoice(currency_id=self.currency_usd_id, invoice_amount=100)
|
||||
bank_stmt = self.acc_bank_stmt_model.create(
|
||||
{
|
||||
"company_id": self.env.ref("base.main_company").id,
|
||||
"journal_id": self.bank_journal_euro.id,
|
||||
"date": time.strftime("%Y-07-15"),
|
||||
"name": "test",
|
||||
}
|
||||
)
|
||||
bank_stmt_line = self.acc_bank_stmt_line_model.create(
|
||||
{
|
||||
"name": "testLine",
|
||||
"journal_id": self.bank_journal_euro.id,
|
||||
"statement_id": bank_stmt.id,
|
||||
"amount": 50,
|
||||
"amount_currency": 100,
|
||||
"foreign_currency_id": self.currency_usd_id,
|
||||
"date": time.strftime("%Y-07-15"),
|
||||
}
|
||||
)
|
||||
with Form(
|
||||
bank_stmt_line,
|
||||
view="account_reconcile_oca.bank_statement_line_form_reconcile_view",
|
||||
) as f:
|
||||
self.assertFalse(f.can_reconcile)
|
||||
f.add_account_move_line_id = inv1.line_ids.filtered(
|
||||
lambda l: l.account_id.account_type == "asset_receivable"
|
||||
)
|
||||
self.assertFalse(f.add_account_move_line_id)
|
||||
self.assertTrue(f.can_reconcile)
|
||||
|
||||
def test_reconcile_invoice_reconcile_full(self):
|
||||
"""
|
||||
We want to test the reconcile widget for bank statements on invoices.
|
||||
As we use edit mode by default, we will also check what happens when
|
||||
we press unreconcile
|
||||
"""
|
||||
inv1 = self.create_invoice(
|
||||
currency_id=self.currency_euro_id, invoice_amount=100
|
||||
)
|
||||
bank_stmt = self.acc_bank_stmt_model.create(
|
||||
{
|
||||
"company_id": self.env.ref("base.main_company").id,
|
||||
"journal_id": self.bank_journal_euro.id,
|
||||
"date": time.strftime("%Y-07-15"),
|
||||
"name": "test",
|
||||
}
|
||||
)
|
||||
bank_stmt_line = self.acc_bank_stmt_line_model.create(
|
||||
{
|
||||
"name": "testLine",
|
||||
"journal_id": self.bank_journal_euro.id,
|
||||
"statement_id": bank_stmt.id,
|
||||
"amount": 50,
|
||||
"date": time.strftime("%Y-07-15"),
|
||||
}
|
||||
)
|
||||
receivable1 = inv1.line_ids.filtered(
|
||||
lambda l: l.account_id.account_type == "asset_receivable"
|
||||
)
|
||||
with Form(
|
||||
bank_stmt_line,
|
||||
view="account_reconcile_oca.bank_statement_line_form_reconcile_view",
|
||||
) as f:
|
||||
self.assertFalse(f.can_reconcile)
|
||||
f.add_account_move_line_id = receivable1
|
||||
self.assertFalse(f.add_account_move_line_id)
|
||||
self.assertTrue(f.can_reconcile)
|
||||
f.manual_reference = "account.move.line;%s" % receivable1.id
|
||||
self.assertEqual(-50, f.manual_amount)
|
||||
self.assertEqual(2, len(bank_stmt_line.reconcile_data_info["data"]))
|
||||
bank_stmt_line.button_manual_reference_full_paid()
|
||||
self.assertEqual(3, len(bank_stmt_line.reconcile_data_info["data"]))
|
||||
with Form(
|
||||
bank_stmt_line,
|
||||
view="account_reconcile_oca.bank_statement_line_form_reconcile_view",
|
||||
) as f:
|
||||
f.manual_reference = "account.move.line;%s" % receivable1.id
|
||||
self.assertEqual(-100, f.manual_amount)
|
||||
|
||||
def test_reconcile_invoice_unreconcile(self):
|
||||
"""
|
||||
We want to test the reconcile widget for bank statements on invoices.
|
||||
|
@ -348,6 +429,85 @@ class TestReconciliationWidget(TestAccountReconciliationCommon):
|
|||
with self.assertRaises(UserError):
|
||||
bank_stmt_line.unreconcile_bank_line()
|
||||
|
||||
# Testing to check functionality
|
||||
|
||||
def test_reconcile_invoice_to_check_reconciled(self):
|
||||
"""
|
||||
We want to test the reconcile widget for bank statements on invoices.
|
||||
As we use edit mode by default, we will also check what happens when
|
||||
we press unreconcile
|
||||
"""
|
||||
inv1 = self.create_invoice(
|
||||
currency_id=self.currency_euro_id, invoice_amount=100
|
||||
)
|
||||
bank_stmt = self.acc_bank_stmt_model.create(
|
||||
{
|
||||
"company_id": self.env.ref("base.main_company").id,
|
||||
"journal_id": self.bank_journal_euro.id,
|
||||
"date": time.strftime("%Y-07-15"),
|
||||
"name": "test",
|
||||
}
|
||||
)
|
||||
bank_stmt_line = self.acc_bank_stmt_line_model.create(
|
||||
{
|
||||
"name": "testLine",
|
||||
"journal_id": self.bank_journal_euro.id,
|
||||
"statement_id": bank_stmt.id,
|
||||
"amount": 100,
|
||||
"date": time.strftime("%Y-07-15"),
|
||||
}
|
||||
)
|
||||
receivable1 = inv1.line_ids.filtered(
|
||||
lambda l: l.account_id.account_type == "asset_receivable"
|
||||
)
|
||||
with Form(
|
||||
bank_stmt_line,
|
||||
view="account_reconcile_oca.bank_statement_line_form_reconcile_view",
|
||||
) as f:
|
||||
self.assertFalse(f.can_reconcile)
|
||||
f.add_account_move_line_id = receivable1
|
||||
self.assertTrue(f.can_reconcile)
|
||||
self.assertFalse(bank_stmt_line.is_reconciled)
|
||||
self.assertFalse(bank_stmt_line.to_check)
|
||||
bank_stmt_line.action_to_check()
|
||||
self.assertTrue(bank_stmt_line.is_reconciled)
|
||||
self.assertTrue(bank_stmt_line.to_check)
|
||||
bank_stmt_line.action_checked()
|
||||
self.assertTrue(bank_stmt_line.is_reconciled)
|
||||
self.assertFalse(bank_stmt_line.to_check)
|
||||
|
||||
def test_reconcile_invoice_to_check_not_reconciled(self):
|
||||
"""
|
||||
We want to test the reconcile widget for bank statements on invoices.
|
||||
As we use edit mode by default, we will also check what happens when
|
||||
we press unreconcile
|
||||
"""
|
||||
bank_stmt = self.acc_bank_stmt_model.create(
|
||||
{
|
||||
"company_id": self.env.ref("base.main_company").id,
|
||||
"journal_id": self.bank_journal_euro.id,
|
||||
"date": time.strftime("%Y-07-15"),
|
||||
"name": "test",
|
||||
}
|
||||
)
|
||||
bank_stmt_line = self.acc_bank_stmt_line_model.create(
|
||||
{
|
||||
"name": "testLine",
|
||||
"journal_id": self.bank_journal_euro.id,
|
||||
"statement_id": bank_stmt.id,
|
||||
"amount": 100,
|
||||
"date": time.strftime("%Y-07-15"),
|
||||
}
|
||||
)
|
||||
self.assertFalse(bank_stmt_line.is_reconciled)
|
||||
self.assertFalse(bank_stmt_line.to_check)
|
||||
bank_stmt_line.action_to_check()
|
||||
self.assertFalse(bank_stmt_line.is_reconciled)
|
||||
self.assertTrue(bank_stmt_line.to_check)
|
||||
bank_stmt_line.action_checked()
|
||||
self.assertFalse(bank_stmt_line.is_reconciled)
|
||||
self.assertFalse(bank_stmt_line.to_check)
|
||||
|
||||
# Testing widget
|
||||
|
||||
def test_widget_invoice_clean(self):
|
||||
|
@ -545,10 +705,6 @@ class TestReconciliationWidget(TestAccountReconciliationCommon):
|
|||
|
||||
# Testing actions
|
||||
|
||||
def test_bank_statement_action_to_check(self):
|
||||
action = self.bank_journal_euro.action_open_reconcile_to_check()
|
||||
self.assertFalse(self.env[action["res_model"]].search(action["domain"]))
|
||||
|
||||
def test_bank_statement_rainbowman(self):
|
||||
message = self.bank_journal_euro.get_rainbowman_message()
|
||||
self.assertTrue(message)
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
<field name="is_reconciled" />
|
||||
<field name="currency_id" />
|
||||
<field name="foreign_currency_id" />
|
||||
<field name="to_check" />
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div
|
||||
|
@ -43,6 +44,12 @@
|
|||
<field name="payment_ref" />
|
||||
</div>
|
||||
<div class="col-4" style="text-align:right">
|
||||
<div
|
||||
t-if="record.to_check.raw_value"
|
||||
class="badge text-bg-warning"
|
||||
>
|
||||
To check
|
||||
</div>
|
||||
<div
|
||||
t-if="record.is_reconciled.raw_value"
|
||||
class="badge text-bg-success"
|
||||
|
@ -121,7 +128,8 @@
|
|||
<button
|
||||
name="reconcile_bank_line"
|
||||
type="object"
|
||||
string="Reconcile"
|
||||
string="Validate"
|
||||
accesskey="v"
|
||||
class="btn btn-primary"
|
||||
attrs="{'invisible': ['|', ('is_reconciled', '=', True), ('can_reconcile', '=', False)]}"
|
||||
/>
|
||||
|
@ -135,7 +143,8 @@
|
|||
<button
|
||||
name="unreconcile_bank_line"
|
||||
type="object"
|
||||
string="Unreconcile"
|
||||
string="Reset"
|
||||
accesskey="r"
|
||||
class="btn btn-warning"
|
||||
attrs="{'invisible': [('is_reconciled', '=', False)]}"
|
||||
confirm="Are you sure that the move should be unreconciled?"
|
||||
|
@ -147,9 +156,25 @@
|
|||
class="btn btn-secondary"
|
||||
attrs="{'invisible': [('is_reconciled', '=', True)]}"
|
||||
/>
|
||||
<button
|
||||
name="action_to_check"
|
||||
string="To Check"
|
||||
class="btn btn-secondary"
|
||||
accesskey="c"
|
||||
type="object"
|
||||
attrs="{'invisible': [('to_check', '=', True)]}"
|
||||
/>
|
||||
<button
|
||||
name="action_checked"
|
||||
string="Set as Checked"
|
||||
accesskey="c"
|
||||
type="object"
|
||||
attrs="{'invisible': [('to_check', '=', False)]}"
|
||||
/>
|
||||
<button
|
||||
name="action_show_move"
|
||||
type="object"
|
||||
accesskey="m"
|
||||
string="View move"
|
||||
class="btn btn-info"
|
||||
/>
|
||||
|
@ -158,6 +183,7 @@
|
|||
<field name="id" invisible="1" />
|
||||
<field name="name" invisible="1" />
|
||||
<field name="can_reconcile" invisible="1" />
|
||||
<field name="to_check" invisible="1" />
|
||||
<field name="partner_id" invisible="1" />
|
||||
<field name="company_id" invisible="1" />
|
||||
<field name="journal_id" invisible="1" />
|
||||
|
@ -208,6 +234,13 @@
|
|||
string="Partner"
|
||||
attrs="{'readonly': ['|', '|', ('manual_reference', '=', False), ('is_reconciled', '=', True), '&', ('manual_line_id', '!=', False), ('manual_kind', '!=', 'liquidity')]}"
|
||||
/>
|
||||
<field
|
||||
name="analytic_distribution"
|
||||
widget="analytic_distribution"
|
||||
groups="analytic.group_analytic_accounting"
|
||||
options="{'account_field': 'manual_account_id', 'business_domain': 'general'}"
|
||||
attrs="{'invisible': ['|', ('manual_kind', '=', 'liquidity'), ('manual_reference', '=', False)], 'readonly': [('is_reconciled', '=', True)]}"
|
||||
/>
|
||||
</group>
|
||||
<group>
|
||||
<field
|
||||
|
@ -220,6 +253,35 @@
|
|||
string="Amount"
|
||||
attrs="{'readonly': ['|', ('manual_reference', '=', False), ('is_reconciled', '=', True)]}"
|
||||
/>
|
||||
<field name="manual_original_amount" invisible="1" />
|
||||
<field name="manual_move_type" invisible="1" />
|
||||
<label
|
||||
for="manual_move_id"
|
||||
string=""
|
||||
attrs="{'invisible': ['|', ('manual_move_type', 'not in', ['in_invoice', 'in_refund', 'out_invoice', 'out_refund']), ('manual_original_amount', '=', 0)]}"
|
||||
/>
|
||||
<div
|
||||
attrs="{'invisible': ['|', ('manual_move_type', 'not in', ['in_invoice', 'in_refund', 'out_invoice', 'out_refund']), ('manual_original_amount', '=', 0)]}"
|
||||
>
|
||||
Invoice <field
|
||||
class="oe_inline"
|
||||
name="manual_move_id"
|
||||
/>
|
||||
with an open amount <field
|
||||
class="oe_inline"
|
||||
name="manual_original_amount"
|
||||
/> will be reduced by <field
|
||||
class="oe_inline"
|
||||
name="manual_amount"
|
||||
readonly="1"
|
||||
/>.
|
||||
<br />
|
||||
You might want to set the invoice as <button
|
||||
name="button_manual_reference_full_paid"
|
||||
type="object"
|
||||
method_args="[1]"
|
||||
>fully paid</button>.
|
||||
</div>
|
||||
</group>
|
||||
</group>
|
||||
</page>
|
||||
|
@ -268,6 +330,28 @@
|
|||
</p>
|
||||
</field>
|
||||
</record>
|
||||
<record
|
||||
id="action_bank_statement_line_reconcile_to_check"
|
||||
model="ir.actions.act_window"
|
||||
>
|
||||
<field name="name">Reconcile bank statement lines</field>
|
||||
<field name="res_model">account.bank.statement.line</field>
|
||||
<field name="domain">[('journal_id', '=', active_id)]</field>
|
||||
<field
|
||||
name="context"
|
||||
>{'default_journal_id': active_id, 'search_default_to_check': True, 'view_ref': 'account_reconcile_oca.bank_statement_line_form_reconcile_view'}</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field
|
||||
name="view_ids"
|
||||
eval="[(5, 0, 0),
|
||||
(0, 0, {'view_mode': 'tree', 'view_id': ref('bank_statement_line_reconcile_view')})]"
|
||||
/>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
Nothing to check
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record
|
||||
id="action_bank_statement_line_move_view_reconcile"
|
||||
|
|
|
@ -44,7 +44,10 @@
|
|||
<t t-if="dashboard.number_to_check > 0">
|
||||
<div class="row">
|
||||
<div class="col overflow-hidden text-left">
|
||||
<a type="object" name="action_open_reconcile_to_check">
|
||||
<a
|
||||
type="action"
|
||||
name="%(account_reconcile_oca.action_bank_statement_line_reconcile_to_check)s"
|
||||
>
|
||||
<t t-esc="dashboard.number_to_check" /> to check</a>
|
||||
</div>
|
||||
<div class="col-auto text-right">
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
<field name="account_id" />
|
||||
<field name="account_root_id" />
|
||||
<field name="account_type" />
|
||||
<field name="partner_id" domain="[('parent_id', '=', False)]"/>
|
||||
<field name="partner_id" domain="[('parent_id', '=', False)]" />
|
||||
<field name="journal_id" />
|
||||
<field
|
||||
name="move_id"
|
||||
|
|
|
@ -117,6 +117,12 @@
|
|||
domain="[('is_reconciled', '=', False)]"
|
||||
/>
|
||||
<separator />
|
||||
<filter
|
||||
name="to_check"
|
||||
string="To check"
|
||||
domain="[('to_check', '=', True)]"
|
||||
/>
|
||||
<separator />
|
||||
<filter name="date" string="Date" date="date" />
|
||||
<group name="groupby">
|
||||
<filter
|
||||
|
|
Loading…
Reference in New Issue