Merge lp:~therp-nl/banking-addons/ba61-company_awareness_bank_import_settings into lp:banking-addons/6.1

Proposed by Stefan Rijnhart (Opener)
Status: Merged
Merged at revision: 160
Proposed branch: lp:~therp-nl/banking-addons/ba61-company_awareness_bank_import_settings
Merge into: lp:banking-addons/6.1
Diff against target: 192 lines (+97/-37)
2 files modified
account_banking/account_banking.py (+74/-28)
account_banking/account_banking_view.xml (+23/-9)
To merge this branch: bzr merge lp:~therp-nl/banking-addons/ba61-company_awareness_bank_import_settings
Reviewer Review Type Date Requested Status
Alexandre Fayolle - camptocamp code review, no test Approve
Guewen Baconnier @ Camptocamp no test, code review Approve
Review via email: mp+145023@code.launchpad.net

Description of the change

This branch adds company awareness when configuring bank statement import settings. Accounts, journals and bank accounts are now filtered by the company setting on the payment mode. Only bank accounts from the company's partner can be selected. Upon selection of the bank account, the associated journal is selected automatically.

To post a comment you must log in.
Revision history for this message
Guewen Baconnier @ Camptocamp (gbaconnier-c2c) wrote :

LGTM

review: Approve (no test, code review)
Revision history for this message
Alexandre Fayolle - camptocamp (alexandre-fayolle-c2c) wrote :

nitpicking (line numbers refer the to preview diff)

line 8: missing space after colon

line 29: it looks like all other methods in that file use "cr" as argument name. Time to make this one conform with the convention?

line 35-38: this is verging on abuse, IMO. I much prefer something like

if user['company_id']:
    return user['company_id'][0]
else:
    company_ids = self.pool.get('res.company').search(
                         cursor, uid, [('parent_id', '=', False)])
    return company_ids[0]

in the XML, I think using '!=' rather than '<>' is much nicer

Nothing blocking in the above.

review: Approve (code review, no test)
157. By Stefan Rijnhart (Opener)

[RFR] Style as per review

Revision history for this message
Stefan Rijnhart (Opener) (stefan-opener) wrote :

Hi Alexandre,

thank you for the style notes. I followed them up only with a slight variation in the return statements of _default_company(). Additionally, I removed the void company_id keyword argument to this method.

Revision history for this message
Alexandre Fayolle - camptocamp (alexandre-fayolle-c2c) wrote :

> Hi Alexandre,
>
> thank you for the style notes. I followed them up only with a slight variation
> in the return statements of _default_company(). Additionally, I removed the
> void company_id keyword argument to this method.

Thanks a lot for taking my contribution into account.

Indeed, no one seems to pass that argument...

As for the return statement, there are way too many "X and Y or Z" in openerp related code. I understand the historical context, the need for a single statement in many places. IMO when a single statement is not mandatory (e.g. in a return statement) the full blown if: else: construct should be prefered. In other case, I would like to see a generalisation of the use of Python's ternary operator (Y if X else Z) which does not feature the pitfall of "X and Y or Z" (which returns Z if X is true and Y is false). I'm not asking for this in my reviews unless I spot a case where Y can be false. Do you have an opinion on this?

Revision history for this message
Stefan Rijnhart (Opener) (stefan-opener) wrote :

Not really, no. But I would be happy to follow any set of best practices that the community can agree on. I was surprised that I could not find a general Python style guide on this, apart from a short statent in Google's [1]

