Merge lp:~camptocamp/account-consolidation/account-consolidation-fix-mono-currency into lp:~account-core-editors/account-consolidation/7.0

Proposed by Nicolas Bessi - Camptocamp
Status: Merged
Merged at revision: 17
Proposed branch: lp:~camptocamp/account-consolidation/account-consolidation-fix-mono-currency
Merge into: lp:~account-core-editors/account-consolidation/7.0
Diff against target: 722 lines (+333/-129)
13 files modified
account_consolidation/__init__.py (+4/-3)
account_consolidation/__openerp__.py (+37/-38)
account_consolidation/account.py (+10/-7)
account_consolidation/account_move_line.py (+51/-0)
account_consolidation/account_move_line_view.xml (+30/-0)
account_consolidation/account_view.xml (+4/-3)
account_consolidation/analysis_view.xml (+39/-0)
account_consolidation/company.py (+14/-6)
account_consolidation/company_view.xml (+2/-1)
account_consolidation/consolidation_menu.xml (+3/-0)
account_consolidation/data.xml (+13/-0)
account_consolidation/wizard/consolidation_base.py (+11/-8)
account_consolidation/wizard/consolidation_consolidate.py (+115/-63)
To merge this branch: bzr merge lp:~camptocamp/account-consolidation/account-consolidation-fix-mono-currency
Reviewer Review Type Date Requested Status
Alexandre Fayolle - camptocamp code review, no test Approve
Guewen Baconnier @ Camptocamp Needs Fixing
Review via email: mp+151966@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Guewen Baconnier @ Camptocamp (gbaconnier-c2c) wrote :

Typo lines 36,37:
s/currency_vale/currency_value/

Apart that, the fix seems correct to me.

review: Needs Fixing
Revision history for this message
Nicolas Bessi - Camptocamp (nbessi-c2c-deactivatedaccount) wrote :

Hello,

Forget to merge a revision, here it is.

Revision history for this message
Nicolas Bessi - Camptocamp (nbessi-c2c-deactivatedaccount) wrote :

Frédéric has detected some side effect to be fixed

Revision history for this message
Nicolas Bessi - Camptocamp (nbessi-c2c-deactivatedaccount) wrote :

Add some fixes in lines generation.

Implement the hook to allows to manage consolidation difference.

Add some usability improvements:
-defaults value
-label improvement
-filtered view in move line
-missing tooltip

Add the possibility to group by subsidaries

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

> Add some fixes in lines generation.
>
> Implement the hook to allows to manage consolidation difference.
>
> Add some usability improvements:
> -defaults value
> -label improvement
> -filtered view in move line
> -missing tooltip
>
> Add the possibility to group by subsidaries

So what is the status of the MP? is it work in progress or can we review now?

Revision history for this message
Nicolas Bessi - Camptocamp (nbessi-c2c-deactivatedaccount) wrote :

It can be reviewed the status is not anymore "work in progress".

Regards

Nicolas

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

Can a renaming of consol_company_id be considered?

line 549: "if balance" I thing this could be wrong, because of rounding errors. Are you sure you don't need to use the rounding methods available in the framework, or float_is_zero + a precision here?

line 603: you can't return None in a "public" method which can be called from xmlrpc. Either return False, or rename the method.

review: Needs Fixing (code review, no test)
Revision history for this message
Nicolas Bessi - Camptocamp (nbessi-c2c-deactivatedaccount) wrote :

Hello,

Thanks for the review.

For the consol_company_id I agree with you it should be subsidary_id but I do not want to alter data model.

For the rounding your right. There is no mean to create consolidation line for difference < than 0.01. I will extend the test.

34. By Nicolas Bessi - Camptocamp

[FIX] None return in public function + conso. differences smaller than cent will not be generated

Revision history for this message
Nicolas Bessi - Camptocamp (nbessi-c2c-deactivatedaccount) wrote :

Add recommended fixes

Revision history for this message
Guewen Baconnier @ Camptocamp (gbaconnier-c2c) wrote :

0.01 does not represent the same amount according to the currency.
That's why the model res.currency has a method `is_zero`. This method uses `openerp.tools.float_is_zero` but uses the configuration of the currency for the precision.
Is it applicable here?

Revision history for this message
Nicolas Bessi - Camptocamp (nbessi-c2c-deactivatedaccount) wrote :

