← Back to team overview

openerp-community-reviewer team mailing list archive

lp:~camptocamp/account-financial-tools/7.0-add-account_move_batch_validate-lep into lp:account-financial-tools

 

Leonardo Pistone @ camptocamp has proposed merging lp:~camptocamp/account-financial-tools/7.0-add-account_move_batch_validate-lep into lp:account-financial-tools.

Requested reviews:
  Account Core Editors (account-core-editors)

For more details, see:
https://code.launchpad.net/~camptocamp/account-financial-tools/7.0-add-account_move_batch_validate-lep/+merge/201187
-- 
https://code.launchpad.net/~camptocamp/account-financial-tools/7.0-add-account_move_batch_validate-lep/+merge/201187
Your team OpenERP Community Reviewer/Maintainer is subscribed to branch lp:account-financial-tools.
=== added directory 'account_move_batch_validate'
=== added file 'account_move_batch_validate/__init__.py'
--- account_move_batch_validate/__init__.py	1970-01-01 00:00:00 +0000
+++ account_move_batch_validate/__init__.py	2014-01-14 12:41:01 +0000
@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+###############################################################################
+#                                                                             #
+#   Author: Leonardo Pistone
+#   Copyright 2014 Camptocamp SA
+#                                                                             #
+#   This program is free software: you can redistribute it and/or modify      #
+#   it under the terms of the GNU Affero General Public License as            #
+#   published by the Free Software Foundation, either version 3 of the        #
+#   License, or (at your option) any later version.                           #
+#                                                                             #
+#   This program is distributed in the hope that it will be useful,           #
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of            #
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             #
+#   GNU Affero General Public License for more details.                       #
+#                                                                             #
+#   You should have received a copy of the GNU Affero General Public License  #
+#   along with this program.  If not, see <http://www.gnu.org/licenses/>.     #
+#                                                                             #
+###############################################################################
+"""Account Move Batch Validate."""
+
+import account  # noqa
+import wizard  # noqa

=== added file 'account_move_batch_validate/__openerp__.py'
--- account_move_batch_validate/__openerp__.py	1970-01-01 00:00:00 +0000
+++ account_move_batch_validate/__openerp__.py	2014-01-14 12:41:01 +0000
@@ -0,0 +1,54 @@
+# -*- coding: utf-8 -*-
+###############################################################################
+#                                                                             #
+#   Author: Leonardo Pistone
+#   Copyright 2014 Camptocamp SA
+#                                                                             #
+#   This program is free software: you can redistribute it and/or modify      #
+#   it under the terms of the GNU Affero General Public License as            #
+#   published by the Free Software Foundation, either version 3 of the        #
+#   License, or (at your option) any later version.                           #
+#                                                                             #
+#   This program is distributed in the hope that it will be useful,           #
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of            #
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             #
+#   GNU Affero General Public License for more details.                       #
+#                                                                             #
+#   You should have received a copy of the GNU Affero General Public License  #
+#   along with this program.  If not, see <http://www.gnu.org/licenses/>.     #
+#                                                                             #
+###############################################################################
+{
+    'name': "Account Move Batch Validate",
+    'version': '0.1',
+    'author': 'Camptocamp',
+    'maintainer': 'Camptocamp',
+    'category': 'Finance',
+    'complexity': 'normal',
+    'depends': [
+        'account',
+        'account_default_draft_move',
+        'connector',
+    ],
+    'description': """
+        Account Move Batch Validate
+
+        This module provides a wizard to post many Journal Entries in batch. it
+        uses the queue system introduces by the OpenERP Connector to handle a
+        big quantity of moves in batch.
+    """,
+    'website': 'http://www.camptocamp.com',
+    'init_xml': [],
+    'update_xml': [
+        'account_view.xml',
+        'wizard/move_marker_view.xml',
+    ],
+    'demo_xml': [],
+    'test': [
+        'test/batch_validate.yml',
+        'test/batch_validate_then_unmark.yml',
+    ],
+    'installable': True,
+    'images': [],
+    'license': 'AGPL-3',
+}

=== added file 'account_move_batch_validate/account.py'
--- account_move_batch_validate/account.py	1970-01-01 00:00:00 +0000
+++ account_move_batch_validate/account.py	2014-01-14 12:41:01 +0000
@@ -0,0 +1,121 @@
+# -*- coding: utf-8 -*-
+###############################################################################
+#                                                                             #
+#   Author: Leonardo Pistone
+#   Copyright 2014 Camptocamp SA
+#                                                                             #
+#   This program is free software: you can redistribute it and/or modify      #
+#   it under the terms of the GNU Affero General Public License as            #
+#   published by the Free Software Foundation, either version 3 of the        #
+#   License, or (at your option) any later version.                           #
+#                                                                             #
+#   This program is distributed in the hope that it will be useful,           #
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of            #
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             #
+#   GNU Affero General Public License for more details.                       #
+#                                                                             #
+#   You should have received a copy of the GNU Affero General Public License  #
+#   along with this program.  If not, see <http://www.gnu.org/licenses/>.     #
+#                                                                             #
+###############################################################################
+"""Accounting customisation for delayed posting."""
+
+from openerp.osv import fields, orm
+from openerp.tools.translate import _
+
+from openerp.addons.connector.queue.job import job
+from openerp.addons.connector.session import ConnectorSession
+from openerp.addons.connector.queue.job import OpenERPJobStorage
+
+
+class account_move(orm.Model):
+
+    """We modify the account move to allow delayed posting."""
+
+    _name = 'account.move'
+    _inherit = 'account.move'
+
+    _columns = {
+        'to_post': fields.boolean(
+            'To Post',
+            help='Check this box to mark the move for batch posting'
+        ),
+        'post_job_uuid': fields.char(
+            'UUID of the Job to approve this move'
+        ),
+    }
+
+    def _delay_post_marked(self, cr, uid, eta=None, context=None):
+        """Create a job for every move marked for posting.
+
+        If some moves already have a job, they are skipped.
+
+        """
+
+        if context is None:
+            context = {}
+
+        session = ConnectorSession(cr, uid, context=context)
+
+        move_ids = self.search(cr, uid, [
+            ('to_post', '=', True),
+            ('post_job_uuid', '=', False),
+            ('state', '=', 'draft'),
+        ], context=context)
+
+        for move_id in move_ids:
+            job_uuid = validate_one_move.delay(session, self._name, move_id,
+                                               eta=eta)
+            self.write(cr, uid, [move_id], {
+                'post_job_uuid': job_uuid
+            })
+
+    def _cancel_jobs(self, cr, uid, context=None):
+        """Find moves where the mark has been removed and cancel the jobs.
+
+        For the moves that are posted already it's too late: we skip them.
+
+        """
+
+        if context is None:
+            context = {}
+
+        session = ConnectorSession(cr, uid, context=context)
+        storage = OpenERPJobStorage(session)
+
+        move_ids = self.search(cr, uid, [
+            ('to_post', '=', False),
+            ('post_job_uuid', '!=', False),
+            ('state', '=', 'draft'),
+        ], context=context)
+
+        for move in self.browse(cr, uid, move_ids, context=context):
+            job = storage.load(move.post_job_uuid)
+            if job.state in (u'pending', u'enqueued'):
+                job.set_done(result=_(
+                    u'Task set to Done because the user unmarked the move'
+                ))
+
+    def mark_for_posting(self, cr, uid, move_ids, eta=None, context=None):
+        """Mark a list of moves for delayed posting, and enqueue the jobs."""
+        if context is None:
+            context = {}
+        self.write(cr, uid, move_ids, {'to_post': True}, context=context)
+        self._delay_post_marked(cr, uid, eta=eta, context=context)
+
+    def unmark_for_posting(self, cr, uid, move_ids, context=None):
+        """Unmark moves for delayed posting, and cancel the jobs."""
+        if context is None:
+            context = {}
+        self.write(cr, uid, move_ids, {'to_post': False}, context=context)
+        self._cancel_jobs(cr, uid, context=context)
+
+
+@job
+def validate_one_move(session, model_name, move_id):
+    """Validate a move, and leave the job reference in place."""
+    session.pool['account.move'].button_validate(
+        session.cr,
+        session.uid,
+        [move_id]
+    )

=== added file 'account_move_batch_validate/account_view.xml'
--- account_move_batch_validate/account_view.xml	1970-01-01 00:00:00 +0000
+++ account_move_batch_validate/account_view.xml	2014-01-14 12:41:01 +0000
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+    <data>
+
+        <record id="view_move_to_post_tree" model="ir.ui.view">
+            <field name="name">view.move.to_post.tree</field>
+            <field name="model">account.move</field>
+            <field name="inherit_id" ref="account.view_move_tree"/>
+            <field name="arch" type="xml">
+                <field name="to_check" position="after">
+                    <field name="to_post"/>
+                    <field name="post_job_uuid"/>
+                </field>
+            </field>
+        </record>
+
+        <record id="view_move_to_post_form" model="ir.ui.view">
+            <field name="name">view.move.to_post.form</field>
+            <field name="model">account.move</field>
+            <field name="inherit_id" ref="account.view_move_form"/>
+            <field name="arch" type="xml">
+                <field name="to_check" position="after">
+                    <field name="to_post"/>
+                    <field name="post_job_uuid"/>
+                </field>
+            </field>
+        </record>
+
+    </data>
+</openerp>

=== added directory 'account_move_batch_validate/test'
=== added file 'account_move_batch_validate/test/batch_validate.yml'
--- account_move_batch_validate/test/batch_validate.yml	1970-01-01 00:00:00 +0000
+++ account_move_batch_validate/test/batch_validate.yml	2014-01-14 12:41:01 +0000
@@ -0,0 +1,48 @@
+-
+  I create a move
+-
+  !record {model: account.move, id: move1}:
+    journal_id: account.sales_journal
+    line_id:
+      - name: Receivable line
+        account_id: account.a_recv
+        debit: 1000.0
+      - name: Sales line
+        account_id: account.a_sale
+        credit: 1000.0
+-
+  I check that the move is still draft
+-
+  !assert {model: account.move, id: move1}:
+    - state == 'draft'
+-
+  I create a wizard
+-
+  !record {model: account.move.marker, id: wiz_marker1}:
+    action: mark
+-
+  I run the wizard
+-
+  !python {model: account.move.marker}: |
+    self.button_mark(
+      cr, uid, [ref('wiz_marker1')], context=context
+    )
+-
+  I read the UUID from the move, I dequeue the job and run it
+-
+  !python {model: account.move}: |
+    from openerp.addons.connector.queue.job import OpenERPJobStorage
+    from openerp.addons.connector.session import ConnectorSession
+
+    move = self.browse(cr, uid, ref('move1'), context=context)
+    uuid = move.post_job_uuid
+    session = ConnectorSession(cr, uid, context=context)
+    storage = OpenERPJobStorage(session)
+
+    myjob = storage.load(uuid)
+    myjob.perform(session)
+-
+  I check that the move is now approved
+-
+  !assert {model: account.move, id: move1}:
+    - state == 'posted'