[1] http://google-styleguide.googlecode.com/svn/trunk/pyguide.html?showone=Conditional_Expressions#Conditional_Expressions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'account_banking/account_banking.py'
2--- account_banking/account_banking.py 2012-12-15 15:19:49 +0000
3+++ account_banking/account_banking.py 2013-01-30 11:37:19 +0000
4@@ -81,6 +81,10 @@
5 select=True, required=True),
6 'journal_id': fields.many2one('account.journal', 'Journal',
7 required=True),
8+ 'partner_id': fields.related(
9+ 'company_id', 'partner_id',
10+ type='many2one', relation='res.partner',
11+ string='Partner'),
12 'default_credit_account_id': fields.many2one(
13 'account.account', 'Default credit account', select=True,
14 help=('The account to use when an unexpected payment was signaled. '
15@@ -127,44 +131,59 @@
16 #),
17 }
18
19- def _default_company(self, cursor, uid, context=None):
20- user = self.pool.get('res.users').browse(cursor, uid, uid, context=context)
21- if user.company_id:
22- return user.company_id.id
23- company_ids = self.pool.get('res.company').search(
24- cursor, uid, [('parent_id', '=', False)])
25- return len(company_ids) == 1 and company_ids[0] or False
26-
27- def _default_journal(self, cr, uid, context=None):
28- domain = [('type', '=', 'bank')]
29+ def _default_company(self, cr, uid, context=None):
30+ """
31+ Return the user's company or the first company found
32+ in the database
33+ """
34 user = self.pool.get('res.users').read(
35 cr, uid, uid, ['company_id'], context=context)
36 if user['company_id']:
37- domain.append(('company_id', '=', user['company_id'][0]))
38+ return user['company_id'][0]
39+ return self.pool.get('res.company').search(
40+ cr, uid, [('parent_id', '=', False)])[0]
41+
42+ def _default_partner_id(self, cr, uid, context=None, company_id=False):
43+ if not company_id:
44+ company_id = self._default_company(cr, uid, context=context)
45+ return self.pool.get('res.company').read(
46+ cr, uid, company_id, ['partner_id'],
47+ context=context)['partner_id'][0]
48+
49+ def _default_journal(self, cr, uid, context=None, company_id=False):
50+ if not company_id:
51+ company_id = self._default_company(cr, uid, context=context)
52 journal_ids = self.pool.get('account.journal').search(
53- cr, uid, domain)
54- return len(journal_ids) == 1 and journal_ids[0] or False
55-
56- def _default_partner_bank_id(self, cr, uid, context=None):
57- user = self.pool.get('res.users').read(
58- cr, uid, uid, ['company_id'], context=context)
59- if user['company_id']:
60- bank_ids = self.pool.get('res.partner.bank').search(
61- cr, uid, [('company_id', '=', user['company_id'][0])])
62- if len(bank_ids) == 1:
63- return bank_ids[0]
64- return False
65-
66- def _default_debit_account_id(self, cr, uid, context=None):
67+ cr, uid, [('type', '=', 'bank'), ('company_id', '=', company_id)])
68+ return journal_ids and journal_ids[0] or False
69+
70+ def _default_partner_bank_id(
71+ self, cr, uid, context=None, company_id=False):
72+ if not company_id:
73+ company_id = self._default_company(cr, uid, context=context)
74+ partner_id = self.pool.get('res.company').read(
75+ cr, uid, company_id, ['partner_id'], context=context)['partner_id'][0]
76+ bank_ids = self.pool.get('res.partner.bank').search(
77+ cr, uid, [('partner_id', '=', partner_id)], context=context)
78+ return bank_ids and bank_ids[0] or False
79+
80+ def _default_debit_account_id(
81+ self, cr, uid, context=None, company_id=False):
82+ localcontext = context and context.copy() or {}
83+ localcontext['force_company'] = (
84+ company_id or self._default_company(cr, uid, context=context))
85 account_def = self.pool.get('ir.property').get(
86 cr, uid, 'property_account_receivable',
87- 'res.partner', context=context)
88+ 'res.partner', context=localcontext)
89 return account_def and account_def.id or False
90
91- def _default_credit_account_id(self, cr, uid, context=None):
92+ def _default_credit_account_id(self, cr, uid, context=None, company_id=False):
93+ localcontext = context and context.copy() or {}
94+ localcontext['force_company'] = (
95+ company_id or self._default_company(cr, uid, context=context))
96 account_def = self.pool.get('ir.property').get(
97 cr, uid, 'property_account_payable',
98- 'res.partner', context=context)
99+ 'res.partner', context=localcontext)
100 return account_def and account_def.id or False
101
102 def find(self, cr, uid, journal_id, partner_bank_id=False, context=None):
103@@ -173,8 +192,35 @@
104 domain.append(('partner_bank_id','=',partner_bank_id))
105 return self.search(cr, uid, domain, context=context)
106
107+ def onchange_partner_bank_id(
108+ self, cr, uid, ids, partner_bank_id, context=None):
109+ values = {}
110+ if partner_bank_id:
111+ bank = self.pool.get('res.partner.bank').read(
112+ cr, uid, partner_bank_id, ['journal_id'], context=context)
113+ if bank['journal_id']:
114+ values['journal_id'] = bank['journal_id'][0]
115+ return {'value': values}
116+
117+ def onchange_company_id (
118+ self, cr, uid, ids, company_id=False, context=None):
119+ if not company_id:
120+ return {}
121+ result = {
122+ 'partner_id': self._default_partner_id(
123+ cr, uid, company_id=company_id, context=context),
124+ 'journal_id': self._default_journal(
125+ cr, uid, company_id=company_id, context=context),
126+ 'default_debit_account_id': self._default_debit_account_id(
127+ cr, uid, company_id=company_id, context=context),
128+ 'default_credit_account_id': self._default_credit_account_id(
129+ cr, uid, company_id=company_id, context=context),
130+ }
131+ return {'value': result}
132+
133 _defaults = {
134 'company_id': _default_company,
135+ 'partner_id': _default_partner_id,
136 'journal_id': _default_journal,
137 'default_debit_account_id': _default_debit_account_id,
138 'default_credit_account_id': _default_credit_account_id,
139
140=== modified file 'account_banking/account_banking_view.xml'
141--- account_banking/account_banking_view.xml 2012-05-02 14:28:52 +0000
142+++ account_banking/account_banking_view.xml 2013-01-30 11:37:19 +0000
143@@ -39,17 +39,31 @@
144 <field name="type">form</field>
145 <field name="arch" type="xml">
146 <form string="Default Import Settings for Bank Account">
147- <field name="company_id" />
148+ <field name="company_id"
149+ widget='selection'
150+ groups="base.group_multi_company"
151+ on_change="onchange_company_id(company_id)" />
152 <separator string="Bank Account Details" colspan="4" />
153- <field name="partner_bank_id" /> <!-- Needs domain for used companies /-->
154- <field name="journal_id" domain="[('type','=','bank')]" />
155+ <field name="partner_id" invisible="1"/>
156+ <field name="partner_bank_id"
157+ domain="[('partner_id', '=', partner_id)]"
158+ on_change="onchange_partner_bank_id(partner_bank_id)" />
159+ <field name="journal_id"
160+ domain="[('type','=','bank'),
161+ ('company_id', '=', company_id)]" />
162 <separator string="Default Accounts for Unknown Movements" colspan="4" />
163- <field name="default_credit_account_id" />
164- <field name="default_debit_account_id" />
165+ <field name="default_credit_account_id"
166+ domain="[('company_id', '=', company_id)]" />
167+ <field name="default_debit_account_id"
168+ domain="[('company_id', '=', company_id)]" />
169 <separator string="Generation of Bank Costs Invoices" colspan="4" />
170 <field name="bank_partner_id" />
171- <field name="costs_account_id" attrs="{'required': [('bank_partner_id', '&lt;&gt;', False)]}" />
172- <field name="invoice_journal_id" attrs="{'required': [('bank_partner_id', '&lt;&gt;', False)]}" />
173+ <field name="costs_account_id"
174+ attrs="{'required': [('bank_partner_id', '!=', False)]}"
175+ domain="[('company_id', '=', company_id)]" />
176+ <field name="invoice_journal_id"
177+ attrs="{'required': [('bank_partner_id', '!=', False)]}"
178+ domain="[('company_id', '=', company_id)]" />
179 </form>
180 </field>
181 </record>
182@@ -60,8 +74,8 @@
183 <field name="arch" type="xml">
184 <tree string="Default Import Settings for Bank Account">
185 <field name="company_id" />
186- <field name="partner_bank_id" /> <!-- Needs domain for used companies /-->
187- <field name="journal_id" domain="[('type','=','bank')]" />
188+ <field name="partner_bank_id" />
189+ <field name="journal_id" />
190 </tree>
191 </field>
192 </record>

Subscribers

People subscribed via source and target branches