← Back to team overview

account-payment-team team mailing list archive

[Merge] lp:~elbati/account-payment/adding_account_voucher_cash_basis_7 into lp:account-payment/7.0

 

Lorenzo Battistini - Agile BG has proposed merging lp:~elbati/account-payment/adding_account_voucher_cash_basis_7 into lp:account-payment/7.0.

Requested reviews:
  Account Payment (account-payment-team)

For more details, see:
https://code.launchpad.net/~elbati/account-payment/adding_account_voucher_cash_basis_7/+merge/159379

This module gathers all the basic functionalities that allow to handle the cash basis

It is used by l10n_it_withholding_tax and account_vat_on_payment
-- 
https://code.launchpad.net/~elbati/account-payment/adding_account_voucher_cash_basis_7/+merge/159379
Your team Account Payment is requested to review the proposed merge of lp:~elbati/account-payment/adding_account_voucher_cash_basis_7 into lp:account-payment/7.0.
=== added directory 'account_voucher_cash_basis'
=== added file 'account_voucher_cash_basis/AUTHORS.txt'
--- account_voucher_cash_basis/AUTHORS.txt	1970-01-01 00:00:00 +0000
+++ account_voucher_cash_basis/AUTHORS.txt	2013-04-17 12:53:31 +0000
@@ -0,0 +1,1 @@
+Lorenzo Battistini <lorenzo.battistini@xxxxxxxxxxx>

