From c563013f3f721b882a8fd927d62decd1065c54fe Mon Sep 17 00:00:00 2001 From: Pierre Rousseau <pro@odoo.com> Date: Tue, 14 Nov 2017 09:14:32 +0100 Subject: [PATCH] [IMP] account: Automatic reverse entry at specific date Added options to reverse entries automatically based on a cron job. Was PR #18626. Was task 35012. --- addons/account/__manifest__.py | 1 + addons/account/data/service_cron_reverse.xml | 13 ++++++++ addons/account/models/account_move.py | 34 +++++++++++++++++--- addons/account/views/account_view.xml | 14 ++++++++ 4 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 addons/account/data/service_cron_reverse.xml diff --git a/addons/account/__manifest__.py b/addons/account/__manifest__.py index 3024b1702f57..8ead6af89619 100644 --- a/addons/account/__manifest__.py +++ b/addons/account/__manifest__.py @@ -65,6 +65,7 @@ Core mechanisms for the accounting modules. To display the menuitems, install th 'views/account_dashboard_setup_bar.xml', 'wizard/account_report_tax_view.xml', 'views/report_tax.xml', + 'data/service_cron_reverse.xml', ], 'demo': [ 'demo/account_demo.xml', diff --git a/addons/account/data/service_cron_reverse.xml b/addons/account/data/service_cron_reverse.xml new file mode 100644 index 000000000000..982abbeea1f6 --- /dev/null +++ b/addons/account/data/service_cron_reverse.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?> +<odoo> + <record id="ir_cron_reverse_entry" model="ir.cron"> + <field name="name">Account; Reverse entries</field> + <field name="interval_number">1</field> + <field name="interval_type">days</field> + <field name="numbercall">-1</field> + <field name="doall" eval="False"/> + <field name="model_id" ref="model_account_move"/> + <field name="code">model._run_reverses_entries()</field> + <field name="state">code</field> + </record> +</odoo> diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py index 3fe029f62be4..df44362cb7f9 100644 --- a/addons/account/models/account_move.py +++ b/addons/account/models/account_move.py @@ -112,6 +112,9 @@ class AccountMove(models.Model): string='Tax Cash Basis Entry of', help="Technical field used to keep track of the tax cash basis reconciliation." "This is needed when cancelling the source: it will post the inverse journal entry to cancel that part too.") + auto_reverse = fields.Boolean(string='Reverse Automatically', default=False, help='If this checkbox is ticked, this entry will be automatically reversed at the reversal date you defined.') + reverse_date = fields.Date(string='Reversal Date', help='Date of the reverse accounting entry.') + reverse_entry_id = fields.Many2one('account.move', String="Reverse entry", store=True, readonly=True) @api.model def fields_view_get(self, view_id=None, view_type='form', toolbar=False, submenu=False): @@ -228,27 +231,30 @@ class AccountMove(models.Model): return True @api.multi - def _reverse_move(self, date=None, journal_id=None): + def _reverse_move(self, date=None, journal_id=None, auto=False): self.ensure_one() reversed_move = self.copy(default={ 'date': date, 'journal_id': journal_id.id if journal_id else self.journal_id.id, - 'ref': _('reversal of: ') + self.name}) + 'ref': _('%sreversal of: ') % (_('Automatic ') if auto else '') + self.name, + 'auto_reverse': False}) for acm_line in reversed_move.line_ids.with_context(check_move_validity=False): acm_line.write({ 'debit': acm_line.credit, 'credit': acm_line.debit, 'amount_currency': -acm_line.amount_currency }) + self.reverse_entry_id = reversed_move return reversed_move @api.multi - def reverse_moves(self, date=None, journal_id=None): + def reverse_moves(self, date=None, journal_id=None, auto=False): date = date or fields.Date.today() reversed_moves = self.env['account.move'] for ac_move in self: reversed_move = ac_move._reverse_move(date=date, - journal_id=journal_id) + journal_id=journal_id, + auto=auto) reversed_moves |= reversed_move #unreconcile all lines reversed aml = ac_move.line_ids.filtered(lambda x: x.account_id.reconcile or x.account_id.internal_type == 'liquidity') @@ -270,6 +276,26 @@ class AccountMove(models.Model): def open_reconcile_view(self): return self.line_ids.open_reconcile_view() + @api.model + def _run_reverses_entries(self): + ''' This method is called from a cron job. ''' + records = self.search([ + ('state', '=', 'posted'), + ('auto_reverse', '=', True), + ('reverse_date', '<=', fields.Date.today()), + ('reverse_entry_id', '=', False)]) + for move in records: + date = None + if move.reverse_date and (not self.env.user.company_id.period_lock_date or move.reverse_date > self.env.user.company_id.period_lock_date): + date = move.reverse_date + move.reverse_moves(date=date, auto=True) + + @api.multi + def action_view_reverse_entry(self): + action = self.env.ref('account.action_move_journal_line').read()[0] + action['views'] = [(self.env.ref('account.view_move_form').id, 'form')] + action['res_id'] = self.reverse_entry_id.id + return action class AccountMoveLine(models.Model): _name = "account.move.line" diff --git a/addons/account/views/account_view.xml b/addons/account/views/account_view.xml index 7b392caf4b17..280659d96102 100644 --- a/addons/account/views/account_view.xml +++ b/addons/account/views/account_view.xml @@ -1434,6 +1434,13 @@ <sheet> <field name="id" invisible="1"/> <div class="oe_button_box"> + <button name="action_view_reverse_entry" + type="object" + class="oe_stat_button" + icon="fa-refresh" + attrs="{'invisible': [('reverse_entry_id', '=', False)]}" + string="Reversed entry"> + </button> <button name="open_reconcile_view" class="oe_stat_button" icon="fa-bars" @@ -1478,6 +1485,13 @@ </field> <field name="narration" colspan="4" placeholder="Add an internal note..." nolabel="1" height="50"/> </page> + <page string="Other Info"> + <group> + <field name="auto_reverse" attrs="{'readonly':[('reverse_entry_id', '!=', False)]}"/> + <field name="reverse_date" attrs="{'invisible':[('auto_reverse', '=', False)], 'required':[('auto_reverse', '=', True)],'readonly':[('reverse_entry_id', '!=', False)]}"/> + <field name="reverse_entry_id" attrs="{'invisible':True}"/> + </group> + </page> </notebook> </sheet> </form> -- GitLab