1 # -*- coding: utf-8 -*-
6 # Created by Nicolas Bessi based on Credric Krier contribution
8 # Copyright (c) 2009 CamptoCamp. All rights reserved.
9 ##############################################################################
10 # WARNING: This program as such is intended to be used by professional
11 # programmers who take the whole responsability of assessing all potential
12 # consequences resulting from its eventual inadequacies and bugs
13 # End users who are looking for a ready-to-use solution with commercial
14 # garantees and support are strongly adviced to contract a Free Software
17 # This program is Free Software; you can redistribute it and/or
18 # modify it under the terms of the GNU General Public License
19 # as published by the Free Software Foundation; either version 2
20 # of the License, or (at your option) any later version.
22 # This program is distributed in the hope that it will be useful,
23 # but WITHOUT ANY WARRANTY; without even the implied warranty of
24 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 # GNU General Public License for more details.
27 # You should have received a copy of the GNU General Public License
28 # along with this program; if not, write to the Free Software
29 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 ##############################################################################
36 from tools import mod10r
38 from tools.translate import _
40 ASK_FORM = """<?xml version="1.0"?>
41 <form string="BVR Import">
53 def _reconstruct_invoice_ref(cursor, user, reference, context):
56 # On fait d'abord une recherche sur toutes les factures
57 # we now searhc for company
58 user_obj=pooler.get_pool(cursor.dbname).get('res.users')
59 user_current=user_obj.browse(cursor, user, user)
62 cursor.execute("SELECT inv.id,inv.number from account_invoice AS inv where inv.company_id = %s" ,(user_current.company_id.id,))
63 result_invoice = cursor.fetchall()
65 for inv_id,inv_name in result_invoice:
66 inv_name = re.sub('[^0-9]', '0', str(inv_name))
67 if inv_name == reference:
71 cursor.execute('SELECT l.id ' \
72 'FROM account_move_line l, account_invoice i ' \
73 'WHERE l.move_id = i.move_id AND l.reconcile_id is NULL ' \
74 'AND i.id =ANY(%s)',([id_invoice],))
76 for id_line in cursor.fetchall():
77 inv_line.append(id_line[0])
82 def _import(obj, cursor, user, data, context):
84 pool = pooler.get_pool(cursor.dbname)
85 statement_line_obj = pool.get('account.bank.statement.line')
86 statement_reconcile_obj = pool.get('account.bank.statement.reconcile')
87 move_line_obj = pool.get('account.move.line')
88 property_obj = pool.get('ir.property')
89 model_fields_obj = pool.get('ir.model.fields')
90 attachment_obj = pool.get('ir.attachment')
91 file = data['form']['file']
92 statement_id = data['id']
99 for lines in base64.decodestring(file).split("\n"):
100 # Manage files without carriage return
102 (line, lines) = (lines[:128], lines[128:])
105 if line[0:3] in ('999', '995'):
107 raise wizard.except_wizard(_('Error'),
108 _('Too much total record found!'))
111 raise wizard.except_wizard(_('Error'),
112 _('Record found after total record!'))
113 amount = float(line[39:49]) + (float(line[49:51]) / 100)
114 cost = float(line[69:76]) + (float(line[76:78]) / 100)
119 if round(amount - total_amount, 2) >= 0.01 \
120 or round(cost - total_cost, 2) >= 0.01:
121 raise wizard.except_wizard(_('Error'),
122 _('Total record different from the computed!'))
123 if int(line[51:63]) != len(records):
124 raise wizard.except_wizard(_('Error'),
125 _('Number record different from the computed!'))
128 'reference': line[12:39],
129 'amount': float(line[39:47]) + (float(line[47:49]) / 100),
130 'date': time.strftime('%Y-%m-%d',
131 time.strptime(line[65:71], '%y%m%d')),
132 'cost': float(line[96:98]) + (float(line[98:100]) / 100),
135 if record['reference'] != mod10r(record['reference'][:-1]):
136 raise wizard.except_wizard(_('Error'),
137 _('Recursive mod10 is invalid for reference: %s') % \
141 record['amount'] *= -1
143 total_amount += record['amount']
144 total_cost += record['cost']
145 records.append(record)
147 model_fields_ids = model_fields_obj.search(cursor, user, [
148 ('name', 'in', ['property_account_receivable', 'property_account_payable']),
149 ('model', '=', 'res.partner'),
151 property_ids = property_obj.search(cursor, user, [
152 ('fields_id', 'in', model_fields_ids),
153 ('res_id', '=', False),
156 account_receivable = False
157 account_payable = False
158 for property in property_obj.browse(cursor, user, property_ids, context=context):
159 if property.fields_id.name == 'property_account_receivable':
160 account_receivable = int(property.value.split(',')[1])
161 elif property.fields_id.name == 'property_account_payable':
162 account_payable = int(property.value.split(',')[1])
164 for record in records:
165 # Remove the 11 first char because it can be adherent number
166 # TODO check if 11 is the right number
167 reference = record['reference'][11:-1].lstrip('0')
169 'name': 'IN '+ reference,
170 'date': record['date'],
171 'amount': record['amount'],
173 'type': (record['amount'] >= 0 and 'customer') or 'supplier',
174 'statement_id': statement_id,
176 line_ids = move_line_obj.search(cursor, user, [
177 ('ref', 'like', reference),
178 ('reconcile_id', '=', False),
179 ('account_id.type', 'in', ['receivable', 'payable']),
180 ], order='date desc', context=context)
182 line_ids = _reconstruct_invoice_ref(cursor,user,reference,None)
184 line2reconcile = False
187 for line in move_line_obj.browse(cursor, user, line_ids, context=context):
188 if line.partner_id.id:
189 partner_id = line.partner_id.id
190 if record['amount'] >= 0:
191 if round(record['amount'] - line.debit, 2) < 0.01:
192 line2reconcile = line.id
193 account_id = line.account_id.id
196 if round(line.credit + record['amount'], 2) < 0.01:
197 line2reconcile = line.id
198 account_id = line.account_id.id
201 if record['amount'] >= 0:
202 account_id = account_receivable
204 account_id = account_payable
206 raise wizard.except_wizard(_('Error'),
207 _('The properties account payable account receivable'))
208 values['account_id'] = account_id
209 values['partner_id'] = partner_id
212 values['reconcile_id'] = statement_reconcile_obj.create(cursor, user, {
213 'line_ids': [(6, 0, [line2reconcile])],
216 statement_line_obj.create(cursor, user, values, context=context)
217 attachment_obj.create(cursor, user, {
220 'datas_fname': 'BVR.txt',
221 'res_model': 'account.bank.statement',
222 'res_id': statement_id,
227 class BVRImport(wizard.interface):
234 'fields': ASK_FIELDS,
236 ('end', 'Cancel', 'gtk-cancel'),
237 ('import', 'Import', 'gtk-ok', True),
251 BVRImport('l10n_ch.bvr_import')
252 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: