Merge lp:~camptocamp/account-consolidation/7.0-account_consolidation-migr into lp:~account-core-editors/account-consolidation/7.0

Proposed by Guewen Baconnier @ Camptocamp
Status: Merged
Merge reported by: Joël Grand-Guillaume @ camptocamp
Merged at revision: not available
Proposed branch: lp:~camptocamp/account-consolidation/7.0-account_consolidation-migr
Merge into: lp:~account-core-editors/account-consolidation/7.0
Diff against target: 2360 lines (+873/-850)
12 files modified
account_consolidation/__openerp__.py (+36/-35)
account_consolidation/account.py (+47/-53)
account_consolidation/account_view.xml (+5/-5)
account_consolidation/company.py (+29/-40)
account_consolidation/demo/consolidation_demo.xml (+17/-19)
account_consolidation/test/consolidation_checks.yml (+4/-3)
account_consolidation/test/test_data.yml (+147/-147)
account_consolidation/wizard/consolidation_base.py (+186/-158)
account_consolidation/wizard/consolidation_check.py (+66/-84)
account_consolidation/wizard/consolidation_check_view.xml (+35/-24)
account_consolidation/wizard/consolidation_consolidate.py (+262/-252)
account_consolidation/wizard/consolidation_consolidate_view.xml (+39/-30)
To merge this branch: bzr merge lp:~camptocamp/account-consolidation/7.0-account_consolidation-migr
Reviewer Review Type Date Requested Status
Alexandre Fayolle - camptocamp Approve
Review via email: mp+142453@code.launchpad.net

Commit message

[MIGR] Migration of account_consolidation to OpenERP version 7.0

Description of the change

Migration of the 'account_consolidation' module.

Updated:

 * views
 * python formatting / style
 * tests
 * license changed from GPLv2 to AGPLv3

To post a comment you must log in.
Revision history for this message
Alexandre Fayolle - camptocamp (alexandre-fayolle-c2c) wrote :

992 + :param fyear_id: ID of the fiscal years to compare

-> if it is a single fiscal year, then s/years/year/. Otherwise, the arg should be renamed fyear_ids.

1758 + return account.user_type.consolidation_rate_type_id

-> I think you want to return account.user_type.consolidation_rate_type_id.id (according to the original code)

review: Needs Fixing (code review, no test)
26. By Guewen Baconnier @ Camptocamp

[FIX] unclear docstring

27. By Guewen Baconnier @ Camptocamp

[FIX] currency rate type should return an id instead of a browse record, fix the docstring as well

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

I fixed both issues.

You are right for the second one, it was a bug.

Thanks for your review!

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

