[REF] account: remove manual reconciliation widget

The manual reconciliation widget is too complex. We completely remove it and
replace it with a simple wizard `account.reconcile.wizard` that opens when
selected lines can't be directly/silently reconciled (then we need a
write-off whose data will be filled in the wizard).

To do so we had to refactor reconciliation methods to allow to shadow some
values and fake reconciliation to get correct values.
We also now use of the _reconcile_plan instead of the previous reconciliation
which should be more efficient and correct.

Refactored a bit common between `test_account_reconcile_wizard` and
`test_account_move_reconcile` to avoid duplication.

In this process of simplification we also separate the previous `automatic_entry_wizard`
in two separate interfaces from the user's perspective: one only handle the change of
period and the other will handle complex transfer that are not possible through regular
reconciliation process (i.e. through the wizard we are creating in Enterprise related PR).

closes odoo/odoo#120832

Task: 3060792
Related: odoo/upgrade#4674
Related: odoo/enterprise#40510
Signed-off-by: Laurent Smet <las@odoo.com>
This commit is contained in:
Claire Bretton (clbr)
2023-05-14 00:02:31 +02:00
committed by Laurent Smet
parent cd20b56693
commit f8597f3301
8 changed files with 407 additions and 456 deletions
+1 -9
View File
@@ -3941,15 +3941,7 @@ class AccountMove(models.Model):
:param has_tax: If any taxes are involved in the lines of the invoice
:return: a list of tuples containing the lock dates affecting this move, ordered chronologically.
"""
locks = []
user_lock_date = self.company_id._get_user_fiscal_lock_date()
if invoice_date and user_lock_date and invoice_date <= user_lock_date:
locks.append((user_lock_date, _('user')))
tax_lock_date = self.company_id.tax_lock_date
if invoice_date and tax_lock_date and has_tax and invoice_date <= tax_lock_date:
locks.append((tax_lock_date, _('tax')))
locks.sort()
return locks
return self.company_id._get_violated_lock_dates(invoice_date, has_tax)
@api.model
def _move_dict_to_preview_vals(self, move_vals, currency_id=None):
+235 -141
View File
@@ -1595,30 +1595,95 @@ class AccountMoveLine(models.Model):
# RECONCILIATION
# -------------------------------------------------------------------------
def _get_reconciliation_aml_field_value(self, field, shadowed_aml_values):
self.ensure_one()
if shadowed_aml_values and field in shadowed_aml_values.get(self, {}):
return shadowed_aml_values[self][field]
else:
return self[field]
@api.model
def _prepare_reconciliation_single_partial(self, debit_values, credit_values):
""" Prepare the values to create an account.partial.reconcile later when reconciling the dictionaries passed
as parameters, each one representing an account.move.line.
:param debit_values: The values of account.move.line to consider for a debit line.
:param credit_values: The values of account.move.line to consider for a credit line.
:return: A dictionary:
* debit_values: None if the line has nothing left to reconcile.
* credit_values: None if the line has nothing left to reconcile.
* partial_values: The newly computed values for the partial.
* exchange_values: The values to create an exchange difference linked to this partial.
def _prepare_move_line_residual_amounts(self, aml_values, counterpart_currency, shadowed_aml_values=None):
""" Prepare the available residual amounts for each currency.
:param aml_values: The values of account.move.line to consider.
:param counterpart_currency: The currency of the opposite line this line will be reconciled with.
:param shadowed_aml_values: A mapping aml -> dictionary to replace some original aml values to something else.
This is usefull if you want to preview the reconciliation before doing some changes
on amls like changing a date or an account.
:return: A mapping currency -> dictionary containing:
* residual: The residual amount left for this currency.
* rate: The rate applied regarding the company's currency.
"""
def get_odoo_rate(aml, currency):
if aml.move_id.is_invoice(include_receipts=True):
exchange_rate_date = aml.move_id.invoice_date
else:
exchange_rate_date = aml.date
exchange_rate_date = aml._get_reconciliation_aml_field_value('date', shadowed_aml_values)
return currency._get_conversion_rate(aml.company_currency_id, currency, aml.company_id, exchange_rate_date)
def get_accounting_rate(aml):
if not aml.company_currency_id.is_zero(aml.balance) and not aml.currency_id.is_zero(aml.amount_currency):
return abs(aml.amount_currency) / abs(aml.balance)
def get_accounting_rate(aml, currency):
balance = aml._get_reconciliation_aml_field_value('balance', shadowed_aml_values)
amount_currency = aml._get_reconciliation_aml_field_value('amount_currency', shadowed_aml_values)
if not aml.company_currency_id.is_zero(balance) and not currency.is_zero(amount_currency):
return abs(amount_currency / balance)
aml = aml_values['aml']
remaining_amount_curr = aml_values['amount_residual_currency']
remaining_amount = aml_values['amount_residual']
company_currency = aml.company_currency_id
currency = aml._get_reconciliation_aml_field_value('currency_id', shadowed_aml_values)
account = aml._get_reconciliation_aml_field_value('account_id', shadowed_aml_values)
has_zero_residual = company_currency.is_zero(remaining_amount)
has_zero_residual_currency = currency.is_zero(remaining_amount_curr)
is_rec_pay_account = account.account_type in ('asset_receivable', 'liability_payable')
available_residual_per_currency = {}
if not has_zero_residual:
available_residual_per_currency[company_currency] = {
'residual': remaining_amount,
'rate': 1,
}
if currency != company_currency and not has_zero_residual_currency:
available_residual_per_currency[currency] = {
'residual': remaining_amount_curr,
'rate': get_accounting_rate(aml, currency),
}
if currency == company_currency \
and is_rec_pay_account \
and not has_zero_residual \
and counterpart_currency != company_currency:
rate = get_odoo_rate(aml, counterpart_currency)
available_residual_per_currency[counterpart_currency] = {
'residual': counterpart_currency.round(remaining_amount * rate),
'rate': rate,
}
elif currency == counterpart_currency \
and currency != company_currency \
and not has_zero_residual_currency:
available_residual_per_currency[counterpart_currency] = {
'residual': remaining_amount_curr,
'rate': get_accounting_rate(aml, currency),
}
return available_residual_per_currency
@api.model
def _prepare_reconciliation_single_partial(self, debit_values, credit_values, shadowed_aml_values=None):
""" Prepare the values to create an account.partial.reconcile later when reconciling the dictionaries passed
as parameters, each one representing an account.move.line.
:param debit_values: The values of account.move.line to consider for a debit line.
:param credit_values: The values of account.move.line to consider for a credit line.
:param shadowed_aml_values: A mapping aml -> dictionary to replace some original aml values to something else.
This is usefull if you want to preview the reconciliation before doing some changes
on amls like changing a date or an account.
:return: A dictionary:
* debit_values: None if the line has nothing left to reconcile.
* credit_values: None if the line has nothing left to reconcile.
* partial_values: The newly computed values for the partial.
* exchange_values: The values to create an exchange difference linked to this partial.
"""
# ==== Determine the currency in which the reconciliation will be done ====
# In this part, we retrieve the residual amounts, check if they are zero or not and determine in which
# currency and at which rate the reconciliation will be done.
@@ -1626,95 +1691,70 @@ class AccountMoveLine(models.Model):
'debit_values': debit_values,
'credit_values': credit_values,
}
debit_aml = debit_values['aml']
credit_aml = credit_values['aml']
debit_currency = debit_aml._get_reconciliation_aml_field_value('currency_id', shadowed_aml_values)
credit_currency = credit_aml._get_reconciliation_aml_field_value('currency_id', shadowed_aml_values)
company_currency = debit_aml.company_currency_id
remaining_debit_amount_curr = debit_values['amount_residual_currency']
remaining_credit_amount_curr = credit_values['amount_residual_currency']
remaining_debit_amount = debit_values['amount_residual']
remaining_credit_amount = credit_values['amount_residual']
debit_aml = debit_values['aml']
credit_aml = credit_values['aml']
company_currency = debit_aml.company_currency_id
has_debit_zero_residual = company_currency.is_zero(remaining_debit_amount)
has_credit_zero_residual = company_currency.is_zero(remaining_credit_amount)
has_debit_zero_residual_currency = debit_aml.currency_id.is_zero(remaining_debit_amount_curr)
has_credit_zero_residual_currency = credit_aml.currency_id.is_zero(remaining_credit_amount_curr)
is_rec_pay_account = debit_aml.account_type in ('asset_receivable', 'liability_payable')
debit_available_residual_amounts = self._prepare_move_line_residual_amounts(
debit_values,
credit_currency,
shadowed_aml_values=shadowed_aml_values,
)
credit_available_residual_amounts = self._prepare_move_line_residual_amounts(
credit_values,
debit_currency,
shadowed_aml_values=shadowed_aml_values,
)
if debit_aml.currency_id == credit_aml.currency_id == company_currency \
and not has_debit_zero_residual \
and not has_credit_zero_residual:
# Everything is expressed in company's currency and there is something left to reconcile.
recon_currency = company_currency
debit_rate = credit_rate = 1.0
recon_debit_amount = remaining_debit_amount
recon_credit_amount = -remaining_credit_amount
elif debit_aml.currency_id == company_currency \
and is_rec_pay_account \
and not has_debit_zero_residual \
and credit_aml.currency_id != company_currency \
and not has_credit_zero_residual_currency:
# The credit line is using a foreign currency but not the opposite line.
# In that case, convert the amount in company currency to the foreign currency one.
recon_currency = credit_aml.currency_id
debit_rate = get_odoo_rate(debit_aml, recon_currency)
credit_rate = get_accounting_rate(credit_aml)
recon_debit_amount = recon_currency.round(remaining_debit_amount * debit_rate)
recon_credit_amount = -remaining_credit_amount_curr
elif debit_aml.currency_id != company_currency \
and is_rec_pay_account \
and not has_debit_zero_residual_currency \
and credit_aml.currency_id == company_currency \
and not has_credit_zero_residual:
# The debit line is using a foreign currency but not the opposite line.
# In that case, convert the amount in company currency to the foreign currency one.
recon_currency = debit_aml.currency_id
debit_rate = get_accounting_rate(debit_aml)
credit_rate = get_odoo_rate(credit_aml, recon_currency)
recon_debit_amount = remaining_debit_amount_curr
recon_credit_amount = recon_currency.round(-remaining_credit_amount * credit_rate)
elif debit_aml.currency_id == credit_aml.currency_id \
and debit_aml.currency_id != company_currency \
and not has_debit_zero_residual_currency \
and not has_credit_zero_residual_currency:
# Both lines are sharing the same foreign currency.
recon_currency = debit_aml.currency_id
debit_rate = get_accounting_rate(debit_aml)
credit_rate = get_accounting_rate(credit_aml)
recon_debit_amount = remaining_debit_amount_curr
recon_credit_amount = -remaining_credit_amount_curr
elif debit_aml.currency_id == credit_aml.currency_id \
and debit_aml.currency_id != company_currency \
and (has_debit_zero_residual_currency or has_credit_zero_residual_currency):
# Special case for exchange difference lines. In that case, both lines are sharing the same foreign
# currency but at least one has no amount in foreign currency.
# In that case, we don't want a rate for the opposite line because the exchange difference is supposed
# to reduce only the amount in company currency but not the foreign one.
recon_currency = company_currency
debit_rate = None
credit_rate = None
recon_debit_amount = remaining_debit_amount
recon_credit_amount = -remaining_credit_amount
if debit_currency != company_currency \
and debit_currency in debit_available_residual_amounts \
and debit_currency in credit_available_residual_amounts:
recon_currency = debit_currency
elif credit_currency != company_currency \
and credit_currency in debit_available_residual_amounts \
and credit_currency in credit_available_residual_amounts:
recon_currency = credit_currency
else:
# Multiple involved foreign currencies. The reconciliation is done using the currency of the company.
recon_currency = company_currency
debit_rate = get_accounting_rate(debit_aml)
credit_rate = get_accounting_rate(credit_aml)
recon_debit_amount = remaining_debit_amount
recon_credit_amount = -remaining_credit_amount
debit_recon_values = debit_available_residual_amounts.get(recon_currency)
credit_recon_values = credit_available_residual_amounts.get(recon_currency)
# Check if there is something left to reconcile. Move to the next loop iteration if not.
skip_reconciliation = False
if recon_currency.is_zero(recon_debit_amount):
if not debit_recon_values:
res['debit_values'] = None
skip_reconciliation = True
if recon_currency.is_zero(recon_credit_amount):
if not credit_recon_values:
res['credit_values'] = None
skip_reconciliation = True
if skip_reconciliation:
return res
recon_debit_amount = debit_recon_values['residual']
recon_credit_amount = -credit_recon_values['residual']
# ==== Match both lines together and compute amounts to reconcile ====
# Special case for exchange difference lines. In that case, both lines are sharing the same foreign
# currency but at least one has no amount in foreign currency.
# In that case, we don't want a rate for the opposite line because the exchange difference is supposed
# to reduce only the amount in company currency but not the foreign one.
exchange_line_mode = \
recon_currency == company_currency \
and debit_currency == credit_currency \
and (
not debit_available_residual_amounts.get(debit_currency)
or not credit_available_residual_amounts.get(credit_currency)
)
# Determine which line is fully matched by the other.
compare_amounts = recon_currency.compare_amounts(recon_debit_amount, recon_credit_amount)
min_recon_amount = min(recon_debit_amount, recon_credit_amount)
@@ -1723,24 +1763,38 @@ class AccountMoveLine(models.Model):
# ==== Computation of partial amounts ====
if recon_currency == company_currency:
if exchange_line_mode:
debit_rate = None
credit_rate = None
else:
debit_rate = debit_available_residual_amounts.get(debit_currency, {}).get('rate')
credit_rate = credit_available_residual_amounts.get(credit_currency, {}).get('rate')
# Compute the partial amount expressed in company currency.
partial_amount = min_recon_amount
# Compute the partial amount expressed in foreign currency.
if debit_rate:
partial_debit_amount_currency = debit_aml.currency_id.round(debit_rate * min_recon_amount)
partial_debit_amount_currency = debit_currency.round(debit_rate * min_recon_amount)
partial_debit_amount_currency = min(partial_debit_amount_currency, remaining_debit_amount_curr)
else:
partial_debit_amount_currency = 0.0
if credit_rate:
partial_credit_amount_currency = credit_aml.currency_id.round(credit_rate * min_recon_amount)
partial_credit_amount_currency = credit_currency.round(credit_rate * min_recon_amount)
partial_credit_amount_currency = min(partial_credit_amount_currency, -remaining_credit_amount_curr)
else:
partial_credit_amount_currency = 0.0
else:
# recon_currency != company_currency
# Compute the partial amount expressed in company currency.
if exchange_line_mode:
debit_rate = None
credit_rate = None
else:
debit_rate = debit_recon_values['rate']
credit_rate = credit_recon_values['rate']
# Compute the partial amount expressed in foreign currency.
if debit_rate:
partial_debit_amount = company_currency.round(min_recon_amount / debit_rate)
partial_debit_amount = min(partial_debit_amount, remaining_debit_amount)
@@ -1756,11 +1810,11 @@ class AccountMoveLine(models.Model):
# Compute the partial amount expressed in foreign currency.
# Take care to handle the case when a line expressed in company currency is mimicking the foreign
# currency of the opposite line.
if debit_aml.currency_id == company_currency:
if debit_currency == company_currency:
partial_debit_amount_currency = partial_amount
else:
partial_debit_amount_currency = min_recon_amount
if credit_aml.currency_id == company_currency:
if credit_currency == company_currency:
partial_credit_amount_currency = partial_amount
else:
partial_credit_amount_currency = min_recon_amount
@@ -1773,13 +1827,13 @@ class AccountMoveLine(models.Model):
if recon_currency == company_currency:
if debit_fully_matched:
debit_exchange_amount = remaining_debit_amount_curr - partial_debit_amount_currency
if not debit_aml.currency_id.is_zero(debit_exchange_amount):
if not debit_currency.is_zero(debit_exchange_amount):
exchange_lines_to_fix += debit_aml
amounts_list.append({'amount_residual_currency': debit_exchange_amount})
remaining_debit_amount_curr -= debit_exchange_amount
if credit_fully_matched:
credit_exchange_amount = remaining_credit_amount_curr + partial_credit_amount_currency
if not credit_aml.currency_id.is_zero(credit_exchange_amount):
if not credit_currency.is_zero(credit_exchange_amount):
exchange_lines_to_fix += credit_aml
amounts_list.append({'amount_residual_currency': credit_exchange_amount})
remaining_credit_amount_curr += credit_exchange_amount
@@ -1792,7 +1846,7 @@ class AccountMoveLine(models.Model):
exchange_lines_to_fix += debit_aml
amounts_list.append({'amount_residual': debit_exchange_amount})
remaining_debit_amount -= debit_exchange_amount
if debit_aml.currency_id == company_currency:
if debit_currency == company_currency:
remaining_debit_amount_curr -= debit_exchange_amount
else:
# Create an exchange difference ensuring the rate between the residual amounts expressed in
@@ -1803,7 +1857,7 @@ class AccountMoveLine(models.Model):
exchange_lines_to_fix += debit_aml
amounts_list.append({'amount_residual': debit_exchange_amount})
remaining_debit_amount -= debit_exchange_amount
if debit_aml.currency_id == company_currency:
if debit_currency == company_currency:
remaining_debit_amount_curr -= debit_exchange_amount
if credit_fully_matched:
@@ -1813,7 +1867,7 @@ class AccountMoveLine(models.Model):
exchange_lines_to_fix += credit_aml
amounts_list.append({'amount_residual': credit_exchange_amount})
remaining_credit_amount += credit_exchange_amount
if credit_aml.currency_id == company_currency:
if credit_currency == company_currency:
remaining_credit_amount_curr -= credit_exchange_amount
else:
# Create an exchange difference ensuring the rate between the residual amounts expressed in
@@ -1824,13 +1878,16 @@ class AccountMoveLine(models.Model):
exchange_lines_to_fix += credit_aml
amounts_list.append({'amount_residual': credit_exchange_amount})
remaining_credit_amount -= credit_exchange_amount
if credit_aml.currency_id == company_currency:
if credit_currency == company_currency:
remaining_credit_amount_curr -= credit_exchange_amount
if exchange_lines_to_fix:
res['exchange_values'] = exchange_lines_to_fix._prepare_exchange_difference_move_vals(
amounts_list,
exchange_date=max(debit_aml.date, credit_aml.date),
exchange_date=max(
debit_aml._get_reconciliation_aml_field_value('date', shadowed_aml_values),
credit_aml._get_reconciliation_aml_field_value('date', shadowed_aml_values),
),
)
# ==== Create partials ====
@@ -1860,16 +1917,30 @@ class AccountMoveLine(models.Model):
return res
@api.model
def _prepare_reconciliation_amls(self, values_list):
def _prepare_reconciliation_amls(self, values_list, shadowed_aml_values=None):
""" Prepare the partials on the current journal items to perform the reconciliation.
Note: The order of records in self is important because the journal items will be reconciled using this order.
:param values_list: A list of dictionaries, one for each aml.
:param shadowed_aml_values: A mapping aml -> dictionary to replace some original aml values to something else.
This is usefull if you want to preview the reconciliation before doing some changes
on amls like changing a date or an account.
:return: a tuple of
1) list of vals for partial reconciliation creation,
2) the list of vals for the exchange difference entries to be created
"""
debit_values_list = iter([x for x in values_list if x['aml'].balance > 0.0 or x['aml'].amount_currency > 0.0])
credit_values_list = iter([x for x in values_list if x['aml'].balance < 0.0 or x['aml'].amount_currency < 0.0])
debit_values_list = iter([
x
for x in values_list
if x['aml']._get_reconciliation_aml_field_value('balance', shadowed_aml_values) > 0.0
or x['aml']._get_reconciliation_aml_field_value('amount_currency', shadowed_aml_values) > 0.0
])
credit_values_list = iter([
x
for x in values_list
if x['aml']._get_reconciliation_aml_field_value('balance', shadowed_aml_values) < 0.0
or x['aml']._get_reconciliation_aml_field_value('amount_currency', shadowed_aml_values) < 0.0
])
debit_values = None
credit_values = None
fully_reconciled_aml_ids = set()
@@ -1896,7 +1967,11 @@ class AccountMoveLine(models.Model):
# ==== Compute the amounts to reconcile ====
results = self._prepare_reconciliation_single_partial(debit_values, credit_values)
results = self._prepare_reconciliation_single_partial(
debit_values,
credit_values,
shadowed_aml_values=shadowed_aml_values,
)
if results.get('partial_values'):
all_results.append(results)
if results['debit_values'] is None:
@@ -1909,11 +1984,14 @@ class AccountMoveLine(models.Model):
return all_results, fully_reconciled_aml_ids
@api.model
def _prepare_reconciliation_plan(self, plan, amls_values_map):
def _prepare_reconciliation_plan(self, plan, amls_values_map, shadowed_aml_values=None):
""" Perform virtually the reconciliation of the plan passed as parameter.
:param plan: The plan to know which lines to reconcile in which order.
:param amls_values_map: A mapping aml => amount_residual/amount_residual_currency
:param shadowed_aml_values: A mapping aml -> dictionary to replace some original aml values to something else.
This is usefull if you want to preview the reconciliation before doing some changes
on amls like changing a date or an account.
:return: A list of all results returned by the '_prepare_reconciliation_amls' method.
"""
all_fully_reconciled_aml_ids = set()
@@ -1921,10 +1999,13 @@ class AccountMoveLine(models.Model):
def process_amls(amls):
remaining_amls = amls.filtered(lambda aml: aml.id not in all_fully_reconciled_aml_ids)
amls_results, fully_reconciled_aml_ids = self._prepare_reconciliation_amls([
amls_values_map[aml]
for aml in remaining_amls
])
amls_results, fully_reconciled_aml_ids = self._prepare_reconciliation_amls(
[
amls_values_map[aml]
for aml in remaining_amls
],
shadowed_aml_values=shadowed_aml_values,
)
all_fully_reconciled_aml_ids.update(fully_reconciled_aml_ids)
for amls_result in amls_results:
all_results.append(amls_result)
@@ -1940,8 +2021,39 @@ class AccountMoveLine(models.Model):
process_leaf(plan)
return all_results
def _check_amls_exigibility_for_reconciliation(self, shadowed_aml_values=None):
""" Ensure the current journal items are eligible to be reconciled together.
:param shadowed_aml_values: A mapping aml -> dictionary to replace some original aml values to something else.
This is usefull if you want to preview the reconciliation before doing some changes
on amls like changing a date or an account.
"""
if not self:
return
if any(aml.reconciled for aml in self):
raise UserError(_("You are trying to reconcile some entries that are already reconciled."))
if any(aml.parent_state != 'posted' for aml in self):
raise UserError(_("You can only reconcile posted entries."))
accounts = self.mapped(lambda x: x._get_reconciliation_aml_field_value('account_id', shadowed_aml_values))
if len(accounts) > 1:
raise UserError(_(
"Entries are not from the same account: %s",
", ".join(accounts.mapped('display_name')),
))
if len(self.company_id) > 1:
raise UserError(_(
"Entries don't belong to the same company: %s",
", ".join(self.company_id.mapped('display_name')),
))
if not accounts.reconcile and accounts.account_type not in ('asset_cash', 'liability_credit_card'):
raise UserError(_(
"Account %s does not allow reconciliation. First change the configuration of this account "
"to allow it.",
accounts.display_name,
))
@api.model
def _optimize_reconciliation_plan(self, reconciliation_plan):
def _optimize_reconciliation_plan(self, reconciliation_plan, shadowed_aml_values=None):
""" Decode the initial reconciliation plan passed as parameter and converted it into a list of tree depicting
the way the reconciliation should be done.
Also, this method is responsible sorting the amls and splitting them by currency.
@@ -1955,6 +2067,9 @@ class AccountMoveLine(models.Model):
[[account.move.line(1, 2), account.move.line(3, 4)]]
:param reconciliation_plan: A list of reconciliation to perform.
:param shadowed_aml_values: A mapping aml -> dictionary to replace some original aml values to something else.
This is usefull if you want to preview the reconciliation before doing some changes
on amls like changing a date or an account.
:return: A list of dictionaries containing:
* amls: A recordset.
* aml_ids: The recordset ids.
@@ -1964,18 +2079,19 @@ class AccountMoveLine(models.Model):
def process_amls(amls):
if self._context.get('reduced_line_sorting'):
sorted_amls = amls.sorted(key=lambda aml: (
aml.date_maturity or aml.date,
aml.currency_id,
aml._get_reconciliation_aml_field_value('date_maturity', shadowed_aml_values)
or aml._get_reconciliation_aml_field_value('date', shadowed_aml_values),
aml._get_reconciliation_aml_field_value('currency_id', shadowed_aml_values),
))
else:
sorted_amls = amls.sorted(key=lambda aml: (
aml.date_maturity or aml.date,
aml.currency_id,
aml.amount_currency,
aml.balance,
aml._get_reconciliation_aml_field_value('date_maturity', shadowed_aml_values)
or aml._get_reconciliation_aml_field_value('date', shadowed_aml_values),
aml._get_reconciliation_aml_field_value('currency_id', shadowed_aml_values),
aml._get_reconciliation_aml_field_value('amount_currency', shadowed_aml_values),
aml._get_reconciliation_aml_field_value('balance', shadowed_aml_values),
))
currencies = sorted_amls.currency_id
currencies = sorted_amls.mapped(lambda x: x._get_reconciliation_aml_field_value('currency_id', shadowed_aml_values))
results = {
'amls': sorted_amls,
'aml_ids': set(sorted_amls.ids),
@@ -1984,7 +2100,8 @@ class AccountMoveLine(models.Model):
if len(currencies) != 1:
nodes = results['nodes'] = []
for currency in currencies:
amls_in_currency = sorted_amls.filtered(lambda x: x.currency_id == currency)
amls_in_currency = sorted_amls\
.filtered(lambda x: x._get_reconciliation_aml_field_value('currency_id', shadowed_aml_values) == currency)
nodes.append({
'amls': amls_in_currency,
'aml_ids': set(amls_in_currency.ids),
@@ -2024,32 +2141,7 @@ class AccountMoveLine(models.Model):
# Check the amls to be reconciled all together.
amls = plan_node['amls']
if any(aml.reconciled for aml in amls):
raise UserError(_("You are trying to reconcile some entries that are already reconciled."))
if any(aml.parent_state != 'posted' for aml in amls):
raise UserError(_("You can only reconcile posted entries."))
if len(amls.account_id) > 1:
raise UserError(_(
"Entries are not from the same account: %s",
", ".join(amls.account_id.mapped('display_name')),
))
if len(amls.company_id) > 1:
raise UserError(_(
"Entries doesn't belong to the same company: %s",
", ".join(amls.company_id.mapped('display_name')),
))
if any(
not aml.account_id.reconcile
and aml.account_id.account_type not in ('asset_cash', 'liability_credit_card')
for aml in amls
):
raise UserError(_(
"Account %s does not allow reconciliation. First change the configuration of this account "
"to allow it.",
amls.account_id.display_name
))
amls._check_amls_exigibility_for_reconciliation(shadowed_aml_values=shadowed_aml_values)
plan_list.append(plan_node)
all_aml_ids.update(plan_node['aml_ids'])
@@ -2899,7 +2991,7 @@ class AccountMoveLine(models.Model):
def action_open_business_doc(self):
return self.move_id.action_open_business_doc()
def action_automatic_entry(self):
def action_automatic_entry(self, default_action=None):
action = self.env['ir.actions.act_window']._for_xml_id('account.account_automatic_entry_wizard_action')
# Force the values of the move line in the context to avoid issues
ctx = dict(self.env.context)
@@ -2907,6 +2999,8 @@ class AccountMoveLine(models.Model):
ctx.pop('default_journal_id', None)
ctx['active_ids'] = self.ids
ctx['active_model'] = 'account.move.line'
if default_action:
ctx['default_action'] = default_action
action['context'] = ctx
return action
+17
View File
@@ -366,6 +366,23 @@ class ResCompany(models.Model):
lock_date = self.fiscalyear_lock_date or date.min
return lock_date
def _get_violated_lock_dates(self, accounting_date, has_tax):
"""Get all the lock dates affecting the current accounting_date.
:param accoutiaccounting_dateng_date: The accounting date
:param has_tax: If any taxes are involved in the lines of the invoice
:return: a list of tuples containing the lock dates ordered chronologically.
"""
self.ensure_one()
locks = []
user_lock_date = self._get_user_fiscal_lock_date()
if accounting_date and user_lock_date and accounting_date <= user_lock_date:
locks.append((user_lock_date, _('user')))
tax_lock_date = self.tax_lock_date
if accounting_date and tax_lock_date and has_tax and accounting_date <= tax_lock_date:
locks.append((tax_lock_date, _('tax')))
locks.sort()
return locks
def write(self, values):
#restrict the closing of FY if there are still unposted entries
self._validate_fiscalyear_lock(values)
+35 -165
View File
@@ -413,6 +413,41 @@ class AccountTestInvoicingCommon(TransactionCase):
return rslt
def create_line_for_reconciliation(self, balance, amount_currency, currency, move_date, account_1=None, partner=None):
write_off_account_to_be_reconciled = account_1 if account_1 else self.receivable_account
move = self.env['account.move'].create({
'move_type': 'entry',
'date': move_date,
'line_ids': [
Command.create({
'debit': balance if balance > 0.0 else 0.0,
'credit': -balance if balance < 0.0 else 0.0,
'amount_currency': amount_currency,
'account_id': write_off_account_to_be_reconciled.id,
'currency_id': currency.id,
'partner_id': partner.id if partner else None,
}),
Command.create({
'debit': -balance if balance < 0.0 else 0.0,
'credit': balance if balance > 0.0 else 0.0,
'amount_currency': -amount_currency,
'account_id': self.revenue_account.id,
'currency_id': currency.id,
'partner_id': partner.id if partner else None,
}),
],
})
move.action_post()
line = move.line_ids.filtered(lambda x: x.account_id == write_off_account_to_be_reconciled)
self.assertRecordValues(line, [{
'amount_residual': balance,
'amount_residual_currency': amount_currency,
'reconciled': False,
}])
return line
def assertInvoiceValues(self, move, expected_lines_values, expected_move_values):
def sort_lines(lines):
return lines.sorted(lambda line: (line.sequence, not bool(line.tax_line_id), line.name or '', line.balance))
@@ -541,168 +576,3 @@ class AccountTestInvoicingCommon(TransactionCase):
class AccountTestInvoicingHttpCommon(AccountTestInvoicingCommon, HttpCase):
pass
class TestAccountReconciliationCommon(AccountTestInvoicingCommon):
"""Tests for reconciliation (account.tax)
Test used to check that when doing a sale or purchase invoice in a different currency,
the result will be balanced.
"""
@classmethod
def setUpClass(cls, chart_template_ref=None):
super().setUpClass(chart_template_ref=chart_template_ref)
cls.company = cls.company_data['company']
cls.company.currency_id = cls.env.ref('base.EUR')
cls.partner_agrolait = cls.env['res.partner'].create({
'name': 'Deco Addict',
'is_company': True,
'country_id': cls.env.ref('base.us').id,
})
cls.partner_agrolait_id = cls.partner_agrolait.id
cls.currency_swiss_id = cls.env.ref("base.CHF").id
cls.currency_usd_id = cls.env.ref("base.USD").id
cls.currency_euro_id = cls.env.ref("base.EUR").id
cls.account_rcv = cls.company_data['default_account_receivable']
cls.account_rsa = cls.company_data['default_account_payable']
cls.product = cls.env['product.product'].create({
'name': 'Product Product 4',
'standard_price': 500.0,
'list_price': 750.0,
'type': 'consu',
'categ_id': cls.env.ref('product.product_category_all').id,
})
cls.bank_journal_euro = cls.env['account.journal'].create({'name': 'Bank', 'type': 'bank', 'code': 'BNK67'})
cls.account_euro = cls.bank_journal_euro.default_account_id
cls.bank_journal_usd = cls.env['account.journal'].create({'name': 'Bank US', 'type': 'bank', 'code': 'BNK68', 'currency_id': cls.currency_usd_id})
cls.account_usd = cls.bank_journal_usd.default_account_id
cls.fx_journal = cls.company.currency_exchange_journal_id
cls.diff_income_account = cls.company.income_currency_exchange_account_id
cls.diff_expense_account = cls.company.expense_currency_exchange_account_id
cls.expense_account = cls.company_data['default_account_expense']
# cash basis intermediary account
cls.tax_waiting_account = cls.env['account.account'].create({
'name': 'TAX_WAIT',
'code': 'TWAIT',
'account_type': 'liability_current',
'reconcile': True,
'company_id': cls.company.id,
})
# cash basis final account
cls.tax_final_account = cls.env['account.account'].create({
'name': 'TAX_TO_DEDUCT',
'code': 'TDEDUCT',
'account_type': 'asset_current',
'company_id': cls.company.id,
})
cls.tax_base_amount_account = cls.env['account.account'].create({
'name': 'TAX_BASE',
'code': 'TBASE',
'account_type': 'asset_current',
'company_id': cls.company.id,
})
cls.company.account_cash_basis_base_account_id = cls.tax_base_amount_account.id
# Journals
cls.purchase_journal = cls.company_data['default_journal_purchase']
cls.cash_basis_journal = cls.env['account.journal'].create({
'name': 'Test CABA',
'code': 'tCABA',
'type': 'general',
})
cls.general_journal = cls.company_data['default_journal_misc']
# Tax Cash Basis
cls.tax_cash_basis = cls.env['account.tax'].create({
'name': 'cash basis 20%',
'type_tax_use': 'purchase',
'company_id': cls.company.id,
'country_id': cls.company.account_fiscal_country_id.id,
'amount': 20,
'tax_exigibility': 'on_payment',
'cash_basis_transition_account_id': cls.tax_waiting_account.id,
'invoice_repartition_line_ids': [
(0,0, {
'repartition_type': 'base',
}),
(0,0, {
'repartition_type': 'tax',
'account_id': cls.tax_final_account.id,
}),
],
'refund_repartition_line_ids': [
(0,0, {
'repartition_type': 'base',
}),
(0,0, {
'repartition_type': 'tax',
'account_id': cls.tax_final_account.id,
}),
],
})
cls.env['res.currency.rate'].create([
{
'currency_id': cls.env.ref('base.EUR').id,
'name': '2010-01-02',
'rate': 1.0,
}, {
'currency_id': cls.env.ref('base.USD').id,
'name': '2010-01-02',
'rate': 1.2834,
}, {
'currency_id': cls.env.ref('base.USD').id,
'name': time.strftime('%Y-06-05'),
'rate': 1.5289,
}
])
def _create_invoice(self, move_type='out_invoice', invoice_amount=50, currency_id=None, partner_id=None, date_invoice=None, payment_term_id=False, auto_validate=False):
date_invoice = date_invoice or time.strftime('%Y') + '-07-01'
invoice_vals = {
'move_type': move_type,
'partner_id': partner_id or self.partner_agrolait_id,
'invoice_date': date_invoice,
'date': date_invoice,
'invoice_line_ids': [(0, 0, {
'name': 'product that cost %s' % invoice_amount,
'quantity': 1,
'price_unit': invoice_amount,
'tax_ids': [Command.set([])],
})]
}
if payment_term_id:
invoice_vals['invoice_payment_term_id'] = payment_term_id
if currency_id:
invoice_vals['currency_id'] = currency_id
invoice = self.env['account.move'].with_context(default_move_type=move_type).create(invoice_vals)
if auto_validate:
invoice.action_post()
return invoice
def create_invoice(self, move_type='out_invoice', invoice_amount=50, currency_id=None):
return self._create_invoice(move_type=move_type, invoice_amount=invoice_amount, currency_id=currency_id, auto_validate=True)
def create_invoice_partner(self, move_type='out_invoice', invoice_amount=50, currency_id=None, partner_id=False, payment_term_id=False):
return self._create_invoice(
move_type=move_type,
invoice_amount=invoice_amount,
currency_id=currency_id,
partner_id=partner_id,
payment_term_id=payment_term_id,
auto_validate=True
)
@@ -19,6 +19,10 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon):
super().setUpClass(chart_template_ref=chart_template_ref)
cls.receivable_account = cls.company_data['default_account_receivable']
cls.payable_account = cls.company_data['default_account_payable']
cls.expense_account = cls.company_data['default_account_expense']
cls.revenue_account = cls.company_data['default_account_revenue']
cls.extra_receivable_account_1 = cls.copy_account(cls.receivable_account)
cls.extra_receivable_account_2 = cls.copy_account(cls.receivable_account)
cls.extra_payable_account_1 = cls.copy_account(cls.company_data['default_account_payable'])
@@ -27,6 +31,7 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon):
cls.exch_income_account = cls.env.company.income_currency_exchange_account_id
cls.exch_expense_account = cls.env.company.expense_currency_exchange_account_id
# ==== Multi-currency setup ====
cls.currency_data_2 = cls.setup_multi_currency_data(default_values={
@@ -207,38 +212,6 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon):
def _get_caba_moves(self, moves):
return moves.search([('tax_cash_basis_origin_move_id', 'in', moves.ids)])
def _create_line_for_reconciliation(self, balance, amount_currency, currency, move_date):
move = self.env['account.move'].create({
'move_type': 'entry',
'date': move_date,
'line_ids': [
Command.create({
'debit': balance if balance > 0.0 else 0.0,
'credit': -balance if balance < 0.0 else 0.0,
'amount_currency': amount_currency,
'account_id': self.receivable_account.id,
'currency_id': currency.id,
}),
Command.create({
'debit': -balance if balance < 0.0 else 0.0,
'credit': balance if balance > 0.0 else 0.0,
'amount_currency': -amount_currency,
'account_id': self.company_data['default_account_revenue'].id,
'currency_id': currency.id,
}),
],
})
move.action_post()
line = move.line_ids.filtered(lambda x: x.account_id == self.receivable_account)
self.assertRecordValues(line, [{
'amount_residual': balance,
'amount_residual_currency': amount_currency,
'reconciled': False,
}])
return line
def test_full_reconcile_bunch_lines(self):
""" Test the reconciliation with multiple lines at the same time and ensure the result is always a full
reconcile whatever the number of involved currencies.
@@ -247,25 +220,25 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon):
foreign_curr1 = self.currency_data['currency']
foreign_curr2 = self.currency_data_2['currency']
line_1 = self._create_line_for_reconciliation(1000.0, 1000.0, comp_curr, '2016-01-01')
line_2 = self._create_line_for_reconciliation(-300.0, -300.0, comp_curr, '2016-01-01')
line_3 = self._create_line_for_reconciliation(-400.0, -400.0, comp_curr, '2016-01-01')
line_4 = self._create_line_for_reconciliation(-500.0, -500.0, comp_curr, '2016-01-01')
line_5 = self._create_line_for_reconciliation(200.0, 200.0, comp_curr, '2016-01-01')
line_1 = self.create_line_for_reconciliation(1000.0, 1000.0, comp_curr, '2016-01-01')
line_2 = self.create_line_for_reconciliation(-300.0, -300.0, comp_curr, '2016-01-01')
line_3 = self.create_line_for_reconciliation(-400.0, -400.0, comp_curr, '2016-01-01')
line_4 = self.create_line_for_reconciliation(-500.0, -500.0, comp_curr, '2016-01-01')
line_5 = self.create_line_for_reconciliation(200.0, 200.0, comp_curr, '2016-01-01')
comp_curr_batch = line_1 + line_2 + line_3 + line_4 + line_5
line_1 = self._create_line_for_reconciliation(1200.0, 3600.0, foreign_curr1, '2016-01-01')
line_2 = self._create_line_for_reconciliation(-240.0, -480.0, foreign_curr1, '2017-01-01')
line_3 = self._create_line_for_reconciliation(-720.0, -1440.0, foreign_curr1, '2017-01-01')
line_4 = self._create_line_for_reconciliation(-1020.0, -2040.0, foreign_curr1, '2017-01-01')
line_5 = self._create_line_for_reconciliation(120.0, 360.0, foreign_curr1, '2016-01-01')
line_1 = self.create_line_for_reconciliation(1200.0, 3600.0, foreign_curr1, '2016-01-01')
line_2 = self.create_line_for_reconciliation(-240.0, -480.0, foreign_curr1, '2017-01-01')
line_3 = self.create_line_for_reconciliation(-720.0, -1440.0, foreign_curr1, '2017-01-01')
line_4 = self.create_line_for_reconciliation(-1020.0, -2040.0, foreign_curr1, '2017-01-01')
line_5 = self.create_line_for_reconciliation(120.0, 360.0, foreign_curr1, '2016-01-01')
same_curr_batch = line_1 + line_2 + line_3 + line_4 + line_5
line_1 = self._create_line_for_reconciliation(1200.0, 3600.0, foreign_curr1, '2016-01-01')
line_2 = self._create_line_for_reconciliation(780.0, 2340.0, foreign_curr1, '2016-01-01')
line_3 = self._create_line_for_reconciliation(-240.0, -960.0, foreign_curr2, '2017-01-01')
line_4 = self._create_line_for_reconciliation(-720.0, -2880.0, foreign_curr2, '2017-01-01')
line_5 = self._create_line_for_reconciliation(-1020.0, -4080.0, foreign_curr2, '2017-01-01')
line_1 = self.create_line_for_reconciliation(1200.0, 3600.0, foreign_curr1, '2016-01-01')
line_2 = self.create_line_for_reconciliation(780.0, 2340.0, foreign_curr1, '2016-01-01')
line_3 = self.create_line_for_reconciliation(-240.0, -960.0, foreign_curr2, '2017-01-01')
line_4 = self.create_line_for_reconciliation(-720.0, -2880.0, foreign_curr2, '2017-01-01')
line_5 = self.create_line_for_reconciliation(-1020.0, -4080.0, foreign_curr2, '2017-01-01')
multi_curr_batch = line_1 + line_2 + line_3 + line_4 + line_5
for batch, sub_test_name in (
@@ -292,9 +265,9 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon):
for rate2 in rates:
for rate3 in rates:
with self.subTest(rate1=rate1, rate2=rate2, rate3=rate3):
line_1 = self._create_line_for_reconciliation(120.0 * rate1, 120.0, currency, '2017-01-01')
line_2 = self._create_line_for_reconciliation(120.0 * rate2, 120.0, currency, '2017-01-01')
line_3 = self._create_line_for_reconciliation(-240.0 * rate3, -240.0, currency, '2017-01-01')
line_1 = self.create_line_for_reconciliation(120.0 * rate1, 120.0, currency, '2017-01-01')
line_2 = self.create_line_for_reconciliation(120.0 * rate2, 120.0, currency, '2017-01-01')
line_3 = self.create_line_for_reconciliation(-240.0 * rate3, -240.0, currency, '2017-01-01')
(line_1 + line_2 + line_3).reconcile()
self.assertTrue(line_1.full_reconcile_id)
@@ -312,8 +285,8 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon):
((60.0, 60.0, comp_curr, '2017-01-01'), (-40.0, -120.0, foreign_curr, '2016-01-01')),
((-60.0, -60.0, comp_curr, '2017-01-01'), (40.0, 120.0, foreign_curr, '2016-01-01')),
):
line1 = self._create_line_for_reconciliation(*line1_vals)
line2 = self._create_line_for_reconciliation(*line2_vals)
line1 = self.create_line_for_reconciliation(*line1_vals)
line2 = self.create_line_for_reconciliation(*line2_vals)
with self.subTest(line1_vals=line1_vals, line2_vals=line2_vals):
(line1 + line2).reconcile()
@@ -368,13 +341,13 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon):
an additional move is added with the right foreign currency amount. """
currency = self.currency_data['currency']
line_1 = self._create_line_for_reconciliation(0.0, -0.02, currency, '2017-01-01')
line_2 = self._create_line_for_reconciliation(0.0, 0.01, currency, '2017-01-01')
line_1 = self.create_line_for_reconciliation(0.0, -0.02, currency, '2017-01-01')
line_2 = self.create_line_for_reconciliation(0.0, 0.01, currency, '2017-01-01')
(line_1 + line_2).reconcile()
self.assertFalse(line_1.full_reconcile_id + line_2.full_reconcile_id, "The reconciliation should not be considered full, as 0.01 still remain open in foreign currency.")
line_3 = self._create_line_for_reconciliation(0.0, 0.01, currency, '2017-01-01')
line_3 = self.create_line_for_reconciliation(0.0, 0.01, currency, '2017-01-01')
(line_1 + line_3).reconcile()
self.assertTrue(line_1.full_reconcile_id)
@@ -393,8 +366,8 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon):
'currency_subunit_label': 'Bretonnian Denier',
})['currency']
line_1 = self._create_line_for_reconciliation(0.0, -0.01, currency_1, '2017-01-01')
line_2 = self._create_line_for_reconciliation(0.0, 0.02, currency_2, '2016-01-01')
line_1 = self.create_line_for_reconciliation(0.0, -0.01, currency_1, '2017-01-01')
line_2 = self.create_line_for_reconciliation(0.0, 0.02, currency_2, '2016-01-01')
amls = line_1 + line_2
amls.reconcile()
@@ -412,8 +385,8 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon):
"""
currency = self.currency_data['currency']
line_1 = self._create_line_for_reconciliation(-0.01, 0.0, currency, '2017-01-01')
line_2 = self._create_line_for_reconciliation(0.02, 0.0, currency, '2016-01-01')
line_1 = self.create_line_for_reconciliation(-0.01, 0.0, currency, '2017-01-01')
line_2 = self.create_line_for_reconciliation(0.02, 0.0, currency, '2016-01-01')
amls = line_1 + line_2
amls.reconcile()
@@ -467,8 +440,8 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon):
comp_curr = self.company_data['currency']
foreign_curr = self.currency_data['currency']
line_1 = self._create_line_for_reconciliation(-0.01, -0.01, comp_curr, '2017-01-01')
line_2 = self._create_line_for_reconciliation(0.0, 0.03, foreign_curr, '2016-01-01')
line_1 = self.create_line_for_reconciliation(-0.01, -0.01, comp_curr, '2017-01-01')
line_2 = self.create_line_for_reconciliation(0.0, 0.03, foreign_curr, '2016-01-01')
amls = line_1 + line_2
amls.reconcile()
@@ -542,8 +515,8 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon):
foreign_curr1 = self.currency_data['currency']
foreign_curr2 = self.currency_data_2['currency']
line_1 = self._create_line_for_reconciliation(-0.01, 0.0, foreign_curr2, '2017-01-01')
line_2 = self._create_line_for_reconciliation(0.01, 0.03, foreign_curr1, '2016-01-01')
line_1 = self.create_line_for_reconciliation(-0.01, 0.0, foreign_curr2, '2017-01-01')
line_2 = self.create_line_for_reconciliation(0.01, 0.03, foreign_curr1, '2016-01-01')
amls = line_1 + line_2
amls.reconcile()
@@ -572,8 +545,8 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon):
"""
currency = self.currency_data['currency']
line_1 = self._create_line_for_reconciliation(-0.06, 0.0, currency, '2017-01-01')
line_2 = self._create_line_for_reconciliation(0.12, 0.24, currency, '2017-01-01')
line_1 = self.create_line_for_reconciliation(-0.06, 0.0, currency, '2017-01-01')
line_2 = self.create_line_for_reconciliation(0.12, 0.24, currency, '2017-01-01')
amls = line_1 + line_2
amls.reconcile()
@@ -596,8 +569,8 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon):
def test_reconcile_exchange_difference_on_partial_same_foreign_currency_debit_expense_partial_payment(self):
currency = self.currency_data['currency']
line_1 = self._create_line_for_reconciliation(60.0, 120.0, currency, '2017-01-01')
line_2 = self._create_line_for_reconciliation(-80.0, -240.0, currency, '2016-01-01')
line_1 = self.create_line_for_reconciliation(60.0, 120.0, currency, '2017-01-01')
line_2 = self.create_line_for_reconciliation(-80.0, -240.0, currency, '2016-01-01')
amls = line_1 + line_2
amls.reconcile()
@@ -644,8 +617,8 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon):
def test_reconcile_exchange_difference_on_partial_same_foreign_currency_debit_income_partial_payment(self):
currency = self.currency_data['currency']
line_1 = self._create_line_for_reconciliation(40.0, 120.0, currency, '2016-01-01')
line_2 = self._create_line_for_reconciliation(-120.0, -240.0, currency, '2017-01-01')
line_1 = self.create_line_for_reconciliation(40.0, 120.0, currency, '2016-01-01')
line_2 = self.create_line_for_reconciliation(-120.0, -240.0, currency, '2017-01-01')
amls = line_1 + line_2
amls.reconcile()
@@ -692,8 +665,8 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon):
def test_reconcile_exchange_difference_on_partial_same_foreign_currency_credit_expense_partial_payment(self):
currency = self.currency_data['currency']
line_1 = self._create_line_for_reconciliation(-40.0, -120.0, currency, '2016-01-01')
line_2 = self._create_line_for_reconciliation(120.0, 240.0, currency, '2017-01-01')
line_1 = self.create_line_for_reconciliation(-40.0, -120.0, currency, '2016-01-01')
line_2 = self.create_line_for_reconciliation(120.0, 240.0, currency, '2017-01-01')
amls = line_1 + line_2
amls.reconcile()
@@ -740,8 +713,8 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon):
def test_reconcile_exchange_difference_on_partial_same_foreign_currency_credit_income_partial_payment(self):
currency = self.currency_data['currency']
line_1 = self._create_line_for_reconciliation(-60.0, -120.0, currency, '2017-01-01')
line_2 = self._create_line_for_reconciliation(80.0, 240.0, currency, '2016-01-01')
line_1 = self.create_line_for_reconciliation(-60.0, -120.0, currency, '2017-01-01')
line_2 = self.create_line_for_reconciliation(80.0, 240.0, currency, '2016-01-01')
amls = line_1 + line_2
amls.reconcile()
@@ -789,8 +762,8 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon):
comp_curr = self.company_data['currency']
foreign_curr = self.currency_data['currency']
line_1 = self._create_line_for_reconciliation(60.0, 120.0, foreign_curr, '2017-01-01')
line_2 = self._create_line_for_reconciliation(-80.0, -80.0, comp_curr, '2016-01-01')
line_1 = self.create_line_for_reconciliation(60.0, 120.0, foreign_curr, '2017-01-01')
line_2 = self.create_line_for_reconciliation(-80.0, -80.0, comp_curr, '2016-01-01')
amls = line_1 + line_2
amls.reconcile()
@@ -838,8 +811,8 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon):
comp_curr = self.company_data['currency']
foreign_curr = self.currency_data['currency']
line_1 = self._create_line_for_reconciliation(60.0, 60.0, comp_curr, '2017-01-01')
line_2 = self._create_line_for_reconciliation(-80.0, -240.0, foreign_curr, '2016-01-01')
line_1 = self.create_line_for_reconciliation(60.0, 60.0, comp_curr, '2017-01-01')
line_2 = self.create_line_for_reconciliation(-80.0, -240.0, foreign_curr, '2016-01-01')
amls = line_1 + line_2
amls.reconcile()
@@ -887,8 +860,8 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon):
comp_curr = self.company_data['currency']
foreign_curr = self.currency_data['currency']
line_1 = self._create_line_for_reconciliation(40.0, 120.0, foreign_curr, '2016-01-01')
line_2 = self._create_line_for_reconciliation(-120.0, -120.0, comp_curr, '2017-01-01')
line_1 = self.create_line_for_reconciliation(40.0, 120.0, foreign_curr, '2016-01-01')
line_2 = self.create_line_for_reconciliation(-120.0, -120.0, comp_curr, '2017-01-01')
amls = line_1 + line_2
amls.reconcile()
@@ -936,8 +909,8 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon):
comp_curr = self.company_data['currency']
foreign_curr = self.currency_data['currency']
line_1 = self._create_line_for_reconciliation(40.0, 40.0, comp_curr, '2016-01-01')
line_2 = self._create_line_for_reconciliation(-120.0, -240.0, foreign_curr, '2017-01-01')
line_1 = self.create_line_for_reconciliation(40.0, 40.0, comp_curr, '2016-01-01')
line_2 = self.create_line_for_reconciliation(-120.0, -240.0, foreign_curr, '2017-01-01')
amls = line_1 + line_2
amls.reconcile()
@@ -985,8 +958,8 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon):
comp_curr = self.company_data['currency']
foreign_curr = self.currency_data['currency']
line_1 = self._create_line_for_reconciliation(-40.0, -120.0, foreign_curr, '2016-01-01')
line_2 = self._create_line_for_reconciliation(120.0, 120.0, comp_curr, '2017-01-01')
line_1 = self.create_line_for_reconciliation(-40.0, -120.0, foreign_curr, '2016-01-01')
line_2 = self.create_line_for_reconciliation(120.0, 120.0, comp_curr, '2017-01-01')
amls = line_1 + line_2
amls.reconcile()
@@ -1034,8 +1007,8 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon):
comp_curr = self.company_data['currency']
foreign_curr = self.currency_data['currency']
line_1 = self._create_line_for_reconciliation(-40.0, -40.0, comp_curr, '2016-01-01')
line_2 = self._create_line_for_reconciliation(120.0, 240.0, foreign_curr, '2017-01-01')
line_1 = self.create_line_for_reconciliation(-40.0, -40.0, comp_curr, '2016-01-01')
line_2 = self.create_line_for_reconciliation(120.0, 240.0, foreign_curr, '2017-01-01')
amls = line_1 + line_2
amls.reconcile()
@@ -1083,8 +1056,8 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon):
comp_curr = self.company_data['currency']
foreign_curr = self.currency_data['currency']
line_1 = self._create_line_for_reconciliation(-60.0, -60.0, comp_curr, '2017-01-01')
line_2 = self._create_line_for_reconciliation(80.0, 240.0, foreign_curr, '2016-01-01')
line_1 = self.create_line_for_reconciliation(-60.0, -60.0, comp_curr, '2017-01-01')
line_2 = self.create_line_for_reconciliation(80.0, 240.0, foreign_curr, '2016-01-01')
amls = line_1 + line_2
amls.reconcile()
@@ -1132,8 +1105,8 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon):
comp_curr = self.company_data['currency']
foreign_curr = self.currency_data['currency']
line_1 = self._create_line_for_reconciliation(-60.0, -120.0, foreign_curr, '2017-01-01')
line_2 = self._create_line_for_reconciliation(80.0, 80.0, comp_curr, '2016-01-01')
line_1 = self.create_line_for_reconciliation(-60.0, -120.0, foreign_curr, '2017-01-01')
line_2 = self.create_line_for_reconciliation(80.0, 80.0, comp_curr, '2016-01-01')
amls = line_1 + line_2
amls.reconcile()
@@ -1180,8 +1153,8 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon):
def test_reconcile_exchange_difference_on_partial_same_foreign_currency_debit_expense_full_payment(self):
currency = self.currency_data['currency']
line_1 = self._create_line_for_reconciliation(60.0, 120.0, currency, '2017-01-01')
line_2 = self._create_line_for_reconciliation(-40.0, -120.0, currency, '2016-01-01')
line_1 = self.create_line_for_reconciliation(60.0, 120.0, currency, '2017-01-01')
line_2 = self.create_line_for_reconciliation(-40.0, -120.0, currency, '2016-01-01')
amls = line_1 + line_2
amls.reconcile()
@@ -1231,8 +1204,8 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon):
def test_reconcile_exchange_difference_on_partial_same_foreign_currency_debit_income_full_payment(self):
currency = self.currency_data['currency']
line_1 = self._create_line_for_reconciliation(40.0, 120.0, currency, '2016-01-01')
line_2 = self._create_line_for_reconciliation(-60.0, -120.0, currency, '2017-01-01')
line_1 = self.create_line_for_reconciliation(40.0, 120.0, currency, '2016-01-01')
line_2 = self.create_line_for_reconciliation(-60.0, -120.0, currency, '2017-01-01')
amls = line_1 + line_2
amls.reconcile()
@@ -1282,8 +1255,8 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon):
def test_reconcile_exchange_difference_on_partial_same_foreign_currency_credit_expense_full_payment(self):
currency = self.currency_data['currency']
line_1 = self._create_line_for_reconciliation(-40.0, -120.0, currency, '2016-01-01')
line_2 = self._create_line_for_reconciliation(60.0, 120.0, currency, '2017-01-01')
line_1 = self.create_line_for_reconciliation(-40.0, -120.0, currency, '2016-01-01')
line_2 = self.create_line_for_reconciliation(60.0, 120.0, currency, '2017-01-01')
amls = line_1 + line_2
amls.reconcile()
@@ -1333,8 +1306,8 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon):
def test_reconcile_exchange_difference_on_partial_same_foreign_currency_credit_income_full_payment(self):
currency = self.currency_data['currency']
line_1 = self._create_line_for_reconciliation(-60.0, -120.0, currency, '2017-01-01')
line_2 = self._create_line_for_reconciliation(40.0, 120.0, currency, '2016-01-01')
line_1 = self.create_line_for_reconciliation(-60.0, -120.0, currency, '2017-01-01')
line_2 = self.create_line_for_reconciliation(40.0, 120.0, currency, '2016-01-01')
amls = line_1 + line_2
amls.reconcile()
@@ -1385,8 +1358,8 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon):
comp_curr = self.company_data['currency']
foreign_curr = self.currency_data['currency']
line_1 = self._create_line_for_reconciliation(60.0, 120.0, foreign_curr, '2017-01-01')
line_2 = self._create_line_for_reconciliation(-40.0, -40.0, comp_curr, '2016-01-01')
line_1 = self.create_line_for_reconciliation(60.0, 120.0, foreign_curr, '2017-01-01')
line_2 = self.create_line_for_reconciliation(-40.0, -40.0, comp_curr, '2016-01-01')
amls = line_1 + line_2
amls.reconcile()
@@ -1437,8 +1410,8 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon):
comp_curr = self.company_data['currency']
foreign_curr = self.currency_data['currency']
line_1 = self._create_line_for_reconciliation(60.0, 60.0, comp_curr, '2017-01-01')
line_2 = self._create_line_for_reconciliation(-40.0, -120.0, foreign_curr, '2016-01-01')
line_1 = self.create_line_for_reconciliation(60.0, 60.0, comp_curr, '2017-01-01')
line_2 = self.create_line_for_reconciliation(-40.0, -120.0, foreign_curr, '2016-01-01')
amls = line_1 + line_2
amls.reconcile()
@@ -1489,8 +1462,8 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon):
comp_curr = self.company_data['currency']
foreign_curr = self.currency_data['currency']
line_1 = self._create_line_for_reconciliation(40.0, 120.0, foreign_curr, '2016-01-01')
line_2 = self._create_line_for_reconciliation(-60.0, -60.0, comp_curr, '2017-01-01')
line_1 = self.create_line_for_reconciliation(40.0, 120.0, foreign_curr, '2016-01-01')
line_2 = self.create_line_for_reconciliation(-60.0, -60.0, comp_curr, '2017-01-01')
amls = line_1 + line_2
amls.reconcile()
@@ -1541,8 +1514,8 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon):
comp_curr = self.company_data['currency']
foreign_curr = self.currency_data['currency']
line_1 = self._create_line_for_reconciliation(40.0, 40.0, comp_curr, '2016-01-01')
line_2 = self._create_line_for_reconciliation(-60.0, -120.0, foreign_curr, '2017-01-01')
line_1 = self.create_line_for_reconciliation(40.0, 40.0, comp_curr, '2016-01-01')
line_2 = self.create_line_for_reconciliation(-60.0, -120.0, foreign_curr, '2017-01-01')
amls = line_1 + line_2
amls.reconcile()
@@ -1593,8 +1566,8 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon):
comp_curr = self.company_data['currency']
foreign_curr = self.currency_data['currency']
line_1 = self._create_line_for_reconciliation(-40.0, -40.0, comp_curr, '2016-01-01')
line_2 = self._create_line_for_reconciliation(60.0, 120.0, foreign_curr, '2017-01-01')
line_1 = self.create_line_for_reconciliation(-40.0, -40.0, comp_curr, '2016-01-01')
line_2 = self.create_line_for_reconciliation(60.0, 120.0, foreign_curr, '2017-01-01')
amls = line_1 + line_2
amls.reconcile()
@@ -1645,8 +1618,8 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon):
comp_curr = self.company_data['currency']
foreign_curr = self.currency_data['currency']
line_1 = self._create_line_for_reconciliation(-40.0, -120.0, foreign_curr, '2016-01-01')
line_2 = self._create_line_for_reconciliation(60.0, 60.0, comp_curr, '2017-01-01')
line_1 = self.create_line_for_reconciliation(-40.0, -120.0, foreign_curr, '2016-01-01')
line_2 = self.create_line_for_reconciliation(60.0, 60.0, comp_curr, '2017-01-01')
amls = line_1 + line_2
amls.reconcile()
@@ -1697,8 +1670,8 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon):
comp_curr = self.company_data['currency']
foreign_curr = self.currency_data['currency']
line_1 = self._create_line_for_reconciliation(-60.0, -60.0, comp_curr, '2017-01-01')
line_2 = self._create_line_for_reconciliation(40.0, 120.0, foreign_curr, '2016-01-01')
line_1 = self.create_line_for_reconciliation(-60.0, -60.0, comp_curr, '2017-01-01')
line_2 = self.create_line_for_reconciliation(40.0, 120.0, foreign_curr, '2016-01-01')
amls = line_1 + line_2
amls.reconcile()
@@ -1749,8 +1722,8 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon):
comp_curr = self.company_data['currency']
foreign_curr = self.currency_data['currency']
line_1 = self._create_line_for_reconciliation(-60.0, -120.0, foreign_curr, '2017-01-01')
line_2 = self._create_line_for_reconciliation(40.0, 40.0, comp_curr, '2016-01-01')
line_1 = self.create_line_for_reconciliation(-60.0, -120.0, foreign_curr, '2017-01-01')
line_2 = self.create_line_for_reconciliation(40.0, 40.0, comp_curr, '2016-01-01')
amls = line_1 + line_2
amls.reconcile()
@@ -2459,8 +2432,8 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon):
def test_migration_to_new_reconciliation_same_foreign_currency(self):
foreign_curr = self.currency_data['currency']
line_1 = self._create_line_for_reconciliation(-60.0, -120.0, foreign_curr, '2017-01-01')
line_2 = self._create_line_for_reconciliation(80.0, 240.0, foreign_curr, '2016-01-01')
line_1 = self.create_line_for_reconciliation(-60.0, -120.0, foreign_curr, '2017-01-01')
line_2 = self.create_line_for_reconciliation(80.0, 240.0, foreign_curr, '2016-01-01')
# Create the partial as it should be created in previous version.
self.env['account.partial.reconcile'].create({
@@ -2476,14 +2449,14 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon):
])
# Reconcile using the "new" reconciliation.
line_3 = self._create_line_for_reconciliation(-15.0, -30.0, foreign_curr, '2017-01-01')
line_3 = self.create_line_for_reconciliation(-15.0, -30.0, foreign_curr, '2017-01-01')
(line_2 + line_3).reconcile()
self.assertRecordValues(line_2 + line_3, [
{'amount_residual': 10.0, 'amount_residual_currency': 90.0, 'reconciled': False},
{'amount_residual': 0.0, 'amount_residual_currency': 0.0, 'reconciled': True},
])
line_4 = self._create_line_for_reconciliation(-30.0, -90.0, foreign_curr, '2016-01-01')
line_4 = self.create_line_for_reconciliation(-30.0, -90.0, foreign_curr, '2016-01-01')
(line_2 + line_4).reconcile()
self.assertRecordValues(line_2 + line_4, [
{'amount_residual': 0.0, 'amount_residual_currency': 0.0, 'reconciled': True},
@@ -2494,9 +2467,9 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon):
comp_curr = self.company_data['currency']
foreign_curr1 = self.currency_data['currency']
line_1 = self._create_line_for_reconciliation(600.0, 1200.0, foreign_curr1, '2017-01-01')
line_2 = self._create_line_for_reconciliation(-800.0, -2400.0, foreign_curr1, '2016-01-01')
line_3 = self._create_line_for_reconciliation(400.0, 400.0, comp_curr, '2016-01-01')
line_1 = self.create_line_for_reconciliation(600.0, 1200.0, foreign_curr1, '2017-01-01')
line_2 = self.create_line_for_reconciliation(-800.0, -2400.0, foreign_curr1, '2016-01-01')
line_3 = self.create_line_for_reconciliation(400.0, 400.0, comp_curr, '2016-01-01')
# Create the partials as it should be created in previous version.
self.env['account.partial.reconcile'].create([
@@ -2522,8 +2495,8 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon):
])
# Fix 'line_2' & 'line_4' using the "new" reconciliation.
line_4 = self._create_line_for_reconciliation(0.0, 600.0, foreign_curr1, '2016-01-01')
line_5 = self._create_line_for_reconciliation(-200.0, -200.0, comp_curr, '2016-01-01')
line_4 = self.create_line_for_reconciliation(0.0, 600.0, foreign_curr1, '2016-01-01')
line_5 = self.create_line_for_reconciliation(-200.0, -200.0, comp_curr, '2016-01-01')
(line_2 + line_3 + line_4 + line_5).reconcile()
self.assertRecordValues(line_1 + line_2 + line_3 + line_4 + line_5, [
@@ -2576,11 +2549,11 @@ class TestAccountMoveReconcile(AccountTestInvoicingCommon):
comp_curr = self.company_data['currency']
line_1 = self._create_line_for_reconciliation(600.0, 600.0, comp_curr, '2017-01-01')
line_2 = self._create_line_for_reconciliation(-100.0, -100.0, comp_curr, '2017-01-02')
line_3 = self._create_line_for_reconciliation(700.0, 700.0, comp_curr, '2017-01-03')
line_5 = self._create_line_for_reconciliation(-700.0, -700.0, comp_curr, '2017-01-04')
line_4 = self._create_line_for_reconciliation(-500.0, -500.0, comp_curr, '2017-01-05')
line_1 = self.create_line_for_reconciliation(600.0, 600.0, comp_curr, '2017-01-01')
line_2 = self.create_line_for_reconciliation(-100.0, -100.0, comp_curr, '2017-01-02')
line_3 = self.create_line_for_reconciliation(700.0, 700.0, comp_curr, '2017-01-03')
line_5 = self.create_line_for_reconciliation(-700.0, -700.0, comp_curr, '2017-01-04')
line_4 = self.create_line_for_reconciliation(-500.0, -500.0, comp_curr, '2017-01-05')
with rollback():
# 5 batches of 1 aml. This won't reconcile anything.
+4 -8
View File
@@ -195,9 +195,8 @@ class TestTransferWizard(AccountTestInvoicingCommon):
active_move_lines = (self.move_1 + self.move_2).mapped('line_ids').filtered(lambda x: x.account_id.account_type in ('asset_receivable', 'liability_payable'))
# We use a form to pass the context properly to the depends_context move_line_ids field
context = {'active_model': 'account.move.line', 'active_ids': active_move_lines.ids}
context = {'active_model': 'account.move.line', 'active_ids': active_move_lines.ids, 'default_action': 'change_account'}
with Form(self.env['account.automatic.entry.wizard'].with_context(context)) as wizard_form:
wizard_form.action = 'change_account'
wizard_form.destination_account_id = self.receivable_account
wizard_form.journal_id = self.journal
wizard = wizard_form.save()
@@ -221,9 +220,8 @@ class TestTransferWizard(AccountTestInvoicingCommon):
active_move_lines = (self.move_1 + self.move_2).mapped('line_ids').filtered(lambda x: x.name in ('test1_3', 'test1_4', 'test1_5', 'test2_3', 'test2_4', 'test2_5', 'test2_6', 'test2_8'))
# We use a form to pass the context properly to the depends_context move_line_ids field
context = {'active_model': 'account.move.line', 'active_ids': active_move_lines.ids}
context = {'active_model': 'account.move.line', 'active_ids': active_move_lines.ids, 'default_action': 'change_account'}
with Form(self.env['account.automatic.entry.wizard'].with_context(context)) as wizard_form:
wizard_form.action = 'change_account'
wizard_form.destination_account_id = self.accounts[4]
wizard_form.journal_id = self.journal
wizard = wizard_form.save()
@@ -252,9 +250,8 @@ class TestTransferWizard(AccountTestInvoicingCommon):
active_move_lines = self.move_1.mapped('line_ids').filtered(lambda x: x.name in ('test1_6', 'test1_9'))
# We use a form to pass the context properly to the depends_context move_line_ids field
context = {'active_model': 'account.move.line', 'active_ids': active_move_lines.ids}
context = {'active_model': 'account.move.line', 'active_ids': active_move_lines.ids, 'default_action': 'change_account'}
with Form(self.env['account.automatic.entry.wizard'].with_context(context)) as wizard_form:
wizard_form.action = 'change_account'
wizard_form.destination_account_id = self.test_currency_account
wizard_form.journal_id = self.journal
wizard = wizard_form.save()
@@ -275,9 +272,8 @@ class TestTransferWizard(AccountTestInvoicingCommon):
active_move_lines = self.move_2.mapped('line_ids').filtered(lambda x: x.name in ('test2_9', 'test2_6', 'test2_8'))
# We use a form to pass the context properly to the depends_context move_line_ids field
context = {'active_model': 'account.move.line', 'active_ids': active_move_lines.ids}
context = {'active_model': 'account.move.line', 'active_ids': active_move_lines.ids, 'default_action': 'change_account'}
with Form(self.env['account.automatic.entry.wizard'].with_context(context)) as wizard_form:
wizard_form.action = 'change_account'
wizard_form.destination_account_id = self.receivable_account
wizard_form.journal_id = self.journal
wizard = wizard_form.save()
+13 -4
View File
@@ -1152,7 +1152,7 @@
aria-label="Change Period"
class="float-end"
attrs="{'invisible': [('account_internal_group', 'not in', ('income', 'expense'))], 'column_invisible': ['|', ('parent.move_type', '=', 'entry'), ('parent.state', '!=', 'posted')]}"
context="{'hide_automatic_options': 1, 'default_action': 'change_period'}"/>
context="{'default_action': 'change_period'}"/>
<!-- Others fields -->
<field name="tax_line_id" invisible="1"/>
@@ -1368,13 +1368,22 @@
<field name="context">{'search_default_account_id': [active_id], 'search_default_posted': 1}</field>
</record>
<record id="action_automatic_entry" model="ir.actions.server">
<field name="name">Automatic Entries</field>
<record id="action_automatic_entry_change_account" model="ir.actions.server">
<field name="name">Move to Account</field>
<field name="model_id" ref="account.model_account_move_line"/>
<field name="groups_id" eval="[(4, ref('account.group_account_user'))]"/>
<field name="binding_model_id" ref="account.model_account_move_line"/>
<field name="state">code</field>
<field name="code">action = records.action_automatic_entry()</field>
<field name="code">action = records.action_automatic_entry('change_account')</field>
</record>
<record id="action_automatic_entry_change_period" model="ir.actions.server">
<field name="name">Change Period</field>
<field name="model_id" ref="account.model_account_move_line"/>
<field name="groups_id" eval="[(4, ref('account.group_account_user'))]"/>
<field name="binding_model_id" ref="account.model_account_move_line"/>
<field name="state">code</field>
<field name="code">action = records.action_automatic_entry('change_period')</field>
</record>
<record id="action_account_moves_all_a" model="ir.actions.act_window">
@@ -10,11 +10,11 @@
<field name="company_id" invisible="1"/>
<field name="move_line_ids" invisible="1"/>
<field name="display_currency_helper" invisible="1"/>
<field name="action" invisible="1"/>
<div attrs="{'invisible': [('display_currency_helper', '=', False)]}" class="alert alert-info text-center" role="status">
The selected destination account is set to use a specific currency. Every entry transferred to it will be converted into this currency, causing
the loss of any pre-existing foreign currency amount.
</div>
<field name="action" invisible="context.get('hide_automatic_options')" widget="radio" options="{'horizontal': true}"/>
<group>
<group attrs="{'invisible': [('action', '!=', 'change_period')]}">
<field name="date" string="Recognition Date"/>
@@ -47,7 +47,7 @@
</record>
<record id="account_automatic_entry_wizard_action" model="ir.actions.act_window">
<field name="name">Create Automatic Entries for selected Journal Items</field>
<field name="name">Transfer Journal Items</field>
<field name="res_model">account.automatic.entry.wizard</field>
<field name="view_mode">form</field>
<field name="target">new</field>