← Back to team overview

openobject-italia-core-devs team mailing list archive

[Merge] lp:~elbati/openobject-italia/ref_l10n_it_withholding_tax into lp:openobject-italia/6.1

 

Lorenzo Battistini - Agile BG - Domsense has proposed merging lp:~elbati/openobject-italia/ref_l10n_it_withholding_tax into lp:openobject-italia/6.1.

Requested reviews:
  OpenERP Italia core devs (openobject-italia-core-devs)

For more details, see:
https://code.launchpad.net/~elbati/openobject-italia/ref_l10n_it_withholding_tax/+merge/116825
-- 
https://code.launchpad.net/~elbati/openobject-italia/ref_l10n_it_withholding_tax/+merge/116825
Your team OpenERP Italia core devs is requested to review the proposed merge of lp:~elbati/openobject-italia/ref_l10n_it_withholding_tax into lp:openobject-italia/6.1.
=== modified file 'l10n_it_withholding_tax/__openerp__.py'
--- l10n_it_withholding_tax/__openerp__.py	2012-07-03 06:22:49 +0000
+++ l10n_it_withholding_tax/__openerp__.py	2012-07-26 10:24:24 +0000
@@ -36,7 +36,7 @@
     'author': 'OpenERP Italian Community',
     'website': 'http://www.openerp-italia.org',
     'license': 'AGPL-3',
-    "depends" : ['account_invoice_template'],
+    "depends" : ['account_invoice_template', 'account_voucher_cash_basis'],
     "init_xml" : [
         'account_view.xml',
         ],

=== modified file 'l10n_it_withholding_tax/account.py'
--- l10n_it_withholding_tax/account.py	2012-06-12 15:40:54 +0000
+++ l10n_it_withholding_tax/account.py	2012-07-26 10:24:24 +0000
@@ -26,50 +26,112 @@
 from osv import fields, osv
 from tools.translate import _
 
+# TODO creare la tax ritenuta
 class account_tax(osv.osv):
     _inherit = 'account.tax'
     _columns = {
         'withholding_tax': fields.boolean('Withholding Tax'),
         'withholding_payment_term_id': fields.many2one('account.payment.term', 'Withholding Payment Term'),
+        'withholding_account_id': fields.many2one('account.account','Withholding account', help='Payable account used for amount due to tax authority'),
+        'withholding_journal_id': fields.many2one('account.journal','Withholding journal'),
         }
-account_tax()
 
-class account_invoice(osv.osv):
-    _inherit = "account.invoice"
-    
-    def action_move_create(self, cr, uid, ids, context=None):
-        res = super(account_invoice, self).action_move_create(cr, uid, ids, context=context)
-        tax_pool = self.pool.get('account.tax')
+class account_voucher(osv.osv):
+    _inherit = "account.voucher"
+    
+    _columns = {
+        'withholding_move_id': fields.many2one('account.move','Withholding Entry', readonly=True),
+        }
+    
+    def is_withholding_move_line(self, cr , uid, line_id, context=None):
+        move_line = self.pool.get('account.move.line').browse(cr, uid, line_id, context)
+        tax_pool = self.pool.get('account.tax')
+        tax_ids = tax_pool.search(cr, uid, [('tax_code_id', '=', move_line.tax_code_id.id)])
+        is_withholding = False
+        for tax in tax_pool.browse(cr, uid, tax_ids):
+            if tax.withholding_tax:
+                is_withholding = True
+        return is_withholding
+        
+    def get_withholding_tax(self, cr, uid, move_line_id, context=None):
+        tax_pool = self.pool.get('account.tax')
+        move_line = self.pool.get('account.move.line').browse(cr, uid, move_line_id, context)
+        tax_ids = tax_pool.search(cr, uid, [('tax_code_id', '=', move_line.tax_code_id.id)])
+        if len(tax_ids) > 1:
+            raise osv.except_osv(_('Error'),
+                _('Too many taxes associated to tax.code %s') % move_line.tax_code_id.name)
+        if not tax_ids:
+            raise osv.except_osv(_('Error'),
+                _('No taxes associated to tax.code %s') % move_line.tax_code_id.name)
+        return tax_ids[0]
+    
+    def action_move_line_create(self, cr, uid, ids, context=None):
+        res = super(account_voucher,self).action_move_line_create(cr, uid, ids, context)
+        inv_pool = self.pool.get('account.invoice')
+        tax_pool = self.pool.get('account.tax')
+        curr_pool = self.pool.get('res.currency')
         term_pool = self.pool.get('account.payment.term')
-        for inv in self.browse(cr, uid, ids, context=context):
-            for move_line in inv.move_id.line_id:
-                if move_line.tax_code_id:
-                    tax_ids = tax_pool.search(cr, uid, [('tax_code_id', '=', move_line.tax_code_id.id)])
-                    is_withholding = False
-                    for tax in tax_pool.browse(cr, uid, tax_ids):
-                        if tax.withholding_tax:
-                            is_withholding = True
-                    if is_withholding:
-                        if len(tax_ids) > 1:
-                            raise osv.except_osv(_('Error'),
-                                _('Too many taxes associated to tax.code %s') % move_line.tax_code_id.name)
-                        if not tax_ids:
-                            raise osv.except_osv(_('Error'),
-                                _('No taxes associated to tax.code %s') % move_line.tax_code_id.name)
-                        tax = tax_pool.browse(cr, uid, tax_ids[0])
-                        if tax.withholding_tax and tax.withholding_payment_term_id:
-                            due_list = term_pool.compute(
-                                cr, uid, tax.withholding_payment_term_id.id, move_line.tax_amount,
-                                date_ref=inv.date_invoice, context=context)
-                            if len(due_list) > 1:
-                                raise osv.except_osv(_('Error'),
-                                    _('The payment term %s has too many due dates')
-                                    % tax.withholding_payment_term_id.name)
-                            if len(due_list) == 0:
-                                raise osv.except_osv(_('Error'),
-                                    _('The payment term %s does not have due dates')
-                                    % tax.withholding_payment_term_id.name)
-                            move_line.write({'date_maturity': due_list[0][0]})
+        for voucher in self.browse(cr, uid, ids, context):
+            amounts_by_invoice = super(account_voucher,self).allocated_amounts_grouped_by_invoice(cr, uid,voucher, context)
+            for inv_id in amounts_by_invoice:
+                invoice = inv_pool.browse(cr, uid, inv_id, context)
+                for move_line in invoice.move_id.line_id:
+                    if self.is_withholding_move_line(cr , uid, move_line.id, context):
+                        # only for supplier payments
+                        if voucher.type != 'payment':
+                            raise osv.except_osv(_('Error'), _('Can\'t handle withholding tax with voucher of type other than payment'))
+                        wh_tax = tax_pool.browse(cr, uid, self.get_withholding_tax(cr, uid, move_line.id, context), context)
+                        if not wh_tax.withholding_account_id:
+                            raise osv.except_osv(_('Error'), _('The tax %s does not have an associated Withholding account') % wh_tax.name)
+                        if not wh_tax.withholding_payment_term_id:
+                            raise osv.except_osv(_('Error'), _('The tax %s does not have an associated Withholding Payment Term') % wh_tax.name)
+                        if not wh_tax.withholding_journal_id:
+                            raise osv.except_osv(_('Error'), _('The tax %s does not have an associated Withholding journal') % wh_tax.name)
+                        # compute the new amount proportionally to paid amount
+                        new_line_amount = curr_pool.round(cr, uid, voucher.company_id.currency_id, ((amounts_by_invoice[invoice.id]['allocated'] + amounts_by_invoice[invoice.id]['write-off']) / amounts_by_invoice[invoice.id]['total']) * (move_line.credit or move_line.debit))
+                        
+                        # compute the due date
+                        due_list = term_pool.compute(
+                            cr, uid, wh_tax.withholding_payment_term_id.id, new_line_amount,
+                            date_ref=invoice.date_invoice, context=context)
+                        if len(due_list) > 1:
+                            raise osv.except_osv(_('Error'),
+                                _('The payment term %s has too many due dates')
+                                % wh_tax.withholding_payment_term_id.name)
+                        if len(due_list) == 0:
+                            raise osv.except_osv(_('Error'),
+                                _('The payment term %s does not have due dates')
+                                % wh_tax.withholding_payment_term_id.name)
+                                
+                        new_move = {
+                            'journal_id': wh_tax.withholding_journal_id.id,
+                            'line_id': [
+                                (0,0,{
+                                    'name': move_line.name,
+                                    'account_id': move_line.account_id.id,
+                                    'debit': new_line_amount,
+                                    'credit': 0.0,
+                                    }),
+                                (0,0,{
+                                    'name': _('Payable withholding - ') + move_line.name,
+                                    'account_id': wh_tax.withholding_account_id.id,
+                                    'debit': 0.0,
+                                    'credit': new_line_amount,
+                                    'date_maturity': due_list[0][0],
+                                    }),
+                                ]
+                            }
+                        move_id = self.pool.get('account.move').create(cr, uid, new_move, context=context)
+                        voucher.write({'withholding_move_id': move_id})
         return res
 
-account_invoice()
+    def cancel_voucher(self, cr, uid, ids, context=None):
+        res = super(account_voucher,self).cancel_voucher(cr, uid, ids, context)
+        reconcile_pool = self.pool.get('account.move.reconcile')
+        move_pool = self.pool.get('account.move')
+        for voucher in self.browse(cr, uid, ids, context=context):
+            recs = []
+            if voucher.withholding_move_id:
+                move_pool.button_cancel(cr, uid, [voucher.withholding_move_id.id])
+                move_pool.unlink(cr, uid, [voucher.withholding_move_id.id])
+        return res

=== modified file 'l10n_it_withholding_tax/account_view.xml'
--- l10n_it_withholding_tax/account_view.xml	2012-02-17 14:03:46 +0000
+++ l10n_it_withholding_tax/account_view.xml	2012-07-26 10:24:24 +0000
@@ -10,7 +10,21 @@
             <field name="arch" type="xml">
                 <field name="active" position="after">
                     <field name="withholding_tax"/>
-                    <field name="withholding_payment_term_id" attrs="{'readonly':[('withholding_tax','=',False)]}"/>
+                    <field name="withholding_payment_term_id" attrs="{'readonly':[('withholding_tax','=',False)], 'required':[('withholding_tax','!=',False)]}"/>
+                    <field name="withholding_account_id" attrs="{'readonly':[('withholding_tax','=',False)], 'required':[('withholding_tax','!=',False)]}"  domain="[('type', '=', 'payable')]"/>
+                    <field name="withholding_journal_id" attrs="{'readonly':[('withholding_tax','=',False)], 'required':[('withholding_tax','!=',False)]}"/>
+                </field>
+            </field>
+        </record>
+        
+        <record id="view_vendor_payment_form_wh_move" model="ir.ui.view">
+            <field name="name">account.voucher.payment.form.wh.move</field>
+            <field name="model">account.voucher</field>
+            <field name="type">form</field>
+            <field name="inherit_id" ref="account_voucher.view_vendor_payment_form"/>
+            <field name="arch" type="xml">
+                <field name="move_ids" position="after">
+                    <field name="withholding_move_id" />
                 </field>
             </field>
         </record>


Follow ups