Merge lp:~camptocamp/account-consolidation/7.0-fix_1334639-afe into lp:~account-core-editors/account-consolidation/6.1

Proposed by Alexandre Fayolle - camptocamp on 2014-06-26
Status: Needs review
Proposed branch: lp:~camptocamp/account-consolidation/7.0-fix_1334639-afe
Merge into: lp:~account-core-editors/account-consolidation/6.1
Diff against target: 5877 lines (+4196/-909)
40 files modified
account_consolidation/__init__.py (+4/-3)
account_consolidation/__openerp__.py (+67/-67)
account_consolidation/account.py (+56/-59)
account_consolidation/account_move_line.py (+52/-0)
account_consolidation/account_move_line_view.xml (+30/-0)
account_consolidation/account_view.xml (+7/-6)
account_consolidation/analysis_view.xml (+39/-0)
account_consolidation/company.py (+38/-41)
account_consolidation/company_view.xml (+2/-1)
account_consolidation/consolidation_menu.xml (+3/-0)
account_consolidation/data.xml (+13/-0)
account_consolidation/demo/consolidation_demo.xml (+17/-19)
account_consolidation/i18n/account_consolidation.pot (+488/-0)
account_consolidation/i18n/fr.po (+488/-0)
account_consolidation/test/consolidation_checks.yml (+4/-3)
account_consolidation/test/test_data.yml (+147/-147)
account_consolidation/wizard/consolidation_base.py (+251/-166)
account_consolidation/wizard/consolidation_check.py (+91/-84)
account_consolidation/wizard/consolidation_check_view.xml (+43/-24)
account_consolidation/wizard/consolidation_consolidate.py (+321/-259)
account_consolidation/wizard/consolidation_consolidate_view.xml (+39/-30)
account_parallel_currency/AUTHORS.txt (+1/-0)
account_parallel_currency/__init__.py (+23/-0)
account_parallel_currency/__openerp__.py (+56/-0)
account_parallel_currency/account.py (+506/-0)
account_parallel_currency/account_demo.xml (+504/-0)
account_parallel_currency/account_view.xml (+64/-0)
account_parallel_currency/company_view.xml (+16/-0)
account_parallel_currency/i18n/account_parallel_currency.pot (+343/-0)
account_parallel_currency/res_company.py (+33/-0)
account_parallel_currency/security/security.xml (+11/-0)
account_parallel_currency/test/customer_invoice.yml (+143/-0)
account_parallel_currency/test/mapping_parallel_accounts.yml (+25/-0)
account_parallel_currency/wizard/__init__.py (+22/-0)
account_parallel_currency/wizard/do_mapping.py (+92/-0)
account_parallel_currency/wizard/do_mapping.xml (+32/-0)
account_parallel_currency_centralized/__init__.py (+21/-0)
account_parallel_currency_centralized/__openerp__.py (+40/-0)
account_parallel_currency_centralized/account.py (+53/-0)
account_parallel_currency_centralized/account_demo.xml (+11/-0)
To merge this branch: bzr merge lp:~camptocamp/account-consolidation/7.0-fix_1334639-afe
Reviewer Review Type Date Requested Status
Lorenzo Battistini (community) 2014-06-26 Resubmit on 2014-06-26
Account Core Editors 2014-06-26 Pending
Review via email: mp+224629@code.launchpad.net

Description of the change

add link module between account_parallel_currency and account_financial_report_webkit to replace code removed in https://code.launchpad.net/~agilebg/account-consolidation/7.0-bug-1296740-elbati/+merge/212487

Note that this MP removes the specific code originally found in account.tax.code, since AFAIK there is no centralized field on this model and I thought it was likely a copy-paste error.

To post a comment you must log in.
Lorenzo Battistini (elbati) wrote :

wrong target

review: Resubmit

Unmerged revisions

23. By Alexandre Fayolle - camptocamp on 2014-06-26

new link module account_parallel_currency_centralized

linking account_parallel_currency and account_financial_report_webkit

22. By Lorenzo Battistini on 2014-06-26

[MRG] fix usage of undefined field 'centralized'

21. By Nicolas Bessi - Camptocamp on 2014-04-28

[FIX] missing domain in multi currency consolidation

20. By Vincent Renaville@camptocamp on 2014-01-09

[MRG] - Translations
      - Add a check to see if all "normal" account is linked to a consolidated account
      - Add label in consolidation check wizard to help the user to understand the check test purpose

19. By Pedro Manuel Baeza on 2013-11-11

[IMP] Translation template files for all modules.