OK for merge then

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'account_consolidation/__openerp__.py'
--- account_consolidation/__openerp__.py 2013-01-04 10:28:46 +0000
+++ account_consolidation/__openerp__.py 2013-01-09 09:53:22 +0000
@@ -1,47 +1,49 @@
1# -*- coding: utf-8 -*-1# -*- coding: utf-8 -*-
2##############################################################################2##############################################################################
3#3#
4# Copyright (c) 2011 Camptocamp SA (http://www.camptocamp.com)4# Author: Guewen Baconnier
5# All Right Reserved5# Copyright 2011-2013 Camptocamp SA
6#6#
7# Author : Guewen Baconnier (Camptocamp)7# This program is free software: you can redistribute it and/or modify
8#8# it under the terms of the GNU Affero General Public License as
9# WARNING: This program as such is intended to be used by professional9# published by the Free Software Foundation, either version 3 of the
10# programmers who take the whole responsability of assessing all potential10# License, or (at your option) any later version.
11# consequences resulting from its eventual inadequacies and bugs11#
12# End users who are looking for a ready-to-use solution with commercial12# This program is distributed in the hope that it will be useful,
13# garantees and support are strongly adviced to contract a Free Software13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# Service Company14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15#15# GNU Affero General Public License for more details.
16# This program is Free Software; you can redistribute it and/or16#
17# modify it under the terms of the GNU General Public License17# You should have received a copy of the GNU Affero General Public License
18# as published by the Free Software Foundation; either version 218# along with this program. If not, see <http://www.gnu.org/licenses/>.
19# of the License, or (at your option) any later version.
20#
21# This program is distributed in the hope that it will be useful,
22# but WITHOUT ANY WARRANTY; without even the implied warranty of
23# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24# GNU General Public License for more details.
25#
26# You should have received a copy of the GNU General Public License
27# along with this program; if not, write to the Free Software
28# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29#19#
30##############################################################################20##############################################################################
3121
32
33{22{
34 "name" : "Account Consolidation",23 "name" : "Account Consolidation",
35 "version" : "0.0",24 "version" : "1.0",
36 "author" : "Camptocamp",25 "author" : "Camptocamp",
26 'license': 'AGPL-3',
37 "category" : "Generic Modules/Accounting",27 "category" : "Generic Modules/Accounting",
38 "description":28 "description":
39"""29"""
40Account consolidation module. Coding in progress...30Account consolidation
4131=====================
42Some explanations to do...32
4333Introduction
44 - Difference between debit/credit is balanced on the debit/credit default account of the journal?34------------
35
36Consolidate chart of accounts on subsidiaries
37in a virtual chart of accounts of the holding.
38
39Installation
40------------
41The `account_reversal` module is required,
42it can be found on the account-financial-tools_
43project
44
45.. _account-financial-tools: https://launchpad.net/account-financial-tools
46
45""",47""",
46 "website": "http://www.camptocamp.com",48 "website": "http://www.camptocamp.com",
47 "depends" : [49 "depends" : [
@@ -49,13 +51,12 @@
49 'account',51 'account',
50 'account_reversal',52 'account_reversal',
51 ],53 ],
52 "init_xml" : [],
53 "demo_xml" : [54 "demo_xml" : [
54 'demo/consolidation_demo.xml',55 'demo/consolidation_demo.xml',
55 'demo/chart_a_demo.xml',56 'demo/chart_a_demo.xml',
56 'demo/chart_b_demo.xml',57 'demo/chart_b_demo.xml',
57 ],58 ],
58 "update_xml" : [59 "data" : [
59 'company_view.xml',60 'company_view.xml',
60 'account_view.xml',61 'account_view.xml',
61 'wizard/consolidation_check_view.xml',62 'wizard/consolidation_check_view.xml',
@@ -68,5 +69,5 @@
68 'test/consolidation_consolidate.yml',69 'test/consolidation_consolidate.yml',
69 ],70 ],
70 "active": False,71 "active": False,
71 "installable": False,72 "installable": True,
72}73}
7374
=== modified file 'account_consolidation/account.py'
--- account_consolidation/account.py 2011-08-29 14:04:57 +0000
+++ account_consolidation/account.py 2013-01-09 09:53:22 +0000
@@ -1,77 +1,71 @@
1# -*- coding: utf-8 -*-1# -*- coding: utf-8 -*-
2##############################################################################2##############################################################################
3#3#
4# Copyright (c) 2011 Camptocamp SA (http://www.camptocamp.com)4# Author: Guewen Baconnier
5#5# Copyright 2011-2013 Camptocamp SA
6# Author : Guewen Baconnier (Camptocamp)6#
7#7# This program is free software: you can redistribute it and/or modify
8# WARNING: This program as such is intended to be used by professional8# it under the terms of the GNU Affero General Public License as
9# programmers who take the whole responsability of assessing all potential9# published by the Free Software Foundation, either version 3 of the
10# consequences resulting from its eventual inadequacies and bugs10# License, or (at your option) any later version.
11# End users who are looking for a ready-to-use solution with commercial11#
12# garantees and support are strongly adviced to contract a Free Software12# This program is distributed in the hope that it will be useful,
13# Service Company13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14#14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# This program is Free Software; you can redistribute it and/or15# GNU Affero General Public License for more details.
16# modify it under the terms of the GNU General Public License16#
17# as published by the Free Software Foundation; either version 217# You should have received a copy of the GNU Affero General Public License
18# of the License, or (at your option) any later version.18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20# This program is distributed in the hope that it will be useful,
21# but WITHOUT ANY WARRANTY; without even the implied warranty of
22# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23# GNU General Public License for more details.
24#
25# You should have received a copy of the GNU General Public License
26# along with this program; if not, write to the Free Software
27# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28#19#
29##############################################################################20##############################################################################
3021
31from osv import osv, fields22from openerp.osv import orm, fields
3223
3324
34class account_account(osv.osv):25class account_account(orm.Model):
35 _inherit = 'account.account'26 _inherit = 'account.account'
3627
37 _columns = {28 _columns = {
38 'consolidation_rate_type_id': fields.many2one('res.currency.rate.type',29 'consolidation_rate_type_id': fields.many2one(
39 'Consolidation Currency Rate Type',30 'res.currency.rate.type',
40 help="Currency rate type used on this account for the consolidation, Leave empty to use the rate type of the account type."),31 'Consolidation Currency Rate Type',
41 'consolidation_mode': fields.selection([('', ''),32 help="Currency rate type used on this account "
42 ('ytd', 'YTD'),33 "for the consolidation. "
43 ('period', 'Period Movements'),34 "Leave empty to use the rate type of the account type."),
44 ],35 'consolidation_mode': fields.selection(
45 'Consolidation Mode'),36 [('ytd', 'YTD'),
37 ('period', 'Period Movements')],
38 'Consolidation Mode'),
46 }39 }
4740
48account_account()41
4942class account_account_type(orm.Model):
50
51class account_account_type(osv.osv):
52 _inherit = 'account.account.type'43 _inherit = 'account.account.type'
5344
54 _columns = {45 _columns = {
55 'consolidation_rate_type_id': fields.many2one('res.currency.rate.type',46 'consolidation_rate_type_id': fields.many2one(
56 'Consolidation Currency Rate Type',47 'res.currency.rate.type',
57 help="Currency rate type used on this account type for the consolidation, Leave empty to use the 'spot' rate type."),48 'Consolidation Currency Rate Type',
58 'consolidation_mode': fields.selection([('ytd', 'YTD'),49 help="Currency rate type used on this account type "
59 ('period', 'Period Movements'),],50 "for the consolidation. "
60 'Consolidation Mode'),51 "Leave empty to use the 'spot' rate type."),
52 'consolidation_mode': fields.selection(
53 [('ytd', 'YTD'),
54 ('period', 'Period Movements')],
55 'Consolidation Mode'),
61 }56 }
6257
63 _defaults = {58 _defaults = {
64 'consolidation_mode': 'ytd',59 'consolidation_mode': 'ytd',
65 }60 }
6661
67account_account_type()62
6863class account_move(orm.Model):
69
70class account_move(osv.osv):
71 _inherit = 'account.move'64 _inherit = 'account.move'
7265
73 _columns = {66 _columns = {
74 'consol_company_id': fields.many2one('res.company', 'Consolidated from Company', readonly=True),67 'consol_company_id': fields.many2one(
68 'res.company',
69 'Consolidated from Company',
70 readonly=True),
75 }71 }
76
77account_move()
7872
=== modified file 'account_consolidation/account_view.xml'
--- account_consolidation/account_view.xml 2011-08-29 14:04:57 +0000
+++ account_consolidation/account_view.xml 2013-01-09 09:53:22 +0000
@@ -9,8 +9,8 @@
9 <field name="type">form</field>9 <field name="type">form</field>
10 <field name="arch" type="xml">10 <field name="arch" type="xml">
11 <data>11 <data>
12 <xpath expr="/form/notebook/page[@string='General Information']/group[2]" position="after">12 <xpath expr="//field[@name='note']" position="after">
13 <group col="2" colspan="2">13 <group>
14 <separator string="Consolidation" colspan="2"/>14 <separator string="Consolidation" colspan="2"/>
15 <field name="consolidation_rate_type_id" widget="selection"/>15 <field name="consolidation_rate_type_id" widget="selection"/>
16 <field name="consolidation_mode"/>16 <field name="consolidation_mode"/>
@@ -20,7 +20,7 @@
20 </data>20 </data>
21 </field>21 </field>
22 </record>22 </record>
23 23
24 <record id="view_account_type_consolidation_form" model="ir.ui.view">24 <record id="view_account_type_consolidation_form" model="ir.ui.view">
25 <field name="name">account.account.type.consolidation.form</field>25 <field name="name">account.account.type.consolidation.form</field>
26 <field name="model">account.account.type</field>26 <field name="model">account.account.type</field>
@@ -44,11 +44,11 @@
44 <field name="type">form</field>44 <field name="type">form</field>
45 <field name="arch" type="xml">45 <field name="arch" type="xml">
46 <field name="company_id" position="after">46 <field name="company_id" position="after">
47 <field name="consol_company_id" attrs="{'invisible': [('consol_company_id', '=', False)]}"/>47 <field name="consol_company_id"
48 attrs="{'invisible': [('consol_company_id', '=', False)]}"/>
48 </field>49 </field>
49 </field>50 </field>
50 </record>51 </record>
5152
52 </data>53 </data>
53</openerp>54</openerp>
54
5555
=== modified file 'account_consolidation/company.py'
--- account_consolidation/company.py 2011-08-19 07:16:03 +0000
+++ account_consolidation/company.py 2013-01-09 09:53:22 +0000
@@ -1,44 +1,33 @@
1# -*- coding: utf-8 -*-1# -* coding: utf-8 -*-
2##############################################################################2##############################################################################
3#3#
4# Copyright (c) 2011 Camptocamp SA (http://www.camptocamp.com)4# Author: Guewen Baconnier
5# All Right Reserved5# Copyright 2011-2013 Camptocamp SA
6#6#
7# Author : Guewen Baconnier (Camptocamp)7# This program is free software: you can redistribute it and/or modify
8#8# it under the terms of the GNU Affero General Public License as
9# WARNING: This program as such is intended to be used by professional9# published by the Free Software Foundation, either version 3 of the
10# programmers who take the whole responsability of assessing all potential10# License, or (at your option) any later version.
11# consequences resulting from its eventual inadequacies and bugs11#
12# End users who are looking for a ready-to-use solution with commercial12# This program is distributed in the hope that it will be useful,
13# garantees and support are strongly adviced to contract a Free Software13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# Service Company14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15#15# GNU Affero General Public License for more details.
16# This program is Free Software; you can redistribute it and/or16#
17# modify it under the terms of the GNU General Public License17# You should have received a copy of the GNU Affero General Public License
18# as published by the Free Software Foundation; either version 218# along with this program. If not, see <http://www.gnu.org/licenses/>.
19# of the License, or (at your option) any later version.19#
20#20##############################################################################
21# This program is distributed in the hope that it will be useful,21
22# but WITHOUT ANY WARRANTY; without even the implied warranty of22from openerp.osv import orm, fields
23# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the23
24# GNU General Public License for more details.24
25#25class res_company(orm.Model):
26# You should have received a copy of the GNU General Public License
27# along with this program; if not, write to the Free Software
28# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29#
30##############################################################################
31
32from osv import osv, fields
33
34
35class res_company(osv.osv):
36 _inherit = 'res.company'26 _inherit = 'res.company'
3727
38 _columns = {28 _columns = {
39 'consolidation_chart_account_id': fields.many2one('account.account',29 'consolidation_chart_account_id': fields.many2one(
40 'Chart of Accounts for Consolidation',30 'account.account',
41 domain=[('parent_id', '=', False)]),31 'Chart of Accounts for Consolidation',
32 domain=[('parent_id', '=', False)]),
42 }33 }
43
44res_company()
4534
=== modified file 'account_consolidation/demo/consolidation_demo.xml'
--- account_consolidation/demo/consolidation_demo.xml 2012-04-18 14:35:42 +0000
+++ account_consolidation/demo/consolidation_demo.xml 2013-01-09 09:53:22 +0000
@@ -183,7 +183,7 @@
183 <field name="company_id" ref="subsidiary_a"/>183 <field name="company_id" ref="subsidiary_a"/>
184 </record>184 </record>
185185
186 <record id="period_b_1" model="account.period">186 <record id="period_b_1" model="account.period">
187 <field eval="'01/'+time.strftime('%Y')" name="code"/>187 <field eval="'01/'+time.strftime('%Y')" name="code"/>
188 <field eval="'01/'+time.strftime('%Y')" name="name"/>188 <field eval="'01/'+time.strftime('%Y')" name="name"/>
189 <field eval="True" name="special"/>189 <field eval="True" name="special"/>
@@ -292,25 +292,23 @@
292 <field name="company_id" ref="subsidiary_b"/>292 <field name="company_id" ref="subsidiary_b"/>
293 </record>293 </record>
294294
295 <record id="account_journal_sale0" model="account.journal">295 <record id="account_journal_sale0" model="account.journal">
296 <field name="code">SALE</field>296 <field name="code">SALE</field>
297 <field name="name">SALE</field>297 <field name="name">SALE</field>
298 <field name="view_id" ref="account.account_sp_journal_view"/>298 <field name="company_id" ref="account_consolidation.subsidiary_a"/>
299 <field name="company_id" ref="account_consolidation.subsidiary_a"/>299 <field name="sequence_id" ref="account.sequence_sale_journal"/>
300 <field name="sequence_id" ref="account.sequence_sale_journal"/>300 <field eval="1" name="allow_date"/>
301 <field eval="1" name="allow_date"/>301 <field name="type">sale</field>
302 <field name="type">sale</field>302 </record>
303 </record>
304303
305 <record id="account_journal_sale1" model="account.journal">304 <record id="account_journal_sale1" model="account.journal">
306 <field name="code">SALE</field>305 <field name="code">SALE</field>
307 <field name="name">SALE</field>306 <field name="name">SALE</field>
308 <field name="view_id" ref="account.account_sp_journal_view"/>307 <field name="company_id" ref="account_consolidation.subsidiary_b"/>
309 <field name="company_id" ref="account_consolidation.subsidiary_b"/>308 <field name="sequence_id" ref="account.sequence_sale_journal"/>
310 <field name="sequence_id" ref="account.sequence_sale_journal"/>309 <field eval="1" name="allow_date"/>
311 <field eval="1" name="allow_date"/>310 <field name="type">sale</field>
312 <field name="type">sale</field>311 </record>
313 </record>
314312
315 </data>313 </data>
316</openerp>314</openerp>
317315
=== modified file 'account_consolidation/test/consolidation_checks.yml'
--- account_consolidation/test/consolidation_checks.yml 2011-08-19 13:08:01 +0000
+++ account_consolidation/test/consolidation_checks.yml 2013-01-09 09:53:22 +0000
@@ -42,7 +42,8 @@
42 raise42 raise
4343
44-44-
45 In order to test the consolidation checks on misconfigured periods, I use the wizard on FY201245 In order to test the consolidation checks on misconfigured periods, I use the wizard on the next year
46 which is misconfigured
46-47-
47 !record {model: account.consolidation.check, id: conso_check_period_1}:48 !record {model: account.consolidation.check, id: conso_check_period_1}:
48 fiscalyear_id: account_fiscalyear_fy049 fiscalyear_id: account_fiscalyear_fy0
@@ -79,8 +80,8 @@
79 name: Virtual Account Spare80 name: Virtual Account Spare
80 parent_id: account_consolidation.virtual_chart_subsidiary_a81 parent_id: account_consolidation.virtual_chart_subsidiary_a
81 type: consolidation82 type: consolidation
82 user_type: account.account_type_expense83 user_type: account.data_account_type_expense
83 84
84-85-
85 In order to test the consolidation checks on misconfigured charts, I use the wizard86 In order to test the consolidation checks on misconfigured charts, I use the wizard
86-87-
8788
=== modified file 'account_consolidation/test/test_data.yml'
--- account_consolidation/test/test_data.yml 2011-08-19 13:08:01 +0000
+++ account_consolidation/test/test_data.yml 2013-01-09 09:53:22 +0000
@@ -3,14 +3,14 @@
3-3-
4 !record {model: account.move, id: account_move_0}:4 !record {model: account.move, id: account_move_0}:
5 company_id: subsidiary_b5 company_id: subsidiary_b
6 date: '2011-01-02'6 date: !eval "'%s-01-02' % datetime.now().year"
7 journal_id: account_journal_sale17 journal_id: account_journal_sale1
8 line_id:8 line_id:
9 - company_id: subsidiary_b9 - company_id: subsidiary_b
10 account_id: a_sale_b10 account_id: a_sale_b
11 amount_currency: 0.011 amount_currency: 0.0
12 credit: 0.012 credit: 0.0
13 date: '2011-01-01'13 date: !eval "'%s-01-02' % datetime.now().year"
14 debit: 1240.014 debit: 1240.0
15 journal_id: account_journal_sale115 journal_id: account_journal_sale1
16 name: Entry 016 name: Entry 0
@@ -22,7 +22,7 @@
22 account_id: cog_b22 account_id: cog_b
23 amount_currency: 0.023 amount_currency: 0.0
24 credit: 1240.024 credit: 1240.0
25 date: '2011-01-01'25 date: !eval "'%s-01-02' % datetime.now().year"
26 debit: 0.026 debit: 0.0
27 journal_id: account_journal_sale127 journal_id: account_journal_sale1
28 name: Entry 028 name: Entry 0
@@ -40,14 +40,14 @@
40-40-
41 !record {model: account.move, id: account_move_1}:41 !record {model: account.move, id: account_move_1}:
42 company_id: account_consolidation.subsidiary_a42 company_id: account_consolidation.subsidiary_a
43 date: '2011-01-20'43 date: !eval "'%s-01-20' % datetime.now().year"
44 journal_id: account_journal_sale044 journal_id: account_journal_sale0
45 line_id:45 line_id:
46 - account_id: account_consolidation.a_sale_a46 - account_id: account_consolidation.a_sale_a
47 amount_currency: 0.047 amount_currency: 0.0
48 company_id: account_consolidation.subsidiary_a48 company_id: account_consolidation.subsidiary_a
49 credit: 0.049 credit: 0.0
50 date: '2011-01-20'50 date: !eval "'%s-01-20' % datetime.now().year"
51 debit: 40.051 debit: 40.0
52 journal_id: account_journal_sale052 journal_id: account_journal_sale0
53 name: Entry 153 name: Entry 1
@@ -59,7 +59,7 @@
59 amount_currency: 0.059 amount_currency: 0.0
60 company_id: account_consolidation.subsidiary_a60 company_id: account_consolidation.subsidiary_a
61 credit: 40.061 credit: 40.0
62 date: '2011-01-20'62 date: !eval "'%s-01-20' % datetime.now().year"
63 debit: 0.063 debit: 0.0
64 journal_id: account_journal_sale064 journal_id: account_journal_sale0
65 name: Entry 165 name: Entry 1
@@ -77,14 +77,14 @@
77-77-
78 !record {model: account.move, id: account_move_2}:78 !record {model: account.move, id: account_move_2}:
79 company_id: account_consolidation.subsidiary_a79 company_id: account_consolidation.subsidiary_a
80 date: '2011-02-23'80 date: !eval "'%s-02-23' % datetime.now().year"
81 journal_id: account_journal_sale081 journal_id: account_journal_sale0
82 line_id:82 line_id:
83 - account_id: account_consolidation.a_sale_a83 - account_id: account_consolidation.a_sale_a
84 amount_currency: 0.084 amount_currency: 0.0
85 company_id: account_consolidation.subsidiary_a85 company_id: account_consolidation.subsidiary_a
86 credit: 0.086 credit: 0.0
87 date: '2011-02-01'87 date: !eval "'%s-02-23' % datetime.now().year"
88 debit: 200.088 debit: 200.0
89 journal_id: account_journal_sale089 journal_id: account_journal_sale0
90 name: Entry 290 name: Entry 2
@@ -96,7 +96,7 @@
96 amount_currency: 0.096 amount_currency: 0.0
97 company_id: account_consolidation.subsidiary_a97 company_id: account_consolidation.subsidiary_a
98 credit: 200.098 credit: 200.0
99 date: '2011-02-01'99 date: !eval "'%s-02-23' % datetime.now().year"
100 debit: 0.0100 debit: 0.0
101 journal_id: account_journal_sale0101 journal_id: account_journal_sale0
102 name: Entry 2102 name: Entry 2
@@ -114,14 +114,14 @@
114-114-
115 !record {model: account.move, id: account_move_3}:115 !record {model: account.move, id: account_move_3}:
116 company_id: account_consolidation.subsidiary_a116 company_id: account_consolidation.subsidiary_a
117 date: '2011-01-15'117 date: !eval "'%s-01-15' % datetime.now().year"
118 journal_id: account_journal_sale0118 journal_id: account_journal_sale0
119 line_id:119 line_id:
120 - account_id: account_consolidation.cog_a120 - account_id: account_consolidation.cog_a
121 amount_currency: 0.0121 amount_currency: 0.0
122 company_id: account_consolidation.subsidiary_a122 company_id: account_consolidation.subsidiary_a
123 credit: 300.0123 credit: 300.0
124 date: '2011-01-01'124 date: !eval "'%s-01-15' % datetime.now().year"
125 debit: 0.0125 debit: 0.0
126 journal_id: account_journal_sale0126 journal_id: account_journal_sale0
127 name: Entry 3127 name: Entry 3
@@ -133,7 +133,7 @@
133 amount_currency: 0.0133 amount_currency: 0.0
134 company_id: account_consolidation.subsidiary_a134 company_id: account_consolidation.subsidiary_a
135 credit: 0.0135 credit: 0.0
136 date: '2011-01-01'136 date: !eval "'%s-01-15' % datetime.now().year"
137 debit: 300.0137 debit: 300.0
138 journal_id: account_journal_sale0138 journal_id: account_journal_sale0
139 name: Entry 3139 name: Entry 3
@@ -150,94 +150,94 @@
150 Creating a account.fiscalyear record with a missing period for january150 Creating a account.fiscalyear record with a missing period for january
151-151-
152 !record {model: account.fiscalyear, id: account_fiscalyear_fy0}:152 !record {model: account.fiscalyear, id: account_fiscalyear_fy0}:
153 code: FY2012153 code: !eval "'FY%s' % (datetime.now().year + 1)"
154 company_id: base.main_company154 company_id: base.main_company
155 date_start: '2012-01-01'155 date_start: !eval "'%s-01-01' % (datetime.now().year + 1)"
156 date_stop: '2012-12-31'156 date_stop: !eval "'%s-12-31' % (datetime.now().year + 1)"
157 name: FY2012157 name: !eval "'FY%s' % (datetime.now().year + 1)"
158 period_ids:158 period_ids:
159 - code: 00/2012159 - code: !eval "'00/%s' % (datetime.now().year + 1)"
160 company_id: base.main_company160 company_id: base.main_company
161 date_start: '2012-01-01'161 date_start: !eval "'%s-01-01' % (datetime.now().year + 1)"
162 date_stop: '2012-01-01'162 date_stop: !eval "'%s-01-01' % (datetime.now().year + 1)"
163 name: Opening Period163 name: Opening Period
164 special: true164 special: true
165 - code: 01/2012165 - code: !eval "'01/%s' % (datetime.now().year + 1)"
166 company_id: base.main_company166 company_id: base.main_company
167 date_start: '2012-01-01'167 date_start: !eval "'%s-01-01' % (datetime.now().year + 1)"
168 date_stop: '2012-01-31'168 date_stop: !eval "'%s-01-31' % (datetime.now().year + 1)"
169 name: 01/2012169 name: !eval "'01/%s' % (datetime.now().year + 1)"
170 - code: 02/2012170 - code: !eval "'02/%s' % (datetime.now().year + 1)"
171 company_id: base.main_company171 company_id: base.main_company
172 date_start: '2012-02-01'172 date_start: !eval "'%s-02-01' % (datetime.now().year + 1)"
173 date_stop: '2012-02-29'173 date_stop: !eval "'%s-02-%s' % ((datetime.now().year + 1), (datetime((datetime.now().year + 1), 3, 1) - timedelta(days=1)).day)"
174 name: 02/2012174 name: !eval "'02/%s' % (datetime.now().year + 1)"
175 - code: 03/2012175 - code: !eval "'03/%s' % (datetime.now().year + 1)"
176 company_id: base.main_company176 company_id: base.main_company
177 date_start: '2012-03-01'177 date_start: !eval "'%s-03-01' % (datetime.now().year + 1)"
178 date_stop: '2012-03-31'178 date_stop: !eval "'%s-03-31' % (datetime.now().year + 1)"
179 name: 03/2012179 name: !eval "'03/%s' % (datetime.now().year + 1)"
180 - code: 04/2012180 - code: !eval "'04/%s' % (datetime.now().year + 1)"
181 company_id: base.main_company181 company_id: base.main_company
182 date_start: '2012-04-01'182 date_start: !eval "'%s-04-01' % (datetime.now().year + 1)"
183 date_stop: '2012-04-30'183 date_stop: !eval "'%s-04-30' % (datetime.now().year + 1)"
184 name: 04/2012184 name: !eval "'04/%s' % (datetime.now().year + 1)"
185 - code: 05/2012185 - code: !eval "'05/%s' % (datetime.now().year + 1)"
186 company_id: base.main_company186 company_id: base.main_company
187 date_start: '2012-05-01'187 date_start: !eval "'%s-05-01' % (datetime.now().year + 1)"
188 date_stop: '2012-05-31'188 date_stop: !eval "'%s-05-31' % (datetime.now().year + 1)"
189 name: 05/2012189 name: !eval "'05/%s' % (datetime.now().year + 1)"
190 - code: 06/2012190 - code: !eval "'06/%s' % (datetime.now().year + 1)"
191 company_id: base.main_company191 company_id: base.main_company
192 date_start: '2012-06-01'192 date_start: !eval "'%s-06-01' % (datetime.now().year + 1)"
193 date_stop: '2012-06-30'193 date_stop: !eval "'%s-06-30' % (datetime.now().year + 1)"
194 name: 06/2012194 name: !eval "'06/%s' % (datetime.now().year + 1)"
195 - code: 07/2012195 - code: !eval "'07/%s' % (datetime.now().year + 1)"
196 company_id: base.main_company196 company_id: base.main_company
197 date_start: '2012-07-01'197 date_start: !eval "'%s-07-01' % (datetime.now().year + 1)"
198 date_stop: '2012-07-31'198 date_stop: !eval "'%s-07-31' % (datetime.now().year + 1)"
199 name: 07/2012199 name: !eval "'07/%s' % (datetime.now().year + 1)"
200 - code: 08/2012200 - code: !eval "'08/%s' % (datetime.now().year + 1)"
201 company_id: base.main_company201 company_id: base.main_company
202 date_start: '2012-08-01'202 date_start: !eval "'%s-08-01' % (datetime.now().year + 1)"
203 date_stop: '2012-08-31'203 date_stop: !eval "'%s-08-31' % (datetime.now().year + 1)"
204 name: 08/2012204 name: !eval "'08/%s' % (datetime.now().year + 1)"
205 - code: 09/2012205 - code: !eval "'09/%s' % (datetime.now().year + 1)"
206 company_id: base.main_company206 company_id: base.main_company
207 date_start: '2012-09-01'207 date_start: !eval "'%s-09-01' % (datetime.now().year + 1)"
208 date_stop: '2012-09-30'208 date_stop: !eval "'%s-09-30' % (datetime.now().year + 1)"
209 name: 09/2012209 name: !eval "'09/%s' % (datetime.now().year + 1)"
210 - code: 10/2012210 - code: !eval "'10/%s' % (datetime.now().year + 1)"
211 company_id: base.main_company211 company_id: base.main_company
212 date_start: '2012-10-01'212 date_start: !eval "'%s-10-01' % (datetime.now().year + 1)"
213 date_stop: '2012-10-31'213 date_stop: !eval "'%s-10-31' % (datetime.now().year + 1)"
214 name: 10/2012214 name: !eval "'10/%s' % (datetime.now().year + 1)"
215 - code: 11/2012215 - code: !eval "'11/%s' % (datetime.now().year + 1)"
216 company_id: base.main_company216 company_id: base.main_company
217 date_start: '2012-11-01'217 date_start: !eval "'%s-11-01' % (datetime.now().year + 1)"
218 date_stop: '2012-11-30'218 date_stop: !eval "'%s-11-30' % (datetime.now().year + 1)"
219 name: 11/2012219 name: !eval "'11/%s' % (datetime.now().year + 1)"
220 - code: 12/2012220 - code: !eval "'12/%s' % (datetime.now().year + 1)"
221 company_id: base.main_company221 company_id: base.main_company
222 date_start: '2012-12-01'222 date_start: !eval "'%s-12-01' % (datetime.now().year + 1)"
223 date_stop: '2012-12-31'223 date_stop: !eval "'%s-12-31' % (datetime.now().year + 1)"
224 name: 12/2012224 name: !eval "'12/%s' % (datetime.now().year + 1)"
225225
226226
227-227-
228 Creating a account.fiscalyear record with a period in december but with different dates than the holding228 Creating a account.fiscalyear record with a period in december but with different dates than the holding
229-229-
230 !record {model: account.fiscalyear, id: account_fiscalyear_fy1}:230 !record {model: account.fiscalyear, id: account_fiscalyear_fy1}:
231 code: FY2012231 code: !eval "'FY%s' % (datetime.now().year + 1)"
232 company_id: account_consolidation.subsidiary_b232 company_id: account_consolidation.subsidiary_b
233 date_start: '2012-01-01'233 date_start: !eval "'%s-01-01' % (datetime.now().year + 1)"
234 date_stop: '2012-12-31'234 date_stop: !eval "'%s-12-31' % (datetime.now().year + 1)"
235 name: FY2012235 name: !eval "'FY%s' % (datetime.now().year + 1)"
236 period_ids:236 period_ids:
237 - code: diff_dates237 - code: diff_dates
238 company_id: account_consolidation.subsidiary_b238 company_id: account_consolidation.subsidiary_b
239 date_start: '2012-12-15'239 date_start: !eval "'%s-12-15' % (datetime.now().year + 1)"
240 date_stop: '2012-12-31'240 date_stop: !eval "'%s-12-31' % (datetime.now().year + 1)"
241 name: diff_dates241 name: diff_dates
242242
243243
@@ -245,70 +245,70 @@
245 Creating a account.fiscalyear record on subsidiary with a period for january (missing on holding)245 Creating a account.fiscalyear record on subsidiary with a period for january (missing on holding)
246-246-
247 !record {model: account.fiscalyear, id: account_fiscalyear_fy2}:247 !record {model: account.fiscalyear, id: account_fiscalyear_fy2}:
248 code: FY2012248 code: !eval "'FY%s' % (datetime.now().year + 1)"
249 company_id: account_consolidation.subsidiary_a249 company_id: account_consolidation.subsidiary_a
250 date_start: '2012-01-01'250 date_start: !eval "'%s-01-01' % (datetime.now().year + 1)"
251 date_stop: '2012-12-31'251 date_stop: !eval "'%s-12-31' % (datetime.now().year + 1)"
252 name: FY2012252 name: !eval "'FY%s' % (datetime.now().year + 1)"
253 period_ids:253 period_ids:
254 - code: 00/2012254 - code: !eval "'00/%s' % (datetime.now().year + 1)"
255 company_id: account_consolidation.subsidiary_a255 company_id: account_consolidation.subsidiary_a
256 date_start: '2012-01-01'256 date_start: !eval "'%s-01-01' % (datetime.now().year + 1)"
257 date_stop: '2012-01-01'257 date_stop: !eval "'%s-01-01' % (datetime.now().year + 1)"
258 name: Opening Period258 name: Opening Period
259 special: true259 special: true
260 - code: 01/2012260 - code: !eval "'01/%s' % (datetime.now().year + 1)"
261 company_id: account_consolidation.subsidiary_a261 company_id: account_consolidation.subsidiary_a
262 date_start: '2012-01-01'262 date_start: !eval "'%s-01-01' % (datetime.now().year + 1)"
263 date_stop: '2012-01-31'263 date_stop: !eval "'%s-01-31' % (datetime.now().year + 1)"
264 name: 01/2012264 name: !eval "'01/%s' % (datetime.now().year + 1)"
265 - code: 02/2012265 - code: !eval "'02/%s' % (datetime.now().year + 1)"
266 company_id: account_consolidation.subsidiary_a266 company_id: account_consolidation.subsidiary_a
267 date_start: '2012-02-01'267 date_start: !eval "'%s-02-01' % (datetime.now().year + 1)"
268 date_stop: '2012-02-29'268 date_stop: !eval "'%s-02-%s' % ((datetime.now().year + 1), (datetime((datetime.now().year + 1), 3, 1) - timedelta(days=1)).day)"
269 name: 02/2012269 name: !eval "'02/%s' % (datetime.now().year + 1)"
270 - code: 03/2012270 - code: !eval "'03/%s' % (datetime.now().year + 1)"
271 company_id: account_consolidation.subsidiary_a271 company_id: account_consolidation.subsidiary_a
272 date_start: '2012-03-01'272 date_start: !eval "'%s-03-01' % (datetime.now().year + 1)"
273 date_stop: '2012-03-31'273 date_stop: !eval "'%s-03-31' % (datetime.now().year + 1)"
274 name: 03/2012274 name: !eval "'03/%s' % (datetime.now().year + 1)"
275 - code: 04/2012275 - code: !eval "'04/%s' % (datetime.now().year + 1)"
276 company_id: account_consolidation.subsidiary_a276 company_id: account_consolidation.subsidiary_a
277 date_start: '2012-04-01'277 date_start: !eval "'%s-04-01' % (datetime.now().year + 1)"
278 date_stop: '2012-04-30'278 date_stop: !eval "'%s-04-30' % (datetime.now().year + 1)"
279 name: 04/2012279 name: !eval "'04/%s' % (datetime.now().year + 1)"
280 - code: 05/2012280 - code: !eval "'05/%s' % (datetime.now().year + 1)"
281 company_id: account_consolidation.subsidiary_a281 company_id: account_consolidation.subsidiary_a
282 date_start: '2012-05-01'282 date_start: !eval "'%s-05-01' % (datetime.now().year + 1)"
283 date_stop: '2012-05-31'283 date_stop: !eval "'%s-05-31' % (datetime.now().year + 1)"
284 name: 05/2012284 name: !eval "'05/%s' % (datetime.now().year + 1)"
285 - code: 06/2012285 - code: !eval "'06/%s' % (datetime.now().year + 1)"
286 company_id: account_consolidation.subsidiary_a286 company_id: account_consolidation.subsidiary_a
287 date_start: '2012-06-01'287 date_start: !eval "'%s-06-01' % (datetime.now().year + 1)"
288 date_stop: '2012-06-30'288 date_stop: !eval "'%s-06-30' % (datetime.now().year + 1)"
289 name: 06/2012289 name: !eval "'06/%s' % (datetime.now().year + 1)"
290 - code: 08/2012290 - code: !eval "'08/%s' % (datetime.now().year + 1)"
291 company_id: account_consolidation.subsidiary_a291 company_id: account_consolidation.subsidiary_a
292 date_start: '2012-08-01'292 date_start: !eval "'%s-08-01' % (datetime.now().year + 1)"
293 date_stop: '2012-08-31'293 date_stop: !eval "'%s-08-31' % (datetime.now().year + 1)"
294 name: 08/2012294 name: !eval "'08/%s' % (datetime.now().year + 1)"
295 - code: 09/2012295 - code: !eval "'09/%s' % (datetime.now().year + 1)"
296 company_id: account_consolidation.subsidiary_a296 company_id: account_consolidation.subsidiary_a
297 date_start: '2012-09-01'297 date_start: !eval "'%s-09-01' % (datetime.now().year + 1)"
298 date_stop: '2012-09-30'298 date_stop: !eval "'%s-09-30' % (datetime.now().year + 1)"
299 name: 09/2012299 name: !eval "'09/%s' % (datetime.now().year + 1)"
300 - code: 10/2012300 - code: !eval "'10/%s' % (datetime.now().year + 1)"
301 company_id: account_consolidation.subsidiary_a301 company_id: account_consolidation.subsidiary_a
302 date_start: '2012-10-01'302 date_start: !eval "'%s-10-01' % (datetime.now().year + 1)"
303 date_stop: '2012-10-31'303 date_stop: !eval "'%s-10-31' % (datetime.now().year + 1)"
304 name: 10/2012304 name: !eval "'10/%s' % (datetime.now().year + 1)"
305 - code: 11/2012305 - code: !eval "'11/%s' % (datetime.now().year + 1)"
306 company_id: account_consolidation.subsidiary_a306 company_id: account_consolidation.subsidiary_a
307 date_start: '2012-11-01'307 date_start: !eval "'%s-11-01' % (datetime.now().year + 1)"
308 date_stop: '2012-11-30'308 date_stop: !eval "'%s-11-30' % (datetime.now().year + 1)"
309 name: 11/2012309 name: !eval "'11/%s' % (datetime.now().year + 1)"
310 - code: 12/2012310 - code: !eval "'12/%s' % (datetime.now().year + 1)"
311 company_id: account_consolidation.subsidiary_a311 company_id: account_consolidation.subsidiary_a
312 date_start: '2012-12-01'312 date_start: !eval "'%s-12-01' % (datetime.now().year + 1)"
313 date_stop: '2012-12-31'313 date_stop: !eval "'%s-12-31' % (datetime.now().year + 1)"
314 name: 12/2012314 name: !eval "'12/%s' % (datetime.now().year + 1)"
315315
=== modified file 'account_consolidation/wizard/consolidation_base.py'
--- account_consolidation/wizard/consolidation_base.py 2012-04-18 14:35:42 +0000
+++ account_consolidation/wizard/consolidation_base.py 2013-01-09 09:53:22 +0000
@@ -1,38 +1,29 @@
1# -*- coding: utf-8 -*-1# -*- coding: utf-8 -*-
2##############################################################################2##############################################################################
3#3#
4# Copyright (c) 2011 Camptocamp SA (http://www.camptocamp.com)4# Author: Guewen Baconnier
5#5# Copyright 2011-2013 Camptocamp SA
6# Author : Guewen Baconnier (Camptocamp)6#
7#7# This program is free software: you can redistribute it and/or modify
8# WARNING: This program as such is intended to be used by professional8# it under the terms of the GNU Affero General Public License as
9# programmers who take the whole responsability of assessing all potential9# published by the Free Software Foundation, either version 3 of the
10# consequences resulting from its eventual inadequacies and bugs10# License, or (at your option) any later version.
11# End users who are looking for a ready-to-use solution with commercial11#
12# garantees and support are strongly adviced to contract a Free Software12# This program is distributed in the hope that it will be useful,
13# Service Company13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14#14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# This program is Free Software; you can redistribute it and/or15# GNU Affero General Public License for more details.
16# modify it under the terms of the GNU General Public License16#
17# as published by the Free Software Foundation; either version 217# You should have received a copy of the GNU Affero General Public License
18# of the License, or (at your option) any later version.18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20# This program is distributed in the hope that it will be useful,
21# but WITHOUT ANY WARRANTY; without even the implied warranty of
22# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23# GNU General Public License for more details.
24#
25# You should have received a copy of the GNU General Public License
26# along with this program; if not, write to the Free Software
27# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28#19#
29##############################################################################20##############################################################################
3021
31from osv import osv, fields22from openerp.osv import osv, orm, fields
32from tools.translate import _23from openerp.tools.translate import _
3324
3425
35class account_consolidation_base(osv.osv_memory):26class account_consolidation_base(orm.AbstractModel):
36 _name = 'account.consolidation.base'27 _name = 'account.consolidation.base'
37 _description = 'Common consolidation wizard. Intended to be inherited'28 _description = 'Common consolidation wizard. Intended to be inherited'
3829
@@ -40,18 +31,30 @@
40 user = self.pool.get('res.users').browse(cr, uid, uid, context=context)31 user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
41 if user.company_id:32 if user.company_id:
42 return user.company_id.id33 return user.company_id.id
43 return self.pool.get('res.company').search(cr, uid, [('parent_id', '=', False)])[0]34 return self.pool.get('res.company').search(
35 cr, uid, [('parent_id', '=', False)])[0]
4436
45 _columns = {37 _columns = {
46 'fiscalyear_id': fields.many2one('account.fiscalyear', 'Fiscal Year', required=True,38 'fiscalyear_id': fields.many2one(
47 help="The checks will be done on the periods of the selected fiscal year."),39 'account.fiscalyear',
48 'company_id': fields.many2one('res.company', 'Company', required=True),40 'Fiscal Year',
49 'holding_chart_account_id': fields.many2one('account.account',41 required=True,
50 'Chart of Accounts',42 help="The checks will be done on the periods of "
51 required=True,43 "the selected fiscal year."),
52 domain=[('parent_id', '=', False)]),44 'company_id': fields.many2one(
53 'subsidiary_ids': fields.many2many('res.company', 'account_conso_comp_rel', 'conso_id', 'company_id',45 'res.company', 'Company', required=True),
54 'Subsidiaries', required=True)46 'holding_chart_account_id': fields.many2one(
47 'account.account',
48 'Chart of Accounts',
49 required=True,
50 domain=[('parent_id', '=', False)]),
51 'subsidiary_ids': fields.many2many(
52 'res.company',
53 'account_conso_comp_rel',
54 'conso_id',
55 'company_id',
56 'Subsidiaries',
57 required=True)
55 }58 }
5659
57 _defaults = {60 _defaults = {
@@ -62,14 +65,9 @@
62 """65 """
63 On change of the company, set the chart of account and the subsidiaries66 On change of the company, set the chart of account and the subsidiaries
6467
65 @param self: The object pointer68 :param company_id: ID of the selected company
66 @param cr: the current row, from the database cursor,
67 @param uid: the current user’s ID for security checks,
68 @param ids: List of the wizard IDs (commonly the first element is the current ID)
69 @param company_id: ID of the selected company
70 @param context: A standard dictionary for contextual values
7169
72 @return: dict of values to change70 :return: dict of values to change
73 """71 """
74 company_obj = self.pool.get('res.company')72 company_obj = self.pool.get('res.company')
7573
@@ -82,21 +80,27 @@
8280
83 return {'value': result}81 return {'value': result}
8482
85 def check_subsidiary_periods(self, cr, uid, ids, holding_company_id, subs_company_id, fyear_id, context=None):83 def check_subsidiary_periods(self, cr, uid, ids, holding_company_id,
86 """84 subs_company_id, fyear_id, context=None):
87 Check Subsidiary company periods vs Holding company periods and returns a list of errors85 """ Check Subsidiary company periods vs Holding company periods and
88 All the periods defined within the group must be the same (same beginning and ending dates)86 returns a list of errors
8987
90 @param self: The object pointer88 The periods checked are the periods within the fiscal year of the
91 @param cr: the current row, from the database cursor,89 holding, and the periods of the subsidiary company in the same range of
92 @param uid: the current user’s ID for security checks,90 time.
93 @param ids: List of the wizard IDs (commonly the first element is the current ID)91
94 @param holding_company_id: ID of the holding company92 The fiscal year of the subsidiary is deduced from the start/stop date
95 @param subs_company_id: ID of the subsidiary company to check93 of the holding's fiscal year.
96 @param fyear_id: ID of the fiscal years to compare94
97 @param context: A standard dictionary for contextual values95 All the periods defined within the group must have the same beginning
9896 and ending dates to be valid.
99 @return: dict of list with errors for each company {company_id: ['error 1', 'error2']}97
98 :param holding_company_id: ID of the holding company
99 :param subs_company_id: ID of the subsidiary company to check
100 :param fyear_id: ID of the fiscal year of the holding.
101
102 :return: dict of list with errors for each company
103 {company_id: ['error 1', 'error2']}
100 """104 """
101 company_obj = self.pool.get('res.company')105 company_obj = self.pool.get('res.company')
102 period_obj = self.pool.get('account.period')106 period_obj = self.pool.get('account.period')
@@ -108,48 +112,69 @@
108 errors = []112 errors = []
109113
110 # get holding fiscal year and periods114 # get holding fiscal year and periods
111 holding = company_obj.browse(cr, uid, holding_company_id, context=context)115 holding = company_obj.browse(
112 subsidiary = company_obj.browse(cr, uid, subs_company_id, context=context)116 cr, uid, holding_company_id, context=context)
117 subsidiary = company_obj.browse(
118 cr, uid, subs_company_id, context=context)
113119
114 holding_periods_ids = period_obj.search(cr, uid,120 holding_periods_ids = period_obj.search(
121 cr, uid,
115 [('company_id', '=', holding.id),122 [('company_id', '=', holding.id),
116 ('fiscalyear_id', '=', holding_fiscal_year.id)],123 ('fiscalyear_id', '=', holding_fiscal_year.id)],
117 context=context)124 context=context)
118 holding_periods = period_obj.browse(cr, uid, holding_periods_ids, context=context)125 holding_periods = period_obj.browse(
126 cr, uid, holding_periods_ids, context=context)
119127
120 # get subsidiary fiscal year and periods128 # get subsidiary fiscal year and periods
121 subsidiary_fiscal_year = fy_obj.search(cr, uid,129 subsidiary_fiscal_year = fy_obj.search(
130 cr, uid,
122 [('company_id', '=', subsidiary.id),131 [('company_id', '=', subsidiary.id),
123 ('date_start', '=', holding_fiscal_year.date_start),132 ('date_start', '=', holding_fiscal_year.date_start),
124 ('date_stop', '=', holding_fiscal_year.date_stop),133 ('date_stop', '=', holding_fiscal_year.date_stop),
125 ])134 ],
135 context=context)
126 if not subsidiary_fiscal_year:136 if not subsidiary_fiscal_year:
127 errors.append(_('The fiscal year of the subsidiary company %s does not exists from %s to %s')137 errors.append(
128 % (subsidiary.name, holding_fiscal_year.date_start, holding_fiscal_year.date_stop))138 _('The fiscal year of the subsidiary company %s '
139 'does not exists from %s to %s') %
140 (subsidiary.name,
141 holding_fiscal_year.date_start,
142 holding_fiscal_year.date_stop))
129 else:143 else:
130 subsidiary_period_ids = period_obj.search(cr, uid,144 subsidiary_period_ids = period_obj.search(
145 cr, uid,
131 [('company_id', '=', subsidiary.id),146 [('company_id', '=', subsidiary.id),
132 ('fiscalyear_id', '=', subsidiary_fiscal_year[0])], # 0 because there can be only 1 fiscal year on the same dates as the holding147 # 0 because there can be only 1 fiscal year
148 # on the same dates than the holding
149 ('fiscalyear_id', '=', subsidiary_fiscal_year[0])],
133 context=context)150 context=context)
134 subsidiary_periods = period_obj.browse(cr, uid, subsidiary_period_ids, context=context)151 subsidiary_periods = period_obj.browse(
152 cr, uid, subsidiary_period_ids, context=context)
135153
136 # a holding fiscal year may have more periods than a subsidiary (a subsidiary created at the middle of the year for example)154 # a holding fiscal year may have more periods than a subsidiary
155 # (a subsidiary created at the middle of the year for example)
137 # but the reverse situation is not allowed156 # but the reverse situation is not allowed
138 if len(holding_periods) < len(subsidiary_periods):157 if len(holding_periods) < len(subsidiary_periods):
139 errors.append(_('Holding company has less periods than the subsidiary company %s!') % (subsidiary.name,))158 errors.append(
159 _('Holding company has less periods than the '
160 'subsidiary company %s!') % subsidiary.name)
140161
141 # check subsidiary periods dates vs holding periods for each period of the subsidiary162 # check subsidiary periods dates vs holding periods
163 # for each period of the subsidiary
142 for subsidiary_period in subsidiary_periods:164 for subsidiary_period in subsidiary_periods:
143 period_exists = False165 period_exists = False
144 for holding_period in holding_periods:166 for holding_period in holding_periods:
145 if subsidiary_period.date_start == holding_period.date_start \167 if (subsidiary_period.date_start == holding_period.date_start and
146 and subsidiary_period.date_stop == holding_period.date_stop:168 subsidiary_period.date_stop == holding_period.date_stop):
147 period_exists = True169 period_exists = True
148 break170 break
149 if not period_exists:171 if not period_exists:
150 errors.append(_('Period from %s to %s not found in holding company %s')172 errors.append(
151 % (subsidiary_period.date_start, subsidiary_period.date_stop, holding.name))173 _('Period from %s to %s not found '
152174 'in holding company %s') %
175 (subsidiary_period.date_start,
176 subsidiary_period.date_stop,
177 holding.name))
153 return errors178 return errors
154179
155 def check_all_periods(self, cr, uid, ids, context=None):180 def check_all_periods(self, cr, uid, ids, context=None):
@@ -157,24 +182,24 @@
157 Call the period check on each period of all subsidiaries182 Call the period check on each period of all subsidiaries
158 Returns the errors by subsidiary183 Returns the errors by subsidiary
159184
160 @param self: The object pointer185 :return: dict of list with errors for each company
161 @param cr: the current row, from the database cursor,186 {company_id: ['error 1', 'error2']}
162 @param uid: the current user’s ID for security checks,
163 @param ids: List of the wizard IDs (commonly the first element is the current ID)
164 @param context: A standard dictionary for contextual values
165
166 @return: dict of list with errors for each company {company_id: ['error 1', 'error2']}
167 """187 """
188 if isinstance(ids, (int, long)):
189 ids = [ids]
190 assert len(ids) == 1, "only 1 id expected"
191
168 form = self.browse(cr, uid, ids[0], context=context)192 form = self.browse(cr, uid, ids[0], context=context)
169193
170 errors_by_company = {}194 errors_by_company = {}
171 for subsidiary in form.subsidiary_ids:195 for subsidiary in form.subsidiary_ids:
172 errors = \196 errors = self.check_subsidiary_periods(
173 self.check_subsidiary_periods(cr, uid, ids,197 cr, uid,
174 form.company_id.id,198 ids,
175 subsidiary.id,199 form.company_id.id,
176 form.fiscalyear_id.id,200 subsidiary.id,
177 context=context)201 form.fiscalyear_id.id,
202 context=context)
178 if errors:203 if errors:
179 errors_by_company[subsidiary.id] = errors204 errors_by_company[subsidiary.id] = errors
180205
@@ -182,24 +207,23 @@
182207
183 def _chart_accounts_data(self, cr, uid, ids, chart_account_id, context=None):208 def _chart_accounts_data(self, cr, uid, ids, chart_account_id, context=None):
184 """209 """
185 Returns the list of accounts to use for the consolidation for the holding210 Returns the list of accounts to use for the consolidation
186 or the subsidiaries. Keys of the returned dict are the account codes and211 for the holding or the subsidiaries.
187 if the context is holding_coa, dict values are the browse instances of the accounts212 Keys of the returned dict are the account codes and
188213 if the context is holding_coa,
189 @param self: The object pointer214 dict values are the browse instances of the accounts
190 @param cr: the current row, from the database cursor,215
191 @param uid: the current user’s ID for security checks,216 :chart_account_id: ID of the Chart of Account for which
192 @param ids: List of the wizard IDs (commonly the first element is the current ID)217 we want the account codes
193 @chart_account_id: ID of the "Chart" Account for which we want the account codes218
194 @param context: A standard dictionary for contextual values219 :return: dict with {account codes: browse instances}
195
196 @return: dict with {account codes: browse instances}
197 """220 """
198 context = context or {}221 if context is None:
222 context = {}
199 account_obj = self.pool.get('account.account')223 account_obj = self.pool.get('account.account')
200 res = {}224 res = {}
201 account_ids = account_obj.\225 account_ids = account_obj._get_children_and_consol(
202 _get_children_and_consol(cr, uid, chart_account_id, context=context)226 cr, uid, chart_account_id, context=context)
203227
204 # do not consolidate chart root228 # do not consolidate chart root
205 account_ids.remove(chart_account_id)229 account_ids.remove(chart_account_id)
@@ -216,33 +240,37 @@
216 continue240 continue
217241
218 res[account.code] = {}242 res[account.code] = {}
219 # we'll need the browse object during the "consolidate wizard" for the holding243 # we'll need the browse object during the
220 res[account.code] = holding and account or True244 # "consolidate wizard" for the holding
245 res[account.code] = account if holding else True
221246
222 return res247 return res
223248
224 def check_subsidiary_chart(self, cr, uid, ids, holding_chart_account_id, subsidiary_chart_account_id, context=None):249 def check_subsidiary_chart(self, cr, uid, ids, holding_chart_account_id,
250 subsidiary_chart_account_id, context=None):
225 """251 """
226 Check a Holding Chart of Accounts vs a Subsidiary Virtual Chart of Accounts252 Check a Holding Chart of Accounts vs a Subsidiary Virtual
253 Chart of Accounts
227 All the accounts of the Virtual CoA must exist in the Holding CoA.254 All the accounts of the Virtual CoA must exist in the Holding CoA.
228 The Holding's CoA may hold accounts which do not exist in the Subsidiary's Virtual CoA.255 The Holding's CoA may hold accounts which do not exist
229256 in the Subsidiary's Virtual CoA.
230 @param self: The object pointer257
231 @param cr: the current row, from the database cursor,258 :param holding_chart_account_id: ID of the Chart of Account
232 @param uid: the current user’s ID for security checks,259 of the holding company
233 @param ids: List of the wizard IDs (commonly the first element is the current ID)260 :param subsidiary_chart_account_id: ID of the Chart of Account
234 @param holding_chart_account_id: ID of the "Chart" Account of the holding company261 of the subsidiary company to check
235 @param subsidiary_chart_account_id: ID of the "Chart" Account of the subsidiary company to check262
236 @param context: A standard dictionary for contextual values263 :return: List of accounts existing on subsidiary but no on holding COA
237
238 @return: List of accounts existing on subsidiary but no on holding COA
239 """264 """
240 context = context or {}265 if context is None:
241 holding_ctx = context.copy()266 context = {}
242 holding_ctx.update({'holding_coa': True})267 holding_ctx = dict(context, holding_coa=True)
243 holding_accounts = self._chart_accounts_data(cr, uid, ids, holding_chart_account_id, context=holding_ctx)268 holding_accounts = self._chart_accounts_data(
244 subsidiary_accounts = self._chart_accounts_data(cr, uid, ids, subsidiary_chart_account_id, context=context)269 cr, uid, ids, holding_chart_account_id, context=holding_ctx)
245 # accounts which are configured on the subsidiary VCoA but not on the holding CoA270 subsidiary_accounts = self._chart_accounts_data(
271 cr, uid, ids, subsidiary_chart_account_id, context=context)
272 # accounts which are configured on the subsidiary
273 # Virtual CoA but not on the holding CoA
246 spare_accounts = [code for code274 spare_accounts = [code for code
247 in subsidiary_accounts275 in subsidiary_accounts
248 if code not in holding_accounts]276 if code not in holding_accounts]
@@ -250,26 +278,27 @@
250278
251 def check_account_charts(self, cr, uid, ids, context=None):279 def check_account_charts(self, cr, uid, ids, context=None):
252 """280 """
253 Check the chart of accounts of the holding vs each virtual chart of accounts of the subsidiaries281 Check the chart of accounts of the holding vs
254282 each virtual chart of accounts of the subsidiaries
255 @param self: The object pointer
256 @param cr: the current row, from the database cursor,
257 @param uid: the current user’s ID for security checks,
258 @param ids: List of the wizard IDs (commonly the first element is the current ID)
259 @param context: A standard dictionary for contextual values
260 """283 """
284 if isinstance(ids, (int, long)):
285 ids = [ids]
286 assert len(ids) == 1, "only 1 id expected"
261 form = self.browse(cr, uid, ids[0], context=context)287 form = self.browse(cr, uid, ids[0], context=context)
262288
263 invalid_items_per_company = {}289 invalid_items_per_company = {}
264 for subsidiary in form.subsidiary_ids:290 for subsidiary in form.subsidiary_ids:
265 if not subsidiary.consolidation_chart_account_id:291 if not subsidiary.consolidation_chart_account_id:
266 raise osv.except_osv(_('Error'), _('No chart of accounts for company %s') % (subsidiary,))292 raise osv.except_osv(
293 _('Error'),
294 _('No chart of accounts for company %s') % subsidiary)
267295
268 invalid_items = \296 invalid_items = self.check_subsidiary_chart(
269 self.check_subsidiary_chart(cr, uid, ids,297 cr, uid,
270 form.holding_chart_account_id.id,298 ids,
271 subsidiary.consolidation_chart_account_id.id,299 form.holding_chart_account_id.id,
272 context=context)300 subsidiary.consolidation_chart_account_id.id,
301 context=context)
273 if any(invalid_items):302 if any(invalid_items):
274 invalid_items_per_company[subsidiary.id] = invalid_items303 invalid_items_per_company[subsidiary.id] = invalid_items
275304
@@ -278,25 +307,24 @@
278 def run_consolidation(self, cr, uid, ids, context=None):307 def run_consolidation(self, cr, uid, ids, context=None):
279 """308 """
280 Proceed with all checks before launch any consolidation step309 Proceed with all checks before launch any consolidation step
281 This is a base method intended to be inherited with the next consolidation steps310 This is a base method intended to be inherited with the next
282311 consolidation steps
283 @param self: The object pointer
284 @param cr: the current row, from the database cursor,
285 @param uid: the current user’s ID for security checks,
286 @param ids: List of the wizard IDs (commonly the first element is the current ID)
287 @param context: A standard dictionary for contextual values
288 """312 """
313 if isinstance(ids, (int, long)):
314 ids = [ids]
315 assert len(ids) == 1, "only 1 id expected"
289316
290 if self.check_all_periods(cr, uid, ids, context=context):317 if self.check_all_periods(cr, uid, ids, context=context):
291 raise osv.except_osv(_('Error'),318 raise osv.except_osv(
292 _('Invalid periods, please launch the "Consolidation: Checks" wizard'))319 _('Error'),
320 _('Invalid periods, please launch the '
321 '"Consolidation: Checks" wizard'))
293 if self.check_account_charts(cr, uid, ids, context=context):322 if self.check_account_charts(cr, uid, ids, context=context):
294 raise osv.except_osv(_('Error'),323 raise osv.except_osv(
295 _('Invalid charts, please launch the "Consolidation: Checks" wizard'))324 _('Error'),
325 _('Invalid charts, please launch the '
326 '"Consolidation: Checks" wizard'))
296327
297 # inherit to add the next steps of the reconciliation328 # inherit to add the next steps of the reconciliation
298329
299 return {'type': 'ir.actions.act_window_close'}330 return {'type': 'ir.actions.act_window_close'}
300
301
302account_consolidation_base()
303331
=== modified file 'account_consolidation/wizard/consolidation_check.py'
--- account_consolidation/wizard/consolidation_check.py 2012-04-18 14:35:42 +0000
+++ account_consolidation/wizard/consolidation_check.py 2013-01-09 09:53:22 +0000
@@ -1,109 +1,91 @@
1# -*- coding: utf-8 -*-1# -*- coding: utf-8 -*-
2##############################################################################2##############################################################################
3#3#
4# Copyright (c) 2011 Camptocamp SA (http://www.camptocamp.com)4# Author: Guewen Baconnier
5#5# Copyright 2011-2013 Camptocamp SA
6# Author : Guewen Baconnier (Camptocamp)6#
7#7# This program is free software: you can redistribute it and/or modify
8# WARNING: This program as such is intended to be used by professional8# it under the terms of the GNU Affero General Public License as
9# programmers who take the whole responsability of assessing all potential9# published by the Free Software Foundation, either version 3 of the
10# consequences resulting from its eventual inadequacies and bugs10# License, or (at your option) any later version.
11# End users who are looking for a ready-to-use solution with commercial11#
12# garantees and support are strongly adviced to contract a Free Software12# This program is distributed in the hope that it will be useful,
13# Service Company13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14#14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# This program is Free Software; you can redistribute it and/or15# GNU Affero General Public License for more details.
16# modify it under the terms of the GNU General Public License16#
17# as published by the Free Software Foundation; either version 217# You should have received a copy of the GNU Affero General Public License
18# of the License, or (at your option) any later version.18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20# This program is distributed in the hope that it will be useful,
21# but WITHOUT ANY WARRANTY; without even the implied warranty of
22# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23# GNU General Public License for more details.
24#
25# You should have received a copy of the GNU General Public License
26# along with this program; if not, write to the Free Software
27# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28#19#
29##############################################################################20##############################################################################
3021
31from osv import osv, fields22from openerp.osv import osv, orm, fields
3223from openerp.tools.translate import _
33from tools.translate import _24
3425
3526class account_consolidation_check(orm.TransientModel):
36class account_consolidation_check(osv.osv_memory):
37 _name = 'account.consolidation.check'27 _name = 'account.consolidation.check'
38 _inherit = 'account.consolidation.base'28 _inherit = 'account.consolidation.base'
39 _description = 'Consolidation Checks. Model used for views'29 _description = 'Consolidation Checks. Model used for views'
4030
41 _columns = {31 _columns = {
42 'subsidiary_ids': fields.many2many('res.company', 'account_conso_check_comp_rel', 'conso_id', 'company_id',32 'subsidiary_ids': fields.many2many(
43 'Subsidiaries', required=True),33 'res.company',
34 'account_conso_check_comp_rel',
35 'conso_id',
36 'company_id',
37 'Subsidiaries',
38 required=True),
44 }39 }
4540
46 def check_account_charts(self, cr, uid, ids, context=None):41 def check_account_charts(self, cr, uid, ids, context=None):
47 """42 """
48 Action launched with the button on the view.43 Action launched with the button on the view.
49 Check the account charts and display a report of the errors44 Check the account charts and display a report of the errors
50
51 @param self: The object pointer
52 @param cr: the current row, from the database cursor,
53 @param uid: the current user’s ID for security checks,
54 @param ids: List of the wizard IDs (commonly the first element is the current ID)
55 @param context: A standard dictionary for contextual values
56 """45 """
57 invalid_items_per_company = \46 company_obj = self.pool.get('res.company')
58 super(account_consolidation_check, self).check_account_charts(cr, uid, ids, context=context)47 invalid_items_per_company = super(account_consolidation_check, self).\
59 if invalid_items_per_company:48 check_account_charts(cr, uid, ids, context=context)
60 err_lines = []49
61 for company_id, account_codes in invalid_items_per_company.iteritems():50 if not invalid_items_per_company:
62 company_obj = self.pool.get('res.company')51 raise osv.except_osv(
63 company = company_obj.browse(cr, uid, company_id, context=context)52 _('Validation'),
64 err_lines.append(_("%s :") % (company.name,))53 _('Chart of Accounts are OK.'))
65 [err_lines.append(_("Account with code %s does not exist on the Holding company.") % (account_code,))54
66 for account_code55 err_lines = []
67 in account_codes]56 for company_id, account_codes in invalid_items_per_company.iteritems():
68 err_lines.append('')57 company = company_obj.browse(
6958 cr, uid, company_id, context=context)
70 raise osv.except_osv(_('Invalid charts'),59 err_lines.append(_("%s :") % company.name)
71 '\n'.join(err_lines))60 for account_code in account_codes:
7261 err_lines.append(
73 else:62 _("Account with code %s does not exist on the "
74 raise osv.except_osv(_('Validation'), _('Chart of Accounts are OK.'))63 "Holding company.") % account_code)
75 # open a confirmation view ?64 err_lines.append('')
76 return True65
66 raise osv.except_osv(
67 _('Invalid charts'), '\n'.join(err_lines))
7768
78 def check_all_periods(self, cr, uid, ids, context=None):69 def check_all_periods(self, cr, uid, ids, context=None):
79 """70 """
80 Action launched with the button on the view.71 Action launched with the button on the view.
81 Check the periods and display a report of the errors72 Check the periods and display a report of the errors
82
83 @param self: The object pointer
84 @param cr: the current row, from the database cursor,
85 @param uid: the current user’s ID for security checks,
86 @param ids: List of the wizard IDs (commonly the first element is the current ID)
87 @param context: A standard dictionary for contextual values
88 """73 """
89 errors_by_company = \74 errors_by_company = super(account_consolidation_check, self).\
90 super(account_consolidation_check, self).check_all_periods(cr, uid, ids, context=context)75 check_all_periods(cr, uid, ids, context=context)
9176
92 if errors_by_company:77 if not errors_by_company:
93 company_obj = self.pool.get('res.company')
94
95 err_lines = []
96 for company_id, errors in errors_by_company.iteritems():
97 company = company_obj.browse(cr, uid, company_id, context=context)
98 err_lines.append(_("%s :") % (company.name,))
99 [err_lines.append(error) for error in errors]
100 err_lines.append('')
101
102 raise osv.except_osv(_('Invalid periods'),
103 '\n'.join(err_lines))
104 else:
105 raise osv.except_osv(_('Validation'), _('Periods are OK.'))78 raise osv.except_osv(_('Validation'), _('Periods are OK.'))
106 # open a confirmation view ?79
107 return True80 company_obj = self.pool.get('res.company')
10881
109account_consolidation_check()82 err_lines = []
83 for company_id, errors in errors_by_company.iteritems():
84 company = company_obj.browse(cr, uid, company_id, context=context)
85 err_lines.append(_("%s :") % company.name)
86 for error in errors:
87 err_lines.append(error)
88 err_lines.append('')
89
90 raise osv.except_osv(_('Invalid periods'),
91 '\n'.join(err_lines))
11092
=== modified file 'account_consolidation/wizard/consolidation_check_view.xml'
--- account_consolidation/wizard/consolidation_check_view.xml 2011-08-19 13:08:01 +0000
+++ account_consolidation/wizard/consolidation_check_view.xml 2013-01-09 09:53:22 +0000
@@ -2,32 +2,44 @@
2<openerp>2<openerp>
3 <data>3 <data>
44
5 <record id="view_consolidation_check_form" model="ir.ui.view">5 <record id="view_consolidation_check_form" model="ir.ui.view">
6 <field name="name">account.consolidation.check.form</field>6 <field name="name">account.consolidation.check.form</field>
7 <field name="model">account.consolidation.check</field>7 <field name="model">account.consolidation.check</field>
8 <field name="type">form</field>8 <field name="type">form</field>
9 <field name="arch" type="xml">9 <field name="arch" type="xml">
10 <form string="Consolidation: Checks">10 <form string="Consolidation: Checks" version="7.0">
11 <group col="4" colspan="6">11 <label string="Prepare your consolidation and make sure that your consolidation will be correct by proceeding with the checks. The 'Check Periods' verify if fiscal year exists for each subsidiary, and if the periods have the same beginning and ending dates. The 'Check Charts' verify if subsidiary accounts are missing in the Holding's Chart of Accounts."/>
12 <field name="company_id" on_change="on_change_company_id(company_id)" invisible="True"/>12 <group>
13 <field name="fiscalyear_id" domain="[('company_id', '=', company_id)]"/>13 <field name="company_id"
14 <newline/>14 on_change="on_change_company_id(company_id)"
15 <field name="holding_chart_account_id" domain="[('company_id', '=', company_id), ('parent_id', '=', False)]"/>15 invisible="True"/>
16 <separator string="Subsidiaries to Consolidate" colspan="4"/>16 <field name="fiscalyear_id"
17 <field name="subsidiary_ids" colspan="4" nolabel="1" required="True" domain="[('parent_id', '=', company_id)]">17 domain="[('company_id', '=', company_id)]"/>
18 <tree>18 <newline/>
19 <field name="name"/>19 <field name="holding_chart_account_id"
20 <field name="consolidation_chart_account_id"/>20 domain="[('company_id', '=', company_id), ('parent_id', '=', False)]"/>
21 </tree>21 <separator string="Subsidiaries to Consolidate" colspan="4"/>
22 </field>22 <field name="subsidiary_ids" colspan="4" nolabel="1"
23 </group>23 required="True"
24 <separator colspan="4"/>24 domain="[('parent_id', '=', company_id)]">
25 <group col="3" colspan="4">25 <tree>
26 <button special="cancel" string="Cancel" icon='gtk-cancel'/>26 <field name="name"/>
27 <button name="check_all_periods" string="Check Periods" colspan="1" type="object" icon="gtk-execute"/>27 <field name="consolidation_chart_account_id"/>
28 <button name="check_account_charts" string="Check Charts" colspan="1" type="object" icon="gtk-execute"/>28 </tree>
29 </group>29 </field>
30 </form> 30 </group>
31 <footer>
32 <button name="check_all_periods"
33 string="Check Periods" type="object"
34 class="oe_highlight"/>
35 or
36 <button name="check_account_charts"
37 string="Check Charts" type="object"
38 class="oe_highlight"/>
39 or
40 <button string="Cancel" class="oe_link" special="cancel"/>
41 </footer>
42 </form>
31 </field>43 </field>
32 </record>44 </record>
3345
@@ -37,9 +49,8 @@
37 <field name="res_model">account.consolidation.check</field>49 <field name="res_model">account.consolidation.check</field>
38 <field name="view_type">form</field>50 <field name="view_type">form</field>
39 <field name="view_mode">form</field>51 <field name="view_mode">form</field>
40 <field name="help">Prepare your consolidation and make sure that your consolidation will be correct by proceeding with the checks. The "Check Periods" verify if fiscal year exists for each subsidiary, and if the periods have the same beginning and ending dates. The "Check Charts" verify if subsidiary accounts are missing in the Holding's Chart of Accounts.</field>
41 <field name="target">new</field>52 <field name="target">new</field>
42 </record>53 </record>
4354
44 </data>55 </data>
45</openerp>56</openerp>
4657
=== modified file 'account_consolidation/wizard/consolidation_consolidate.py'
--- account_consolidation/wizard/consolidation_consolidate.py 2012-04-11 07:57:56 +0000
+++ account_consolidation/wizard/consolidation_consolidate.py 2013-01-09 09:53:22 +0000
@@ -1,55 +1,60 @@
1# -*- coding: utf-8 -*-1# -*- coding: utf-8 -*-
2##############################################################################2##############################################################################
3#3#
4# Copyright (c) 2011 Camptocamp SA (http://www.camptocamp.com)4# Author: Guewen Baconnier
5#5# Copyright 2011-2013 Camptocamp SA
6# Author : Guewen Baconnier (Camptocamp)6#
7#7# This program is free software: you can redistribute it and/or modify
8# WARNING: This program as such is intended to be used by professional8# it under the terms of the GNU Affero General Public License as
9# programmers who take the whole responsability of assessing all potential9# published by the Free Software Foundation, either version 3 of the
10# consequences resulting from its eventual inadequacies and bugs10# License, or (at your option) any later version.
11# End users who are looking for a ready-to-use solution with commercial11#
12# garantees and support are strongly adviced to contract a Free Software12# This program is distributed in the hope that it will be useful,
13# Service Company13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14#14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# This program is Free Software; you can redistribute it and/or15# GNU Affero General Public License for more details.
16# modify it under the terms of the GNU General Public License16#
17# as published by the Free Software Foundation; either version 217# You should have received a copy of the GNU Affero General Public License
18# of the License, or (at your option) any later version.18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20# This program is distributed in the hope that it will be useful,
21# but WITHOUT ANY WARRANTY; without even the implied warranty of
22# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23# GNU General Public License for more details.
24#
25# You should have received a copy of the GNU General Public License
26# along with this program; if not, write to the Free Software
27# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28#19#
29##############################################################################20##############################################################################
3021
31from osv import osv, fields22from openerp.osv import orm, fields
32from tools.translate import _23from openerp.tools.translate import _
33from tools import safe_eval as eval24
3425
35class account_consolidation_consolidate(osv.osv_memory):26class account_consolidation_consolidate(orm.TransientModel):
36 _name = 'account.consolidation.consolidate'27 _name = 'account.consolidation.consolidate'
37 _inherit = 'account.consolidation.base'28 _inherit = 'account.consolidation.base'
3829
39 _columns = {30 _columns = {
40 'from_period_id': fields.many2one('account.period', 'Start Period', required=True,31 'from_period_id': fields.many2one(
41 help="Select the same period in 'from' and 'to' if you want to proceed with a single period. Start Period is ignored for Year To Date accounts."),32 'account.period',
42 'to_period_id': fields.many2one('account.period', 'End Period', required=True,33 'Start Period',
43 help="The consolidation will be done at the very last date of the selected period."),34 required=True,
44 'journal_id': fields.many2one('account.journal', 'Journal', required=True),35 help="Select the same period in 'from' and 'to' "
45 # not sure that we'll use them, actually using centralised counterpart journal36 "if you want to proceed with a single period. "
46# 'gain_account_id': fields.many2one('account.account', 'Gain Account', required=True,),37 "Start Period is ignored for Year To Date accounts."),
47# 'loss_account_id': fields.many2one('account.account', 'Loss Account', required=True,),38 'to_period_id': fields.many2one(
48 'target_move': fields.selection([('posted', 'All Posted Entries'),39 'account.period',
49 ('all', 'All Entries'),40 'End Period',
50 ], 'Target Moves', required=True),41 required=True,
51 'subsidiary_ids': fields.many2many('res.company', 'account_conso_conso_comp_rel', 'conso_id', 'company_id',42 help="The consolidation will be done at the very "
52 'Subsidiaries', required=True),43 "last date of the selected period."),
44 'journal_id': fields.many2one(
45 'account.journal', 'Journal', required=True),
46 'target_move': fields.selection(
47 [('posted', 'All Posted Entries'),
48 ('all', 'All Entries')],
49 'Target Moves',
50 required=True),
51 'subsidiary_ids': fields.many2many(
52 'res.company',
53 'account_conso_conso_comp_rel',
54 'conso_id',
55 'company_id',
56 string='Subsidiaries',
57 required=True),
53 }58 }
5459
55 _defaults = {60 _defaults = {
@@ -57,38 +62,39 @@
57 }62 }
5863
59 def _check_periods_fy(self, cr, uid, ids, context=None):64 def _check_periods_fy(self, cr, uid, ids, context=None):
60 if context is None:65 if isinstance(ids, (int, long)):
61 context = {}66 ids = [ids]
67 assert len(ids) == 1, "only 1 id expected"
68
62 form = self.browse(cr, uid, ids[0], context=context)69 form = self.browse(cr, uid, ids[0], context=context)
63 if form.from_period_id.fiscalyear_id.id != form.to_period_id.fiscalyear_id.id:70 return (form.from_period_id.fiscalyear_id.id ==
64 return False71 form.to_period_id.fiscalyear_id.id)
65 return True
6672
67 _constraints = [73 _constraints = [
68 (_check_periods_fy, 'Start Period and End Period must be of the same Fiscal Year !', ['from_period_id', 'to_period_id']),74 (_check_periods_fy,
75 'Start Period and End Period must be of the same Fiscal Year !',
76 ['from_period_id', 'to_period_id']),
69 ]77 ]
7078
71 def on_change_from_period_id(self, cr, uid, ids, from_period_id, to_period_id, context=None):79 def on_change_from_period_id(self, cr, uid, ids, from_period_id,
72 """80 to_period_id, context=None):
73 On change of the From period, set the To period to the same period if it is empty81 """ On change of the From period, set the To period
7482 to the same period if it is empty
75 @param self: The object pointer83
76 @param cr: the current row, from the database cursor,84 :param from_period_id: ID of the selected from period id
77 @param uid: the current user’s ID for security checks,85 :param to_period_id: ID of the current from period id
78 @param ids: List of the wizard IDs (commonly the first element is the current ID)86
79 @param from_period_id: ID of the selected from period id87 :return: dict of values to change
80 @param to_period_id: ID of the current from period id
81 @param context: A standard dictionary for contextual values
82
83 @return: dict of values to change
84 """88 """
85 result = {}89 result = {}
86 period_obj = self.pool.get('account.period')90 period_obj = self.pool.get('account.period')
87 from_period = period_obj.browse(cr, uid, from_period_id, context=context)91 from_period = period_obj.browse(
92 cr, uid, from_period_id, context=context)
88 if not to_period_id:93 if not to_period_id:
89 result['to_period_id'] = from_period_id94 result['to_period_id'] = from_period_id
90 else:95 else:
91 to_period = period_obj.browse(cr, uid, to_period_id, context=context)96 to_period = period_obj.browse(
97 cr, uid, to_period_id, context=context)
92 if to_period.date_start < from_period.date_start:98 if to_period.date_start < from_period.date_start:
93 result['to_period_id'] = from_period_id99 result['to_period_id'] = from_period_id
94100
@@ -99,97 +105,87 @@
99 """105 """
100 Returns the currency rate type to use106 Returns the currency rate type to use
101107
102 @param self: The object pointer108 :param account: browse_record instance of account.account
103 @param cr: the current row, from the database cursor,
104 @param uid: the current user’s ID for security checks,
105 @param ids: List of the wizard IDs (commonly the first element is the current ID)
106 @param account: browse instance of account.account
107 @param context: A standard dictionary for contextual values
108109
109 @return: 'spot' or 'average'110 :return: id of the currency rate type to use
110 """111 """
111 return account.consolidation_rate_type_id and account.consolidation_rate_type_id \112 if account.consolidation_rate_type_id:
112 or account.user_type.consolidation_rate_type_id and account.user_type.consolidation_rate_type_id.id \113 return account.consolidation_rate_type_id.id
113 or False114
115 elif account.user_type.consolidation_rate_type_id:
116 return account.user_type.consolidation_rate_type_id.id
117
118 else:
119 return False
114120
115 def _consolidation_mode(self, cr, uid, ids, account, context=None):121 def _consolidation_mode(self, cr, uid, ids, account, context=None):
116 """122 """
117 Returns the consolidation mode to use123 Returns the consolidation mode to use
118124
119 @param self: The object pointer125 :param account: browse instance of account.account
120 @param cr: the current row, from the database cursor,126
121 @param uid: the current user’s ID for security checks,127 :return: 'ytd' or 'period'
122 @param ids: List of the wizard IDs (commonly the first element is the current ID)128 """
123 @param account: browse instance of account.account129 return (account.consolidation_mode or
124 @param context: A standard dictionary for contextual values130 account.user_type.consolidation_mode)
125131
126 @return: 'ytd' or 'period'132 def _periods_holding_to_subsidiary(self, cr, uid, ids, period_ids,
127 """133 subsidiary_id, context=None):
128 return account.consolidation_mode or account.user_type.consolidation_mode134 """
129135 Returns the periods of a subsidiary company which
130 def _periods_holding_to_subsidiary(self, cr, uid, ids, period_ids, subsidiary_id, context=None):136 correspond to the holding periods (same beginning and ending dates)
131 """137
132 Returns the periods of a subsidiary company which correspond to the holding periods138 :param period_ids: list of periods of the holding
133 (same beginning and ending dates)139 :param subsidiary_id: ID of the subsidiary for which
134140 we want the period IDs
135 @param self: The object pointer141
136 @param cr: the current row, from the database cursor,142 :return: list of periods of the subsidiaries
137 @param uid: the current user’s ID for security checks,
138 @param ids: List of the wizard IDs (commonly the first element is the current ID)
139 @param period_ids: list of periods of the holding
140 @param subsidiary_id: ID of the subsidiary for which we want the period IDs
141 @param context: A standard dictionary for contextual values
142
143 @return: list of periods of the subsidiaries
144 """143 """
145 period_obj = self.pool.get('account.period')144 period_obj = self.pool.get('account.period')
146 if isinstance(period_ids, (int, long)):145 if isinstance(period_ids, (int, long)):
147 period_ids = [period_ids]146 period_ids = [period_ids]
147
148 subs_period_ids = []148 subs_period_ids = []
149 for period in period_obj.browse(cr, uid, period_ids, context=context):149 for period in period_obj.browse(cr, uid, period_ids, context=context):
150 subs_period_ids.extend(period_obj.search(cr, uid,150 subs_period_ids += period_obj.search(
151 cr, uid,
151 [('date_start', '=', period.date_start),152 [('date_start', '=', period.date_start),
152 ('date_stop', '=', period.date_stop),153 ('date_stop', '=', period.date_stop),
153 ('company_id', '=', subsidiary_id)])154 ('company_id', '=', subsidiary_id)],
154 )155 context=context)
155 return subs_period_ids156 return subs_period_ids
156157
157 def create_rate_difference_line(self, cr, uid, ids, move_id, context):158 def create_rate_difference_line(self, cr, uid, ids, move_id, context):
158 """159 """
159 Create a move line for the gain/loss currency difference160 Placeholder for creation of a move line
160161 for the gain/loss currency difference
161 @param self: The object pointer162
162 @param cr: the current row, from the database cursor,163 :param move_id: ID of the move
163 @param uid: the current user’s ID for security checks,
164 @param ids: List of the wizard IDs (commonly the first element is the current ID)
165 @param move_id: ID of the move
166 @param context: A standard dictionary for contextual values
167
168 @return:
169 """164 """
170165
171 pass166 def consolidate_account(self, cr, uid, ids, consolidation_mode,
172167 subsidiary_period_ids, state, move_id,
173 def consolidate_account(self, cr, uid, ids, consolidation_mode, subsidiary_period_ids, state, move_id,
174 holding_account_id, subsidiary_id, context=None):168 holding_account_id, subsidiary_id, context=None):
175 """169 """
176 Consolidates the subsidiary account on the holding account170 Consolidates the subsidiary account on the holding account
177 Creates move lines on the move with id "move_id"171 Creates move lines on the move with id "move_id"
178172
179 @param self: The object pointer173 :param consolidation_mode: consolidate by Periods or
180 @param cr: the current row, from the database cursor,174 Year To Date ('period' or 'ytd')
181 @param uid: the current user’s ID for security checks,175 :param subsidiary_period_ids: IDs of periods for which we
182 @param ids: List of the wizard IDs (commonly the first element is the current ID)176 want to sum the debit/credit
183 @param consolidation_mode: consolidate by Periods or Year To Date ('period' or 'ytd')177 :param state: state of the moves to consolidate ('all' or 'posted')
184 @param subsidiary_period_ids: IDs of periods for which we want to sum the debit/credit178 :param move_id: ID of the move on which all the
185 @param state: state of the moves to consolidate ('all' or 'posted')179 created move lines will be linked
186 @param move_id: ID of the move on which all the created move lines will be linked180 :param holding_account_id: ID of the account to consolidate
187 @param holding_account_id: ID of the account to consolidate (on the holding), the method will find the subsidiary's corresponding account181 (on the holding), the method will
188 @param subsidiary_id: ID of the subsidiary to consolidate182 find the subsidiary's corresponding account
189 @param context: A standard dictionary for contextual values183 :param subsidiary_id: ID of the subsidiary to consolidate
190184
191 @return: list of IDs of the created move lines185 :return: list of IDs of the created move lines
192 """186 """
187 if context is None:
188 context = {}
193189
194 account_obj = self.pool.get('account.account')190 account_obj = self.pool.get('account.account')
195 move_obj = self.pool.get('account.move')191 move_obj = self.pool.get('account.move')
@@ -197,26 +193,27 @@
197 currency_obj = self.pool.get('res.currency')193 currency_obj = self.pool.get('res.currency')
198194
199 move = move_obj.browse(cr, uid, move_id, context=context)195 move = move_obj.browse(cr, uid, move_id, context=context)
200 holding_account = account_obj.browse(cr, uid, holding_account_id, context=context)196 holding_account = account_obj.browse(
197 cr, uid, holding_account_id, context=context)
201198
202 subsidiary_account_id = account_obj.search(cr, uid,199 subsidiary_account_id = account_obj.search(
203 [('code', '=', holding_account.code),200 cr, uid,
204 ('company_id', '=', subsidiary_id)],201 [('code', '=', holding_account.code),
205 context=context)202 ('company_id', '=', subsidiary_id)],
203 context=context)
206204
207 if not subsidiary_account_id:205 if not subsidiary_account_id:
208 return [] # an account may exist on the holding and not in the subsidiaries, nothing to do206 # an account may exist on the holding and not in the subsidiaries,
207 # nothing to do
208 return []
209209
210 browse_ctx = context.copy()210 browse_ctx = dict(context, state=state, periods=subsidiary_period_ids)
211 browse_ctx.update({211 # 1st item because the account's code is unique per company
212 'state': state,212 subs_account = account_obj.browse(
213 'periods': subsidiary_period_ids,213 cr, uid, subsidiary_account_id[0], context=browse_ctx)
214 })
215 # subsidiary_account_id[0] because only one account per company for one code is permitted
216 subs_account = account_obj.browse(cr, uid, subsidiary_account_id[0], context=browse_ctx)
217214
218 vals = {215 vals = {
219 'name': _("Consolidation line in %s mode") % (consolidation_mode,),216 'name': _("Consolidation line in %s mode") % consolidation_mode,
220 'account_id': holding_account.id,217 'account_id': holding_account.id,
221 'move_id': move.id,218 'move_id': move.id,
222 'journal_id': move.journal_id.id,219 'journal_id': move.journal_id.id,
@@ -225,16 +222,24 @@
225 'date': move.date222 'date': move.date
226 }223 }
227224
228 if holding_account.company_currency_id.id != subs_account.company_currency_id.id:225 if (holding_account.company_currency_id.id ==
229 currency_rate_type = self._currency_rate_type(cr, uid, ids, holding_account, context=context)226 subs_account.company_currency_id.id):
227 vals.update({
228 'debit': subs_account.debit,
229 'credit': subs_account.credit,
230 })
231 else:
232 currency_rate_type = self._currency_rate_type(
233 cr, uid, ids, holding_account, context=context)
230234
231 currency_value = currency_obj.compute(cr, uid,235 currency_value = currency_obj.compute(
232 holding_account.company_currency_id.id,236 cr, uid,
233 subs_account.company_currency_id.id,237 holding_account.company_currency_id.id,
234 subs_account.balance,238 subs_account.company_currency_id.id,
235 currency_rate_type_from=False, # means spot239 subs_account.balance,
236 currency_rate_type_to=currency_rate_type,240 currency_rate_type_from=False, # means spot
237 context=context)241 currency_rate_type_to=currency_rate_type,
242 context=context)
238 vals.update({243 vals.update({
239 'currency_id': subs_account.company_currency_id.id,244 'currency_id': subs_account.company_currency_id.id,
240 'amount_currency': subs_account.balance,245 'amount_currency': subs_account.balance,
@@ -242,72 +247,73 @@
242 'credit': currency_value < 0 and -currency_value or 0.0247 'credit': currency_value < 0 and -currency_value or 0.0
243 })248 })
244249
245 else:
246 vals.update({
247 'debit': subs_account.debit,
248 'credit': subs_account.credit,
249 })
250
251 move_line_id = move_line_obj.create(cr, uid, vals, context=context)250 move_line_id = move_line_obj.create(cr, uid, vals, context=context)
252251
253 return move_line_id252 return move_line_id
254253
255 def reverse_moves(self, cr, uid, ids, subsidiary_id, journal_id, reversal_date, context):254 def reverse_moves(self, cr, uid, ids, subsidiary_id, journal_id,
255 reversal_date, context=None):
256 """256 """
257 Reverse all account moves of a journal which have the "To be reversed" flag257 Reverse all account moves of a journal which have
258258 the "To be reversed" flag
259 @param self: The object pointer259
260 @param cr: the current row, from the database cursor,260 :param subsidiary_id: ID of the subsidiary moves to reverse
261 @param uid: the current user’s ID for security checks,261 :param journal_id: ID of the journal with moves to reverse
262 @param ids: List of the wizard IDs (commonly the first element is the current ID)262 :param reversal_date: date when to create the reversal
263 @param subsidiary_id: ID of the subsidiary moves to reverse263
264 @param journal_id: ID of the journal with moves to reverse264 :return: tuple with : list of IDs of the reversed moves,
265 @param reversal_date: date when to create the reversal265 list of IDs of the reversal moves
266 @param context: A standard dictionary for contextual values
267
268 @return: tuple with : list of IDs of the reversed moves, list of IDs of the reversal moves
269 """266 """
270 move_obj = self.pool.get('account.move')267 move_obj = self.pool.get('account.move')
271 reversed_ids = move_obj.search(cr, uid,268 reversed_ids = move_obj.search(
272 [('journal_id', '=', journal_id),269 cr, uid,
273 ('to_be_reversed', '=', True),270 [('journal_id', '=', journal_id),
274 ('consol_company_id', '=', subsidiary_id)],271 ('to_be_reversed', '=', True),
275 context=context)272 ('consol_company_id', '=', subsidiary_id)],
276 reversal_ids = move_obj.create_reversals(cr, uid, reversed_ids, reversal_date, context=context)273 context=context)
274 reversal_ids = move_obj.create_reversals(
275 cr, uid, reversed_ids, reversal_date, context=context)
277 return reversed_ids, reversal_ids276 return reversed_ids, reversal_ids
278277
279 def consolidate_subsidiary(self, cr, uid, ids, subsidiary_id, context=None):278 def consolidate_subsidiary(self, cr, uid, ids,
279 subsidiary_id, context=None):
280 """280 """
281 Consolidate one subsidiary on the Holding.281 Consolidate one subsidiary on the Holding.
282 Create a move per subsidiary and consolidation type (YTD/Period)282 Create a move per subsidiary and consolidation type (YTD/Period)
283 and an move line per account of the subsidiary283 and an move line per account of the subsidiary
284 Plus a move line for the currency gain / loss # FIXME to check!284
285 285 :param subsidiary_id: ID of the subsidiary to consolidate
286 @param self: The object pointer286 on the holding
287 @param cr: the current row, from the database cursor,287
288 @param uid: the current user’s ID for security checks,288 :return: Tuple of form:
289 @param ids: List of the wizard IDs (commonly the first element is the current ID)289 (list of IDs of the YTD moves,
290 @param subsidiary_id: ID of the subsidiary to consolidate on the holding290 list of IDs of the Period Moves)
291 @param context: A standard dictionary for contextual values
292
293 @return: Tuple of (list of IDs of the YTD moves, list of IDs of the Period Moves)
294 """291 """
295292 if context is None:
296 context = context or {}293 context = {}
294
295 if isinstance(ids, (int, long)):
296 ids = [ids]
297 assert len(ids) == 1, "only 1 id expected"
298
297 company_obj = self.pool.get('res.company')299 company_obj = self.pool.get('res.company')
298 move_obj = self.pool.get('account.move')300 move_obj = self.pool.get('account.move')
299 period_obj = self.pool.get('account.period')301 period_obj = self.pool.get('account.period')
302
300 form = self.browse(cr, uid, ids[0], context=context)303 form = self.browse(cr, uid, ids[0], context=context)
301 subsidiary = company_obj.browse(cr, uid, subsidiary_id, context=None)304 subsidiary = company_obj.browse(cr, uid, subsidiary_id, context=None)
302305
303 data_ctx = context.copy()306 data_ctx = dict(context, holding_coa=True)
304 data_ctx.update({'holding_coa': True})307 holding_accounts_data = self._chart_accounts_data(
305 holding_accounts_data = self._chart_accounts_data(cr, uid, ids,308 cr, uid,
306 form.holding_chart_account_id.id,309 ids,
307 context=data_ctx)310 form.holding_chart_account_id.id,
308 subs_accounts_codes = self._chart_accounts_data(cr, uid, ids,311 context=data_ctx)
309 subsidiary.consolidation_chart_account_id.id,312 subs_accounts_codes = self._chart_accounts_data(
310 context=context)313 cr, uid,
314 ids,
315 subsidiary.consolidation_chart_account_id.id,
316 context=context)
311 holding_accounts = [values for key, values317 holding_accounts = [values for key, values
312 in holding_accounts_data.iteritems()318 in holding_accounts_data.iteritems()
313 if key in subs_accounts_codes]319 if key in subs_accounts_codes]
@@ -316,12 +322,14 @@
316 # a move per type will be created322 # a move per type will be created
317 consolidation_modes = {'ytd': [], 'period': []}323 consolidation_modes = {'ytd': [], 'period': []}
318 for account in holding_accounts:324 for account in holding_accounts:
319 cm = self._consolidation_mode(cr, uid, ids, account, context=context)325 cm = self._consolidation_mode(
326 cr, uid, ids, account, context=context)
320 consolidation_modes[cm].append(account)327 consolidation_modes[cm].append(account)
321328
322 period_ids = period_obj.build_ctx_periods(cr, uid,329 period_ids = period_obj.build_ctx_periods(
323 form.from_period_id.id,330 cr, uid,
324 form.to_period_id.id)331 form.from_period_id.id,
332 form.to_period_id.id)
325333
326 generic_move_vals = {334 generic_move_vals = {
327 'journal_id': form.journal_id.id,335 'journal_id': form.journal_id.id,
@@ -337,15 +345,18 @@
337345
338 # get list of periods for which we have to create a move346 # get list of periods for which we have to create a move
339 # in period mode : a move per period347 # in period mode : a move per period
340 # in ytd mode : a move at the last period (which will contains lines from 1st january to last period)348 # in ytd mode : a move at the last period
341 move_period_ids = consolidation_mode == 'period' \349 # (which will contains lines from 1st january to last period)
342 and period_ids \350 move_period_ids = (period_ids
343 or [form.to_period_id.id]351 if consolidation_mode == 'period'
352 else [form.to_period_id.id])
344353
345 for move_period_id in move_period_ids:354 for move_period_id in move_period_ids:
346 period = period_obj.browse(cr, uid, move_period_id, context=context)355 period = period_obj.browse(
356 cr, uid, move_period_id, context=context)
347357
348 # in ytd we compute the amount from the first day of the fiscal year358 # in ytd we compute the amount from the first
359 # day of the fiscal year
349 # in period, only for the period360 # in period, only for the period
350 if consolidation_mode == 'ytd':361 if consolidation_mode == 'ytd':
351 date_from = period.fiscalyear_id.date_start362 date_from = period.fiscalyear_id.date_start
@@ -353,50 +364,51 @@
353 date_from = period.date_start364 date_from = period.date_start
354 date_to = period.date_stop365 date_to = period.date_stop
355366
356 period_ctx = context.copy()367 period_ctx = dict(context, company_id=subsidiary.id)
357 period_ctx.update({368 compute_from_period_id = period_obj.find(
358 'company_id': subsidiary.id,369 cr, uid, date_from, context=period_ctx)[0]
359 })370 compute_to_period_id = period_obj.find(
360 compute_from_period_id = period_obj.find(cr, uid, date_from, context=period_ctx)[0]371 cr, uid, date_to, context=period_ctx)[0]
361 compute_to_period_id = period_obj.find(cr, uid, date_to, context=period_ctx)[0]372 compute_period_ids = period_obj.build_ctx_periods(
362 compute_period_ids = period_obj.build_ctx_periods(cr, uid,373 cr, uid,
363 compute_from_period_id,374 compute_from_period_id,
364 compute_to_period_id)375 compute_to_period_id)
365376
366 # reverse previous entries with flag 'to_be_reversed' (YTD)377 # reverse previous entries with flag 'to_be_reversed' (YTD)
367 self.reverse_moves(cr, uid, ids, subsidiary.id, form.journal_id.id, date_to, context=context)378 self.reverse_moves(
368379 cr, uid,
369 # TODO if moves found for the same period : skip ?380 ids,
381 subsidiary.id,
382 form.journal_id.id,
383 date_to,
384 context=context)
370385
371 # create the account move386 # create the account move
372 # at the very last date of the end period387 # at the very last date of the end period
373 move_vals = generic_move_vals.copy()388 move_vals = dict(
374 move_vals.update({389 generic_move_vals,
375 'ref': _("Consolidation %s") % (consolidation_mode,),390 ref=_("Consolidation %s") % consolidation_mode,
376 'period_id': period.id,391 period_id=period.id,
377 'date': period.date_stop,392 date=period.date_stop)
378 })
379 move_id = move_obj.create(cr, uid, move_vals, context=context)393 move_id = move_obj.create(cr, uid, move_vals, context=context)
380394
381 move_line_ids = []395 move_line_ids = []
382 # create a move line per account396 # create a move line per account
383 for account in accounts:397 for account in accounts:
384 move_line_ids.append(398 move_line_ids.append(
385 self.consolidate_account(cr, uid, ids,399 self.consolidate_account(
386 consolidation_mode,400 cr, uid, ids,
387 compute_period_ids,401 consolidation_mode,
388 form.target_move,402 compute_period_ids,
389 move_id,403 form.target_move,
390 account.id,404 move_id,
391 subsidiary.id,405 account.id,
392 context=context)406 subsidiary.id,
407 context=context)
393 )408 )
394409
395 # TODO calculate currency rate difference (all move lines debit - all move lines credit) and post a move line410 self.create_rate_difference_line(
396 # on the gain / loss account411 cr, uid, ids, move_id, context=context)
397 # will works IF : counterparts are always configured with the same mode (YTD/Periods)
398 self.create_rate_difference_line(cr, uid, ids,
399 move_id, context=context)
400412
401 locals()[consolidation_mode + '_move_ids'].append(move_id)413 locals()[consolidation_mode + '_move_ids'].append(move_id)
402414
@@ -407,15 +419,10 @@
407 Consolidate all selected subsidiaries Virtual Chart of Accounts419 Consolidate all selected subsidiaries Virtual Chart of Accounts
408 on the Holding Chart of Account420 on the Holding Chart of Account
409421
410 @param self: The object pointer422 :return: dict to open an Entries view filtered on the created moves
411 @param cr: the current row, from the database cursor,
412 @param uid: the current user’s ID for security checks,
413 @param ids: List of the wizard IDs (commonly the first element is the current ID)
414 @param context: A standard dictionary for contextual values
415
416 @return: dict to open an Entries view filtered on the created moves
417 """423 """
418 super(account_consolidation_consolidate, self).run_consolidation(cr, uid, ids, context=context)424 super(account_consolidation_consolidate, self).run_consolidation(
425 cr, uid, ids, context=context)
419426
420 mod_obj = self.pool.get('ir.model.data')427 mod_obj = self.pool.get('ir.model.data')
421 act_obj = self.pool.get('ir.actions.act_window')428 act_obj = self.pool.get('ir.actions.act_window')
@@ -425,20 +432,23 @@
425 move_ids = []432 move_ids = []
426 ytd_move_ids = []433 ytd_move_ids = []
427 for subsidiary in form.subsidiary_ids:434 for subsidiary in form.subsidiary_ids:
428 new_move_ids = self.consolidate_subsidiary(cr, uid, ids, subsidiary.id, context=context)435 new_move_ids = self.consolidate_subsidiary(
429 ytd_move_ids.extend(new_move_ids[0])436 cr, uid, ids, subsidiary.id, context=context)
430 move_ids.extend(sum(new_move_ids, []))437 ytd_move_ids += new_move_ids[0]
438 move_ids += sum(new_move_ids, [])
431439
432 # YTD moves have to be reversed on the next consolidation440 # YTD moves have to be reversed on the next consolidation
433 move_obj.write(cr, uid, ytd_move_ids, {'to_be_reversed': True}, context=context)441 move_obj.write(
442 cr, uid,
443 ytd_move_ids,
444 {'to_be_reversed': True},
445 context=context)
434446
435 context.update({'move_ids': move_ids})447 context.update({'move_ids': move_ids})
436 action_ref = mod_obj.get_object_reference(cr, uid, 'account', 'action_move_journal_line')448 __, action_id = mod_obj.get_object_reference(
437 action_id = action_ref and action_ref[1] or False449 cr, uid, 'account', 'action_move_journal_line')
438 action = act_obj.read(cr, uid, [action_id], context=context)[0]450 action = act_obj.read(cr, uid, [action_id], context=context)[0]
439 action['domain'] = unicode([('id', 'in', move_ids)])451 action['domain'] = unicode([('id', 'in', move_ids)])
440 action['name'] = _('Consolidated Entries')452 action['name'] = _('Consolidated Entries')
441 action['context'] = unicode({'search_default_to_be_reversed': 0})453 action['context'] = unicode({'search_default_to_be_reversed': 0})
442 return action454 return action
443
444account_consolidation_consolidate()
445455
=== modified file 'account_consolidation/wizard/consolidation_consolidate_view.xml'
--- account_consolidation/wizard/consolidation_consolidate_view.xml 2011-08-29 05:45:40 +0000
+++ account_consolidation/wizard/consolidation_consolidate_view.xml 2013-01-09 09:53:22 +0000
@@ -2,39 +2,49 @@
2<openerp>2<openerp>
3 <data>3 <data>
44
5 <record id="view_consolidation_consolidate_form" model="ir.ui.view">5 <record id="view_consolidation_consolidate_form" model="ir.ui.view">
6 <field name="name">account.consolidation.consolidate.form</field>6 <field name="name">account.consolidation.consolidate.form</field>
7 <field name="model">account.consolidation.consolidate</field>7 <field name="model">account.consolidation.consolidate</field>
8 <field name="type">form</field>8 <field name="type">form</field>
9 <field name="arch" type="xml">9 <field name="arch" type="xml">
10 <form string="Consolidation: Consolidate">10 <form string="Consolidation: Consolidate" version="7.0">
11 <group col="4" colspan="6">11 <label string="Run the consolidation for the selected periods and subsidiaries."/>
12 <field name="company_id" on_change="on_change_company_id(company_id)" invisible="True"/>12 <group>
13 <field name="fiscalyear_id" invisible="True"/>13 <field name="company_id"
14 <field name="from_period_id" on_change="on_change_from_period_id(from_period_id, to_period_id)" domain="[('company_id', '=', company_id)]"/>14 on_change="on_change_company_id(company_id)"
15 <field name="to_period_id" domain="[('company_id', '=', company_id)]"/>15 invisible="True"/>
16 <field name="journal_id" domain="[('company_id', '=', company_id)]"/>16 <field name="fiscalyear_id" invisible="True"/>
17 <field name="target_move"/>17 <field name="from_period_id"
18 <separator string="Holding Chart of Accounts" colspan="4"/>18 on_change="on_change_from_period_id(from_period_id, to_period_id)"
19 <field name="holding_chart_account_id" domain="[('company_id', '=', company_id), ('parent_id', '=', False)]"/>19 domain="[('company_id', '=', company_id)]"/>
20 <field name="to_period_id"
21 domain="[('company_id', '=', company_id)]"/>
22 <field name="journal_id"
23 domain="[('company_id', '=', company_id)]"/>
24 <field name="target_move"/>
25 <separator string="Holding Chart of Accounts" colspan="4"/>
26 <field name="holding_chart_account_id"
27 domain="[('company_id', '=', company_id), ('parent_id', '=', False)]"/>
2028
21 <!--<separator string="Consolidation Difference Accounts" colspan="4"/>-->29 <separator string="Subsidiaries to Consolidate" colspan="4"/>
22 <!--<field name="gain_account_id" domain="[('type','&lt;&gt;','view'), ('id', 'child_of', [holding_chart_account_id])]"/>-->30 <field name="subsidiary_ids" colspan="4"
23 <!--<field name="loss_account_id" domain="[('type','&lt;&gt;','view'), ('id', 'child_of', [holding_chart_account_id])]"/>-->31 nolabel="1" required="True">
24 <separator string="Subsidiaries to Consolidate" colspan="4"/>32 <tree>
25 <field name="subsidiary_ids" colspan="4" nolabel="1" required="True">33 <field name="name"/>
26 <tree>34 <field name="consolidation_chart_account_id"/>
27 <field name="name"/>35 </tree>
28 <field name="consolidation_chart_account_id"/>36 </field>
29 </tree>37 </group>
30 </field>38 <separator colspan="4"/>
31 </group>39 <footer>
32 <separator colspan="4"/>40 <button name="run_consolidation"
33 <group col="2" colspan="4">41 string="Consolidate"
34 <button special="cancel" string="Cancel" icon='gtk-cancel'/>42 type="object"
35 <button name="run_consolidation" string="Consolidate" colspan="1" type="object" icon="gtk-execute"/>43 class="oe_highlight"/>
36 </group>44 or
37 </form>45 <button string="Cancel" class="oe_link" special="cancel"/>
46 </footer>
47 </form>
38 </field>48 </field>
39 </record>49 </record>
4050
@@ -44,9 +54,8 @@
44 <field name="res_model">account.consolidation.consolidate</field>54 <field name="res_model">account.consolidation.consolidate</field>
45 <field name="view_type">form</field>55 <field name="view_type">form</field>
46 <field name="view_mode">form</field>56 <field name="view_mode">form</field>
47 <field name="help">Run the consolidation for the selected periods and subsidiaries.</field>
48 <field name="target">new</field>57 <field name="target">new</field>
49 </record>58 </record>
5059
51 </data>60 </data>
52</openerp>61</openerp>

Subscribers

People subscribed via source and target branches