[MERGE] account_voucher : Merged my branch to import partially paid invoice in the...
[odoo/odoo.git] / addons / l10n_ch / wizard / bvr_import.py
index c2f62ca..5fb7bda 100644 (file)
@@ -1,58 +1,46 @@
-# -*- coding: utf-8 -*-
-#
-#  bvr_import.py
-#  l10n_ch
-#
-#  Created by Nicolas Bessi based on Credric Krier contribution
-#
-#  Copyright (c) 2009 CamptoCamp. All rights reserved.
+# -*- encoding: utf-8 -*-
 ##############################################################################
-# WARNING: This program as such is intended to be used by professional
-# programmers who take the whole responsability of assessing all potential
-# consequences resulting from its eventual inadequacies and bugs
-# End users who are looking for a ready-to-use solution with commercial
-# garantees and support are strongly adviced to contract a Free Software
-# Service Company
 #
-# This program is Free Software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
+#    Author: Nicolas Bessi. Copyright Camptocamp SA
+#    Donors: Hasa Sàrl, Open Net Sàrl and Prisme Solutions Informatique SA
 #
-# 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 General Public License for more details.
+#    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.
 #
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#    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 base64
 import time
-from tools import mod10r
 import re
-from tools.translate import _
 
+from tools.translate import _
 from osv import osv, fields
+from tools import mod10r
 import pooler
 
-def _reconstruct_invoice_ref(cursor, user, reference, context):
+def _reconstruct_invoice_ref(cursor, user, reference, context=None):
     ###
     id_invoice = False
     # On fait d'abord une recherche sur toutes les factures
-    # we now searhc for company
-    user_obj=pooler.get_pool(cursor.dbname).get('res.users')
+    # we now search for an invoice
+    user_obj = pooler.get_pool(cursor.dbname).get('res.users')
     user_current=user_obj.browse(cursor, user, user)
 
     ##
     cursor.execute("SELECT inv.id,inv.number from account_invoice AS inv where inv.company_id = %s" ,(user_current.company_id.id,))
     result_invoice = cursor.fetchall()
-
+    REF = re.compile('[^0-9]')
     for inv_id,inv_name in result_invoice:
-        inv_name =  re.sub('[^0-9]', '0', str(inv_name))
+        inv_name =  REF.sub('0', str(inv_name))
         if inv_name == reference:
             id_invoice = inv_id
             break
@@ -68,23 +56,28 @@ def _reconstruct_invoice_ref(cursor, user, reference, context):
     else:
         return []
     return True
-def _import(obj, cursor, user, data, context):
-
-    pool = pooler.get_pool(cursor.dbname)
-    statement_line_obj = pool.get('account.bank.statement.line')
-    statement_reconcile_obj = pool.get('account.bank.statement.reconcile')
-    move_line_obj = pool.get('account.move.line')
-    property_obj = pool.get('ir.property')
-    model_fields_obj = pool.get('ir.model.fields')
-    attachment_obj = pool.get('ir.attachment')
+
+def _import(self, cursor, user, data, context=None):
+
+    statement_line_obj = self.pool.get('account.bank.statement.line')
+#    statement_reconcile_obj = pool.get('account.bank.statement.reconcile')
+    voucher_obj = self.pool.get('account.voucher')
+    voucher_line_obj = self.pool.get('account.voucher.line')
+    move_line_obj = self.pool.get('account.move.line')
+    property_obj = self.pool.get('ir.property')
+    model_fields_obj = self.pool.get('ir.model.fields')
+    attachment_obj = self.pool.get('ir.attachment')
+    statement_obj = self.pool.get('account.bank.statement')
+    property_obj = self.pool.get('ir.property')
     file = data['form']['file']
     statement_id = data['id']
-
     records = []
     total_amount = 0
     total_cost = 0
     find_total = False
 
+    if context is None:
+        context = {}
     for lines in base64.decodestring(file).split("\n"):
         # Manage files without carriage return
         while lines:
@@ -133,22 +126,9 @@ def _import(obj, cursor, user, data, context):
                 total_cost += record['cost']
                 records.append(record)
 
-    model_fields_ids = model_fields_obj.search(cursor, user, [
-        ('name', 'in', ['property_account_receivable', 'property_account_payable']),
-        ('model', '=', 'res.partner'),
-        ], context=context)
-    property_ids = property_obj.search(cursor, user, [
-        ('fields_id', 'in', model_fields_ids),
-        ('res_id', '=', False),
-        ], context=context)
-
     account_receivable = False
     account_payable = False
-    for property in property_obj.browse(cursor, user, property_ids, context=context):
-        if property.fields_id.name == 'property_account_receivable':
-            account_receivable = int(property.value.split(',')[1])
-        elif property.fields_id.name == 'property_account_payable':
-            account_payable = int(property.value.split(',')[1])
+    statement = statement_obj.browse(cursor, user, statement_id, context=context)
 
     for record in records:
         # Remove the 11 first char because it can be adherent number
@@ -162,46 +142,88 @@ def _import(obj, cursor, user, data, context):
             'type': (record['amount'] >= 0 and 'customer') or 'supplier',
             'statement_id': statement_id,
         }
