Rodney Enciso Arias před 7 roky
revize
c0b61ed7f0

+ 5 - 0
__init__.py

@@ -0,0 +1,5 @@
+# -*- encoding: utf-8 -*-
+from . import wizard
+from . import account
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

binární
__init__.pyc


+ 35 - 0
__openerp__.py

@@ -0,0 +1,35 @@
+# -*- encoding: utf-8 -*-
+{
+    "name": "Bank and Cash Statement with Vouchers",
+    "version": "2.0",
+    "description": """
+Manage the bank/cash reconciliation with account vouchers (payments and receipts)
+=================================================================================
+
+The management of treasury require integrate the payments of customers and suppliers to bank statements, allowing real bank reconciliations.
+
+Key Features
+------------
+* Add button on bank statement to add vouchers
+* Integrate the account vouchers with the bank statements
+* Optimize the payments and receipts in treasury management
+* Fix some features on bank statements to enable the bank reconciliation
+
+    """,
+    "author": "Cubic ERP/Rodney Enciso Arias",
+    "website": "http://cubicERP.com",
+    "category": "Financial",
+    "depends": [
+        "account",
+        "account_voucher",
+        "account_reference",
+    ],
+    "data": [
+        "wizard/bank_statement_populate_view.xml",
+        "account_view.xml",
+    ],
+    "demo_xml": [],
+    "active": False,
+    "installable": True,
+}
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

+ 82 - 0
account.py

@@ -0,0 +1,82 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+# For copyright and license notices, see __openerp__.py file in module root
+# directory
+##############################################################################
+from openerp import models, fields, api,  _
+from openerp.exceptions import Warning
+
+
+class account_bank_statement(models.Model):
+    _inherit = 'account.bank.statement'
+
+    def button_cancel(self, cr, uid, ids, context=None):
+        context['cancel_from_statement'] = True
+        return super(account_bank_statement, self).button_cancel(
+            cr, uid, ids, context=context)
+
+
+class account_bank_statement_line(models.Model):
+    _inherit = 'account.bank.statement.line'
+
+    voucher_id = fields.Many2one('account.voucher', 'Voucher', readonly=True)
+
+    def cancel(self, cr, uid, ids, context=None):
+        # if we are canceling the statement then we dont raise the warning
+        if context.get('cancel_from_statement', False):
+            none_voucher_ids = self.search(
+                cr, uid,
+                [('id', 'in', ids), ('voucher_id', '=', False)])
+            return super(account_bank_statement_line, self).cancel(
+                cr, uid, none_voucher_ids, context)
+
+        for line in self.browse(cr, uid, ids, context):
+            if line.voucher_id:
+                raise Warning(
+                    _("You can not cancel a line that has been imported from a Voucher, you should cancel the voucher first"))
+        return super(account_bank_statement_line, self).cancel(
+            cr, uid, ids, context)
+
+        account_move_obj = self.pool.get('account.move')
+        move_ids = []
+        for line in self.browse(cr, uid, ids, context=context):
+            if line.journal_entry_id:
+                move_ids.append(line.journal_entry_id.id)
+                for aml in line.journal_entry_id.line_id:
+                    if aml.reconcile_id:
+                        move_lines = [l.id for l in aml.reconcile_id.line_id]
+                        move_lines.remove(aml.id)
+                        self.pool.get('account.move.reconcile').unlink(
+                            cr, uid, [aml.reconcile_id.id], context=context)
+                        if len(move_lines) >= 2:
+                            self.pool.get('account.move.line').reconcile_partial(
+                                cr, uid, move_lines, 'auto', context=context)
+        if move_ids:
+            account_move_obj.button_cancel(cr, uid, move_ids, context=context)
+            account_move_obj.unlink(cr, uid, move_ids, context)
+
+    def unlink(self, cr, uid, ids, context=None):
+        line_voucher_ids = self.search(
+            cr, uid,
+            [('id', 'in', ids), ('voucher_id', '!=', False)])
+        # First remove journal_entry_id id in order to avoid constraint
+        self.write(cr, uid, line_voucher_ids, {'journal_entry_id': False})
+        return super(account_bank_statement_line, self).unlink(
+            cr, uid, ids, context=context)
+
+
+class account_voucher(models.Model):
+    _inherit = 'account.voucher'
+
+    bank_statement_line_ids = fields.One2many(
+        'account.bank.statement.line', 'voucher_id', string="Statement Lines")
+
+    @api.multi
+    def cancel_voucher(self):
+        # run with sudo because some users may not have access to statement line
+        if self.sudo().bank_statement_line_ids.statement_id.state == 'confirm':
+            raise Warning(
+                _("You can not cancel a voucher that is linked to a confirm bank statement"))
+        else:
+            super(account_voucher, self).cancel_voucher()
+            return self.sudo().bank_statement_line_ids.unlink()

binární
account.pyc


+ 32 - 0
account_view.xml