=== added file 'account_voucher_cash_basis/__init__.py'
--- account_voucher_cash_basis/__init__.py	1970-01-01 00:00:00 +0000
+++ account_voucher_cash_basis/__init__.py	2013-04-17 12:53:31 +0000
@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (C) 2012 Domsense s.r.l. (<http://www.domsense.com>).
+#    Copyright (C) 2012-2013 Agile Business Group sagl
+#    (<http://www.agilebg.com>)
+#
+#    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/>.
+#
+##############################################################################
+import account_voucher
+import company

=== added file 'account_voucher_cash_basis/__openerp__.py'
--- account_voucher_cash_basis/__openerp__.py	1970-01-01 00:00:00 +0000
+++ account_voucher_cash_basis/__openerp__.py	2013-04-17 12:53:31 +0000
@@ -0,0 +1,46 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (C) 2011-2012 Domsense s.r.l. (<http://www.domsense.com>).
+#    Copyright (C) 2012-2013 Agile Business Group sagl
+#    (<http://www.agilebg.com>)
+#
+#    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": "Cash basis extensions for vouchers",
+    "version": "1.0",
+    'category': 'Hidden/Dependency',
+    "depends": ["account_voucher"],
+    "author": "Agile Business Group",
+    "description": """
+    In some countries, under certain conditions, companies can apply the cash basis.
+    The cash basis means businesses may account for VAT as payment comes in from their customers. It is easier to manage than the normal method, which forces businesses to account for VAT based on invoices issued, regardless of whether or not the money has come in.
+    The key advantage to accounting for VAT on a cash basis is the cashflow benefit to your business. The effect of the cash basis is that you only become liable for VAT when you have actually received payment, so you don't have to fund the VAT on your debtors. This is particularly helpful in a startup situation and in the case of an expanding business.
+    
+    This module gathers all the basic functionalities that allow to handle the cash basis
+    """,
+    'website': 'http://www.agilebg.com',
+    'init_xml': [],
+    'data': [
+        'company_view.xml',
+        ],
+    'demo': [],
+    'installable': True,
+    'active': False,
+}

=== added file 'account_voucher_cash_basis/account_voucher.py'
--- account_voucher_cash_basis/account_voucher.py	1970-01-01 00:00:00 +0000
+++ account_voucher_cash_basis/account_voucher.py	2013-04-17 12:53:31 +0000
@@ -0,0 +1,126 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (C) 2012 Domsense s.r.l. (<http://www.domsense.com>).
+#    Copyright (C) 2012-2013 Agile Business Group sagl
+#    (<http://www.agilebg.com>)
+#
+#    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/>.
+#
+##############################################################################
+
+from openerp.osv import fields, orm
+from openerp.tools.translate import _
+import decimal_precision as dp
+
+class account_voucher(orm.Model):
+    _inherit = "account.voucher"
+    
+    _columns = {
+        'line_total': fields.float('Lines Total', digits_compute=dp.get_precision('Account'), readonly=True),
+        }
+    
+    def balance_move(self, cr, uid, move_id, context=None):
+        currency_obj = self.pool.get('res.currency')
+        move = self.pool.get('account.move').browse(cr, uid, move_id, context)
+        amount = 0.0
+        for line in move.line_id:
+            amount += line.debit - line.credit
+        amount = currency_obj.round(cr, uid, move.company_id.currency_id, amount)
+        # check if balance differs for more than 1 decimal according to account decimal precision
+        if  abs(amount * 10 ** dp.get_precision('Account')(cr)[1]) > 1:
+            raise orm.except_orm(_('Error'), _('The generated payment entry is unbalanced for more than 1 decimal'))
+        if not currency_obj.is_zero(cr, uid, move.company_id.currency_id, amount):
+            for line in move.line_id:
+                # adjust the first move line that's not receivable, payable or liquidity
+                if line.account_id.type != 'receivable' and line.account_id.type != 'payable' and line.account_id.type != 'liquidity':
+                    if line.credit:
+                        line.write({
+                            'credit': line.credit + amount,
+                            }, update_check=False)
+                    elif line.debit:
+                        line.write({
+                            'debit': line.debit - amount,
+                            }, update_check=False)
+                    if line.tax_amount:
+                        line.write({
+                            'tax_amount': line.tax_amount + amount,
+                            }, update_check=False)
+                    break
+        return amount
+        
+    def voucher_move_line_create(self, cr, uid, voucher_id, line_total, move_id, company_currency, current_currency, context=None):
+        res = super(account_voucher,self).voucher_move_line_create(cr, uid, voucher_id, line_total, move_id, company_currency, current_currency, context)
+        self.write(cr, uid, voucher_id, {'line_total': res[0]}, context)
+        return res
+        
+    def get_invoice_total(self, invoice):
+        res = 0.0
+        for inv_move_line in invoice.move_id.line_id:
+            if inv_move_line.account_id.type in ('receivable','payable'):
+                res += inv_move_line.debit or inv_move_line.credit # can both be presents?
+        return res
+        
+    def allocated_amounts_grouped_by_invoice(self, cr, uid, voucher, context=None):
+        '''
+        
+        this method builds a dictionary in the following form
+        
+        {
+            first_invoice_id: {
+                'allocated': 120.0,
+                'total': 120.0,
+                'write-off': 20.0,
+                }
+            second_invoice_id: {
+                'allocated': 50.0,
+                'total': 100.0,
+                'write-off': 0.0,
+                }
+        }
+        
+        every amout is expressed in company currency.
+        
+        In order to compute cashed amount correctly, write-off will be subtract to reconciled amount.
+        If more than one invoice is paid with this voucher, we distribute write-off equally (if allowed)
+        
+        '''
+        res={}
+        company_currency = super(account_voucher,self)._get_company_currency(
+            cr, uid, voucher.id, context)
+        current_currency = super(account_voucher,self)._get_current_currency(
+            cr, uid, voucher.id, context)
+        for line in voucher.line_ids:
+            if line.amount and line.move_line_id and line.move_line_id.invoice:
+                if not res.has_key(line.move_line_id.invoice.id):
+                    res[line.move_line_id.invoice.id] = {
+                        'allocated': 0.0,
+                        'total': 0.0,
+                        'write-off': 0.0,}
+                current_amount = line.amount
+                if company_currency != current_currency:
+                    current_amount = super(account_voucher,self)._convert_amount(cr, uid, line.amount, voucher.id, context)
+                res[line.move_line_id.invoice.id]['allocated'] += current_amount
+                res[line.move_line_id.invoice.id]['total'] = self.get_invoice_total(line.move_line_id.invoice)
+        if res:
+            write_off_per_invoice = voucher.line_total / len(res.keys())
+            if not voucher.company_id.allow_distributing_write_off and  len(res.keys()) > 1 and write_off_per_invoice:
+                raise orm.except_orm(_('Error'), _(
+                    'You are trying to pay with write-off more than one invoice and distributing write-off is not allowed. See company settings.'))
+            if voucher.type == 'payment' or voucher.type == 'purchase':
+                write_off_per_invoice = - write_off_per_invoice
+            for inv_id in res:
+                res[inv_id]['write-off'] = write_off_per_invoice
+        return res

=== added file 'account_voucher_cash_basis/company.py'
--- account_voucher_cash_basis/company.py	1970-01-01 00:00:00 +0000
+++ account_voucher_cash_basis/company.py	2013-04-17 12:53:31 +0000
@@ -0,0 +1,61 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (C) 2011-2012 Domsense s.r.l. (<http://www.domsense.com>).
+#    Copyright (C) 2012-2013 Agile Business Group sagl
+#    (<http://www.agilebg.com>)
+#
+#    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/>.
+#
+##############################################################################
+
+from openerp.osv import fields, orm
+from openerp.tools.translate import _
+
+class res_company(orm.Model):
+    _inherit = "res.company"
+    _columns = {
+        'vat_on_payment': fields.boolean('VAT on payment treatment'),
+        'allow_distributing_write_off': fields.boolean('Allow distributing write-off', help="If not set, paying several 'cash basis' invoices with same voucher with write-off won't be allowed. If set, write-off will be distributed equally over invoices"),
+        }
+    
+class account_config_settings(orm.TransientModel):
+    _inherit = 'account.config.settings'
+    _columns = {
+        'vat_on_payment': fields.related(
+            'company_id', 'vat_on_payment',
+            type='boolean',
+            string="VAT on payment treatment"),
+        'allow_distributing_write_off': fields.related(
+            'company_id', 'allow_distributing_write_off',
+            type="boolean",
+            string="Allow distributing write-off",
+            help="If not set, paying several 'cash basis' invoices with same voucher with write-off won't be allowed. If set, write-off will be distributed equally over invoices"),
+    }
+    
+    def onchange_company_id(self, cr, uid, ids, company_id, context=None):
+        res = super(account_config_settings, self).onchange_company_id(cr, uid, ids, company_id, context=context)
+        if company_id:
+            company = self.pool.get('res.company').browse(cr, uid, company_id, context=context)
+            res['value'].update({
+                'vat_on_payment': company.vat_on_payment, 
+                'allow_distributing_write_off': company.allow_distributing_write_off,
+                })
+        else: 
+            res['value'].update({
+                'vat_on_payment': False, 
+                'allow_distributing_write_off': False,
+                })
+        return res

=== added file 'account_voucher_cash_basis/company_view.xml'
--- account_voucher_cash_basis/company_view.xml	1970-01-01 00:00:00 +0000
+++ account_voucher_cash_basis/company_view.xml	2013-04-17 12:53:31 +0000
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+    <data>
+
+        <record id="view_account_config_settings" model="ir.ui.view">
+            <field name="name">view_account_config_settings</field>
+            <field name="model">account.config.settings</field>
+            <field name="inherit_id" ref="account.view_account_config_settings"/>
+            <field name="arch" type="xml">
+                <xpath expr="/form/group[5]/div" position="inside">
+                    <div>
+                        <field name="allow_distributing_write_off" class="oe_inline"/>
+                        <label for="allow_distributing_write_off"/>
+                    </div>
+                </xpath>
+            </field>
+        </record>
+    </data>
+</openerp>

=== added directory 'account_voucher_cash_basis/i18n'

Follow ups