summaryrefslogtreecommitdiff
path: root/addons/account/wizard
diff options
context:
space:
mode:
authorwan <wan@odoo.com>2020-01-06 15:38:58 +0000
committerwan <wan@odoo.com>2020-03-03 15:28:02 +0000
commitae8115e6c8870e87ae8de99e47486dd77fdb6f6c (patch)
tree97e8c34cafda06026c27ae1d928bd002bc8b84ff /addons/account/wizard
parent70a79da8a06a3096ea82da6c0d7b26b73811a1c6 (diff)
[IMP] account: preview in accrual wizard
Task 2168064 Show a preview of what will be done when using the accrual wizard
Diffstat (limited to 'addons/account/wizard')
-rw-r--r--addons/account/wizard/account_accrual_accounting.py247
-rw-r--r--addons/account/wizard/account_accrual_accounting_view.xml6
-rw-r--r--addons/account/wizard/account_transfer_wizard.py45
-rw-r--r--addons/account/wizard/account_transfer_wizard.xml4
4 files changed, 179 insertions, 123 deletions
diff --git a/addons/account/wizard/account_accrual_accounting.py b/addons/account/wizard/account_accrual_accounting.py
index 84cde15d05d..98058bbd035 100644
--- a/addons/account/wizard/account_accrual_accounting.py
+++ b/addons/account/wizard/account_accrual_accounting.py
@@ -1,11 +1,13 @@
# -*- coding: utf-8 -*-
from odoo import api, fields, models, _
from odoo.exceptions import UserError
+from odoo.tools.misc import format_date
+import json
class AccrualAccountingWizard(models.TransientModel):
_name = 'account.accrual.accounting.wizard'
- _description = 'Create accrual entry.'
+ _description = 'Create accrual entries.'
date = fields.Date(required=True)
company_id = fields.Many2one('res.company', required=True, readonly=True)
@@ -23,6 +25,8 @@ class AccrualAccountingWizard(models.TransientModel):
percentage = fields.Float("Percentage", default=100.0)
total_amount = fields.Monetary(compute="_compute_total_amount", currency_field='company_currency_id')
company_currency_id = fields.Many2one('res.currency', related='company_id.currency_id')
+ data = fields.Text(compute="_compute_data")
+ preview_data = fields.Text(compute="_compute_preview_data")
@api.constrains('percentage')
def _constraint_percentage(self):
@@ -54,112 +58,163 @@ class AccrualAccountingWizard(models.TransientModel):
rec['company_id'] = active_move_line_ids[0].company_id.id
account_types_allowed = self.env.ref('account.data_account_type_expenses') + self.env.ref('account.data_account_type_revenue') + self.env.ref('account.data_account_type_other_income')
if active_move_line_ids[0].account_id.user_type_id not in account_types_allowed:
- raise UserError(_('You can only change the period for items in these types of accounts: ') + ", ".join(account_types_allowed.mapped('name')))
+ raise UserError(_('You can only change the period for items in these types of accounts: %s') % ", ".join(account_types_allowed.mapped('name')))
rec['account_type'] = active_move_line_ids[0].account_id.user_type_id.internal_group
return rec
- def amend_entries(self):
- # set the accrual account on the selected journal items
- accrual_account = self.revenue_accrual_account if self.account_type == 'income' else self.expense_accrual_account
-
- # Generate journal entries.
- move_data = {}
- for aml in self.active_move_line_ids:
- ref1 = _('Accrual Adjusting Entry (%s recognized) for invoice: %s') % (self.percentage, aml.move_id.name)
- ref2 = _('Accrual Adjusting Entry (%s recognized) for invoice: %s') % (100 - self.percentage, aml.move_id.name)
- move_data.setdefault(aml.move_id, (
- [
- # Values to create moves.
- {
- 'date': self.date,
- 'ref': ref1,
- 'journal_id': self.journal_id.id,
- 'line_ids': [],
- },
- {
- 'date': aml.move_id.date,
- 'ref': ref2,
- 'journal_id': self.journal_id.id,
- 'line_ids': [],
- },
- ], [
- # Messages to log on the chatter.
- (_('Accrual Adjusting Entry ({percent}% recognized) for invoice:') + ' <a href=# data-oe-model=account.move data-oe-id={id}>{name}</a>').format(
- percent=self.percentage,
- id=aml.move_id.id,
- name=aml.move_id.name,
- ),
- (_('Accrual Adjusting Entry ({percent}% recognized) for invoice:') + ' <a href=# data-oe-model=account.move data-oe-id={id}>{name}</a>').format(
- percent=100 - self.percentage,
- id=aml.move_id.id,
- name=aml.move_id.name,
- ),
+ @api.depends('active_move_line_ids', 'journal_id', 'revenue_accrual_account', 'expense_accrual_account', 'percentage', 'date', 'account_type')
+ def _compute_data(self):
+ for record in self:
+ # set the accrual account on the selected journal items
+ accrual_account = record.revenue_accrual_account if record.account_type == 'income' else record.expense_accrual_account
+
+ move_data = {}
+
+ # compute the account.move.lines and the total amount per move
+ for aml in record.active_move_line_ids:
+ if aml.move_id not in move_data:
+ move_data[aml.move_id] = {
+ 'total_amount': 0,
+ 'move_vals': {
+ 'new_date': {'line_ids': []},
+ 'original_date': {'line_ids': []},
+ }
+ }
+ # total amount per move is used to build the account.move references and chatter messages
+ move_data[aml.move_id]['total_amount'] += aml.balance
+
+ # account.move.line data
+ reported_debit = aml.company_id.currency_id.round((record.percentage / 100) * aml.debit)
+ reported_credit = aml.company_id.currency_id.round((record.percentage / 100) * aml.credit)
+ if aml.currency_id:
+ reported_amount_currency = aml.currency_id.round((record.percentage / 100) * aml.amount_currency)
+ else:
+ reported_amount_currency = 0.0
+
+ move_data[aml.move_id]['move_vals']['new_date']['line_ids'] += [
+ (0, 0, {
+ 'name': aml.name,
+ 'debit': reported_debit,
+ 'credit': reported_credit,
+ 'amount_currency': reported_amount_currency,
+ 'currency_id': aml.currency_id.id,
+ 'account_id': aml.account_id.id,
+ 'partner_id': aml.partner_id.id,
+ }),
+ (0, 0, {
+ 'name': _('Accrual Adjusting Entry'),
+ 'debit': reported_credit,
+ 'credit': reported_debit,
+ 'amount_currency': -reported_amount_currency,
+ 'currency_id': aml.currency_id.id,
+ 'account_id': accrual_account.id,
+ 'partner_id': aml.partner_id.id,
+ }),
+ ]
+ move_data[aml.move_id]['move_vals']['original_date']['line_ids'] += [
+ (0, 0, {
+ 'name': aml.name,
+ 'debit': aml.debit - reported_debit,
+ 'credit': aml.credit - reported_credit,
+ 'amount_currency': aml.amount_currency - reported_amount_currency,
+ 'currency_id': aml.currency_id.id,
+ 'account_id': aml.account_id.id,
+ 'partner_id': aml.partner_id.id,
+ }),
+ (0, 0, {
+ 'name': _('Accrual Adjusting Entry'),
+ 'debit': aml.credit - reported_credit,
+ 'credit': aml.debit - reported_debit,
+ 'amount_currency': reported_amount_currency - aml.amount_currency,
+ 'currency_id': aml.currency_id.id,
+ 'account_id': accrual_account.id,
+ 'partner_id': aml.partner_id.id,
+ }),
]
- ))
- reported_debit = aml.company_id.currency_id.round((self.percentage / 100) * aml.debit)
- reported_credit = aml.company_id.currency_id.round((self.percentage / 100) * aml.credit)
- if aml.currency_id:
- reported_amount_currency = aml.currency_id.round((self.percentage / 100) * aml.amount_currency)
- else:
- reported_amount_currency = 0.0
-
- move_data[aml.move_id][0][0]['line_ids'] += [
- (0, 0, {
- 'name': aml.name,
- 'debit': reported_debit,
- 'credit': reported_credit,
- 'amount_currency': reported_amount_currency,
- 'currency_id': aml.currency_id.id,
- 'account_id': aml.account_id.id,
- 'partner_id': aml.partner_id.id,
- }),
- (0, 0, {
- 'name': ref1,
- 'debit': reported_credit,
- 'credit': reported_debit,
- 'amount_currency': -reported_amount_currency,
- 'currency_id': aml.currency_id.id,
- 'account_id': accrual_account.id,
- 'partner_id': aml.partner_id.id,
- }),
+ # complete the account.move data
+ for move in record.active_move_line_ids.move_id:
+ def format_strings(string):
+ return string.format(
+ percent=record.percentage,
+ name=move.name,
+ id=move.id,
+ origin_amount=origin_amount,
+ date=format_date(self.env, move.date),
+ new_date=record.date and format_date(self.env, record.date) or _('[Not set]'),
+ )
+ origin_amount = abs(move_data[move]['total_amount'])
+ ref1 = format_strings(_('Adjusting Entry of {name} ({percent}% of {origin_amount} recognized from {date})'))
+ ref2 = format_strings(_('Adjusting Entry of {name} ({percent}% of {origin_amount} recognized on {new_date})'))
+ move_data[move]['move_vals']['new_date']['ref'] = ref1
+ move_data[move]['move_vals']['new_date']['date'] = fields.Date.to_string(record.date)
+ move_data[move]['move_vals']['new_date']['journal_id'] = record.journal_id.id
+ move_data[move]['move_vals']['original_date']['ref'] = ref2
+ move_data[move]['move_vals']['original_date']['date'] = fields.Date.to_string(move.date)
+ move_data[move]['move_vals']['original_date']['journal_id'] = record.journal_id.id
+ move_data[move]['log_messages'] = {
+ 'new_date': format_strings(
+ _('Accrual Adjusting Entry')
+ + ' <a href=# data-oe-model=account.move data-oe-id={id}>{name}</a>: '
+ + _('{percent}% of {origin_amount} recognized from {date}')
+ ),
+ 'original_date': format_strings(
+ _('Accrual Adjusting Entry for')
+ + ' <a href=# data-oe-model=account.move data-oe-id={id}>{name}</a>: '
+ + _('{percent}% of {origin_amount} recognized on {date}')
+ ),
+ 'origin': format_strings(
+ _('Accrual Adjusting Entries have been created for this invoice')
+ + ':<ul><li><a href=# data-oe-model=account.move data-oe-id=%(second_id)d>%(second_name)s</a> '
+ + _('cancelling {percent}%% of {origin_amount} ')
+ + '</li><li><a href=# data-oe-model=account.move data-oe-id=%(first_id)d>%(first_name)s</a> '
+ + _('postponing it to {date}')
+ + '</li></ul>'
+ )
+ }
+
+ move_vals = [m for o in move_data.values() for m in o['move_vals'].values()]
+ log_messages = [m for o in move_data.values() for m in o['log_messages'].values()]
+
+ record.data = json.dumps({
+ 'move_vals': move_vals,
+ 'log_messages': log_messages,
+ })
+
+ @api.depends('data')
+ def _compute_preview_data(self):
+ for record in self:
+ data = json.loads(record.data)
+ move_vals, log_messages = (data['move_vals'], data['log_messages'])
+
+ preview_vals = []
+ for move in move_vals[:4]:
+ preview_vals += [self.env['account.move']._move_dict_to_preview_vals(move, record.company_id.currency_id)]
+
+ preview_discarded = max(0, len(move_vals) - len(preview_vals))
+ preview_columns = [
+ {'field': 'account_id', 'label': _('Account')},
+ {'field': 'name', 'label': _('Label')},
+ {'field': 'debit', 'label': _('Debit'), 'class': 'text-right text-nowrap'},
+ {'field': 'credit', 'label': _('Credit'), 'class': 'text-right text-nowrap'},
]
- move_data[aml.move_id][0][1]['line_ids'] += [
- (0, 0, {
- 'name': aml.name,
- 'debit': aml.debit - reported_debit,
- 'credit': aml.credit - reported_credit,
- 'amount_currency': aml.amount_currency - reported_amount_currency,
- 'currency_id': aml.currency_id.id,
- 'account_id': aml.account_id.id,
- 'partner_id': aml.partner_id.id,
- }),
- (0, 0, {
- 'name': ref2,
- 'debit': aml.credit - reported_credit,
- 'credit': aml.debit - reported_debit,
- 'amount_currency': reported_amount_currency - aml.amount_currency,
- 'currency_id': aml.currency_id.id,
- 'account_id': accrual_account.id,
- 'partner_id': aml.partner_id.id,
- }),
- ]
+ record.preview_data = json.dumps({
+ 'groups_vals': preview_vals,
+ 'options': {
+ 'discarded_number': (_("%d moves") % preview_discarded) if preview_discarded else False,
+ 'columns': preview_columns,
+ },
+ })
+
+ def amend_entries(self):
+ accrual_account = self.revenue_accrual_account if self.account_type == 'income' else self.expense_accrual_account
+ data = json.loads(self.data)
+ move_vals, log_messages = (data['move_vals'], data['log_messages'])
# Update the account of selected journal items.
self.active_move_line_ids.write({'account_id': accrual_account.id})
- # When the percentage is 100%, the second move is not needed.
- if self.percentage < 100:
- move_vals = []
- log_messages = []
- for v in move_data.values():
- move_vals += v[0]
- log_messages += v[1]
- else:
- move_vals = [v[0][0] for k, v in move_data.items()]
- log_messages = [v[1][0] for k, v in move_data.items()]
-
created_moves = self.env['account.move'].create(move_vals)
created_moves.post()
diff --git a/addons/account/wizard/account_accrual_accounting_view.xml b/addons/account/wizard/account_accrual_accounting_view.xml
index c8684aa67a7..98b88d94530 100644
--- a/addons/account/wizard/account_accrual_accounting_view.xml
+++ b/addons/account/wizard/account_accrual_accounting_view.xml
@@ -22,8 +22,10 @@
<field name="journal_id"/>
</group>
</group>
+ <label for="preview_data" string="The following Journal Entries will be generated"/>
+ <field name="preview_data" widget="grouped_view_widget"/>
<footer>
- <button string="Create Journal Entry" name="amend_entries" type="object" class="oe_highlight"/>
+ <button string="Create Journal Entries" name="amend_entries" type="object" class="oe_highlight"/>
<button string="Cancel" class="btn btn-secondary" special="cancel"/>
</footer>
</form>
@@ -31,7 +33,7 @@
</record>
<record id="account_accrual_accounting_wizard_action" model="ir.actions.act_window">
- <field name="name">Create Accrual Entry for the expense/revenue recognition</field>
+ <field name="name">Create Accrual Entries for the expense/revenue recognition</field>
<field name="res_model">account.accrual.accounting.wizard</field>
<field name="view_mode">form</field>
<field name="target">new</field>
diff --git a/addons/account/wizard/account_transfer_wizard.py b/addons/account/wizard/account_transfer_wizard.py
index e771cd0342a..c6d73973abf 100644
--- a/addons/account/wizard/account_transfer_wizard.py
+++ b/addons/account/wizard/account_transfer_wizard.py
@@ -2,6 +2,7 @@
from odoo import api, fields, models, _
from odoo.exceptions import UserError
+from odoo.tools.misc import format_date, formatLang
from collections import defaultdict
@@ -43,9 +44,20 @@ class AccountTransferWizard(models.TransientModel):
@api.depends('destination_account_id')
def _compute_aml_preview_data(self):
for record in self:
- record.aml_preview_data = json.dumps(self._get_lines_to_create_dict())
-
- def _get_lines_to_create_dict(self):
+ record.aml_preview_data = json.dumps({
+ 'groups_vals': [self.env['account.move']._move_dict_to_preview_vals(self._get_move_to_create_dict(), record.company_id.currency_id)],
+ 'options': {
+ 'columns': [
+ {'field': 'account_id', 'label': _('Account')},
+ {'field': 'name', 'label': _('Label')},
+ {'field': 'partner_id', 'label': _('Partner')},
+ {'field': 'debit', 'label': _('Debit'), 'class': 'text-right text-nowrap'},
+ {'field': 'credit', 'label': _('Credit'), 'class': 'text-right text-nowrap'},
+ ],
+ },
+ })
+
+ def _get_move_to_create_dict(self):
line_vals = []
# Group data from selected move lines
@@ -77,9 +89,7 @@ class AccountTransferWizard(models.TransientModel):
'debit': counterpart_vals['balance'] > 0 and self.company_id.currency_id.round(counterpart_vals['balance']) or 0,
'credit': counterpart_vals['balance'] < 0 and self.company_id.currency_id.round(-counterpart_vals['balance']) or 0,
'account_id': self.destination_account_id.id,
- 'preview-account': self.destination_account_id and self.destination_account_id.name_get()[0][1] or _('Destination Account'),
'partner_id': counterpart_partner.id or None,
- 'preview-partner': counterpart_partner and counterpart_partner.name or None,
'amount_currency': counterpart_currency and counterpart_currency.round((counterpart_vals['balance'] < 0 and -1 or 1) * abs(counterpart_vals['amount_currency'])) or 0,
'currency_id': counterpart_currency.id or None,
})
@@ -94,31 +104,20 @@ class AccountTransferWizard(models.TransientModel):
'debit': account_balance < 0 and self.company_id.currency_id.round(-account_balance) or 0,
'credit': account_balance > 0 and self.company_id.currency_id.round(account_balance) or 0,
'account_id': account.id,
- 'preview-account': account.name_get()[0][1],
'partner_id': partner.id or None,
- 'preview-partner': partner and partner.name or None,
'currency_id': currency.id or None,
'amount_currency': (account_balance > 0 and -1 or 1) * abs(account_amount_currency),
})
- return line_vals
-
- def button_transfer(self):
- all_lines_dict = self._get_lines_to_create_dict()
-
- orm_line_commands = []
- for line_dict in all_lines_dict:
- del line_dict['preview-account']
- del line_dict['preview-partner']
- orm_line_commands.append((0, 0, line_dict))
-
- new_move = self.env['account.move'].create({
+ return {
'journal_id': self.journal_id.id,
'date': self.date,
- 'ref': _("Transfer entry to %s") % self.destination_account_id.display_name,
- 'line_ids': orm_line_commands,
- })
+ 'ref': self.destination_account_id.display_name and _("Transfer entry to %s") % self.destination_account_id.display_name or '',
+ 'line_ids': [(0, 0, line) for line in line_vals],
+ }
+ def button_transfer(self):
+ new_move = self.env['account.move'].create(self._get_move_to_create_dict())
new_move.post()
# Group lines
@@ -193,4 +192,4 @@ class AccountTransferWizard(models.TransientModel):
def _format_move_link(self, move):
move_link_format = "<a href=# data-oe-model=account.move data-oe-id=%(move_id)s>%(move_name)s</a>"
- return move_link_format % {'move_id': move.id, 'move_name': move.name} \ No newline at end of file
+ return move_link_format % {'move_id': move.id, 'move_name': move.name}
diff --git a/addons/account/wizard/account_transfer_wizard.xml b/addons/account/wizard/account_transfer_wizard.xml
index 965e737f750..052bf8cdc9b 100644
--- a/addons/account/wizard/account_transfer_wizard.xml
+++ b/addons/account/wizard/account_transfer_wizard.xml
@@ -27,7 +27,7 @@
<p><strong>The following journal entry will be generated</strong></p>
- <field name="aml_preview_data" widget="aml_preview"/>
+ <field name="aml_preview_data" widget="grouped_view_widget"/>
<footer>
<button string="Transfer Entries" name="button_transfer" type="object" class="oe_highlight"/>
@@ -38,4 +38,4 @@
</record>
</data>
-</odoo> \ No newline at end of file
+</odoo>