18. By Maxime Chambreuil (http://www.savoirfairelinux.com) on 2013-09-30

[MRG] This module handles parallel accounting entries based on different currencies.

17. By Nicolas Bessi - Camptocamp on 2013-03-22

[MRG] bug fixes for lp:1149429 and lp:1133189

16. By Joël Grand-Guillaume @ camptocamp on 2013-01-14

[MIGR] Migration of account_consolidation to OpenERP version 7.0

15. By Guewen Baconnier @ Camptocamp on 2013-01-04

[MIGR] set modules not installable (need migration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'account_consolidation/__init__.py'
2--- account_consolidation/__init__.py 2011-08-12 15:39:07 +0000
3+++ account_consolidation/__init__.py 2014-06-26 13:58:55 +0000
4@@ -1,3 +1,4 @@
5-import company
6-import account
7-import wizard
8+from . import company
9+from . import account
10+from . import account_move_line
11+from . import wizard
12
13=== modified file 'account_consolidation/__openerp__.py'
14--- account_consolidation/__openerp__.py 2012-04-11 07:52:09 +0000
15+++ account_consolidation/__openerp__.py 2014-06-26 13:58:55 +0000
16@@ -1,72 +1,72 @@
17 # -*- coding: utf-8 -*-
18 ##############################################################################
19 #
20-# Copyright (c) 2011 Camptocamp SA (http://www.camptocamp.com)
21-# All Right Reserved
22-#
23-# Author : Guewen Baconnier (Camptocamp)
24-#
25-# WARNING: This program as such is intended to be used by professional
26-# programmers who take the whole responsability of assessing all potential
27-# consequences resulting from its eventual inadequacies and bugs
28-# End users who are looking for a ready-to-use solution with commercial
29-# garantees and support are strongly adviced to contract a Free Software
30-# Service Company
31-#
32-# This program is Free Software; you can redistribute it and/or
33-# modify it under the terms of the GNU General Public License
34-# as published by the Free Software Foundation; either version 2
35-# of the License, or (at your option) any later version.
36-#
37-# This program is distributed in the hope that it will be useful,
38-# but WITHOUT ANY WARRANTY; without even the implied warranty of
39-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
40-# GNU General Public License for more details.
41-#
42-# You should have received a copy of the GNU General Public License
43-# along with this program; if not, write to the Free Software
44-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
45+# Author: Guewen Baconnier
46+# Copyright 2011-2013 Camptocamp SA
47+#
48+# This program is free software: you can redistribute it and/or modify
49+# it under the terms of the GNU Affero General Public License as
50+# published by the Free Software Foundation, either version 3 of the
51+# License, or (at your option) any later version.
52+#
53+# This program is distributed in the hope that it will be useful,
54+# but WITHOUT ANY WARRANTY; without even the implied warranty of
55+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
56+# GNU Affero General Public License for more details.
57+#
58+# You should have received a copy of the GNU Affero General Public License
59+# along with this program. If not, see <http://www.gnu.org/licenses/>.
60 #
61 ##############################################################################
62-
63-
64-{
65- "name" : "Account Consolidation",
66- "version" : "0.0",
67- "author" : "Camptocamp",
68- "category" : "Generic Modules/Accounting",
69- "description":
70-"""
71-Account consolidation module. Coding in progress...
72-
73-Some explanations to do...
74-
75- - Difference between debit/credit is balanced on the debit/credit default account of the journal?
76-""",
77- "website": "http://www.camptocamp.com",
78- "depends" : [
79- 'base',
80- 'account',
81- 'account_reversal',
82- ],
83- "init_xml" : [],
84- "demo_xml" : [
85- 'demo/consolidation_demo.xml',
86- 'demo/chart_a_demo.xml',
87- 'demo/chart_b_demo.xml',
88- ],
89- "update_xml" : [
90- 'company_view.xml',
91- 'account_view.xml',
92- 'wizard/consolidation_check_view.xml',
93- 'wizard/consolidation_consolidate_view.xml',
94- 'consolidation_menu.xml',
95- ],
96- 'test': [
97- 'test/test_data.yml',
98- 'test/consolidation_checks.yml',
99- 'test/consolidation_consolidate.yml',
100- ],
101- "active": False,
102- "installable": True
103-}
104+{"name": "Account Consolidation",
105+ "version": "1.0",
106+ "author": "Camptocamp",
107+ "license": "AGPL-3",
108+ "category": "Generic Modules/Accounting",
109+ "description": """
110+Account consolidation
111+=====================
112+
113+Introduction
114+------------
115+
116+Consolidate chart of accounts on subsidiaries
117+in a virtual chart of accounts of the holding.
118+
119+Installation
120+------------
121+The `account_reversal` module is required,
122+it can be found on the account-financial-tools_
123+project
124+
125+.. _account-financial-tools: https://launchpad.net/account-financial-tools""",
126+
127+ "website": "http://www.camptocamp.com",
128+ "depends": ['base',
129+ 'account',
130+ 'account_reversal', # TODO check account_constraints compat.
131+ ],
132+
133+ "demo_xml": ['demo/consolidation_demo.xml',
134+ 'demo/chart_a_demo.xml',
135+ 'demo/chart_b_demo.xml',
136+ ],
137+
138+ "data": ['data.xml',
139+ 'account_move_line_view.xml',
140+ 'company_view.xml',
141+ 'account_view.xml',
142+ 'wizard/consolidation_check_view.xml',
143+ 'wizard/consolidation_consolidate_view.xml',
144+ 'consolidation_menu.xml',
145+ 'analysis_view.xml'
146+ ],
147+
148+ "test": ['test/test_data.yml',
149+ 'test/consolidation_checks.yml',
150+ 'test/consolidation_consolidate.yml',
151+ ],
152+
153+ "active": False,
154+ "installable": True,
155+ }
156
157=== modified file 'account_consolidation/account.py'
158--- account_consolidation/account.py 2011-08-29 14:04:57 +0000
159+++ account_consolidation/account.py 2014-06-26 13:58:55 +0000
160@@ -1,77 +1,74 @@
161 # -*- coding: utf-8 -*-
162 ##############################################################################
163 #
164-# Copyright (c) 2011 Camptocamp SA (http://www.camptocamp.com)
165-#
166-# Author : Guewen Baconnier (Camptocamp)
167-#
168-# WARNING: This program as such is intended to be used by professional
169-# programmers who take the whole responsability of assessing all potential
170-# consequences resulting from its eventual inadequacies and bugs
171-# End users who are looking for a ready-to-use solution with commercial
172-# garantees and support are strongly adviced to contract a Free Software
173-# Service Company
174-#
175-# This program is Free Software; you can redistribute it and/or
176-# modify it under the terms of the GNU General Public License
177-# as published by the Free Software Foundation; either version 2
178-# of the License, or (at your option) any later version.
179-#
180-# This program is distributed in the hope that it will be useful,
181-# but WITHOUT ANY WARRANTY; without even the implied warranty of
182-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
183-# GNU General Public License for more details.
184-#
185-# You should have received a copy of the GNU General Public License
186-# along with this program; if not, write to the Free Software
187-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
188+# Author: Guewen Baconnier
189+# Copyright 2011-2013 Camptocamp SA
190+#
191+# This program is free software: you can redistribute it and/or modify
192+# it under the terms of the GNU Affero General Public License as
193+# published by the Free Software Foundation, either version 3 of the
194+# License, or (at your option) any later version.
195+#
196+# This program is distributed in the hope that it will be useful,
197+# but WITHOUT ANY WARRANTY; without even the implied warranty of
198+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
199+# GNU Affero General Public License for more details.
200+#
201+# You should have received a copy of the GNU Affero General Public License
202+# along with this program. If not, see <http://www.gnu.org/licenses/>.
203 #
204 ##############################################################################
205
206-from osv import osv, fields
207-
208-
209-class account_account(osv.osv):
210+from openerp.osv import orm, fields
211+
212+
213+class account_account(orm.Model):
214 _inherit = 'account.account'
215
216 _columns = {
217- 'consolidation_rate_type_id': fields.many2one('res.currency.rate.type',
218- 'Consolidation Currency Rate Type',
219- help="Currency rate type used on this account for the consolidation, Leave empty to use the rate type of the account type."),
220- 'consolidation_mode': fields.selection([('', ''),
221- ('ytd', 'YTD'),
222- ('period', 'Period Movements'),
223- ],
224- 'Consolidation Mode'),
225+ 'consolidation_rate_type_id': fields.many2one(
226+ 'res.currency.rate.type',
227+ 'Consolidation Currency Rate Type',
228+ help="Currency rate type used on this account "
229+ "for the consolidation. "
230+ "Leave empty to use the rate type of the account type."),
231+
232+ 'consolidation_mode': fields.selection(
233+ [('ytd', 'YTD'),
234+ ('period', 'Period Movements')],
235+ 'Consolidation Mode',
236+ help="This must be set on the holding company accounts only"),
237 }
238
239-account_account()
240-
241-
242-class account_account_type(osv.osv):
243+
244+class account_account_type(orm.Model):
245 _inherit = 'account.account.type'
246
247 _columns = {
248- 'consolidation_rate_type_id': fields.many2one('res.currency.rate.type',
249- 'Consolidation Currency Rate Type',
250- help="Currency rate type used on this account type for the consolidation, Leave empty to use the 'spot' rate type."),
251- 'consolidation_mode': fields.selection([('ytd', 'YTD'),
252- ('period', 'Period Movements'),],
253- 'Consolidation Mode'),
254- }
255-
256- _defaults = {
257- 'consolidation_mode': 'ytd',
258- }
259-
260-account_account_type()
261-
262-
263-class account_move(osv.osv):
264+ 'consolidation_rate_type_id': fields.many2one(
265+ 'res.currency.rate.type',
266+ 'Consolidation Currency Rate Type',
267+ help="Currency rate type used on this account type "
268+ "for the consolidation. "
269+ "Leave empty to use the 'spot' rate type."),
270+
271+ 'consolidation_mode': fields.selection(
272+ [('ytd', 'YTD'),
273+ ('period', 'Period Movements')],
274+ 'Consolidation Mode',
275+ help="This must be set on the holding company accounts only"),
276+
277+ }
278+
279+ _defaults = {'consolidation_mode': 'ytd'}
280+
281+
282+class account_move(orm.Model):
283 _inherit = 'account.move'
284
285 _columns = {
286- 'consol_company_id': fields.many2one('res.company', 'Consolidated from Company', readonly=True),
287+ 'consol_company_id': fields.many2one(
288+ 'res.company',
289+ 'Consolidated from Company',
290+ readonly=True),
291 }
292-
293-account_move()
294
295=== added file 'account_consolidation/account_move_line.py'
296--- account_consolidation/account_move_line.py 1970-01-01 00:00:00 +0000
297+++ account_consolidation/account_move_line.py 2014-06-26 13:58:55 +0000
298@@ -0,0 +1,52 @@
299+# -*- coding: utf-8 -*-
300+##############################################################################
301+#
302+# Author: Nicolas Bessi Guewen Baconnier
303+# Copyright 2011-2013 Camptocamp SA
304+#
305+# This program is free software: you can redistribute it and/or modify
306+# it under the terms of the GNU Affero General Public License as
307+# published by the Free Software Foundation, either version 3 of the
308+# License, or (at your option) any later version.
309+#
310+# This program is distributed in the hope that it will be useful,
311+# but WITHOUT ANY WARRANTY; without even the implied warranty of
312+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
313+# GNU Affero General Public License for more details.
314+#
315+# You should have received a copy of the GNU Affero General Public License
316+# along with this program. If not, see <http://www.gnu.org/licenses/>.
317+#
318+##############################################################################
319+
320+from openerp.osv import orm, fields
321+
322+
323+class AccountMoveLine(orm.Model):
324+ _inherit = 'account.move.line'
325+
326+ def _current_company(self, cursor, uid, ids, name, args, context=None):
327+ company_id = self.pool['res.company']._company_default_get(cursor, uid)
328+ curr_ids = self.search(cursor, uid, [('company_id', '=', company_id),
329+ ('id', 'in', ids)])
330+ res = dict([(tid, tid in curr_ids) for tid in ids])
331+ return res
332+
333+
334+ def search_is_current_company(self, cursor, uid, obj, name, args, context=None):
335+ company_id = self.pool['res.company']._company_default_get(cursor, uid)
336+ res = self.search(cursor, uid, [('company_id', '=', company_id)])
337+ return [('id', 'in', res)]
338+
339+ _columns = {'consol_company_id': fields.related('move_id', 'consol_company_id',
340+ relation='res.company',
341+ type="many2one",
342+ string='Subsidaries',
343+ store=True, # for the group_by
344+ readonly=True),
345+
346+ 'is_current_company': fields.function(_current_company,
347+ string="Current company",
348+ type="boolean",
349+ fnct_search=search_is_current_company)
350+ }
351
352=== added file 'account_consolidation/account_move_line_view.xml'
353--- account_consolidation/account_move_line_view.xml 1970-01-01 00:00:00 +0000
354+++ account_consolidation/account_move_line_view.xml 2014-06-26 13:58:55 +0000
355@@ -0,0 +1,30 @@
356+<openerp>
357+ <data>
358+ <record id="view_move_line_tree" model="ir.ui.view">
359+ <field name="name">account.move.line.tree.conso</field>
360+ <field name="model">account.move.line</field>
361+ <field name="inherit_id" ref="account.view_move_line_tree"/>
362+ <field name="arch" type="xml">
363+ <field name="date" position="before">
364+ <field name="consol_company_id"
365+ groups="account_consolidation.consolidation_manager,account_consolidation.consolidation_user"/>
366+ <field name="is_current_company" invisible="1"/>
367+ </field>
368+ </field>
369+ </record>
370+
371+ <record id="view_account_move_line_filter" model="ir.ui.view">
372+ <field name="name">Journal Items conso</field>
373+ <field name="model">account.move.line</field>
374+ <field name="inherit_id" ref="account.view_account_move_line_filter"/>
375+ <field name="arch" type="xml">
376+ <filter string="Period" position="after">
377+ <filter string="Subsidaries"
378+ icon="terp-folder-green"
379+ context="{'group_by':'consol_company_id'}"
380+ groups="account_consolidation.consolidation_manager,account_consolidation.consolidation_user"/>
381+ </filter>
382+ </field>
383+ </record>
384+ </data>
385+</openerp>
386
387=== modified file 'account_consolidation/account_view.xml'
388--- account_consolidation/account_view.xml 2011-08-29 14:04:57 +0000
389+++ account_consolidation/account_view.xml 2014-06-26 13:58:55 +0000
390@@ -9,8 +9,8 @@
391 <field name="type">form</field>
392 <field name="arch" type="xml">
393 <data>
394- <xpath expr="/form/notebook/page[@string='General Information']/group[2]" position="after">
395- <group col="2" colspan="2">
396+ <xpath expr="//field[@name='note']" position="after">
397+ <group groups="account_consolidation.consolidation_manager">
398 <separator string="Consolidation" colspan="2"/>
399 <field name="consolidation_rate_type_id" widget="selection"/>
400 <field name="consolidation_mode"/>
401@@ -20,7 +20,7 @@
402 </data>
403 </field>
404 </record>
405-
406+
407 <record id="view_account_type_consolidation_form" model="ir.ui.view">
408 <field name="name">account.account.type.consolidation.form</field>
409 <field name="model">account.account.type</field>
410@@ -28,7 +28,7 @@
411 <field name="type">form</field>
412 <field name="arch" type="xml">
413 <separator string="Description" position="before">
414- <group col="2" colspan="2">
415+ <group col="2" colspan="2" groups="account_consolidation.consolidation_manager">
416 <separator string="Consolidation" colspan="4"/>
417 <field name="consolidation_rate_type_id" widget="selection"/>
418 <field name="consolidation_mode"/>
419@@ -44,11 +44,12 @@
420 <field name="type">form</field>
421 <field name="arch" type="xml">
422 <field name="company_id" position="after">
423- <field name="consol_company_id" attrs="{'invisible': [('consol_company_id', '=', False)]}"/>
424+ <field name="consol_company_id"
425+ attrs="{'invisible': [('consol_company_id', '=', False)]}"
426+ groups="account_consolidation.consolidation_manager,account_consolidation.consolidation_user"/>
427 </field>
428 </field>
429 </record>
430
431 </data>
432 </openerp>
433-
434
435=== added file 'account_consolidation/analysis_view.xml'
436--- account_consolidation/analysis_view.xml 1970-01-01 00:00:00 +0000
437+++ account_consolidation/analysis_view.xml 2014-06-26 13:58:55 +0000
438@@ -0,0 +1,39 @@
439+<openerp>
440+ <data>
441+
442+ <menuitem id="menu_conso_entries"
443+ name="Consolidation Entries"
444+ parent="account.menu_finance"
445+ sequence="5"
446+ groups="account_consolidation.consolidation_manager,account_consolidation.consolidation_user"/>
447+
448+ <record id="action_account_moves_all_a" model="ir.actions.act_window">
449+ <field name="context">{'journal_type':'general'}</field>
450+ <field name="name">Journal Items</field>
451+ <field name="domain">[('is_current_company', '=', True)]</field>
452+ <field name="res_model">account.move.line</field>
453+ <field name="view_id" ref="account.view_move_line_tree"/>
454+ <field name="view_mode">tree_account_move_line_quickadd,form</field>
455+ <field name="help" type="html">
456+ <p class="oe_view_nocontent_create">
457+ Select the period and the journal you want to fill.
458+ </p><p>
459+ This view can be used by accountants in order to quickly record
460+ entries in OpenERP. If you want to record a supplier invoice,
461+ start by recording the line of the expense account. OpenERP
462+ will propose to you automatically the Tax related to this
463+ account and the counterpart "Account Payable".
464+ </p>
465+ </field>
466+ </record>
467+
468+ <menuitem
469+ action="action_account_moves_all_a"
470+ icon="STOCK_JUSTIFY_FILL"
471+ id="menu_action_account_moves_all"
472+ parent="menu_conso_entries"
473+ sequence="1"
474+ groups="account_consolidation.consolidation_manager,account_consolidation.consolidation_user"/>
475+
476+ </data>
477+</openerp>
478
479=== modified file 'account_consolidation/company.py'
480--- account_consolidation/company.py 2011-08-19 07:16:03 +0000
481+++ account_consolidation/company.py 2014-06-26 13:58:55 +0000
482@@ -1,44 +1,41 @@
483-# -*- coding: utf-8 -*-
484-##############################################################################
485-#
486-# Copyright (c) 2011 Camptocamp SA (http://www.camptocamp.com)
487-# All Right Reserved
488-#
489-# Author : Guewen Baconnier (Camptocamp)
490-#
491-# WARNING: This program as such is intended to be used by professional
492-# programmers who take the whole responsability of assessing all potential
493-# consequences resulting from its eventual inadequacies and bugs
494-# End users who are looking for a ready-to-use solution with commercial
495-# garantees and support are strongly adviced to contract a Free Software
496-# Service Company
497-#
498-# This program is Free Software; you can redistribute it and/or
499-# modify it under the terms of the GNU General Public License
500-# as published by the Free Software Foundation; either version 2
501-# of the License, or (at your option) any later version.
502-#
503-# This program is distributed in the hope that it will be useful,
504-# but WITHOUT ANY WARRANTY; without even the implied warranty of
505-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
506-# GNU General Public License for more details.
507-#
508-# You should have received a copy of the GNU General Public License
509-# along with this program; if not, write to the Free Software
510-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
511-#
512-##############################################################################
513-
514-from osv import osv, fields
515-
516-
517-class res_company(osv.osv):
518+# -* coding: utf-8 -*-
519+##############################################################################
520+#
521+# Author: Guewen Baconnier
522+# Copyright 2011-2013 Camptocamp SA
523+#
524+# This program is free software: you can redistribute it and/or modify
525+# it under the terms of the GNU Affero General Public License as
526+# published by the Free Software Foundation, either version 3 of the
527+# License, or (at your option) any later version.
528+#
529+# This program is distributed in the hope that it will be useful,
530+# but WITHOUT ANY WARRANTY; without even the implied warranty of
531+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
532+# GNU Affero General Public License for more details.
533+#
534+# You should have received a copy of the GNU Affero General Public License
535+# along with this program. If not, see <http://www.gnu.org/licenses/>.
536+#
537+##############################################################################
538+
539+from openerp.osv import orm, fields
540+
541+
542+class res_company(orm.Model):
543 _inherit = 'res.company'
544
545- _columns = {
546- 'consolidation_chart_account_id': fields.many2one('account.account',
547- 'Chart of Accounts for Consolidation',
548- domain=[('parent_id', '=', False)]),
549- }
550+ _columns = {'consolidation_chart_account_id': fields.many2one(
551+ 'account.account',
552+ 'Chart of Accounts for Consolidation',
553+ domain=[('parent_id', '=', False)],
554+ help=("Current company root account"
555+ " to be used when consolidating")),
556
557-res_company()
558+ 'consolidation_diff_account_id': fields.many2one(
559+ 'account.account',
560+ 'Consolidation difference account',
561+ domain=[('type', '=', 'other')],
562+ help=("Conso. differences will be affected"
563+ " to this account"))
564+ }
565
566=== modified file 'account_consolidation/company_view.xml'
567--- account_consolidation/company_view.xml 2011-08-19 07:16:03 +0000
568+++ account_consolidation/company_view.xml 2014-06-26 13:58:55 +0000
569@@ -9,9 +9,10 @@
570 <field name="type">form</field>
571 <field name="arch" type="xml">
572 <page string="Configuration" position="inside">
573- <group col="2" colspan="2">
574+ <group col="2" colspan="2" groups="account_consolidation.consolidation_manager">
575 <separator string="Accounts Consolidation" colspan="2"/>
576 <field name="consolidation_chart_account_id" colspan="2"/>
577+ <field name="consolidation_diff_account_id" colspan="2"/>
578 </group>
579 </page>
580 </field>
581
582=== modified file 'account_consolidation/consolidation_menu.xml'
583--- account_consolidation/consolidation_menu.xml 2011-08-12 15:39:07 +0000
584+++ account_consolidation/consolidation_menu.xml 2014-06-26 13:58:55 +0000
585@@ -5,18 +5,21 @@
586 <menuitem
587 name="Consolidation"
588 parent="account.menu_finance_periodical_processing"
589+ groups="account_consolidation.consolidation_manager,account_consolidation.consolidation_user"
590 id="menu_consolidation"/>
591
592 <menuitem
593 name="Consolidation: Checks"
594 parent="menu_consolidation"
595 action="action_consolidation_checks"
596+ groups="account_consolidation.consolidation_manager,account_consolidation.consolidation_user"
597 id="menu_consolidation_checks"/>
598
599 <menuitem
600 name="Consolidation: Consolidate"
601 parent="menu_consolidation"
602 action="action_consolidation_consolidate"
603+ groups="account_consolidation.consolidation_manager,account_consolidation.consolidation_user"
604 id="menu_consolidation_consolidate"/>
605
606 </data>
607
608=== added file 'account_consolidation/data.xml'
609--- account_consolidation/data.xml 1970-01-01 00:00:00 +0000
610+++ account_consolidation/data.xml 2014-06-26 13:58:55 +0000
611@@ -0,0 +1,13 @@
612+<openerp>
613+ <data>
614+ <record id="consolidation_manager" model="res.groups">
615+ <field name="name">Consolidation manager</field>
616+ <field name="category_id" ref="base.module_category_accounting_and_finance"/>
617+ </record>
618+
619+ <record id="consolidation_user" model="res.groups">
620+ <field name="name">Consolidation user</field>
621+ <field name="category_id" ref="base.module_category_accounting_and_finance"/>
622+ </record>
623+ </data>
624+</openerp>
625
626=== modified file 'account_consolidation/demo/consolidation_demo.xml'
627--- account_consolidation/demo/consolidation_demo.xml 2012-04-18 14:35:42 +0000
628+++ account_consolidation/demo/consolidation_demo.xml 2014-06-26 13:58:55 +0000
629@@ -183,7 +183,7 @@
630 <field name="company_id" ref="subsidiary_a"/>
631 </record>
632
633- <record id="period_b_1" model="account.period">
634+ <record id="period_b_1" model="account.period">
635 <field eval="'01/'+time.strftime('%Y')" name="code"/>
636 <field eval="'01/'+time.strftime('%Y')" name="name"/>
637 <field eval="True" name="special"/>
638@@ -292,25 +292,23 @@
639 <field name="company_id" ref="subsidiary_b"/>
640 </record>
641
642- <record id="account_journal_sale0" model="account.journal">
643- <field name="code">SALE</field>
644- <field name="name">SALE</field>
645- <field name="view_id" ref="account.account_sp_journal_view"/>
646- <field name="company_id" ref="account_consolidation.subsidiary_a"/>
647- <field name="sequence_id" ref="account.sequence_sale_journal"/>
648- <field eval="1" name="allow_date"/>
649- <field name="type">sale</field>
650- </record>
651+ <record id="account_journal_sale0" model="account.journal">
652+ <field name="code">SALE</field>
653+ <field name="name">SALE</field>
654+ <field name="company_id" ref="account_consolidation.subsidiary_a"/>
655+ <field name="sequence_id" ref="account.sequence_sale_journal"/>
656+ <field eval="1" name="allow_date"/>
657+ <field name="type">sale</field>
658+ </record>
659
660- <record id="account_journal_sale1" model="account.journal">
661- <field name="code">SALE</field>
662- <field name="name">SALE</field>
663- <field name="view_id" ref="account.account_sp_journal_view"/>
664- <field name="company_id" ref="account_consolidation.subsidiary_b"/>
665- <field name="sequence_id" ref="account.sequence_sale_journal"/>
666- <field eval="1" name="allow_date"/>
667- <field name="type">sale</field>
668- </record>
669+ <record id="account_journal_sale1" model="account.journal">
670+ <field name="code">SALE</field>
671+ <field name="name">SALE</field>
672+ <field name="company_id" ref="account_consolidation.subsidiary_b"/>
673+ <field name="sequence_id" ref="account.sequence_sale_journal"/>
674+ <field eval="1" name="allow_date"/>
675+ <field name="type">sale</field>
676+ </record>
677
678 </data>
679 </openerp>
680
681=== added file 'account_consolidation/i18n/account_consolidation.pot'
682--- account_consolidation/i18n/account_consolidation.pot 1970-01-01 00:00:00 +0000
683+++ account_consolidation/i18n/account_consolidation.pot 2014-06-26 13:58:55 +0000
684@@ -0,0 +1,488 @@
685+# Translation of OpenERP Server.
686+# This file contains the translation of the following modules:
687+# * account_consolidation
688+#
689+msgid ""
690+msgstr ""
691+"Project-Id-Version: OpenERP Server 7.0\n"
692+"Report-Msgid-Bugs-To: \n"
693+"POT-Creation-Date: 2013-12-13 09:10+0000\n"
694+"PO-Revision-Date: 2013-12-13 09:10+0000\n"
695+"Last-Translator: <>\n"
696+"Language-Team: \n"
697+"MIME-Version: 1.0\n"
698+"Content-Type: text/plain; charset=UTF-8\n"
699+"Content-Transfer-Encoding: \n"
700+"Plural-Forms: \n"
701+
702+#. module: account_consolidation
703+#: help:account.account,consolidation_rate_type_id:0
704+msgid "Currency rate type used on this account for the consolidation. Leave empty to use the rate type of the account type."
705+msgstr ""
706+
707+#. module: account_consolidation
708+#: help:account.consolidation.consolidate,from_period_id:0
709+msgid "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."
710+msgstr ""
711+
712+#. module: account_consolidation
713+#: model:ir.model,name:account_consolidation.model_account_consolidation_base
714+#: model:ir.model,name:account_consolidation.model_account_consolidation_consolidate
715+msgid "Common consolidation wizard. Intended to be inherited"
716+msgstr ""
717+
718+#. module: account_consolidation
719+#: field:account.account,consolidation_mode:0
720+#: field:account.account.type,consolidation_mode:0
721+msgid "Consolidation Mode"
722+msgstr ""
723+
724+#. module: account_consolidation
725+#: code:addons/account_consolidation/wizard/consolidation_base.py:375
726+#, python-format
727+msgid "Invalid periods, please launch the \"Consolidation: Checks\" wizard"
728+msgstr ""
729+
730+#. module: account_consolidation
731+#: code:addons/account_consolidation/wizard/consolidation_check.py:67
732+#, python-format
733+msgid "Invalid charts"
734+msgstr ""
735+
736+#. module: account_consolidation
737+#: code:addons/account_consolidation/wizard/consolidation_consolidate.py:434
738+#, python-format
739+msgid "Consolidation %s"
740+msgstr ""
741+
742+#. module: account_consolidation
743+#: view:account.consolidation.check:0
744+msgid "Check Chart 2 : For each subsidiary, check consistency between the regular chart of accounts and the consolidation chart."
745+msgstr ""
746+
747+#. module: account_consolidation
748+#: code:addons/account_consolidation/wizard/consolidation_check.py:53
749+#, python-format
750+msgid "Chart of Accounts are OK."
751+msgstr ""
752+
753+#. module: account_consolidation
754+#: code:addons/account_consolidation/wizard/consolidation_consolidate.py:261
755+#, python-format
756+msgid "Consolidation line in %s mode"
757+msgstr ""
758+
759+#. module: account_consolidation
760+#: field:account.move,consol_company_id:0
761+msgid "Consolidated from Company"
762+msgstr ""
763+
764+#. module: account_consolidation
765+#: view:account.move.line:0
766+msgid "Period"
767+msgstr ""
768+
769+#. module: account_consolidation
770+#: help:account.consolidation.base,fiscalyear_id:0
771+#: help:account.consolidation.check,fiscalyear_id:0
772+#: help:account.consolidation.consolidate,fiscalyear_id:0
773+msgid "The checks will be done on the periods of the selected fiscal year."
774+msgstr ""
775+
776+#. module: account_consolidation
777+#: model:ir.model,name:account_consolidation.model_account_account_type
778+msgid "Account Type"
779+msgstr ""
780+
781+#. module: account_consolidation
782+#: field:account.consolidation.base,holding_chart_account_id:0
783+#: field:account.consolidation.check,holding_chart_account_id:0
784+#: field:account.consolidation.consolidate,holding_chart_account_id:0
785+msgid "Chart of Accounts"
786+msgstr ""
787+
788+#. module: account_consolidation
789+#: view:account.consolidation.consolidate:0
790+msgid "Run the consolidation for the selected periods and subsidiaries."
791+msgstr ""
792+
793+#. module: account_consolidation
794+#: code:addons/account_consolidation/wizard/consolidation_consolidate.py:185
795+#, python-format
796+msgid "Settings ERROR"
797+msgstr ""
798+
799+#. module: account_consolidation
800+#: view:account.consolidation.check:0
801+#: view:account.consolidation.consolidate:0
802+msgid "or"
803+msgstr ""
804+
805+#. module: account_consolidation
806+#: code:addons/account_consolidation/wizard/consolidation_check.py:59
807+#: code:addons/account_consolidation/wizard/consolidation_check.py:85
808+#: code:addons/account_consolidation/wizard/consolidation_check.py:110
809+#, python-format
810+msgid "%s :"
811+msgstr ""
812+
813+#. module: account_consolidation
814+#: field:account.consolidation.base,subsidiary_ids:0
815+#: field:account.consolidation.check,subsidiary_ids:0
816+#: field:account.consolidation.consolidate,subsidiary_ids:0
817+msgid "Subsidiaries"
818+msgstr ""
819+
820+#. module: account_consolidation
821+#: view:account.account.type:0
822+msgid "Description"
823+msgstr ""
824+
825+#. module: account_consolidation
826+#: code:addons/account_consolidation/wizard/consolidation_base.py:300
827+#, python-format
828+msgid "Code %s is mapping %s times"
829+msgstr ""
830+
831+#. module: account_consolidation
832+#: view:account.consolidation.check:0
833+msgid "Check Periods"
834+msgstr ""
835+
836+#. module: account_consolidation
837+#: selection:account.account,consolidation_mode:0
838+#: selection:account.account.type,consolidation_mode:0
839+msgid "Period Movements"
840+msgstr ""
841+
842+#. module: account_consolidation
843+#: field:account.consolidation.base,company_id:0
844+#: field:account.consolidation.check,company_id:0
845+#: field:account.consolidation.consolidate,company_id:0
846+msgid "Company"
847+msgstr ""
848+
849+#. module: account_consolidation
850+#: view:account.consolidation.check:0
851+#: model:ir.actions.act_window,name:account_consolidation.action_consolidation_checks
852+#: model:ir.ui.menu,name:account_consolidation.menu_consolidation_checks
853+msgid "Consolidation: Checks"
854+msgstr ""
855+
856+#. module: account_consolidation
857+#: view:account.account:0
858+#: view:account.account.type:0
859+#: model:ir.ui.menu,name:account_consolidation.menu_consolidation
860+msgid "Consolidation"
861+msgstr ""
862+
863+#. module: account_consolidation
864+#: code:addons/account_consolidation/wizard/consolidation_check.py:78
865+#, python-format
866+msgid "Periods are OK."
867+msgstr ""
868+
869+#. module: account_consolidation
870+#: view:account.move.line:0
871+#: field:account.move.line,consol_company_id:0
872+msgid "Subsidaries"
873+msgstr ""
874+
875+#. module: account_consolidation
876+#: code:addons/account_consolidation/wizard/consolidation_consolidate.py:186
877+#, python-format
878+msgid "Please set the \"Consolidation difference account\" in company %s"
879+msgstr ""
880+
881+#. module: account_consolidation
882+#: field:res.company,consolidation_chart_account_id:0
883+msgid "Chart of Accounts for Consolidation"
884+msgstr ""
885+
886+#. module: account_consolidation
887+#: code:addons/account_consolidation/wizard/consolidation_check.py:90
888+#: code:addons/account_consolidation/wizard/consolidation_check.py:115
889+#, python-format
890+msgid "Invalid periods"
891+msgstr ""
892+
893+#. module: account_consolidation
894+#: help:account.consolidation.consolidate,to_period_id:0
895+msgid "The consolidation will be done at the very last date of the selected period."
896+msgstr ""
897+
898+#. module: account_consolidation
899+#: field:res.company,consolidation_diff_account_id:0
900+msgid "Consolidation difference account"
901+msgstr ""
902+
903+#. module: account_consolidation
904+#: view:res.company:0
905+msgid "Accounts Consolidation"
906+msgstr ""
907+
908+#. module: account_consolidation
909+#: view:res.company:0
910+msgid "Configuration"
911+msgstr ""
912+
913+#. module: account_consolidation
914+#: field:account.consolidation.consolidate,target_move:0
915+msgid "Target Moves"
916+msgstr ""
917+
918+#. module: account_consolidation
919+#: field:account.consolidation.consolidate,from_period_id:0
920+msgid "Start Period"
921+msgstr ""
922+
923+#. module: account_consolidation
924+#: model:res.groups,name:account_consolidation.consolidation_manager
925+msgid "Consolidation manager"
926+msgstr ""
927+
928+#. module: account_consolidation
929+#: help:res.company,consolidation_chart_account_id:0
930+msgid "Current company root account to be used when consolidating"
931+msgstr ""
932+
933+#. module: account_consolidation
934+#: model:ir.model,name:account_consolidation.model_account_account
935+msgid "Account"
936+msgstr ""
937+
938+#. module: account_consolidation
939+#: code:addons/account_consolidation/wizard/consolidation_base.py:350
940+#, python-format
941+msgid "No chart of accounts for company %s"
942+msgstr ""
943+
944+#. module: account_consolidation
945+#: view:account.consolidation.check:0
946+msgid "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."
947+msgstr ""
948+
949+#. module: account_consolidation
950+#: code:addons/account_consolidation/wizard/consolidation_base.py:176
951+#, python-format
952+msgid "Period from %s to %s not found in holding company %s"
953+msgstr ""
954+
955+#. module: account_consolidation
956+#: selection:account.consolidation.consolidate,target_move:0
957+msgid "All Posted Entries"
958+msgstr ""
959+
960+#. module: account_consolidation
961+#: code:addons/account_consolidation/wizard/consolidation_base.py:162
962+#, python-format
963+msgid "Holding company has less periods than the subsidiary company %s!"
964+msgstr ""
965+
966+#. module: account_consolidation
967+#: model:ir.model,name:account_consolidation.model_res_company
968+msgid "Companies"
969+msgstr ""
970+
971+#. module: account_consolidation
972+#: field:account.consolidation.consolidate,to_period_id:0
973+msgid "End Period"
974+msgstr ""
975+
976+#. module: account_consolidation
977+#: model:ir.actions.act_window,help:account_consolidation.action_account_moves_all_a
978+msgid "<p class=\"oe_view_nocontent_create\">\n"
979+" Select the period and the journal you want to fill.\n"
980+" </p><p>\n"
981+" This view can be used by accountants in order to quickly record\n"
982+" entries in OpenERP. If you want to record a supplier invoice,\n"
983+" start by recording the line of the expense account. OpenERP\n"
984+" will propose to you automatically the Tax related to this\n"
985+" account and the counterpart \"Account Payable\".\n"
986+" </p>\n"
987+" "
988+msgstr ""
989+
990+#. module: account_consolidation
991+#: field:account.consolidation.base,fiscalyear_id:0
992+#: field:account.consolidation.check,fiscalyear_id:0
993+#: field:account.consolidation.consolidate,fiscalyear_id:0
994+msgid "Fiscal Year"
995+msgstr ""
996+
997+#. module: account_consolidation
998+#: help:account.account,consolidation_mode:0
999+#: help:account.account.type,consolidation_mode:0
1000+msgid "This must be set on the holding company accounts only"
1001+msgstr ""
1002+
1003+#. module: account_consolidation
1004+#: code:addons/account_consolidation/wizard/consolidation_check.py:62
1005+#, python-format
1006+msgid "Account with code %s does not exist on the Holding company."
1007+msgstr ""
1008+
1009+#. module: account_consolidation
1010+#: code:addons/account_consolidation/wizard/consolidation_base.py:380
1011+#, python-format
1012+msgid "Invalid charts, please launch the \"Consolidation: Checks\" wizard"
1013+msgstr ""
1014+
1015+#. module: account_consolidation
1016+#: code:addons/account_consolidation/wizard/consolidation_base.py:349
1017+#: code:addons/account_consolidation/wizard/consolidation_base.py:374
1018+#: code:addons/account_consolidation/wizard/consolidation_base.py:379
1019+#, python-format
1020+msgid "Error"
1021+msgstr ""
1022+
1023+#. module: account_consolidation
1024+#: view:account.consolidation.check:0
1025+#: view:account.consolidation.consolidate:0
1026+msgid "Subsidiaries to Consolidate"
1027+msgstr ""
1028+
1029+#. module: account_consolidation
1030+#: view:account.consolidation.check:0
1031+msgid "Check Charts 1"
1032+msgstr ""
1033+
1034+#. module: account_consolidation
1035+#: selection:account.account,consolidation_mode:0
1036+#: selection:account.account.type,consolidation_mode:0
1037+msgid "YTD"
1038+msgstr ""
1039+
1040+#. module: account_consolidation
1041+#: view:account.consolidation.check:0
1042+msgid "Check Period : Check consistency of accounting periods between subsidiaries and holding company."
1043+msgstr ""
1044+
1045+#. module: account_consolidation
1046+#: view:account.consolidation.check:0
1047+msgid "Check Chart 1 : Check consistency between subsidiaries consolidation chart and Holding company chart."
1048+msgstr ""
1049+
1050+#. module: account_consolidation
1051+#: field:account.move.line,is_current_company:0
1052+msgid "Current company"
1053+msgstr ""
1054+
1055+#. module: account_consolidation
1056+#: code:addons/account_consolidation/wizard/consolidation_consolidate.py:207
1057+#, python-format
1058+msgid "Consolidation difference in mode %s"
1059+msgstr ""
1060+
1061+#. module: account_consolidation
1062+#: view:account.consolidation.consolidate:0
1063+msgid "Consolidate"
1064+msgstr ""
1065+
1066+#. module: account_consolidation
1067+#: constraint:account.consolidation.consolidate:0
1068+msgid "Start Period and End Period must be of the same Fiscal Year !"
1069+msgstr ""
1070+
1071+#. module: account_consolidation
1072+#: view:account.consolidation.consolidate:0
1073+#: model:ir.actions.act_window,name:account_consolidation.action_consolidation_consolidate
1074+#: model:ir.ui.menu,name:account_consolidation.menu_consolidation_consolidate
1075+msgid "Consolidation: Consolidate"
1076+msgstr ""
1077+
1078+#. module: account_consolidation
1079+#: model:ir.model,name:account_consolidation.model_account_move
1080+msgid "Account Entry"
1081+msgstr ""
1082+
1083+#. module: account_consolidation
1084+#: model:ir.ui.menu,name:account_consolidation.menu_conso_entries
1085+msgid "Consolidation Entries"
1086+msgstr ""
1087+
1088+#. module: account_consolidation
1089+#: help:res.company,consolidation_diff_account_id:0
1090+msgid "Conso. differences will be affected to this account"
1091+msgstr ""
1092+
1093+#. module: account_consolidation
1094+#: view:account.consolidation.check:0
1095+msgid "Check Charts 2"
1096+msgstr ""
1097+
1098+#. module: account_consolidation
1099+#: model:ir.model,name:account_consolidation.model_account_consolidation_check
1100+msgid "Consolidation Checks. Model used for views"
1101+msgstr ""
1102+
1103+#. module: account_consolidation
1104+#: code:addons/account_consolidation/wizard/consolidation_base.py:141
1105+#, python-format
1106+msgid "The fiscal year of the subsidiary company %s does not exists from %s to %s"
1107+msgstr ""
1108+
1109+#. module: account_consolidation
1110+#: code:addons/account_consolidation/wizard/consolidation_consolidate.py:504
1111+#, python-format
1112+msgid "Consolidated Entries"
1113+msgstr ""
1114+
1115+#. module: account_consolidation
1116+#: code:addons/account_consolidation/wizard/consolidation_check.py:52
1117+#: code:addons/account_consolidation/wizard/consolidation_check.py:78
1118+#: code:addons/account_consolidation/wizard/consolidation_check.py:103
1119+#, python-format
1120+msgid "Validation"
1121+msgstr ""
1122+
1123+#. module: account_consolidation
1124+#: model:res.groups,name:account_consolidation.consolidation_user
1125+msgid "Consolidation user"
1126+msgstr ""
1127+
1128+#. module: account_consolidation
1129+#: help:account.account.type,consolidation_rate_type_id:0
1130+msgid "Currency rate type used on this account type for the consolidation. Leave empty to use the 'spot' rate type."
1131+msgstr ""
1132+
1133+#. module: account_consolidation
1134+#: view:account.consolidation.consolidate:0
1135+msgid "Holding Chart of Accounts"
1136+msgstr ""
1137+
1138+#. module: account_consolidation
1139+#: view:account.consolidation.check:0
1140+#: view:account.consolidation.consolidate:0
1141+msgid "Cancel"
1142+msgstr ""
1143+
1144+#. module: account_consolidation
1145+#: code:addons/account_consolidation/wizard/consolidation_check.py:103
1146+#, python-format
1147+msgid "All account is mapped"
1148+msgstr ""
1149+
1150+#. module: account_consolidation
1151+#: field:account.account,consolidation_rate_type_id:0
1152+#: field:account.account.type,consolidation_rate_type_id:0
1153+msgid "Consolidation Currency Rate Type"
1154+msgstr ""
1155+
1156+#. module: account_consolidation
1157+#: field:account.consolidation.consolidate,journal_id:0
1158+msgid "Journal"
1159+msgstr ""
1160+
1161+#. module: account_consolidation
1162+#: selection:account.consolidation.consolidate,target_move:0
1163+msgid "All Entries"
1164+msgstr ""
1165+
1166+#. module: account_consolidation
1167+#: model:ir.actions.act_window,name:account_consolidation.action_account_moves_all_a
1168+#: model:ir.model,name:account_consolidation.model_account_move_line
1169+#: model:ir.ui.menu,name:account_consolidation.menu_action_account_moves_all
1170+msgid "Journal Items"
1171+msgstr ""
1172+
1173
1174=== added file 'account_consolidation/i18n/fr.po'
1175--- account_consolidation/i18n/fr.po 1970-01-01 00:00:00 +0000
1176+++ account_consolidation/i18n/fr.po 2014-06-26 13:58:55 +0000
1177@@ -0,0 +1,488 @@
1178+# Translation of OpenERP Server.
1179+# This file contains the translation of the following modules:
1180+# * account_consolidation
1181+#
1182+msgid ""
1183+msgstr ""
1184+"Project-Id-Version: OpenERP Server 7.0\n"
1185+"Report-Msgid-Bugs-To: \n"
1186+"POT-Creation-Date: 2013-12-13 09:10+0000\n"
1187+"PO-Revision-Date: 2013-12-13 09:10+0000\n"
1188+"Last-Translator: <>\n"
1189+"Language-Team: \n"
1190+"MIME-Version: 1.0\n"
1191+"Content-Type: text/plain; charset=UTF-8\n"
1192+"Content-Transfer-Encoding: \n"
1193+"Plural-Forms: \n"
1194+
1195+#. module: account_consolidation
1196+#: help:account.account,consolidation_rate_type_id:0
1197+msgid "Currency rate type used on this account for the consolidation. Leave empty to use the rate type of the account type."
1198+msgstr "Type du taux de devise utilisé sur ce compte pour la consolidation. Laissez vide pour utiliser le type de devise indiqué au niveau du type de compte"
1199+
1200+#. module: account_consolidation
1201+#: help:account.consolidation.consolidate,from_period_id:0
1202+msgid "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."
1203+msgstr "Sélectionnez la même periode de début et de fin si vous ne voulez qu'une seule période. 'Période début' est ignoré pour les champs consolidé en mode 'YTD'"
1204+
1205+#. module: account_consolidation
1206+#: model:ir.model,name:account_consolidation.model_account_consolidation_base
1207+#: model:ir.model,name:account_consolidation.model_account_consolidation_consolidate
1208+msgid "Common consolidation wizard. Intended to be inherited"
1209+msgstr ""
1210+
1211+#. module: account_consolidation
1212+#: field:account.account,consolidation_mode:0
1213+#: field:account.account.type,consolidation_mode:0
1214+msgid "Consolidation Mode"
1215+msgstr "Mode de consolidation"
1216+
1217+#. module: account_consolidation
1218+#: code:addons/account_consolidation/wizard/consolidation_base.py:375
1219+#, python-format
1220+msgid "Invalid periods, please launch the \"Consolidation: Checks\" wizard"
1221+msgstr "Périodes invalide, SVP lancez le menu \"Consolidation: Contôles\" "
1222+
1223+#. module: account_consolidation
1224+#: code:addons/account_consolidation/wizard/consolidation_check.py:67
1225+#, python-format
1226+msgid "Invalid charts"
1227+msgstr "Plan comptables invalides"
1228+
1229+#. module: account_consolidation
1230+#: code:addons/account_consolidation/wizard/consolidation_consolidate.py:434
1231+#, python-format
1232+msgid "Consolidation %s"
1233+msgstr "Consolidation %s"
1234+
1235+#. module: account_consolidation
1236+#: view:account.consolidation.check:0
1237+msgid "Check Chart 2 : For each subsidiary, check consistency between the regular chart of accounts and the consolidation chart."
1238+msgstr "Contrôle Plans Comptables : Pour chaque filiale, vérifie la cohérence entre le plan comptable local et le plan consolidé"
1239+
1240+#. module: account_consolidation
1241+#: code:addons/account_consolidation/wizard/consolidation_check.py:53
1242+#, python-format
1243+msgid "Chart of Accounts are OK."
1244+msgstr "Plans comptables : OK "
1245+
1246+#. module: account_consolidation
1247+#: code:addons/account_consolidation/wizard/consolidation_consolidate.py:261
1248+#, python-format
1249+msgid "Consolidation line in %s mode"
1250+msgstr ""
1251+
1252+#. module: account_consolidation
1253+#: field:account.move,consol_company_id:0
1254+msgid "Consolidated from Company"
1255+msgstr "Filiale"
1256+
1257+#. module: account_consolidation
1258+#: view:account.move.line:0
1259+msgid "Period"
1260+msgstr "Période"
1261+
1262+#. module: account_consolidation
1263+#: help:account.consolidation.base,fiscalyear_id:0
1264+#: help:account.consolidation.check,fiscalyear_id:0
1265+#: help:account.consolidation.consolidate,fiscalyear_id:0
1266+msgid "The checks will be done on the periods of the selected fiscal year."
1267+msgstr "Les contrôles seront effectués sur les périodes de l'excercice comptable sélectionné"
1268+
1269+#. module: account_consolidation
1270+#: model:ir.model,name:account_consolidation.model_account_account_type
1271+msgid "Account Type"
1272+msgstr "Type de compte"
1273+
1274+#. module: account_consolidation
1275+#: field:account.consolidation.base,holding_chart_account_id:0
1276+#: field:account.consolidation.check,holding_chart_account_id:0
1277+#: field:account.consolidation.consolidate,holding_chart_account_id:0
1278+msgid "Chart of Accounts"
1279+msgstr "Plan comptable"
1280+
1281+#. module: account_consolidation
1282+#: view:account.consolidation.consolidate:0
1283+msgid "Run the consolidation for the selected periods and subsidiaries."
1284+msgstr "Lancer la consolidation sur les périodes et les filiales sélectionnées "
1285+
1286+#. module: account_consolidation
1287+#: code:addons/account_consolidation/wizard/consolidation_consolidate.py:185
1288+#, python-format
1289+msgid "Settings ERROR"
1290+msgstr "Erreur de paramétrage"
1291+
1292+#. module: account_consolidation
1293+#: view:account.consolidation.check:0
1294+#: view:account.consolidation.consolidate:0
1295+msgid "or"
1296+msgstr "ou"
1297+
1298+#. module: account_consolidation
1299+#: code:addons/account_consolidation/wizard/consolidation_check.py:59
1300+#: code:addons/account_consolidation/wizard/consolidation_check.py:85
1301+#: code:addons/account_consolidation/wizard/consolidation_check.py:110
1302+#, python-format
1303+msgid "%s :"
1304+msgstr "%s :"
1305+
1306+#. module: account_consolidation
1307+#: field:account.consolidation.base,subsidiary_ids:0
1308+#: field:account.consolidation.check,subsidiary_ids:0
1309+#: field:account.consolidation.consolidate,subsidiary_ids:0
1310+msgid "Subsidiaries"
1311+msgstr "Filiales"
1312+
1313+#. module: account_consolidation
1314+#: view:account.account.type:0
1315+msgid "Description"
1316+msgstr "Description"
1317+
1318+#. module: account_consolidation
1319+#: code:addons/account_consolidation/wizard/consolidation_base.py:300
1320+#, python-format
1321+msgid "Code %s is mapping %s times"
1322+msgstr "Le compte %s est liés à un compte consolidé %s fois"
1323+
1324+#. module: account_consolidation
1325+#: view:account.consolidation.check:0
1326+msgid "Check Periods"
1327+msgstr "Contrôle Périodes"
1328+
1329+#. module: account_consolidation
1330+#: selection:account.account,consolidation_mode:0
1331+#: selection:account.account.type,consolidation_mode:0
1332+msgid "Period Movements"
1333+msgstr "Mouvements par période"
1334+
1335+#. module: account_consolidation
1336+#: field:account.consolidation.base,company_id:0
1337+#: field:account.consolidation.check,company_id:0
1338+#: field:account.consolidation.consolidate,company_id:0
1339+msgid "Company"
1340+msgstr "Société"
1341+
1342+#. module: account_consolidation
1343+#: view:account.consolidation.check:0
1344+#: model:ir.actions.act_window,name:account_consolidation.action_consolidation_checks
1345+#: model:ir.ui.menu,name:account_consolidation.menu_consolidation_checks
1346+msgid "Consolidation: Checks"
1347+msgstr "Consolidation: Contrôle"
1348+
1349+#. module: account_consolidation
1350+#: view:account.account:0
1351+#: view:account.account.type:0
1352+#: model:ir.ui.menu,name:account_consolidation.menu_consolidation
1353+msgid "Consolidation"
1354+msgstr "Consolidation"
1355+
1356+#. module: account_consolidation
1357+#: code:addons/account_consolidation/wizard/consolidation_check.py:78
1358+#, python-format
1359+msgid "Periods are OK."
1360+msgstr "Periodes OK."
1361+
1362+#. module: account_consolidation
1363+#: view:account.move.line:0
1364+#: field:account.move.line,consol_company_id:0
1365+msgid "Subsidaries"
1366+msgstr "Filiales"
1367+
1368+#. module: account_consolidation
1369+#: code:addons/account_consolidation/wizard/consolidation_consolidate.py:186
1370+#, python-format
1371+msgid "Please set the \"Consolidation difference account\" in company %s"
1372+msgstr "Veuilez paramétrer le \"Compte d'écart de consolidation\" pour la société %s"
1373+
1374+#. module: account_consolidation
1375+#: field:res.company,consolidation_chart_account_id:0
1376+msgid "Chart of Accounts for Consolidation"
1377+msgstr "Plan comptable consolidé"
1378+
1379+#. module: account_consolidation
1380+#: code:addons/account_consolidation/wizard/consolidation_check.py:90
1381+#: code:addons/account_consolidation/wizard/consolidation_check.py:115
1382+#, python-format
1383+msgid "Invalid periods"
1384+msgstr "Périodes invalides"
1385+
1386+#. module: account_consolidation
1387+#: help:account.consolidation.consolidate,to_period_id:0
1388+msgid "The consolidation will be done at the very last date of the selected period."
1389+msgstr "Les écritures de consolidation seront passées le dernier jour de la période sélectionnée"
1390+
1391+#. module: account_consolidation
1392+#: field:res.company,consolidation_diff_account_id:0
1393+msgid "Consolidation difference account"
1394+msgstr "Compte d'écart de consolidation"
1395+
1396+#. module: account_consolidation
1397+#: view:res.company:0
1398+msgid "Accounts Consolidation"
1399+msgstr "Comptes de consolidation"
1400+
1401+#. module: account_consolidation
1402+#: view:res.company:0
1403+msgid "Configuration"
1404+msgstr "Configuration"
1405+
1406+#. module: account_consolidation
1407+#: field:account.consolidation.consolidate,target_move:0
1408+msgid "Target Moves"
1409+msgstr "Ecritures cibles"
1410+
1411+#. module: account_consolidation
1412+#: field:account.consolidation.consolidate,from_period_id:0
1413+msgid "Start Period"
1414+msgstr "Période de début"
1415+
1416+#. module: account_consolidation
1417+#: model:res.groups,name:account_consolidation.consolidation_manager
1418+msgid "Consolidation manager"
1419+msgstr "Responsable"
1420+
1421+#. module: account_consolidation
1422+#: help:res.company,consolidation_chart_account_id:0
1423+msgid "Current company root account to be used when consolidating"
1424+msgstr "Plan comptable consolidé de la société"
1425+
1426+#. module: account_consolidation
1427+#: model:ir.model,name:account_consolidation.model_account_account
1428+msgid "Account"
1429+msgstr "Compte"
1430+
1431+#. module: account_consolidation
1432+#: code:addons/account_consolidation/wizard/consolidation_base.py:350
1433+#, python-format
1434+msgid "No chart of accounts for company %s"
1435+msgstr "Pas de plan comptable pour la société %s"
1436+
1437+#. module: account_consolidation
1438+#: view:account.consolidation.check:0
1439+msgid "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."
1440+msgstr "Contrôle préalables au lancement des écritures de consolidation"
1441+
1442+#. module: account_consolidation
1443+#: code:addons/account_consolidation/wizard/consolidation_base.py:176
1444+#, python-format
1445+msgid "Period from %s to %s not found in holding company %s"
1446+msgstr "Périodes de %s à %s non trouvées dans la société holding"
1447+
1448+#. module: account_consolidation
1449+#: selection:account.consolidation.consolidate,target_move:0
1450+msgid "All Posted Entries"
1451+msgstr "Ecritures validées seulement"
1452+
1453+#. module: account_consolidation
1454+#: code:addons/account_consolidation/wizard/consolidation_base.py:162
1455+#, python-format
1456+msgid "Holding company has less periods than the subsidiary company %s!"
1457+msgstr "La holding a moins de périodes comptables créées que la filiale %s"
1458+
1459+#. module: account_consolidation
1460+#: model:ir.model,name:account_consolidation.model_res_company
1461+msgid "Companies"
1462+msgstr "Sociétés"
1463+
1464+#. module: account_consolidation
1465+#: field:account.consolidation.consolidate,to_period_id:0
1466+msgid "End Period"
1467+msgstr "Période de fin"
1468+
1469+#. module: account_consolidation
1470+#: model:ir.actions.act_window,help:account_consolidation.action_account_moves_all_a
1471+msgid "<p class=\"oe_view_nocontent_create\">\n"
1472+" Select the period and the journal you want to fill.\n"
1473+" </p><p>\n"
1474+" This view can be used by accountants in order to quickly record\n"
1475+" entries in OpenERP. If you want to record a supplier invoice,\n"
1476+" start by recording the line of the expense account. OpenERP\n"
1477+" will propose to you automatically the Tax related to this\n"
1478+" account and the counterpart \"Account Payable\".\n"
1479+" </p>\n"
1480+" "
1481+msgstr ""
1482+
1483+#. module: account_consolidation
1484+#: field:account.consolidation.base,fiscalyear_id:0
1485+#: field:account.consolidation.check,fiscalyear_id:0
1486+#: field:account.consolidation.consolidate,fiscalyear_id:0
1487+msgid "Fiscal Year"
1488+msgstr "Excercice comptable"
1489+
1490+#. module: account_consolidation
1491+#: help:account.account,consolidation_mode:0
1492+#: help:account.account.type,consolidation_mode:0
1493+msgid "This must be set on the holding company accounts only"
1494+msgstr "Ceci doit être paramétré au niveau des comptes de la holding seulement"
1495+
1496+#. module: account_consolidation
1497+#: code:addons/account_consolidation/wizard/consolidation_check.py:62
1498+#, python-format
1499+msgid "Account with code %s does not exist on the Holding company."
1500+msgstr "Le compte %s n'existe pas dans la holding"
1501+
1502+#. module: account_consolidation
1503+#: code:addons/account_consolidation/wizard/consolidation_base.py:380
1504+#, python-format
1505+msgid "Invalid charts, please launch the \"Consolidation: Checks\" wizard"
1506+msgstr "Plans comptables invalides, veuillez lancer le \"Consolidation: Contrôle\" "
1507+
1508+#. module: account_consolidation
1509+#: code:addons/account_consolidation/wizard/consolidation_base.py:349
1510+#: code:addons/account_consolidation/wizard/consolidation_base.py:374
1511+#: code:addons/account_consolidation/wizard/consolidation_base.py:379
1512+#, python-format
1513+msgid "Error"
1514+msgstr "Erreur"
1515+
1516+#. module: account_consolidation
1517+#: view:account.consolidation.check:0
1518+#: view:account.consolidation.consolidate:0
1519+msgid "Subsidiaries to Consolidate"
1520+msgstr "Filiales à consolider"
1521+
1522+#. module: account_consolidation
1523+#: view:account.consolidation.check:0
1524+msgid "Check Charts 1"
1525+msgstr "Plans comptables Contrôle1"
1526+
1527+#. module: account_consolidation
1528+#: selection:account.account,consolidation_mode:0
1529+#: selection:account.account.type,consolidation_mode:0
1530+msgid "YTD"
1531+msgstr "YTD"
1532+
1533+#. module: account_consolidation
1534+#: view:account.consolidation.check:0
1535+msgid "Check Period : Check consistency of accounting periods between subsidiaries and holding company."
1536+msgstr "Contrôle Period : Vérifie la cohérence des périodes comptables entre les filiales et la holding"
1537+
1538+#. module: account_consolidation
1539+#: view:account.consolidation.check:0
1540+msgid "Check Chart 1 : Check consistency between subsidiaries consolidation chart and Holding company chart."
1541+msgstr "Contrôle Plans comptables 1 : Vérifie la cohérence entre les plans comptables consolidés des filiales et le plan comptable de la holding"
1542+
1543+#. module: account_consolidation
1544+#: field:account.move.line,is_current_company:0
1545+msgid "Current company"
1546+msgstr "Société courante"
1547+
1548+#. module: account_consolidation
1549+#: code:addons/account_consolidation/wizard/consolidation_consolidate.py:207
1550+#, python-format
1551+msgid "Consolidation difference in mode %s"
1552+msgstr "Ecart de consolidation du mode %s "
1553+
1554+#. module: account_consolidation
1555+#: view:account.consolidation.consolidate:0
1556+msgid "Consolidate"
1557+msgstr "Consolide"
1558+
1559+#. module: account_consolidation
1560+#: constraint:account.consolidation.consolidate:0
1561+msgid "Start Period and End Period must be of the same Fiscal Year !"
1562+msgstr "La période de début et de fin doivent appartenir au même excercice comptable"
1563+
1564+#. module: account_consolidation
1565+#: view:account.consolidation.consolidate:0
1566+#: model:ir.actions.act_window,name:account_consolidation.action_consolidation_consolidate
1567+#: model:ir.ui.menu,name:account_consolidation.menu_consolidation_consolidate
1568+msgid "Consolidation: Consolidate"
1569+msgstr "Consolidation : Génération des écritures"
1570+
1571+#. module: account_consolidation
1572+#: model:ir.model,name:account_consolidation.model_account_move
1573+msgid "Account Entry"
1574+msgstr "Ecriture"
1575+
1576+#. module: account_consolidation
1577+#: model:ir.ui.menu,name:account_consolidation.menu_conso_entries
1578+msgid "Consolidation Entries"
1579+msgstr "Ecritures de consolidation"
1580+
1581+#. module: account_consolidation
1582+#: help:res.company,consolidation_diff_account_id:0
1583+msgid "Conso. differences will be affected to this account"
1584+msgstr "Les écarts de consolidation seront passés sur ce compte "
1585+
1586+#. module: account_consolidation
1587+#: view:account.consolidation.check:0
1588+msgid "Check Charts 2"
1589+msgstr "Plans comptables Contrôle2"
1590+
1591+#. module: account_consolidation
1592+#: model:ir.model,name:account_consolidation.model_account_consolidation_check
1593+msgid "Consolidation Checks. Model used for views"
1594+msgstr "Contrôle pré-consolidation. Modèle utilisé pour les vues"
1595+
1596+#. module: account_consolidation
1597+#: code:addons/account_consolidation/wizard/consolidation_base.py:141
1598+#, python-format
1599+msgid "The fiscal year of the subsidiary company %s does not exists from %s to %s"
1600+msgstr "Pas excercice comptable dans la filiale %s pour les périodes de %s à %s."
1601+
1602+#. module: account_consolidation
1603+#: code:addons/account_consolidation/wizard/consolidation_consolidate.py:504
1604+#, python-format
1605+msgid "Consolidated Entries"
1606+msgstr "Ecritures de consolidation"
1607+
1608+#. module: account_consolidation
1609+#: code:addons/account_consolidation/wizard/consolidation_check.py:52
1610+#: code:addons/account_consolidation/wizard/consolidation_check.py:78
1611+#: code:addons/account_consolidation/wizard/consolidation_check.py:103
1612+#, python-format
1613+msgid "Validation"
1614+msgstr "Validation"
1615+
1616+#. module: account_consolidation
1617+#: model:res.groups,name:account_consolidation.consolidation_user
1618+msgid "Consolidation user"
1619+msgstr "Utilisateur"
1620+
1621+#. module: account_consolidation
1622+#: help:account.account.type,consolidation_rate_type_id:0
1623+msgid "Currency rate type used on this account type for the consolidation. Leave empty to use the 'spot' rate type."
1624+msgstr "Type de devise utilisé pour la consolidation de ce type de compte. Laisser vide pour utiliser le taux par défaut "
1625+
1626+#. module: account_consolidation
1627+#: view:account.consolidation.consolidate:0
1628+msgid "Holding Chart of Accounts"
1629+msgstr "Plan comptable Holding"
1630+
1631+#. module: account_consolidation
1632+#: view:account.consolidation.check:0
1633+#: view:account.consolidation.consolidate:0
1634+msgid "Cancel"
1635+msgstr "Annuler"
1636+
1637+#. module: account_consolidation
1638+#: code:addons/account_consolidation/wizard/consolidation_check.py:103
1639+#, python-format
1640+msgid "All account is mapped"
1641+msgstr "Tout les comptes sont bien liés à des comptes consolidés"
1642+
1643+#. module: account_consolidation
1644+#: field:account.account,consolidation_rate_type_id:0
1645+#: field:account.account.type,consolidation_rate_type_id:0
1646+msgid "Consolidation Currency Rate Type"
1647+msgstr "Type de taux de devise utilisé pour la consolidation"
1648+
1649+#. module: account_consolidation
1650+#: field:account.consolidation.consolidate,journal_id:0
1651+msgid "Journal"
1652+msgstr "Journal"
1653+
1654+#. module: account_consolidation
1655+#: selection:account.consolidation.consolidate,target_move:0
1656+msgid "All Entries"
1657+msgstr "Ecritures validées + brouillon"
1658+
1659+#. module: account_consolidation
1660+#: model:ir.actions.act_window,name:account_consolidation.action_account_moves_all_a
1661+#: model:ir.model,name:account_consolidation.model_account_move_line
1662+#: model:ir.ui.menu,name:account_consolidation.menu_action_account_moves_all
1663+msgid "Journal Items"
1664+msgstr "Ecritures comptables"
1665+
1666
1667=== modified file 'account_consolidation/test/consolidation_checks.yml'
1668--- account_consolidation/test/consolidation_checks.yml 2011-08-19 13:08:01 +0000
1669+++ account_consolidation/test/consolidation_checks.yml 2014-06-26 13:58:55 +0000
1670@@ -42,7 +42,8 @@
1671 raise
1672
1673 -
1674- In order to test the consolidation checks on misconfigured periods, I use the wizard on FY2012
1675+ In order to test the consolidation checks on misconfigured periods, I use the wizard on the next year
1676+ which is misconfigured
1677 -
1678 !record {model: account.consolidation.check, id: conso_check_period_1}:
1679 fiscalyear_id: account_fiscalyear_fy0
1680@@ -79,8 +80,8 @@
1681 name: Virtual Account Spare
1682 parent_id: account_consolidation.virtual_chart_subsidiary_a
1683 type: consolidation
1684- user_type: account.account_type_expense
1685-
1686+ user_type: account.data_account_type_expense
1687+
1688 -
1689 In order to test the consolidation checks on misconfigured charts, I use the wizard
1690 -
1691
1692=== modified file 'account_consolidation/test/test_data.yml'
1693--- account_consolidation/test/test_data.yml 2011-08-19 13:08:01 +0000
1694+++ account_consolidation/test/test_data.yml 2014-06-26 13:58:55 +0000
1695@@ -3,14 +3,14 @@
1696 -
1697 !record {model: account.move, id: account_move_0}:
1698 company_id: subsidiary_b
1699- date: '2011-01-02'
1700+ date: !eval "'%s-01-02' % datetime.now().year"
1701 journal_id: account_journal_sale1
1702 line_id:
1703 - company_id: subsidiary_b
1704 account_id: a_sale_b
1705 amount_currency: 0.0
1706 credit: 0.0
1707- date: '2011-01-01'
1708+ date: !eval "'%s-01-02' % datetime.now().year"
1709 debit: 1240.0
1710 journal_id: account_journal_sale1
1711 name: Entry 0
1712@@ -22,7 +22,7 @@
1713 account_id: cog_b
1714 amount_currency: 0.0
1715 credit: 1240.0
1716- date: '2011-01-01'
1717+ date: !eval "'%s-01-02' % datetime.now().year"
1718 debit: 0.0
1719 journal_id: account_journal_sale1
1720 name: Entry 0
1721@@ -40,14 +40,14 @@
1722 -
1723 !record {model: account.move, id: account_move_1}:
1724 company_id: account_consolidation.subsidiary_a
1725- date: '2011-01-20'
1726+ date: !eval "'%s-01-20' % datetime.now().year"
1727 journal_id: account_journal_sale0
1728 line_id:
1729 - account_id: account_consolidation.a_sale_a
1730 amount_currency: 0.0
1731 company_id: account_consolidation.subsidiary_a
1732 credit: 0.0
1733- date: '2011-01-20'
1734+ date: !eval "'%s-01-20' % datetime.now().year"
1735 debit: 40.0
1736 journal_id: account_journal_sale0
1737 name: Entry 1
1738@@ -59,7 +59,7 @@
1739 amount_currency: 0.0
1740 company_id: account_consolidation.subsidiary_a
1741 credit: 40.0
1742- date: '2011-01-20'
1743+ date: !eval "'%s-01-20' % datetime.now().year"
1744 debit: 0.0
1745 journal_id: account_journal_sale0
1746 name: Entry 1
1747@@ -77,14 +77,14 @@
1748 -
1749 !record {model: account.move, id: account_move_2}:
1750 company_id: account_consolidation.subsidiary_a
1751- date: '2011-02-23'
1752+ date: !eval "'%s-02-23' % datetime.now().year"
1753 journal_id: account_journal_sale0
1754 line_id:
1755 - account_id: account_consolidation.a_sale_a
1756 amount_currency: 0.0
1757 company_id: account_consolidation.subsidiary_a
1758 credit: 0.0
1759- date: '2011-02-01'
1760+ date: !eval "'%s-02-23' % datetime.now().year"
1761 debit: 200.0
1762 journal_id: account_journal_sale0
1763 name: Entry 2
1764@@ -96,7 +96,7 @@
1765 amount_currency: 0.0
1766 company_id: account_consolidation.subsidiary_a
1767 credit: 200.0
1768- date: '2011-02-01'
1769+ date: !eval "'%s-02-23' % datetime.now().year"
1770 debit: 0.0
1771 journal_id: account_journal_sale0
1772 name: Entry 2
1773@@ -114,14 +114,14 @@
1774 -
1775 !record {model: account.move, id: account_move_3}:
1776 company_id: account_consolidation.subsidiary_a
1777- date: '2011-01-15'
1778+ date: !eval "'%s-01-15' % datetime.now().year"
1779 journal_id: account_journal_sale0
1780 line_id:
1781 - account_id: account_consolidation.cog_a
1782 amount_currency: 0.0
1783 company_id: account_consolidation.subsidiary_a
1784 credit: 300.0
1785- date: '2011-01-01'
1786+ date: !eval "'%s-01-15' % datetime.now().year"
1787 debit: 0.0
1788 journal_id: account_journal_sale0
1789 name: Entry 3
1790@@ -133,7 +133,7 @@
1791 amount_currency: 0.0
1792 company_id: account_consolidation.subsidiary_a
1793 credit: 0.0
1794- date: '2011-01-01'
1795+ date: !eval "'%s-01-15' % datetime.now().year"
1796 debit: 300.0
1797 journal_id: account_journal_sale0
1798 name: Entry 3
1799@@ -150,94 +150,94 @@
1800 Creating a account.fiscalyear record with a missing period for january
1801 -
1802 !record {model: account.fiscalyear, id: account_fiscalyear_fy0}:
1803- code: FY2012
1804+ code: !eval "'FY%s' % (datetime.now().year + 1)"
1805 company_id: base.main_company
1806- date_start: '2012-01-01'
1807- date_stop: '2012-12-31'
1808- name: FY2012
1809+ date_start: !eval "'%s-01-01' % (datetime.now().year + 1)"
1810+ date_stop: !eval "'%s-12-31' % (datetime.now().year + 1)"
1811+ name: !eval "'FY%s' % (datetime.now().year + 1)"
1812 period_ids:
1813- - code: 00/2012
1814+ - code: !eval "'00/%s' % (datetime.now().year + 1)"
1815 company_id: base.main_company
1816- date_start: '2012-01-01'
1817- date_stop: '2012-01-01'
1818+ date_start: !eval "'%s-01-01' % (datetime.now().year + 1)"
1819+ date_stop: !eval "'%s-01-01' % (datetime.now().year + 1)"
1820 name: Opening Period
1821 special: true
1822- - code: 01/2012
1823- company_id: base.main_company
1824- date_start: '2012-01-01'
1825- date_stop: '2012-01-31'
1826- name: 01/2012
1827- - code: 02/2012
1828- company_id: base.main_company
1829- date_start: '2012-02-01'
1830- date_stop: '2012-02-29'
1831- name: 02/2012
1832- - code: 03/2012
1833- company_id: base.main_company
1834- date_start: '2012-03-01'
1835- date_stop: '2012-03-31'
1836- name: 03/2012
1837- - code: 04/2012
1838- company_id: base.main_company
1839- date_start: '2012-04-01'
1840- date_stop: '2012-04-30'
1841- name: 04/2012
1842- - code: 05/2012
1843- company_id: base.main_company
1844- date_start: '2012-05-01'
1845- date_stop: '2012-05-31'
1846- name: 05/2012
1847- - code: 06/2012
1848- company_id: base.main_company
1849- date_start: '2012-06-01'
1850- date_stop: '2012-06-30'
1851- name: 06/2012
1852- - code: 07/2012
1853- company_id: base.main_company
1854- date_start: '2012-07-01'
1855- date_stop: '2012-07-31'
1856- name: 07/2012
1857- - code: 08/2012
1858- company_id: base.main_company
1859- date_start: '2012-08-01'
1860- date_stop: '2012-08-31'
1861- name: 08/2012
1862- - code: 09/2012
1863- company_id: base.main_company
1864- date_start: '2012-09-01'
1865- date_stop: '2012-09-30'
1866- name: 09/2012
1867- - code: 10/2012
1868- company_id: base.main_company
1869- date_start: '2012-10-01'
1870- date_stop: '2012-10-31'
1871- name: 10/2012
1872- - code: 11/2012
1873- company_id: base.main_company
1874- date_start: '2012-11-01'
1875- date_stop: '2012-11-30'
1876- name: 11/2012
1877- - code: 12/2012
1878- company_id: base.main_company
1879- date_start: '2012-12-01'
1880- date_stop: '2012-12-31'
1881- name: 12/2012
1882+ - code: !eval "'01/%s' % (datetime.now().year + 1)"
1883+ company_id: base.main_company
1884+ date_start: !eval "'%s-01-01' % (datetime.now().year + 1)"
1885+ date_stop: !eval "'%s-01-31' % (datetime.now().year + 1)"
1886+ name: !eval "'01/%s' % (datetime.now().year + 1)"
1887+ - code: !eval "'02/%s' % (datetime.now().year + 1)"
1888+ company_id: base.main_company
1889+ date_start: !eval "'%s-02-01' % (datetime.now().year + 1)"
1890+ date_stop: !eval "'%s-02-%s' % ((datetime.now().year + 1), (datetime((datetime.now().year + 1), 3, 1) - timedelta(days=1)).day)"
1891+ name: !eval "'02/%s' % (datetime.now().year + 1)"
1892+ - code: !eval "'03/%s' % (datetime.now().year + 1)"
1893+ company_id: base.main_company
1894+ date_start: !eval "'%s-03-01' % (datetime.now().year + 1)"
1895+ date_stop: !eval "'%s-03-31' % (datetime.now().year + 1)"
1896+ name: !eval "'03/%s' % (datetime.now().year + 1)"
1897+ - code: !eval "'04/%s' % (datetime.now().year + 1)"
1898+ company_id: base.main_company
1899+ date_start: !eval "'%s-04-01' % (datetime.now().year + 1)"
1900+ date_stop: !eval "'%s-04-30' % (datetime.now().year + 1)"
1901+ name: !eval "'04/%s' % (datetime.now().year + 1)"
1902+ - code: !eval "'05/%s' % (datetime.now().year + 1)"
1903+ company_id: base.main_company
1904+ date_start: !eval "'%s-05-01' % (datetime.now().year + 1)"
1905+ date_stop: !eval "'%s-05-31' % (datetime.now().year + 1)"
1906+ name: !eval "'05/%s' % (datetime.now().year + 1)"
1907+ - code: !eval "'06/%s' % (datetime.now().year + 1)"
1908+ company_id: base.main_company
1909+ date_start: !eval "'%s-06-01' % (datetime.now().year + 1)"
1910+ date_stop: !eval "'%s-06-30' % (datetime.now().year + 1)"
1911+ name: !eval "'06/%s' % (datetime.now().year + 1)"
1912+ - code: !eval "'07/%s' % (datetime.now().year + 1)"
1913+ company_id: base.main_company
1914+ date_start: !eval "'%s-07-01' % (datetime.now().year + 1)"
1915+ date_stop: !eval "'%s-07-31' % (datetime.now().year + 1)"
1916+ name: !eval "'07/%s' % (datetime.now().year + 1)"
1917+ - code: !eval "'08/%s' % (datetime.now().year + 1)"
1918+ company_id: base.main_company
1919+ date_start: !eval "'%s-08-01' % (datetime.now().year + 1)"
1920+ date_stop: !eval "'%s-08-31' % (datetime.now().year + 1)"
1921+ name: !eval "'08/%s' % (datetime.now().year + 1)"
1922+ - code: !eval "'09/%s' % (datetime.now().year + 1)"
1923+ company_id: base.main_company
1924+ date_start: !eval "'%s-09-01' % (datetime.now().year + 1)"
1925+ date_stop: !eval "'%s-09-30' % (datetime.now().year + 1)"
1926+ name: !eval "'09/%s' % (datetime.now().year + 1)"
1927+ - code: !eval "'10/%s' % (datetime.now().year + 1)"
1928+ company_id: base.main_company
1929+ date_start: !eval "'%s-10-01' % (datetime.now().year + 1)"
1930+ date_stop: !eval "'%s-10-31' % (datetime.now().year + 1)"
1931+ name: !eval "'10/%s' % (datetime.now().year + 1)"
1932+ - code: !eval "'11/%s' % (datetime.now().year + 1)"
1933+ company_id: base.main_company
1934+ date_start: !eval "'%s-11-01' % (datetime.now().year + 1)"
1935+ date_stop: !eval "'%s-11-30' % (datetime.now().year + 1)"
1936+ name: !eval "'11/%s' % (datetime.now().year + 1)"
1937+ - code: !eval "'12/%s' % (datetime.now().year + 1)"
1938+ company_id: base.main_company
1939+ date_start: !eval "'%s-12-01' % (datetime.now().year + 1)"
1940+ date_stop: !eval "'%s-12-31' % (datetime.now().year + 1)"
1941+ name: !eval "'12/%s' % (datetime.now().year + 1)"
1942
1943
1944 -
1945 Creating a account.fiscalyear record with a period in december but with different dates than the holding
1946 -
1947 !record {model: account.fiscalyear, id: account_fiscalyear_fy1}:
1948- code: FY2012
1949+ code: !eval "'FY%s' % (datetime.now().year + 1)"
1950 company_id: account_consolidation.subsidiary_b
1951- date_start: '2012-01-01'
1952- date_stop: '2012-12-31'
1953- name: FY2012
1954+ date_start: !eval "'%s-01-01' % (datetime.now().year + 1)"
1955+ date_stop: !eval "'%s-12-31' % (datetime.now().year + 1)"
1956+ name: !eval "'FY%s' % (datetime.now().year + 1)"
1957 period_ids:
1958 - code: diff_dates
1959 company_id: account_consolidation.subsidiary_b
1960- date_start: '2012-12-15'
1961- date_stop: '2012-12-31'
1962+ date_start: !eval "'%s-12-15' % (datetime.now().year + 1)"
1963+ date_stop: !eval "'%s-12-31' % (datetime.now().year + 1)"
1964 name: diff_dates
1965
1966
1967@@ -245,70 +245,70 @@
1968 Creating a account.fiscalyear record on subsidiary with a period for january (missing on holding)
1969 -
1970 !record {model: account.fiscalyear, id: account_fiscalyear_fy2}:
1971- code: FY2012
1972+ code: !eval "'FY%s' % (datetime.now().year + 1)"
1973 company_id: account_consolidation.subsidiary_a
1974- date_start: '2012-01-01'
1975- date_stop: '2012-12-31'
1976- name: FY2012
1977+ date_start: !eval "'%s-01-01' % (datetime.now().year + 1)"
1978+ date_stop: !eval "'%s-12-31' % (datetime.now().year + 1)"
1979+ name: !eval "'FY%s' % (datetime.now().year + 1)"
1980 period_ids:
1981- - code: 00/2012
1982+ - code: !eval "'00/%s' % (datetime.now().year + 1)"
1983 company_id: account_consolidation.subsidiary_a
1984- date_start: '2012-01-01'
1985- date_stop: '2012-01-01'
1986+ date_start: !eval "'%s-01-01' % (datetime.now().year + 1)"
1987+ date_stop: !eval "'%s-01-01' % (datetime.now().year + 1)"
1988 name: Opening Period
1989 special: true
1990- - code: 01/2012
1991- company_id: account_consolidation.subsidiary_a
1992- date_start: '2012-01-01'
1993- date_stop: '2012-01-31'
1994- name: 01/2012
1995- - code: 02/2012
1996- company_id: account_consolidation.subsidiary_a
1997- date_start: '2012-02-01'
1998- date_stop: '2012-02-29'
1999- name: 02/2012
2000- - code: 03/2012
2001- company_id: account_consolidation.subsidiary_a
2002- date_start: '2012-03-01'
2003- date_stop: '2012-03-31'
2004- name: 03/2012
2005- - code: 04/2012
2006- company_id: account_consolidation.subsidiary_a
2007- date_start: '2012-04-01'
2008- date_stop: '2012-04-30'
2009- name: 04/2012
2010- - code: 05/2012
2011- company_id: account_consolidation.subsidiary_a
2012- date_start: '2012-05-01'
2013- date_stop: '2012-05-31'
2014- name: 05/2012
2015- - code: 06/2012
2016- company_id: account_consolidation.subsidiary_a
2017- date_start: '2012-06-01'
2018- date_stop: '2012-06-30'
2019- name: 06/2012
2020- - code: 08/2012
2021- company_id: account_consolidation.subsidiary_a
2022- date_start: '2012-08-01'
2023- date_stop: '2012-08-31'
2024- name: 08/2012
2025- - code: 09/2012
2026- company_id: account_consolidation.subsidiary_a
2027- date_start: '2012-09-01'
2028- date_stop: '2012-09-30'
2029- name: 09/2012
2030- - code: 10/2012
2031- company_id: account_consolidation.subsidiary_a
2032- date_start: '2012-10-01'
2033- date_stop: '2012-10-31'
2034- name: 10/2012
2035- - code: 11/2012
2036- company_id: account_consolidation.subsidiary_a
2037- date_start: '2012-11-01'
2038- date_stop: '2012-11-30'
2039- name: 11/2012
2040- - code: 12/2012
2041- company_id: account_consolidation.subsidiary_a
2042- date_start: '2012-12-01'
2043- date_stop: '2012-12-31'
2044- name: 12/2012
2045+ - code: !eval "'01/%s' % (datetime.now().year + 1)"
2046+ company_id: account_consolidation.subsidiary_a
2047+ date_start: !eval "'%s-01-01' % (datetime.now().year + 1)"
2048+ date_stop: !eval "'%s-01-31' % (datetime.now().year + 1)"
2049+ name: !eval "'01/%s' % (datetime.now().year + 1)"
2050+ - code: !eval "'02/%s' % (datetime.now().year + 1)"
2051+ company_id: account_consolidation.subsidiary_a
2052+ date_start: !eval "'%s-02-01' % (datetime.now().year + 1)"
2053+ date_stop: !eval "'%s-02-%s' % ((datetime.now().year + 1), (datetime((datetime.now().year + 1), 3, 1) - timedelta(days=1)).day)"
2054+ name: !eval "'02/%s' % (datetime.now().year + 1)"
2055+ - code: !eval "'03/%s' % (datetime.now().year + 1)"
2056+ company_id: account_consolidation.subsidiary_a
2057+ date_start: !eval "'%s-03-01' % (datetime.now().year + 1)"
2058+ date_stop: !eval "'%s-03-31' % (datetime.now().year + 1)"
2059+ name: !eval "'03/%s' % (datetime.now().year + 1)"
2060+ - code: !eval "'04/%s' % (datetime.now().year + 1)"
2061+ company_id: account_consolidation.subsidiary_a
2062+ date_start: !eval "'%s-04-01' % (datetime.now().year + 1)"
2063+ date_stop: !eval "'%s-04-30' % (datetime.now().year + 1)"
2064+ name: !eval "'04/%s' % (datetime.now().year + 1)"
2065+ - code: !eval "'05/%s' % (datetime.now().year + 1)"
2066+ company_id: account_consolidation.subsidiary_a
2067+ date_start: !eval "'%s-05-01' % (datetime.now().year + 1)"
2068+ date_stop: !eval "'%s-05-31' % (datetime.now().year + 1)"
2069+ name: !eval "'05/%s' % (datetime.now().year + 1)"
2070+ - code: !eval "'06/%s' % (datetime.now().year + 1)"
2071+ company_id: account_consolidation.subsidiary_a
2072+ date_start: !eval "'%s-06-01' % (datetime.now().year + 1)"
2073+ date_stop: !eval "'%s-06-30' % (datetime.now().year + 1)"
2074+ name: !eval "'06/%s' % (datetime.now().year + 1)"
2075+ - code: !eval "'08/%s' % (datetime.now().year + 1)"
2076+ company_id: account_consolidation.subsidiary_a
2077+ date_start: !eval "'%s-08-01' % (datetime.now().year + 1)"
2078+ date_stop: !eval "'%s-08-31' % (datetime.now().year + 1)"
2079+ name: !eval "'08/%s' % (datetime.now().year + 1)"
2080+ - code: !eval "'09/%s' % (datetime.now().year + 1)"
2081+ company_id: account_consolidation.subsidiary_a
2082+ date_start: !eval "'%s-09-01' % (datetime.now().year + 1)"
2083+ date_stop: !eval "'%s-09-30' % (datetime.now().year + 1)"
2084+ name: !eval "'09/%s' % (datetime.now().year + 1)"
2085+ - code: !eval "'10/%s' % (datetime.now().year + 1)"
2086+ company_id: account_consolidation.subsidiary_a
2087+ date_start: !eval "'%s-10-01' % (datetime.now().year + 1)"
2088+ date_stop: !eval "'%s-10-31' % (datetime.now().year + 1)"
2089+ name: !eval "'10/%s' % (datetime.now().year + 1)"
2090+ - code: !eval "'11/%s' % (datetime.now().year + 1)"
2091+ company_id: account_consolidation.subsidiary_a
2092+ date_start: !eval "'%s-11-01' % (datetime.now().year + 1)"
2093+ date_stop: !eval "'%s-11-30' % (datetime.now().year + 1)"
2094+ name: !eval "'11/%s' % (datetime.now().year + 1)"
2095+ - code: !eval "'12/%s' % (datetime.now().year + 1)"
2096+ company_id: account_consolidation.subsidiary_a
2097+ date_start: !eval "'%s-12-01' % (datetime.now().year + 1)"
2098+ date_stop: !eval "'%s-12-31' % (datetime.now().year + 1)"
2099+ name: !eval "'12/%s' % (datetime.now().year + 1)"
2100
2101=== modified file 'account_consolidation/wizard/consolidation_base.py'
2102--- account_consolidation/wizard/consolidation_base.py 2012-04-18 14:35:42 +0000
2103+++ account_consolidation/wizard/consolidation_base.py 2014-06-26 13:58:55 +0000
2104@@ -1,75 +1,76 @@
2105 # -*- coding: utf-8 -*-
2106 ##############################################################################
2107 #
2108-# Copyright (c) 2011 Camptocamp SA (http://www.camptocamp.com)
2109-#
2110-# Author : Guewen Baconnier (Camptocamp)
2111-#
2112-# WARNING: This program as such is intended to be used by professional
2113-# programmers who take the whole responsability of assessing all potential
2114-# consequences resulting from its eventual inadequacies and bugs
2115-# End users who are looking for a ready-to-use solution with commercial
2116-# garantees and support are strongly adviced to contract a Free Software
2117-# Service Company
2118-#
2119-# This program is Free Software; you can redistribute it and/or
2120-# modify it under the terms of the GNU General Public License
2121-# as published by the Free Software Foundation; either version 2
2122-# of the License, or (at your option) any later version.
2123-#
2124-# This program is distributed in the hope that it will be useful,
2125-# but WITHOUT ANY WARRANTY; without even the implied warranty of
2126-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2127-# GNU General Public License for more details.
2128-#
2129-# You should have received a copy of the GNU General Public License
2130-# along with this program; if not, write to the Free Software
2131-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
2132+# Author: Guewen Baconnier
2133+# Copyright 2011-2013 Camptocamp SA
2134+#
2135+# This program is free software: you can redistribute it and/or modify
2136+# it under the terms of the GNU Affero General Public License as
2137+# published by the Free Software Foundation, either version 3 of the
2138+# License, or (at your option) any later version.
2139+#
2140+# This program is distributed in the hope that it will be useful,
2141+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2142+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2143+# GNU Affero General Public License for more details.
2144+#
2145+# You should have received a copy of the GNU Affero General Public License
2146+# along with this program. If not, see <http://www.gnu.org/licenses/>.
2147 #
2148 ##############################################################################
2149
2150-from osv import osv, fields
2151-from tools.translate import _
2152-
2153-
2154-class account_consolidation_base(osv.osv_memory):
2155+from openerp.osv import osv, orm, fields
2156+from openerp.tools.translate import _
2157+
2158+
2159+class account_consolidation_base(orm.AbstractModel):
2160 _name = 'account.consolidation.base'
2161 _description = 'Common consolidation wizard. Intended to be inherited'
2162
2163 def _default_company(self, cr, uid, context=None):
2164- user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
2165- if user.company_id:
2166- return user.company_id.id
2167- return self.pool.get('res.company').search(cr, uid, [('parent_id', '=', False)])[0]
2168+ comp_obj = self.pool['res.company']
2169+ return comp_obj._company_default_get(cr, uid)
2170+
2171+ def _default_chart(self, cr, uid, context=None):
2172+ comp_obj = self.pool['res.company']
2173+ comp_id = comp_obj._company_default_get(cr, uid)
2174+ company = comp_obj.browse(cr, uid, comp_id)
2175+ return company.consolidation_chart_account_id.id
2176
2177 _columns = {
2178- 'fiscalyear_id': fields.many2one('account.fiscalyear', 'Fiscal Year', required=True,
2179- help="The checks will be done on the periods of the selected fiscal year."),
2180- 'company_id': fields.many2one('res.company', 'Company', required=True),
2181- 'holding_chart_account_id': fields.many2one('account.account',
2182- 'Chart of Accounts',
2183- required=True,
2184- domain=[('parent_id', '=', False)]),
2185- 'subsidiary_ids': fields.many2many('res.company', 'account_conso_comp_rel', 'conso_id', 'company_id',
2186- 'Subsidiaries', required=True)
2187+ 'fiscalyear_id': fields.many2one(
2188+ 'account.fiscalyear',
2189+ 'Fiscal Year',
2190+ required=True,
2191+ help="The checks will be done on the periods of "
2192+ "the selected fiscal year."),
2193+ 'company_id': fields.many2one(
2194+ 'res.company', 'Company', required=True),
2195+ 'holding_chart_account_id': fields.many2one(
2196+ 'account.account',
2197+ 'Chart of Accounts',
2198+ required=True,
2199+ domain=[('parent_id', '=', False)]),
2200+ 'subsidiary_ids': fields.many2many(
2201+ 'res.company',
2202+ 'account_conso_comp_rel',
2203+ 'conso_id',
2204+ 'company_id',
2205+ 'Subsidiaries',
2206+ required=True)
2207 }
2208
2209- _defaults = {
2210- 'company_id': _default_company,
2211- }
2212+ _defaults = {'company_id': _default_company,
2213+ 'holding_chart_account_id': _default_chart,
2214+ }
2215
2216 def on_change_company_id(self, cr, uid, ids, company_id, context=None):
2217 """
2218 On change of the company, set the chart of account and the subsidiaries
2219
2220- @param self: The object pointer
2221- @param cr: the current row, from the database cursor,
2222- @param uid: the current user’s ID for security checks,
2223- @param ids: List of the wizard IDs (commonly the first element is the current ID)
2224- @param company_id: ID of the selected company
2225- @param context: A standard dictionary for contextual values
2226+ :param company_id: ID of the selected company
2227
2228- @return: dict of values to change
2229+ :return: dict of values to change
2230 """
2231 company_obj = self.pool.get('res.company')
2232
2233@@ -82,21 +83,27 @@
2234
2235 return {'value': result}
2236
2237- def check_subsidiary_periods(self, cr, uid, ids, holding_company_id, subs_company_id, fyear_id, context=None):
2238- """
2239- Check Subsidiary company periods vs Holding company periods and returns a list of errors
2240- All the periods defined within the group must be the same (same beginning and ending dates)
2241-
2242- @param self: The object pointer
2243- @param cr: the current row, from the database cursor,
2244- @param uid: the current user’s ID for security checks,
2245- @param ids: List of the wizard IDs (commonly the first element is the current ID)
2246- @param holding_company_id: ID of the holding company
2247- @param subs_company_id: ID of the subsidiary company to check
2248- @param fyear_id: ID of the fiscal years to compare
2249- @param context: A standard dictionary for contextual values
2250-
2251- @return: dict of list with errors for each company {company_id: ['error 1', 'error2']}
2252+ def check_subsidiary_periods(self, cr, uid, ids, holding_company_id,
2253+ subs_company_id, fyear_id, context=None):
2254+ """ Check Subsidiary company periods vs Holding company periods and
2255+ returns a list of errors
2256+
2257+ The periods checked are the periods within the fiscal year of the
2258+ holding, and the periods of the subsidiary company in the same range of
2259+ time.
2260+
2261+ The fiscal year of the subsidiary is deduced from the start/stop date
2262+ of the holding's fiscal year.
2263+
2264+ All the periods defined within the group must have the same beginning
2265+ and ending dates to be valid.
2266+
2267+ :param holding_company_id: ID of the holding company
2268+ :param subs_company_id: ID of the subsidiary company to check
2269+ :param fyear_id: ID of the fiscal year of the holding.
2270+
2271+ :return: dict of list with errors for each company
2272+ {company_id: ['error 1', 'error2']}
2273 """
2274 company_obj = self.pool.get('res.company')
2275 period_obj = self.pool.get('account.period')
2276@@ -108,48 +115,69 @@
2277 errors = []
2278
2279 # get holding fiscal year and periods
2280- holding = company_obj.browse(cr, uid, holding_company_id, context=context)
2281- subsidiary = company_obj.browse(cr, uid, subs_company_id, context=context)
2282+ holding = company_obj.browse(
2283+ cr, uid, holding_company_id, context=context)
2284+ subsidiary = company_obj.browse(
2285+ cr, uid, subs_company_id, context=context)
2286
2287- holding_periods_ids = period_obj.search(cr, uid,
2288+ holding_periods_ids = period_obj.search(
2289+ cr, uid,
2290 [('company_id', '=', holding.id),
2291 ('fiscalyear_id', '=', holding_fiscal_year.id)],
2292 context=context)
2293- holding_periods = period_obj.browse(cr, uid, holding_periods_ids, context=context)
2294+ holding_periods = period_obj.browse(
2295+ cr, uid, holding_periods_ids, context=context)
2296
2297 # get subsidiary fiscal year and periods
2298- subsidiary_fiscal_year = fy_obj.search(cr, uid,
2299+ subsidiary_fiscal_year = fy_obj.search(
2300+ cr, uid,
2301 [('company_id', '=', subsidiary.id),
2302 ('date_start', '=', holding_fiscal_year.date_start),
2303 ('date_stop', '=', holding_fiscal_year.date_stop),
2304- ])
2305+ ],
2306+ context=context)
2307 if not subsidiary_fiscal_year:
2308- errors.append(_('The fiscal year of the subsidiary company %s does not exists from %s to %s')
2309- % (subsidiary.name, holding_fiscal_year.date_start, holding_fiscal_year.date_stop))
2310+ errors.append(
2311+ _('The fiscal year of the subsidiary company %s '
2312+ 'does not exists from %s to %s') %
2313+ (subsidiary.name,
2314+ holding_fiscal_year.date_start,
2315+ holding_fiscal_year.date_stop))
2316 else:
2317- subsidiary_period_ids = period_obj.search(cr, uid,
2318+ subsidiary_period_ids = period_obj.search(
2319+ cr, uid,
2320 [('company_id', '=', subsidiary.id),
2321- ('fiscalyear_id', '=', subsidiary_fiscal_year[0])], # 0 because there can be only 1 fiscal year on the same dates as the holding
2322+ # 0 because there can be only 1 fiscal year
2323+ # on the same dates than the holding
2324+ ('fiscalyear_id', '=', subsidiary_fiscal_year[0])],
2325 context=context)
2326- subsidiary_periods = period_obj.browse(cr, uid, subsidiary_period_ids, context=context)
2327+ subsidiary_periods = period_obj.browse(
2328+ cr, uid, subsidiary_period_ids, context=context)
2329
2330- # a holding fiscal year may have more periods than a subsidiary (a subsidiary created at the middle of the year for example)
2331+ # a holding fiscal year may have more periods than a subsidiary
2332+ # (a subsidiary created at the middle of the year for example)
2333 # but the reverse situation is not allowed
2334 if len(holding_periods) < len(subsidiary_periods):
2335- errors.append(_('Holding company has less periods than the subsidiary company %s!') % (subsidiary.name,))
2336+ errors.append(
2337+ _('Holding company has less periods than the '
2338+ 'subsidiary company %s!') % subsidiary.name)
2339
2340- # check subsidiary periods dates vs holding periods for each period of the subsidiary
2341+ # check subsidiary periods dates vs holding periods
2342+ # for each period of the subsidiary
2343 for subsidiary_period in subsidiary_periods:
2344 period_exists = False
2345 for holding_period in holding_periods:
2346- if subsidiary_period.date_start == holding_period.date_start \
2347- and subsidiary_period.date_stop == holding_period.date_stop:
2348- period_exists = True
2349- break
2350+ if (subsidiary_period.date_start == holding_period.date_start and
2351+ subsidiary_period.date_stop == holding_period.date_stop):
2352+ period_exists = True
2353+ break
2354 if not period_exists:
2355- errors.append(_('Period from %s to %s not found in holding company %s')
2356- % (subsidiary_period.date_start, subsidiary_period.date_stop, holding.name))
2357-
2358+ errors.append(
2359+ _('Period from %s to %s not found '
2360+ 'in holding company %s') %
2361+ (subsidiary_period.date_start,
2362+ subsidiary_period.date_stop,
2363+ holding.name))
2364 return errors
2365
2366 def check_all_periods(self, cr, uid, ids, context=None):
2367@@ -157,24 +185,24 @@
2368 Call the period check on each period of all subsidiaries
2369 Returns the errors by subsidiary
2370
2371- @param self: The object pointer
2372- @param cr: the current row, from the database cursor,
2373- @param uid: the current user’s ID for security checks,
2374- @param ids: List of the wizard IDs (commonly the first element is the current ID)
2375- @param context: A standard dictionary for contextual values
2376-
2377- @return: dict of list with errors for each company {company_id: ['error 1', 'error2']}
2378+ :return: dict of list with errors for each company
2379+ {company_id: ['error 1', 'error2']}
2380 """
2381+ if isinstance(ids, (int, long)):
2382+ ids = [ids]
2383+ assert len(ids) == 1, "only 1 id expected"
2384+
2385 form = self.browse(cr, uid, ids[0], context=context)
2386
2387 errors_by_company = {}
2388 for subsidiary in form.subsidiary_ids:
2389- errors = \
2390- self.check_subsidiary_periods(cr, uid, ids,
2391- form.company_id.id,
2392- subsidiary.id,
2393- form.fiscalyear_id.id,
2394- context=context)
2395+ errors = self.check_subsidiary_periods(
2396+ cr, uid,
2397+ ids,
2398+ form.company_id.id,
2399+ subsidiary.id,
2400+ form.fiscalyear_id.id,
2401+ context=context)
2402 if errors:
2403 errors_by_company[subsidiary.id] = errors
2404
2405@@ -182,24 +210,23 @@
2406
2407 def _chart_accounts_data(self, cr, uid, ids, chart_account_id, context=None):
2408 """
2409- Returns the list of accounts to use for the consolidation for the holding
2410- or the subsidiaries. Keys of the returned dict are the account codes and
2411- if the context is holding_coa, dict values are the browse instances of the accounts
2412-
2413- @param self: The object pointer
2414- @param cr: the current row, from the database cursor,
2415- @param uid: the current user’s ID for security checks,
2416- @param ids: List of the wizard IDs (commonly the first element is the current ID)
2417- @chart_account_id: ID of the "Chart" Account for which we want the account codes
2418- @param context: A standard dictionary for contextual values
2419-
2420- @return: dict with {account codes: browse instances}
2421+ Returns the list of accounts to use for the consolidation
2422+ for the holding or the subsidiaries.
2423+ Keys of the returned dict are the account codes and
2424+ if the context is holding_coa,
2425+ dict values are the browse instances of the accounts
2426+
2427+ :chart_account_id: ID of the Chart of Account for which
2428+ we want the account codes
2429+
2430+ :return: dict with {account codes: browse instances}
2431 """
2432- context = context or {}
2433+ if context is None:
2434+ context = {}
2435 account_obj = self.pool.get('account.account')
2436 res = {}
2437- account_ids = account_obj.\
2438- _get_children_and_consol(cr, uid, chart_account_id, context=context)
2439+ account_ids = account_obj._get_children_and_consol(
2440+ cr, uid, chart_account_id, context=context)
2441
2442 # do not consolidate chart root
2443 account_ids.remove(chart_account_id)
2444@@ -216,33 +243,92 @@
2445 continue
2446
2447 res[account.code] = {}
2448- # we'll need the browse object during the "consolidate wizard" for the holding
2449- res[account.code] = holding and account or True
2450+ # we'll need the browse object during the
2451+ # "consolidate wizard" for the holding
2452+ res[account.code] = account if holding else True
2453
2454 return res
2455
2456- def check_subsidiary_chart(self, cr, uid, ids, holding_chart_account_id, subsidiary_chart_account_id, context=None):
2457- """
2458- Check a Holding Chart of Accounts vs a Subsidiary Virtual Chart of Accounts
2459+ def check_subsidiary_mapping_account(self, cr, uid, ids, context=None):
2460+ """ Call the period check on each period of all subsidiaries
2461+ Returns the errors by subsidiary
2462+
2463+ :return: dict of list with errors for each company
2464+ {company_id: ['error 1', 'error2']}
2465+
2466+ """
2467+ if isinstance(ids, (int, long)):
2468+ ids = [ids]
2469+ assert len(ids) == 1, "only 1 id expected"
2470+
2471+ form = self.browse(cr, uid, ids[0], context=context)
2472+ errors_by_company = {}
2473+ for subsidiary in form.subsidiary_ids:
2474+ errors = self._check_subsidiary_mapping_account(
2475+ cr, uid,
2476+ ids,
2477+ subsidiary,
2478+ context=context)
2479+ if errors:
2480+ errors_by_company[subsidiary.id] = errors
2481+
2482+ return errors_by_company
2483+
2484+ def _check_subsidiary_mapping_account(self, cr, uid, ids,
2485+ company_id, context=None):
2486+ if context is None:
2487+ context = {}
2488+ errors = []
2489+ account_obj = self.pool.get('account.account')
2490+ normal_account_ids = account_obj.search(cr, uid,
2491+ [('company_id', '=', company_id.id),
2492+ ('type', 'not in', ['consolidation', 'view'])],
2493+ context=context)
2494+ consolidated_account_ids = account_obj.search(
2495+ cr, uid,
2496+ [('company_id', '=', company_id.id),
2497+ ('type', '=', 'consolidation')],
2498+ context=context)
2499+ consolidate_child_ids = []
2500+ for account_id in consolidated_account_ids:
2501+ child_consol_ids = account_obj._get_children_and_consol(
2502+ cr, uid, account_id, context=context)
2503+ consolidate_child_ids = consolidate_child_ids + child_consol_ids
2504+ for sub_id in normal_account_ids:
2505+ cpt_occur = consolidate_child_ids.count(sub_id)
2506+ if cpt_occur == 0 or cpt_occur > 1:
2507+ ## We read the code of account
2508+ code = account_obj.read(cr, uid, sub_id, ['code'],
2509+ context=context)['code']
2510+ message = _("Code %s is mapping %s times" % (code, cpt_occur))
2511+ errors.append(message)
2512+ return errors
2513+
2514+ def check_subsidiary_chart(self, cr, uid, ids, holding_chart_account_id,
2515+ subsidiary_chart_account_id, context=None):
2516+ """
2517+ Check a Holding Chart of Accounts vs a Subsidiary Virtual
2518+ Chart of Accounts
2519 All the accounts of the Virtual CoA must exist in the Holding CoA.
2520- The Holding's CoA may hold accounts which do not exist in the Subsidiary's Virtual CoA.
2521-
2522- @param self: The object pointer
2523- @param cr: the current row, from the database cursor,
2524- @param uid: the current user’s ID for security checks,
2525- @param ids: List of the wizard IDs (commonly the first element is the current ID)
2526- @param holding_chart_account_id: ID of the "Chart" Account of the holding company
2527- @param subsidiary_chart_account_id: ID of the "Chart" Account of the subsidiary company to check
2528- @param context: A standard dictionary for contextual values
2529-
2530- @return: List of accounts existing on subsidiary but no on holding COA
2531+ The Holding's CoA may hold accounts which do not exist
2532+ in the Subsidiary's Virtual CoA.
2533+
2534+ :param holding_chart_account_id: ID of the Chart of Account
2535+ of the holding company
2536+ :param subsidiary_chart_account_id: ID of the Chart of Account
2537+ of the subsidiary company to check
2538+
2539+ :return: List of accounts existing on subsidiary but no on holding COA
2540 """
2541- context = context or {}
2542- holding_ctx = context.copy()
2543- holding_ctx.update({'holding_coa': True})
2544- holding_accounts = self._chart_accounts_data(cr, uid, ids, holding_chart_account_id, context=holding_ctx)
2545- subsidiary_accounts = self._chart_accounts_data(cr, uid, ids, subsidiary_chart_account_id, context=context)
2546- # accounts which are configured on the subsidiary VCoA but not on the holding CoA
2547+ if context is None:
2548+ context = {}
2549+ holding_ctx = dict(context, holding_coa=True)
2550+ holding_accounts = self._chart_accounts_data(
2551+ cr, uid, ids, holding_chart_account_id, context=holding_ctx)
2552+ subsidiary_accounts = self._chart_accounts_data(
2553+ cr, uid, ids, subsidiary_chart_account_id, context=context)
2554+ # accounts which are configured on the subsidiary
2555+ # Virtual CoA but not on the holding CoA
2556 spare_accounts = [code for code
2557 in subsidiary_accounts
2558 if code not in holding_accounts]
2559@@ -250,26 +336,26 @@
2560
2561 def check_account_charts(self, cr, uid, ids, context=None):
2562 """
2563- Check the chart of accounts of the holding vs each virtual chart of accounts of the subsidiaries
2564-
2565- @param self: The object pointer
2566- @param cr: the current row, from the database cursor,
2567- @param uid: the current user’s ID for security checks,
2568- @param ids: List of the wizard IDs (commonly the first element is the current ID)
2569- @param context: A standard dictionary for contextual values
2570+ Check the chart of accounts of the holding vs
2571+ each virtual chart of accounts of the subsidiaries
2572 """
2573+ if isinstance(ids, (int, long)):
2574+ ids = [ids]
2575+ assert len(ids) == 1, "only 1 id expected"
2576 form = self.browse(cr, uid, ids[0], context=context)
2577
2578 invalid_items_per_company = {}
2579 for subsidiary in form.subsidiary_ids:
2580 if not subsidiary.consolidation_chart_account_id:
2581- raise osv.except_osv(_('Error'), _('No chart of accounts for company %s') % (subsidiary,))
2582-
2583- invalid_items = \
2584- self.check_subsidiary_chart(cr, uid, ids,
2585- form.holding_chart_account_id.id,
2586- subsidiary.consolidation_chart_account_id.id,
2587- context=context)
2588+ raise osv.except_osv(
2589+ _('Error'),
2590+ _('No chart of accounts for company %s') % subsidiary.name)
2591+ invalid_items = self.check_subsidiary_chart(
2592+ cr, uid,
2593+ ids,
2594+ form.holding_chart_account_id.id,
2595+ subsidiary.consolidation_chart_account_id.id,
2596+ context=context)
2597 if any(invalid_items):
2598 invalid_items_per_company[subsidiary.id] = invalid_items
2599
2600@@ -278,25 +364,24 @@
2601 def run_consolidation(self, cr, uid, ids, context=None):
2602 """
2603 Proceed with all checks before launch any consolidation step
2604- This is a base method intended to be inherited with the next consolidation steps
2605-
2606- @param self: The object pointer
2607- @param cr: the current row, from the database cursor,
2608- @param uid: the current user’s ID for security checks,
2609- @param ids: List of the wizard IDs (commonly the first element is the current ID)
2610- @param context: A standard dictionary for contextual values
2611+ This is a base method intended to be inherited with the next
2612+ consolidation steps
2613 """
2614+ if isinstance(ids, (int, long)):
2615+ ids = [ids]
2616+ assert len(ids) == 1, "only 1 id expected"
2617
2618 if self.check_all_periods(cr, uid, ids, context=context):
2619- raise osv.except_osv(_('Error'),
2620- _('Invalid periods, please launch the "Consolidation: Checks" wizard'))
2621+ raise osv.except_osv(
2622+ _('Error'),
2623+ _('Invalid periods, please launch the '
2624+ '"Consolidation: Checks" wizard'))
2625 if self.check_account_charts(cr, uid, ids, context=context):
2626- raise osv.except_osv(_('Error'),
2627- _('Invalid charts, please launch the "Consolidation: Checks" wizard'))
2628+ raise osv.except_osv(
2629+ _('Error'),
2630+ _('Invalid charts, please launch the '
2631+ '"Consolidation: Checks" wizard'))
2632
2633 # inherit to add the next steps of the reconciliation
2634
2635 return {'type': 'ir.actions.act_window_close'}
2636-
2637-
2638-account_consolidation_base()
2639
2640=== modified file 'account_consolidation/wizard/consolidation_check.py'
2641--- account_consolidation/wizard/consolidation_check.py 2012-04-18 14:35:42 +0000
2642+++ account_consolidation/wizard/consolidation_check.py 2014-06-26 13:58:55 +0000
2643@@ -1,109 +1,116 @@
2644 # -*- coding: utf-8 -*-
2645 ##############################################################################
2646 #
2647-# Copyright (c) 2011 Camptocamp SA (http://www.camptocamp.com)
2648-#
2649-# Author : Guewen Baconnier (Camptocamp)
2650-#
2651-# WARNING: This program as such is intended to be used by professional
2652-# programmers who take the whole responsability of assessing all potential
2653-# consequences resulting from its eventual inadequacies and bugs
2654-# End users who are looking for a ready-to-use solution with commercial
2655-# garantees and support are strongly adviced to contract a Free Software
2656-# Service Company
2657-#
2658-# This program is Free Software; you can redistribute it and/or
2659-# modify it under the terms of the GNU General Public License
2660-# as published by the Free Software Foundation; either version 2
2661-# of the License, or (at your option) any later version.
2662-#
2663-# This program is distributed in the hope that it will be useful,
2664-# but WITHOUT ANY WARRANTY; without even the implied warranty of
2665-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2666-# GNU General Public License for more details.
2667-#
2668-# You should have received a copy of the GNU General Public License
2669-# along with this program; if not, write to the Free Software
2670-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
2671+# Author: Guewen Baconnier
2672+# Copyright 2011-2013 Camptocamp SA
2673+#
2674+# This program is free software: you can redistribute it and/or modify
2675+# it under the terms of the GNU Affero General Public License as
2676+# published by the Free Software Foundation, either version 3 of the
2677+# License, or (at your option) any later version.
2678+#
2679+# This program is distributed in the hope that it will be useful,
2680+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2681+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2682+# GNU Affero General Public License for more details.
2683+#
2684+# You should have received a copy of the GNU Affero General Public License
2685+# along with this program. If not, see <http://www.gnu.org/licenses/>.
2686 #
2687 ##############################################################################
2688
2689-from osv import osv, fields
2690-
2691-from tools.translate import _
2692-
2693-
2694-class account_consolidation_check(osv.osv_memory):
2695+from openerp.osv import osv, orm, fields
2696+from openerp.tools.translate import _
2697+
2698+
2699+class account_consolidation_check(orm.TransientModel):
2700 _name = 'account.consolidation.check'
2701 _inherit = 'account.consolidation.base'
2702 _description = 'Consolidation Checks. Model used for views'
2703
2704 _columns = {
2705- 'subsidiary_ids': fields.many2many('res.company', 'account_conso_check_comp_rel', 'conso_id', 'company_id',
2706- 'Subsidiaries', required=True),
2707+ 'subsidiary_ids': fields.many2many(
2708+ 'res.company',
2709+ 'account_conso_check_comp_rel',
2710+ 'conso_id',
2711+ 'company_id',
2712+ 'Subsidiaries',
2713+ required=True),
2714 }
2715
2716 def check_account_charts(self, cr, uid, ids, context=None):
2717 """
2718 Action launched with the button on the view.
2719 Check the account charts and display a report of the errors
2720-
2721- @param self: The object pointer
2722- @param cr: the current row, from the database cursor,
2723- @param uid: the current user’s ID for security checks,
2724- @param ids: List of the wizard IDs (commonly the first element is the current ID)
2725- @param context: A standard dictionary for contextual values
2726 """
2727- invalid_items_per_company = \
2728- super(account_consolidation_check, self).check_account_charts(cr, uid, ids, context=context)
2729- if invalid_items_per_company:
2730- err_lines = []
2731- for company_id, account_codes in invalid_items_per_company.iteritems():
2732- company_obj = self.pool.get('res.company')
2733- company = company_obj.browse(cr, uid, company_id, context=context)
2734- err_lines.append(_("%s :") % (company.name,))
2735- [err_lines.append(_("Account with code %s does not exist on the Holding company.") % (account_code,))
2736- for account_code
2737- in account_codes]
2738- err_lines.append('')
2739-
2740- raise osv.except_osv(_('Invalid charts'),
2741- '\n'.join(err_lines))
2742-
2743- else:
2744- raise osv.except_osv(_('Validation'), _('Chart of Accounts are OK.'))
2745- # open a confirmation view ?
2746- return True
2747+ company_obj = self.pool.get('res.company')
2748+ invalid_items_per_company = super(account_consolidation_check, self).\
2749+ check_account_charts(cr, uid, ids, context=context)
2750+
2751+ if not invalid_items_per_company:
2752+ raise osv.except_osv(
2753+ _('Validation'),
2754+ _('Chart of Accounts are OK.'))
2755+
2756+ err_lines = []
2757+ for company_id, account_codes in invalid_items_per_company.iteritems():
2758+ company = company_obj.browse(
2759+ cr, uid, company_id, context=context)
2760+ err_lines.append(_("%s :") % company.name)
2761+ for account_code in account_codes:
2762+ err_lines.append(
2763+ _("Account with code %s does not exist on the "
2764+ "Holding company.") % account_code)
2765+ err_lines.append('')
2766+
2767+ raise osv.except_osv(
2768+ _('Invalid charts'), '\n'.join(err_lines))
2769
2770 def check_all_periods(self, cr, uid, ids, context=None):
2771 """
2772 Action launched with the button on the view.
2773 Check the periods and display a report of the errors
2774-
2775- @param self: The object pointer
2776- @param cr: the current row, from the database cursor,
2777- @param uid: the current user’s ID for security checks,
2778- @param ids: List of the wizard IDs (commonly the first element is the current ID)
2779- @param context: A standard dictionary for contextual values
2780 """
2781- errors_by_company = \
2782- super(account_consolidation_check, self).check_all_periods(cr, uid, ids, context=context)
2783-
2784- if errors_by_company:
2785- company_obj = self.pool.get('res.company')
2786-
2787- err_lines = []
2788- for company_id, errors in errors_by_company.iteritems():
2789- company = company_obj.browse(cr, uid, company_id, context=context)
2790- err_lines.append(_("%s :") % (company.name,))
2791- [err_lines.append(error) for error in errors]
2792- err_lines.append('')
2793-
2794- raise osv.except_osv(_('Invalid periods'),
2795- '\n'.join(err_lines))
2796- else:
2797+ errors_by_company = super(account_consolidation_check, self).\
2798+ check_all_periods(cr, uid, ids, context=context)
2799+
2800+ if not errors_by_company:
2801 raise osv.except_osv(_('Validation'), _('Periods are OK.'))
2802- # open a confirmation view ?
2803- return True
2804-
2805-account_consolidation_check()
2806+
2807+ company_obj = self.pool.get('res.company')
2808+
2809+ err_lines = []
2810+ for company_id, errors in errors_by_company.iteritems():
2811+ company = company_obj.browse(cr, uid, company_id, context=context)
2812+ err_lines.append(_("%s :") % company.name)
2813+ for error in errors:
2814+ err_lines.append(error)
2815+ err_lines.append('')
2816+
2817+ raise osv.except_osv(_('Invalid periods'),
2818+ '\n'.join(err_lines))
2819+
2820+ def check_subsidiary_mapping_account(self, cr, uid, ids, context=None):
2821+ """
2822+ Action launched with the button on the view.
2823+ Check the periods and display a report of the errors
2824+ """
2825+ errors_by_company = super(
2826+ account_consolidation_check, self
2827+ ).check_subsidiary_mapping_account(cr, uid, ids, context=context)
2828+
2829+ if not errors_by_company:
2830+ raise osv.except_osv(_('Validation'), _('All account is mapped'))
2831+
2832+ company_obj = self.pool.get('res.company')
2833+
2834+ err_lines = []
2835+ for company_id, errors in errors_by_company.iteritems():
2836+ company = company_obj.browse(cr, uid, company_id, context=context)
2837+ err_lines.append(_("%s :") % company.name)
2838+ for error in errors:
2839+ err_lines.append(error)
2840+ err_lines.append('')
2841+
2842+ raise osv.except_osv(_('Invalid accounts'),
2843+ '\n'.join(err_lines))
2844
2845=== modified file 'account_consolidation/wizard/consolidation_check_view.xml'
2846--- account_consolidation/wizard/consolidation_check_view.xml 2011-08-19 13:08:01 +0000
2847+++ account_consolidation/wizard/consolidation_check_view.xml 2014-06-26 13:58:55 +0000
2848@@ -2,32 +2,52 @@
2849 <openerp>
2850 <data>
2851
2852- <record id="view_consolidation_check_form" model="ir.ui.view">
2853+ <record id="view_consolidation_check_form" model="ir.ui.view">
2854 <field name="name">account.consolidation.check.form</field>
2855 <field name="model">account.consolidation.check</field>
2856 <field name="type">form</field>
2857 <field name="arch" type="xml">
2858- <form string="Consolidation: Checks">
2859- <group col="4" colspan="6">
2860- <field name="company_id" on_change="on_change_company_id(company_id)" invisible="True"/>
2861- <field name="fiscalyear_id" domain="[('company_id', '=', company_id)]"/>
2862- <newline/>
2863- <field name="holding_chart_account_id" domain="[('company_id', '=', company_id), ('parent_id', '=', False)]"/>
2864- <separator string="Subsidiaries to Consolidate" colspan="4"/>
2865- <field name="subsidiary_ids" colspan="4" nolabel="1" required="True" domain="[('parent_id', '=', company_id)]">
2866- <tree>
2867- <field name="name"/>
2868- <field name="consolidation_chart_account_id"/>
2869- </tree>
2870- </field>
2871- </group>
2872- <separator colspan="4"/>
2873- <group col="3" colspan="4">
2874- <button special="cancel" string="Cancel" icon='gtk-cancel'/>
2875- <button name="check_all_periods" string="Check Periods" colspan="1" type="object" icon="gtk-execute"/>
2876- <button name="check_account_charts" string="Check Charts" colspan="1" type="object" icon="gtk-execute"/>
2877- </group>
2878- </form>
2879+ <form string="Consolidation: Checks" version="7.0">
2880+ <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."/>
2881+ <group>
2882+ <field name="company_id"
2883+ on_change="on_change_company_id(company_id)"
2884+ invisible="True"/>
2885+ <field name="fiscalyear_id"
2886+ domain="[('company_id', '=', company_id)]"/>
2887+ <newline/>
2888+ <field name="holding_chart_account_id"
2889+ domain="[('company_id', '=', company_id), ('parent_id', '=', False)]"/>
2890+ <separator string="Subsidiaries to Consolidate" colspan="4"/>
2891+ <field name="subsidiary_ids" colspan="4" nolabel="1"
2892+ required="True"
2893+ domain="[('parent_id', '=', company_id)]">
2894+ <tree>
2895+ <field name="name"/>
2896+ <field name="consolidation_chart_account_id"/>
2897+ </tree>
2898+ </field>
2899+ </group>
2900+ <footer>
2901+ <button name="check_all_periods"
2902+ string="Check Periods" type="object"
2903+ class="oe_highlight"/>
2904+ or
2905+ <button name="check_account_charts"
2906+ string="Check Charts 1" type="object"
2907+ class="oe_highlight"/>
2908+ or
2909+ <button name="check_subsidiary_mapping_account"
2910+ string="Check Charts 2" type="object"
2911+ class="oe_highlight"/>
2912+ <button string="Cancel" class="oe_link" special="cancel"/>
2913+ </footer>
2914+ <group>
2915+ <label string="Check Period : Check consistency of accounting periods between subsidiaries and holding company." />
2916+ <label string="Check Chart 1 : Check consistency between subsidiaries consolidation chart and Holding company chart." />
2917+ <label string="Check Chart 2 : For each subsidiary, check consistency between the regular chart of accounts and the consolidation chart." />
2918+ </group>
2919+ </form>
2920 </field>
2921 </record>
2922
2923@@ -37,9 +57,8 @@
2924 <field name="res_model">account.consolidation.check</field>
2925 <field name="view_type">form</field>
2926 <field name="view_mode">form</field>
2927- <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>
2928 <field name="target">new</field>
2929 </record>
2930
2931- </data>
2932+ </data>
2933 </openerp>
2934
2935=== modified file 'account_consolidation/wizard/consolidation_consolidate.py'
2936--- account_consolidation/wizard/consolidation_consolidate.py 2012-04-11 07:57:56 +0000
2937+++ account_consolidation/wizard/consolidation_consolidate.py 2014-06-26 13:58:55 +0000
2938@@ -1,94 +1,113 @@
2939 # -*- coding: utf-8 -*-
2940 ##############################################################################
2941 #
2942-# Copyright (c) 2011 Camptocamp SA (http://www.camptocamp.com)
2943-#
2944-# Author : Guewen Baconnier (Camptocamp)
2945-#
2946-# WARNING: This program as such is intended to be used by professional
2947-# programmers who take the whole responsability of assessing all potential
2948-# consequences resulting from its eventual inadequacies and bugs
2949-# End users who are looking for a ready-to-use solution with commercial
2950-# garantees and support are strongly adviced to contract a Free Software
2951-# Service Company
2952-#
2953-# This program is Free Software; you can redistribute it and/or
2954-# modify it under the terms of the GNU General Public License
2955-# as published by the Free Software Foundation; either version 2
2956-# of the License, or (at your option) any later version.
2957-#
2958-# This program is distributed in the hope that it will be useful,
2959-# but WITHOUT ANY WARRANTY; without even the implied warranty of
2960-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2961-# GNU General Public License for more details.
2962-#
2963-# You should have received a copy of the GNU General Public License
2964-# along with this program; if not, write to the Free Software
2965-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
2966+# Author: Guewen Baconnier
2967+# Copyright 2011-2013 Camptocamp SA
2968+#
2969+# This program is free software: you can redistribute it and/or modify
2970+# it under the terms of the GNU Affero General Public License as
2971+# published by the Free Software Foundation, either version 3 of the
2972+# License, or (at your option) any later version.
2973+#
2974+# This program is distributed in the hope that it will be useful,
2975+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2976+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2977+# GNU Affero General Public License for more details.
2978+#
2979+# You should have received a copy of the GNU Affero General Public License
2980+# along with this program. If not, see <http://www.gnu.org/licenses/>.
2981 #
2982 ##############################################################################
2983
2984-from osv import osv, fields
2985-from tools.translate import _
2986-from tools import safe_eval as eval
2987+from openerp.osv import orm, fields
2988+from openerp.osv.osv import except_osv
2989+from openerp.tools.translate import _
2990
2991-class account_consolidation_consolidate(osv.osv_memory):
2992+class account_consolidation_consolidate(orm.TransientModel):
2993 _name = 'account.consolidation.consolidate'
2994 _inherit = 'account.consolidation.base'
2995
2996+ def _default_journal(self, cr, uid, context=None):
2997+ comp_obj = self.pool['res.company']
2998+ journ_obj = self.pool['account.journal']
2999+ comp_id = comp_obj._company_default_get(cr, uid)
3000+ journal_id = journ_obj.search(cr, uid, [('company_id', '=', comp_id)], limit=1)
3001+ if journal_id:
3002+ return journal_id[0]
3003+ return False
3004+
3005 _columns = {
3006- 'from_period_id': fields.many2one('account.period', 'Start Period', required=True,
3007- 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."),
3008- 'to_period_id': fields.many2one('account.period', 'End Period', required=True,
3009- help="The consolidation will be done at the very last date of the selected period."),
3010- 'journal_id': fields.many2one('account.journal', 'Journal', required=True),
3011- # not sure that we'll use them, actually using centralised counterpart journal
3012-# 'gain_account_id': fields.many2one('account.account', 'Gain Account', required=True,),
3013-# 'loss_account_id': fields.many2one('account.account', 'Loss Account', required=True,),
3014- 'target_move': fields.selection([('posted', 'All Posted Entries'),
3015- ('all', 'All Entries'),
3016- ], 'Target Moves', required=True),
3017- 'subsidiary_ids': fields.many2many('res.company', 'account_conso_conso_comp_rel', 'conso_id', 'company_id',
3018- 'Subsidiaries', required=True),
3019- }
3020-
3021- _defaults = {
3022- 'target_move': 'posted'
3023- }
3024+ 'from_period_id': fields.many2one(
3025+ 'account.period',
3026+ 'Start Period',
3027+ required=True,
3028+ help="Select the same period in 'from' and 'to' "
3029+ "if you want to proceed with a single period. "
3030+ "Start Period is ignored for Year To Date accounts."),
3031+
3032+ 'to_period_id': fields.many2one(
3033+ 'account.period',
3034+ 'End Period',
3035+ required=True,
3036+ help="The consolidation will be done at the very "
3037+ "last date of the selected period."),
3038+
3039+ 'journal_id': fields.many2one(
3040+ 'account.journal', 'Journal', required=True),
3041+
3042+ 'target_move': fields.selection(
3043+ [('posted', 'All Posted Entries'),
3044+ ('all', 'All Entries')],
3045+ 'Target Moves',
3046+ required=True),
3047+
3048+ 'subsidiary_ids': fields.many2many(
3049+ 'res.company',
3050+ 'account_conso_conso_comp_rel',
3051+ 'conso_id',
3052+ 'company_id',
3053+ string='Subsidiaries',
3054+ required=True),
3055+ }
3056+
3057+ _defaults = {'target_move': 'posted',
3058+ 'journal_id': _default_journal,
3059+ }
3060
3061 def _check_periods_fy(self, cr, uid, ids, context=None):
3062- if context is None:
3063- context = {}
3064+ if isinstance(ids, (int, long)):
3065+ ids = [ids]
3066+ assert len(ids) == 1, "only 1 id expected"
3067+
3068 form = self.browse(cr, uid, ids[0], context=context)
3069- if form.from_period_id.fiscalyear_id.id != form.to_period_id.fiscalyear_id.id:
3070- return False
3071- return True
3072+ return (form.from_period_id.fiscalyear_id.id ==
3073+ form.to_period_id.fiscalyear_id.id)
3074
3075 _constraints = [
3076- (_check_periods_fy, 'Start Period and End Period must be of the same Fiscal Year !', ['from_period_id', 'to_period_id']),
3077+ (_check_periods_fy,
3078+ 'Start Period and End Period must be of the same Fiscal Year !',
3079+ ['from_period_id', 'to_period_id']),
3080 ]
3081
3082- def on_change_from_period_id(self, cr, uid, ids, from_period_id, to_period_id, context=None):
3083- """
3084- On change of the From period, set the To period to the same period if it is empty
3085-
3086- @param self: The object pointer
3087- @param cr: the current row, from the database cursor,
3088- @param uid: the current user’s ID for security checks,
3089- @param ids: List of the wizard IDs (commonly the first element is the current ID)
3090- @param from_period_id: ID of the selected from period id
3091- @param to_period_id: ID of the current from period id
3092- @param context: A standard dictionary for contextual values
3093-
3094- @return: dict of values to change
3095+ def on_change_from_period_id(self, cr, uid, ids, from_period_id,
3096+ to_period_id, context=None):
3097+ """ On change of the From period, set the To period
3098+ to the same period if it is empty
3099+
3100+ :param from_period_id: ID of the selected from period id
3101+ :param to_period_id: ID of the current from period id
3102+
3103+ :return: dict of values to change
3104 """
3105 result = {}
3106 period_obj = self.pool.get('account.period')
3107- from_period = period_obj.browse(cr, uid, from_period_id, context=context)
3108+ from_period = period_obj.browse(cr, uid, from_period_id,
3109+ context=context)
3110 if not to_period_id:
3111 result['to_period_id'] = from_period_id
3112 else:
3113- to_period = period_obj.browse(cr, uid, to_period_id, context=context)
3114+ to_period = period_obj.browse(cr, uid, to_period_id,
3115+ context=context)
3116 if to_period.date_start < from_period.date_start:
3117 result['to_period_id'] = from_period_id
3118
3119@@ -99,97 +118,120 @@
3120 """
3121 Returns the currency rate type to use
3122
3123- @param self: The object pointer
3124- @param cr: the current row, from the database cursor,
3125- @param uid: the current user’s ID for security checks,
3126- @param ids: List of the wizard IDs (commonly the first element is the current ID)
3127- @param account: browse instance of account.account
3128- @param context: A standard dictionary for contextual values
3129+ :param account: browse_record instance of account.account
3130
3131- @return: 'spot' or 'average'
3132+ :return: id of the currency rate type to use
3133 """
3134- return account.consolidation_rate_type_id and account.consolidation_rate_type_id \
3135- or account.user_type.consolidation_rate_type_id and account.user_type.consolidation_rate_type_id.id \
3136- or False
3137+ if account.consolidation_rate_type_id:
3138+ return account.consolidation_rate_type_id.id
3139+
3140+ elif account.user_type.consolidation_rate_type_id:
3141+ return account.user_type.consolidation_rate_type_id.id
3142+
3143+ else:
3144+ return False
3145
3146 def _consolidation_mode(self, cr, uid, ids, account, context=None):
3147 """
3148 Returns the consolidation mode to use
3149
3150- @param self: The object pointer
3151- @param cr: the current row, from the database cursor,
3152- @param uid: the current user’s ID for security checks,
3153- @param ids: List of the wizard IDs (commonly the first element is the current ID)
3154- @param account: browse instance of account.account
3155- @param context: A standard dictionary for contextual values
3156-
3157- @return: 'ytd' or 'period'
3158- """
3159- return account.consolidation_mode or account.user_type.consolidation_mode
3160-
3161- def _periods_holding_to_subsidiary(self, cr, uid, ids, period_ids, subsidiary_id, context=None):
3162- """
3163- Returns the periods of a subsidiary company which correspond to the holding periods
3164- (same beginning and ending dates)
3165-
3166- @param self: The object pointer
3167- @param cr: the current row, from the database cursor,
3168- @param uid: the current user’s ID for security checks,
3169- @param ids: List of the wizard IDs (commonly the first element is the current ID)
3170- @param period_ids: list of periods of the holding
3171- @param subsidiary_id: ID of the subsidiary for which we want the period IDs
3172- @param context: A standard dictionary for contextual values
3173-
3174- @return: list of periods of the subsidiaries
3175+ :param account: browse instance of account.account
3176+
3177+ :return: 'ytd' or 'period'
3178+ """
3179+ return (account.consolidation_mode or
3180+ account.user_type.consolidation_mode)
3181+
3182+ def _periods_holding_to_subsidiary(self, cr, uid, ids, period_ids,
3183+ subsidiary_id, context=None):
3184+ """
3185+ Returns the periods of a subsidiary company which
3186+ correspond to the holding periods (same beginning and ending dates)
3187+
3188+ :param period_ids: list of periods of the holding
3189+ :param subsidiary_id: ID of the subsidiary for which
3190+ we want the period IDs
3191+
3192+ :return: list of periods of the subsidiaries
3193 """
3194 period_obj = self.pool.get('account.period')
3195 if isinstance(period_ids, (int, long)):
3196 period_ids = [period_ids]
3197+
3198 subs_period_ids = []
3199 for period in period_obj.browse(cr, uid, period_ids, context=context):
3200- subs_period_ids.extend(period_obj.search(cr, uid,
3201+ subs_period_ids += period_obj.search(
3202+ cr, uid,
3203 [('date_start', '=', period.date_start),
3204 ('date_stop', '=', period.date_stop),
3205- ('company_id', '=', subsidiary_id)])
3206- )
3207+ ('company_id', '=', subsidiary_id)],
3208+ context=context)
3209 return subs_period_ids
3210
3211- def create_rate_difference_line(self, cr, uid, ids, move_id, context):
3212- """
3213- Create a move line for the gain/loss currency difference
3214-
3215- @param self: The object pointer
3216- @param cr: the current row, from the database cursor,
3217- @param uid: the current user’s ID for security checks,
3218- @param ids: List of the wizard IDs (commonly the first element is the current ID)
3219- @param move_id: ID of the move
3220- @param context: A standard dictionary for contextual values
3221-
3222- @return:
3223- """
3224-
3225- pass
3226-
3227- def consolidate_account(self, cr, uid, ids, consolidation_mode, subsidiary_period_ids, state, move_id,
3228+ def create_rate_difference_line(self, cr, uid, ids, move_id, consolidation_mode, context):
3229+ """
3230+ We can have consolidation difference when a account is in YTD but in normal counterpart
3231+ has a different setting.
3232+ """
3233+ move_obj = self.pool['account.move']
3234+ move_line_obj = self.pool['account.move.line']
3235+ currency_obj = self.pool['res.currency']
3236+ move = move_obj.browse(cr, uid, move_id, context=context)
3237+
3238+ if not move.line_id:
3239+ return False
3240+ diff_account = move.company_id.consolidation_diff_account_id
3241+ if not diff_account:
3242+ raise except_osv(_('Settings ERROR'),
3243+ _('Please set the "Consolidation difference account"'
3244+ ' in company %s') % move.company_id.name)
3245+ debit = credit = 0.0
3246+ for line in move.line_id:
3247+ debit += line.debit
3248+ credit += line.credit
3249+ balance = debit - credit
3250+ # We do not want to create counter parts for amount smaller than
3251+ # "holding" company currency rounding policy.
3252+ # As generated lines are in draft state, accountant will be able to manage
3253+ # special cases
3254+ move_is_balanced = currency_obj.is_zero(cr, uid, move.company_id.currency_id, balance)
3255+ if not move_is_balanced:
3256+ diff_vals = {'account_id': diff_account.id,
3257+ 'move_id': move.id,
3258+ 'journal_id': move.journal_id.id,
3259+ 'period_id': move.period_id.id,
3260+ 'company_id': move.company_id.id,
3261+ 'date': move.date,
3262+ 'debit': abs(balance) if balance < 0.0 else 0.0,
3263+ 'credit': balance if balance > 0.0 else 0.0,
3264+ 'name': _('Consolidation difference in mode %s') % consolidation_mode
3265+ }
3266+ return move_line_obj.create(cr, uid, diff_vals, context=context)
3267+ return False
3268+
3269+ def consolidate_account(self, cr, uid, ids, consolidation_mode,
3270+ subsidiary_period_ids, state, move_id,
3271 holding_account_id, subsidiary_id, context=None):
3272 """
3273 Consolidates the subsidiary account on the holding account
3274 Creates move lines on the move with id "move_id"
3275
3276- @param self: The object pointer
3277- @param cr: the current row, from the database cursor,
3278- @param uid: the current user’s ID for security checks,
3279- @param ids: List of the wizard IDs (commonly the first element is the current ID)
3280- @param consolidation_mode: consolidate by Periods or Year To Date ('period' or 'ytd')
3281- @param subsidiary_period_ids: IDs of periods for which we want to sum the debit/credit
3282- @param state: state of the moves to consolidate ('all' or 'posted')
3283- @param move_id: ID of the move on which all the created move lines will be linked
3284- @param holding_account_id: ID of the account to consolidate (on the holding), the method will find the subsidiary's corresponding account
3285- @param subsidiary_id: ID of the subsidiary to consolidate
3286- @param context: A standard dictionary for contextual values
3287+ :param consolidation_mode: consolidate by Periods or
3288+ Year To Date ('period' or 'ytd')
3289+ :param subsidiary_period_ids: IDs of periods for which we
3290+ want to sum the debit/credit
3291+ :param state: state of the moves to consolidate ('all' or 'posted')
3292+ :param move_id: ID of the move on which all the
3293+ created move lines will be linked
3294+ :param holding_account_id: ID of the account to consolidate
3295+ (on the holding), the method will
3296+ find the subsidiary's corresponding account
3297+ :param subsidiary_id: ID of the subsidiary to consolidate
3298
3299- @return: list of IDs of the created move lines
3300+ :return: list of IDs of the created move lines
3301 """
3302+ if context is None:
3303+ context = {}
3304
3305 account_obj = self.pool.get('account.account')
3306 move_obj = self.pool.get('account.move')
3307@@ -197,7 +239,8 @@
3308 currency_obj = self.pool.get('res.currency')
3309
3310 move = move_obj.browse(cr, uid, move_id, context=context)
3311- holding_account = account_obj.browse(cr, uid, holding_account_id, context=context)
3312+ holding_account = account_obj.browse(cr, uid, holding_account_id,
3313+ context=context)
3314
3315 subsidiary_account_id = account_obj.search(cr, uid,
3316 [('code', '=', holding_account.code),
3317@@ -205,18 +248,17 @@
3318 context=context)
3319
3320 if not subsidiary_account_id:
3321- return [] # an account may exist on the holding and not in the subsidiaries, nothing to do
3322+ # an account may exist on the holding and not in the subsidiaries,
3323+ # nothing to do
3324+ return []
3325
3326- browse_ctx = context.copy()
3327- browse_ctx.update({
3328- 'state': state,
3329- 'periods': subsidiary_period_ids,
3330- })
3331- # subsidiary_account_id[0] because only one account per company for one code is permitted
3332- subs_account = account_obj.browse(cr, uid, subsidiary_account_id[0], context=browse_ctx)
3333+ browse_ctx = dict(context, state=state, periods=subsidiary_period_ids)
3334+ # 1st item because the account's code is unique per company
3335+ subs_account = account_obj.browse(cr, uid, subsidiary_account_id[0],
3336+ context=browse_ctx)
3337
3338 vals = {
3339- 'name': _("Consolidation line in %s mode") % (consolidation_mode,),
3340+ 'name': _("Consolidation line in %s mode") % consolidation_mode,
3341 'account_id': holding_account.id,
3342 'move_id': move.id,
3343 'journal_id': move.journal_id.id,
3344@@ -225,47 +267,47 @@
3345 'date': move.date
3346 }
3347
3348- if holding_account.company_currency_id.id != subs_account.company_currency_id.id:
3349- currency_rate_type = self._currency_rate_type(cr, uid, ids, holding_account, context=context)
3350+ balance = subs_account.balance
3351+ if not balance:
3352+ return False
3353+ if (holding_account.company_currency_id.id ==
3354+ subs_account.company_currency_id.id):
3355+ vals.update({
3356+ 'debit': balance if balance > 0.0 else 0.0,
3357+ 'credit': abs(balance) if balance < 0.0 else 0.0,
3358+ })
3359+ else:
3360+ currency_rate_type = self._currency_rate_type(cr, uid, ids,
3361+ holding_account, context=context)
3362
3363 currency_value = currency_obj.compute(cr, uid,
3364 holding_account.company_currency_id.id,
3365 subs_account.company_currency_id.id,
3366- subs_account.balance,
3367+ balance,
3368 currency_rate_type_from=False, # means spot
3369 currency_rate_type_to=currency_rate_type,
3370 context=context)
3371 vals.update({
3372 'currency_id': subs_account.company_currency_id.id,
3373 'amount_currency': subs_account.balance,
3374- 'debit': currency_value > 0 and currency_value or 0.0,
3375- 'credit': currency_value < 0 and -currency_value or 0.0
3376- })
3377-
3378- else:
3379- vals.update({
3380- 'debit': subs_account.debit,
3381- 'credit': subs_account.credit,
3382- })
3383-
3384- move_line_id = move_line_obj.create(cr, uid, vals, context=context)
3385-
3386- return move_line_id
3387-
3388- def reverse_moves(self, cr, uid, ids, subsidiary_id, journal_id, reversal_date, context):
3389+ 'debit': currency_value if currency_value > 0.0 else 0.0,
3390+ 'credit': abs(currency_value) if currency_value < 0.0 else 0.0,
3391+ })
3392+
3393+ return move_line_obj.create(cr, uid, vals, context=context)
3394+
3395+ def reverse_moves(self, cr, uid, ids, subsidiary_id, journal_id,
3396+ reversal_date, context=None):
3397 """
3398- Reverse all account moves of a journal which have the "To be reversed" flag
3399-
3400- @param self: The object pointer
3401- @param cr: the current row, from the database cursor,
3402- @param uid: the current user’s ID for security checks,
3403- @param ids: List of the wizard IDs (commonly the first element is the current ID)
3404- @param subsidiary_id: ID of the subsidiary moves to reverse
3405- @param journal_id: ID of the journal with moves to reverse
3406- @param reversal_date: date when to create the reversal
3407- @param context: A standard dictionary for contextual values
3408-
3409- @return: tuple with : list of IDs of the reversed moves, list of IDs of the reversal moves
3410+ Reverse all account moves of a journal which have
3411+ the "To be reversed" flag
3412+
3413+ :param subsidiary_id: ID of the subsidiary moves to reverse
3414+ :param journal_id: ID of the journal with moves to reverse
3415+ :param reversal_date: date when to create the reversal
3416+
3417+ :return: tuple with : list of IDs of the reversed moves,
3418+ list of IDs of the reversal moves
3419 """
3420 move_obj = self.pool.get('account.move')
3421 reversed_ids = move_obj.search(cr, uid,
3422@@ -273,41 +315,49 @@
3423 ('to_be_reversed', '=', True),
3424 ('consol_company_id', '=', subsidiary_id)],
3425 context=context)
3426- reversal_ids = move_obj.create_reversals(cr, uid, reversed_ids, reversal_date, context=context)
3427+ reversal_ids = move_obj.create_reversals(
3428+ cr, uid, reversed_ids, reversal_date, context=context)
3429 return reversed_ids, reversal_ids
3430
3431- def consolidate_subsidiary(self, cr, uid, ids, subsidiary_id, context=None):
3432+ def consolidate_subsidiary(self, cr, uid, ids,
3433+ subsidiary_id, context=None):
3434 """
3435 Consolidate one subsidiary on the Holding.
3436 Create a move per subsidiary and consolidation type (YTD/Period)
3437 and an move line per account of the subsidiary
3438- Plus a move line for the currency gain / loss # FIXME to check!
3439-
3440- @param self: The object pointer
3441- @param cr: the current row, from the database cursor,
3442- @param uid: the current user’s ID for security checks,
3443- @param ids: List of the wizard IDs (commonly the first element is the current ID)
3444- @param subsidiary_id: ID of the subsidiary to consolidate on the holding
3445- @param context: A standard dictionary for contextual values
3446-
3447- @return: Tuple of (list of IDs of the YTD moves, list of IDs of the Period Moves)
3448+
3449+ :param subsidiary_id: ID of the subsidiary to consolidate
3450+ on the holding
3451+
3452+ :return: Tuple of form:
3453+ (list of IDs of the YTD moves,
3454+ list of IDs of the Period Moves)
3455 """
3456-
3457- context = context or {}
3458+ if context is None:
3459+ context = {}
3460+
3461+ if isinstance(ids, (int, long)):
3462+ ids = [ids]
3463+ assert len(ids) == 1, "only 1 id expected"
3464+
3465 company_obj = self.pool.get('res.company')
3466 move_obj = self.pool.get('account.move')
3467 period_obj = self.pool.get('account.period')
3468+
3469 form = self.browse(cr, uid, ids[0], context=context)
3470 subsidiary = company_obj.browse(cr, uid, subsidiary_id, context=None)
3471
3472- data_ctx = context.copy()
3473- data_ctx.update({'holding_coa': True})
3474- holding_accounts_data = self._chart_accounts_data(cr, uid, ids,
3475- form.holding_chart_account_id.id,
3476- context=data_ctx)
3477- subs_accounts_codes = self._chart_accounts_data(cr, uid, ids,
3478- subsidiary.consolidation_chart_account_id.id,
3479- context=context)
3480+ data_ctx = dict(context, holding_coa=True)
3481+ holding_accounts_data = self._chart_accounts_data(
3482+ cr, uid,
3483+ ids,
3484+ form.holding_chart_account_id.id,
3485+ context=data_ctx)
3486+ subs_accounts_codes = self._chart_accounts_data(
3487+ cr, uid,
3488+ ids,
3489+ subsidiary.consolidation_chart_account_id.id,
3490+ context=context)
3491 holding_accounts = [values for key, values
3492 in holding_accounts_data.iteritems()
3493 if key in subs_accounts_codes]
3494@@ -316,12 +366,14 @@
3495 # a move per type will be created
3496 consolidation_modes = {'ytd': [], 'period': []}
3497 for account in holding_accounts:
3498- cm = self._consolidation_mode(cr, uid, ids, account, context=context)
3499+ cm = self._consolidation_mode(
3500+ cr, uid, ids, account, context=context)
3501 consolidation_modes[cm].append(account)
3502
3503- period_ids = period_obj.build_ctx_periods(cr, uid,
3504- form.from_period_id.id,
3505- form.to_period_id.id)
3506+ period_ids = period_obj.build_ctx_periods(
3507+ cr, uid,
3508+ form.from_period_id.id,
3509+ form.to_period_id.id)
3510
3511 generic_move_vals = {
3512 'journal_id': form.journal_id.id,
3513@@ -337,15 +389,18 @@
3514
3515 # get list of periods for which we have to create a move
3516 # in period mode : a move per period
3517- # in ytd mode : a move at the last period (which will contains lines from 1st january to last period)
3518- move_period_ids = consolidation_mode == 'period' \
3519- and period_ids \
3520- or [form.to_period_id.id]
3521+ # in ytd mode : a move at the last period
3522+ # (which will contains lines from 1st january to last period)
3523+ move_period_ids = (period_ids
3524+ if consolidation_mode == 'period'
3525+ else [form.to_period_id.id])
3526
3527 for move_period_id in move_period_ids:
3528- period = period_obj.browse(cr, uid, move_period_id, context=context)
3529+ period = period_obj.browse(
3530+ cr, uid, move_period_id, context=context)
3531
3532- # in ytd we compute the amount from the first day of the fiscal year
3533+ # in ytd we compute the amount from the first
3534+ # day of the fiscal year
3535 # in period, only for the period
3536 if consolidation_mode == 'ytd':
3537 date_from = period.fiscalyear_id.date_start
3538@@ -353,52 +408,61 @@
3539 date_from = period.date_start
3540 date_to = period.date_stop
3541
3542- period_ctx = context.copy()
3543- period_ctx.update({
3544- 'company_id': subsidiary.id,
3545- })
3546- compute_from_period_id = period_obj.find(cr, uid, date_from, context=period_ctx)[0]
3547- compute_to_period_id = period_obj.find(cr, uid, date_to, context=period_ctx)[0]
3548- compute_period_ids = period_obj.build_ctx_periods(cr, uid,
3549- compute_from_period_id,
3550- compute_to_period_id)
3551+ period_ctx = dict(context, company_id=subsidiary.id)
3552+ compute_from_period_id = period_obj.find(
3553+ cr, uid, date_from, context=period_ctx)[0]
3554+ compute_to_period_id = period_obj.find(
3555+ cr, uid, date_to, context=period_ctx)[0]
3556+ compute_period_ids = period_obj.build_ctx_periods(
3557+ cr, uid,
3558+ compute_from_period_id,
3559+ compute_to_period_id)
3560
3561 # reverse previous entries with flag 'to_be_reversed' (YTD)
3562- self.reverse_moves(cr, uid, ids, subsidiary.id, form.journal_id.id, date_to, context=context)
3563-
3564- # TODO if moves found for the same period : skip ?
3565+ self.reverse_moves(
3566+ cr, uid,
3567+ ids,
3568+ subsidiary.id,
3569+ form.journal_id.id,
3570+ date_to,
3571+ context=context)
3572
3573 # create the account move
3574 # at the very last date of the end period
3575- move_vals = generic_move_vals.copy()
3576- move_vals.update({
3577- 'ref': _("Consolidation %s") % (consolidation_mode,),
3578- 'period_id': period.id,
3579- 'date': period.date_stop,
3580- })
3581+ move_vals = dict(
3582+ generic_move_vals,
3583+ ref=_("Consolidation %s") % consolidation_mode,
3584+ period_id=period.id,
3585+ date=period.date_stop)
3586 move_id = move_obj.create(cr, uid, move_vals, context=context)
3587
3588- move_line_ids = []
3589 # create a move line per account
3590+ has_move_line = False
3591 for account in accounts:
3592- move_line_ids.append(
3593- self.consolidate_account(cr, uid, ids,
3594- consolidation_mode,
3595- compute_period_ids,
3596- form.target_move,
3597- move_id,
3598- account.id,
3599- subsidiary.id,
3600- context=context)
3601- )
3602-
3603- # TODO calculate currency rate difference (all move lines debit - all move lines credit) and post a move line
3604- # on the gain / loss account
3605- # will works IF : counterparts are always configured with the same mode (YTD/Periods)
3606- self.create_rate_difference_line(cr, uid, ids,
3607- move_id, context=context)
3608-
3609- locals()[consolidation_mode + '_move_ids'].append(move_id)
3610+ m_id = self.consolidate_account(
3611+ cr, uid, ids,
3612+ consolidation_mode,
3613+ compute_period_ids,
3614+ form.target_move,
3615+ move_id,
3616+ account.id,
3617+ subsidiary.id,
3618+ context=context)
3619+ if m_id:
3620+ has_move_line = True
3621+
3622+ if has_move_line:
3623+ self.create_rate_difference_line(cr, uid, ids,
3624+ move_id, consolidation_mode, context=context)
3625+ locals()[consolidation_mode + '_move_ids'].append(move_id)
3626+
3627+ else:
3628+ # We delete created move if it has no line.
3629+ # As move are generated in draft mode they will be no gap in
3630+ # number if consolidation journal has correct settings.
3631+ # I agree it can be more efficient but size of refactoring
3632+ # is not in ressource scope
3633+ move_obj.unlink(cr, uid, [move_id])
3634
3635 return ytd_move_ids, period_move_ids
3636
3637@@ -407,15 +471,10 @@
3638 Consolidate all selected subsidiaries Virtual Chart of Accounts
3639 on the Holding Chart of Account
3640
3641- @param self: The object pointer
3642- @param cr: the current row, from the database cursor,
3643- @param uid: the current user’s ID for security checks,
3644- @param ids: List of the wizard IDs (commonly the first element is the current ID)
3645- @param context: A standard dictionary for contextual values
3646-
3647- @return: dict to open an Entries view filtered on the created moves
3648+ :return: dict to open an Entries view filtered on the created moves
3649 """
3650- super(account_consolidation_consolidate, self).run_consolidation(cr, uid, ids, context=context)
3651+ super(account_consolidation_consolidate, self).run_consolidation(
3652+ cr, uid, ids, context=context)
3653
3654 mod_obj = self.pool.get('ir.model.data')
3655 act_obj = self.pool.get('ir.actions.act_window')
3656@@ -425,20 +484,23 @@
3657 move_ids = []
3658 ytd_move_ids = []
3659 for subsidiary in form.subsidiary_ids:
3660- new_move_ids = self.consolidate_subsidiary(cr, uid, ids, subsidiary.id, context=context)
3661- ytd_move_ids.extend(new_move_ids[0])
3662- move_ids.extend(sum(new_move_ids, []))
3663+ new_move_ids = self.consolidate_subsidiary(
3664+ cr, uid, ids, subsidiary.id, context=context)
3665+ ytd_move_ids += new_move_ids[0]
3666+ move_ids += sum(new_move_ids, [])
3667
3668 # YTD moves have to be reversed on the next consolidation
3669- move_obj.write(cr, uid, ytd_move_ids, {'to_be_reversed': True}, context=context)
3670+ move_obj.write(
3671+ cr, uid,
3672+ ytd_move_ids,
3673+ {'to_be_reversed': True},
3674+ context=context)
3675
3676 context.update({'move_ids': move_ids})
3677- action_ref = mod_obj.get_object_reference(cr, uid, 'account', 'action_move_journal_line')
3678- action_id = action_ref and action_ref[1] or False
3679+ __, action_id = mod_obj.get_object_reference(
3680+ cr, uid, 'account', 'action_move_journal_line')
3681 action = act_obj.read(cr, uid, [action_id], context=context)[0]
3682 action['domain'] = unicode([('id', 'in', move_ids)])
3683 action['name'] = _('Consolidated Entries')
3684 action['context'] = unicode({'search_default_to_be_reversed': 0})
3685 return action
3686-
3687-account_consolidation_consolidate()
3688
3689=== modified file 'account_consolidation/wizard/consolidation_consolidate_view.xml'
3690--- account_consolidation/wizard/consolidation_consolidate_view.xml 2011-08-29 05:45:40 +0000
3691+++ account_consolidation/wizard/consolidation_consolidate_view.xml 2014-06-26 13:58:55 +0000
3692@@ -2,39 +2,49 @@
3693 <openerp>
3694 <data>
3695
3696- <record id="view_consolidation_consolidate_form" model="ir.ui.view">
3697+ <record id="view_consolidation_consolidate_form" model="ir.ui.view">
3698 <field name="name">account.consolidation.consolidate.form</field>
3699 <field name="model">account.consolidation.consolidate</field>
3700 <field name="type">form</field>
3701 <field name="arch" type="xml">
3702- <form string="Consolidation: Consolidate">
3703- <group col="4" colspan="6">
3704- <field name="company_id" on_change="on_change_company_id(company_id)" invisible="True"/>
3705- <field name="fiscalyear_id" invisible="True"/>
3706- <field name="from_period_id" on_change="on_change_from_period_id(from_period_id, to_period_id)" domain="[('company_id', '=', company_id)]"/>
3707- <field name="to_period_id" domain="[('company_id', '=', company_id)]"/>
3708- <field name="journal_id" domain="[('company_id', '=', company_id)]"/>
3709- <field name="target_move"/>
3710- <separator string="Holding Chart of Accounts" colspan="4"/>
3711- <field name="holding_chart_account_id" domain="[('company_id', '=', company_id), ('parent_id', '=', False)]"/>
3712+ <form string="Consolidation: Consolidate" version="7.0">
3713+ <label string="Run the consolidation for the selected periods and subsidiaries."/>
3714+ <group>
3715+ <field name="company_id"
3716+ on_change="on_change_company_id(company_id)"
3717+ invisible="True"/>
3718+ <field name="fiscalyear_id" invisible="True"/>
3719+ <field name="from_period_id"
3720+ on_change="on_change_from_period_id(from_period_id, to_period_id)"
3721+ domain="[('company_id', '=', company_id)]"/>
3722+ <field name="to_period_id"
3723+ domain="[('company_id', '=', company_id)]"/>
3724+ <field name="journal_id"
3725+ domain="[('company_id', '=', company_id)]"/>
3726+ <field name="target_move"/>
3727+ <separator string="Holding Chart of Accounts" colspan="4"/>
3728+ <field name="holding_chart_account_id"
3729+ domain="[('company_id', '=', company_id), ('parent_id', '=', False)]"/>
3730
3731- <!--<separator string="Consolidation Difference Accounts" colspan="4"/>-->
3732- <!--<field name="gain_account_id" domain="[('type','&lt;&gt;','view'), ('id', 'child_of', [holding_chart_account_id])]"/>-->
3733- <!--<field name="loss_account_id" domain="[('type','&lt;&gt;','view'), ('id', 'child_of', [holding_chart_account_id])]"/>-->
3734- <separator string="Subsidiaries to Consolidate" colspan="4"/>
3735- <field name="subsidiary_ids" colspan="4" nolabel="1" required="True">
3736- <tree>
3737- <field name="name"/>
3738- <field name="consolidation_chart_account_id"/>
3739- </tree>
3740- </field>
3741- </group>
3742- <separator colspan="4"/>
3743- <group col="2" colspan="4">
3744- <button special="cancel" string="Cancel" icon='gtk-cancel'/>
3745- <button name="run_consolidation" string="Consolidate" colspan="1" type="object" icon="gtk-execute"/>
3746- </group>
3747- </form>
3748+ <separator string="Subsidiaries to Consolidate" colspan="4"/>
3749+ <field name="subsidiary_ids" colspan="4"
3750+ nolabel="1" required="True">
3751+ <tree>
3752+ <field name="name"/>
3753+ <field name="consolidation_chart_account_id"/>
3754+ </tree>
3755+ </field>
3756+ </group>
3757+ <separator colspan="4"/>
3758+ <footer>
3759+ <button name="run_consolidation"
3760+ string="Consolidate"
3761+ type="object"
3762+ class="oe_highlight"/>
3763+ or
3764+ <button string="Cancel" class="oe_link" special="cancel"/>
3765+ </footer>
3766+ </form>
3767 </field>
3768 </record>
3769
3770@@ -44,9 +54,8 @@
3771 <field name="res_model">account.consolidation.consolidate</field>
3772 <field name="view_type">form</field>
3773 <field name="view_mode">form</field>
3774- <field name="help">Run the consolidation for the selected periods and subsidiaries.</field>
3775 <field name="target">new</field>
3776 </record>
3777
3778- </data>
3779+ </data>
3780 </openerp>
3781
3782=== added directory 'account_parallel_currency'
3783=== added file 'account_parallel_currency/AUTHORS.txt'
3784--- account_parallel_currency/AUTHORS.txt 1970-01-01 00:00:00 +0000
3785+++ account_parallel_currency/AUTHORS.txt 2014-06-26 13:58:55 +0000
3786@@ -0,0 +1,1 @@
3787+Lorenzo Battistini <lorenzo.battistini@agilebg.com>
3788
3789=== added file 'account_parallel_currency/__init__.py'
3790--- account_parallel_currency/__init__.py 1970-01-01 00:00:00 +0000
3791+++ account_parallel_currency/__init__.py 2014-06-26 13:58:55 +0000
3792@@ -0,0 +1,23 @@
3793+# -*- coding: utf-8 -*-
3794+##############################################################################
3795+#
3796+# Copyright (C) 2012 Agile Business Group sagl (<http://www.agilebg.com>)
3797+# Copyright (C) 2012 Domsense srl (<http://www.domsense.com>)
3798+#
3799+# This program is free software: you can redistribute it and/or modify
3800+# it under the terms of the GNU Affero General Public License as published
3801+# by the Free Software Foundation, either version 3 of the License, or
3802+# (at your option) any later version.
3803+#
3804+# This program is distributed in the hope that it will be useful,
3805+# but WITHOUT ANY WARRANTY; without even the implied warranty of
3806+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3807+# GNU General Public License for more details.
3808+#
3809+# You should have received a copy of the GNU Affero General Public License
3810+# along with this program. If not, see <http://www.gnu.org/licenses/>.
3811+#
3812+##############################################################################
3813+import account
3814+import res_company
3815+import wizard
3816
3817=== added file 'account_parallel_currency/__openerp__.py'
3818--- account_parallel_currency/__openerp__.py 1970-01-01 00:00:00 +0000
3819+++ account_parallel_currency/__openerp__.py 2014-06-26 13:58:55 +0000
3820@@ -0,0 +1,56 @@
3821+# -*- coding: utf-8 -*-
3822+##############################################################################
3823+#
3824+# Copyright (C) 2012-2013 Agile Business Group sagl
3825+# (<http://www.agilebg.com>)
3826+# Copyright (C) 2012 Domsense srl (<http://www.domsense.com>)
3827+#
3828+# This program is free software: you can redistribute it and/or modify
3829+# it under the terms of the GNU Affero General Public License as published
3830+# by the Free Software Foundation, either version 3 of the License, or
3831+# (at your option) any later version.
3832+#
3833+# This program is distributed in the hope that it will be useful,
3834+# but WITHOUT ANY WARRANTY; without even the implied warranty of
3835+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3836+# GNU Affero General Public License for more details.
3837+#
3838+# You should have received a copy of the GNU Affero General Public License
3839+# along with this program. If not, see <http://www.gnu.org/licenses/>.
3840+#
3841+##############################################################################
3842+{
3843+ 'name': "Account Parallel Currency",
3844+ 'version': '0.2',
3845+ 'category': 'Generic Modules/Accounting',
3846+ 'description': """
3847+This module handles parallel accounting entries based on different currencies.
3848+It is useful for companies who have to manage accounting with more than one currency at the same time. For instance, companies who have to produce balances on different currencies.
3849+
3850+In order to use the module, you have to define one company for each parallel chart of accounts. Then you have to map parallel accounts and parallel journals through the related forms.
3851+
3852+A 'Parallel Account Mapping' wizard is provided. It is intended to be run when the same chart of account is used for the parallel companies. It allows to automatically map the 'master' account to 'parallel' accounts, based on account code.
3853+
3854+When posting new journal entries, the system checks the configured parallel accounts and automatically generates the parallel entries.
3855+This is achieved keeping the companies separate, so that users of the master company don't see secondary company data (e.g. currencies and journals) but the system uses the super user in order to perform the parallel registrations.
3856+""",
3857+ 'author': 'Agile Business Group',
3858+ 'website': 'http://www.agilebg.com',
3859+ 'license': 'AGPL-3',
3860+ "depends" : ['account'],
3861+ "data" : [
3862+ 'account_view.xml',
3863+ 'company_view.xml',
3864+ 'wizard/do_mapping.xml',
3865+ 'security/security.xml',
3866+ ],
3867+ "demo" : [
3868+ 'account_demo.xml',
3869+ ],
3870+ 'test': [
3871+ 'test/mapping_parallel_accounts.yml',
3872+ 'test/customer_invoice.yml',
3873+ ],
3874+ "active": False,
3875+ "installable": True
3876+}
3877
3878=== added file 'account_parallel_currency/account.py'
3879--- account_parallel_currency/account.py 1970-01-01 00:00:00 +0000
3880+++ account_parallel_currency/account.py 2014-06-26 13:58:55 +0000
3881@@ -0,0 +1,506 @@
3882+# -*- coding: utf-8 -*-
3883+##############################################################################
3884+#
3885+# Copyright (C) 2012-2013 Agile Business Group sagl
3886+# (<http://www.agilebg.com>)
3887+# Copyright (C) 2012 Domsense srl (<http://www.domsense.com>)
3888+#
3889+# This program is free software: you can redistribute it and/or modify
3890+# it under the terms of the GNU Affero General Public License as published
3891+# by the Free Software Foundation, either version 3 of the License, or
3892+# (at your option) any later version.
3893+#
3894+# This program is distributed in the hope that it will be useful,
3895+# but WITHOUT ANY WARRANTY; without even the implied warranty of
3896+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3897+# GNU Affero General Public License for more details.
3898+#
3899+# You should have received a copy of the GNU Affero General Public License
3900+# along with this program. If not, see <http://www.gnu.org/licenses/>.
3901+#
3902+##############################################################################
3903+
3904+from openerp.osv import fields, orm
3905+from tools.translate import _
3906+import logging
3907+from openerp import SUPERUSER_ID
3908+
3909+_logger = logging.getLogger(__name__)
3910+
3911+
3912+class account_account(orm.Model):
3913+ _inherit = "account.account"
3914+
3915+ def _get_parallel_accounts_summary(self, cr, uid, ids, field_name, arg, context=None):
3916+ res = {}
3917+ for account in self.browse(cr, SUPERUSER_ID, ids, context):
3918+ text = 'Configured parallel accounts:\n'
3919+ text2 = ''
3920+ for parallel_account in account.parallel_account_ids:
3921+ text2 += _('Account code: %s. Company: %s\n') % (
3922+ parallel_account.code, parallel_account.company_id.name)
3923+ if text2:
3924+ res[account.id] = text + text2
3925+ else:
3926+ res[account.id] = _("No parallel accounts found")
3927+ return res
3928+
3929+ _columns = {
3930+ 'parallel_account_ids': fields.many2many('account.account',
3931+ 'parallel_account_rel', 'parent_id',
3932+ 'child_id', 'Parallel Currency Accounts',
3933+ Help="""Set here the accounts you want to automatically move when
3934+ registering entries in this account"""),
3935+ 'master_parallel_account_ids': fields.many2many('account.account',
3936+ 'parallel_account_rel', 'child_id',
3937+ 'parent_id', 'Master Parallel Currency Accounts',
3938+ Help="You can see here the accounts that automatically move this account",
3939+ readonly=True),
3940+ 'parallel_accounts_summary': fields.function(
3941+ _get_parallel_accounts_summary, type='text',
3942+ string='Parallel accounts summary'),
3943+ }
3944+
3945+ def _search_parallel_account(self, cr, uid, account_code, parallel_company,
3946+ context=None):
3947+ parallel_acc_ids = self.search(cr, uid, [
3948+ ('company_id', '=', parallel_company.id),
3949+ ('code', '=', account_code),
3950+ ], context=context)
3951+ if len(parallel_acc_ids) > 1:
3952+ raise orm.except_orm(_('Error'), _('Too many accounts %s for company %s')
3953+ % (account_code, parallel_company.name))
3954+ return parallel_acc_ids and parallel_acc_ids[0] or False
3955+
3956+ def _build_account_vals(self, cr, uid, account_vals, parallel_company, context=None):
3957+ # build only fields I need
3958+ vals = {}
3959+ if 'name' in account_vals:
3960+ vals['name'] = account_vals['name']
3961+ if 'code' in account_vals:
3962+ vals['code'] = account_vals['code']
3963+ if 'type' in account_vals:
3964+ vals['type'] = account_vals['type']
3965+ if 'user_type' in account_vals:
3966+ vals['user_type'] = account_vals['user_type']
3967+ if 'active' in account_vals:
3968+ vals['active'] = account_vals['active']
3969+ if 'parent_id' in account_vals:
3970+ parent_account = self.browse(cr, uid, account_vals['parent_id'], context)
3971+ parent_parallel_acc_id = self._search_parallel_account(
3972+ cr, uid, parent_account.code, parallel_company, context=context)
3973+ if not parent_parallel_acc_id:
3974+ raise orm.except_orm(_('Error'),
3975+ _('No parent account %s found in company %s') %
3976+ (parent_account.code, parallel_company.name))
3977+ vals['parent_id'] = parent_parallel_acc_id
3978+ return vals
3979+
3980+ def _prepare_parallel_account(self, cr, uid, parallel_company, account, context):
3981+ parent_parallel_acc_id = self._search_parallel_account(
3982+ cr, SUPERUSER_ID, account.parent_id.code, parallel_company,
3983+ context=context)
3984+ return {'company_id': parallel_company.id,
3985+ 'parent_id': parent_parallel_acc_id,
3986+ 'name': account.name,
3987+ 'code': account.code,
3988+ 'type': account.type,
3989+ 'user_type': account.user_type and account.user_type.id or False,
3990+ 'active': account.active,
3991+ }
3992+
3993+ def create_parallel_accounts(self, cr, uid, ids, context=None):
3994+ for account in self.browse(cr, SUPERUSER_ID, ids, context):
3995+ for parallel_company in account.company_id.parallel_company_ids:
3996+ account_val = self._prepare_parallel_account(cr, uid,
3997+ parallel_company,
3998+ account,
3999+ context)
4000+ new_id = self.create(cr, SUPERUSER_ID, account_val, context=context)
4001+ cr.execute("INSERT INTO parallel_account_rel(parent_id, child_id) VALUES (%d, %d)",
4002+ (account.id, new_id))
4003+ return True
4004+
4005+ '''
4006+ def sync_parallel_accounts(self, cr, uid, ids, vals={}, context=None):
4007+ for account in self.browse(cr, uid, ids, context):
4008+ new_parallel_acc_ids = []
4009+ company_id = vals.get('company_id') or account.company_id.id
4010+ code = vals.get('code') or account.code
4011+ company = self.pool.get('res.company').browse(cr, uid, company_id, context)
4012+ for parallel_company in company.parallel_company_ids:
4013+ parallel_acc_id = self._search_parallel_account(
4014+ cr, uid, code, parallel_company, context=context)
4015+ if not parallel_acc_id:
4016+ # Then I create it, linked to parent account
4017+ #parallel_acc_id = self.create(cr, uid,
4018+ #self._build_account_vals(cr, uid,
4019+ #vals, parallel_company, context=context), context=context)
4020+ pass
4021+ else:
4022+ super(account_account,self).write(cr, uid, [parallel_acc_id],
4023+ self._build_account_vals(cr, uid,
4024+ vals, parallel_company, context=context), context)
4025+ _logger.info(
4026+ _("Parallel account %s (company %s) written") %
4027+ (code, parallel_company.name))
4028+ new_parallel_acc_ids.append(parallel_acc_id)
4029+ return new_parallel_acc_ids
4030+ '''
4031+
4032+ def write(self, cr, uid, ids, vals, context=None):
4033+ if 'parallel_account_ids' not in vals:
4034+ # write/create parallel accounts only if 'parallel_account_ids' not explicity written
4035+ for acc_id in ids:
4036+ account = self.browse(cr, SUPERUSER_ID, acc_id, context)
4037+ for parallel_account in account.parallel_account_ids:
4038+ parallel_vals = self._build_account_vals(
4039+ cr, SUPERUSER_ID, vals, parallel_account.company_id,
4040+ context=context)
4041+ parallel_account.write(parallel_vals)
4042+ res=super(account_account,self).write(cr, uid, ids, vals, context=context)
4043+ return res
4044+
4045+ def create(self, cr, uid, vals, context=None):
4046+ res=super(account_account,self).create(cr, uid, vals, context)
4047+ self.create_parallel_accounts(cr, uid, [res], context=None)
4048+ return res
4049+
4050+ def unlink(self, cr, uid, ids, context=None):
4051+ for account in self.browse(cr, SUPERUSER_ID, ids, context):
4052+ for parallel_account in account.parallel_account_ids:
4053+ parallel_account.unlink()
4054+ res=super(account_account,self).unlink(cr, uid, ids, context=context)
4055+ return res
4056+
4057+class account_move(orm.Model):
4058+ _inherit = "account.move"
4059+
4060+ _columns = {
4061+ 'parallel_move_ids': fields.one2many('account.move', 'master_parallel_move_id', 'Parallel Entries',
4062+ readonly=True),
4063+ 'master_parallel_move_id': fields.many2one('account.move', 'Master Parallel Entry'),
4064+ }
4065+
4066+ def button_cancel(self, cr, uid, ids, context=None):
4067+ res = super(account_move, self).button_cancel(cr, uid, ids, context=context)
4068+ for move in self.browse(cr, SUPERUSER_ID, ids, context=context):
4069+ for parallel_move in move.parallel_move_ids:
4070+ parallel_move.button_cancel(context=context)
4071+ parallel_move.unlink(context=context)
4072+ return res
4073+
4074+ def lines_balance(self, move_lines):
4075+ """
4076+ returns 0 if lines are balanced, difference if unbalanced
4077+ """
4078+ balance = 0.0
4079+ for line_tuple in move_lines:
4080+ balance += line_tuple[2]['debit'] or (- line_tuple[2]['credit']) or 0.0
4081+ return balance
4082+
4083+ def balance_lines(self, cr, uid, move_lines, currency_id, context=None):
4084+ """
4085+ Balance move lines that were unbalanced due to roundings.
4086+ """
4087+ balance = self.lines_balance(move_lines)
4088+ acc_pool = self.pool.get('account.account')
4089+ curr_pool = self.pool.get('res.currency')
4090+ if curr_pool.is_zero(cr, uid, curr_pool.browse(cr, uid, currency_id), balance):
4091+ return move_lines
4092+ else:
4093+ found = False
4094+ for line_tuple in move_lines:
4095+ account = acc_pool.browse(cr, uid, line_tuple[2]['account_id'], context)
4096+ # search for liquidity, receivable or payable accounts
4097+ # beacause usually they are the result of operations (invoice total).
4098+ # So, if we made the invoice in parallel currency, we'd get that different invoice total
4099+ if account.type == 'liquidity' or account.type == 'receivable' or account.type == 'payable':
4100+ if line_tuple[2]['debit']:
4101+ line_tuple[2]['debit'] -= balance
4102+ found = True
4103+ break
4104+ elif line_tuple[2]['credit']:
4105+ line_tuple[2]['credit'] += balance
4106+ found = True
4107+ break
4108+ if not found:
4109+ # if no liquidity, receivable or payable accounts are present, we use the first line (randomly).
4110+ # TODO check if this makes sense
4111+ if move_lines[0][2]['debit']:
4112+ move_lines[0][2]['debit'] -= balance
4113+ elif move_lines[0][2]['credit']:
4114+ move_lines[0][2]['credit'] += balance
4115+ return move_lines
4116+
4117+ def post(self, cr, uid, ids, context=None):
4118+ res = super(account_move, self).post(cr, uid, ids, context=context)
4119+ if context is None:
4120+ context = {}
4121+ curr_pool = self.pool.get('res.currency')
4122+ company_pool = self.pool.get('res.company')
4123+ uid = SUPERUSER_ID
4124+ for move in self.browse(cr, uid, ids, context=context):
4125+ if move.state == 'posted' and not move.parallel_move_ids:
4126+ # avoid double post in case of 'Skip Draft State for Manual Entries'
4127+ new_move_lines = []
4128+ parallel_data = {}
4129+ for line in move.line_id:
4130+ for parallel_account in line.account_id.parallel_account_ids:
4131+ parallel_data[parallel_account.company_id.id] = {}
4132+ parallel_data[parallel_account.company_id.id]['move_name'] = line.move_id.name
4133+ parallel_data[parallel_account.company_id.id]['ref'] = line.move_id.ref
4134+ parallel_data[parallel_account.company_id.id]['date'] = line.date
4135+ parallel_data[parallel_account.company_id.id]['move_id'] = line.move_id.id
4136+
4137+ # search period by code and parallel company
4138+ period_ids = self.pool.get('account.period').search(cr, uid, [
4139+ ('code','=',line.period_id.code),
4140+ ('company_id', '=', parallel_account.company_id.id),
4141+ ])
4142+
4143+ if len(period_ids) == 0:
4144+ raise orm.except_orm(_('Error !'), _('Period %s does not exist in company %s !')
4145+ % (line.period_id.code, parallel_account.company_id.name))
4146+ if len(period_ids) > 1:
4147+ raise orm.except_orm(_('Error !'), _('Too many periods %s for company %s !')
4148+ % (line.period_id.code, parallel_account.company_id.name))
4149+
4150+ parallel_data[parallel_account.company_id.id]['period_id'] = period_ids[0]
4151+
4152+ # search parallel journals for the parallel company
4153+ parallel_journal_ids = []
4154+ for journal in line.journal_id.parallel_journal_ids:
4155+ if journal.company_id.id == parallel_account.company_id.id:
4156+ parallel_journal_ids.append(journal.id)
4157+
4158+ if len(parallel_journal_ids) == 0:
4159+ raise orm.except_orm(_('Error !'), _('Journal %s does not exist in company %s !')
4160+ % (line.journal_id.name, parallel_account.company_id.name))
4161+ if len(parallel_journal_ids) > 1:
4162+ raise orm.except_orm(_('Error !'), _('Too many journals %s for company %s !')
4163+ % (line.journal_id.name, parallel_account.company_id.name))
4164+
4165+ parallel_data[parallel_account.company_id.id]['journal_id'] = parallel_journal_ids[0]
4166+
4167+ new_line_values = {
4168+ 'name': line.name,
4169+ 'date_maturity': line.date_maturity or False,
4170+ 'account_id': parallel_account.id,
4171+ 'period_id': period_ids[0],
4172+ 'journal_id': parallel_journal_ids[0],
4173+ 'company_id': parallel_account.company_id.id,
4174+ 'partner_id': line.partner_id and line.partner_id.id or False,
4175+ }
4176+
4177+ if line.currency_id and line.amount_currency:
4178+ parallel_sec_curr_iso_code = line.currency_id.name
4179+ amount = line.amount_currency
4180+ else:
4181+ parallel_sec_curr_iso_code = line.company_id.currency_id.name
4182+ amount = line.debit or ( - line.credit)
4183+
4184+ parallel_base_amount = amount
4185+ if parallel_sec_curr_iso_code != parallel_account.company_id.currency_id.name:
4186+ # only if parallel company currency is != master move currency
4187+ # search parallel currency by ISO code and parallel company
4188+ parallel_secondary_curr_ids = curr_pool.search(cr, uid, [
4189+ ('name', '=', parallel_sec_curr_iso_code),
4190+ ('company_id', '=', parallel_account.company_id.id),
4191+ ], context=context)
4192+
4193+ if len(parallel_secondary_curr_ids) == 0:
4194+ raise orm.except_orm(_('Error !'), _('Currency %s does not exist in company %s !')
4195+ % (parallel_sec_curr_iso_code, parallel_account.company_id.name))
4196+ if len(parallel_secondary_curr_ids) > 1:
4197+ raise orm.except_orm(_('Error !'), _('Too many currencies %s for company %s !')
4198+ % (parallel_sec_curr_iso_code, parallel_account.company_id.name))
4199+
4200+ # compute parallel base amount from document currency, using move date
4201+ context.update({'date': line.date})
4202+ parallel_base_amount = curr_pool.compute(cr, uid, parallel_secondary_curr_ids[0],
4203+ parallel_account.company_id.currency_id.id, amount,
4204+ context=context)
4205+
4206+ new_line_values['amount_currency'] = amount
4207+ new_line_values['currency_id'] = parallel_secondary_curr_ids[0]
4208+
4209+ new_line_values['debit'] = 0.0
4210+ new_line_values['credit'] = 0.0
4211+ if parallel_base_amount > 0:
4212+ new_line_values['debit'] = abs(parallel_base_amount)
4213+ elif parallel_base_amount < 0:
4214+ new_line_values['credit'] = abs(parallel_base_amount)
4215+
4216+ if line.tax_code_id and line.tax_amount:
4217+ # search parallel tax codes for the parallel company
4218+ parallel_tax_code_ids = []
4219+ for tax_code in line.tax_code_id.parallel_tax_code_ids:
4220+ if tax_code.company_id.id == parallel_account.company_id.id:
4221+ parallel_tax_code_ids.append(tax_code.id)
4222+
4223+ if len(parallel_tax_code_ids) == 0:
4224+ raise orm.except_orm(_('Error !'), _('Tax code %s does not exist in company %s !')
4225+ % (line.tax_code_id.name, parallel_account.company_id.name))
4226+ if len(parallel_tax_code_ids) > 1:
4227+ raise orm.except_orm(_('Error !'), _('Too many tax_codes %s for company %s !')
4228+ % (line.tax_code_id.name, parallel_account.company_id.name))
4229+
4230+ new_line_values['tax_code_id'] = parallel_tax_code_ids[0]
4231+ total_tax = new_line_values['debit'] - new_line_values['credit']
4232+ new_line_values['tax_amount'] = line.tax_amount < 0 \
4233+ and - abs(total_tax) \
4234+ or line.tax_amount > 0 \
4235+ and abs(total_tax) \
4236+ or 0.0
4237+
4238+ new_move_lines.append((parallel_account.company_id.id, (0,0,new_line_values)))
4239+ #parallel_data[parallel_account.company_id.id]['move_lines'].append((0,0,new_line_values))
4240+
4241+ for company_id in parallel_data:
4242+ move_lines = []
4243+ for new_move_line in new_move_lines:
4244+ if new_move_line[0] == company_id:
4245+ move_lines.append(new_move_line[1])
4246+ move_lines=self.balance_lines(cr, uid, move_lines, company_pool.browse(cr, uid, company_id).currency_id.id, context=context)
4247+ move_values = {
4248+ 'name': parallel_data[company_id]['move_name'],
4249+ 'period_id': parallel_data[company_id]['period_id'],
4250+ 'journal_id': parallel_data[company_id]['journal_id'],
4251+ 'date': parallel_data[company_id]['date'],
4252+ 'company_id': company_id,
4253+ 'line_id': move_lines,
4254+ 'master_parallel_move_id': parallel_data[company_id]['move_id'],
4255+ 'ref': parallel_data[company_id]['ref'],
4256+ }
4257+ self.create(cr, uid, move_values, context=context)
4258+ # self.post(cr, uid, [move_id], context=context)
4259+
4260+ return res
4261+
4262+
4263+class account_journal(orm.Model):
4264+ _inherit = "account.journal"
4265+
4266+ _columns = {
4267+ 'parallel_journal_ids': fields.many2many('account.journal',
4268+ 'parallel_journal_rel', 'parent_id',
4269+ 'child_id', 'Parallel Currency Journals',
4270+ Help="Set here the journals you want to automatically move when registering entries in this journal"),
4271+ 'master_parallel_journal_ids': fields.many2many('account.journal',
4272+ 'parallel_journal_rel', 'child_id',
4273+ 'parent_id', 'Master Parallel Currency Journals',
4274+ Help="You can see here the journals that automatically move this journal", readonly=True),
4275+ }
4276+
4277+class account_tax_code(orm.Model):
4278+ _inherit = "account.tax.code"
4279+
4280+ def _get_parallel_tax_codes_summary(self, cr, uid, ids, field_name, arg, context=None):
4281+ res={}
4282+ for tax_code in self.browse(cr, SUPERUSER_ID, ids, context):
4283+ text='Configured parallel tax codes:\n'
4284+ text2=''
4285+ for parallel_tax_code in tax_code.parallel_tax_code_ids:
4286+ text2+= _('Tax code: %s. Company: %s\n') % (
4287+ parallel_tax_code.code, parallel_tax_code.company_id.name)
4288+ if text2:
4289+ res[tax_code.id] = text + text2
4290+ else:
4291+ res[tax_code.id] = _("No parallel tax codes found")
4292+ return res
4293+
4294+ _columns = {
4295+ 'parallel_tax_code_ids': fields.many2many('account.tax.code',
4296+ 'parallel_tax_code_rel', 'parent_id',
4297+ 'child_id', 'Parallel Currency Tax Codes',
4298+ Help="Set here the tax codes you want to automatically move when registering entries in this tax code"),
4299+ 'master_parallel_tax_code_ids': fields.many2many('account.tax.code',
4300+ 'parallel_tax_code_rel', 'child_id',
4301+ 'parent_id', 'Master Parallel Currency Tax Codes',
4302+ Help="You can see here the tax codes that automatically move this journal", readonly=True),
4303+ 'parallel_tax_codes_summary': fields.function(_get_parallel_tax_codes_summary, type='text', string='Parallel tax codes summary'),
4304+ }
4305+
4306+ def _search_parallel_tax_code(self, cr, uid, tax_code, parallel_company,
4307+ context=None):
4308+ parallel_tax_code_ids = self.search(cr, uid, [
4309+ ('company_id','=', parallel_company.id),
4310+ ('code','=', tax_code),
4311+ ], context=context)
4312+ if len(parallel_tax_code_ids) > 1:
4313+ raise orm.except_orm(_('Error'), _('Too many tax codes %s for company %s')
4314+ % (tax_code,parallel_company.name))
4315+ return parallel_tax_code_ids and parallel_tax_code_ids[0] or False
4316+
4317+ def _build_tax_code_vals(self, cr, uid, tax_code_vals, parallel_company, context=None):
4318+ # build only fields I need
4319+ vals={}
4320+ if tax_code_vals.has_key('name'):
4321+ vals['name'] = tax_code_vals['name']
4322+ if tax_code_vals.has_key('code'):
4323+ vals['code'] = tax_code_vals['code']
4324+ if tax_code_vals.has_key('type'):
4325+ vals['type'] = tax_code_vals['type']
4326+ if tax_code_vals.has_key('user_type'):
4327+ vals['user_type'] = tax_code_vals['user_type']
4328+ if tax_code_vals.has_key('active'):
4329+ vals['active'] = tax_code_vals['active']
4330+ if tax_code_vals.has_key('parent_id'):
4331+ parent_tax_code = self.browse(cr, uid, tax_code_vals['parent_id'], context)
4332+ parent_parallel_acc_id = self._search_parallel_tax_code(
4333+ cr, uid, parent_tax_code.code, parallel_company, context=context)
4334+ if not parent_parallel_acc_id:
4335+ raise orm.except_orm(_('Error'),
4336+ _('No parent tax code %s found in company %s') %
4337+ (parent_tax_code.code, parallel_company.name))
4338+ vals['parent_id'] = parent_parallel_acc_id
4339+ return vals
4340+
4341+ def create_parallel_tax_codes(self, cr, uid, ids, context=None):
4342+ for tax_code in self.browse(cr, SUPERUSER_ID, ids, context):
4343+ for parallel_company in tax_code.company_id.parallel_company_ids:
4344+ if not tax_code.parent_id:
4345+ raise orm.except_orm(_('Error'),_('Tax code %s does not have parent')
4346+ % tax_code.code)
4347+ existing_ids = self.search(cr, SUPERUSER_ID, [
4348+ ('code', '=', tax_code.code),
4349+ ('company_id', '=', parallel_company.id),
4350+ ])
4351+ if existing_ids:
4352+ raise orm.except_orm(_('Error'),
4353+ _('Tax code %s already exists for company %s')
4354+ % (tax_code.code, parallel_company.name))
4355+ parent_parallel_tax_code_id = self._search_parallel_tax_code(
4356+ cr, SUPERUSER_ID, tax_code.parent_id.code, parallel_company,
4357+ context=context)
4358+ new_id = self.create(cr, SUPERUSER_ID,{
4359+ 'company_id': parallel_company.id,
4360+ 'parent_id': parent_parallel_tax_code_id,
4361+ 'name': tax_code.name,
4362+ 'code': tax_code.code,
4363+ 'notprintable': tax_code.notprintable,
4364+ 'sign': tax_code.sign,
4365+ 'info': tax_code.info,
4366+ })
4367+ cr.execute(
4368+ "insert into parallel_tax_code_rel(parent_id,child_id) values (%d,%d)"
4369+ % (tax_code.id,new_id))
4370+ return True
4371+
4372+ def write(self, cr, uid, ids, vals, context=None):
4373+ if not vals.has_key('parallel_tax_code_ids'):
4374+ # write/create parallel tax codes only if 'parallel_tax_code_ids' not explicity written
4375+ for tax_code_id in ids:
4376+ tax_code = self.browse(cr, SUPERUSER_ID, tax_code_id, context)
4377+ for parallel_tax_code in tax_code.parallel_tax_code_ids:
4378+ parallel_vals = self._build_tax_code_vals(
4379+ cr, SUPERUSER_ID, vals, parallel_tax_code.company_id, context=context)
4380+ parallel_tax_code.write(parallel_vals)
4381+ res=super(account_tax_code,self).write(cr, uid, ids, vals, context=context)
4382+ return res
4383+
4384+ def create(self, cr, uid, vals, context=None):
4385+ res=super(account_tax_code,self).create(cr, uid, vals, context)
4386+ self.create_parallel_tax_codes(cr, uid, [res], context=None)
4387+ return res
4388
4389=== added file 'account_parallel_currency/account_demo.xml'
4390--- account_parallel_currency/account_demo.xml 1970-01-01 00:00:00 +0000
4391+++ account_parallel_currency/account_demo.xml 2014-06-26 13:58:55 +0000
4392@@ -0,0 +1,504 @@
4393+<?xml version="1.0" encoding="utf-8"?>
4394+<openerp>
4395+ <data>
4396+
4397+ <!--
4398+ Parallel company
4399+ -->
4400+
4401+ <record id="parallel_company" model="res.company">
4402+ <field name="name" >Parallel company</field>
4403+ <field name="currency_id" ref="base.CHF"></field>
4404+ </record>
4405+
4406+ <record id="base.main_company" model="res.company">
4407+ <field name="parallel_company_ids" eval="[(6,0,[ref('parallel_company')])]"></field>
4408+ </record>
4409+
4410+ <!--
4411+ currencies
4412+ -->
4413+
4414+ <record id="USD" model="res.currency">
4415+ <field name="name">USD</field>
4416+ <field name="symbol">$</field>
4417+ <field name="rounding">0.01</field>
4418+ <field name="accuracy">4</field>
4419+ <field name="position">before</field>
4420+ <field name="company_id" ref="parallel_company"/>
4421+ </record>
4422+ <record id="rateUSD" model="res.currency.rate">
4423+ <field name="rate">1.2834</field>
4424+ <field name="currency_id" ref="USD"/>
4425+ <field eval="time.strftime('%Y-01-01')" name="name"/>
4426+ </record>
4427+ <record id="CHF" model="res.currency">
4428+ <field name="name">CHF</field>
4429+ <field name="symbol">CHF</field>
4430+ <field name="rounding">0.01</field>
4431+ <field name="accuracy">4</field>
4432+ <field name="company_id" ref="parallel_company"/>
4433+ </record>
4434+ <record id="rateCHF" model="res.currency.rate">
4435+ <field name="rate">1.3086</field>
4436+ <field name="currency_id" ref="CHF"/>
4437+ <field eval="time.strftime('%Y-01-01')" name="name"/>
4438+ </record>
4439+ <record id="EUR" model="res.currency">
4440+ <field name="name">EUR</field>
4441+ <field name="symbol">€</field>
4442+ <field name="rounding">0.01</field>
4443+ <field name="accuracy">4</field>
4444+ <field name="company_id" ref="parallel_company"/>
4445+ </record>
4446+ <record id="rateEUR" model="res.currency.rate">
4447+ <field name="currency_id" ref="EUR" />
4448+ <field eval="time.strftime('%Y-01-01')" name="name"/>
4449+ <field name="rate">1.0</field>
4450+ </record>
4451+
4452+ <!--
4453+ Journal
4454+ -->
4455+
4456+ <record id="parallel_sales_journal" model="account.journal">
4457+ <field name="name">Parallel Sales Journal - (test)</field>
4458+ <field name="code">PSAJ</field>
4459+ <field name="type">sale</field>
4460+ <field name="company_id" ref="parallel_company"/>
4461+ </record>
4462+ <record id="account.sales_journal" model="account.journal">
4463+ <field name="parallel_journal_ids" eval="[(6,0,[ref('parallel_sales_journal')])]"></field>
4464+ </record>
4465+
4466+ <!--
4467+ Fiscal year
4468+ -->
4469+
4470+ <record id="data_fiscalyear" model="account.fiscalyear">
4471+ <field eval="'Fiscal Year X '+time.strftime('%Y')" name="name"/>
4472+ <field eval="'FY'+time.strftime('%Y')" name="code"/>
4473+ <field eval="time.strftime('%Y')+'-01-01'" name="date_start"/>
4474+ <field eval="time.strftime('%Y')+'-12-31'" name="date_stop"/>
4475+ <field name="company_id" ref="parallel_company"/>
4476+ </record>
4477+
4478+ <!--
4479+ Fiscal Periods
4480+ -->
4481+
4482+ <record id="period_1" model="account.period">
4483+ <field eval="'01/'+time.strftime('%Y')" name="code"/>
4484+ <field eval="'X 01/'+time.strftime('%Y')" name="name"/>
4485+ <field eval="True" name="special"/>
4486+ <field name="fiscalyear_id" ref="data_fiscalyear"/>
4487+ <field eval="time.strftime('%Y')+'-01-01'" name="date_start"/>
4488+ <field eval="time.strftime('%Y')+'-01-31'" name="date_stop"/>
4489+ <field name="company_id" ref="parallel_company"/>
4490+ </record>
4491+ <record id="period_2" model="account.period">
4492+ <field eval="'02/'+time.strftime('%Y')" name="code"/>
4493+ <field eval="'X 02/'+time.strftime('%Y')" name="name"/>
4494+ <field eval="True" name="special"/>
4495+ <field name="fiscalyear_id" ref="data_fiscalyear"/>
4496+ <field eval="time.strftime('%Y')+'-02-01'" name="date_start"/>
4497+ <!-- for the last day of February, we have to compute the day before March 1st -->
4498+ <field eval="(DateTime.today().replace(month=3, day=1) - timedelta(days=1)).strftime('%Y-%m-%d')" name="date_stop"/>
4499+ <field name="company_id" ref="parallel_company"/>
4500+ </record>
4501+ <record id="period_3" model="account.period">
4502+ <field eval="'03/'+time.strftime('%Y')" name="code"/>
4503+ <field eval="'X 03/'+time.strftime('%Y')" name="name"/>
4504+ <field eval="True" name="special"/>
4505+ <field name="fiscalyear_id" ref="data_fiscalyear"/>
4506+ <field eval="time.strftime('%Y')+'-03-01'" name="date_start"/>
4507+ <field eval="time.strftime('%Y')+'-03-31'" name="date_stop"/>
4508+ <field name="company_id" ref="parallel_company"/>
4509+ </record>
4510+ <record id="period_4" model="account.period">
4511+ <field eval="'04/'+time.strftime('%Y')" name="code"/>
4512+ <field eval="'X 04/'+time.strftime('%Y')" name="name"/>
4513+ <field eval="True" name="special"/>
4514+ <field name="fiscalyear_id" ref="data_fiscalyear"/>
4515+ <field eval="time.strftime('%Y')+'-04-01'" name="date_start"/>
4516+ <field eval="time.strftime('%Y')+'-04-30'" name="date_stop"/>
4517+ <field name="company_id" ref="parallel_company"/>
4518+ </record>
4519+ <record id="period_5" model="account.period">
4520+ <field eval="'05/'+time.strftime('%Y')" name="code"/>
4521+ <field eval="'X 05/'+time.strftime('%Y')" name="name"/>
4522+ <field eval="True" name="special"/>
4523+ <field name="fiscalyear_id" ref="data_fiscalyear"/>
4524+ <field eval="time.strftime('%Y')+'-05-01'" name="date_start"/>
4525+ <field eval="time.strftime('%Y')+'-05-31'" name="date_stop"/>
4526+ <field name="company_id" ref="parallel_company"/>
4527+ </record>
4528+ <record id="period_6" model="account.period">
4529+ <field eval="'06/'+time.strftime('%Y')" name="code"/>
4530+ <field eval="'X 06/'+time.strftime('%Y')" name="name"/>
4531+ <field name="fiscalyear_id" ref="data_fiscalyear"/>
4532+ <field eval="True" name="special"/>
4533+ <field eval="time.strftime('%Y')+'-06-01'" name="date_start"/>
4534+ <field eval="time.strftime('%Y')+'-06-30'" name="date_stop"/>
4535+ <field name="company_id" ref="parallel_company"/>
4536+ </record>
4537+ <record id="period_7" model="account.period">
4538+ <field eval="'07/'+time.strftime('%Y')" name="code"/>
4539+ <field eval="'X 07/'+time.strftime('%Y')" name="name"/>
4540+ <field eval="True" name="special"/>
4541+ <field name="fiscalyear_id" ref="data_fiscalyear"/>
4542+ <field eval="time.strftime('%Y')+'-07-01'" name="date_start"/>
4543+ <field eval="time.strftime('%Y')+'-07-31'" name="date_stop"/>
4544+ <field name="company_id" ref="parallel_company"/>
4545+ </record>
4546+ <record id="period_8" model="account.period">
4547+ <field eval="'08/'+time.strftime('%Y')" name="code"/>
4548+ <field eval="'X 08/'+time.strftime('%Y')" name="name"/>
4549+ <field eval="True" name="special"/>
4550+ <field name="fiscalyear_id" ref="data_fiscalyear"/>
4551+ <field eval="time.strftime('%Y')+'-08-01'" name="date_start"/>
4552+ <field eval="time.strftime('%Y')+'-08-31'" name="date_stop"/>
4553+ <field name="company_id" ref="parallel_company"/>
4554+ </record>
4555+ <record id="period_9" model="account.period">
4556+ <field eval="'09/'+time.strftime('%Y')" name="code"/>
4557+ <field eval="'X 09/'+time.strftime('%Y')" name="name"/>
4558+ <field eval="True" name="special"/>
4559+ <field name="fiscalyear_id" ref="data_fiscalyear"/>
4560+ <field eval="time.strftime('%Y')+'-09-01'" name="date_start"/>
4561+ <field eval="time.strftime('%Y')+'-09-30'" name="date_stop"/>
4562+ <field name="company_id" ref="parallel_company"/>
4563+ </record>
4564+ <record id="period_10" model="account.period">
4565+ <field eval="'10/'+time.strftime('%Y')" name="code"/>
4566+ <field eval="'X 10/'+time.strftime('%Y')" name="name"/>
4567+ <field eval="True" name="special"/>
4568+ <field name="fiscalyear_id" ref="data_fiscalyear"/>
4569+ <field eval="time.strftime('%Y')+'-10-01'" name="date_start"/>
4570+ <field eval="time.strftime('%Y')+'-10-31'" name="date_stop"/>
4571+ <field name="company_id" ref="parallel_company"/>
4572+ </record>
4573+ <record id="period_11" model="account.period">
4574+ <field eval="'11/'+time.strftime('%Y')" name="code"/>
4575+ <field eval="'X 11/'+time.strftime('%Y')" name="name"/>
4576+ <field eval="True" name="special"/>
4577+ <field name="fiscalyear_id" ref="data_fiscalyear"/>
4578+ <field eval="time.strftime('%Y')+'-11-01'" name="date_start"/>
4579+ <field eval="time.strftime('%Y')+'-11-30'" name="date_stop"/>
4580+ <field name="company_id" ref="parallel_company"/>
4581+ </record>
4582+ <record id="period_12" model="account.period">
4583+ <field eval="'12/'+time.strftime('%Y')" name="code"/>
4584+ <field eval="'X 12/'+time.strftime('%Y')" name="name"/>
4585+ <field eval="True" name="special"/>
4586+ <field name="fiscalyear_id" ref="data_fiscalyear"/>
4587+ <field eval="time.strftime('%Y')+'-12-01'" name="date_start"/>
4588+ <field eval="time.strftime('%Y')+'-12-31'" name="date_stop"/>
4589+ <field name="company_id" ref="parallel_company"/>
4590+ </record>
4591+
4592+ <!--
4593+ Chart of Accounts
4594+ -->
4595+
4596+ <record id="chart0" model="account.account">
4597+ <field name="company_id" ref="parallel_company"/>
4598+ <field name="code">X0</field>
4599+ <field name="name">Chart For Automated Tests</field>
4600+ <field name="type">view</field>
4601+ <field name="user_type" ref="account.data_account_type_view"/>
4602+ </record>
4603+
4604+ <!-- Balance Sheet -->
4605+
4606+ <record id="bal" model="account.account">
4607+ <field name="company_id" ref="parallel_company"/>
4608+ <field name="code">X1</field>
4609+ <field name="name">Balance Sheet - (test)</field>
4610+ <field ref="chart0" name="parent_id"/>
4611+ <field name="type">view</field>
4612+ <field name="user_type" ref="account.data_account_type_view"/>
4613+ </record>
4614+
4615+ <record model="account.account" id="assets_view">
4616+ <field name="company_id" ref="parallel_company"/>
4617+ <field name="name">Assets - (test)</field>
4618+ <field name="code">X10</field>
4619+ <field name="type">view</field>
4620+ <field name="user_type" ref="account.data_account_type_asset"/>
4621+ <field name="reconcile" eval="False"/>
4622+ <field name="parent_id" ref="bal"/>
4623+ </record>
4624+
4625+ <record id="fas" model="account.account">
4626+ <field name="company_id" ref="parallel_company"/>
4627+ <field name="code">X100</field>
4628+ <field name="name">Fixed Assets - (test)</field>
4629+ <field ref="assets_view" name="parent_id"/>
4630+ <field name="type">view</field>
4631+ <field name="user_type" ref="account.data_account_type_asset"/>
4632+ </record>
4633+
4634+ <record id="xfa" model="account.account">
4635+ <field name="company_id" ref="parallel_company"/>
4636+ <field name="code">X1000</field>
4637+ <field name="name">Fixed Asset Account - (test)</field>
4638+ <field ref="fas" name="parent_id"/>
4639+ <field name="type">other</field>
4640+ <field name="user_type" ref="account.data_account_type_asset"/>
4641+ </record>
4642+
4643+ <record id="nca" model="account.account">
4644+ <field name="company_id" ref="parallel_company"/>
4645+ <field name="code">X101</field>
4646+ <field name="name">Net Current Assets - (test)</field>
4647+ <field ref="assets_view" name="parent_id"/>
4648+ <field name="type">view</field>
4649+ <field name="user_type" ref="account.data_account_type_asset"/>
4650+ </record>
4651+
4652+ <record id="cas" model="account.account">
4653+ <field name="company_id" ref="parallel_company"/>
4654+ <field name="code">X1100</field>
4655+ <field name="name">Current Assets - (test)</field>
4656+ <field ref="nca" name="parent_id"/>
4657+ <field name="type">view</field>
4658+ <field name="user_type" ref="account.data_account_type_asset"/>
4659+ </record>
4660+
4661+ <record id="stk" model="account.account">
4662+ <field name="company_id" ref="parallel_company"/>
4663+ <field name="code">X11001</field>
4664+ <field name="name">Purchased Stocks - (test)</field>
4665+ <field ref="cas" name="parent_id"/>
4666+ <field name="type">other</field>
4667+ <field name="user_type" ref="account.data_account_type_asset"/>
4668+ </record>
4669+
4670+ <record id="a_recv" model="account.account">
4671+ <field name="company_id" ref="parallel_company"/>
4672+ <field name="code">X11002</field>
4673+ <field name="name">Debtors - (test)</field>
4674+ <field ref="cas" name="parent_id"/>
4675+ <field name="type">receivable</field>
4676+ <field eval="True" name="reconcile"/>
4677+ <field name="user_type" ref="account.data_account_type_receivable"/>
4678+ </record>
4679+
4680+ <record id="ova" model="account.account">
4681+ <field name="company_id" ref="parallel_company"/>
4682+ <field name="code">X11003</field>
4683+ <field name="name">Output VAT - (test)</field>
4684+ <field ref="cas" name="parent_id"/>
4685+ <field name="type">other</field>
4686+ <field name="user_type" ref="account.data_account_type_asset"/>
4687+ </record>
4688+
4689+ <record id="bnk" model="account.account">
4690+ <field name="company_id" ref="parallel_company"/>
4691+ <field name="code">X11004</field>
4692+ <field name="name">Bank Current Account - (test)</field>
4693+ <field ref="cas" name="parent_id"/>
4694+ <field name="type">liquidity</field>
4695+ <field name="user_type" ref="account.data_account_type_asset"/>
4696+ </record>
4697+
4698+ <record id="cash" model="account.account">
4699+ <field name="company_id" ref="parallel_company"/>
4700+ <field name="code">X11005</field>
4701+ <field name="name">Cash - (test)</field>
4702+ <field ref="cas" name="parent_id"/>
4703+ <field name="type">liquidity</field>
4704+ <field name="user_type" ref="account.data_account_type_asset"/>
4705+ </record>
4706+
4707+ <record id="o_income" model="account.account">
4708+ <field name="company_id" ref="parallel_company"/>
4709+ <field name="code">X11006</field>
4710+ <field name="name">Opening Income - (test)</field>
4711+ <field ref="cas" name="parent_id"/>
4712+ <field name="type">other</field>
4713+ <field name="user_type" ref="account.data_account_type_income"/>
4714+ </record>
4715+ <record id="usd_bnk" model="account.account">
4716+ <field name="company_id" ref="parallel_company"/>
4717+ <field name="code">X11007</field>
4718+ <field name="name">USD Bank Account - (test)</field>
4719+ <field ref="cas" name="parent_id"/>
4720+ <field name="type">liquidity</field>
4721+ <field name="user_type" ref="account.data_account_type_asset"/>
4722+ <field name="currency_id" ref="base.USD"/>
4723+ </record>
4724+
4725+ <record model="account.account" id="liabilities_view">
4726+ <field name="company_id" ref="parallel_company"/>
4727+ <field name="name">Liabilities - (test)</field>
4728+ <field name="code">X11</field>
4729+ <field name="type">view</field>
4730+ <field name="user_type" ref="account.data_account_type_liability"/>
4731+ <field name="reconcile" eval="False"/>
4732+ <field name="parent_id" ref="bal"/>
4733+ </record>
4734+
4735+ <record id="cli" model="account.account">
4736+ <field name="company_id" ref="parallel_company"/>
4737+ <field name="code">X110</field>
4738+ <field name="name">Current Liabilities - (test)</field>
4739+ <field ref="liabilities_view" name="parent_id"/>
4740+ <field name="type">view</field>
4741+ <field name="user_type" ref="account.data_account_type_liability"/>
4742+ </record>
4743+
4744+ <record id="a_pay" model="account.account">
4745+ <field name="company_id" ref="parallel_company"/>
4746+ <field name="code">X1111</field>
4747+ <field name="name">Creditors - (test)</field>
4748+ <field ref="cli" name="parent_id"/>
4749+ <field name="type">payable</field>
4750+ <field eval="True" name="reconcile"/>
4751+ <field name="user_type" ref="account.data_account_type_payable"/>
4752+ </record>
4753+
4754+ <record id="iva" model="account.account">
4755+ <field name="company_id" ref="parallel_company"/>
4756+ <field name="code">X1112</field>
4757+ <field name="name">Input VAT - (test)</field>
4758+ <field ref="cli" name="parent_id"/>
4759+ <field name="type">other</field>
4760+ <field name="user_type" ref="account.data_account_type_liability"/>
4761+ </record>
4762+
4763+ <record id="rsa" model="account.account">
4764+ <field name="company_id" ref="parallel_company"/>
4765+ <field name="code">X1113</field>
4766+ <field name="name">Reserve and Profit/Loss - (test)</field>
4767+ <field ref="cli" name="parent_id"/>
4768+ <field name="type">other</field>
4769+ <field name="user_type" ref="account.data_account_type_liability"/>
4770+ </record>
4771+
4772+ <record id="o_expense" model="account.account">
4773+ <field name="company_id" ref="parallel_company"/>
4774+ <field name="code">X1114</field>
4775+ <field name="name">Opening Expense - (test)</field>
4776+ <field ref="cli" name="parent_id"/>
4777+ <field name="type">other</field>
4778+ <field name="user_type" ref="account.data_account_type_expense"/>
4779+ </record>
4780+
4781+ <!-- Profit and Loss -->
4782+
4783+ <record id="gpf" model="account.account">
4784+ <field name="company_id" ref="parallel_company"/>
4785+ <field name="code">X2</field>
4786+ <field name="name">Profit and Loss - (test)</field>
4787+ <field ref="chart0" name="parent_id"/>
4788+ <field name="type">view</field>
4789+ <field name="user_type" ref="account.data_account_type_view"/>
4790+ </record>
4791+
4792+ <record model="account.account" id="income_view">
4793+ <field name="company_id" ref="parallel_company"/>
4794+ <field name="name">Income - (test)</field>
4795+ <field name="code">X20</field>
4796+ <field name="type">view</field>
4797+ <field name="user_type" ref="account.data_account_type_income"/>
4798+ <field name="reconcile" eval="False"/>
4799+ <field name="parent_id" ref="gpf"/>
4800+ </record>
4801+
4802+ <record model="account.account" id="income_fx_income">
4803+ <field name="company_id" ref="parallel_company"/>
4804+ <field name="name">Foreign Exchange Gain - (test)</field>
4805+ <field name="code">X201</field>
4806+ <field name="type">other</field>
4807+ <field name="user_type" ref="account.data_account_type_income"/>
4808+ <field name="reconcile" eval="False"/>
4809+ <field name="parent_id" ref="income_view"/>
4810+ </record>
4811+
4812+ <record id="rev" model="account.account">
4813+ <field name="company_id" ref="parallel_company"/>
4814+ <field name="code">X200</field>
4815+ <field name="name">Revenue - (test)</field>
4816+ <field ref="income_view" name="parent_id"/>
4817+ <field name="type">view</field>
4818+ <field name="user_type" ref="account.data_account_type_income"/>
4819+ </record>
4820+
4821+ <record id="a_sale" model="account.account">
4822+ <field name="company_id" ref="parallel_company"/>
4823+ <field name="code">X2001</field>
4824+ <field name="name">Product Sales - (test)</field>
4825+ <field ref="rev" name="parent_id"/>
4826+ <field name="type">other</field>
4827+ <field name="user_type" ref="account.data_account_type_income"/>
4828+ </record>
4829+
4830+ <record model="account.account" id="expense_view">
4831+ <field name="company_id" ref="parallel_company"/>
4832+ <field name="name">Expense - (test)</field>
4833+ <field name="code">X21</field>
4834+ <field name="type">view</field>
4835+ <field name="user_type" ref="account.data_account_type_expense"/>
4836+ <field name="reconcile" eval="False"/>
4837+ <field name="parent_id" ref="gpf"/>
4838+ </record>
4839+
4840+
4841+ <record id="cos" model="account.account">
4842+ <field name="company_id" ref="parallel_company"/>
4843+ <field name="code">X210</field>
4844+ <field name="name">Cost of Sales - (test)</field>
4845+ <field ref="expense_view" name="parent_id"/>
4846+ <field name="type">view</field>
4847+ <field name="user_type" ref="account.data_account_type_expense"/>
4848+ </record>
4849+
4850+ <record id="cog" model="account.account">
4851+ <field name="company_id" ref="parallel_company"/>
4852+ <field name="code">X2100</field>
4853+ <field name="name">Cost of Goods Sold - (test)</field>
4854+ <field ref="cos" name="parent_id"/>
4855+ <field name="type">other</field>
4856+ <field name="user_type" ref="account.data_account_type_expense"/>
4857+ </record>
4858+
4859+ <record id="ovr" model="account.account">
4860+ <field name="company_id" ref="parallel_company"/>
4861+ <field name="code">X211</field>
4862+ <field name="name">Overheads - (test)</field>
4863+ <field ref="expense_view" name="parent_id"/>
4864+ <field name="type">view</field>
4865+ <field name="user_type" ref="account.data_account_type_expense"/>
4866+ </record>
4867+
4868+ <record id="a_expense" model="account.account">
4869+ <field name="company_id" ref="parallel_company"/>
4870+ <field name="code">X2110</field>
4871+ <field name="name">Expenses - (test)</field>
4872+ <field ref="ovr" name="parent_id"/>
4873+ <field name="type">other</field>
4874+ <field name="user_type" ref="account.data_account_type_expense"/>
4875+ </record>
4876+
4877+ <record model="account.account" id="income_fx_expense">
4878+ <field name="company_id" ref="parallel_company"/>
4879+ <field name="name">Foreign Exchange Loss - (test)</field>
4880+ <field name="code">X2111</field>
4881+ <field name="type">other</field>
4882+ <field name="user_type" ref="account.data_account_type_expense"/>
4883+ <field name="reconcile" eval="False"/>
4884+ <field name="parent_id" ref="ovr"/>
4885+ </record>
4886+
4887+ <record id="a_salary_expense" model="account.account">
4888+ <field name="company_id" ref="parallel_company"/>
4889+ <field name="code">X2112</field>
4890+ <field name="name">Salary Expenses - (test)</field>
4891+ <field ref="ovr" name="parent_id"/>
4892+ <field name="type">other</field>
4893+ <field name="user_type" ref="account.data_account_type_expense"/>
4894+ </record>
4895+ </data>
4896+</openerp>
4897
4898=== added file 'account_parallel_currency/account_view.xml'
4899--- account_parallel_currency/account_view.xml 1970-01-01 00:00:00 +0000
4900+++ account_parallel_currency/account_view.xml 2014-06-26 13:58:55 +0000
4901@@ -0,0 +1,64 @@
4902+<?xml version="1.0" encoding="utf-8"?>
4903+<openerp>
4904+ <data>
4905+ <record id="view_account_form" model="ir.ui.view">
4906+ <field name="name">account.account.form</field>
4907+ <field name="model">account.account</field>
4908+ <field name="inherit_id" ref="account.view_account_form"></field>
4909+ <field name="arch" type="xml">
4910+ <field name="note" position="after">
4911+ <group colspan="4" string="Parallel Currency" groups="account.group_account_manager">
4912+ <field name="parallel_accounts_summary" />
4913+ <button name="create_parallel_accounts" type="object" string="Create parallel accounts"></button>
4914+ <separator string="Parallel Currency Accounts" colspan="4"/>
4915+ <field colspan="4" name="parallel_account_ids" nolabel="1" domain="[('company_id', '!=', company_id)]"/>
4916+ <separator string="Master Parallel Currency Accounts" colspan="4"/>
4917+ <field colspan="4" name="master_parallel_account_ids" nolabel="1"/>
4918+ </group>
4919+ </field>
4920+ </field>
4921+ </record>
4922+ <record id="view_account_journal_form" model="ir.ui.view">
4923+ <field name="name">view_account_journal_form</field>
4924+ <field name="model">account.journal</field>
4925+ <field name="inherit_id" ref="account.view_account_journal_form"></field>
4926+ <field name="arch" type="xml">
4927+ <page string="Entry Controls" position="after">
4928+ <page string="Parallel Currency" groups="account.group_account_manager">
4929+ <separator string="Parallel Currency Journals" colspan="4"/>
4930+ <field colspan="4" name="parallel_journal_ids" nolabel="1" domain="[('company_id', '!=', company_id)]"/>
4931+ <separator string="Master Parallel Currency Journals" colspan="4"/>
4932+ <field colspan="4" name="master_parallel_journal_ids" nolabel="1"/>
4933+ </page>
4934+ </page>
4935+ </field>
4936+ </record>
4937+ <record id="view_tax_code_form" model="ir.ui.view">
4938+ <field name="name">view_tax_code_form</field>
4939+ <field name="model">account.tax.code</field>
4940+ <field name="inherit_id" ref="account.view_tax_code_form"></field>
4941+ <field name="arch" type="xml">
4942+ <field name="info" position="after">
4943+ <group colspan="4" col="1" groups="account.group_account_manager">
4944+ <field name="parallel_tax_codes_summary" />
4945+ <button name="create_parallel_tax_codes" type="object" string="Create parallel tax codes"></button>
4946+ <field name="parallel_tax_code_ids" domain="[('company_id', '!=', company_id)]"/>
4947+ <field name="master_parallel_tax_code_ids"/>
4948+ </group>
4949+ </field>
4950+ </field>
4951+ </record>
4952+ <record id="view_move_form" model="ir.ui.view">
4953+ <field name="name">view_move_form</field>
4954+ <field name="model">account.move</field>
4955+ <field name="inherit_id" ref="account.view_move_form"></field>
4956+ <field name="arch" type="xml">
4957+ <page string="Journal Items" position="after">
4958+ <page string="Parallel Entries" groups="account.group_account_manager">
4959+ <field colspan="4" name="parallel_move_ids" nolabel="1" />
4960+ </page>
4961+ </page>
4962+ </field>
4963+ </record>
4964+ </data>
4965+</openerp>
4966
4967=== added file 'account_parallel_currency/company_view.xml'
4968--- account_parallel_currency/company_view.xml 1970-01-01 00:00:00 +0000
4969+++ account_parallel_currency/company_view.xml 2014-06-26 13:58:55 +0000
4970@@ -0,0 +1,16 @@
4971+<?xml version="1.0" encoding="UTF-8"?>
4972+<openerp>
4973+ <data>
4974+ <record id="view_company_form" model="ir.ui.view">
4975+ <field name="inherit_id" ref="base.view_company_form"/>
4976+ <field name="name">view.company.form</field>
4977+ <field name="model">res.company</field>
4978+ <field name="arch" type="xml">
4979+ <page string="Configuration" position="inside">
4980+ <separator string="Parallel Companies" colspan="4"/>
4981+ <field name="parallel_company_ids" nolabel="1" colspan="4"/>
4982+ </page>
4983+ </field>
4984+ </record>
4985+ </data>
4986+</openerp>
4987
4988=== added directory 'account_parallel_currency/i18n'
4989=== added file 'account_parallel_currency/i18n/account_parallel_currency.pot'
4990--- account_parallel_currency/i18n/account_parallel_currency.pot 1970-01-01 00:00:00 +0000
4991+++ account_parallel_currency/i18n/account_parallel_currency.pot 2014-06-26 13:58:55 +0000
4992@@ -0,0 +1,343 @@
4993+# Translation of OpenERP Server.
4994+# This file contains the translation of the following modules:
4995+# * account_parallel_currency
4996+#
4997+msgid ""
4998+msgstr ""
4999+"Project-Id-Version: OpenERP Server 7.0\n"
5000+"Report-Msgid-Bugs-To: \n"
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches