Merge lp:~therp-nl/banking-addons/6.1-link_partner_wizard into lp:banking-addons/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
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
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 :

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

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
=== modified file 'account_banking/__openerp__.py'
--- account_banking/__openerp__.py 2012-05-07 11:49:08 +0000
+++ account_banking/__openerp__.py 2013-04-29 08:25:30 +0000
@@ -45,6 +45,7 @@
45 'account_banking_view.xml',45 'account_banking_view.xml',
46 'account_banking_workflow.xml',46 'account_banking_workflow.xml',
47 'wizard/banking_transaction_wizard.xml',47 'wizard/banking_transaction_wizard.xml',
48 'wizard/link_partner.xml',
48 'workflow/account_invoice.xml',49 'workflow/account_invoice.xml',
49 ],50 ],
50 'demo_xml': [],51 'demo_xml': [],
5152
=== modified file 'account_banking/account_banking_view.xml'
--- account_banking/account_banking_view.xml 2013-04-25 08:15:21 +0000
+++ account_banking/account_banking_view.xml 2013-04-29 08:25:30 +0000
@@ -286,6 +286,13 @@
286 <field name="arch" type="xml">286 <field name="arch" type="xml">
287 <data>287 <data>
288 <xpath expr="/form/notebook/page/field[@name='line_ids']/tree/field[@name='partner_id']" position="after">288 <xpath expr="/form/notebook/page/field[@name='line_ids']/tree/field[@name='partner_id']" position="after">
289 <field name="link_partner_ok" invisible="1" />
290 <button name="link_partner"
291 string="Link partner"
292 icon="terp-partner"
293 type="object"
294 attrs="{'invisible': [('link_partner_ok', '=', False)]}"
295 />
289 <!-- TODO set partner_id when partner_bank_id changes -->296 <!-- TODO set partner_id when partner_bank_id changes -->
290 <field name="partner_bank_id"/>297 <field name="partner_bank_id"/>
291 </xpath>298 </xpath>
@@ -514,6 +521,13 @@
514 <field name="name"/>521 <field name="name"/>
515 <field name="ref"/>522 <field name="ref"/>
516 <field name="partner_id" on_change="onchange_partner_id(partner_id)"/>523 <field name="partner_id" on_change="onchange_partner_id(partner_id)"/>
524 <field name="link_partner_ok" invisible="1" />
525 <button name="link_partner"
526 string="Link partner"
527 icon="terp-partner"
528 type="object"
529 attrs="{'invisible': [('link_partner_ok', '=', False)]}"
530 />
517 <!-- TODO set partner_id when partner_bank_id changes -->531 <!-- TODO set partner_id when partner_bank_id changes -->
518 <field name="partner_bank_id"/>532 <field name="partner_bank_id"/>
519 <field name="type" on_change="onchange_type(partner_id, type)"/>533 <field name="type" on_change="onchange_type(partner_id, type)"/>
520534
=== modified file 'account_banking/banking_import_transaction.py'
--- account_banking/banking_import_transaction.py 2013-04-26 08:27:33 +0000
+++ account_banking/banking_import_transaction.py 2013-04-29 08:25:30 +0000
@@ -1134,6 +1134,9 @@
1134 i += 11134 i += 1
1135 continue1135 continue
1136 1136
1137 partner_banks = []
1138 partner_ids = []
1139
1137 # TODO: optimize by ordering transactions per company, 1140 # TODO: optimize by ordering transactions per company,
1138 # and perform the stanza below only once per company.1141 # and perform the stanza below only once per company.
1139 # In that case, take newest transaction date into account1142 # In that case, take newest transaction date into account
@@ -1277,6 +1280,7 @@
1277 if transaction.type == bt.STORNO:1280 if transaction.type == bt.STORNO:
1278 move_info = self._match_storno(1281 move_info = self._match_storno(
1279 cr, uid, transaction, results['log'], context)1282 cr, uid, transaction, results['log'], context)
1283
1280 # Allow inclusion of generated bank invoices1284 # Allow inclusion of generated bank invoices
1281 if transaction.type == bt.BANK_COSTS:1285 if transaction.type == bt.BANK_COSTS:
1282 lines = self._match_costs(1286 lines = self._match_costs(
@@ -1288,7 +1292,6 @@
1288 if not [x for x in move_lines if x.id == line.id]:1292 if not [x for x in move_lines if x.id == line.id]:
1289 move_lines.append(line)1293 move_lines.append(line)
1290 partner_ids = [account_info.bank_partner_id.id]1294 partner_ids = [account_info.bank_partner_id.id]
1291 partner_banks = []
1292 else:1295 else:
1293 # Link remote partner, import account when needed1296 # Link remote partner, import account when needed
1294 partner_banks = get_bank_accounts(1297 partner_banks = get_bank_accounts(
@@ -1298,44 +1301,28 @@
1298 if partner_banks:1301 if partner_banks:
1299 partner_ids = [x.partner_id.id for x in partner_banks]1302 partner_ids = [x.partner_id.id for x in partner_banks]
1300 elif transaction.remote_owner:1303 elif transaction.remote_owner:
1301 iban = sepa.IBAN(transaction.remote_account)1304 country_id = get_country_id(
1302 if iban.valid:1305 self.pool, cr, uid, transaction, context=context)
1303 country_code = iban.countrycode1306 partner_id = get_partner(
1304 elif transaction.remote_owner_country_code:
1305 country_code = transaction.remote_owner_country_code
1306 # fallback on the import parsers country code
1307 elif transaction.bank_country_code:
1308 country_code = transaction.bank_country_code
1309 elif company.partner_id and company.partner_id.country:
1310 country_code = company.partner_id.country.code
1311 else:
1312 country_code = None
1313 partner_id = get_or_create_partner(
1314 self.pool, cr, uid, transaction.remote_owner,1307 self.pool, cr, uid, transaction.remote_owner,
1315 transaction.remote_owner_address,1308 transaction.remote_owner_address,
1316 transaction.remote_owner_postalcode,1309 transaction.remote_owner_postalcode,
1317 transaction.remote_owner_city,1310 transaction.remote_owner_city,
1318 country_code, results['log'], context=context)1311 country_id, results['log'], context=context)
1319 if transaction.remote_account:1312 if partner_id:
1320 partner_bank_id = create_bank_account(1313 partner_ids = [partner_id]
1321 self.pool, cr, uid, partner_id,1314 if transaction.remote_account:
1322 transaction.remote_account,1315 partner_bank_id = create_bank_account(
1323 transaction.remote_owner, 1316 self.pool, cr, uid, partner_id,
1324 transaction.remote_owner_address,1317 transaction.remote_account,
1325 transaction.remote_owner_city,1318 transaction.remote_owner,
1326 country_code, results['log'],1319 transaction.remote_owner_address,
1327 bic=transaction.remote_bank_bic1320 transaction.remote_owner_city,
1328 )1321 country_id, bic=transaction.remote_bank_bic,
1329 partner_banks = partner_bank_obj.browse(1322 )
1330 cr, uid, [partner_bank_id]1323 partner_banks = partner_bank_obj.browse(
1331 )1324 cr, uid, [partner_bank_id]
1332 else:1325 )
1333 partner_bank_id = None
1334 partner_banks = []
1335 partner_ids = [partner_id]
1336 else:
1337 partner_ids = []
1338 partner_banks = []
13391326
1340 # Credit means payment... isn't it?1327 # Credit means payment... isn't it?
1341 if (not move_info1328 if (not move_info
@@ -1706,6 +1693,24 @@
17061693
1707class account_bank_statement_line(osv.osv):1694class account_bank_statement_line(osv.osv):
1708 _inherit = 'account.bank.statement.line'1695 _inherit = 'account.bank.statement.line'
1696
1697 def _get_link_partner_ok(
1698 self, cr, uid, ids, name, args, context=None):
1699 """
1700 Deliver the values of the function field that
1701 determines if the 'link partner' wizard is show on the
1702 bank statement line
1703 """
1704 res = {}
1705 for line in self.browse(cr, uid, ids, context):
1706 res[line.id] = bool(
1707 line.state == 'draft'
1708 and not line.partner_id
1709 and line.import_transaction_id
1710 and line.import_transaction_id.remote_owner
1711 and line.import_transaction_id.remote_account)
1712 return res
1713
1709 _columns = {1714 _columns = {
1710 'import_transaction_id': fields.many2one(1715 'import_transaction_id': fields.many2one(
1711 'banking.import.transaction', 1716 'banking.import.transaction',
@@ -1730,6 +1735,9 @@
1730 'state': fields.selection(1735 'state': fields.selection(
1731 [('draft', 'Draft'), ('confirmed', 'Confirmed')], 'State',1736 [('draft', 'Draft'), ('confirmed', 'Confirmed')], 'State',
1732 readonly=True, required=True),1737 readonly=True, required=True),
1738 'link_partner_ok': fields.function(
1739 _get_link_partner_ok, type='boolean',
1740 string='Can link partner'),
1733 }1741 }
17341742
1735 _defaults = {1743 _defaults = {
@@ -1750,6 +1758,66 @@
1750 res = wizard_obj.create_act_window(cr, uid, res_id, context=context)1758 res = wizard_obj.create_act_window(cr, uid, res_id, context=context)
1751 return res1759 return res
17521760
1761 def link_partner(self, cr, uid, ids, context=None):
1762 """
1763 Get the appropriate partner or fire a wizard to create
1764 or link one
1765 """
1766 if not ids:
1767 return False
1768
1769 if isinstance(ids, (int, long)):
1770 ids = [ids]
1771
1772 # Check if the partner is already known but not shown
1773 # because the screen was not refreshed yet
1774 statement_line = self.browse(
1775 cr, uid, ids[0], context=context)
1776 if statement_line.partner_id:
1777 return True
1778
1779 # Reuse the bank's partner if any
1780 if (statement_line.partner_bank_id and
1781 statement_line.partner_bank_id.partner_id):
1782 statement_line.write(
1783 {'partner_id': statement_line.partner_bank_id.partner_id.id})
1784 return True
1785
1786 if (not statement_line.import_transaction_id or
1787 not statement_line.import_transaction_id.remote_account):
1788 raise osv.except_osv(
1789 _("Error"),
1790 _("No bank account available to link partner to"))
1791
1792 # Check if the bank account was already been linked
1793 # manually to another transaction
1794 remote_account = statement_line.import_transaction_id.remote_account
1795 source_line_ids = self.search(
1796 cr, uid,
1797 [('import_transaction_id.remote_account', '=', remote_account),
1798 ('partner_bank_id.partner_id', '!=', False),
1799 ], limit=1, context=context)
1800 if source_line_ids:
1801 source_line = self.browse(
1802 cr, uid, source_line_ids[0], context=context)
1803 target_line_ids = self.search(
1804 cr, uid,
1805 [('import_transaction_id.remote_account', '=', remote_account),
1806 ('partner_bank_id', '=', False),
1807 ('state', '=', 'draft')], context=context)
1808 self.write(
1809 cr, uid, target_line_ids,
1810 {'partner_bank_id': source_line.partner_bank_id.id,
1811 'partner_id': source_line.partner_bank_id.partner_id.id,
1812 }, context=context)
1813 return True
1814
1815 # Or fire the wizard to link partner and account
1816 wizard_obj = self.pool.get('banking.link_partner')
1817 res_id = wizard_obj.create(
1818 cr, uid, {'statement_line_id': ids[0]}, context=context)
1819 return wizard_obj.create_act_window(cr, uid, res_id, context=context)
1820
1753 def _convert_currency(1821 def _convert_currency(
1754 self, cr, uid, from_curr_id, to_curr_id, from_amount,1822 self, cr, uid, from_curr_id, to_curr_id, from_amount,
1755 round=False, date=None, context=None):1823 round=False, date=None, context=None):
17561824
=== modified file 'account_banking/wizard/__init__.py'
--- account_banking/wizard/__init__.py 2011-12-19 12:03:32 +0000
+++ account_banking/wizard/__init__.py 2013-04-29 08:25:30 +0000
@@ -22,5 +22,6 @@
22import bank_payment_manual22import bank_payment_manual
23import account_payment_order23import account_payment_order
24import banking_transaction_wizard24import banking_transaction_wizard
25import link_partner
2526
26# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:27# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
2728
=== modified file 'account_banking/wizard/banking_transaction_wizard.py'
--- account_banking/wizard/banking_transaction_wizard.py 2012-12-01 18:31:34 +0000
+++ account_banking/wizard/banking_transaction_wizard.py 2013-04-29 08:25:30 +0000
@@ -71,7 +71,7 @@
71 Call the automatic matching routine for one or71 Call the automatic matching routine for one or
72 more bank transactions72 more bank transactions
73 """73 """
74 if isinstance(ids, (int, float)):74 if isinstance(ids, (int, long)):
75 ids = [ids]75 ids = [ids]
76 import_transaction_obj = self.pool.get('banking.import.transaction')76 import_transaction_obj = self.pool.get('banking.import.transaction')
77 trans_id = self.read(77 trans_id = self.read(
@@ -231,7 +231,7 @@
231 settings_pool = self.pool.get('account.banking.account.settings')231 settings_pool = self.pool.get('account.banking.account.settings')
232 statement_pool = self.pool.get('account.bank.statement.line')232 statement_pool = self.pool.get('account.bank.statement.line')
233233
234 if isinstance(ids, (int, float)):234 if isinstance(ids, (int, long)):
235 ids = [ids]235 ids = [ids]
236236
237 for wiz in self.browse(cr, uid, ids, context=context):237 for wiz in self.browse(cr, uid, ids, context=context):
@@ -258,7 +258,7 @@
258 return True258 return True
259259
260 def reverse_duplicate(self, cr, uid, ids, context=None):260 def reverse_duplicate(self, cr, uid, ids, context=None):
261 if isinstance(ids, (int, float)):261 if isinstance(ids, (int, long)):
262 ids = [ids]262 ids = [ids]
263 transaction_obj = self.pool.get('banking.import.transaction')263 transaction_obj = self.pool.get('banking.import.transaction')
264 for wiz in self.read(264 for wiz in self.read(
265265
=== modified file 'account_banking/wizard/banktools.py'
--- account_banking/wizard/banktools.py 2013-02-07 09:38:41 +0000
+++ account_banking/wizard/banktools.py 2013-04-29 08:25:30 +0000
@@ -28,7 +28,8 @@
28__all__ = [28__all__ = [
29 'get_period', 29 'get_period',
30 'get_bank_accounts',30 'get_bank_accounts',
31 'get_or_create_partner',31 'get_partner',
32 'get_country_id',
32 'get_company_bank_account',33 'get_company_bank_account',
33 'create_bank_account',34 'create_bank_account',
34]35]
@@ -89,7 +90,7 @@
89 '''90 '''
90 # No need to search for nothing91 # No need to search for nothing
91 if not account_number:92 if not account_number:
92 return False93 return []
9394
94 partner_bank_obj = pool.get('res.partner.bank')95 partner_bank_obj = pool.get('res.partner.bank')
95 bank_account_ids = partner_bank_obj.search(cursor, uid, [96 bank_account_ids = partner_bank_obj.search(cursor, uid, [
@@ -107,7 +108,7 @@
107 _('Bank account %(account_no)s was not found in the database')108 _('Bank account %(account_no)s was not found in the database')
108 % dict(account_no=account_number)109 % dict(account_no=account_number)
109 )110 )
110 return False111 return []
111 return partner_bank_obj.browse(cursor, uid, bank_account_ids)112 return partner_bank_obj.browse(cursor, uid, bank_account_ids)
112113
113def _has_attr(obj, attr):114def _has_attr(obj, attr):
@@ -118,10 +119,10 @@
118 except KeyError:119 except KeyError:
119 return False120 return False
120121
121def get_or_create_partner(pool, cr, uid, name, address, postal_code, city,122def get_partner(pool, cr, uid, name, address, postal_code, city,
122 country_code, log, context=None):123 country_id, log, context=None):
123 '''124 '''
124 Get or create the partner belonging to the account holders name <name>125 Get the partner belonging to the account holders name <name>
125126
126 If multiple partners are found with the same name, select the first and127 If multiple partners are found with the same name, select the first and
127 add a warning to the import log.128 add a warning to the import log.
@@ -131,16 +132,10 @@
131 partner_obj = pool.get('res.partner')132 partner_obj = pool.get('res.partner')
132 partner_ids = partner_obj.search(cr, uid, [('name', 'ilike', name)],133 partner_ids = partner_obj.search(cr, uid, [('name', 'ilike', name)],
133 context=context)134 context=context)
134 country_id = False
135 if not partner_ids:135 if not partner_ids:
136 # Try brute search on address and then match reverse136 # Try brute search on address and then match reverse
137 criteria = []137 criteria = []
138 if country_code:138 if country_id:
139 country_obj = pool.get('res.country')
140 country_ids = country_obj.search(
141 cr, uid, [('code', '=', country_code.upper())],
142 context=context)
143 country_id = country_ids and country_ids[0] or False
144 criteria.append(('address.country_id', '=', country_id))139 criteria.append(('address.country_id', '=', country_id))
145 if city:140 if city:
146 criteria.append(('address.city', 'ilike', city))141 criteria.append(('address.city', 'ilike', city))
@@ -148,6 +143,11 @@
148 criteria.append(('address.zip', 'ilike', postal_code))143 criteria.append(('address.zip', 'ilike', postal_code))
149 partner_search_ids = partner_obj.search(144 partner_search_ids = partner_obj.search(
150 cr, uid, criteria, context=context)145 cr, uid, criteria, context=context)
146 if (not partner_search_ids and country_id):
147 # Try again with country_id = False
148 criteria[0] = ('address.country_id', '=', False)
149 partner_search_ids = partner_obj.search(
150 cr, uid, criteria, context=context)
151 key = name.lower()151 key = name.lower()
152 partners = []152 partners = []
153 for partner in partner_obj.read(153 for partner in partner_obj.read(
@@ -156,31 +156,11 @@
156 partners.append(partner)156 partners.append(partner)
157 partners.sort(key=lambda x: len(x['name']), reverse=True)157 partners.sort(key=lambda x: len(x['name']), reverse=True)
158 partner_ids = [x['id'] for x in partners]158 partner_ids = [x['id'] for x in partners]
159 if not partner_ids:159 if len(partner_ids) > 1:
160 if not country_id:160 log.append(
161 user = pool.get('res.user').browse(cr, uid, uid, context=context)161 _('More than one possible match found for partner with '
162 country_id = (162 'name %(name)s') % {'name': name})
163 user.company_id.partner_id.country and 163 return partner_ids and partner_ids[0] or False
164 user.company_id.partner_id.country.id or
165 False
166 )
167 partner_id = partner_obj.create(cr, uid, dict(
168 name=name, active=True,
169 comment='Generated from Bank Statements Import',
170 address=[(0,0,{
171 'street': address and address[0] or '',
172 'street2': len(address) > 1 and address[1] or '',
173 'city': city,
174 'zip': postal_code or '',
175 'country_id': country_id,
176 })]), context=context)
177 else:
178 if len(partner_ids) > 1:
179 log.append(
180 _('More than one possible match found for partner with '
181 'name %(name)s') % {'name': name})
182 partner_id = partner_ids[0]
183 return partner_id
184164
185def get_company_bank_account(pool, cursor, uid, account_number, currency,165def get_company_bank_account(pool, cursor, uid, account_number, currency,
186 company, log):166 company, log):
@@ -311,19 +291,47 @@
311 ))291 ))
312 return bank_id, country_id292 return bank_id, country_id
313293
314def create_bank_account(pool, cursor, uid, partner_id,294def get_country_id(pool, cr, uid, transaction, context=None):
295 """
296 Derive a country id from the info on the transaction.
297
298 :param transaction: browse record of a transaction
299 :returns: res.country id or False
300 """
301
302 country_code = False
303 iban = sepa.IBAN(transaction.remote_account)
304 if iban.valid:
305 country_code = iban.countrycode
306 elif transaction.remote_owner_country_code:
307 country_code = transaction.remote_owner_country_code
308 # fallback on the import parsers country code
309 elif transaction.bank_country_code:
310 country_code = transaction.bank_country_code
311 if country_code:
312 country_ids = pool.get('res.country').search(
313 cr, uid, [('code', '=', country_code.upper())],
314 context=context)
315 country_id = country_ids and country_ids[0] or False
316 if not country_id:
317 company = transaction.statement_line_id.company_id
318 if company.partner_id.country:
319 country_id = company.partner_id.country.id
320 return country_id
321
322def create_bank_account(pool, cr, uid, partner_id,
315 account_number, holder_name, address, city,323 account_number, holder_name, address, city,
316 country_code, log, bic=False,324 country_id, bic=False,
317 ):325 context=None):
318 '''326 '''
319 Create a matching bank account with this holder for this partner.327 Create a matching bank account with this holder for this partner.
320 '''328 '''
321 values = struct(329 values = struct(
322 partner_id = partner_id,330 partner_id = partner_id,
323 owner_name = holder_name,331 owner_name = holder_name,
332 country_id = country_id,
324 )333 )
325 bankcode = None334 bankcode = None
326 country_obj = pool.get('res.country')
327335
328 # Are we dealing with IBAN?336 # Are we dealing with IBAN?
329 iban = sepa.IBAN(account_number)337 iban = sepa.IBAN(account_number)
@@ -333,44 +341,29 @@
333 values.acc_number = str(iban)341 values.acc_number = str(iban)
334 values.acc_number_domestic = iban.BBAN342 values.acc_number_domestic = iban.BBAN
335 bankcode = iban.bankcode + iban.countrycode343 bankcode = iban.bankcode + iban.countrycode
336 country_code = iban.countrycode
337
338 if not country_code:
339 country = pool.get('res.partner').browse(
340 cursor, uid, partner_id).country
341 country_code = country.code
342 country_id = country.id
343 else:344 else:
344 if iban.valid:
345 country_ids = country_obj.search(cursor, uid,
346 [('code', '=', iban.countrycode)]
347 )
348 else:
349 country_ids = country_obj.search(cursor, uid,
350 [('code', '=', country_code)]
351 )
352 country_id = country_ids[0]
353
354 account_info = False
355 if not iban.valid:
356 # No, try to convert to IBAN345 # No, try to convert to IBAN
357 values.state = 'bank'346 values.state = 'bank'
358 values.acc_number = values.acc_number_domestic = account_number347 values.acc_number = values.acc_number_domestic = account_number
359 if country_code in sepa.IBAN.countries:348
360 account_info = sepa.online.account_info(country_code,349 if country_id:
361 values.acc_number350 country_code = pool.get('res.country').read(
362 )351 cr, uid, country_id, ['code'], context=context)['code']
363 if account_info:352 if country_code in sepa.IBAN.countries:
364 values.acc_number = iban = account_info.iban353 account_info = sepa.online.account_info(
365 values.state = 'iban'354 country_code, values.acc_number)
366 bankcode = account_info.code355 if account_info:
367 bic = account_info.bic356 values.acc_number = iban = account_info.iban
357 values.state = 'iban'
358 bankcode = account_info.code
359 bic = account_info.bic
368360
369 if bic:361 if bic:
370 values.bank = get_or_create_bank(pool, cursor, uid, bic)[0]362 values.bank = get_or_create_bank(pool, cr, uid, bic)[0]
371 values.bank_bic = bic363 values.bank_bic = bic
372364
373 # Create bank account and return365 # Create bank account and return
374 return pool.get('res.partner.bank').create(cursor, uid, values)366 return pool.get('res.partner.bank').create(
367 cr, uid, values, context=context)
375368
376# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:369# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
377370
=== added file 'account_banking/wizard/link_partner.py'
--- account_banking/wizard/link_partner.py 1970-01-01 00:00:00 +0000
+++ account_banking/wizard/link_partner.py 2013-04-29 08:25:30 +0000
@@ -0,0 +1,157 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# Copyright (C) 2013 Therp BV (<http://therp.nl>).
5# All Rights Reserved
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation, either version 3 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21
22from openerp.osv import orm, fields
23from openerp.tools.translate import _
24from openerp.addons.account_banking.wizard import banktools
25
26class link_partner(orm.TransientModel):
27 _name = 'banking.link_partner'
28 _inherit = 'res.partner.address'
29 _description = 'Link partner'
30
31 _columns = {
32 'name': fields.char(
33 'Create partner with name', size=128, required=True),
34 'supplier': fields.boolean('Supplier'),
35 'customer': fields.boolean('Customer'),
36 'partner_id': fields.many2one(
37 'res.partner', 'or link existing partner'),
38 'statement_line_id': fields.many2one(
39 'account.bank.statement.line',
40 'Statement line', required=True),
41 'remote_account': fields.char(
42 'Account number', size=24, readonly=True),
43 }
44
45 def create(self, cr, uid, vals, context=None):
46 """
47 Get default values from the transaction data
48 on the statement line
49 """
50 if vals and vals.get('statement_line_id'):
51 statement_line_obj = self.pool.get('account.bank.statement.line')
52 statement_line = statement_line_obj.browse(
53 cr, uid, vals['statement_line_id'], context=context)
54 transaction = statement_line.import_transaction_id
55
56 if statement_line.partner_bank_id:
57 raise orm.except_orm(
58 _('Error'),
59 _('Statement line is already linked to a bank account '))
60
61 if not(transaction and transaction.remote_owner
62 and transaction.remote_account):
63 raise orm.except_orm(
64 _('Error'),
65 _('No transaction data on statement line'))
66
67 if 'supplier' not in vals and statement_line.amount < 0:
68 vals['supplier'] = True
69 if 'customer' not in vals and statement_line.amount > 0:
70 vals['customer'] = True
71
72 if not vals.get('street'):
73 vals['street'] = transaction.remote_owner_address
74 if not vals.get('street'):
75 vals['city'] = transaction.remote_owner_city
76 if not vals.get('country_id'):
77 vals['country_id'] = banktools.get_country_id(
78 self.pool, cr, uid, transaction, context=context)
79 if not vals.get('name'):
80 vals['name'] = transaction.remote_owner
81 if not vals.get('remote_account'):
82 vals['remote_account'] = transaction.remote_account
83
84 return super(link_partner, self).create(
85 cr, uid, vals, context=context)
86
87 def link_partner(self, cr, uid, ids, context=None):
88 statement_line_obj = self.pool.get(
89 'account.bank.statement.line')
90 wiz = self.browse(cr, uid, ids[0], context=context)
91
92 if wiz.partner_id:
93 partner_id = wiz.partner_id.id
94 else:
95 partner_id = self.pool.get('res.partner').create(
96 cr, uid, {
97 'name': wiz.name,
98 'customer': wiz.customer,
99 'supplier': wiz.supplier,
100 }, context=context)
101 wiz_read = self.read(
102 cr, uid, ids[0], context=context, load='_classic_write')
103 address_fields = self.pool.get(
104 'res.partner.address')._columns.keys()
105 address_vals = {}
106 for field in self._columns.keys():
107 # NB: wizard model contains 'partner_id' like the address
108 # but in this code path it is False
109 if field in address_fields:
110 address_vals[field] = wiz_read[field]
111 address_vals.update({
112 'partner_id': partner_id,
113 'type': 'default',
114 })
115 self.pool.get('res.partner.address').create(
116 cr, uid, address_vals, context=context)
117
118 partner_bank_id = banktools.create_bank_account(
119 self.pool, cr, uid, partner_id,
120 wiz.remote_account, wiz.name,
121 wiz.street, wiz.city,
122 wiz.country_id and wiz.country_id.id or False,
123 bic=wiz.statement_line_id.import_transaction_id.remote_bank_bic
124 )
125
126 statement_line_ids = statement_line_obj.search(
127 cr, uid,
128 [('import_transaction_id.remote_account', '=', wiz.remote_account),
129 ('partner_bank_id', '=', False),
130 ('state', '=', 'draft')], context=context)
131 statement_line_obj.write(
132 cr, uid, statement_line_ids,
133 {'partner_bank_id': partner_bank_id,
134 'partner_id': partner_id}, context=context)
135
136 return {'type': 'ir.actions.act_window_close'}
137
138 def create_act_window(self, cr, uid, ids, nodestroy=True, context=None):
139 """
140 Return a popup window for this model
141 """
142 if isinstance(ids, (int, long)):
143 ids = [ids]
144 return {
145 'name': self._description,
146 'view_type': 'form',
147 'view_mode': 'form',
148 'res_model': self._name,
149 'domain': [],
150 'context': context,
151 'type': 'ir.actions.act_window',
152 'target': 'new',
153 'res_id': ids[0],
154 'nodestroy': nodestroy,
155 }
156
157
0158
=== added file 'account_banking/wizard/link_partner.xml'
--- account_banking/wizard/link_partner.xml 1970-01-01 00:00:00 +0000
+++ account_banking/wizard/link_partner.xml 2013-04-29 08:25:30 +0000
@@ -0,0 +1,47 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data>
4 <record model="ir.ui.view" id="link_partner_view">
5 <field name="name">Link partner wizard view</field>
6 <field name="type">form</field>
7 <field name="model">banking.link_partner</field>
8 <field name="arch" type="xml">
9 <form string="Link partner">
10 <group colspan="4" col="6">
11 <field name="name"
12 attrs="{'readonly': [('partner_id', '!=', False)]}" />
13 <field name="partner_id"/>
14 <field name="remote_account" />
15 </group>
16 <group colspan="4"
17 string="Address"
18 attrs="{'invisible': [('partner_id', '!=', False)]}">
19 <group colspan="2" col="2">
20 <field name="street"/>
21 <field name="street2"/>
22 <field name="zip"/>
23 <field name="city"/>
24 <field name="country_id"/>
25 <field name="state_id"/>
26 </group>
27 <group colspan="2" col="2">
28 <field name="phone"/>
29 <field name="fax"/>
30 <field name="mobile"/>
31 <field name="email" widget="email"/>
32 </group>
33 </group>
34 <button icon="gtk-cancel" string="Cancel" special="cancel" />
35 <button icon="gtk-ok" string="Create partner"
36 name="link_partner" type="object"
37 attrs="{'invisible': [('partner_id', '!=', False)]}"
38 />
39 <button icon="gtk-ok" string="Link existing partner"
40 name="link_partner" type="object"
41 attrs="{'invisible': [('partner_id', '==', False)]}"
42 />
43 </form>
44 </field>
45 </record>
46 </data>
47</openerp>

Subscribers

People subscribed via source and target branches