odoo-addon-account-reconcile-oca 17.0.1.5.3__py3-none-any.whl → 17.0.1.5.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- odoo/addons/account_reconcile_oca/README.rst +1 -1
- odoo/addons/account_reconcile_oca/__manifest__.py +1 -1
- odoo/addons/account_reconcile_oca/models/account_account_reconcile.py +5 -1
- odoo/addons/account_reconcile_oca/models/account_bank_statement_line.py +300 -31
- odoo/addons/account_reconcile_oca/models/account_reconcile_abstract.py +39 -14
- odoo/addons/account_reconcile_oca/static/description/index.html +1 -1
- odoo/addons/account_reconcile_oca/static/src/js/widgets/reconcile_data_widget.esm.js +12 -0
- odoo/addons/account_reconcile_oca/static/src/xml/reconcile.xml +12 -1
- odoo/addons/account_reconcile_oca/tests/test_bank_account_reconcile.py +214 -47
- {odoo_addon_account_reconcile_oca-17.0.1.5.3.dist-info → odoo_addon_account_reconcile_oca-17.0.1.5.4.dist-info}/METADATA +2 -2
- {odoo_addon_account_reconcile_oca-17.0.1.5.3.dist-info → odoo_addon_account_reconcile_oca-17.0.1.5.4.dist-info}/RECORD +13 -13
- {odoo_addon_account_reconcile_oca-17.0.1.5.3.dist-info → odoo_addon_account_reconcile_oca-17.0.1.5.4.dist-info}/WHEEL +0 -0
- {odoo_addon_account_reconcile_oca-17.0.1.5.3.dist-info → odoo_addon_account_reconcile_oca-17.0.1.5.4.dist-info}/top_level.txt +0 -0
@@ -7,7 +7,7 @@ Account Reconcile Oca
|
|
7
7
|
!! This file is generated by oca-gen-addon-readme !!
|
8
8
|
!! changes will be overwritten. !!
|
9
9
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
10
|
-
!! source digest: sha256:
|
10
|
+
!! source digest: sha256:7b48f8462e4b43596a339d2203f3f4566d5576b9f949ab75dca7f35d781d08c1
|
11
11
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
12
12
|
|
13
13
|
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
|
@@ -5,7 +5,7 @@
|
|
5
5
|
"name": "Account Reconcile Oca",
|
6
6
|
"summary": """
|
7
7
|
Reconcile addons for Odoo CE accounting""",
|
8
|
-
"version": "17.0.1.5.
|
8
|
+
"version": "17.0.1.5.4",
|
9
9
|
"license": "AGPL-3",
|
10
10
|
"author": "CreuBlanca,Dixmit,Odoo Community Association (OCA)",
|
11
11
|
"maintainers": ["etobella"],
|
@@ -163,7 +163,11 @@ class AccountAccountReconcile(models.Model):
|
|
163
163
|
amount = 0.0
|
164
164
|
for line_id in counterparts:
|
165
165
|
lines = self._get_reconcile_line(
|
166
|
-
self.env["account.move.line"].browse(line_id),
|
166
|
+
self.env["account.move.line"].browse(line_id),
|
167
|
+
"other",
|
168
|
+
is_counterpart=True,
|
169
|
+
max_amount=amount,
|
170
|
+
move=True,
|
167
171
|
)
|
168
172
|
new_data["data"] += lines
|
169
173
|
amount += sum(line["amount"] for line in lines)
|
@@ -8,7 +8,8 @@ from dateutil.relativedelta import relativedelta
|
|
8
8
|
|
9
9
|
from odoo import Command, _, api, fields, models, tools
|
10
10
|
from odoo.exceptions import UserError
|
11
|
-
from odoo.
|
11
|
+
from odoo.fields import first
|
12
|
+
from odoo.tools import float_compare, float_is_zero
|
12
13
|
|
13
14
|
|
14
15
|
class AccountBankStatementLine(models.Model):
|
@@ -178,6 +179,18 @@ class AccountBankStatementLine(models.Model):
|
|
178
179
|
)._default_reconcile_data()
|
179
180
|
self.can_reconcile = self.reconcile_data_info.get("can_reconcile", False)
|
180
181
|
|
182
|
+
def _get_amount_currency(self, line, dest_curr):
|
183
|
+
if line["line_currency_id"] == dest_curr.id:
|
184
|
+
amount = line["currency_amount"]
|
185
|
+
else:
|
186
|
+
amount = self.company_id.currency_id._convert(
|
187
|
+
line["amount"],
|
188
|
+
dest_curr,
|
189
|
+
self.company_id,
|
190
|
+
self.date,
|
191
|
+
)
|
192
|
+
return amount
|
193
|
+
|
181
194
|
@api.onchange("add_account_move_line_id")
|
182
195
|
def _onchange_add_account_move_line_id(self):
|
183
196
|
if self.add_account_move_line_id:
|
@@ -185,9 +198,10 @@ class AccountBankStatementLine(models.Model):
|
|
185
198
|
new_data = []
|
186
199
|
is_new_line = True
|
187
200
|
pending_amount = 0.0
|
201
|
+
currency = self._get_reconcile_currency()
|
188
202
|
for line in data:
|
189
203
|
if line["kind"] != "suspense":
|
190
|
-
pending_amount += line
|
204
|
+
pending_amount += self._get_amount_currency(line, currency)
|
191
205
|
if self.add_account_move_line_id.id in line.get(
|
192
206
|
"counterpart_line_ids", []
|
193
207
|
):
|
@@ -196,7 +210,11 @@ class AccountBankStatementLine(models.Model):
|
|
196
210
|
new_data.append(line)
|
197
211
|
if is_new_line:
|
198
212
|
reconcile_auxiliary_id, lines = self._get_reconcile_line(
|
199
|
-
self.add_account_move_line_id,
|
213
|
+
self.add_account_move_line_id,
|
214
|
+
"other",
|
215
|
+
is_counterpart=True,
|
216
|
+
max_amount=currency.round(pending_amount),
|
217
|
+
move=True,
|
200
218
|
)
|
201
219
|
new_data += lines
|
202
220
|
self.reconcile_data_info = self._recompute_suspense_line(
|
@@ -210,9 +228,11 @@ class AccountBankStatementLine(models.Model):
|
|
210
228
|
def _recompute_suspense_line(self, data, reconcile_auxiliary_id, manual_reference):
|
211
229
|
can_reconcile = True
|
212
230
|
total_amount = 0
|
231
|
+
currency_amount = 0
|
213
232
|
new_data = []
|
214
233
|
suspense_line = False
|
215
234
|
counterparts = []
|
235
|
+
suspense_currency = self.foreign_currency_id or self.currency_id
|
216
236
|
for line in data:
|
217
237
|
if line.get("counterpart_line_ids"):
|
218
238
|
counterparts += line["counterpart_line_ids"]
|
@@ -224,10 +244,29 @@ class AccountBankStatementLine(models.Model):
|
|
224
244
|
if line["kind"] != "suspense":
|
225
245
|
new_data.append(line)
|
226
246
|
total_amount += line["amount"]
|
247
|
+
if not line.get("is_exchange_counterpart"):
|
248
|
+
# case of statement line with foreign_currency
|
249
|
+
if (
|
250
|
+
line["kind"] == "liquidity"
|
251
|
+
and line["line_currency_id"] != suspense_currency.id
|
252
|
+
):
|
253
|
+
currency_amount += self.amount_currency
|
254
|
+
elif (
|
255
|
+
line.get("currency_amount")
|
256
|
+
and line.get("line_currency_id") == suspense_currency.id
|
257
|
+
):
|
258
|
+
currency_amount += line.get("currency_amount")
|
259
|
+
else:
|
260
|
+
currency_amount += self.company_id.currency_id._convert(
|
261
|
+
line["amount"],
|
262
|
+
suspense_currency,
|
263
|
+
self.company_id,
|
264
|
+
self.date,
|
265
|
+
)
|
227
266
|
else:
|
228
267
|
suspense_line = line
|
229
268
|
if not float_is_zero(
|
230
|
-
total_amount, precision_digits=self.currency_id.decimal_places
|
269
|
+
total_amount, precision_digits=self.company_id.currency_id.decimal_places
|
231
270
|
):
|
232
271
|
can_reconcile = False
|
233
272
|
if suspense_line:
|
@@ -236,6 +275,7 @@ class AccountBankStatementLine(models.Model):
|
|
236
275
|
"amount": -total_amount,
|
237
276
|
"credit": total_amount if total_amount > 0 else 0.0,
|
238
277
|
"debit": -total_amount if total_amount < 0 else 0.0,
|
278
|
+
"currency_amount": -currency_amount,
|
239
279
|
}
|
240
280
|
)
|
241
281
|
else:
|
@@ -261,8 +301,8 @@ class AccountBankStatementLine(models.Model):
|
|
261
301
|
"debit": -total_amount if total_amount < 0 else 0.0,
|
262
302
|
"kind": "suspense",
|
263
303
|
"currency_id": self.company_id.currency_id.id,
|
264
|
-
"line_currency_id":
|
265
|
-
"currency_amount": -
|
304
|
+
"line_currency_id": suspense_currency.id,
|
305
|
+
"currency_amount": -currency_amount,
|
266
306
|
}
|
267
307
|
reconcile_auxiliary_id += 1
|
268
308
|
new_data.append(suspense_line)
|
@@ -282,11 +322,37 @@ class AccountBankStatementLine(models.Model):
|
|
282
322
|
)
|
283
323
|
or self.manual_account_id.id != line["account_id"][0]
|
284
324
|
or self.manual_name != line["name"]
|
285
|
-
or (
|
325
|
+
or (
|
326
|
+
self.manual_partner_id
|
327
|
+
and [self.manual_partner_id.id, self.manual_partner_id.display_name]
|
328
|
+
or [False, False]
|
329
|
+
)
|
286
330
|
!= line.get("partner_id")
|
287
331
|
or self.analytic_distribution != line.get("analytic_distribution", False)
|
288
332
|
)
|
289
333
|
|
334
|
+
def _check_reconcile_data_changed(self):
|
335
|
+
self.ensure_one()
|
336
|
+
data = self.reconcile_data_info.get("data", [])
|
337
|
+
liquidity_lines, _suspense_lines, _other_lines = self._seek_for_lines()
|
338
|
+
move_amount_cur = sum(liquidity_lines.mapped("amount_currency"))
|
339
|
+
move_credit = sum(liquidity_lines.mapped("credit"))
|
340
|
+
move_debit = sum(liquidity_lines.mapped("debit"))
|
341
|
+
stmt_amount_curr = stmt_debit = stmt_credit = 0.0
|
342
|
+
for line_data in data:
|
343
|
+
if line_data["kind"] != "liquidity":
|
344
|
+
continue
|
345
|
+
stmt_amount_curr += line_data["currency_amount"]
|
346
|
+
stmt_debit += line_data["debit"]
|
347
|
+
stmt_credit += line_data["credit"]
|
348
|
+
prec = self.currency_id.rounding
|
349
|
+
return (
|
350
|
+
float_compare(move_amount_cur, move_amount_cur, precision_rounding=prec)
|
351
|
+
!= 0
|
352
|
+
or float_compare(move_credit, stmt_credit, precision_rounding=prec) != 0
|
353
|
+
or float_compare(move_debit, stmt_debit, precision_rounding=prec) != 0
|
354
|
+
)
|
355
|
+
|
290
356
|
def _get_manual_delete_vals(self):
|
291
357
|
return {
|
292
358
|
"manual_reference": False,
|
@@ -362,7 +428,11 @@ class AccountBankStatementLine(models.Model):
|
|
362
428
|
|
363
429
|
@api.onchange("manual_amount_in_currency")
|
364
430
|
def _onchange_manual_amount_in_currency(self):
|
365
|
-
if
|
431
|
+
if (
|
432
|
+
self.manual_line_id.exists()
|
433
|
+
and self.manual_line_id
|
434
|
+
and self.manual_kind != "liquidity"
|
435
|
+
):
|
366
436
|
self.manual_amount = self.manual_in_currency_id._convert(
|
367
437
|
self.manual_amount_in_currency,
|
368
438
|
self.company_id.currency_id,
|
@@ -372,7 +442,7 @@ class AccountBankStatementLine(models.Model):
|
|
372
442
|
self._onchange_manual_reconcile_vals()
|
373
443
|
|
374
444
|
def _get_manual_reconcile_vals(self):
|
375
|
-
|
445
|
+
vals = {
|
376
446
|
"name": self.manual_name,
|
377
447
|
"partner_id": (
|
378
448
|
self.manual_partner_id
|
@@ -390,6 +460,19 @@ class AccountBankStatementLine(models.Model):
|
|
390
460
|
"debit": self.manual_amount if self.manual_amount > 0 else 0.0,
|
391
461
|
"analytic_distribution": self.analytic_distribution,
|
392
462
|
}
|
463
|
+
liquidity_lines, _suspense_lines, _other_lines = self._seek_for_lines()
|
464
|
+
if self.manual_line_id and self.manual_line_id.id not in liquidity_lines.ids:
|
465
|
+
vals.update(
|
466
|
+
{
|
467
|
+
"currency_amount": self.manual_currency_id._convert(
|
468
|
+
self.manual_amount,
|
469
|
+
self.manual_in_currency_id,
|
470
|
+
self.company_id,
|
471
|
+
self.manual_line_id.date,
|
472
|
+
),
|
473
|
+
}
|
474
|
+
)
|
475
|
+
return vals
|
393
476
|
|
394
477
|
@api.onchange(
|
395
478
|
"manual_account_id",
|
@@ -472,6 +555,8 @@ class AccountBankStatementLine(models.Model):
|
|
472
555
|
def _reconcile_data_by_model(self, data, reconcile_model, reconcile_auxiliary_id):
|
473
556
|
new_data = []
|
474
557
|
liquidity_amount = 0.0
|
558
|
+
currency = self._get_reconcile_currency()
|
559
|
+
currency_amount = False
|
475
560
|
for line_data in data:
|
476
561
|
if line_data["kind"] == "suspense":
|
477
562
|
continue
|
@@ -484,8 +569,18 @@ class AccountBankStatementLine(models.Model):
|
|
484
569
|
new_line = line.copy()
|
485
570
|
amount = line.get("balance")
|
486
571
|
if self.foreign_currency_id:
|
487
|
-
amount = self.foreign_currency_id.
|
488
|
-
amount,
|
572
|
+
amount = self.foreign_currency_id._convert(
|
573
|
+
amount,
|
574
|
+
self.journal_id.currency_id or self.company_currency_id,
|
575
|
+
self.company_id,
|
576
|
+
self.date,
|
577
|
+
)
|
578
|
+
if currency != self.company_id.currency_id:
|
579
|
+
currency_amount = self.company_id.currency_id._convert(
|
580
|
+
amount,
|
581
|
+
currency,
|
582
|
+
self.company_id,
|
583
|
+
self.date,
|
489
584
|
)
|
490
585
|
new_line.update(
|
491
586
|
{
|
@@ -502,9 +597,9 @@ class AccountBankStatementLine(models.Model):
|
|
502
597
|
.display_name,
|
503
598
|
],
|
504
599
|
"date": fields.Date.to_string(self.date),
|
505
|
-
"line_currency_id":
|
600
|
+
"line_currency_id": currency.id,
|
506
601
|
"currency_id": self.company_id.currency_id.id,
|
507
|
-
"currency_amount": amount,
|
602
|
+
"currency_amount": currency_amount or amount,
|
508
603
|
"name": line.get("name") or self.payment_ref,
|
509
604
|
}
|
510
605
|
)
|
@@ -525,7 +620,10 @@ class AccountBankStatementLine(models.Model):
|
|
525
620
|
reconcile_auxiliary_id = 1
|
526
621
|
for line in liquidity_lines:
|
527
622
|
reconcile_auxiliary_id, lines = self._get_reconcile_line(
|
528
|
-
line,
|
623
|
+
line,
|
624
|
+
"liquidity",
|
625
|
+
reconcile_auxiliary_id=reconcile_auxiliary_id,
|
626
|
+
move=True,
|
529
627
|
)
|
530
628
|
data += lines
|
531
629
|
if not from_unreconcile:
|
@@ -551,6 +649,7 @@ class AccountBankStatementLine(models.Model):
|
|
551
649
|
self.manual_reference,
|
552
650
|
)
|
553
651
|
elif res and res.get("amls"):
|
652
|
+
# TODO should be signed in currency get_reconcile_currency
|
554
653
|
amount = self.amount_total_signed
|
555
654
|
for line in res.get("amls", []):
|
556
655
|
reconcile_auxiliary_id, line_data = self._get_reconcile_line(
|
@@ -570,16 +669,89 @@ class AccountBankStatementLine(models.Model):
|
|
570
669
|
self.manual_reference,
|
571
670
|
)
|
572
671
|
for line in other_lines:
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
672
|
+
partial_lines = self._all_partials_lines(line) if from_unreconcile else []
|
673
|
+
if partial_lines:
|
674
|
+
for reconciled_line in (
|
675
|
+
partial_lines.debit_move_id + partial_lines.credit_move_id - line
|
676
|
+
):
|
677
|
+
if (
|
678
|
+
reconciled_line.move_id.journal_id
|
679
|
+
== self.company_id.currency_exchange_journal_id
|
680
|
+
):
|
681
|
+
reconcile_auxiliary_id, lines = self._get_reconcile_line(
|
682
|
+
reconciled_line.move_id.line_ids - reconciled_line,
|
683
|
+
"other",
|
684
|
+
from_unreconcile=False,
|
685
|
+
move=True,
|
686
|
+
)
|
687
|
+
data += lines
|
688
|
+
continue
|
689
|
+
partial = partial_lines.filtered(
|
690
|
+
lambda r, line=reconciled_line: r.debit_move_id == line
|
691
|
+
or r.credit_move_id == line
|
692
|
+
)
|
693
|
+
partial_amount = sum(
|
694
|
+
partial.filtered(
|
695
|
+
lambda r, line=reconciled_line: r.credit_move_id == line
|
696
|
+
).mapped("amount")
|
697
|
+
) - sum(
|
698
|
+
partial.filtered(
|
699
|
+
lambda r, line=reconciled_line: r.debit_move_id == line
|
700
|
+
).mapped("amount")
|
701
|
+
)
|
702
|
+
reconcile_auxiliary_id, lines = self._get_reconcile_line(
|
703
|
+
reconciled_line,
|
704
|
+
"other",
|
705
|
+
from_unreconcile={
|
706
|
+
"amount": partial_amount,
|
707
|
+
"credit": partial_amount > 0 and partial_amount,
|
708
|
+
"debit": partial_amount < 0 and -partial_amount,
|
709
|
+
"currency_amount": sum(
|
710
|
+
partial.filtered(
|
711
|
+
lambda r, line=reconciled_line: r.credit_move_id
|
712
|
+
== line
|
713
|
+
).mapped("credit_amount_currency")
|
714
|
+
)
|
715
|
+
- sum(
|
716
|
+
partial.filtered(
|
717
|
+
lambda r, line=reconciled_line: r.debit_move_id
|
718
|
+
== line
|
719
|
+
).mapped("debit_amount_currency")
|
720
|
+
),
|
721
|
+
},
|
722
|
+
move=True,
|
723
|
+
)
|
724
|
+
data += lines
|
725
|
+
else:
|
726
|
+
reconcile_auxiliary_id, lines = self._get_reconcile_line(
|
727
|
+
line, "other", from_unreconcile=False
|
728
|
+
)
|
729
|
+
data += lines
|
730
|
+
|
577
731
|
return self._recompute_suspense_line(
|
578
732
|
data,
|
579
733
|
reconcile_auxiliary_id,
|
580
734
|
self.manual_reference,
|
581
735
|
)
|
582
736
|
|
737
|
+
def _all_partials_lines(self, lines):
|
738
|
+
reconciliation_lines = lines.filtered(
|
739
|
+
lambda x: x.account_id.reconcile
|
740
|
+
or x.account_id.account_type in ("asset_cash", "liability_credit_card")
|
741
|
+
)
|
742
|
+
current_lines = reconciliation_lines
|
743
|
+
current_partials = self.env["account.partial.reconcile"]
|
744
|
+
partials = self.env["account.partial.reconcile"]
|
745
|
+
while current_lines:
|
746
|
+
current_partials = (
|
747
|
+
current_lines.matched_debit_ids + current_lines.matched_credit_ids
|
748
|
+
) - current_partials
|
749
|
+
current_lines = (
|
750
|
+
current_partials.debit_move_id + current_partials.credit_move_id
|
751
|
+
) - current_lines
|
752
|
+
partials += current_partials
|
753
|
+
return partials
|
754
|
+
|
583
755
|
def clean_reconcile(self):
|
584
756
|
self.reconcile_data_info = self._default_reconcile_data()
|
585
757
|
self.can_reconcile = self.reconcile_data_info.get("can_reconcile", False)
|
@@ -734,12 +906,13 @@ class AccountBankStatementLine(models.Model):
|
|
734
906
|
to_reverse._reverse_moves(default_values_list, cancel=True)
|
735
907
|
|
736
908
|
def _reconcile_move_line_vals(self, line, move_id=False):
|
737
|
-
|
909
|
+
vals = {
|
738
910
|
"move_id": move_id or self.move_id.id,
|
739
911
|
"account_id": line["account_id"][0],
|
740
912
|
"partner_id": line.get("partner_id") and line["partner_id"][0],
|
741
913
|
"credit": line["credit"],
|
742
914
|
"debit": line["debit"],
|
915
|
+
"currency_id": line.get("line_currency_id", self.company_id.currency_id.id),
|
743
916
|
"tax_ids": line.get("tax_ids", []),
|
744
917
|
"tax_tag_ids": line.get("tax_tag_ids", []),
|
745
918
|
"group_tax_id": line.get("group_tax_id"),
|
@@ -748,6 +921,11 @@ class AccountBankStatementLine(models.Model):
|
|
748
921
|
"name": line.get("name"),
|
749
922
|
"reconcile_model_id": line.get("reconcile_model_id"),
|
750
923
|
}
|
924
|
+
if line.get("line_currency_id") and line["currency_id"] != line.get(
|
925
|
+
"line_currency_id"
|
926
|
+
):
|
927
|
+
vals["amount_currency"] = line["currency_amount"]
|
928
|
+
return vals
|
751
929
|
|
752
930
|
@api.model_create_multi
|
753
931
|
def create(self, mvals):
|
@@ -771,7 +949,9 @@ class AccountBankStatementLine(models.Model):
|
|
771
949
|
data = []
|
772
950
|
for line in liquidity_lines:
|
773
951
|
reconcile_auxiliary_id, lines = record._get_reconcile_line(
|
774
|
-
line,
|
952
|
+
line,
|
953
|
+
"liquidity",
|
954
|
+
move=True,
|
775
955
|
)
|
776
956
|
data += lines
|
777
957
|
reconcile_auxiliary_id = 1
|
@@ -783,10 +963,10 @@ class AccountBankStatementLine(models.Model):
|
|
783
963
|
self.manual_reference,
|
784
964
|
)
|
785
965
|
elif res.get("amls"):
|
786
|
-
amount = self.amount
|
966
|
+
amount = self.amount_currency or self.amount
|
787
967
|
for line in res.get("amls", []):
|
788
968
|
reconcile_auxiliary_id, line_datas = record._get_reconcile_line(
|
789
|
-
line, "other", is_counterpart=True, max_amount=amount
|
969
|
+
line, "other", is_counterpart=True, max_amount=amount, move=True
|
790
970
|
)
|
791
971
|
amount -= sum(line_data.get("amount") for line_data in line_datas)
|
792
972
|
data += line_datas
|
@@ -802,6 +982,67 @@ class AccountBankStatementLine(models.Model):
|
|
802
982
|
)(self._prepare_reconcile_line_data(data["data"]))
|
803
983
|
return result
|
804
984
|
|
985
|
+
def _synchronize_to_moves(self, changed_fields):
|
986
|
+
"""We want to avoid to change stuff (mainly amounts ) in accounting entries
|
987
|
+
when some changes happen in the reconciliation widget. The only change
|
988
|
+
(among the fields triggering the synchronization) possible from the
|
989
|
+
reconciliation widget is the partner_id field.
|
990
|
+
|
991
|
+
So, in case of change on partner_id field we do not call super but make
|
992
|
+
only the required change (relative to partner) on accounting entries.
|
993
|
+
|
994
|
+
And if something else changes, we then re-define reconcile_data_info to
|
995
|
+
make the data consistent (for example, if debit/credit has changed by
|
996
|
+
applying a different rate or even if there was a correction on statement
|
997
|
+
line amount).
|
998
|
+
"""
|
999
|
+
if self._context.get("skip_account_move_synchronization"):
|
1000
|
+
return
|
1001
|
+
if "partner_id" in changed_fields and not any(
|
1002
|
+
field_name in changed_fields
|
1003
|
+
for field_name in (
|
1004
|
+
"payment_ref",
|
1005
|
+
"amount",
|
1006
|
+
"amount_currency",
|
1007
|
+
"foreign_currency_id",
|
1008
|
+
"currency_id",
|
1009
|
+
)
|
1010
|
+
):
|
1011
|
+
for st_line in self.with_context(skip_account_move_synchronization=True):
|
1012
|
+
(
|
1013
|
+
liquidity_lines,
|
1014
|
+
suspense_lines,
|
1015
|
+
_other_lines,
|
1016
|
+
) = st_line._seek_for_lines()
|
1017
|
+
line_vals = {"partner_id": st_line.partner_id}
|
1018
|
+
line_ids_commands = [(1, liquidity_lines.id, line_vals)]
|
1019
|
+
if suspense_lines:
|
1020
|
+
line_ids_commands.append((1, suspense_lines.id, line_vals))
|
1021
|
+
st_line_vals = {"line_ids": line_ids_commands}
|
1022
|
+
if st_line.move_id.partner_id != st_line.partner_id:
|
1023
|
+
st_line_vals["partner_id"] = st_line.partner_id.id
|
1024
|
+
st_line.move_id.write(st_line_vals)
|
1025
|
+
else:
|
1026
|
+
super()._synchronize_to_moves(changed_fields=changed_fields)
|
1027
|
+
|
1028
|
+
if not any(
|
1029
|
+
field_name in changed_fields
|
1030
|
+
for field_name in (
|
1031
|
+
"payment_ref",
|
1032
|
+
"amount",
|
1033
|
+
"amount_currency",
|
1034
|
+
"foreign_currency_id",
|
1035
|
+
"currency_id",
|
1036
|
+
"partner_id",
|
1037
|
+
)
|
1038
|
+
):
|
1039
|
+
return
|
1040
|
+
# reset reconcile_data_info if amounts are not consistent anymore with the
|
1041
|
+
# amounts of the accounting entries
|
1042
|
+
for st_line in self:
|
1043
|
+
if st_line._check_reconcile_data_changed():
|
1044
|
+
st_line.reconcile_data_info = st_line._default_reconcile_data()
|
1045
|
+
|
805
1046
|
def _prepare_reconcile_line_data(self, lines):
|
806
1047
|
new_lines = []
|
807
1048
|
reverse_lines = {}
|
@@ -848,6 +1089,7 @@ class AccountBankStatementLine(models.Model):
|
|
848
1089
|
is_counterpart=True,
|
849
1090
|
reconcile_auxiliary_id=reconcile_auxiliary_id,
|
850
1091
|
max_amount=original_amount,
|
1092
|
+
move=True,
|
851
1093
|
)
|
852
1094
|
new_data += lines
|
853
1095
|
new_data.append(
|
@@ -895,6 +1137,7 @@ class AccountBankStatementLine(models.Model):
|
|
895
1137
|
max_amount=False,
|
896
1138
|
from_unreconcile=False,
|
897
1139
|
reconcile_auxiliary_id=False,
|
1140
|
+
move=False,
|
898
1141
|
):
|
899
1142
|
new_vals = super()._get_reconcile_line(
|
900
1143
|
line,
|
@@ -902,29 +1145,48 @@ class AccountBankStatementLine(models.Model):
|
|
902
1145
|
is_counterpart=is_counterpart,
|
903
1146
|
max_amount=max_amount,
|
904
1147
|
from_unreconcile=from_unreconcile,
|
1148
|
+
move=move,
|
905
1149
|
)
|
906
1150
|
rates = []
|
907
1151
|
for vals in new_vals:
|
1152
|
+
rate = False
|
908
1153
|
if vals["partner_id"] is False:
|
909
1154
|
vals["partner_id"] = (False, self.partner_name)
|
910
|
-
|
911
|
-
|
912
|
-
|
1155
|
+
if vals.get("kind") not in ("suspense", "liquidity"):
|
1156
|
+
reconcile_auxiliary_id, rate = self._compute_exchange_rate(
|
1157
|
+
vals, line, reconcile_auxiliary_id
|
1158
|
+
)
|
913
1159
|
if rate:
|
914
1160
|
rates.append(rate)
|
915
1161
|
new_vals += rates
|
916
1162
|
return reconcile_auxiliary_id, new_vals
|
917
1163
|
|
918
1164
|
def _get_exchange_rate_amount(self, amount, currency_amount, currency, line):
|
919
|
-
|
920
|
-
|
1165
|
+
if self.foreign_currency_id == currency:
|
1166
|
+
# take real rate of statement line to compute the exchange rate gain/loss
|
1167
|
+
real_rate = self.amount / self.amount_currency
|
1168
|
+
to_amount_journal_currency = currency_amount * real_rate
|
1169
|
+
to_amount_company_currency = self.currency_id._convert(
|
1170
|
+
to_amount_journal_currency,
|
1171
|
+
self.company_id.currency_id,
|
1172
|
+
self.company_id,
|
1173
|
+
self.date,
|
1174
|
+
)
|
1175
|
+
to_amount = self.company_id.currency_id.round(to_amount_company_currency)
|
1176
|
+
elif self.currency_id == currency and not self.foreign_currency_id:
|
1177
|
+
liquidity_lines, _suspense_lines, _other_lines = self._seek_for_lines()
|
1178
|
+
real_rate = (
|
1179
|
+
first(liquidity_lines).balance / first(liquidity_lines).amount_currency
|
1180
|
+
)
|
1181
|
+
to_amount = self.company_id.currency_id.round(currency_amount * real_rate)
|
1182
|
+
else:
|
1183
|
+
to_amount = currency._convert(
|
921
1184
|
currency_amount,
|
922
1185
|
self.company_id.currency_id,
|
923
1186
|
self.company_id,
|
924
1187
|
self.date,
|
925
1188
|
)
|
926
|
-
|
927
|
-
)
|
1189
|
+
return self.company_id.currency_id.round(to_amount - amount)
|
928
1190
|
|
929
1191
|
def _compute_exchange_rate(
|
930
1192
|
self,
|
@@ -963,8 +1225,8 @@ class AccountBankStatementLine(models.Model):
|
|
963
1225
|
"debit": amount if amount > 0 else 0.0,
|
964
1226
|
"kind": "other",
|
965
1227
|
"currency_id": self.company_id.currency_id.id,
|
966
|
-
"line_currency_id":
|
967
|
-
"currency_amount":
|
1228
|
+
"line_currency_id": currency.id,
|
1229
|
+
"currency_amount": 0,
|
968
1230
|
}
|
969
1231
|
reconcile_auxiliary_id += 1
|
970
1232
|
return reconcile_auxiliary_id, data
|
@@ -991,3 +1253,10 @@ class AccountBankStatementLine(models.Model):
|
|
991
1253
|
"split_line_id": self.id,
|
992
1254
|
}
|
993
1255
|
return action
|
1256
|
+
|
1257
|
+
def _get_reconcile_currency(self):
|
1258
|
+
return (
|
1259
|
+
self.foreign_currency_id
|
1260
|
+
or self.journal_id.currency_id
|
1261
|
+
or self.company_id.currency_id
|
1262
|
+
)
|
@@ -33,24 +33,46 @@ class AccountReconcileAbstract(models.AbstractModel):
|
|
33
33
|
related="company_id.currency_id", string="Company Currency"
|
34
34
|
)
|
35
35
|
|
36
|
+
def _get_reconcile_currency(self):
|
37
|
+
return self.currency_id or self.company_id._currency_id
|
38
|
+
|
36
39
|
def _get_reconcile_line(
|
37
|
-
self,
|
40
|
+
self,
|
41
|
+
line,
|
42
|
+
kind,
|
43
|
+
is_counterpart=False,
|
44
|
+
max_amount=False,
|
45
|
+
from_unreconcile=False,
|
46
|
+
move=False,
|
38
47
|
):
|
39
48
|
date = self.date if "date" in self._fields else line.date
|
40
49
|
original_amount = amount = net_amount = line.debit - line.credit
|
50
|
+
line_currency = line.currency_id
|
41
51
|
if is_counterpart:
|
42
52
|
currency_amount = -line.amount_residual_currency or line.amount_residual
|
43
53
|
amount = -line.amount_residual
|
44
|
-
currency = line.currency_id or
|
54
|
+
currency = line.currency_id or line.company_id.currency_id
|
45
55
|
original_amount = net_amount = -line.amount_residual
|
46
56
|
if max_amount:
|
47
|
-
|
48
|
-
|
49
|
-
|
57
|
+
dest_currency = self._get_reconcile_currency()
|
58
|
+
if currency == dest_currency:
|
59
|
+
real_currency_amount = currency_amount
|
60
|
+
elif self.company_id.currency_id == dest_currency:
|
61
|
+
real_currency_amount = amount
|
62
|
+
else:
|
63
|
+
real_currency_amount = self.company_id.currency_id._convert(
|
64
|
+
amount,
|
65
|
+
dest_currency,
|
66
|
+
self.company_id,
|
67
|
+
date,
|
68
|
+
)
|
50
69
|
if (
|
51
|
-
-
|
52
|
-
or -
|
70
|
+
-real_currency_amount > max_amount > 0
|
71
|
+
or -real_currency_amount < max_amount < 0
|
53
72
|
):
|
73
|
+
currency_max_amount = self._get_reconcile_currency()._convert(
|
74
|
+
max_amount, currency, self.company_id, date
|
75
|
+
)
|
54
76
|
amount = currency_max_amount
|
55
77
|
net_amount = -max_amount
|
56
78
|
currency_amount = -amount
|
@@ -61,8 +83,11 @@ class AccountReconcileAbstract(models.AbstractModel):
|
|
61
83
|
date,
|
62
84
|
)
|
63
85
|
else:
|
64
|
-
currency_amount =
|
86
|
+
currency_amount = self.amount_currency or self.amount
|
87
|
+
line_currency = self._get_reconcile_currency()
|
65
88
|
vals = {
|
89
|
+
"move_id": move and line.move_id.id,
|
90
|
+
"move": move and line.move_id.name,
|
66
91
|
"reference": "account.move.line;%s" % line.id,
|
67
92
|
"id": line.id,
|
68
93
|
"account_id": [line.account_id.id, line.account_id.display_name],
|
@@ -76,7 +101,7 @@ class AccountReconcileAbstract(models.AbstractModel):
|
|
76
101
|
"amount": amount,
|
77
102
|
"net_amount": amount - net_amount,
|
78
103
|
"currency_id": self.company_id.currency_id.id,
|
79
|
-
"line_currency_id":
|
104
|
+
"line_currency_id": line_currency.id,
|
80
105
|
"currency_amount": currency_amount,
|
81
106
|
"analytic_distribution": line.analytic_distribution,
|
82
107
|
"kind": kind,
|
@@ -84,11 +109,11 @@ class AccountReconcileAbstract(models.AbstractModel):
|
|
84
109
|
if from_unreconcile:
|
85
110
|
vals.update(
|
86
111
|
{
|
87
|
-
"
|
88
|
-
"
|
89
|
-
|
90
|
-
|
91
|
-
|
112
|
+
"credit": vals["debit"] and from_unreconcile["debit"],
|
113
|
+
"debit": vals["credit"] and from_unreconcile["credit"],
|
114
|
+
"amount": from_unreconcile["amount"],
|
115
|
+
"net_amount": from_unreconcile["amount"],
|
116
|
+
"currency_amount": from_unreconcile["currency_amount"],
|
92
117
|
}
|
93
118
|
)
|
94
119
|
if not float_is_zero(
|
@@ -367,7 +367,7 @@ ul.auto-toc {
|
|
367
367
|
!! This file is generated by oca-gen-addon-readme !!
|
368
368
|
!! changes will be overwritten. !!
|
369
369
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
370
|
-
!! source digest: sha256:
|
370
|
+
!! source digest: sha256:7b48f8462e4b43596a339d2203f3f4566d5576b9f949ab75dca7f35d781d08c1
|
371
371
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
|
372
372
|
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/account-reconcile/tree/17.0/account_reconcile_oca"><img alt="OCA/account-reconcile" src="https://img.shields.io/badge/github-OCA%2Faccount--reconcile-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/account-reconcile-17-0/account-reconcile-17-0-account_reconcile_oca"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/account-reconcile&target_branch=17.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
|
373
373
|
<p>This addon allows to reconcile bank statements and account marked as
|
@@ -2,12 +2,15 @@
|
|
2
2
|
import {formatDate, parseDate} from "@web/core/l10n/dates";
|
3
3
|
import {formatMonetary} from "@web/views/fields/formatters";
|
4
4
|
import {registry} from "@web/core/registry";
|
5
|
+
import {useService} from "@web/core/utils/hooks";
|
5
6
|
|
6
7
|
const {Component} = owl;
|
7
8
|
|
8
9
|
export class AccountReconcileDataWidget extends Component {
|
9
10
|
setup() {
|
10
11
|
super.setup(...arguments);
|
12
|
+
this.orm = useService("orm");
|
13
|
+
this.action = useService("action");
|
11
14
|
this.foreignCurrency =
|
12
15
|
this.props &&
|
13
16
|
this.props.record &&
|
@@ -70,6 +73,15 @@ export class AccountReconcileDataWidget extends Component {
|
|
70
73
|
});
|
71
74
|
this.env.bus.trigger("RECONCILE_PAGE_NAVIGATE", triggerEv);
|
72
75
|
}
|
76
|
+
async openMove(ev, moveId) {
|
77
|
+
ev.preventDefault();
|
78
|
+
ev.stopPropagation();
|
79
|
+
console.log(moveId);
|
80
|
+
const action = await this.orm.call("account.move", "get_formview_action", [
|
81
|
+
[moveId],
|
82
|
+
]);
|
83
|
+
this.action.doAction(action);
|
84
|
+
}
|
73
85
|
}
|
74
86
|
AccountReconcileDataWidget.template = "account_reconcile_oca.ReconcileDataWidget";
|
75
87
|
|
@@ -114,7 +114,18 @@
|
|
114
114
|
t-on-click="(ev) => this.selectReconcileLine(ev, reconcile_line)"
|
115
115
|
t-att-class="'o_reconcile_widget_line ' + reconcile_line.kind + (props.record.data.manual_reference == reconcile_line.reference ? ' selected ' : ' ')"
|
116
116
|
>
|
117
|
-
<td
|
117
|
+
<td>
|
118
|
+
<div t-esc="reconcile_line.account_id[1]" />
|
119
|
+
<div t-if="reconcile_line.move_id">
|
120
|
+
<a
|
121
|
+
t-att-href="'/web#id=' + reconcile_line.move_id + '&view_type=form&model=account.move'"
|
122
|
+
class="o_form_uri"
|
123
|
+
t-on-click="(ev) => this.openMove(ev, reconcile_line.move_id)"
|
124
|
+
>
|
125
|
+
<small t-esc="reconcile_line.move" />
|
126
|
+
</a>
|
127
|
+
</div>
|
128
|
+
</td>
|
118
129
|
<td>
|
119
130
|
<span
|
120
131
|
t-esc="reconcile_line.partner_id[1]"
|
@@ -91,7 +91,6 @@ class TestReconciliationWidget(TestAccountReconciliationCommon):
|
|
91
91
|
inv1 = self.create_invoice(currency_id=self.currency_usd_id, invoice_amount=100)
|
92
92
|
bank_stmt = self.acc_bank_stmt_model.create(
|
93
93
|
{
|
94
|
-
"company_id": self.env.ref("base.main_company").id,
|
95
94
|
"journal_id": self.bank_journal_euro.id,
|
96
95
|
"date": time.strftime("%Y-07-15"),
|
97
96
|
"name": "test",
|
@@ -119,6 +118,42 @@ class TestReconciliationWidget(TestAccountReconciliationCommon):
|
|
119
118
|
self.assertFalse(f.add_account_move_line_id)
|
120
119
|
self.assertTrue(f.can_reconcile)
|
121
120
|
|
121
|
+
def test_manual_line_with_currency(self):
|
122
|
+
bank_stmt = self.acc_bank_stmt_model.create(
|
123
|
+
{
|
124
|
+
"journal_id": self.bank_journal_euro.id,
|
125
|
+
"date": time.strftime("%Y-07-15"),
|
126
|
+
"name": "test",
|
127
|
+
}
|
128
|
+
)
|
129
|
+
bank_stmt_line = self.acc_bank_stmt_line_model.create(
|
130
|
+
{
|
131
|
+
"name": "testLine",
|
132
|
+
"journal_id": self.bank_journal_euro.id,
|
133
|
+
"statement_id": bank_stmt.id,
|
134
|
+
"amount": 50,
|
135
|
+
"amount_currency": 100,
|
136
|
+
"foreign_currency_id": self.currency_usd_id,
|
137
|
+
"date": time.strftime("%Y-07-15"),
|
138
|
+
}
|
139
|
+
)
|
140
|
+
receivable_acc = self.company_data["default_account_receivable"]
|
141
|
+
with Form(
|
142
|
+
bank_stmt_line,
|
143
|
+
view="account_reconcile_oca.bank_statement_line_form_reconcile_view",
|
144
|
+
) as f:
|
145
|
+
self.assertFalse(f.can_reconcile)
|
146
|
+
f.manual_reference = "reconcile_auxiliary;1"
|
147
|
+
f.manual_account_id = receivable_acc
|
148
|
+
self.assertTrue(f.can_reconcile)
|
149
|
+
bank_stmt_line.reconcile_bank_line()
|
150
|
+
receivable_line = bank_stmt_line.line_ids.filtered(
|
151
|
+
lambda line: line.account_id == receivable_acc
|
152
|
+
)
|
153
|
+
self.assertEqual(receivable_line.currency_id.id, self.currency_usd_id)
|
154
|
+
self.assertEqual(receivable_line.amount_currency, -100)
|
155
|
+
self.assertEqual(receivable_line.balance, -50)
|
156
|
+
|
122
157
|
def test_reconcile_invoice_reconcile_full(self):
|
123
158
|
"""
|
124
159
|
We want to test the reconcile widget for bank statements on invoices.
|
@@ -130,7 +165,6 @@ class TestReconciliationWidget(TestAccountReconciliationCommon):
|
|
130
165
|
)
|
131
166
|
bank_stmt = self.acc_bank_stmt_model.create(
|
132
167
|
{
|
133
|
-
"company_id": self.env.ref("base.main_company").id,
|
134
168
|
"journal_id": self.bank_journal_euro.id,
|
135
169
|
"date": time.strftime("%Y-07-15"),
|
136
170
|
"name": "test",
|
@@ -179,7 +213,6 @@ class TestReconciliationWidget(TestAccountReconciliationCommon):
|
|
179
213
|
)
|
180
214
|
bank_stmt = self.acc_bank_stmt_model.create(
|
181
215
|
{
|
182
|
-
"company_id": self.env.ref("base.main_company").id,
|
183
216
|
"journal_id": self.bank_journal_euro.id,
|
184
217
|
"date": time.strftime("%Y-07-15"),
|
185
218
|
"name": "test",
|
@@ -242,7 +275,6 @@ class TestReconciliationWidget(TestAccountReconciliationCommon):
|
|
242
275
|
)
|
243
276
|
bank_stmt = self.acc_bank_stmt_model.create(
|
244
277
|
{
|
245
|
-
"company_id": self.env.ref("base.main_company").id,
|
246
278
|
"journal_id": self.bank_journal_euro.id,
|
247
279
|
"date": time.strftime("%Y-07-15"),
|
248
280
|
"name": "test",
|
@@ -306,7 +338,6 @@ class TestReconciliationWidget(TestAccountReconciliationCommon):
|
|
306
338
|
)
|
307
339
|
bank_stmt = self.acc_bank_stmt_model.create(
|
308
340
|
{
|
309
|
-
"company_id": self.env.ref("base.main_company").id,
|
310
341
|
"journal_id": self.bank_journal_euro.id,
|
311
342
|
"date": time.strftime("%Y-07-15"),
|
312
343
|
"name": "test",
|
@@ -360,7 +391,6 @@ class TestReconciliationWidget(TestAccountReconciliationCommon):
|
|
360
391
|
"""
|
361
392
|
bank_stmt = self.acc_bank_stmt_model.create(
|
362
393
|
{
|
363
|
-
"company_id": self.env.ref("base.main_company").id,
|
364
394
|
"journal_id": self.bank_journal_euro.id,
|
365
395
|
"date": time.strftime("%Y-07-15"),
|
366
396
|
"name": "test",
|
@@ -404,7 +434,6 @@ class TestReconciliationWidget(TestAccountReconciliationCommon):
|
|
404
434
|
)
|
405
435
|
bank_stmt = self.acc_bank_stmt_model.create(
|
406
436
|
{
|
407
|
-
"company_id": self.env.ref("base.main_company").id,
|
408
437
|
"journal_id": self.bank_journal_euro.id,
|
409
438
|
"date": time.strftime("%Y-07-15"),
|
410
439
|
"name": "test",
|
@@ -459,7 +488,6 @@ class TestReconciliationWidget(TestAccountReconciliationCommon):
|
|
459
488
|
)
|
460
489
|
bank_stmt = self.acc_bank_stmt_model.create(
|
461
490
|
{
|
462
|
-
"company_id": self.env.ref("base.main_company").id,
|
463
491
|
"journal_id": self.bank_journal_euro.id,
|
464
492
|
"date": time.strftime("%Y-07-15"),
|
465
493
|
"name": "test",
|
@@ -519,7 +547,6 @@ class TestReconciliationWidget(TestAccountReconciliationCommon):
|
|
519
547
|
|
520
548
|
bank_stmt = self.acc_bank_stmt_model.create(
|
521
549
|
{
|
522
|
-
"company_id": self.env.ref("base.main_company").id,
|
523
550
|
"journal_id": self.bank_journal_euro.id,
|
524
551
|
"date": time.strftime("%Y-07-15"),
|
525
552
|
"name": "test",
|
@@ -549,7 +576,6 @@ class TestReconciliationWidget(TestAccountReconciliationCommon):
|
|
549
576
|
)
|
550
577
|
bank_stmt = self.acc_bank_stmt_model.create(
|
551
578
|
{
|
552
|
-
"company_id": self.env.ref("base.main_company").id,
|
553
579
|
"journal_id": self.bank_journal_euro.id,
|
554
580
|
"date": time.strftime("%Y-07-15"),
|
555
581
|
"name": "test",
|
@@ -594,6 +620,57 @@ class TestReconciliationWidget(TestAccountReconciliationCommon):
|
|
594
620
|
self.assertTrue(reconcile_move.reversal_move_id)
|
595
621
|
self.assertFalse(bank_stmt_line.is_reconciled)
|
596
622
|
|
623
|
+
def test_reconcile_model_with_foreign_currency(self):
|
624
|
+
"""
|
625
|
+
We want to test what happens when we select a reconcile model to fill a
|
626
|
+
bank statement with a foreign currency.
|
627
|
+
"""
|
628
|
+
bank_stmt = self.acc_bank_stmt_model.create(
|
629
|
+
{
|
630
|
+
"journal_id": self.bank_journal_usd.id,
|
631
|
+
"date": time.strftime("%Y-07-15"),
|
632
|
+
"name": "test",
|
633
|
+
}
|
634
|
+
)
|
635
|
+
bank_stmt_line = self.acc_bank_stmt_line_model.create(
|
636
|
+
{
|
637
|
+
"name": "testLine",
|
638
|
+
"journal_id": self.bank_journal_usd.id,
|
639
|
+
"statement_id": bank_stmt.id,
|
640
|
+
"amount": 100,
|
641
|
+
"date": time.strftime("%Y-07-15"),
|
642
|
+
}
|
643
|
+
)
|
644
|
+
with Form(
|
645
|
+
bank_stmt_line,
|
646
|
+
view="account_reconcile_oca.bank_statement_line_form_reconcile_view",
|
647
|
+
) as f:
|
648
|
+
self.assertFalse(f.can_reconcile)
|
649
|
+
f.manual_model_id = self.rule
|
650
|
+
self.assertTrue(f.can_reconcile)
|
651
|
+
number_of_lines = len(bank_stmt_line.reconcile_data_info["data"])
|
652
|
+
bank_stmt_line.reconcile_bank_line()
|
653
|
+
self.assertEqual(
|
654
|
+
number_of_lines, len(bank_stmt_line.reconcile_data_info["data"])
|
655
|
+
)
|
656
|
+
self.assertEqual(2, len(bank_stmt_line.move_id.line_ids))
|
657
|
+
self.assertTrue(
|
658
|
+
bank_stmt_line.move_id.line_ids.filtered(
|
659
|
+
lambda r: r.account_id == self.current_assets_account
|
660
|
+
)
|
661
|
+
)
|
662
|
+
expected_amount = bank_stmt_line._get_reconcile_currency()._convert(
|
663
|
+
bank_stmt_line.amount,
|
664
|
+
bank_stmt_line.company_id.currency_id,
|
665
|
+
bank_stmt_line.company_id,
|
666
|
+
bank_stmt_line.date,
|
667
|
+
)
|
668
|
+
self.assertEqual(
|
669
|
+
bank_stmt_line.move_id.line_ids[0].amount_currency, bank_stmt_line.amount
|
670
|
+
)
|
671
|
+
self.assertEqual(bank_stmt_line.move_id.line_ids[0].debit, expected_amount)
|
672
|
+
self.assertEqual(bank_stmt_line.move_id.line_ids[1].credit, expected_amount)
|
673
|
+
|
597
674
|
# Testing to check functionality
|
598
675
|
|
599
676
|
def test_reconcile_invoice_to_check_reconciled(self):
|
@@ -607,7 +684,6 @@ class TestReconciliationWidget(TestAccountReconciliationCommon):
|
|
607
684
|
)
|
608
685
|
bank_stmt = self.acc_bank_stmt_model.create(
|
609
686
|
{
|
610
|
-
"company_id": self.env.ref("base.main_company").id,
|
611
687
|
"journal_id": self.bank_journal_euro.id,
|
612
688
|
"date": time.strftime("%Y-07-15"),
|
613
689
|
"name": "test",
|
@@ -649,7 +725,6 @@ class TestReconciliationWidget(TestAccountReconciliationCommon):
|
|
649
725
|
"""
|
650
726
|
bank_stmt = self.acc_bank_stmt_model.create(
|
651
727
|
{
|
652
|
-
"company_id": self.env.ref("base.main_company").id,
|
653
728
|
"journal_id": self.bank_journal_euro.id,
|
654
729
|
"date": time.strftime("%Y-07-15"),
|
655
730
|
"name": "test",
|
@@ -684,7 +759,6 @@ class TestReconciliationWidget(TestAccountReconciliationCommon):
|
|
684
759
|
)
|
685
760
|
bank_stmt = self.acc_bank_stmt_model.create(
|
686
761
|
{
|
687
|
-
"company_id": self.env.ref("base.main_company").id,
|
688
762
|
"journal_id": self.bank_journal_euro.id,
|
689
763
|
"date": time.strftime("%Y-07-15"),
|
690
764
|
"name": "test",
|
@@ -722,7 +796,6 @@ class TestReconciliationWidget(TestAccountReconciliationCommon):
|
|
722
796
|
)
|
723
797
|
bank_stmt = self.acc_bank_stmt_model.create(
|
724
798
|
{
|
725
|
-
"company_id": self.env.ref("base.main_company").id,
|
726
799
|
"journal_id": self.bank_journal_euro.id,
|
727
800
|
"date": time.strftime("%Y-07-15"),
|
728
801
|
"name": "test",
|
@@ -763,7 +836,6 @@ class TestReconciliationWidget(TestAccountReconciliationCommon):
|
|
763
836
|
)
|
764
837
|
bank_stmt = self.acc_bank_stmt_model.create(
|
765
838
|
{
|
766
|
-
"company_id": self.env.ref("base.main_company").id,
|
767
839
|
"journal_id": self.bank_journal_euro.id,
|
768
840
|
"date": time.strftime("%Y-07-15"),
|
769
841
|
"name": "test",
|
@@ -804,7 +876,6 @@ class TestReconciliationWidget(TestAccountReconciliationCommon):
|
|
804
876
|
)
|
805
877
|
bank_stmt = self.acc_bank_stmt_model.create(
|
806
878
|
{
|
807
|
-
"company_id": self.env.ref("base.main_company").id,
|
808
879
|
"journal_id": self.bank_journal_euro.id,
|
809
880
|
"date": time.strftime("%Y-07-15"),
|
810
881
|
"name": "test",
|
@@ -828,6 +899,7 @@ class TestReconciliationWidget(TestAccountReconciliationCommon):
|
|
828
899
|
self.assertFalse(f.partner_id)
|
829
900
|
f.manual_reference = "account.move.line;%s" % liquidity_lines.id
|
830
901
|
f.manual_partner_id = inv1.partner_id
|
902
|
+
f.save()
|
831
903
|
self.assertEqual(f.partner_id, inv1.partner_id)
|
832
904
|
bank_stmt_line.clean_reconcile()
|
833
905
|
# As we have set a partner, the cleaning should assign the invoice automatically
|
@@ -840,7 +912,6 @@ class TestReconciliationWidget(TestAccountReconciliationCommon):
|
|
840
912
|
"""
|
841
913
|
bank_stmt = self.acc_bank_stmt_model.create(
|
842
914
|
{
|
843
|
-
"company_id": self.env.ref("base.main_company").id,
|
844
915
|
"journal_id": self.bank_journal_euro.id,
|
845
916
|
"date": time.strftime("%Y-07-15"),
|
846
917
|
"name": "test",
|
@@ -891,7 +962,6 @@ class TestReconciliationWidget(TestAccountReconciliationCommon):
|
|
891
962
|
"""
|
892
963
|
bank_stmt = self.acc_bank_stmt_model.create(
|
893
964
|
{
|
894
|
-
"company_id": self.env.ref("base.main_company").id,
|
895
965
|
"journal_id": self.bank_journal_euro.id,
|
896
966
|
"date": time.strftime("%Y-07-15"),
|
897
967
|
"name": "test",
|
@@ -934,7 +1004,6 @@ class TestReconciliationWidget(TestAccountReconciliationCommon):
|
|
934
1004
|
|
935
1005
|
bank_stmt = self.acc_bank_stmt_model.create(
|
936
1006
|
{
|
937
|
-
"company_id": self.env.ref("base.main_company").id,
|
938
1007
|
"journal_id": self.bank_journal_euro.id,
|
939
1008
|
"date": time.strftime("%Y-07-15"),
|
940
1009
|
"name": "test",
|
@@ -998,7 +1067,6 @@ class TestReconciliationWidget(TestAccountReconciliationCommon):
|
|
998
1067
|
|
999
1068
|
bank_stmt = self.acc_bank_stmt_model.create(
|
1000
1069
|
{
|
1001
|
-
"company_id": self.env.ref("base.main_company").id,
|
1002
1070
|
"journal_id": self.bank_journal_euro.id,
|
1003
1071
|
"date": time.strftime("%Y-07-15"),
|
1004
1072
|
"name": "test",
|
@@ -1032,7 +1100,6 @@ class TestReconciliationWidget(TestAccountReconciliationCommon):
|
|
1032
1100
|
inv1 = self.create_invoice(currency_id=self.currency_usd_id, invoice_amount=100)
|
1033
1101
|
bank_stmt = self.acc_bank_stmt_model.create(
|
1034
1102
|
{
|
1035
|
-
"company_id": self.env.ref("base.main_company").id,
|
1036
1103
|
"journal_id": self.bank_journal_usd.id,
|
1037
1104
|
"date": time.strftime("%Y-07-15"),
|
1038
1105
|
"name": "test",
|
@@ -1071,45 +1138,50 @@ class TestReconciliationWidget(TestAccountReconciliationCommon):
|
|
1071
1138
|
)
|
1072
1139
|
|
1073
1140
|
def test_journal_foreign_currency_change(self):
|
1141
|
+
cny = self.env.ref("base.CNY")
|
1142
|
+
cny.write({"active": True})
|
1143
|
+
cny_journal = self.env["account.journal"].create(
|
1144
|
+
{
|
1145
|
+
"name": "Bank CNY",
|
1146
|
+
"type": "bank",
|
1147
|
+
"currency_id": cny.id,
|
1148
|
+
}
|
1149
|
+
)
|
1074
1150
|
self.env["res.currency.rate"].create(
|
1075
1151
|
{
|
1076
|
-
"
|
1077
|
-
"
|
1078
|
-
"
|
1152
|
+
"name": time.strftime("%Y-09-10"),
|
1153
|
+
"currency_id": cny.id,
|
1154
|
+
"inverse_company_rate": 0.125989013758,
|
1155
|
+
}
|
1156
|
+
)
|
1157
|
+
self.env["res.currency.rate"].create(
|
1158
|
+
{
|
1159
|
+
"name": time.strftime("%Y-09-09"),
|
1160
|
+
"currency_id": cny.id,
|
1161
|
+
"inverse_company_rate": 0.126225969731,
|
1079
1162
|
}
|
1080
1163
|
)
|
1081
1164
|
bank_stmt = self.acc_bank_stmt_model.create(
|
1082
1165
|
{
|
1083
|
-
"
|
1084
|
-
"
|
1085
|
-
"date": time.strftime("%Y-07-15"),
|
1166
|
+
"journal_id": cny_journal.id,
|
1167
|
+
"date": time.strftime("%Y-09-10"),
|
1086
1168
|
"name": "test",
|
1087
1169
|
}
|
1088
1170
|
)
|
1089
1171
|
bank_stmt_line = self.acc_bank_stmt_line_model.create(
|
1090
1172
|
{
|
1091
1173
|
"name": "testLine",
|
1092
|
-
"journal_id":
|
1174
|
+
"journal_id": cny_journal.id,
|
1093
1175
|
"statement_id": bank_stmt.id,
|
1094
|
-
"amount":
|
1095
|
-
"date": time.strftime("%Y-
|
1176
|
+
"amount": 259200,
|
1177
|
+
"date": time.strftime("%Y-09-10"),
|
1096
1178
|
}
|
1097
1179
|
)
|
1098
|
-
|
1099
|
-
|
1100
|
-
|
1101
|
-
|
1102
|
-
|
1103
|
-
self.assertEqual(
|
1104
|
-
line["currency_amount"],
|
1105
|
-
100,
|
1106
|
-
)
|
1107
|
-
self.env["res.currency.rate"].create(
|
1108
|
-
{
|
1109
|
-
"currency_id": self.env.ref("base.EUR").id,
|
1110
|
-
"name": time.strftime("%Y-07-15"),
|
1111
|
-
"rate": 1.2,
|
1112
|
-
}
|
1180
|
+
inv1 = self._create_invoice(
|
1181
|
+
currency_id=cny.id,
|
1182
|
+
invoice_amount=259200,
|
1183
|
+
date_invoice=time.strftime("%Y-09-09"),
|
1184
|
+
auto_validate=True,
|
1113
1185
|
)
|
1114
1186
|
with Form(
|
1115
1187
|
bank_stmt_line,
|
@@ -1118,8 +1190,17 @@ class TestReconciliationWidget(TestAccountReconciliationCommon):
|
|
1118
1190
|
line = f.reconcile_data_info["data"][0]
|
1119
1191
|
self.assertEqual(
|
1120
1192
|
line["currency_amount"],
|
1121
|
-
|
1193
|
+
259200,
|
1122
1194
|
)
|
1195
|
+
f.add_account_move_line_id = inv1.line_ids.filtered(
|
1196
|
+
lambda line: line.account_id.account_type == "asset_receivable"
|
1197
|
+
)
|
1198
|
+
self.assertTrue(f.can_reconcile)
|
1199
|
+
self.assertEqual(len(bank_stmt_line.reconcile_data_info["data"]), 3)
|
1200
|
+
exchange_line = bank_stmt_line.reconcile_data_info["data"][-1]
|
1201
|
+
self.assertEqual(exchange_line["amount"], 61.42)
|
1202
|
+
bank_stmt_line.reconcile_bank_line()
|
1203
|
+
self.assertEqual(inv1.payment_state, "paid")
|
1123
1204
|
|
1124
1205
|
def test_invoice_foreign_currency_change(self):
|
1125
1206
|
self.env["res.currency.rate"].create(
|
@@ -1144,7 +1225,6 @@ class TestReconciliationWidget(TestAccountReconciliationCommon):
|
|
1144
1225
|
)
|
1145
1226
|
bank_stmt = self.acc_bank_stmt_model.create(
|
1146
1227
|
{
|
1147
|
-
"company_id": self.env.ref("base.main_company").id,
|
1148
1228
|
"journal_id": self.bank_journal_usd.id,
|
1149
1229
|
"date": time.strftime("%Y-07-15"),
|
1150
1230
|
"name": "test",
|
@@ -1222,3 +1302,90 @@ class TestReconciliationWidget(TestAccountReconciliationCommon):
|
|
1222
1302
|
.account_type,
|
1223
1303
|
"liability_payable",
|
1224
1304
|
)
|
1305
|
+
|
1306
|
+
def test_invoice_foreign_currency_late_change_of_rate(self):
|
1307
|
+
# Test we can reconcile lines in foreign currency even if the rate was updated
|
1308
|
+
# late in odoo, meaning the statement line was created and the rate was updated
|
1309
|
+
# in odoo after that.
|
1310
|
+
self.env["res.currency.rate"].create(
|
1311
|
+
{
|
1312
|
+
"currency_id": self.env.ref("base.USD").id,
|
1313
|
+
"name": time.strftime("%Y-07-14"),
|
1314
|
+
"rate": 1.15,
|
1315
|
+
}
|
1316
|
+
)
|
1317
|
+
self.env["res.currency.rate"].create(
|
1318
|
+
{
|
1319
|
+
"currency_id": self.env.ref("base.USD").id,
|
1320
|
+
"name": time.strftime("%Y-07-15"),
|
1321
|
+
"rate": 1.2,
|
1322
|
+
}
|
1323
|
+
)
|
1324
|
+
inv1 = self._create_invoice(
|
1325
|
+
currency_id=self.currency_usd_id,
|
1326
|
+
invoice_amount=100,
|
1327
|
+
date_invoice=time.strftime("%Y-07-14"),
|
1328
|
+
auto_validate=True,
|
1329
|
+
)
|
1330
|
+
bank_stmt = self.acc_bank_stmt_model.create(
|
1331
|
+
{
|
1332
|
+
"journal_id": self.bank_journal_usd.id,
|
1333
|
+
"date": time.strftime("%Y-07-15"),
|
1334
|
+
"name": "test",
|
1335
|
+
}
|
1336
|
+
)
|
1337
|
+
bank_stmt_line = self.acc_bank_stmt_line_model.create(
|
1338
|
+
{
|
1339
|
+
"name": "testLine",
|
1340
|
+
"journal_id": self.bank_journal_usd.id,
|
1341
|
+
"statement_id": bank_stmt.id,
|
1342
|
+
"amount": 100,
|
1343
|
+
"date": time.strftime("%Y-07-16"),
|
1344
|
+
}
|
1345
|
+
)
|
1346
|
+
# rate of 07-16 is create after the statement line, meaning the rate of the
|
1347
|
+
# statement line is the one of the 07-15
|
1348
|
+
self.env["res.currency.rate"].create(
|
1349
|
+
{
|
1350
|
+
"currency_id": self.env.ref("base.USD").id,
|
1351
|
+
"name": time.strftime("%Y-07-16"),
|
1352
|
+
"rate": 1.25,
|
1353
|
+
}
|
1354
|
+
)
|
1355
|
+
liquidity_lines, suspense_lines, other_lines = bank_stmt_line._seek_for_lines()
|
1356
|
+
with Form(
|
1357
|
+
bank_stmt_line,
|
1358
|
+
view="account_reconcile_oca.bank_statement_line_form_reconcile_view",
|
1359
|
+
) as f:
|
1360
|
+
line = f.reconcile_data_info["data"][0]
|
1361
|
+
self.assertEqual(
|
1362
|
+
line["currency_amount"],
|
1363
|
+
100,
|
1364
|
+
)
|
1365
|
+
self.assertEqual(
|
1366
|
+
line["amount"],
|
1367
|
+
83.33,
|
1368
|
+
)
|
1369
|
+
# check that adding a partner does not recompute the amounts on accounting
|
1370
|
+
# entries, but is still synchronized with accounting entries
|
1371
|
+
f.manual_reference = "account.move.line;%s" % liquidity_lines.id
|
1372
|
+
f.manual_partner_id = inv1.partner_id
|
1373
|
+
self.assertEqual(f.partner_id, inv1.partner_id)
|
1374
|
+
self.assertEqual(liquidity_lines.debit, 83.33)
|
1375
|
+
f.save()
|
1376
|
+
# check liquidity line did not recompute debit with the new rate with
|
1377
|
+
# partner change
|
1378
|
+
self.assertEqual(liquidity_lines.debit, 83.33)
|
1379
|
+
self.assertEqual(liquidity_lines.partner_id, inv1.partner_id)
|
1380
|
+
f.manual_reference = "account.move.line;%s" % line["id"]
|
1381
|
+
# simulate click on statement line, check amount does not recompute
|
1382
|
+
f.manual_partner_id = inv1.partner_id
|
1383
|
+
self.assertEqual(f.manual_amount, 83.33)
|
1384
|
+
# check currency amount is still fine
|
1385
|
+
self.assertEqual(f.reconcile_data_info["data"][0]["currency_amount"], 100)
|
1386
|
+
f.add_account_move_line_id = inv1.line_ids.filtered(
|
1387
|
+
lambda line: line.account_id.account_type == "asset_receivable"
|
1388
|
+
)
|
1389
|
+
self.assertEqual(3, len(f.reconcile_data_info["data"]))
|
1390
|
+
self.assertTrue(f.can_reconcile)
|
1391
|
+
self.assertEqual(f.reconcile_data_info["data"][-1]["amount"], 3.63)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: odoo-addon-account_reconcile_oca
|
3
|
-
Version: 17.0.1.5.
|
3
|
+
Version: 17.0.1.5.4
|
4
4
|
Requires-Python: >=3.10
|
5
5
|
Requires-Dist: odoo-addon-account_reconcile_model_oca>=17.0dev,<17.1dev
|
6
6
|
Requires-Dist: odoo-addon-account_statement_base>=17.0dev,<17.1dev
|
@@ -24,7 +24,7 @@ Account Reconcile Oca
|
|
24
24
|
!! This file is generated by oca-gen-addon-readme !!
|
25
25
|
!! changes will be overwritten. !!
|
26
26
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
27
|
-
!! source digest: sha256:
|
27
|
+
!! source digest: sha256:7b48f8462e4b43596a339d2203f3f4566d5576b9f949ab75dca7f35d781d08c1
|
28
28
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
29
29
|
|
30
30
|
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
|
@@ -1,6 +1,6 @@
|
|
1
|
-
odoo/addons/account_reconcile_oca/README.rst,sha256=
|
1
|
+
odoo/addons/account_reconcile_oca/README.rst,sha256=9cy5LDNzoKV5x490CP1NpNXtrF5WhMnIdaJqMh_ASfo,3703
|
2
2
|
odoo/addons/account_reconcile_oca/__init__.py,sha256=vqRYeBgCVZMpZhYvILSxVsNLC9V7zDnvxMnKU8RQP94,55
|
3
|
-
odoo/addons/account_reconcile_oca/__manifest__.py,sha256=
|
3
|
+
odoo/addons/account_reconcile_oca/__manifest__.py,sha256=P_Rw_ev5GFEAaW_MBlIAdxHwW7z1wvpqKdUDmJJDZQU,1865
|
4
4
|
odoo/addons/account_reconcile_oca/hooks.py,sha256=SfJ-GlIGYL1kf8xhQs5qDqwNnE8S9Gs-5dP3vOD-IMM,182
|
5
5
|
odoo/addons/account_reconcile_oca/demo/demo.xml,sha256=6k0uK-H1aBiyogVNhQMQfFGL5zUfUGV2M-sSV6LHeUs,204
|
6
6
|
odoo/addons/account_reconcile_oca/i18n/account_reconcile_oca.pot,sha256=RnxHPjPpQk_qZs4ZHFvH13KDHnqQO-ppgcUnULeZxwo,25700
|
@@ -17,12 +17,12 @@ odoo/addons/account_reconcile_oca/i18n/tr.po,sha256=jdrItgYAt4JAEpwbuSuy2vAq-Si_
|
|
17
17
|
odoo/addons/account_reconcile_oca/i18n/zh.po,sha256=i7HjN44XrHzZ-qIG994NXgaEvjYU10Cw0Jcp7HQGAWk,25765
|
18
18
|
odoo/addons/account_reconcile_oca/i18n/zh_CN.po,sha256=gHrxzsXR_B6rbs_0iU8_-9doeTZwiy-HmPtFoiiZJ3s,27504
|
19
19
|
odoo/addons/account_reconcile_oca/models/__init__.py,sha256=28wbZjUZa30uHQY10BMJtKQ_BqJgwLQMQvB9uv0H_fY,282
|
20
|
-
odoo/addons/account_reconcile_oca/models/account_account_reconcile.py,sha256=
|
20
|
+
odoo/addons/account_reconcile_oca/models/account_account_reconcile.py,sha256=j5tTL1RvlDIYAjrVNf7kt1tf58-TzFL7iqocSfMjo9g,6811
|
21
21
|
odoo/addons/account_reconcile_oca/models/account_bank_statement.py,sha256=CFqlLLtmTqmt5yH3v_pkUfkZezSb1nEhBTu2J5gCjxM,1034
|
22
|
-
odoo/addons/account_reconcile_oca/models/account_bank_statement_line.py,sha256=
|
22
|
+
odoo/addons/account_reconcile_oca/models/account_bank_statement_line.py,sha256=CjZvCNLgki-d5g-DHX3TtzmbgKd2TcQ0Ln9_GRf2PSM,51781
|
23
23
|
odoo/addons/account_reconcile_oca/models/account_journal.py,sha256=PXXoGnByO7ve9_G09tnn95HKJoLvXM1pDxHDdd7bpU4,1359
|
24
24
|
odoo/addons/account_reconcile_oca/models/account_move_line.py,sha256=PfdU6cfrKjKMqL_qGqNdyPUWg-frGQ6nR5uCoYtW38M,1212
|
25
|
-
odoo/addons/account_reconcile_oca/models/account_reconcile_abstract.py,sha256=
|
25
|
+
odoo/addons/account_reconcile_oca/models/account_reconcile_abstract.py,sha256=vtQX3yQqUslslTny7QSbbrh0u4vfsCG4p5MAKHAOlyA,5011
|
26
26
|
odoo/addons/account_reconcile_oca/models/res_company.py,sha256=IaSLPwHJZre5RYPVW8V6mnSoxltS_w0GUN1Ev-cfcB4,354
|
27
27
|
odoo/addons/account_reconcile_oca/models/res_config_settings.py,sha256=AuenxX0UfqYWWP-QvtB0irSf_JuWVh4a9QylPfl-Lxc,325
|
28
28
|
odoo/addons/account_reconcile_oca/readme/CONTRIBUTORS.md,sha256=subC7gWq_kRC_nJfLRfrI_IXlNoGgWaq9Es5qXuMa1w,16
|
@@ -31,7 +31,7 @@ odoo/addons/account_reconcile_oca/readme/ROADMAP.md,sha256=fxR8QnC8BkHyODdPScpgJ
|
|
31
31
|
odoo/addons/account_reconcile_oca/readme/USAGE.md,sha256=yNLGo35X7TW2TLyJqHU-gdQiXazW8Iu59rI0dpa4WjM,365
|
32
32
|
odoo/addons/account_reconcile_oca/security/ir.model.access.csv,sha256=XfN2EKOoChlEDonVd5DtodVAQyRbShiJ8nrXx6EwNmM,339
|
33
33
|
odoo/addons/account_reconcile_oca/static/description/icon.png,sha256=6xBPJauaFOF0KDHfHgQopSc28kKvxMaeoQFQWZtfZDo,9455
|
34
|
-
odoo/addons/account_reconcile_oca/static/description/index.html,sha256=
|
34
|
+
odoo/addons/account_reconcile_oca/static/description/index.html,sha256=dr22xFUNNb6Hu-T4XpmXmHq6NCPkzVK6EGPDU-zxL08,13790
|
35
35
|
odoo/addons/account_reconcile_oca/static/src/js/reconcile/reconcile_controller.esm.js,sha256=k85Scd4skR5y56TvFVEqB_uf7vCD9Y7RpInETuNBAc8,4891
|
36
36
|
odoo/addons/account_reconcile_oca/static/src/js/reconcile/reconcile_kanban_record.esm.js,sha256=ewNK1VQgFZWccTiyJMKYkOG6KtbHHVnI2pdNy9kjkig,467
|
37
37
|
odoo/addons/account_reconcile_oca/static/src/js/reconcile/reconcile_renderer.esm.js,sha256=9NSr3iZ7H_QGTpixW5D4WEJuD_u4KRpdYwRmKqcML_k,2117
|
@@ -46,14 +46,14 @@ odoo/addons/account_reconcile_oca/static/src/js/reconcile_move_line/reconcile_mo
|
|
46
46
|
odoo/addons/account_reconcile_oca/static/src/js/reconcile_move_line/reconcile_move_line_renderer.esm.js,sha256=TwiLpAbPJtr9VDZs8ZDIVFoieiogueHnpw0n0a1P_Kk,605
|
47
47
|
odoo/addons/account_reconcile_oca/static/src/js/reconcile_move_line/reconcile_move_line_view.esm.js,sha256=TFHNQB-A2wyBlfUHXpqKBt_-ICY0pbO90n4ao9dCVBI,510
|
48
48
|
odoo/addons/account_reconcile_oca/static/src/js/widgets/reconcile_chatter_field.esm.js,sha256=w8vDPCCovRJRKYZtp1XnlWGNGXDfvoJYuttKF-jpTHw,902
|
49
|
-
odoo/addons/account_reconcile_oca/static/src/js/widgets/reconcile_data_widget.esm.js,sha256
|
49
|
+
odoo/addons/account_reconcile_oca/static/src/js/widgets/reconcile_data_widget.esm.js,sha256=-m-It4krr0hLeRoM7VtiOdy7ZsutJPxokCY7HZRjfD8,3335
|
50
50
|
odoo/addons/account_reconcile_oca/static/src/js/widgets/reconcile_move_line_widget.esm.js,sha256=G5lbsagkTYErqNlPvhW0vfljQWRKI4eI5spDlH3_emk,3772
|
51
51
|
odoo/addons/account_reconcile_oca/static/src/js/widgets/selection_badge_uncheck.esm.js,sha256=yFqG5t4wKA47k-wUMzPuDZ1AvILft6_hucGOz2YHWGE,836
|
52
52
|
odoo/addons/account_reconcile_oca/static/src/scss/reconcile.scss,sha256=b6clO2yWT91dEdTE3RcdORFE6dNqqzsXz3S0Rc5afZU,2318
|
53
|
-
odoo/addons/account_reconcile_oca/static/src/xml/reconcile.xml,sha256=
|
53
|
+
odoo/addons/account_reconcile_oca/static/src/xml/reconcile.xml,sha256=zrLcG1bVWDwjm3PzrStw8MgX9IaTtANDBLVF3X51-ms,9266
|
54
54
|
odoo/addons/account_reconcile_oca/tests/__init__.py,sha256=8JhP4auByShS8Z_Ik5dShMuWdh1kBlYP_DLI4Ku8XWA,79
|
55
55
|
odoo/addons/account_reconcile_oca/tests/test_account_reconcile.py,sha256=MP5M-NsVhMoYiU675hr1nsvZRRK-4e5KUYMCCKTUHB8,10807
|
56
|
-
odoo/addons/account_reconcile_oca/tests/test_bank_account_reconcile.py,sha256=
|
56
|
+
odoo/addons/account_reconcile_oca/tests/test_bank_account_reconcile.py,sha256=km7zs8uO6wabfryrsg8VLd5yT0AhkRaI0nI_MHOx-Es,53449
|
57
57
|
odoo/addons/account_reconcile_oca/views/account_account.xml,sha256=0RiPmzfRUj54oMYKWM7mLnZL-5IhI5W8fiRruHL0SYc,866
|
58
58
|
odoo/addons/account_reconcile_oca/views/account_account_reconcile.xml,sha256=2FKosNTl4hVC_yVq8uRzZvMMrXyEttK_YTsdnV8o0NI,7016
|
59
59
|
odoo/addons/account_reconcile_oca/views/account_bank_statement.xml,sha256=QrjQZ3OTsnbopdLnnsFaZ0f7ncLkOUbtVj9osXdxw5k,2436
|
@@ -62,7 +62,7 @@ odoo/addons/account_reconcile_oca/views/account_journal.xml,sha256=T5tZ5Ev0psYp7
|
|
62
62
|
odoo/addons/account_reconcile_oca/views/account_move.xml,sha256=BnvchVpOJ31M-kCoe6AHDxHMfrEEgJTPPysxguX3xgE,975
|
63
63
|
odoo/addons/account_reconcile_oca/views/account_move_line.xml,sha256=Kr_ET1IAat3B8UoW6VPQO3q88JLVdE5-5jpb13ioCbY,5405
|
64
64
|
odoo/addons/account_reconcile_oca/views/res_config_settings.xml,sha256=PxIqWILg_L_ahR-SDlDWEqWDJKNumPRifFAGF0BG57E,807
|
65
|
-
odoo_addon_account_reconcile_oca-17.0.1.5.
|
66
|
-
odoo_addon_account_reconcile_oca-17.0.1.5.
|
67
|
-
odoo_addon_account_reconcile_oca-17.0.1.5.
|
68
|
-
odoo_addon_account_reconcile_oca-17.0.1.5.
|
65
|
+
odoo_addon_account_reconcile_oca-17.0.1.5.4.dist-info/METADATA,sha256=484jst0lJuJFJm_rjELbKOiImdmhPSM3v1gpSqNf3m4,4388
|
66
|
+
odoo_addon_account_reconcile_oca-17.0.1.5.4.dist-info/WHEEL,sha256=9fEMia4zL7ZuZbnCOrcYogUhmn4XFIVaJ8G4YGI31xc,81
|
67
|
+
odoo_addon_account_reconcile_oca-17.0.1.5.4.dist-info/top_level.txt,sha256=QE6RBQ0QX5f4eFuUcGgU5Kbq1A_qJcDs-e_vpr6pmfU,4
|
68
|
+
odoo_addon_account_reconcile_oca-17.0.1.5.4.dist-info/RECORD,,
|
File without changes
|