The goal of this function is to create the move line to manage rounding difference, transitory difference but when it is call the currency conversion has been done upstream and the move we want to adjust is already in "holding" currency.

But you remark is pertinent in the consolidate account method and I will keep it in mind when we will implement the support of auxiliay accounts split.

Revision history for this message
Guewen Baconnier @ Camptocamp (gbaconnier-c2c) wrote :

> The goal of this function is to create the move line to manage rounding
> difference, transitory difference but when it is call the currency conversion
> has been done upstream and the move we want to adjust is already in "holding"
> currency.

I don't speak about currency conversion.

You have to use `is_zero` on the holding's currency instead of `openerp.tools.float_is_zero`.

Here is the method I speak about:

    def is_zero(self, cr, uid, currency, amount):
        """Returns true if ``amount`` is small enough to be treated as
           zero according to ``currency``'s rounding rules.

           Warning: ``is_zero(amount1-amount2)`` is not always equivalent to
           ``compare_amounts(amount1,amount2) == 0``, as the former will round after
           computing the difference, while the latter will round before, giving
           different results for e.g. 0.006 and 0.002 at 2 digits precision.

           :param browse_record currency: currency for which we are rounding
           :param float amount: amount to compare with currency's zero
        """
        return float_is_zero(amount, precision_rounding=currency.rounding)

review: Needs Fixing
Revision history for this message
Nicolas Bessi - Camptocamp (nbessi-c2c-deactivatedaccount) wrote :

Ok I get your point.
Yep, this seems to be the correct solution.

35. By Nicolas Bessi - Camptocamp

[FIX] Consolidation difference uses currency is_zero instead of float_is_zero
+ small style cleanup in method

Revision history for this message
Nicolas Bessi - Camptocamp (nbessi-c2c-deactivatedaccount) wrote :

Consolidation difference uses currency is_zero instead of float_is_zero
+ small style cleanup in method

