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