=== added file 'account_move_batch_validate/test/batch_validate_then_unmark.yml'
--- account_move_batch_validate/test/batch_validate_then_unmark.yml	1970-01-01 00:00:00 +0000
+++ account_move_batch_validate/test/batch_validate_then_unmark.yml	2014-01-14 12:41:01 +0000
@@ -0,0 +1,62 @@
+-
+  I create a move
+-
+  !record {model: account.move, id: move2}:
+    journal_id: account.sales_journal
+    line_id:
+      - name: Receivable line
+        account_id: account.a_recv
+        debit: 2000.0
+      - name: Sales line
+        account_id: account.a_sale
+        credit: 2000.0
+-
+  I check that the move is still draft
+-
+  !assert {model: account.move, id: move2}:
+    - state == 'draft'
+-
+  I create a wizard with a long ETA
+-
+  !record {model: account.move.marker, id: wiz_marker2}:
+    action: mark
+    eta: 10000
+-
+  I run the wizard
+-
+  !python {model: account.move.marker}: |
+    self.button_mark(
+      cr, uid, [ref('wiz_marker2')], context=context
+    )
+-
+  Now I change my mind and I create a wizard to unmark the moves
+-
+  !record {model: account.move.marker, id: wiz_unmarker3}:
+    action: unmark
+-
+  I run the wizard
+-
+  !python {model: account.move.marker}: |
+    self.button_mark(
+      cr, uid, [ref('wiz_unmarker3')], context=context
+    )
+-
+  Now I checked that my job is done, and the move is still draft
+-
+  !python {model: account.move}: |
+    from openerp.addons.connector.queue.job import OpenERPJobStorage
+    from openerp.addons.connector.session import ConnectorSession
+
+    session = ConnectorSession(cr, uid, context=context)
+    storage = OpenERPJobStorage(session)
+
+    move = self.browse(cr, uid, ref('move2'), context=context)
+    myjob = storage.load(move.post_job_uuid)
+    assert myjob.state == 'done', 'Job is in state {0}, should be done'.format(
+        myjob.state
+    )
+-
+  I check that the move is still draft
+-
+  !assert {model: account.move, id: move2}:
+    - state == 'draft'

=== added directory 'account_move_batch_validate/wizard'
=== added file 'account_move_batch_validate/wizard/__init__.py'
--- account_move_batch_validate/wizard/__init__.py	1970-01-01 00:00:00 +0000
+++ account_move_batch_validate/wizard/__init__.py	2014-01-14 12:41:01 +0000
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*-
+###############################################################################
+#                                                                             #
+#   Author: Leonardo Pistone
+#   Copyright 2014 Camptocamp SA
+#                                                                             #
+#   This program is free software: you can redistribute it and/or modify      #
+#   it under the terms of the GNU Affero General Public License as            #
+#   published by the Free Software Foundation, either version 3 of the        #
+#   License, or (at your option) any later version.                           #
+#                                                                             #
+#   This program is distributed in the hope that it will be useful,           #
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of            #
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             #
+#   GNU Affero General Public License for more details.                       #
+#                                                                             #
+#   You should have received a copy of the GNU Affero General Public License  #
+#   along with this program.  If not, see <http://www.gnu.org/licenses/>.     #
+#                                                                             #
+###############################################################################
+"""Wizard to mark account moves for batch posting."""
+import move_marker  # noqa

=== added file 'account_move_batch_validate/wizard/move_marker.py'
--- account_move_batch_validate/wizard/move_marker.py	1970-01-01 00:00:00 +0000
+++ account_move_batch_validate/wizard/move_marker.py	2014-01-14 12:41:01 +0000
@@ -0,0 +1,77 @@
+# -*- coding: utf-8 -*-
+###############################################################################
+#                                                                             #
+#   Author: Leonardo Pistone
+#   Copyright 2014 Camptocamp SA
+#                                                                             #
+#   This program is free software: you can redistribute it and/or modify      #
+#   it under the terms of the GNU Affero General Public License as            #
+#   published by the Free Software Foundation, either version 3 of the        #
+#   License, or (at your option) any later version.                           #
+#                                                                             #
+#   This program is distributed in the hope that it will be useful,           #
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of            #
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             #
+#   GNU Affero General Public License for more details.                       #
+#                                                                             #
+#   You should have received a copy of the GNU Affero General Public License  #
+#   along with this program.  If not, see <http://www.gnu.org/licenses/>.     #
+#                                                                             #
+###############################################################################
+"""Wizards for batch posting."""
+
+from openerp.osv import fields, orm
+
+
+class AccountMoveMarker(orm.TransientModel):
+
+    """Wizard to mark account moves for batch posting."""
+
+    _name = "account.move.marker"
+    _inherit = "account.common.report"
+    _description = "Mark Journal Items for batch posting"
+
+    _columns = {
+        'action': fields.selection([
+            ('mark', 'Mark for posting'),
+            ('unmark', 'Unmark for posting'),
+        ], "Action", required=True),
+        'eta': fields.integer('Seconds to wait before starting the jobs')
+    }
+
+    _defaults = {
+        'action': 'mark',
+    }
+
+    def button_mark(self, cr, uid, ids, context=None):
+        """Mark/unmark lines and update the queue. Return action."""
+
+        for wiz in self.browse(cr, uid, ids, context=context):
+
+            move_obj = self.pool['account.move']
+
+            domain = [('state', '=', 'draft')]
+
+            if wiz.filter != 'filter_no':
+                # TODO
+                raise NotImplementedError(
+                    'Date and period filters are not implemented yet'
+                )
+
+            if wiz.journal_ids:
+                domain.append((
+                    'journal_id',
+                    'in',
+                    [journal.id for journal in wiz.journal_ids]
+                ))
+
+            move_ids = move_obj.search(cr, uid, domain, context=context)
+
+            if wiz.action == 'mark':
+                move_obj.mark_for_posting(cr, uid, move_ids, eta=wiz.eta,
+                                          context=context)
+
+            elif wiz.action == 'unmark':
+                move_obj.unmark_for_posting(cr, uid, move_ids, context=context)
+
+            return {'type': 'ir.actions.act_window_close'}