Revision history for this message
Alexandre Fayolle - camptocamp (alexandre-fayolle-c2c) :
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_consolidation/__init__.py'
2--- account_consolidation/__init__.py 2011-08-12 15:39:07 +0000
3+++ account_consolidation/__init__.py 2013-03-21 10:33:20 +0000
4@@ -1,3 +1,4 @@
5-import company
6-import account
7-import wizard
8+from . import company
9+from . import account
10+from . import account_move_line
11+from . import wizard
12
13=== modified file 'account_consolidation/__openerp__.py'
14--- account_consolidation/__openerp__.py 2013-01-04 13:09:21 +0000
15+++ account_consolidation/__openerp__.py 2013-03-21 10:33:20 +0000
16@@ -18,15 +18,12 @@
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18 #
19 ##############################################################################
20-
21-{
22- "name" : "Account Consolidation",
23- "version" : "1.0",
24- "author" : "Camptocamp",
25- 'license': 'AGPL-3',
26- "category" : "Generic Modules/Accounting",
27- "description":
28-"""
29+{"name": "Account Consolidation",
30+ "version": "1.0",
31+ "author": "Camptocamp",
32+ "license": "AGPL-3",
33+ "category": "Generic Modules/Accounting",
34+ "description": """
35 Account consolidation
36 =====================
37
38@@ -42,32 +39,34 @@
39 it can be found on the account-financial-tools_
40 project
41
42-.. _account-financial-tools: https://launchpad.net/account-financial-tools
43-
44-""",
45- "website": "http://www.camptocamp.com",
46- "depends" : [
47- 'base',
48- 'account',
49- 'account_reversal',
50- ],
51- "demo_xml" : [
52- 'demo/consolidation_demo.xml',
53- 'demo/chart_a_demo.xml',
54- 'demo/chart_b_demo.xml',
55- ],
56- "data" : [
57- 'company_view.xml',
58- 'account_view.xml',
59- 'wizard/consolidation_check_view.xml',
60- 'wizard/consolidation_consolidate_view.xml',
61- 'consolidation_menu.xml',
62- ],
63- 'test': [
64- 'test/test_data.yml',
65- 'test/consolidation_checks.yml',
66- 'test/consolidation_consolidate.yml',
67- ],
68- "active": False,
69- "installable": True,
70-}
71+.. _account-financial-tools: https://launchpad.net/account-financial-tools""",
72+
73+ "website": "http://www.camptocamp.com",
74+ "depends": ['base',
75+ 'account',
76+ 'account_reversal', # TODO check account_constraints compat.
77+ ],
78+
79+ "demo_xml": ['demo/consolidation_demo.xml',
80+ 'demo/chart_a_demo.xml',
81+ 'demo/chart_b_demo.xml',
82+ ],
83+
84+ "data": ['data.xml',
85+ 'account_move_line_view.xml',
86+ 'company_view.xml',
87+ 'account_view.xml',
88+ 'wizard/consolidation_check_view.xml',
89+ 'wizard/consolidation_consolidate_view.xml',
90+ 'consolidation_menu.xml',
91+ 'analysis_view.xml'
92+ ],
93+
94+ "test": ['test/test_data.yml',
95+ 'test/consolidation_checks.yml',
96+ 'test/consolidation_consolidate.yml',
97+ ],
98+
99+ "active": False,
100+ "installable": True,
101+ }
102
103=== modified file 'account_consolidation/account.py'
104--- account_consolidation/account.py 2013-01-04 14:34:13 +0000
105+++ account_consolidation/account.py 2013-03-21 10:33:20 +0000
106@@ -32,10 +32,12 @@
107 help="Currency rate type used on this account "
108 "for the consolidation. "
109 "Leave empty to use the rate type of the account type."),
110+
111 'consolidation_mode': fields.selection(
112 [('ytd', 'YTD'),
113 ('period', 'Period Movements')],
114- 'Consolidation Mode'),
115+ 'Consolidation Mode',
116+ help="This must be set on the holding company accounts only"),
117 }
118
119
120@@ -49,15 +51,16 @@
121 help="Currency rate type used on this account type "
122 "for the consolidation. "
123 "Leave empty to use the 'spot' rate type."),
124+
125 'consolidation_mode': fields.selection(
126 [('ytd', 'YTD'),
127 ('period', 'Period Movements')],
128- 'Consolidation Mode'),
129- }
130-
131- _defaults = {
132- 'consolidation_mode': 'ytd',
133- }
134+ 'Consolidation Mode',
135+ help="This must be set on the holding company accounts only"),
136+
137+ }
138+
139+ _defaults = {'consolidation_mode': 'ytd'}
140
141
142 class account_move(orm.Model):
143
144=== added file 'account_consolidation/account_move_line.py'
145--- account_consolidation/account_move_line.py 1970-01-01 00:00:00 +0000
146+++ account_consolidation/account_move_line.py 2013-03-21 10:33:20 +0000
147@@ -0,0 +1,51 @@
148+# -*- coding: utf-8 -*-
149+##############################################################################
150+#
151+# Author: Nicolas Bessi Guewen Baconnier
152+# Copyright 2011-2013 Camptocamp SA
153+#
154+# This program is free software: you can redistribute it and/or modify
155+# it under the terms of the GNU Affero General Public License as
156+# published by the Free Software Foundation, either version 3 of the
157+# License, or (at your option) any later version.
158+#
159+# This program is distributed in the hope that it will be useful,
160+# but WITHOUT ANY WARRANTY; without even the implied warranty of
161+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
162+# GNU Affero General Public License for more details.
163+#
164+# You should have received a copy of the GNU Affero General Public License
165+# along with this program. If not, see <http://www.gnu.org/licenses/>.
166+#
167+##############################################################################
168+
169+from openerp.osv import orm, fields
170+
171+
172+class AccountMoveLine(orm.Model):
173+ _inherit = 'account.move.line'
174+
175+ def _current_company(self, cursor, uid, ids, name, args, context=None):
176+ company_id = self.pool['res.company']._company_default_get(cursor, uid)
177+ curr_ids = self.search(cursor, uid, [('company_id', '=', company_id)])
178+ res = dict([(tid, tid in curr_ids) for tid in ids])
179+ return res
180+
181+
182+ def search_is_current_company(self, cursor, uid, obj, name, args, context=None):
183+ company_id = self.pool['res.company']._company_default_get(cursor, uid)
184+ res = self.search(cursor, uid, [('company_id', '=', company_id)])
185+ return [('id', 'in', res)]
186+
187+ _columns = {'consol_company_id': fields.related('move_id', 'consol_company_id',
188+ relation='res.company',
189+ type="many2one",
190+ string='Subsidaries',
191+ store=True, # for the group_by
192+ readonly=True),
193+
194+ 'is_current_company': fields.function(_current_company,
195+ string="Current company",
196+ type="boolean",
197+ fnct_search=search_is_current_company)
198+ }
199
200=== added file 'account_consolidation/account_move_line_view.xml'
201--- account_consolidation/account_move_line_view.xml 1970-01-01 00:00:00 +0000
202+++ account_consolidation/account_move_line_view.xml 2013-03-21 10:33:20 +0000
203@@ -0,0 +1,30 @@
204+<openerp>
205+ <data>
206+ <record id="view_move_line_tree" model="ir.ui.view">
207+ <field name="name">account.move.line.tree.conso</field>
208+ <field name="model">account.move.line</field>
209+ <field name="inherit_id" ref="account.view_move_line_tree"/>
210+ <field name="arch" type="xml">
211+ <field name="date" position="before">
212+ <field name="consol_company_id"
213+ groups="account_consolidation.consolidation_manager,account_consolidation.consolidation_user"/>
214+ <field name="is_current_company" invisible="1"/>
215+ </field>
216+ </field>
217+ </record>
218+
219+ <record id="view_account_move_line_filter" model="ir.ui.view">
220+ <field name="name">Journal Items conso</field>
221+ <field name="model">account.move.line</field>
222+ <field name="inherit_id" ref="account.view_account_move_line_filter"/>
223+ <field name="arch" type="xml">
224+ <filter string="Period" position="after">
225+ <filter string="Subsidaries"
226+ icon="terp-folder-green"
227+ context="{'group_by':'consol_company_id'}"
228+ groups="account_consolidation.consolidation_manager,account_consolidation.consolidation_user"/>
229+ </filter>
230+ </field>
231+ </record>
232+ </data>
233+</openerp>
234
235=== modified file 'account_consolidation/account_view.xml'
236--- account_consolidation/account_view.xml 2013-01-04 15:03:23 +0000
237+++ account_consolidation/account_view.xml 2013-03-21 10:33:20 +0000
238@@ -10,7 +10,7 @@
239 <field name="arch" type="xml">
240 <data>
241 <xpath expr="//field[@name='note']" position="after">
242- <group>
243+ <group groups="account_consolidation.consolidation_manager">
244 <separator string="Consolidation" colspan="2"/>
245 <field name="consolidation_rate_type_id" widget="selection"/>
246 <field name="consolidation_mode"/>
247@@ -28,7 +28,7 @@
248 <field name="type">form</field>
249 <field name="arch" type="xml">
250 <separator string="Description" position="before">
251- <group col="2" colspan="2">
252+ <group col="2" colspan="2" groups="account_consolidation.consolidation_manager">
253 <separator string="Consolidation" colspan="4"/>
254 <field name="consolidation_rate_type_id" widget="selection"/>
255 <field name="consolidation_mode"/>
256@@ -45,7 +45,8 @@
257 <field name="arch" type="xml">
258 <field name="company_id" position="after">
259 <field name="consol_company_id"
260- attrs="{'invisible': [('consol_company_id', '=', False)]}"/>
261+ attrs="{'invisible': [('consol_company_id', '=', False)]}"
262+ groups="account_consolidation.consolidation_manager,account_consolidation.consolidation_user"/>
263 </field>
264 </field>
265 </record>
266
267=== added file 'account_consolidation/analysis_view.xml'
268--- account_consolidation/analysis_view.xml 1970-01-01 00:00:00 +0000
269+++ account_consolidation/analysis_view.xml 2013-03-21 10:33:20 +0000
270@@ -0,0 +1,39 @@
271+<openerp>
272+ <data>
273+
274+ <menuitem id="menu_conso_entries"
275+ name="Consolidation Entries"
276+ parent="account.menu_finance"
277+ sequence="5"
278+ groups="account_consolidation.consolidation_manager,account_consolidation.consolidation_user"/>
279+
280+ <record id="action_account_moves_all_a" model="ir.actions.act_window">
281+ <field name="context">{'journal_type':'general'}</field>
282+ <field name="name">Journal Items</field>
283+ <field name="domain">[('is_current_company', '=', True)]</field>
284+ <field name="res_model">account.move.line</field>
285+ <field name="view_id" ref="account.view_move_line_tree"/>
286+ <field name="view_mode">tree_account_move_line_quickadd,form</field>
287+ <field name="help" type="html">
288+ <p class="oe_view_nocontent_create">
289+ Select the period and the journal you want to fill.
290+ </p><p>
291+ This view can be used by accountants in order to quickly record
292+ entries in OpenERP. If you want to record a supplier invoice,
293+ start by recording the line of the expense account. OpenERP
294+ will propose to you automatically the Tax related to this
295+ account and the counterpart "Account Payable".
296+ </p>
297+ </field>
298+ </record>
299+
300+ <menuitem
301+ action="action_account_moves_all_a"
302+ icon="STOCK_JUSTIFY_FILL"
303+ id="menu_action_account_moves_all"
304+ parent="menu_conso_entries"
305+ sequence="1"
306+ groups="account_consolidation.consolidation_manager,account_consolidation.consolidation_user"/>
307+
308+ </data>
309+</openerp>
310
311=== modified file 'account_consolidation/company.py'
312--- account_consolidation/company.py 2013-01-04 14:34:13 +0000
313+++ account_consolidation/company.py 2013-03-21 10:33:20 +0000
314@@ -25,9 +25,17 @@
315 class res_company(orm.Model):
316 _inherit = 'res.company'
317
318- _columns = {
319- 'consolidation_chart_account_id': fields.many2one(
320- 'account.account',
321- 'Chart of Accounts for Consolidation',
322- domain=[('parent_id', '=', False)]),
323- }
324+ _columns = {'consolidation_chart_account_id': fields.many2one(
325+ 'account.account',
326+ 'Chart of Accounts for Consolidation',
327+ domain=[('parent_id', '=', False)],
328+ help=("Current company root account"
329+ " to be used when consolidating")),
330+
331+ 'consolidation_diff_account_id': fields.many2one(
332+ 'account.account',
333+ 'Consolidation difference account',
334+ domain=[('type', '=', 'other')],
335+ help=("Conso. differences will be affected"
336+ " to this account"))
337+ }
338
339=== modified file 'account_consolidation/company_view.xml'
340--- account_consolidation/company_view.xml 2011-08-19 07:16:03 +0000
341+++ account_consolidation/company_view.xml 2013-03-21 10:33:20 +0000
342@@ -9,9 +9,10 @@
343 <field name="type">form</field>
344 <field name="arch" type="xml">
345 <page string="Configuration" position="inside">
346- <group col="2" colspan="2">
347+ <group col="2" colspan="2" groups="account_consolidation.consolidation_manager">
348 <separator string="Accounts Consolidation" colspan="2"/>
349 <field name="consolidation_chart_account_id" colspan="2"/>
350+ <field name="consolidation_diff_account_id" colspan="2"/>
351 </group>
352 </page>
353 </field>
354
355=== modified file 'account_consolidation/consolidation_menu.xml'
356--- account_consolidation/consolidation_menu.xml 2011-08-12 15:39:07 +0000
357+++ account_consolidation/consolidation_menu.xml 2013-03-21 10:33:20 +0000
358@@ -5,18 +5,21 @@
359 <menuitem
360 name="Consolidation"
361 parent="account.menu_finance_periodical_processing"
362+ groups="account_consolidation.consolidation_manager,account_consolidation.consolidation_user"
363 id="menu_consolidation"/>
364
365 <menuitem
366 name="Consolidation: Checks"
367 parent="menu_consolidation"
368 action="action_consolidation_checks"
369+ groups="account_consolidation.consolidation_manager,account_consolidation.consolidation_user"
370 id="menu_consolidation_checks"/>
371
372 <menuitem
373 name="Consolidation: Consolidate"
374 parent="menu_consolidation"
375 action="action_consolidation_consolidate"
376+ groups="account_consolidation.consolidation_manager,account_consolidation.consolidation_user"
377 id="menu_consolidation_consolidate"/>
378
379 </data>
380
381=== added file 'account_consolidation/data.xml'
382--- account_consolidation/data.xml 1970-01-01 00:00:00 +0000
383+++ account_consolidation/data.xml 2013-03-21 10:33:20 +0000
384@@ -0,0 +1,13 @@
385+<openerp>
386+ <data>
387+ <record id="consolidation_manager" model="res.groups">
388+ <field name="name">Consolidation manager</field>
389+ <field name="category_id" ref="base.module_category_accounting_and_finance"/>
390+ </record>
391+
392+ <record id="consolidation_user" model="res.groups">
393+ <field name="name">Consolidation user</field>
394+ <field name="category_id" ref="base.module_category_accounting_and_finance"/>
395+ </record>
396+ </data>
397+</openerp>
398
399=== modified file 'account_consolidation/wizard/consolidation_base.py'
400--- account_consolidation/wizard/consolidation_base.py 2013-01-09 09:31:39 +0000
401+++ account_consolidation/wizard/consolidation_base.py 2013-03-21 10:33:20 +0000
402@@ -28,11 +28,14 @@
403 _description = 'Common consolidation wizard. Intended to be inherited'
404
405 def _default_company(self, cr, uid, context=None):
406- user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
407- if user.company_id:
408- return user.company_id.id
409- return self.pool.get('res.company').search(
410- cr, uid, [('parent_id', '=', False)])[0]
411+ comp_obj = self.pool['res.company']
412+ return comp_obj._company_default_get(cr, uid)
413+
414+ def _default_chart(self, cr, uid, context=None):
415+ comp_obj = self.pool['res.company']
416+ comp_id = comp_obj._company_default_get(cr, uid)
417+ company = comp_obj.browse(cr, uid, comp_id)
418+ return company.consolidation_chart_account_id.id
419
420 _columns = {
421 'fiscalyear_id': fields.many2one(
422@@ -57,9 +60,9 @@
423 required=True)
424 }
425
426- _defaults = {
427- 'company_id': _default_company,
428- }
429+ _defaults = {'company_id': _default_company,
430+ 'holding_chart_account_id': _default_chart,
431+ }
432
433 def on_change_company_id(self, cr, uid, ids, company_id, context=None):
434 """
435
436=== modified file 'account_consolidation/wizard/consolidation_consolidate.py'
437--- account_consolidation/wizard/consolidation_consolidate.py 2013-01-09 09:51:45 +0000
438+++ account_consolidation/wizard/consolidation_consolidate.py 2013-03-21 10:33:20 +0000
439@@ -20,13 +20,22 @@
440 ##############################################################################
441
442 from openerp.osv import orm, fields
443+from openerp.osv.osv import except_osv
444 from openerp.tools.translate import _
445
446-
447 class account_consolidation_consolidate(orm.TransientModel):
448 _name = 'account.consolidation.consolidate'
449 _inherit = 'account.consolidation.base'
450
451+ def _default_journal(self, cr, uid, context=None):
452+ comp_obj = self.pool['res.company']
453+ journ_obj = self.pool['account.journal']
454+ comp_id = comp_obj._company_default_get(cr, uid)
455+ journal_id = journ_obj.search(cr, uid, [('company_id', '=', comp_id)], limit=1)
456+ if journal_id:
457+ return journal_id[0]
458+ return False
459+
460 _columns = {
461 'from_period_id': fields.many2one(
462 'account.period',
463@@ -35,19 +44,23 @@
464 help="Select the same period in 'from' and 'to' "
465 "if you want to proceed with a single period. "
466 "Start Period is ignored for Year To Date accounts."),
467+
468 'to_period_id': fields.many2one(
469 'account.period',
470 'End Period',
471 required=True,
472 help="The consolidation will be done at the very "
473 "last date of the selected period."),
474+
475 'journal_id': fields.many2one(
476 'account.journal', 'Journal', required=True),
477+
478 'target_move': fields.selection(
479 [('posted', 'All Posted Entries'),
480 ('all', 'All Entries')],
481 'Target Moves',
482 required=True),
483+
484 'subsidiary_ids': fields.many2many(
485 'res.company',
486 'account_conso_conso_comp_rel',
487@@ -57,9 +70,9 @@
488 required=True),
489 }
490
491- _defaults = {
492- 'target_move': 'posted'
493- }
494+ _defaults = {'target_move': 'posted',
495+ 'journal_id': _default_journal,
496+ }
497
498 def _check_periods_fy(self, cr, uid, ids, context=None):
499 if isinstance(ids, (int, long)):
500@@ -88,13 +101,13 @@
501 """
502 result = {}
503 period_obj = self.pool.get('account.period')
504- from_period = period_obj.browse(
505- cr, uid, from_period_id, context=context)
506+ from_period = period_obj.browse(cr, uid, from_period_id,
507+ context=context)
508 if not to_period_id:
509 result['to_period_id'] = from_period_id
510 else:
511- to_period = period_obj.browse(
512- cr, uid, to_period_id, context=context)
513+ to_period = period_obj.browse(cr, uid, to_period_id,
514+ context=context)
515 if to_period.date_start < from_period.date_start:
516 result['to_period_id'] = from_period_id
517
518@@ -155,13 +168,46 @@
519 context=context)
520 return subs_period_ids
521
522- def create_rate_difference_line(self, cr, uid, ids, move_id, context):
523- """
524- Placeholder for creation of a move line
525- for the gain/loss currency difference
526+ def create_rate_difference_line(self, cr, uid, ids, move_id, consolidation_mode, context):
527+ """
528+ We can have consolidation difference when a account is in YTD but in normal counterpart
529+ has a different setting.
530+ """
531+ move_obj = self.pool['account.move']
532+ move_line_obj = self.pool['account.move.line']
533+ currency_obj = self.pool['res.currency']
534+ move = move_obj.browse(cr, uid, move_id, context=context)
535
536- :param move_id: ID of the move
537- """
538+ if not move.line_id:
539+ return False
540+ diff_account = move.company_id.consolidation_diff_account_id
541+ if not diff_account:
542+ raise except_osv(_('Settings ERROR'),
543+ _('Please set the "Consolidation difference account"'
544+ ' in company %s') % move.company_id.name)
545+ debit = credit = 0.0
546+ for line in move.line_id:
547+ debit += line.debit
548+ credit += line.credit
549+ balance = debit - credit
550+ # We do not want to create counter parts for amount smaller than
551+ # "holding" company currency rounding policy.
552+ # As generated lines are in draft state, accountant will be able to manage
553+ # special cases
554+ move_is_balanced = currency_obj.is_zero(cr, uid, move.company_id.currency_id, balance)
555+ if not move_is_balanced:
556+ diff_vals = {'account_id': diff_account.id,
557+ 'move_id': move.id,
558+ 'journal_id': move.journal_id.id,
559+ 'period_id': move.period_id.id,
560+ 'company_id': move.company_id.id,
561+ 'date': move.date,
562+ 'debit': abs(balance) if balance < 0.0 else 0.0,
563+ 'credit': balance if balance > 0.0 else 0.0,
564+ 'name': _('Consolidation difference in mode %s') % consolidation_mode
565+ }
566+ return move_line_obj.create(cr, uid, diff_vals, context=context)
567+ return False
568
569 def consolidate_account(self, cr, uid, ids, consolidation_mode,
570 subsidiary_period_ids, state, move_id,
571@@ -193,14 +239,13 @@
572 currency_obj = self.pool.get('res.currency')
573
574 move = move_obj.browse(cr, uid, move_id, context=context)
575- holding_account = account_obj.browse(
576- cr, uid, holding_account_id, context=context)
577+ holding_account = account_obj.browse(cr, uid, holding_account_id,
578+ context=context)
579
580- subsidiary_account_id = account_obj.search(
581- cr, uid,
582- [('code', '=', holding_account.code),
583- ('company_id', '=', subsidiary_id)],
584- context=context)
585+ subsidiary_account_id = account_obj.search(cr, uid,
586+ [('code', '=', holding_account.code),
587+ ('company_id', '=', subsidiary_id)],
588+ context=context)
589
590 if not subsidiary_account_id:
591 # an account may exist on the holding and not in the subsidiaries,
592@@ -209,8 +254,8 @@
593
594 browse_ctx = dict(context, state=state, periods=subsidiary_period_ids)
595 # 1st item because the account's code is unique per company
596- subs_account = account_obj.browse(
597- cr, uid, subsidiary_account_id[0], context=browse_ctx)
598+ subs_account = account_obj.browse(cr, uid, subsidiary_account_id[0],
599+ context=browse_ctx)
600
601 vals = {
602 'name': _("Consolidation line in %s mode") % consolidation_mode,
603@@ -222,34 +267,34 @@
604 'date': move.date
605 }
606
607+ balance = subs_account.balance
608+ if not balance:
609+ return False
610 if (holding_account.company_currency_id.id ==
611 subs_account.company_currency_id.id):
612 vals.update({
613- 'debit': subs_account.debit,
614- 'credit': subs_account.credit,
615+ 'debit': balance if balance > 0.0 else 0.0,
616+ 'credit': abs(balance) if balance < 0.0 else 0.0,
617 })
618 else:
619- currency_rate_type = self._currency_rate_type(
620- cr, uid, ids, holding_account, context=context)
621+ currency_rate_type = self._currency_rate_type(cr, uid, ids,
622+ holding_account, context=context)
623
624- currency_value = currency_obj.compute(
625- cr, uid,
626- holding_account.company_currency_id.id,
627- subs_account.company_currency_id.id,
628- subs_account.balance,
629- currency_rate_type_from=False, # means spot
630- currency_rate_type_to=currency_rate_type,
631- context=context)
632+ currency_value = currency_obj.compute(cr, uid,
633+ holding_account.company_currency_id.id,
634+ subs_account.company_currency_id.id,
635+ balance,
636+ currency_rate_type_from=False, # means spot
637+ currency_rate_type_to=currency_rate_type,
638+ context=context)
639 vals.update({
640 'currency_id': subs_account.company_currency_id.id,
641 'amount_currency': subs_account.balance,
642- 'debit': currency_value > 0 and currency_value or 0.0,
643- 'credit': currency_value < 0 and -currency_value or 0.0
644+ 'debit': currency_value if currency_value > 0.0 else 0.0,
645+ 'credit': abs(currency_value) if currency_value < 0.0 else 0.0,
646 })
647
648- move_line_id = move_line_obj.create(cr, uid, vals, context=context)
649-
650- return move_line_id
651+ return move_line_obj.create(cr, uid, vals, context=context)
652
653 def reverse_moves(self, cr, uid, ids, subsidiary_id, journal_id,
654 reversal_date, context=None):
655@@ -265,12 +310,11 @@
656 list of IDs of the reversal moves
657 """
658 move_obj = self.pool.get('account.move')
659- reversed_ids = move_obj.search(
660- cr, uid,
661- [('journal_id', '=', journal_id),
662- ('to_be_reversed', '=', True),
663- ('consol_company_id', '=', subsidiary_id)],
664- context=context)
665+ reversed_ids = move_obj.search(cr, uid,
666+ [('journal_id', '=', journal_id),
667+ ('to_be_reversed', '=', True),
668+ ('consol_company_id', '=', subsidiary_id)],
669+ context=context)
670 reversal_ids = move_obj.create_reversals(
671 cr, uid, reversed_ids, reversal_date, context=context)
672 return reversed_ids, reversal_ids
673@@ -392,25 +436,33 @@
674 date=period.date_stop)
675 move_id = move_obj.create(cr, uid, move_vals, context=context)
676
677- move_line_ids = []
678 # create a move line per account
679+ has_move_line = False
680 for account in accounts:
681- move_line_ids.append(
682- self.consolidate_account(
683- cr, uid, ids,
684- consolidation_mode,
685- compute_period_ids,
686- form.target_move,
687- move_id,
688- account.id,
689- subsidiary.id,
690- context=context)
691- )
692-
693- self.create_rate_difference_line(
694- cr, uid, ids, move_id, context=context)
695-
696- locals()[consolidation_mode + '_move_ids'].append(move_id)
697+ m_id = self.consolidate_account(
698+ cr, uid, ids,
699+ consolidation_mode,
700+ compute_period_ids,
701+ form.target_move,
702+ move_id,
703+ account.id,
704+ subsidiary.id,
705+ context=context)
706+ if m_id:
707+ has_move_line = True
708+
709+ if has_move_line:
710+ self.create_rate_difference_line(cr, uid, ids,
711+ move_id, consolidation_mode, context=context)
712+ locals()[consolidation_mode + '_move_ids'].append(move_id)
713+
714+ else:
715+ # We delete created move if it has no line.
716+ # As move are generated in draft mode they will be no gap in
717+ # number if consolidation journal has correct settings.
718+ # I agree it can be more efficient but size of refactoring
719+ # is not in ressource scope
720+ move_obj.unlink(cr, uid, [move_id])
721
722 return ytd_move_ids, period_move_ids
723

Subscribers

People subscribed via source and target branches