Merge lp:~therp-nl/banking-addons/7.0-link_partner_wizard into lp:banking-addons
- 7.0-link_partner_wizard
- Merge into banking-addons-70
Proposed by
Stefan Rijnhart (Opener)
Status: | Merged |
---|---|
Merged at revision: | 167 |
Proposed branch: | lp:~therp-nl/banking-addons/7.0-link_partner_wizard |
Merge into: | lp:banking-addons |
Prerequisite: | lp:~therp-nl/banking-addons/ba7.0-manual_multi_match |
Diff against target: |
748 lines (+412/-117) 8 files modified
account_banking/__openerp__.py (+1/-0) account_banking/account_banking_view.xml (+14/-0) account_banking/banking_import_transaction.py (+102/-37) account_banking/wizard/__init__.py (+1/-0) account_banking/wizard/banking_transaction_wizard.py (+3/-3) account_banking/wizard/banktools.py (+65/-77) account_banking/wizard/link_partner.py (+179/-0) account_banking/wizard/link_partner.xml (+47/-0) |
To merge this branch: | bzr merge lp:~therp-nl/banking-addons/7.0-link_partner_wizard |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Holger Brunn (Therp) | code review, no test | Approve | |
Guewen Baconnier @ Camptocamp | code review, no test | Approve | |
Review via email: mp+161828@code.launchpad.net |
Commit message
[MIG] Forward port of lp:~therp-nl/banking-addons/6.1-link_partner_wizard
Description of the change
To post a comment you must log in.
Revision history for this message
Guewen Baconnier @ Camptocamp (gbaconnier-c2c) wrote : | # |
review:
Approve
(code review, no test)
Revision history for this message
Holger Brunn (Therp) (hbrunn) : | # |
review:
Approve
(code review, no test)
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'account_banking/__openerp__.py' |
2 | --- account_banking/__openerp__.py 2013-05-01 15:11:24 +0000 |
3 | +++ account_banking/__openerp__.py 2013-05-01 15:11:24 +0000 |
4 | @@ -41,6 +41,7 @@ |
5 | 'wizard/bank_import_view.xml', |
6 | 'account_banking_view.xml', |
7 | 'wizard/banking_transaction_wizard.xml', |
8 | + 'wizard/link_partner.xml', |
9 | 'workflow/account_invoice.xml', |
10 | ], |
11 | 'js': [ |
12 | |
13 | === modified file 'account_banking/account_banking_view.xml' |
14 | --- account_banking/account_banking_view.xml 2013-05-01 15:11:24 +0000 |
15 | +++ account_banking/account_banking_view.xml 2013-05-01 15:11:24 +0000 |
16 | @@ -236,6 +236,13 @@ |
17 | --> |
18 | <xpath expr="//field[@name='line_ids']/tree/field[@name='partner_id']" |
19 | position="after"> |
20 | + <field name="link_partner_ok" invisible="1" /> |
21 | + <button name="link_partner" |
22 | + string="Link partner" |
23 | + icon="terp-partner" |
24 | + type="object" |
25 | + attrs="{'invisible': [('link_partner_ok', '=', False)]}" |
26 | + /> |
27 | <!-- TODO set partner_id when partner_bank_id changes --> |
28 | <field name="partner_bank_id"/> |
29 | </xpath> |
30 | @@ -323,6 +330,13 @@ |
31 | <field name="name"/> |
32 | <field name="ref"/> |
33 | <field name="partner_id" on_change="onchange_partner_id(partner_id)"/> |
34 | + <field name="link_partner_ok" invisible="1" /> |
35 | + <button name="link_partner" |
36 | + string="Link partner" |
37 | + icon="terp-partner" |
38 | + type="object" |
39 | + attrs="{'invisible': [('link_partner_ok', '=', False)]}" |
40 | + /> |
41 | <!-- TODO set partner_id when partner_bank_id changes --> |
42 | <field name="partner_bank_id"/> |
43 | <field name="type" on_change="onchange_type(partner_id, type)"/> |
44 | |
45 | === modified file 'account_banking/banking_import_transaction.py' |
46 | --- account_banking/banking_import_transaction.py 2013-05-01 15:11:24 +0000 |
47 | +++ account_banking/banking_import_transaction.py 2013-05-01 15:11:24 +0000 |
48 | @@ -885,6 +885,9 @@ |
49 | i += 1 |
50 | continue |
51 | |
52 | + partner_banks = [] |
53 | + partner_ids = [] |
54 | + |
55 | # TODO: optimize by ordering transactions per company, |
56 | # and perform the stanza below only once per company. |
57 | # In that case, take newest transaction date into account |
58 | @@ -1027,6 +1030,7 @@ |
59 | if transaction.type == bt.STORNO and has_payment: |
60 | move_info = self._match_storno( |
61 | cr, uid, transaction, results['log'], context) |
62 | + |
63 | # Allow inclusion of generated bank invoices |
64 | if transaction.type == bt.BANK_COSTS: |
65 | lines = self._match_costs( |
66 | @@ -1038,7 +1042,6 @@ |
67 | if not [x for x in move_lines if x.id == line.id]: |
68 | move_lines.append(line) |
69 | partner_ids = [account_info.bank_partner_id.id] |
70 | - partner_banks = [] |
71 | else: |
72 | # Link remote partner, import account when needed |
73 | partner_banks = banktools.get_bank_accounts( |
74 | @@ -1048,47 +1051,28 @@ |
75 | if partner_banks: |
76 | partner_ids = [x.partner_id.id for x in partner_banks] |
77 | elif transaction.remote_owner: |
78 | - iban = sepa.IBAN(transaction.remote_account) |
79 | - if iban.valid: |
80 | - country_code = iban.countrycode |
81 | - elif transaction.remote_owner_country_code: |
82 | - country_code = transaction.remote_owner_country_code |
83 | - # fallback on the import parsers country code |
84 | - elif transaction.bank_country_code: |
85 | - country_code = transaction.bank_country_code |
86 | - elif company.partner_id and company.partner_id.country: |
87 | - country_code = company.partner_id.country.code |
88 | - else: |
89 | - country_code = None |
90 | - partner_id = banktools.get_or_create_partner( |
91 | + country_id = banktools.get_country_id( |
92 | + self.pool, cr, uid, transaction, context=context) |
93 | + partner_id = banktools.get_partner( |
94 | self.pool, cr, uid, transaction.remote_owner, |
95 | transaction.remote_owner_address, |
96 | transaction.remote_owner_postalcode, |
97 | transaction.remote_owner_city, |
98 | - country_code, results['log'], |
99 | - customer=transaction.transferred_amount > 0, |
100 | - supplier=transaction.transferred_amount < 0, |
101 | + country_id, results['log'], |
102 | context=context) |
103 | - if transaction.remote_account: |
104 | - partner_bank_id = banktools.create_bank_account( |
105 | - self.pool, cr, uid, partner_id, |
106 | - transaction.remote_account, |
107 | - transaction.remote_owner, |
108 | - transaction.remote_owner_address, |
109 | - transaction.remote_owner_city, |
110 | - country_code, results['log'], |
111 | - bic=transaction.remote_bank_bic |
112 | - ) |
113 | - partner_banks = partner_bank_obj.browse( |
114 | - cr, uid, [partner_bank_id] |
115 | - ) |
116 | - else: |
117 | - partner_bank_id = None |
118 | - partner_banks = [] |
119 | - partner_ids = [partner_id] |
120 | - else: |
121 | - partner_ids = [] |
122 | - partner_banks = [] |
123 | + if partner_id: |
124 | + partner_ids = [partner_id] |
125 | + if transaction.remote_account: |
126 | + partner_bank_id = banktools.create_bank_account( |
127 | + self.pool, cr, uid, partner_id, |
128 | + transaction.remote_account, |
129 | + transaction.remote_owner, |
130 | + transaction.remote_owner_address, |
131 | + transaction.remote_owner_city, |
132 | + country_id, bic=transaction.remote_bank_bic, |
133 | + context=context) |
134 | + partner_banks = partner_bank_obj.browse( |
135 | + cr, uid, [partner_bank_id], context=context) |
136 | |
137 | # Credit means payment... isn't it? |
138 | if (not move_info |
139 | @@ -1422,6 +1406,24 @@ |
140 | |
141 | class account_bank_statement_line(orm.Model): |
142 | _inherit = 'account.bank.statement.line' |
143 | + |
144 | + def _get_link_partner_ok( |
145 | + self, cr, uid, ids, name, args, context=None): |
146 | + """ |
147 | + Deliver the values of the function field that |
148 | + determines if the 'link partner' wizard is show on the |
149 | + bank statement line |
150 | + """ |
151 | + res = {} |
152 | + for line in self.browse(cr, uid, ids, context): |
153 | + res[line.id] = bool( |
154 | + line.state == 'draft' |
155 | + and not line.partner_id |
156 | + and line.import_transaction_id |
157 | + and line.import_transaction_id.remote_owner |
158 | + and line.import_transaction_id.remote_account) |
159 | + return res |
160 | + |
161 | _columns = { |
162 | 'import_transaction_id': fields.many2one( |
163 | 'banking.import.transaction', |
164 | @@ -1447,6 +1449,9 @@ |
165 | readonly=True, required=True), |
166 | 'parent_id': fields.many2one('account.bank.statement.line', |
167 | 'Parent'), |
168 | + 'link_partner_ok': fields.function( |
169 | + _get_link_partner_ok, type='boolean', |
170 | + string='Can link partner'), |
171 | } |
172 | |
173 | _defaults = { |
174 | @@ -1467,6 +1472,66 @@ |
175 | res = wizard_obj.create_act_window(cr, uid, res_id, context=context) |
176 | return res |
177 | |
178 | + def link_partner(self, cr, uid, ids, context=None): |
179 | + """ |
180 | + Get the appropriate partner or fire a wizard to create |
181 | + or link one |
182 | + """ |
183 | + if not ids: |
184 | + return False |
185 | + |
186 | + if isinstance(ids, (int, long)): |
187 | + ids = [ids] |
188 | + |
189 | + # Check if the partner is already known but not shown |
190 | + # because the screen was not refreshed yet |
191 | + statement_line = self.browse( |
192 | + cr, uid, ids[0], context=context) |
193 | + if statement_line.partner_id: |
194 | + return True |
195 | + |
196 | + # Reuse the bank's partner if any |
197 | + if (statement_line.partner_bank_id and |
198 | + statement_line.partner_bank_id.partner_id): |
199 | + statement_line.write( |
200 | + {'partner_id': statement_line.partner_bank_id.partner_id.id}) |
201 | + return True |
202 | + |
203 | + if (not statement_line.import_transaction_id or |
204 | + not statement_line.import_transaction_id.remote_account): |
205 | + raise osv.except_osv( |
206 | + _("Error"), |
207 | + _("No bank account available to link partner to")) |
208 | + |
209 | + # Check if the bank account was already been linked |
210 | + # manually to another transaction |
211 | + remote_account = statement_line.import_transaction_id.remote_account |
212 | + source_line_ids = self.search( |
213 | + cr, uid, |
214 | + [('import_transaction_id.remote_account', '=', remote_account), |
215 | + ('partner_bank_id.partner_id', '!=', False), |
216 | + ], limit=1, context=context) |
217 | + if source_line_ids: |
218 | + source_line = self.browse( |
219 | + cr, uid, source_line_ids[0], context=context) |
220 | + target_line_ids = self.search( |
221 | + cr, uid, |
222 | + [('import_transaction_id.remote_account', '=', remote_account), |
223 | + ('partner_bank_id', '=', False), |
224 | + ('state', '=', 'draft')], context=context) |
225 | + self.write( |
226 | + cr, uid, target_line_ids, |
227 | + {'partner_bank_id': source_line.partner_bank_id.id, |
228 | + 'partner_id': source_line.partner_bank_id.partner_id.id, |
229 | + }, context=context) |
230 | + return True |
231 | + |
232 | + # Or fire the wizard to link partner and account |
233 | + wizard_obj = self.pool.get('banking.link_partner') |
234 | + res_id = wizard_obj.create( |
235 | + cr, uid, {'statement_line_id': ids[0]}, context=context) |
236 | + return wizard_obj.create_act_window(cr, uid, res_id, context=context) |
237 | + |
238 | def _convert_currency( |
239 | self, cr, uid, from_curr_id, to_curr_id, from_amount, |
240 | round=False, date=None, context=None): |
241 | |
242 | === modified file 'account_banking/wizard/__init__.py' |
243 | --- account_banking/wizard/__init__.py 2013-05-01 15:11:24 +0000 |
244 | +++ account_banking/wizard/__init__.py 2013-05-01 15:11:24 +0000 |
245 | @@ -20,5 +20,6 @@ |
246 | ############################################################################## |
247 | import bank_import |
248 | import banking_transaction_wizard |
249 | +import link_partner |
250 | |
251 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
252 | |
253 | === modified file 'account_banking/wizard/banking_transaction_wizard.py' |
254 | --- account_banking/wizard/banking_transaction_wizard.py 2013-05-01 15:11:24 +0000 |
255 | +++ account_banking/wizard/banking_transaction_wizard.py 2013-05-01 15:11:24 +0000 |
256 | @@ -73,7 +73,7 @@ |
257 | Call the automatic matching routine for one or |
258 | more bank transactions |
259 | """ |
260 | - if isinstance(ids, (int, float)): |
261 | + if isinstance(ids, (int, long)): |
262 | ids = [ids] |
263 | import_transaction_obj = self.pool.get('banking.import.transaction') |
264 | trans_id = self.read( |
265 | @@ -276,7 +276,7 @@ |
266 | settings_pool = self.pool.get('account.banking.account.settings') |
267 | statement_pool = self.pool.get('account.bank.statement.line') |
268 | |
269 | - if isinstance(ids, (int, float)): |
270 | + if isinstance(ids, (int, long)): |
271 | ids = [ids] |
272 | |
273 | for wiz in self.browse(cr, uid, ids, context=context): |
274 | @@ -309,7 +309,7 @@ |
275 | return self.create_act_window(cr, uid, ids, context=None) |
276 | |
277 | def reverse_duplicate(self, cr, uid, ids, context=None): |
278 | - if isinstance(ids, (int, float)): |
279 | + if isinstance(ids, (int, long)): |
280 | ids = [ids] |
281 | transaction_obj = self.pool.get('banking.import.transaction') |
282 | for wiz in self.read( |
283 | |
284 | === modified file 'account_banking/wizard/banktools.py' |
285 | --- account_banking/wizard/banktools.py 2013-05-01 15:11:24 +0000 |
286 | +++ account_banking/wizard/banktools.py 2013-05-01 15:11:24 +0000 |
287 | @@ -26,7 +26,8 @@ |
288 | __all__ = [ |
289 | 'get_period', |
290 | 'get_bank_accounts', |
291 | - 'get_or_create_partner', |
292 | + 'get_partner', |
293 | + 'get_country_id', |
294 | 'get_company_bank_account', |
295 | 'create_bank_account', |
296 | ] |
297 | @@ -56,7 +57,7 @@ |
298 | ''' |
299 | # No need to search for nothing |
300 | if not account_number: |
301 | - return False |
302 | + return [] |
303 | |
304 | partner_bank_obj = pool.get('res.partner.bank') |
305 | bank_account_ids = partner_bank_obj.search(cursor, uid, [ |
306 | @@ -74,7 +75,7 @@ |
307 | _('Bank account %(account_no)s was not found in the database') |
308 | % dict(account_no=account_number) |
309 | ) |
310 | - return False |
311 | + return [] |
312 | return partner_bank_obj.browse(cursor, uid, bank_account_ids) |
313 | |
314 | def _has_attr(obj, attr): |
315 | @@ -85,11 +86,10 @@ |
316 | except KeyError: |
317 | return False |
318 | |
319 | -def get_or_create_partner(pool, cr, uid, name, address, postal_code, city, |
320 | - country_code, log, supplier=False, customer=False, |
321 | - context=None): |
322 | +def get_partner(pool, cr, uid, name, address, postal_code, city, |
323 | + country_id, log, context=None): |
324 | ''' |
325 | - Get or create the partner belonging to the account holders name <name> |
326 | + Get the partner belonging to the account holders name <name> |
327 | |
328 | If multiple partners are found with the same name, select the first and |
329 | add a warning to the import log. |
330 | @@ -99,16 +99,10 @@ |
331 | partner_obj = pool.get('res.partner') |
332 | partner_ids = partner_obj.search(cr, uid, [('name', 'ilike', name)], |
333 | context=context) |
334 | - country_id = False |
335 | if not partner_ids: |
336 | # Try brute search on address and then match reverse |
337 | criteria = [] |
338 | - if country_code: |
339 | - country_obj = pool.get('res.country') |
340 | - country_ids = country_obj.search( |
341 | - cr, uid, [('code', '=', country_code.upper())], |
342 | - context=context) |
343 | - country_id = country_ids and country_ids[0] or False |
344 | + if country_id: |
345 | criteria.append(('country_id', '=', country_id)) |
346 | if city: |
347 | criteria.append(('city', 'ilike', city)) |
348 | @@ -116,6 +110,11 @@ |
349 | criteria.append(('zip', 'ilike', postal_code)) |
350 | partner_search_ids = partner_obj.search( |
351 | cr, uid, criteria, context=context) |
352 | + if (not partner_search_ids and country_id): |
353 | + # Try again with country_id = False |
354 | + criteria[0] = ('country_id', '=', False) |
355 | + partner_search_ids = partner_obj.search( |
356 | + cr, uid, criteria, context=context) |
357 | key = name.lower() |
358 | partners = [] |
359 | for partner in partner_obj.read( |
360 | @@ -124,35 +123,11 @@ |
361 | partners.append(partner) |
362 | partners.sort(key=lambda x: len(x['name']), reverse=True) |
363 | partner_ids = [x['id'] for x in partners] |
364 | - if not partner_ids: |
365 | - if not country_id: |
366 | - user = pool.get('res.user').browse(cr, uid, uid, context=context) |
367 | - country_id = ( |
368 | - user.company_id.partner_id.country and |
369 | - user.company_id.partner_id.country.id or |
370 | - False |
371 | - ) |
372 | - partner_id = partner_obj.create( |
373 | - cr, uid, { |
374 | - 'name': name, |
375 | - 'active': True, |
376 | - 'comment': 'Generated from Bank Statements Import', |
377 | - 'street': address and address[0] or '', |
378 | - 'street2': len(address) > 1 and address[1] or '', |
379 | - 'city': city, |
380 | - 'zip': postal_code or '', |
381 | - 'country_id': country_id, |
382 | - 'is_company': True, |
383 | - 'supplier': supplier, |
384 | - 'customer': customer, |
385 | - }, context=context) |
386 | - else: |
387 | - if len(partner_ids) > 1: |
388 | - log.append( |
389 | - _('More than one possible match found for partner with ' |
390 | - 'name %(name)s') % {'name': name}) |
391 | - partner_id = partner_ids[0] |
392 | - return partner_id |
393 | + if len(partner_ids) > 1: |
394 | + log.append( |
395 | + _('More than one possible match found for partner with ' |
396 | + 'name %(name)s') % {'name': name}) |
397 | + return partner_ids and partner_ids[0] or False |
398 | |
399 | def get_company_bank_account(pool, cursor, uid, account_number, currency, |
400 | company, log): |
401 | @@ -283,19 +258,47 @@ |
402 | )) |
403 | return bank_id, country_id |
404 | |
405 | -def create_bank_account(pool, cursor, uid, partner_id, |
406 | +def get_country_id(pool, cr, uid, transaction, context=None): |
407 | + """ |
408 | + Derive a country id from the info on the transaction. |
409 | + |
410 | + :param transaction: browse record of a transaction |
411 | + :returns: res.country id or False |
412 | + """ |
413 | + |
414 | + country_code = False |
415 | + iban = sepa.IBAN(transaction.remote_account) |
416 | + if iban.valid: |
417 | + country_code = iban.countrycode |
418 | + elif transaction.remote_owner_country_code: |
419 | + country_code = transaction.remote_owner_country_code |
420 | + # fallback on the import parsers country code |
421 | + elif transaction.bank_country_code: |
422 | + country_code = transaction.bank_country_code |
423 | + if country_code: |
424 | + country_ids = pool.get('res.country').search( |
425 | + cr, uid, [('code', '=', country_code.upper())], |
426 | + context=context) |
427 | + country_id = country_ids and country_ids[0] or False |
428 | + if not country_id: |
429 | + company = transaction.statement_line_id.company_id |
430 | + if company.partner_id.country: |
431 | + country_id = company.partner_id.country.id |
432 | + return country_id |
433 | + |
434 | +def create_bank_account(pool, cr, uid, partner_id, |
435 | account_number, holder_name, address, city, |
436 | - country_code, log, bic=False, |
437 | - ): |
438 | + country_id, bic=False, |
439 | + context=None): |
440 | ''' |
441 | Create a matching bank account with this holder for this partner. |
442 | ''' |
443 | values = struct( |
444 | partner_id = partner_id, |
445 | owner_name = holder_name, |
446 | + country_id = country_id, |
447 | ) |
448 | bankcode = None |
449 | - country_obj = pool.get('res.country') |
450 | |
451 | # Are we dealing with IBAN? |
452 | iban = sepa.IBAN(account_number) |
453 | @@ -305,44 +308,29 @@ |
454 | values.acc_number = str(iban) |
455 | values.acc_number_domestic = iban.BBAN |
456 | bankcode = iban.bankcode + iban.countrycode |
457 | - country_code = iban.countrycode |
458 | - |
459 | - if not country_code: |
460 | - country = pool.get('res.partner').browse( |
461 | - cursor, uid, partner_id).country |
462 | - country_code = country.code |
463 | - country_id = country.id |
464 | else: |
465 | - if iban.valid: |
466 | - country_ids = country_obj.search(cursor, uid, |
467 | - [('code', '=', iban.countrycode)] |
468 | - ) |
469 | - else: |
470 | - country_ids = country_obj.search(cursor, uid, |
471 | - [('code', '=', country_code)] |
472 | - ) |
473 | - country_id = country_ids[0] |
474 | - |
475 | - account_info = False |
476 | - if not iban.valid: |
477 | # No, try to convert to IBAN |
478 | values.state = 'bank' |
479 | values.acc_number = values.acc_number_domestic = account_number |
480 | - if country_code in sepa.IBAN.countries: |
481 | - account_info = sepa.online.account_info(country_code, |
482 | - values.acc_number |
483 | - ) |
484 | - if account_info: |
485 | - values.acc_number = iban = account_info.iban |
486 | - values.state = 'iban' |
487 | - bankcode = account_info.code |
488 | - bic = account_info.bic |
489 | + |
490 | + if country_id: |
491 | + country_code = pool.get('res.country').read( |
492 | + cr, uid, country_id, ['code'], context=context)['code'] |
493 | + if country_code in sepa.IBAN.countries: |
494 | + account_info = sepa.online.account_info( |
495 | + country_code, values.acc_number) |
496 | + if account_info: |
497 | + values.acc_number = iban = account_info.iban |
498 | + values.state = 'iban' |
499 | + bankcode = account_info.code |
500 | + bic = account_info.bic |
501 | |
502 | if bic: |
503 | - values.bank = get_or_create_bank(pool, cursor, uid, bic)[0] |
504 | + values.bank = get_or_create_bank(pool, cr, uid, bic)[0] |
505 | values.bank_bic = bic |
506 | |
507 | # Create bank account and return |
508 | - return pool.get('res.partner.bank').create(cursor, uid, values) |
509 | + return pool.get('res.partner.bank').create( |
510 | + cr, uid, values, context=context) |
511 | |
512 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
513 | |
514 | === added file 'account_banking/wizard/link_partner.py' |
515 | --- account_banking/wizard/link_partner.py 1970-01-01 00:00:00 +0000 |
516 | +++ account_banking/wizard/link_partner.py 2013-05-01 15:11:24 +0000 |
517 | @@ -0,0 +1,179 @@ |
518 | +# -*- coding: utf-8 -*- |
519 | +############################################################################## |
520 | +# |
521 | +# Copyright (C) 2013 Therp BV (<http://therp.nl>). |
522 | +# All Rights Reserved |
523 | +# |
524 | +# This program is free software: you can redistribute it and/or modify |
525 | +# it under the terms of the GNU General Public License as published by |
526 | +# the Free Software Foundation, either version 3 of the License, or |
527 | +# (at your option) any later version. |
528 | +# |
529 | +# This program is distributed in the hope that it will be useful, |
530 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
531 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
532 | +# GNU General Public License for more details. |
533 | +# |
534 | +# You should have received a copy of the GNU General Public License |
535 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
536 | +# |
537 | +############################################################################## |
538 | + |
539 | +from openerp.osv import orm, fields |
540 | +from openerp.tools.translate import _ |
541 | +from openerp.addons.account_banking.wizard import banktools |
542 | + |
543 | +class link_partner(orm.TransientModel): |
544 | + _name = 'banking.link_partner' |
545 | + _description = 'Link partner' |
546 | + |
547 | + _columns = { |
548 | + 'name': fields.char( |
549 | + 'Create partner with name', size=128, required=True), |
550 | + 'supplier': fields.boolean('Supplier'), |
551 | + 'customer': fields.boolean('Customer'), |
552 | + 'partner_id': fields.many2one( |
553 | + 'res.partner', 'or link existing partner'), |
554 | + 'statement_line_id': fields.many2one( |
555 | + 'account.bank.statement.line', |
556 | + 'Statement line', required=True), |
557 | + 'remote_account': fields.char( |
558 | + 'Account number', size=24, readonly=True), |
559 | + # Partner values |
560 | + 'street': fields.char('Street', size=128), |
561 | + 'street2': fields.char('Street2', size=128), |
562 | + 'zip': fields.char('Zip', change_default=True, size=24), |
563 | + 'city': fields.char('City', size=128), |
564 | + 'state_id': fields.many2one("res.country.state", 'State'), |
565 | + 'country_id': fields.many2one('res.country', 'Country'), |
566 | + 'email': fields.char('Email', size=240), |
567 | + 'phone': fields.char('Phone', size=64), |
568 | + 'fax': fields.char('Fax', size=64), |
569 | + 'mobile': fields.char('Mobile', size=64), |
570 | + } |
571 | + |
572 | + def create(self, cr, uid, vals, context=None): |
573 | + """ |
574 | + Get default values from the transaction data |
575 | + on the statement line |
576 | + """ |
577 | + if vals and vals.get('statement_line_id'): |
578 | + statement_line_obj = self.pool.get('account.bank.statement.line') |
579 | + statement_line = statement_line_obj.browse( |
580 | + cr, uid, vals['statement_line_id'], context=context) |
581 | + transaction = statement_line.import_transaction_id |
582 | + |
583 | + if statement_line.partner_bank_id: |
584 | + raise orm.except_orm( |
585 | + _('Error'), |
586 | + _('Statement line is already linked to a bank account ')) |
587 | + |
588 | + if not(transaction and transaction.remote_owner |
589 | + and transaction.remote_account): |
590 | + raise orm.except_orm( |
591 | + _('Error'), |
592 | + _('No transaction data on statement line')) |
593 | + |
594 | + if 'supplier' not in vals and statement_line.amount < 0: |
595 | + vals['supplier'] = True |
596 | + if 'customer' not in vals and statement_line.amount > 0: |
597 | + vals['customer'] = True |
598 | + |
599 | + if not vals.get('street'): |
600 | + vals['street'] = transaction.remote_owner_address |
601 | + if not vals.get('street'): |
602 | + vals['city'] = transaction.remote_owner_city |
603 | + if not vals.get('country_id'): |
604 | + vals['country_id'] = banktools.get_country_id( |
605 | + self.pool, cr, uid, transaction, context=context) |
606 | + if not vals.get('name'): |
607 | + vals['name'] = transaction.remote_owner |
608 | + if not vals.get('remote_account'): |
609 | + vals['remote_account'] = transaction.remote_account |
610 | + |
611 | + return super(link_partner, self).create( |
612 | + cr, uid, vals, context=context) |
613 | + |
614 | + def update_partner_values(self, cr, uid, wizard, values, context=None): |
615 | + """ |
616 | + Updates the new partner values with the values from the wizard |
617 | + |
618 | + :param wizard: read record of wizard (with load='_classic_write') |
619 | + :param values: the dictionary of partner values that will be updated |
620 | + """ |
621 | + for field in ['name', |
622 | + 'street', |
623 | + 'street2', |
624 | + 'zip', |
625 | + 'country_id', |
626 | + 'state_id', |
627 | + 'phone', |
628 | + 'fax', |
629 | + 'mobile', |
630 | + 'email' |
631 | + ]: |
632 | + if wizard[field]: |
633 | + values[field] = wizard[field] |
634 | + return True |
635 | + |
636 | + def link_partner(self, cr, uid, ids, context=None): |
637 | + statement_line_obj = self.pool.get( |
638 | + 'account.bank.statement.line') |
639 | + wiz = self.browse(cr, uid, ids[0], context=context) |
640 | + |
641 | + if wiz.partner_id: |
642 | + partner_id = wiz.partner_id.id |
643 | + else: |
644 | + wiz_read = self.read( |
645 | + cr, uid, ids[0], context=context, load='_classic_write') |
646 | + partner_fields = self.pool.get( |
647 | + 'res.partner')._columns.keys() |
648 | + partner_vals = { |
649 | + 'is_company': True, |
650 | + 'type': 'default', |
651 | + } |
652 | + self.update_partner_values( |
653 | + cr, uid, wiz_read, partner_vals, context=context) |
654 | + partner_id = self.pool.get('res.partner').create( |
655 | + cr, uid, partner_vals, context=context) |
656 | + |
657 | + partner_bank_id = banktools.create_bank_account( |
658 | + self.pool, cr, uid, partner_id, |
659 | + wiz.remote_account, wiz.name, |
660 | + wiz.street, wiz.city, |
661 | + wiz.country_id and wiz.country_id.id or False, |
662 | + bic=wiz.statement_line_id.import_transaction_id.remote_bank_bic, |
663 | + context=context) |
664 | + |
665 | + statement_line_ids = statement_line_obj.search( |
666 | + cr, uid, |
667 | + [('import_transaction_id.remote_account', '=', wiz.remote_account), |
668 | + ('partner_bank_id', '=', False), |
669 | + ('state', '=', 'draft')], context=context) |
670 | + statement_line_obj.write( |
671 | + cr, uid, statement_line_ids, |
672 | + {'partner_bank_id': partner_bank_id, |
673 | + 'partner_id': partner_id}, context=context) |
674 | + |
675 | + return {'type': 'ir.actions.act_window_close'} |
676 | + |
677 | + def create_act_window(self, cr, uid, ids, nodestroy=True, context=None): |
678 | + """ |
679 | + Return a popup window for this model |
680 | + """ |
681 | + if isinstance(ids, (int, long)): |
682 | + ids = [ids] |
683 | + return { |
684 | + 'name': self._description, |
685 | + 'view_type': 'form', |
686 | + 'view_mode': 'form', |
687 | + 'res_model': self._name, |
688 | + 'domain': [], |
689 | + 'context': context, |
690 | + 'type': 'ir.actions.act_window', |
691 | + 'target': 'new', |
692 | + 'res_id': ids[0], |
693 | + 'nodestroy': nodestroy, |
694 | + } |
695 | + |
696 | + |
697 | |
698 | === added file 'account_banking/wizard/link_partner.xml' |
699 | --- account_banking/wizard/link_partner.xml 1970-01-01 00:00:00 +0000 |
700 | +++ account_banking/wizard/link_partner.xml 2013-05-01 15:11:24 +0000 |
701 | @@ -0,0 +1,47 @@ |
702 | +<?xml version="1.0" encoding="utf-8"?> |
703 | +<openerp> |
704 | + <data> |
705 | + <record model="ir.ui.view" id="link_partner_view"> |
706 | + <field name="name">Link partner wizard view</field> |
707 | + <field name="type">form</field> |
708 | + <field name="model">banking.link_partner</field> |
709 | + <field name="arch" type="xml"> |
710 | + <form string="Link partner"> |
711 | + <group colspan="4" col="6"> |
712 | + <field name="name" |
713 | + attrs="{'readonly': [('partner_id', '!=', False)]}" /> |
714 | + <field name="partner_id"/> |
715 | + <field name="remote_account" /> |
716 | + </group> |
717 | + <group colspan="4" |
718 | + string="Address" |
719 | + attrs="{'invisible': [('partner_id', '!=', False)]}"> |
720 | + <group colspan="2" col="2"> |
721 | + <field name="street"/> |
722 | + <field name="street2"/> |
723 | + <field name="zip"/> |
724 | + <field name="city"/> |
725 | + <field name="country_id"/> |
726 | + <field name="state_id"/> |
727 | + </group> |
728 | + <group colspan="2" col="2"> |
729 | + <field name="phone"/> |
730 | + <field name="fax"/> |
731 | + <field name="mobile"/> |
732 | + <field name="email" widget="email"/> |
733 | + </group> |
734 | + </group> |
735 | + <button icon="gtk-cancel" string="Cancel" special="cancel" /> |
736 | + <button icon="gtk-ok" string="Create partner" |
737 | + name="link_partner" type="object" |
738 | + attrs="{'invisible': [('partner_id', '!=', False)]}" |
739 | + /> |
740 | + <button icon="gtk-ok" string="Link existing partner" |
741 | + name="link_partner" type="object" |
742 | + attrs="{'invisible': [('partner_id', '==', False)]}" |
743 | + /> |
744 | + </form> |
745 | + </field> |
746 | + </record> |
747 | + </data> |
748 | +</openerp> |
LGTM