+
         line_ids = move_line_obj.search(cursor, user, [
             ('ref', 'like', reference),
             ('reconcile_id', '=', False),
             ('account_id.type', 'in', ['receivable', 'payable']),
             ], order='date desc', context=context)
         if not line_ids:
-            line_ids = _reconstruct_invoice_ref(cursor,user,reference,None)
-
-        line2reconcile = False
+            line_ids = _reconstruct_invoice_ref(cursor, user, reference, None)
         partner_id = False
         account_id = False
         for line in move_line_obj.browse(cursor, user, line_ids, context=context):
-            if line.partner_id.id:
-                partner_id = line.partner_id.id
+            account_receivable = line.partner_id.property_account_receivable.id
+            account_payable = line.partner_id.property_account_payable.id
+            partner_id = line.partner_id.id
+            move_id = line.move_id.id
             if record['amount'] >= 0:
                 if round(record['amount'] - line.debit, 2) < 0.01:
-                    line2reconcile = line.id
+#                    line2reconcile = line.id
                     account_id = line.account_id.id
                     break
             else:
                 if round(line.credit + record['amount'], 2) < 0.01:
-                    line2reconcile = line.id
+#                    line2reconcile = line.id
                     account_id = line.account_id.id
                     break
+        result = voucher_obj.onchange_partner_id(cursor, user, [], partner_id, journal_id=statement.journal_id.id, price=abs(record['amount']), currency_id= statement.currency.id, ttype='receipt', date=statement.date ,context=context)
+        voucher_res = { 'type': 'receipt' ,
+
+             'name': values['name'],
+             'partner_id': partner_id,
+             'journal_id': statement.journal_id.id,
+             'account_id': result.get('account_id', statement.journal_id.default_credit_account_id.id),
+             'company_id': statement.company_id.id,
+             'currency_id': statement.currency.id,
+             'date': record['date'] or time.strftime('%Y-%m-%d'),
+             'amount': abs(record['amount']),
+            'period_id': statement.period_id.id
+             }
+        voucher_id = voucher_obj.create(cursor, user, voucher_res, context=context)
+        context.update({'move_line_ids': line_ids})
+        values['voucher_id'] = voucher_id
+        voucher_line_dict =  False
+        if result['value']['line_ids']:
+             for line_dict in result['value']['line_ids']:
+                 move_line = move_line_obj.browse(cursor, user, line_dict['move_line_id'], context)
+                 if move_id == move_line.move_id.id:
+                     voucher_line_dict = line_dict
+        if voucher_line_dict:
+             voucher_line_dict.update({'voucher_id':voucher_id})
+             voucher_line_obj.create(cursor, user, voucher_line_dict, context=context)                
+             
         if not account_id:
             if record['amount'] >= 0:
                 account_id = account_receivable
             else:
                 account_id = account_payable
-        if not account_id :
+        ##If line not linked to an invoice we create a line not linked to a voucher
+        if not account_id and not line_ids:
+            name = "property_account_receivable"
+            if record['amount'] < 0:
+                name = "property_account_payable"
+            prop = property_obj.search(
+                        cursor, 
+                        user,
+                        [
+                            ('name','=','property_account_receivable'),
+                            ('company_id','=',statement.company_id.id),
+                            ('res_id', '=', False)
+                        ]
+            )
+            if prop:
+                value = property_obj.read(cursor, user, prop[0], ['value_reference']).get('value_reference', False)
+                if value :
+                    account_id = int(value.split(',')[1])
+            else :
+                raise osv.except_osv(_('Error'),
+                    _('The properties account payable account receivable are not set'))
+        if not account_id and line_ids:
             raise osv.except_osv(_('Error'),
-                _('The properties account payable account receivable'))
+                _('The properties account payable account receivable are not set'))
         values['account_id'] = account_id
         values['partner_id'] = partner_id
-
-        if line2reconcile:
-            values['reconcile_id'] = statement_reconcile_obj.create(cursor, user, {
-                'line_ids': [(6, 0, [line2reconcile])],
-                }, context=context)
-
         statement_line_obj.create(cursor, user, values, context=context)
     attachment_obj.create(cursor, user, {
         'name': 'BVR',
@@ -210,14 +232,19 @@ def _import(obj, cursor, user, data, context):
         'res_model': 'account.bank.statement',
         'res_id': statement_id,
         }, context=context)
+
     return {}
 
 class bvr_import_wizard(osv.osv_memory):
-    _name='bvr.import.wizard'
-    _columns={'file':fields.binary('BVR File', required=True)}
-    
+    _name = 'bvr.import.wizard'
+    _columns = {
+        'file':fields.binary('BVR File', required=True)
+    }
+
     def import_bvr(self, cr, uid, ids, context=None):
-        data={}
+        data = {}
+        if context is None:
+            context = {}
         active_ids = context.get('active_ids', [])
         active_id = context.get('active_id', False)
         data['form'] = {}
@@ -227,8 +254,9 @@ class bvr_import_wizard(osv.osv_memory):
         res = self.read(cr, uid, ids[0], ['file'])
         if res:
             data['form']['file'] = res['file']
-        _import(self, cr, uid, data, context)
+        _import(self, cr, uid, data, context=context)
         return {}
+
 bvr_import_wizard()
 
 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: