[FIX] *: pre-commit fixes
Due to latest copier template with all the checks.pull/654/head
parent
3f8a1a8ef9
commit
90ca34afc2
|
@ -155,8 +155,8 @@ class MassReconcileAdvanced(models.AbstractModel):
|
||||||
mkey, mvalue = matcher
|
mkey, mvalue = matcher
|
||||||
omkey, omvalue = opposite_matcher
|
omkey, omvalue = opposite_matcher
|
||||||
assert mkey == omkey, _(
|
assert mkey == omkey, _(
|
||||||
"A matcher %(mkey)s is compared with a matcher %(omkey)s, the _matchers and "
|
"A matcher %(mkey)s is compared with a matcher %(omkey)s, the _matchers "
|
||||||
"_opposite_matchers are probably wrong"
|
"and _opposite_matchers are probably wrong"
|
||||||
) % {"mkey": mkey, "omkey": omkey}
|
) % {"mkey": mkey, "omkey": omkey}
|
||||||
if not isinstance(mvalue, list | tuple):
|
if not isinstance(mvalue, list | tuple):
|
||||||
mvalue = (mvalue,)
|
mvalue = (mvalue,)
|
||||||
|
|
|
@ -63,12 +63,14 @@ class AccountBankStatementLine(models.Model):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Find a partner having a name contained inside the statement line values.
|
# Find a partner having a name contained inside the statement line values.
|
||||||
# Take care a partner could contain some special characters in its name that needs to be escaped.
|
# Take care a partner could contain some special characters in its name that
|
||||||
|
# needs to be escaped.
|
||||||
sub_queries.append(
|
sub_queries.append(
|
||||||
rf"""
|
rf"""
|
||||||
{unaccent("%s")} ~* ('^' || (
|
{unaccent("%s")} ~* ('^' || (
|
||||||
SELECT STRING_AGG(CONCAT('(?=.*\m', chunk[1], '\M)'), '')
|
SELECT STRING_AGG(CONCAT('(?=.*\m', chunk[1], '\M)'), '')
|
||||||
FROM regexp_matches({unaccent('partner.name')}, '\w{{3,}}', 'g') AS chunk
|
FROM regexp_matches({unaccent('partner.name')}, '\w{{3,}}', 'g')
|
||||||
|
AS chunk
|
||||||
))
|
))
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
@ -100,7 +102,8 @@ class AccountBankStatementLine(models.Model):
|
||||||
return self.env["res.partner"]
|
return self.env["res.partner"]
|
||||||
|
|
||||||
def _get_st_line_strings_for_matching(self, allowed_fields=None):
|
def _get_st_line_strings_for_matching(self, allowed_fields=None):
|
||||||
"""Collect the strings that could be used on the statement line to perform some matching.
|
"""Collect the strings that could be used on the statement line to perform some
|
||||||
|
matching.
|
||||||
:param allowed_fields: A explicit list of fields to consider.
|
:param allowed_fields: A explicit list of fields to consider.
|
||||||
:return: A list of strings.
|
:return: A list of strings.
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -14,13 +14,14 @@ class AccountReconcileModel(models.Model):
|
||||||
####################################################
|
####################################################
|
||||||
|
|
||||||
def _apply_lines_for_bank_widget(self, residual_amount_currency, partner, st_line):
|
def _apply_lines_for_bank_widget(self, residual_amount_currency, partner, st_line):
|
||||||
"""Apply the reconciliation model lines to the statement line passed as parameter.
|
"""Apply the reconciliation model lines to the statement line passed as
|
||||||
:param residual_amount_currency: The open balance of the statement line in the bank reconciliation widget
|
parameter.
|
||||||
expressed in the statement line currency.
|
:param residual_amount_currency: The open balance of the statement line in the
|
||||||
|
bank reconciliation widget expressed in the statement line currency.
|
||||||
:param partner: The partner set on the wizard.
|
:param partner: The partner set on the wizard.
|
||||||
:param st_line: The statement line processed by the bank reconciliation widget.
|
:param st_line: The statement line processed by the bank reconciliation widget.
|
||||||
:return: A list of python dictionaries (one per reconcile model line) representing
|
:return: A list of python dictionaries (one per reconcile model line)
|
||||||
the journal items to be created by the current reconcile model.
|
representing the journal items to be created by the current reconcile model.
|
||||||
"""
|
"""
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
currency = (
|
currency = (
|
||||||
|
@ -49,8 +50,10 @@ class AccountReconcileModel(models.Model):
|
||||||
def _get_taxes_move_lines_dict(self, tax, base_line_dict):
|
def _get_taxes_move_lines_dict(self, tax, base_line_dict):
|
||||||
"""Get move.lines dict (to be passed to the create()) corresponding to a tax.
|
"""Get move.lines dict (to be passed to the create()) corresponding to a tax.
|
||||||
:param tax: An account.tax record.
|
:param tax: An account.tax record.
|
||||||
:param base_line_dict: A dict representing the move.line containing the base amount.
|
:param base_line_dict: A dict representing the move.line containing the base
|
||||||
:return: A list of dict representing move.lines to be created corresponding to the tax.
|
amount.
|
||||||
|
:return: A list of dict representing move.lines to be created corresponding to
|
||||||
|
the tax.
|
||||||
"""
|
"""
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
balance = base_line_dict["balance"]
|
balance = base_line_dict["balance"]
|
||||||
|
@ -103,9 +106,12 @@ class AccountReconcileModel(models.Model):
|
||||||
return new_aml_dicts
|
return new_aml_dicts
|
||||||
|
|
||||||
def _get_write_off_move_lines_dict(self, residual_balance, partner_id):
|
def _get_write_off_move_lines_dict(self, residual_balance, partner_id):
|
||||||
"""Get move.lines dict corresponding to the reconciliation model's write-off lines.
|
"""Get move.lines dict corresponding to the reconciliation model's write-off
|
||||||
:param residual_balance: The residual balance of the account on the manual reconciliation widget.
|
lines.
|
||||||
:return: A list of dict representing move.lines to be created corresponding to the write-off lines.
|
:param residual_balance: The residual balance of the account on the manual
|
||||||
|
reconciliation widget.
|
||||||
|
:return: A list of dict representing move.lines to be created corresponding to
|
||||||
|
the write-off lines.
|
||||||
"""
|
"""
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
|
|
||||||
|
@ -153,8 +159,9 @@ class AccountReconcileModel(models.Model):
|
||||||
if detected_fiscal_position:
|
if detected_fiscal_position:
|
||||||
taxes = detected_fiscal_position.map_tax(taxes)
|
taxes = detected_fiscal_position.map_tax(taxes)
|
||||||
writeoff_line["tax_ids"] += [Command.set(taxes.ids)]
|
writeoff_line["tax_ids"] += [Command.set(taxes.ids)]
|
||||||
# Multiple taxes with force_tax_included results in wrong computation, so we
|
# Multiple taxes with force_tax_included results in wrong computation,
|
||||||
# only allow to set the force_tax_included field if we have one tax selected
|
# so we only allow to set the force_tax_included field if we have one
|
||||||
|
# tax selected
|
||||||
if line.force_tax_included:
|
if line.force_tax_included:
|
||||||
taxes = taxes[0].with_context(force_price_include=True)
|
taxes = taxes[0].with_context(force_price_include=True)
|
||||||
tax_vals_list = self._get_taxes_move_lines_dict(taxes, writeoff_line)
|
tax_vals_list = self._get_taxes_move_lines_dict(taxes, writeoff_line)
|
||||||
|
@ -172,15 +179,17 @@ class AccountReconcileModel(models.Model):
|
||||||
def _apply_rules(self, st_line, partner):
|
def _apply_rules(self, st_line, partner):
|
||||||
"""Apply criteria to get candidates for all reconciliation models.
|
"""Apply criteria to get candidates for all reconciliation models.
|
||||||
This function is called in enterprise by the reconciliation widget to match
|
This function is called in enterprise by the reconciliation widget to match
|
||||||
the statement line with the available candidates (using the reconciliation models).
|
the statement line with the available candidates (using the reconciliation
|
||||||
|
models).
|
||||||
:param st_line: The statement line to match.
|
:param st_line: The statement line to match.
|
||||||
:param partner: The partner to consider.
|
:param partner: The partner to consider.
|
||||||
:return: A dict mapping each statement line id with:
|
:return: A dict mapping each statement line id with:
|
||||||
* aml_ids: A list of account.move.line ids.
|
* aml_ids: A list of account.move.line ids.
|
||||||
* model: An account.reconcile.model record (optional).
|
* model: An account.reconcile.model record (optional).
|
||||||
* status: 'reconciled' if the lines has been already reconciled, 'write_off' if the write-off
|
* status: 'reconciled' if the lines has been already reconciled, 'write_off'
|
||||||
must be applied on the statement line.
|
if the write-off must be applied on the statement line.
|
||||||
* auto_reconcile: A flag indicating if the match is enough significant to auto reconcile the candidates.
|
* auto_reconcile: A flag indicating if the match is enough significant to
|
||||||
|
auto reconcile the candidates.
|
||||||
"""
|
"""
|
||||||
available_models = self.filtered(
|
available_models = self.filtered(
|
||||||
lambda m: m.rule_type != "writeoff_button"
|
lambda m: m.rule_type != "writeoff_button"
|
||||||
|
@ -318,7 +327,8 @@ class AccountReconcileModel(models.Model):
|
||||||
|
|
||||||
def _get_invoice_matching_st_line_tokens(self, st_line):
|
def _get_invoice_matching_st_line_tokens(self, st_line):
|
||||||
"""Parse the textual information from the statement line passed as parameter
|
"""Parse the textual information from the statement line passed as parameter
|
||||||
in order to extract from it the meaningful information in order to perform the matching.
|
in order to extract from it the meaningful information in order to perform the
|
||||||
|
matching.
|
||||||
:param st_line: A statement line.
|
:param st_line: A statement line.
|
||||||
:return: A list of tokens, each one being a string.
|
:return: A list of tokens, each one being a string.
|
||||||
"""
|
"""
|
||||||
|
@ -347,7 +357,8 @@ class AccountReconcileModel(models.Model):
|
||||||
return tokens
|
return tokens
|
||||||
|
|
||||||
def _get_invoice_matching_amls_candidates(self, st_line, partner):
|
def _get_invoice_matching_amls_candidates(self, st_line, partner):
|
||||||
"""Returns the match candidates for the 'invoice_matching' rule, with respect to the provided parameters.
|
"""Returns the match candidates for the 'invoice_matching' rule, with respect to
|
||||||
|
the provided parameters.
|
||||||
:param st_line: A statement line.
|
:param st_line: A statement line.
|
||||||
:param partner: The partner associated to the statement line.
|
:param partner: The partner associated to the statement line.
|
||||||
"""
|
"""
|
||||||
|
@ -381,14 +392,17 @@ class AccountReconcileModel(models.Model):
|
||||||
UNNEST(
|
UNNEST(
|
||||||
REGEXP_SPLIT_TO_ARRAY(
|
REGEXP_SPLIT_TO_ARRAY(
|
||||||
SUBSTRING(
|
SUBSTRING(
|
||||||
REGEXP_REPLACE({table_alias}.{field}, '[^0-9\s]', '', 'g'),
|
REGEXP_REPLACE(
|
||||||
|
{table_alias}.{field}, '[^0-9\s]', '', 'g'
|
||||||
|
),
|
||||||
'\S(?:.*\S)*'
|
'\S(?:.*\S)*'
|
||||||
),
|
),
|
||||||
'\s+'
|
'\s+'
|
||||||
)
|
)
|
||||||
) AS token
|
) AS token
|
||||||
FROM {tables}
|
FROM {tables}
|
||||||
JOIN account_move account_move_line__move_id ON account_move_line__move_id.id = account_move_line.move_id
|
JOIN account_move account_move_line__move_id
|
||||||
|
ON account_move_line__move_id.id = account_move_line.move_id
|
||||||
WHERE {where_clause} AND {table_alias}.{field} IS NOT NULL
|
WHERE {where_clause} AND {table_alias}.{field} IS NOT NULL
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
@ -432,11 +446,14 @@ class AccountReconcileModel(models.Model):
|
||||||
}
|
}
|
||||||
|
|
||||||
def _get_invoice_matching_rules_map(self):
|
def _get_invoice_matching_rules_map(self):
|
||||||
"""Get a mapping <priority_order, rule> that could be overridden in others modules.
|
"""Get a mapping <priority_order, rule> that could be overridden in others
|
||||||
|
modules.
|
||||||
:return: a mapping <priority_order, rule> where:
|
:return: a mapping <priority_order, rule> where:
|
||||||
* priority_order: Defines in which order the rules will be evaluated, the lowest comes first.
|
* priority_order: Defines in which order the rules will be evaluated, the
|
||||||
This is extremely important since the algorithm stops when a rule returns some candidates.
|
lowest comes first. This is extremely important since the algorithm stops
|
||||||
* rule: Method taking <st_line, partner> as parameters and returning the candidates journal items found.
|
when a rule returns some candidates.
|
||||||
|
* rule: Method taking <st_line, partner> as parameters and returning the
|
||||||
|
candidates journal items found.
|
||||||
"""
|
"""
|
||||||
rules_map = defaultdict(list)
|
rules_map = defaultdict(list)
|
||||||
rules_map[10].append(self._get_invoice_matching_amls_candidates)
|
rules_map[10].append(self._get_invoice_matching_amls_candidates)
|
||||||
|
@ -563,9 +580,11 @@ class AccountReconcileModel(models.Model):
|
||||||
)
|
)
|
||||||
> 0
|
> 0
|
||||||
):
|
):
|
||||||
# Here, we still have room for other candidates ; so we add the current one to the list we keep.
|
# Here, we still have room for other candidates ; so we add the
|
||||||
# Then, we continue iterating, even if there is no room anymore, just in case one of the following candidates
|
# current one to the list we keep. Then, we continue iterating, even
|
||||||
# is an exact match, which would then be preferred on the current candidates.
|
# if there is no room anymore, just in case one of the following
|
||||||
|
# candidates is an exact match, which would then be preferred on the
|
||||||
|
# current candidates.
|
||||||
kepts_amls_values_list.append(aml_values)
|
kepts_amls_values_list.append(aml_values)
|
||||||
sum_amount_residual_currency += aml_values[
|
sum_amount_residual_currency += aml_values[
|
||||||
"amount_residual_currency"
|
"amount_residual_currency"
|
||||||
|
@ -580,7 +599,8 @@ class AccountReconcileModel(models.Model):
|
||||||
else:
|
else:
|
||||||
return None, []
|
return None, []
|
||||||
|
|
||||||
# Try to match a batch with the early payment feature. Only a perfect match is allowed.
|
# Try to match a batch with the early payment feature. Only a perfect match is
|
||||||
|
# allowed.
|
||||||
match_type, kepts_amls_values_list = match_batch_amls(amls_with_epd_values_list)
|
match_type, kepts_amls_values_list = match_batch_amls(amls_with_epd_values_list)
|
||||||
if match_type != "perfect":
|
if match_type != "perfect":
|
||||||
kepts_amls_values_list = []
|
kepts_amls_values_list = []
|
||||||
|
@ -607,11 +627,14 @@ class AccountReconcileModel(models.Model):
|
||||||
:param amls_values_list: The candidates account.move.line as a list of dict:
|
:param amls_values_list: The candidates account.move.line as a list of dict:
|
||||||
* aml: The record.
|
* aml: The record.
|
||||||
* amount_residual: The amount residual to consider.
|
* amount_residual: The amount residual to consider.
|
||||||
* amount_residual_currency: The amount residual in foreign currency to consider.
|
* amount_residual_currency: The amount residual in foreign currency to
|
||||||
|
consider.
|
||||||
:return: A string representing what to do with the candidates:
|
:return: A string representing what to do with the candidates:
|
||||||
* rejected: Reject candidates.
|
* rejected: Reject candidates.
|
||||||
* allow_write_off: Allow to generate the write-off from the reconcile model lines if specified.
|
* allow_write_off: Allow to generate the write-off from the reconcile model
|
||||||
* allow_auto_reconcile: Allow to automatically reconcile entries if 'auto_validate' is enabled.
|
lines if specified.
|
||||||
|
* allow_auto_reconcile: Allow to automatically reconcile entries if
|
||||||
|
'auto_validate' is enabled.
|
||||||
"""
|
"""
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
|
|
||||||
|
@ -637,8 +660,8 @@ class AccountReconcileModel(models.Model):
|
||||||
if st_line_currency.is_zero(amount_curr_after_rec):
|
if st_line_currency.is_zero(amount_curr_after_rec):
|
||||||
return {"allow_auto_reconcile"}
|
return {"allow_auto_reconcile"}
|
||||||
|
|
||||||
# The payment amount is higher than the sum of invoices.
|
# The payment amount is higher than the sum of invoices. In that case, don't
|
||||||
# In that case, don't check the tolerance and don't try to generate any write-off.
|
# check the tolerance and don't try to generate any write-off.
|
||||||
if amount_curr_after_rec > 0.0:
|
if amount_curr_after_rec > 0.0:
|
||||||
return {"allow_auto_reconcile"}
|
return {"allow_auto_reconcile"}
|
||||||
|
|
||||||
|
@ -646,8 +669,8 @@ class AccountReconcileModel(models.Model):
|
||||||
if self.payment_tolerance_param == 0:
|
if self.payment_tolerance_param == 0:
|
||||||
return {"rejected"}
|
return {"rejected"}
|
||||||
|
|
||||||
# If the tolerance is expressed as a fixed amount, check the residual payment amount doesn't exceed the
|
# If the tolerance is expressed as a fixed amount, check the residual payment
|
||||||
# tolerance.
|
# amount doesn't exceed the tolerance.
|
||||||
if (
|
if (
|
||||||
self.payment_tolerance_type == "fixed_amount"
|
self.payment_tolerance_type == "fixed_amount"
|
||||||
and -amount_curr_after_rec <= self.payment_tolerance_param
|
and -amount_curr_after_rec <= self.payment_tolerance_param
|
||||||
|
|
|
@ -9,8 +9,8 @@ class TestAccountReconciliationCommon(AccountTestInvoicingCommon):
|
||||||
|
|
||||||
"""Tests for reconciliation (account.tax)
|
"""Tests for reconciliation (account.tax)
|
||||||
|
|
||||||
Test used to check that when doing a sale or purchase invoice in a different currency,
|
Test used to check that when doing a sale or purchase invoice in a different
|
||||||
the result will be balanced.
|
currency, the result will be balanced.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
|
@ -402,7 +402,7 @@ class TestReconciliationMatchingRules(AccountTestInvoicingCommon):
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test matching with the partner name (reinitializing the statement line first)
|
# Test matching with the partner name (resetting the statement line first)
|
||||||
self.bank_line_1.write(
|
self.bank_line_1.write(
|
||||||
{**st_line_initial_vals, st_line_field: self.partner_1.name}
|
{**st_line_initial_vals, st_line_field: self.partner_1.name}
|
||||||
)
|
)
|
||||||
|
@ -920,7 +920,7 @@ class TestReconciliationMatchingRules(AccountTestInvoicingCommon):
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_auto_reconcile_with_tax(self):
|
def test_auto_reconcile_with_tax(self):
|
||||||
"""Test auto reconciliation with a tax amount included in the bank statement line"""
|
"""Test auto reconciliation with a tax amount included in the bank stat. line"""
|
||||||
self.rule_1.write(
|
self.rule_1.write(
|
||||||
{
|
{
|
||||||
"auto_reconcile": True,
|
"auto_reconcile": True,
|
||||||
|
@ -968,7 +968,7 @@ class TestReconciliationMatchingRules(AccountTestInvoicingCommon):
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_auto_reconcile_with_tax_fpos(self):
|
def test_auto_reconcile_with_tax_fpos(self):
|
||||||
"""Test the fiscal positions are applied by reconcile models when using taxes."""
|
"""Test the fiscal positions are applied by reconcile models when using taxes"""
|
||||||
self.rule_1.write(
|
self.rule_1.write(
|
||||||
{
|
{
|
||||||
"auto_reconcile": True,
|
"auto_reconcile": True,
|
||||||
|
@ -1031,6 +1031,7 @@ class TestReconciliationMatchingRules(AccountTestInvoicingCommon):
|
||||||
def test_reverted_move_matching(self):
|
def test_reverted_move_matching(self):
|
||||||
partner = self.partner_1
|
partner = self.partner_1
|
||||||
AccountMove = self.env["account.move"]
|
AccountMove = self.env["account.move"]
|
||||||
|
account = self.bank_journal.company_id.account_journal_payment_credit_account_id
|
||||||
move = AccountMove.create(
|
move = AccountMove.create(
|
||||||
{
|
{
|
||||||
"journal_id": self.bank_journal.id,
|
"journal_id": self.bank_journal.id,
|
||||||
|
@ -1049,7 +1050,7 @@ class TestReconciliationMatchingRules(AccountTestInvoicingCommon):
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
{
|
{
|
||||||
"account_id": self.bank_journal.company_id.account_journal_payment_credit_account_id.id,
|
"account_id": account.id,
|
||||||
"partner_id": partner.id,
|
"partner_id": partner.id,
|
||||||
"name": "I'm gonna cut you into little pieces",
|
"name": "I'm gonna cut you into little pieces",
|
||||||
"credit": 10,
|
"credit": 10,
|
||||||
|
@ -1140,7 +1141,7 @@ class TestReconciliationMatchingRules(AccountTestInvoicingCommon):
|
||||||
"line_ids": [(5, 0, 0)],
|
"line_ids": [(5, 0, 0)],
|
||||||
"match_partner": False,
|
"match_partner": False,
|
||||||
"match_label": "contains",
|
"match_label": "contains",
|
||||||
"match_label_param": "Tournicoti", # So that we only match what we want to test
|
"match_label_param": "Tournicoti", # match what we want to test
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1165,7 +1166,7 @@ class TestReconciliationMatchingRules(AccountTestInvoicingCommon):
|
||||||
{
|
{
|
||||||
"match_partner": False,
|
"match_partner": False,
|
||||||
"match_label": "contains",
|
"match_label": "contains",
|
||||||
"match_label_param": "doudlidou", # So that we only match what we want to test
|
"match_label_param": "doudlidou", # match what we want to test
|
||||||
"payment_tolerance_param": 10.0,
|
"payment_tolerance_param": 10.0,
|
||||||
"auto_reconcile": True,
|
"auto_reconcile": True,
|
||||||
}
|
}
|
||||||
|
@ -1219,7 +1220,7 @@ class TestReconciliationMatchingRules(AccountTestInvoicingCommon):
|
||||||
self.bank_line_2.write({"partner_id": None})
|
self.bank_line_2.write({"partner_id": None})
|
||||||
self.rule_1.write({"match_partner": False})
|
self.rule_1.write({"match_partner": False})
|
||||||
|
|
||||||
# bank_line_1 should match, as its communication contains the invoice's partner name
|
# bank_line_1 should match, as its communic. contains the invoice's partner name
|
||||||
self._check_statement_matching(
|
self._check_statement_matching(
|
||||||
self.rule_1,
|
self.rule_1,
|
||||||
{
|
{
|
||||||
|
@ -1246,13 +1247,13 @@ class TestReconciliationMatchingRules(AccountTestInvoicingCommon):
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_match_multi_currencies(self):
|
def test_match_multi_currencies(self):
|
||||||
"""Ensure the matching of candidates is made using the right statement line currency.
|
"""Ensure the matching of candidates is made using the right statement line
|
||||||
In this test, the value of the statement line is 100 USD = 300 GOL = 900 DAR and we want to match two journal
|
currency. In this test, the value of the statement line is 100 USD = 300
|
||||||
items of:
|
GOL = 900 DAR and we want to match two journal items of:
|
||||||
- 100 USD = 200 GOL (= 600 DAR from the statement line point of view)
|
- 100 USD = 200 GOL (= 600 DAR from the statement line point of view)
|
||||||
- 14 USD = 280 DAR
|
- 14 USD = 280 DAR
|
||||||
Both journal items should be suggested to the user because they represents 98% of the statement line amount
|
Both journal items should be suggested to the user because they represents 98%
|
||||||
(DAR).
|
of the statement line amount (DAR).
|
||||||
"""
|
"""
|
||||||
partner = self.env["res.partner"].create({"name": "Bernard Perdant"})
|
partner = self.env["res.partner"].create({"name": "Bernard Perdant"})
|
||||||
|
|
||||||
|
@ -1280,9 +1281,7 @@ class TestReconciliationMatchingRules(AccountTestInvoicingCommon):
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
statement_line = self.env[
|
statement_line = self.env["account.bank.statement.line"].create(
|
||||||
"account.bank.statement.line"
|
|
||||||
].create(
|
|
||||||
{
|
{
|
||||||
"journal_id": journal.id,
|
"journal_id": journal.id,
|
||||||
"date": "2016-01-01",
|
"date": "2016-01-01",
|
||||||
|
@ -1290,7 +1289,8 @@ class TestReconciliationMatchingRules(AccountTestInvoicingCommon):
|
||||||
"partner_id": partner.id,
|
"partner_id": partner.id,
|
||||||
"foreign_currency_id": self.currency_data_2["currency"].id,
|
"foreign_currency_id": self.currency_data_2["currency"].id,
|
||||||
"amount": 300.0, # Rate is 3 GOL = 1 USD in 2016.
|
"amount": 300.0, # Rate is 3 GOL = 1 USD in 2016.
|
||||||
"amount_currency": 900.0, # Rate is 10 DAR = 1 USD in 2016 but the rate used by the bank is 9:1.
|
# Rate is 10 DAR = 1 USD in 2016 but the rate used by the bank is 9:1.
|
||||||
|
"amount_currency": 900.0,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1447,10 +1447,11 @@ class TestReconciliationMatchingRules(AccountTestInvoicingCommon):
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_no_amount_check_keep_first(self):
|
def test_no_amount_check_keep_first(self):
|
||||||
"""In case the reconciliation model doesn't check the total amount of the candidates,
|
"""In case the reconciliation model doesn't check the total amount of the
|
||||||
we still don't want to suggest more than are necessary to match the statement.
|
candidates, we still don't want to suggest more than are necessary to match the
|
||||||
For example, if a statement line amounts to 250 and is to be matched with three invoices
|
statement. For example, if a statement line amounts to 250 and is to be matched
|
||||||
of 100, 200 and 300 (retrieved in this order), only 100 and 200 should be proposed.
|
with three invoices of 100, 200 and 300 (retrieved in this order), only 100 and
|
||||||
|
200 should be proposed.
|
||||||
"""
|
"""
|
||||||
self.rule_1.allow_payment_tolerance = False
|
self.rule_1.allow_payment_tolerance = False
|
||||||
self.bank_line_2.amount = 250
|
self.bank_line_2.amount = 250
|
||||||
|
|
|
@ -122,7 +122,6 @@ class AccountBankStatementLine(models.Model):
|
||||||
or record.company_id.reconcile_aggregate
|
or record.company_id.reconcile_aggregate
|
||||||
)
|
)
|
||||||
record.reconcile_aggregate = reconcile_aggregate
|
record.reconcile_aggregate = reconcile_aggregate
|
||||||
print(record.date, reconcile_aggregate_map[reconcile_aggregate](record))
|
|
||||||
record.aggregate_id, record.aggregate_name = reconcile_aggregate_map[
|
record.aggregate_id, record.aggregate_name = reconcile_aggregate_map[
|
||||||
reconcile_aggregate
|
reconcile_aggregate
|
||||||
](record)
|
](record)
|
||||||
|
@ -825,9 +824,10 @@ class AccountBankStatementLine(models.Model):
|
||||||
],
|
],
|
||||||
limit=1,
|
limit=1,
|
||||||
)
|
)
|
||||||
|
balance = previous_line_with_statement.statement_id.balance_end_real
|
||||||
action["context"] = {
|
action["context"] = {
|
||||||
"default_journal_id": self.journal_id.id,
|
"default_journal_id": self.journal_id.id,
|
||||||
"default_balance_start": previous_line_with_statement.statement_id.balance_end_real,
|
"default_balance_start": balance,
|
||||||
"split_line_id": self.id,
|
"split_line_id": self.id,
|
||||||
}
|
}
|
||||||
return action
|
return action
|
||||||
|
|
|
@ -711,8 +711,8 @@ class TestReconciliationWidget(TestAccountReconciliationCommon):
|
||||||
|
|
||||||
def test_widget_invoice_unselect(self):
|
def test_widget_invoice_unselect(self):
|
||||||
"""
|
"""
|
||||||
We want to test how selection and unselection of an account move lines is managed
|
We want to test how selection and unselection of an account move lines is
|
||||||
by the system.
|
managed by the system.
|
||||||
"""
|
"""
|
||||||
inv1 = self.create_invoice(
|
inv1 = self.create_invoice(
|
||||||
currency_id=self.currency_euro_id, invoice_amount=100
|
currency_id=self.currency_euro_id, invoice_amount=100
|
||||||
|
@ -786,7 +786,7 @@ class TestReconciliationWidget(TestAccountReconciliationCommon):
|
||||||
f.manual_partner_id = inv1.partner_id
|
f.manual_partner_id = inv1.partner_id
|
||||||
self.assertEqual(f.partner_id, inv1.partner_id)
|
self.assertEqual(f.partner_id, inv1.partner_id)
|
||||||
bank_stmt_line.clean_reconcile()
|
bank_stmt_line.clean_reconcile()
|
||||||
# As we have a set a partner, the cleaning should assign the invoice automatically
|
# As we have set a partner, the cleaning should assign the invoice automatically
|
||||||
self.assertTrue(bank_stmt_line.can_reconcile)
|
self.assertTrue(bank_stmt_line.can_reconcile)
|
||||||
|
|
||||||
def test_widget_model_clean(self):
|
def test_widget_model_clean(self):
|
||||||
|
|
Loading…
Reference in New Issue