@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<openerp>
+	<data>              
+
+        <record id="view_bank_voucher_statement_form" model="ir.ui.view">
+            <field name="name">account.bank.vocuher.statement.form.inherit.voucher</field>
+            <field name="model">account.bank.statement</field>
+            <field name="inherit_id" ref="account.view_bank_statement_form"/>
+            <field name="arch" type="xml">
+                <div name="import_buttons">
+                    <button class="oe_inline oe_stat_button" context="{'default_journal_id': journal_id}" name="%(action_voucher_populate_statement)d" string=" Pagos" type="action" attrs="{'invisible':[('state','=','confirm')]}" widget="statinfo" icon="fa-list"/>
+                </div>
+                <xpath expr="//field[@name='bank_account_id']" position="before">
+                    <field name="voucher_id"/>
+                </xpath>
+            </field>
+        </record>
+        
+        <record id="view_bank_voucher_statement_form2" model="ir.ui.view">
+            <field name="name">account.bank.vocuher.statement.form.inherit.voucher2</field>
+            <field name="model">account.bank.statement</field>
+            <field name="inherit_id" ref="account.view_bank_statement_form2"/>
+            <field name="arch" type="xml">
+                <label for="name" position="before">
+                    <div class="oe_right oe_button_box" name="import_buttons">
+                        <button class="oe_inline oe_stat_button" name="%(action_voucher_populate_statement)d" string=" Pagos" type="action" attrs="{'invisible':[('state','!=','open')]}" context="{'default_journal_id': journal_id}" widget="statinfo" icon="fa-list"/>
+                    </div>
+                </label>
+            </field>
+        </record>
+	</data>
+</openerp>

+ 4 - 0
wizard/__init__.py

@@ -0,0 +1,4 @@
+# -*- encoding: utf-8 -*-
+from . import bank_statement_populate
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

binární
wizard/__init__.pyc


+ 69 - 0
wizard/bank_statement_populate.py

@@ -0,0 +1,69 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+# For copyright and license notices, see __openerp__.py file in module root
+# directory
+##############################################################################
+from openerp import fields, models, api
+
+
+class account_voucher_populate_statement(models.TransientModel):
+    _name = "account.voucher.populate.statement"
+    _description = "Account Voucher Populate Statement"
+
+    journal_id = fields.Many2one(
+        'account.journal',
+        'Metodos de Pago',
+        required=True,
+        domain="[('type', '=', ['cash','bank'])]"
+    )
+    line_ids = fields.Many2many(
+        'account.voucher',
+        'account_voucher_line_rel_',
+        'voucher_id', 'line_id',
+        'Lineas de Pago',
+        domain="[('journal_id', '=', journal_id), ('state', '=', 'posted'), ('bank_statement_line_ids', '=', False)]"
+    )
+    
+    def get_statement_line_new(self, cr, uid, voucher, statement, context=None):
+        # Override thi method to modifiy the new statement line to create
+        ctx = context.copy()
+        ctx['date'] = voucher.date
+        amount = self.pool.get('res.currency').compute(cr, uid, voucher.currency_id.id,
+                                                       statement.currency.id, voucher.amount, context=ctx)
+
+        sign = voucher.type == 'payment' and -1.0 or 1.0
+        type = voucher.type == 'payment' and 'supplier' or 'customer'
+        account_id = voucher.type == 'payment' and voucher.partner_id.property_account_payable.id or voucher.partner_id.property_account_receivable.id
+        return {
+            'name': voucher.reference or voucher.number or '?',
+            'amount': sign * amount,
+            'type': type,
+            'partner_id': voucher.partner_id.id,
+            'account_id': account_id,
+            'statement_id': statement.id,
+            'ref': voucher.name,
+            'voucher_id': voucher.id,
+            'journal_entry_id': voucher.move_id.id,
+        }
+
+    def populate_statement(self, cr, uid, ids, context=None):
+        statement_obj = self.pool.get('account.bank.statement')
+        statement_line_obj = self.pool.get('account.bank.statement.line')
+        voucher_obj = self.pool.get('account.voucher')
+
+        if context is None:
+            context = {}
+        data = self.read(cr, uid, ids, [], context=context)[0]
+        voucher_ids = data['line_ids']
+        if not voucher_ids:
+            return {'type': 'ir.actions.act_window_close'}
+        statement = statement_obj.browse(
+            cr, uid, context['active_id'], context=context)
+        for voucher in voucher_obj.browse(cr, uid, voucher_ids, context=context):
+            statement_line_obj.create(cr, uid,
+                                      self.get_statement_line_new(cr, uid, voucher, statement, context=context), context=context)
+        voucher_obj.write(
+            cr, uid, voucher_ids, {'is_bank_voucher': True}, context=context)
+        return {'type': 'ir.actions.act_window_close'}
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

binární
wizard/bank_statement_populate.pyc


+ 33 - 0
wizard/bank_statement_populate_view.xml

@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<openerp>
+    <data>
+
+        <record id="account_voucher_populate_statement_view" model="ir.ui.view">
+             <field name="name">Registro de Pagos</field>
+             <field name="model">account.voucher.populate.statement</field>
+             <field name="arch" type="xml">
+                <form string="Populate Statement:" version="7.0">
+                    <group>
+                        <field name="journal_id" invisible="1" options="{'no_create':True,'no_create_edit':True}"/>
+                        <field name="line_ids"/>
+                    </group>
+                    <footer>
+                        <button name="populate_statement" string="Aceptar" type="object" class="oe_highlight"/>
+                    </footer>
+                </form>
+             </field>
+        </record>
+        
+        <record id="action_voucher_populate_statement" model="ir.actions.act_window">
+             <field name="name">Registro de Pagos</field>
+             <field name="res_model">account.voucher.populate.statement</field>
+             <field name="type">ir.actions.act_window</field>
+             <field name="view_type">form</field>
+             <field name="view_mode">tree,form</field>
+             <field name="view_id" ref="account_voucher_populate_statement_view"/>
+             <field name="context">{'record_id':active_id}</field>
+             <field name="target">new</field>
+       </record>
+
+    </data>
+</openerp>