=== added file 'account_move_batch_validate/wizard/move_marker_view.xml'
--- account_move_batch_validate/wizard/move_marker_view.xml	1970-01-01 00:00:00 +0000
+++ account_move_batch_validate/wizard/move_marker_view.xml	2014-01-14 12:41:01 +0000
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+    <data>
+
+        <record id="view_account_move_marker" model="ir.ui.view">
+            <field name="name">Mark Jornal Items for Batch Posting</field>
+            <field name="model">account.move.marker</field>
+            <field name="arch" type="xml">
+                <form string="Report Options" version="7.0">
+                    <label string=""/>  <!-- binding for inherited views -->
+                    <group col="4">
+                        <field name="chart_account_id" widget='selection' on_change="onchange_chart_id(chart_account_id, context)"/>
+                        <field name="company_id" invisible="1"/>
+                        <field name="fiscalyear_id" domain="[('company_id','=',company_id)]"/>
+                        <field name="action"/>
+                    </group>
+                    <notebook tabpos="up" colspan="4">
+                        <page string="Filters" name="filters">
+                            <group>
+                                <field name="filter" on_change="onchange_filter(filter, fiscalyear_id)"/>
+                            </group>
+                            <group string="Dates"  attrs="{'invisible':[('filter', '!=', 'filter_date')], 'required':[('filter', '=', 'filter_date')]}">
+                                <field name="date_from" />
+                                <field name="date_to" />
+                            </group>
+                            <group string="Periods" attrs="{'invisible':[('filter','!=','filter_period')], 'required':[('filter', '=', 'filter_period')]}">
+                                <field name="period_from" domain="[('fiscalyear_id', '=', fiscalyear_id)]"/>
+                                <field name="period_to" domain="[('fiscalyear_id', '=', fiscalyear_id)]"/>
+                            </group>
+                        </page>
+                        <page string="Journals" name="journal_ids">
+                            <field name="journal_ids"/>
+                        </page>
+                    </notebook>
+                    <footer>
+                        <button name="button_mark" string="Mark" type="object" default_focus="1" class="oe_highlight"/>
+                        or 
+                        <button string="Cancel" class="oe_link" special="cancel" />
+                    </footer>
+                </form>
+            </field>
+        </record>
+
+        <record id="action_account_move_marker" model="ir.actions.act_window">
+            <field name="name">Mark Jornal Items for Batch Posting</field>
+            <field name="type">ir.actions.act_window</field>
+            <field name="res_model">account.move.marker</field>
+            <field name="view_type">form</field>
+            <field name="view_mode">form</field>
+            <field name="target">new</field>
+        </record>
+
+        <menuitem
+            name="Mark Jornal Items for Batch Posting"
+            parent="account.periodical_processing_journal_entries_validation"
+            action="action_account_move_marker"
+            id="menu_account_move_marker"
+            icon="STOCK_PRINT"/>
+
+    </data>
+</openerp>


Follow ups