diff options
| author | wan <wan@odoo.com> | 2020-01-06 15:38:58 +0000 |
|---|---|---|
| committer | wan <wan@odoo.com> | 2020-03-03 15:28:02 +0000 |
| commit | ae8115e6c8870e87ae8de99e47486dd77fdb6f6c (patch) | |
| tree | 97e8c34cafda06026c27ae1d928bd002bc8b84ff /addons/account/wizard | |
| parent | 70a79da8a06a3096ea82da6c0d7b26b73811a1c6 (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')
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> |
