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

Proposed by Alexandre Fayolle - camptocamp
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) Needs Resubmitting
Account Core Editors 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.
Revision history for this message
Lorenzo Battistini (elbati) wrote :

wrong target

review: Needs Resubmitting
Revision history for this message
Joël Grand-Guillaume @ camptocamp (jgrandguillaume-c2c) wrote :

This project is now hosted on https://github.com/OCA/account-consolidation. Please move your proposal there. This guide may help you https://github.com/OCA/maintainers-tools/wiki/How-to-move-a-Merge-Proposal-to-GitHub

Unmerged revisions

23. By Alexandre Fayolle - camptocamp

new link module account_parallel_currency_centralized

linking account_parallel_currency and account_financial_report_webkit

22. By Lorenzo Battistini

[MRG] fix usage of undefined field 'centralized'

21. By Nicolas Bessi - Camptocamp

[FIX] missing domain in multi currency consolidation

20. By Vincent Renaville@camptocamp

[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

[IMP] Translation template files for all modules.

18. By Maxime Chambreuil (http://www.savoirfairelinux.com)

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

17. By Nicolas Bessi - Camptocamp

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

16. By Joël Grand-Guillaume @ camptocamp

[MIGR] Migration of account_consolidation to OpenERP version 7.0

15. By Guewen Baconnier @ Camptocamp

[MIGR] set modules not installable (need migration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'account_consolidation/__init__.py'
--- account_consolidation/__init__.py 2011-08-12 15:39:07 +0000
+++ account_consolidation/__init__.py 2014-06-26 13:58:55 +0000
@@ -1,3 +1,4 @@
1import company1from . import company
2import account2from . import account
3import wizard3from . import account_move_line
4from . import wizard
45
=== modified file 'account_consolidation/__openerp__.py'
--- account_consolidation/__openerp__.py 2012-04-11 07:52:09 +0000
+++ account_consolidation/__openerp__.py 2014-06-26 13:58:55 +0000
@@ -1,72 +1,72 @@
1# -*- coding: utf-8 -*-1# -*- coding: utf-8 -*-
2##############################################################################2##############################################################################
3#3#
4# Copyright (c) 2011 Camptocamp SA (http://www.camptocamp.com)4# Author: Guewen Baconnier
5# All Right Reserved5# Copyright 2011-2013 Camptocamp SA
6#6#
7# Author : Guewen Baconnier (Camptocamp)7# This program is free software: you can redistribute it and/or modify
8#8# it under the terms of the GNU Affero General Public License as
9# WARNING: This program as such is intended to be used by professional9# published by the Free Software Foundation, either version 3 of the
10# programmers who take the whole responsability of assessing all potential10# License, or (at your option) any later version.
11# consequences resulting from its eventual inadequacies and bugs11#
12# End users who are looking for a ready-to-use solution with commercial12# This program is distributed in the hope that it will be useful,
13# garantees and support are strongly adviced to contract a Free Software13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# Service Company14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15#15# GNU Affero General Public License for more details.
16# This program is Free Software; you can redistribute it and/or16#
17# modify it under the terms of the GNU General Public License17# You should have received a copy of the GNU Affero General Public License
18# as published by the Free Software Foundation; either version 218# along with this program. If not, see <http://www.gnu.org/licenses/>.
19# of the License, or (at your option) any later version.
20#
21# This program is distributed in the hope that it will be useful,
22# but WITHOUT ANY WARRANTY; without even the implied warranty of
23# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24# GNU General Public License for more details.
25#
26# You should have received a copy of the GNU General Public License
27# along with this program; if not, write to the Free Software
28# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29#19#
30##############################################################################20##############################################################################
3121{"name": "Account Consolidation",
3222 "version": "1.0",
33{23 "author": "Camptocamp",
34 "name" : "Account Consolidation",24 "license": "AGPL-3",
35 "version" : "0.0",25 "category": "Generic Modules/Accounting",
36 "author" : "Camptocamp",26 "description": """
37 "category" : "Generic Modules/Accounting",27Account consolidation
38 "description":28=====================
39"""29
40Account consolidation module. Coding in progress...30Introduction
4131------------
42Some explanations to do...32
4333Consolidate chart of accounts on subsidiaries
44 - Difference between debit/credit is balanced on the debit/credit default account of the journal?34in a virtual chart of accounts of the holding.
45""",35
46 "website": "http://www.camptocamp.com",36Installation
47 "depends" : [37------------
48 'base',38The `account_reversal` module is required,
49 'account',39it can be found on the account-financial-tools_
50 'account_reversal',40project
51 ],41
52 "init_xml" : [],42.. _account-financial-tools: https://launchpad.net/account-financial-tools""",
53 "demo_xml" : [43
54 'demo/consolidation_demo.xml',44 "website": "http://www.camptocamp.com",
55 'demo/chart_a_demo.xml',45 "depends": ['base',
56 'demo/chart_b_demo.xml',46 'account',
57 ],47 'account_reversal', # TODO check account_constraints compat.
58 "update_xml" : [48 ],
59 'company_view.xml',49
60 'account_view.xml',50 "demo_xml": ['demo/consolidation_demo.xml',
61 'wizard/consolidation_check_view.xml',51 'demo/chart_a_demo.xml',
62 'wizard/consolidation_consolidate_view.xml',52 'demo/chart_b_demo.xml',
63 'consolidation_menu.xml',53 ],
64 ],54
65 'test': [55 "data": ['data.xml',
66 'test/test_data.yml',56 'account_move_line_view.xml',
67 'test/consolidation_checks.yml',57 'company_view.xml',
68 'test/consolidation_consolidate.yml',58 'account_view.xml',
69 ],59 'wizard/consolidation_check_view.xml',
70 "active": False,60 'wizard/consolidation_consolidate_view.xml',
71 "installable": True61 'consolidation_menu.xml',
72}62 'analysis_view.xml'
63 ],
64
65 "test": ['test/test_data.yml',
66 'test/consolidation_checks.yml',
67 'test/consolidation_consolidate.yml',
68 ],
69
70 "active": False,
71 "installable": True,
72 }
7373
=== modified file 'account_consolidation/account.py'
--- account_consolidation/account.py 2011-08-29 14:04:57 +0000
+++ account_consolidation/account.py 2014-06-26 13:58:55 +0000
@@ -1,77 +1,74 @@
1# -*- coding: utf-8 -*-1# -*- coding: utf-8 -*-
2##############################################################################2##############################################################################
3#3#
4# Copyright (c) 2011 Camptocamp SA (http://www.camptocamp.com)4# Author: Guewen Baconnier
5#5# Copyright 2011-2013 Camptocamp SA
6# Author : Guewen Baconnier (Camptocamp)6#
7#7# This program is free software: you can redistribute it and/or modify
8# WARNING: This program as such is intended to be used by professional8# it under the terms of the GNU Affero General Public License as
9# programmers who take the whole responsability of assessing all potential9# published by the Free Software Foundation, either version 3 of the
10# consequences resulting from its eventual inadequacies and bugs10# License, or (at your option) any later version.
11# End users who are looking for a ready-to-use solution with commercial11#
12# garantees and support are strongly adviced to contract a Free Software12# This program is distributed in the hope that it will be useful,
13# Service Company13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14#14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# This program is Free Software; you can redistribute it and/or15# GNU Affero General Public License for more details.
16# modify it under the terms of the GNU General Public License16#
17# as published by the Free Software Foundation; either version 217# You should have received a copy of the GNU Affero General Public License
18# of the License, or (at your option) any later version.18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20# This program is distributed in the hope that it will be useful,
21# but WITHOUT ANY WARRANTY; without even the implied warranty of
22# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23# GNU General Public License for more details.
24#
25# You should have received a copy of the GNU General Public License
26# along with this program; if not, write to the Free Software
27# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28#19#
29##############################################################################20##############################################################################
3021
31from osv import osv, fields22from openerp.osv import orm, fields
3223
3324
34class account_account(osv.osv):25class account_account(orm.Model):
35 _inherit = 'account.account'26 _inherit = 'account.account'
3627
37 _columns = {28 _columns = {
38 'consolidation_rate_type_id': fields.many2one('res.currency.rate.type',29 'consolidation_rate_type_id': fields.many2one(
39 'Consolidation Currency Rate Type',30 'res.currency.rate.type',
40 help="Currency rate type used on this account for the consolidation, Leave empty to use the rate type of the account type."),31 'Consolidation Currency Rate Type',
41 'consolidation_mode': fields.selection([('', ''),32 help="Currency rate type used on this account "
42 ('ytd', 'YTD'),33 "for the consolidation. "
43 ('period', 'Period Movements'),34 "Leave empty to use the rate type of the account type."),
44 ],35
45 'Consolidation Mode'),36 'consolidation_mode': fields.selection(
37 [('ytd', 'YTD'),
38 ('period', 'Period Movements')],
39 'Consolidation Mode',
40 help="This must be set on the holding company accounts only"),
46 }41 }
4742
48account_account()43
4944class account_account_type(orm.Model):
50
51class account_account_type(osv.osv):
52 _inherit = 'account.account.type'45 _inherit = 'account.account.type'
5346
54 _columns = {47 _columns = {
55 'consolidation_rate_type_id': fields.many2one('res.currency.rate.type',48 'consolidation_rate_type_id': fields.many2one(
56 'Consolidation Currency Rate Type',49 'res.currency.rate.type',
57 help="Currency rate type used on this account type for the consolidation, Leave empty to use the 'spot' rate type."),50 'Consolidation Currency Rate Type',
58 'consolidation_mode': fields.selection([('ytd', 'YTD'),51 help="Currency rate type used on this account type "
59 ('period', 'Period Movements'),],52 "for the consolidation. "
60 'Consolidation Mode'),53 "Leave empty to use the 'spot' rate type."),
61 }54
6255 'consolidation_mode': fields.selection(
63 _defaults = {56 [('ytd', 'YTD'),
64 'consolidation_mode': 'ytd',57 ('period', 'Period Movements')],
65 }58 'Consolidation Mode',
6659 help="This must be set on the holding company accounts only"),
67account_account_type()60
6861 }
6962
70class account_move(osv.osv):63 _defaults = {'consolidation_mode': 'ytd'}
64
65
66class account_move(orm.Model):
71 _inherit = 'account.move'67 _inherit = 'account.move'
7268
73 _columns = {69 _columns = {
74 'consol_company_id': fields.many2one('res.company', 'Consolidated from Company', readonly=True),70 'consol_company_id': fields.many2one(
71 'res.company',
72 'Consolidated from Company',
73 readonly=True),
75 }74 }
76
77account_move()
7875
=== added file 'account_consolidation/account_move_line.py'
--- account_consolidation/account_move_line.py 1970-01-01 00:00:00 +0000
+++ account_consolidation/account_move_line.py 2014-06-26 13:58:55 +0000
@@ -0,0 +1,52 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# Author: Nicolas Bessi Guewen Baconnier
5# Copyright 2011-2013 Camptocamp SA
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21
22from openerp.osv import orm, fields
23
24
25class AccountMoveLine(orm.Model):
26 _inherit = 'account.move.line'
27
28 def _current_company(self, cursor, uid, ids, name, args, context=None):
29 company_id = self.pool['res.company']._company_default_get(cursor, uid)
30 curr_ids = self.search(cursor, uid, [('company_id', '=', company_id),
31 ('id', 'in', ids)])
32 res = dict([(tid, tid in curr_ids) for tid in ids])
33 return res
34
35
36 def search_is_current_company(self, cursor, uid, obj, name, args, context=None):
37 company_id = self.pool['res.company']._company_default_get(cursor, uid)
38 res = self.search(cursor, uid, [('company_id', '=', company_id)])
39 return [('id', 'in', res)]
40
41 _columns = {'consol_company_id': fields.related('move_id', 'consol_company_id',
42 relation='res.company',
43 type="many2one",
44 string='Subsidaries',
45 store=True, # for the group_by
46 readonly=True),
47
48 'is_current_company': fields.function(_current_company,
49 string="Current company",
50 type="boolean",
51 fnct_search=search_is_current_company)
52 }
053
=== added file 'account_consolidation/account_move_line_view.xml'
--- account_consolidation/account_move_line_view.xml 1970-01-01 00:00:00 +0000
+++ account_consolidation/account_move_line_view.xml 2014-06-26 13:58:55 +0000
@@ -0,0 +1,30 @@
1<openerp>
2 <data>
3 <record id="view_move_line_tree" model="ir.ui.view">
4 <field name="name">account.move.line.tree.conso</field>
5 <field name="model">account.move.line</field>
6 <field name="inherit_id" ref="account.view_move_line_tree"/>
7 <field name="arch" type="xml">
8 <field name="date" position="before">
9 <field name="consol_company_id"
10 groups="account_consolidation.consolidation_manager,account_consolidation.consolidation_user"/>
11 <field name="is_current_company" invisible="1"/>
12 </field>
13 </field>
14 </record>
15
16 <record id="view_account_move_line_filter" model="ir.ui.view">
17 <field name="name">Journal Items conso</field>
18 <field name="model">account.move.line</field>
19 <field name="inherit_id" ref="account.view_account_move_line_filter"/>
20 <field name="arch" type="xml">
21 <filter string="Period" position="after">
22 <filter string="Subsidaries"
23 icon="terp-folder-green"
24 context="{'group_by':'consol_company_id'}"
25 groups="account_consolidation.consolidation_manager,account_consolidation.consolidation_user"/>
26 </filter>
27 </field>
28 </record>
29 </data>
30</openerp>
031
=== modified file 'account_consolidation/account_view.xml'
--- account_consolidation/account_view.xml 2011-08-29 14:04:57 +0000
+++ account_consolidation/account_view.xml 2014-06-26 13:58:55 +0000
@@ -9,8 +9,8 @@
9 <field name="type">form</field>9 <field name="type">form</field>
10 <field name="arch" type="xml">10 <field name="arch" type="xml">
11 <data>11 <data>
12 <xpath expr="/form/notebook/page[@string='General Information']/group[2]" position="after">12 <xpath expr="//field[@name='note']" position="after">
13 <group col="2" colspan="2">13 <group groups="account_consolidation.consolidation_manager">
14 <separator string="Consolidation" colspan="2"/>14 <separator string="Consolidation" colspan="2"/>
15 <field name="consolidation_rate_type_id" widget="selection"/>15 <field name="consolidation_rate_type_id" widget="selection"/>
16 <field name="consolidation_mode"/>16 <field name="consolidation_mode"/>
@@ -20,7 +20,7 @@
20 </data>20 </data>
21 </field>21 </field>
22 </record>22 </record>
23 23
24 <record id="view_account_type_consolidation_form" model="ir.ui.view">24 <record id="view_account_type_consolidation_form" model="ir.ui.view">
25 <field name="name">account.account.type.consolidation.form</field>25 <field name="name">account.account.type.consolidation.form</field>
26 <field name="model">account.account.type</field>26 <field name="model">account.account.type</field>
@@ -28,7 +28,7 @@
28 <field name="type">form</field>28 <field name="type">form</field>
29 <field name="arch" type="xml">29 <field name="arch" type="xml">
30 <separator string="Description" position="before">30 <separator string="Description" position="before">
31 <group col="2" colspan="2">31 <group col="2" colspan="2" groups="account_consolidation.consolidation_manager">
32 <separator string="Consolidation" colspan="4"/>32 <separator string="Consolidation" colspan="4"/>
33 <field name="consolidation_rate_type_id" widget="selection"/>33 <field name="consolidation_rate_type_id" widget="selection"/>
34 <field name="consolidation_mode"/>34 <field name="consolidation_mode"/>
@@ -44,11 +44,12 @@
44 <field name="type">form</field>44 <field name="type">form</field>
45 <field name="arch" type="xml">45 <field name="arch" type="xml">
46 <field name="company_id" position="after">46 <field name="company_id" position="after">
47 <field name="consol_company_id" attrs="{'invisible': [('consol_company_id', '=', False)]}"/>47 <field name="consol_company_id"
48 attrs="{'invisible': [('consol_company_id', '=', False)]}"
49 groups="account_consolidation.consolidation_manager,account_consolidation.consolidation_user"/>
48 </field>50 </field>
49 </field>51 </field>
50 </record>52 </record>
5153
52 </data>54 </data>
53</openerp>55</openerp>
54
5556
=== added file 'account_consolidation/analysis_view.xml'
--- account_consolidation/analysis_view.xml 1970-01-01 00:00:00 +0000
+++ account_consolidation/analysis_view.xml 2014-06-26 13:58:55 +0000
@@ -0,0 +1,39 @@
1<openerp>
2 <data>
3
4 <menuitem id="menu_conso_entries"
5 name="Consolidation Entries"
6 parent="account.menu_finance"
7 sequence="5"
8 groups="account_consolidation.consolidation_manager,account_consolidation.consolidation_user"/>
9
10 <record id="action_account_moves_all_a" model="ir.actions.act_window">
11 <field name="context">{'journal_type':'general'}</field>
12 <field name="name">Journal Items</field>
13 <field name="domain">[('is_current_company', '=', True)]</field>
14 <field name="res_model">account.move.line</field>
15 <field name="view_id" ref="account.view_move_line_tree"/>
16 <field name="view_mode">tree_account_move_line_quickadd,form</field>
17 <field name="help" type="html">
18 <p class="oe_view_nocontent_create">
19 Select the period and the journal you want to fill.
20 </p><p>
21 This view can be used by accountants in order to quickly record
22 entries in OpenERP. If you want to record a supplier invoice,
23 start by recording the line of the expense account. OpenERP
24 will propose to you automatically the Tax related to this
25 account and the counterpart "Account Payable".
26 </p>
27 </field>
28 </record>
29
30 <menuitem
31 action="action_account_moves_all_a"
32 icon="STOCK_JUSTIFY_FILL"
33 id="menu_action_account_moves_all"
34 parent="menu_conso_entries"
35 sequence="1"
36 groups="account_consolidation.consolidation_manager,account_consolidation.consolidation_user"/>
37
38 </data>
39</openerp>
040
=== modified file 'account_consolidation/company.py'
--- account_consolidation/company.py 2011-08-19 07:16:03 +0000
+++ account_consolidation/company.py 2014-06-26 13:58:55 +0000
@@ -1,44 +1,41 @@
1# -*- coding: utf-8 -*-1# -* coding: utf-8 -*-
2##############################################################################2##############################################################################
3#3#
4# Copyright (c) 2011 Camptocamp SA (http://www.camptocamp.com)4# Author: Guewen Baconnier
5# All Right Reserved5# Copyright 2011-2013 Camptocamp SA
6#6#
7# Author : Guewen Baconnier (Camptocamp)7# This program is free software: you can redistribute it and/or modify
8#8# it under the terms of the GNU Affero General Public License as
9# WARNING: This program as such is intended to be used by professional9# published by the Free Software Foundation, either version 3 of the
10# programmers who take the whole responsability of assessing all potential10# License, or (at your option) any later version.
11# consequences resulting from its eventual inadequacies and bugs11#
12# End users who are looking for a ready-to-use solution with commercial12# This program is distributed in the hope that it will be useful,
13# garantees and support are strongly adviced to contract a Free Software13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# Service Company14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15#15# GNU Affero General Public License for more details.
16# This program is Free Software; you can redistribute it and/or16#
17# modify it under the terms of the GNU General Public License17# You should have received a copy of the GNU Affero General Public License
18# as published by the Free Software Foundation; either version 218# along with this program. If not, see <http://www.gnu.org/licenses/>.
19# of the License, or (at your option) any later version.19#
20#20##############################################################################
21# This program is distributed in the hope that it will be useful,21
22# but WITHOUT ANY WARRANTY; without even the implied warranty of22from openerp.osv import orm, fields
23# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the23
24# GNU General Public License for more details.24
25#25class res_company(orm.Model):
26# You should have received a copy of the GNU General Public License
27# along with this program; if not, write to the Free Software
28# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29#
30##############################################################################
31
32from osv import osv, fields
33
34
35class res_company(osv.osv):
36 _inherit = 'res.company'26 _inherit = 'res.company'
3727
38 _columns = {28 _columns = {'consolidation_chart_account_id': fields.many2one(
39 'consolidation_chart_account_id': fields.many2one('account.account',29 'account.account',
40 'Chart of Accounts for Consolidation',30 'Chart of Accounts for Consolidation',
41 domain=[('parent_id', '=', False)]),31 domain=[('parent_id', '=', False)],
42 }32 help=("Current company root account"
33 " to be used when consolidating")),
4334
44res_company()35 'consolidation_diff_account_id': fields.many2one(
36 'account.account',
37 'Consolidation difference account',
38 domain=[('type', '=', 'other')],
39 help=("Conso. differences will be affected"
40 " to this account"))
41 }
4542
=== modified file 'account_consolidation/company_view.xml'
--- account_consolidation/company_view.xml 2011-08-19 07:16:03 +0000
+++ account_consolidation/company_view.xml 2014-06-26 13:58:55 +0000
@@ -9,9 +9,10 @@
9 <field name="type">form</field>9 <field name="type">form</field>
10 <field name="arch" type="xml">10 <field name="arch" type="xml">
11 <page string="Configuration" position="inside">11 <page string="Configuration" position="inside">
12 <group col="2" colspan="2">12 <group col="2" colspan="2" groups="account_consolidation.consolidation_manager">
13 <separator string="Accounts Consolidation" colspan="2"/>13 <separator string="Accounts Consolidation" colspan="2"/>
14 <field name="consolidation_chart_account_id" colspan="2"/>14 <field name="consolidation_chart_account_id" colspan="2"/>
15 <field name="consolidation_diff_account_id" colspan="2"/>
15 </group>16 </group>
16 </page>17 </page>
17 </field>18 </field>
1819
=== modified file 'account_consolidation/consolidation_menu.xml'
--- account_consolidation/consolidation_menu.xml 2011-08-12 15:39:07 +0000
+++ account_consolidation/consolidation_menu.xml 2014-06-26 13:58:55 +0000
@@ -5,18 +5,21 @@
5 <menuitem5 <menuitem
6 name="Consolidation"6 name="Consolidation"
7 parent="account.menu_finance_periodical_processing"7 parent="account.menu_finance_periodical_processing"
8 groups="account_consolidation.consolidation_manager,account_consolidation.consolidation_user"
8 id="menu_consolidation"/>9 id="menu_consolidation"/>
910
10 <menuitem11 <menuitem
11 name="Consolidation: Checks"12 name="Consolidation: Checks"
12 parent="menu_consolidation"13 parent="menu_consolidation"
13 action="action_consolidation_checks"14 action="action_consolidation_checks"
15 groups="account_consolidation.consolidation_manager,account_consolidation.consolidation_user"
14 id="menu_consolidation_checks"/>16 id="menu_consolidation_checks"/>
1517
16 <menuitem18 <menuitem
17 name="Consolidation: Consolidate"19 name="Consolidation: Consolidate"
18 parent="menu_consolidation"20 parent="menu_consolidation"
19 action="action_consolidation_consolidate"21 action="action_consolidation_consolidate"
22 groups="account_consolidation.consolidation_manager,account_consolidation.consolidation_user"
20 id="menu_consolidation_consolidate"/>23 id="menu_consolidation_consolidate"/>
2124
22 </data>25 </data>
2326
=== added file 'account_consolidation/data.xml'
--- account_consolidation/data.xml 1970-01-01 00:00:00 +0000
+++ account_consolidation/data.xml 2014-06-26 13:58:55 +0000
@@ -0,0 +1,13 @@
1<openerp>
2 <data>
3 <record id="consolidation_manager" model="res.groups">
4 <field name="name">Consolidation manager</field>
5 <field name="category_id" ref="base.module_category_accounting_and_finance"/>
6 </record>
7
8 <record id="consolidation_user" model="res.groups">
9 <field name="name">Consolidation user</field>
10 <field name="category_id" ref="base.module_category_accounting_and_finance"/>
11 </record>
12 </data>
13</openerp>
014
=== modified file 'account_consolidation/demo/consolidation_demo.xml'
--- account_consolidation/demo/consolidation_demo.xml 2012-04-18 14:35:42 +0000
+++ account_consolidation/demo/consolidation_demo.xml 2014-06-26 13:58:55 +0000
@@ -183,7 +183,7 @@
183 <field name="company_id" ref="subsidiary_a"/>183 <field name="company_id" ref="subsidiary_a"/>
184 </record>184 </record>
185185
186 <record id="period_b_1" model="account.period">186 <record id="period_b_1" model="account.period">
187 <field eval="'01/'+time.strftime('%Y')" name="code"/>187 <field eval="'01/'+time.strftime('%Y')" name="code"/>
188 <field eval="'01/'+time.strftime('%Y')" name="name"/>188 <field eval="'01/'+time.strftime('%Y')" name="name"/>
189 <field eval="True" name="special"/>189 <field eval="True" name="special"/>
@@ -292,25 +292,23 @@
292 <field name="company_id" ref="subsidiary_b"/>292 <field name="company_id" ref="subsidiary_b"/>
293 </record>293 </record>
294294
295 <record id="account_journal_sale0" model="account.journal">295 <record id="account_journal_sale0" model="account.journal">
296 <field name="code">SALE</field>296 <field name="code">SALE</field>
297 <field name="name">SALE</field>297 <field name="name">SALE</field>
298 <field name="view_id" ref="account.account_sp_journal_view"/>298 <field name="company_id" ref="account_consolidation.subsidiary_a"/>
299 <field name="company_id" ref="account_consolidation.subsidiary_a"/>299 <field name="sequence_id" ref="account.sequence_sale_journal"/>
300 <field name="sequence_id" ref="account.sequence_sale_journal"/>300 <field eval="1" name="allow_date"/>
301 <field eval="1" name="allow_date"/>301 <field name="type">sale</field>
302 <field name="type">sale</field>302 </record>
303 </record>
304303
305 <record id="account_journal_sale1" model="account.journal">304 <record id="account_journal_sale1" model="account.journal">
306 <field name="code">SALE</field>305 <field name="code">SALE</field>
307 <field name="name">SALE</field>306 <field name="name">SALE</field>
308 <field name="view_id" ref="account.account_sp_journal_view"/>307 <field name="company_id" ref="account_consolidation.subsidiary_b"/>
309 <field name="company_id" ref="account_consolidation.subsidiary_b"/>308 <field name="sequence_id" ref="account.sequence_sale_journal"/>
310 <field name="sequence_id" ref="account.sequence_sale_journal"/>309 <field eval="1" name="allow_date"/>
311 <field eval="1" name="allow_date"/>310 <field name="type">sale</field>
312 <field name="type">sale</field>311 </record>
313 </record>
314312
315 </data>313 </data>
316</openerp>314</openerp>
317315
=== added file 'account_consolidation/i18n/account_consolidation.pot'
--- account_consolidation/i18n/account_consolidation.pot 1970-01-01 00:00:00 +0000
+++ account_consolidation/i18n/account_consolidation.pot 2014-06-26 13:58:55 +0000
@@ -0,0 +1,488 @@
1# Translation of OpenERP Server.
2# This file contains the translation of the following modules:
3# * account_consolidation
4#
5msgid ""
6msgstr ""
7"Project-Id-Version: OpenERP Server 7.0\n"
8"Report-Msgid-Bugs-To: \n"
9"POT-Creation-Date: 2013-12-13 09:10+0000\n"
10"PO-Revision-Date: 2013-12-13 09:10+0000\n"
11"Last-Translator: <>\n"
12"Language-Team: \n"
13"MIME-Version: 1.0\n"
14"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Transfer-Encoding: \n"
16"Plural-Forms: \n"
17
18#. module: account_consolidation
19#: help:account.account,consolidation_rate_type_id:0
20msgid "Currency rate type used on this account for the consolidation. Leave empty to use the rate type of the account type."
21msgstr ""
22
23#. module: account_consolidation
24#: help:account.consolidation.consolidate,from_period_id:0
25msgid "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."
26msgstr ""
27
28#. module: account_consolidation
29#: model:ir.model,name:account_consolidation.model_account_consolidation_base
30#: model:ir.model,name:account_consolidation.model_account_consolidation_consolidate
31msgid "Common consolidation wizard. Intended to be inherited"
32msgstr ""
33
34#. module: account_consolidation
35#: field:account.account,consolidation_mode:0
36#: field:account.account.type,consolidation_mode:0
37msgid "Consolidation Mode"
38msgstr ""
39
40#. module: account_consolidation
41#: code:addons/account_consolidation/wizard/consolidation_base.py:375
42#, python-format
43msgid "Invalid periods, please launch the \"Consolidation: Checks\" wizard"
44msgstr ""
45
46#. module: account_consolidation
47#: code:addons/account_consolidation/wizard/consolidation_check.py:67
48#, python-format
49msgid "Invalid charts"
50msgstr ""
51
52#. module: account_consolidation
53#: code:addons/account_consolidation/wizard/consolidation_consolidate.py:434
54#, python-format
55msgid "Consolidation %s"
56msgstr ""
57
58#. module: account_consolidation
59#: view:account.consolidation.check:0
60msgid "Check Chart 2 : For each subsidiary, check consistency between the regular chart of accounts and the consolidation chart."
61msgstr ""
62
63#. module: account_consolidation
64#: code:addons/account_consolidation/wizard/consolidation_check.py:53
65#, python-format
66msgid "Chart of Accounts are OK."
67msgstr ""
68
69#. module: account_consolidation
70#: code:addons/account_consolidation/wizard/consolidation_consolidate.py:261
71#, python-format
72msgid "Consolidation line in %s mode"
73msgstr ""
74
75#. module: account_consolidation
76#: field:account.move,consol_company_id:0
77msgid "Consolidated from Company"
78msgstr ""
79
80#. module: account_consolidation
81#: view:account.move.line:0
82msgid "Period"
83msgstr ""
84
85#. module: account_consolidation
86#: help:account.consolidation.base,fiscalyear_id:0
87#: help:account.consolidation.check,fiscalyear_id:0
88#: help:account.consolidation.consolidate,fiscalyear_id:0
89msgid "The checks will be done on the periods of the selected fiscal year."
90msgstr ""
91
92#. module: account_consolidation
93#: model:ir.model,name:account_consolidation.model_account_account_type
94msgid "Account Type"
95msgstr ""
96
97#. module: account_consolidation
98#: field:account.consolidation.base,holding_chart_account_id:0
99#: field:account.consolidation.check,holding_chart_account_id:0
100#: field:account.consolidation.consolidate,holding_chart_account_id:0
101msgid "Chart of Accounts"
102msgstr ""
103
104#. module: account_consolidation
105#: view:account.consolidation.consolidate:0
106msgid "Run the consolidation for the selected periods and subsidiaries."
107msgstr ""
108
109#. module: account_consolidation
110#: code:addons/account_consolidation/wizard/consolidation_consolidate.py:185
111#, python-format
112msgid "Settings ERROR"
113msgstr ""
114
115#. module: account_consolidation
116#: view:account.consolidation.check:0
117#: view:account.consolidation.consolidate:0
118msgid "or"
119msgstr ""
120
121#. module: account_consolidation
122#: code:addons/account_consolidation/wizard/consolidation_check.py:59
123#: code:addons/account_consolidation/wizard/consolidation_check.py:85
124#: code:addons/account_consolidation/wizard/consolidation_check.py:110
125#, python-format
126msgid "%s :"
127msgstr ""
128
129#. module: account_consolidation
130#: field:account.consolidation.base,subsidiary_ids:0
131#: field:account.consolidation.check,subsidiary_ids:0
132#: field:account.consolidation.consolidate,subsidiary_ids:0
133msgid "Subsidiaries"
134msgstr ""
135
136#. module: account_consolidation
137#: view:account.account.type:0
138msgid "Description"
139msgstr ""
140
141#. module: account_consolidation
142#: code:addons/account_consolidation/wizard/consolidation_base.py:300
143#, python-format
144msgid "Code %s is mapping %s times"
145msgstr ""
146
147#. module: account_consolidation
148#: view:account.consolidation.check:0
149msgid "Check Periods"
150msgstr ""
151
152#. module: account_consolidation
153#: selection:account.account,consolidation_mode:0
154#: selection:account.account.type,consolidation_mode:0
155msgid "Period Movements"
156msgstr ""
157
158#. module: account_consolidation
159#: field:account.consolidation.base,company_id:0
160#: field:account.consolidation.check,company_id:0
161#: field:account.consolidation.consolidate,company_id:0
162msgid "Company"
163msgstr ""
164
165#. module: account_consolidation
166#: view:account.consolidation.check:0
167#: model:ir.actions.act_window,name:account_consolidation.action_consolidation_checks
168#: model:ir.ui.menu,name:account_consolidation.menu_consolidation_checks
169msgid "Consolidation: Checks"
170msgstr ""
171
172#. module: account_consolidation
173#: view:account.account:0
174#: view:account.account.type:0
175#: model:ir.ui.menu,name:account_consolidation.menu_consolidation
176msgid "Consolidation"
177msgstr ""
178
179#. module: account_consolidation
180#: code:addons/account_consolidation/wizard/consolidation_check.py:78
181#, python-format
182msgid "Periods are OK."
183msgstr ""
184
185#. module: account_consolidation
186#: view:account.move.line:0
187#: field:account.move.line,consol_company_id:0
188msgid "Subsidaries"
189msgstr ""
190
191#. module: account_consolidation
192#: code:addons/account_consolidation/wizard/consolidation_consolidate.py:186
193#, python-format
194msgid "Please set the \"Consolidation difference account\" in company %s"
195msgstr ""
196
197#. module: account_consolidation
198#: field:res.company,consolidation_chart_account_id:0
199msgid "Chart of Accounts for Consolidation"
200msgstr ""
201
202#. module: account_consolidation
203#: code:addons/account_consolidation/wizard/consolidation_check.py:90
204#: code:addons/account_consolidation/wizard/consolidation_check.py:115
205#, python-format
206msgid "Invalid periods"
207msgstr ""
208
209#. module: account_consolidation
210#: help:account.consolidation.consolidate,to_period_id:0
211msgid "The consolidation will be done at the very last date of the selected period."
212msgstr ""
213
214#. module: account_consolidation
215#: field:res.company,consolidation_diff_account_id:0
216msgid "Consolidation difference account"
217msgstr ""
218
219#. module: account_consolidation
220#: view:res.company:0
221msgid "Accounts Consolidation"
222msgstr ""
223
224#. module: account_consolidation
225#: view:res.company:0
226msgid "Configuration"
227msgstr ""
228
229#. module: account_consolidation
230#: field:account.consolidation.consolidate,target_move:0
231msgid "Target Moves"
232msgstr ""
233
234#. module: account_consolidation
235#: field:account.consolidation.consolidate,from_period_id:0
236msgid "Start Period"
237msgstr ""
238
239#. module: account_consolidation
240#: model:res.groups,name:account_consolidation.consolidation_manager
241msgid "Consolidation manager"
242msgstr ""
243
244#. module: account_consolidation
245#: help:res.company,consolidation_chart_account_id:0
246msgid "Current company root account to be used when consolidating"
247msgstr ""
248
249#. module: account_consolidation
250#: model:ir.model,name:account_consolidation.model_account_account
251msgid "Account"
252msgstr ""
253
254#. module: account_consolidation
255#: code:addons/account_consolidation/wizard/consolidation_base.py:350
256#, python-format
257msgid "No chart of accounts for company %s"
258msgstr ""
259
260#. module: account_consolidation
261#: view:account.consolidation.check:0
262msgid "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."
263msgstr ""
264
265#. module: account_consolidation
266#: code:addons/account_consolidation/wizard/consolidation_base.py:176
267#, python-format
268msgid "Period from %s to %s not found in holding company %s"
269msgstr ""
270
271#. module: account_consolidation
272#: selection:account.consolidation.consolidate,target_move:0
273msgid "All Posted Entries"
274msgstr ""
275
276#. module: account_consolidation
277#: code:addons/account_consolidation/wizard/consolidation_base.py:162
278#, python-format
279msgid "Holding company has less periods than the subsidiary company %s!"
280msgstr ""
281
282#. module: account_consolidation
283#: model:ir.model,name:account_consolidation.model_res_company
284msgid "Companies"
285msgstr ""
286
287#. module: account_consolidation
288#: field:account.consolidation.consolidate,to_period_id:0
289msgid "End Period"
290msgstr ""
291
292#. module: account_consolidation
293#: model:ir.actions.act_window,help:account_consolidation.action_account_moves_all_a
294msgid "<p class=\"oe_view_nocontent_create\">\n"
295" Select the period and the journal you want to fill.\n"
296" </p><p>\n"
297" This view can be used by accountants in order to quickly record\n"
298" entries in OpenERP. If you want to record a supplier invoice,\n"
299" start by recording the line of the expense account. OpenERP\n"
300" will propose to you automatically the Tax related to this\n"
301" account and the counterpart \"Account Payable\".\n"
302" </p>\n"
303" "
304msgstr ""
305
306#. module: account_consolidation
307#: field:account.consolidation.base,fiscalyear_id:0
308#: field:account.consolidation.check,fiscalyear_id:0
309#: field:account.consolidation.consolidate,fiscalyear_id:0
310msgid "Fiscal Year"
311msgstr ""
312
313#. module: account_consolidation
314#: help:account.account,consolidation_mode:0
315#: help:account.account.type,consolidation_mode:0
316msgid "This must be set on the holding company accounts only"
317msgstr ""
318
319#. module: account_consolidation
320#: code:addons/account_consolidation/wizard/consolidation_check.py:62
321#, python-format
322msgid "Account with code %s does not exist on the Holding company."
323msgstr ""
324
325#. module: account_consolidation
326#: code:addons/account_consolidation/wizard/consolidation_base.py:380
327#, python-format
328msgid "Invalid charts, please launch the \"Consolidation: Checks\" wizard"
329msgstr ""
330
331#. module: account_consolidation
332#: code:addons/account_consolidation/wizard/consolidation_base.py:349
333#: code:addons/account_consolidation/wizard/consolidation_base.py:374
334#: code:addons/account_consolidation/wizard/consolidation_base.py:379
335#, python-format
336msgid "Error"
337msgstr ""
338
339#. module: account_consolidation
340#: view:account.consolidation.check:0
341#: view:account.consolidation.consolidate:0
342msgid "Subsidiaries to Consolidate"
343msgstr ""
344
345#. module: account_consolidation
346#: view:account.consolidation.check:0
347msgid "Check Charts 1"
348msgstr ""
349
350#. module: account_consolidation
351#: selection:account.account,consolidation_mode:0
352#: selection:account.account.type,consolidation_mode:0
353msgid "YTD"
354msgstr ""
355
356#. module: account_consolidation
357#: view:account.consolidation.check:0
358msgid "Check Period : Check consistency of accounting periods between subsidiaries and holding company."
359msgstr ""
360
361#. module: account_consolidation
362#: view:account.consolidation.check:0
363msgid "Check Chart 1 : Check consistency between subsidiaries consolidation chart and Holding company chart."
364msgstr ""
365
366#. module: account_consolidation
367#: field:account.move.line,is_current_company:0
368msgid "Current company"
369msgstr ""
370
371#. module: account_consolidation
372#: code:addons/account_consolidation/wizard/consolidation_consolidate.py:207
373#, python-format
374msgid "Consolidation difference in mode %s"
375msgstr ""
376
377#. module: account_consolidation
378#: view:account.consolidation.consolidate:0
379msgid "Consolidate"
380msgstr ""
381
382#. module: account_consolidation
383#: constraint:account.consolidation.consolidate:0
384msgid "Start Period and End Period must be of the same Fiscal Year !"
385msgstr ""
386
387#. module: account_consolidation
388#: view:account.consolidation.consolidate:0
389#: model:ir.actions.act_window,name:account_consolidation.action_consolidation_consolidate
390#: model:ir.ui.menu,name:account_consolidation.menu_consolidation_consolidate
391msgid "Consolidation: Consolidate"
392msgstr ""
393
394#. module: account_consolidation
395#: model:ir.model,name:account_consolidation.model_account_move
396msgid "Account Entry"
397msgstr ""
398
399#. module: account_consolidation
400#: model:ir.ui.menu,name:account_consolidation.menu_conso_entries
401msgid "Consolidation Entries"
402msgstr ""
403
404#. module: account_consolidation
405#: help:res.company,consolidation_diff_account_id:0
406msgid "Conso. differences will be affected to this account"
407msgstr ""
408
409#. module: account_consolidation
410#: view:account.consolidation.check:0
411msgid "Check Charts 2"
412msgstr ""
413
414#. module: account_consolidation
415#: model:ir.model,name:account_consolidation.model_account_consolidation_check
416msgid "Consolidation Checks. Model used for views"
417msgstr ""
418
419#. module: account_consolidation
420#: code:addons/account_consolidation/wizard/consolidation_base.py:141
421#, python-format
422msgid "The fiscal year of the subsidiary company %s does not exists from %s to %s"
423msgstr ""
424
425#. module: account_consolidation
426#: code:addons/account_consolidation/wizard/consolidation_consolidate.py:504
427#, python-format
428msgid "Consolidated Entries"
429msgstr ""
430
431#. module: account_consolidation
432#: code:addons/account_consolidation/wizard/consolidation_check.py:52
433#: code:addons/account_consolidation/wizard/consolidation_check.py:78
434#: code:addons/account_consolidation/wizard/consolidation_check.py:103
435#, python-format
436msgid "Validation"
437msgstr ""
438
439#. module: account_consolidation
440#: model:res.groups,name:account_consolidation.consolidation_user
441msgid "Consolidation user"
442msgstr ""
443
444#. module: account_consolidation
445#: help:account.account.type,consolidation_rate_type_id:0
446msgid "Currency rate type used on this account type for the consolidation. Leave empty to use the 'spot' rate type."
447msgstr ""
448
449#. module: account_consolidation
450#: view:account.consolidation.consolidate:0
451msgid "Holding Chart of Accounts"
452msgstr ""
453
454#. module: account_consolidation
455#: view:account.consolidation.check:0
456#: view:account.consolidation.consolidate:0
457msgid "Cancel"
458msgstr ""
459
460#. module: account_consolidation
461#: code:addons/account_consolidation/wizard/consolidation_check.py:103
462#, python-format
463msgid "All account is mapped"
464msgstr ""
465
466#. module: account_consolidation
467#: field:account.account,consolidation_rate_type_id:0
468#: field:account.account.type,consolidation_rate_type_id:0
469msgid "Consolidation Currency Rate Type"
470msgstr ""
471
472#. module: account_consolidation
473#: field:account.consolidation.consolidate,journal_id:0
474msgid "Journal"
475msgstr ""
476
477#. module: account_consolidation
478#: selection:account.consolidation.consolidate,target_move:0
479msgid "All Entries"
480msgstr ""
481
482#. module: account_consolidation
483#: model:ir.actions.act_window,name:account_consolidation.action_account_moves_all_a
484#: model:ir.model,name:account_consolidation.model_account_move_line
485#: model:ir.ui.menu,name:account_consolidation.menu_action_account_moves_all
486msgid "Journal Items"
487msgstr ""
488
0489
=== added file 'account_consolidation/i18n/fr.po'
--- account_consolidation/i18n/fr.po 1970-01-01 00:00:00 +0000
+++ account_consolidation/i18n/fr.po 2014-06-26 13:58:55 +0000
@@ -0,0 +1,488 @@
1# Translation of OpenERP Server.
2# This file contains the translation of the following modules:
3# * account_consolidation
4#
5msgid ""
6msgstr ""
7"Project-Id-Version: OpenERP Server 7.0\n"
8"Report-Msgid-Bugs-To: \n"
9"POT-Creation-Date: 2013-12-13 09:10+0000\n"
10"PO-Revision-Date: 2013-12-13 09:10+0000\n"
11"Last-Translator: <>\n"
12"Language-Team: \n"
13"MIME-Version: 1.0\n"
14"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Transfer-Encoding: \n"
16"Plural-Forms: \n"
17
18#. module: account_consolidation
19#: help:account.account,consolidation_rate_type_id:0
20msgid "Currency rate type used on this account for the consolidation. Leave empty to use the rate type of the account type."
21msgstr "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"
22
23#. module: account_consolidation
24#: help:account.consolidation.consolidate,from_period_id:0
25msgid "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."
26msgstr "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'"
27
28#. module: account_consolidation
29#: model:ir.model,name:account_consolidation.model_account_consolidation_base
30#: model:ir.model,name:account_consolidation.model_account_consolidation_consolidate
31msgid "Common consolidation wizard. Intended to be inherited"
32msgstr ""
33
34#. module: account_consolidation
35#: field:account.account,consolidation_mode:0
36#: field:account.account.type,consolidation_mode:0
37msgid "Consolidation Mode"
38msgstr "Mode de consolidation"
39
40#. module: account_consolidation
41#: code:addons/account_consolidation/wizard/consolidation_base.py:375
42#, python-format
43msgid "Invalid periods, please launch the \"Consolidation: Checks\" wizard"
44msgstr "Périodes invalide, SVP lancez le menu \"Consolidation: Contôles\" "
45
46#. module: account_consolidation
47#: code:addons/account_consolidation/wizard/consolidation_check.py:67
48#, python-format
49msgid "Invalid charts"
50msgstr "Plan comptables invalides"
51
52#. module: account_consolidation
53#: code:addons/account_consolidation/wizard/consolidation_consolidate.py:434
54#, python-format
55msgid "Consolidation %s"
56msgstr "Consolidation %s"
57
58#. module: account_consolidation
59#: view:account.consolidation.check:0
60msgid "Check Chart 2 : For each subsidiary, check consistency between the regular chart of accounts and the consolidation chart."
61msgstr "Contrôle Plans Comptables : Pour chaque filiale, vérifie la cohérence entre le plan comptable local et le plan consolidé"
62
63#. module: account_consolidation
64#: code:addons/account_consolidation/wizard/consolidation_check.py:53
65#, python-format
66msgid "Chart of Accounts are OK."
67msgstr "Plans comptables : OK "
68
69#. module: account_consolidation
70#: code:addons/account_consolidation/wizard/consolidation_consolidate.py:261
71#, python-format
72msgid "Consolidation line in %s mode"
73msgstr ""
74
75#. module: account_consolidation
76#: field:account.move,consol_company_id:0
77msgid "Consolidated from Company"
78msgstr "Filiale"
79
80#. module: account_consolidation
81#: view:account.move.line:0
82msgid "Period"
83msgstr "Période"
84
85#. module: account_consolidation
86#: help:account.consolidation.base,fiscalyear_id:0
87#: help:account.consolidation.check,fiscalyear_id:0
88#: help:account.consolidation.consolidate,fiscalyear_id:0
89msgid "The checks will be done on the periods of the selected fiscal year."
90msgstr "Les contrôles seront effectués sur les périodes de l'excercice comptable sélectionné"
91
92#. module: account_consolidation
93#: model:ir.model,name:account_consolidation.model_account_account_type
94msgid "Account Type"
95msgstr "Type de compte"
96
97#. module: account_consolidation
98#: field:account.consolidation.base,holding_chart_account_id:0
99#: field:account.consolidation.check,holding_chart_account_id:0
100#: field:account.consolidation.consolidate,holding_chart_account_id:0
101msgid "Chart of Accounts"
102msgstr "Plan comptable"
103
104#. module: account_consolidation
105#: view:account.consolidation.consolidate:0
106msgid "Run the consolidation for the selected periods and subsidiaries."
107msgstr "Lancer la consolidation sur les périodes et les filiales sélectionnées "
108
109#. module: account_consolidation
110#: code:addons/account_consolidation/wizard/consolidation_consolidate.py:185
111#, python-format
112msgid "Settings ERROR"
113msgstr "Erreur de paramétrage"
114
115#. module: account_consolidation
116#: view:account.consolidation.check:0
117#: view:account.consolidation.consolidate:0
118msgid "or"
119msgstr "ou"
120
121#. module: account_consolidation
122#: code:addons/account_consolidation/wizard/consolidation_check.py:59
123#: code:addons/account_consolidation/wizard/consolidation_check.py:85
124#: code:addons/account_consolidation/wizard/consolidation_check.py:110
125#, python-format
126msgid "%s :"
127msgstr "%s :"
128
129#. module: account_consolidation
130#: field:account.consolidation.base,subsidiary_ids:0
131#: field:account.consolidation.check,subsidiary_ids:0
132#: field:account.consolidation.consolidate,subsidiary_ids:0
133msgid "Subsidiaries"
134msgstr "Filiales"
135
136#. module: account_consolidation
137#: view:account.account.type:0
138msgid "Description"
139msgstr "Description"
140
141#. module: account_consolidation
142#: code:addons/account_consolidation/wizard/consolidation_base.py:300
143#, python-format
144msgid "Code %s is mapping %s times"
145msgstr "Le compte %s est liés à un compte consolidé %s fois"
146
147#. module: account_consolidation
148#: view:account.consolidation.check:0
149msgid "Check Periods"
150msgstr "Contrôle Périodes"
151
152#. module: account_consolidation
153#: selection:account.account,consolidation_mode:0
154#: selection:account.account.type,consolidation_mode:0
155msgid "Period Movements"
156msgstr "Mouvements par période"
157
158#. module: account_consolidation
159#: field:account.consolidation.base,company_id:0
160#: field:account.consolidation.check,company_id:0
161#: field:account.consolidation.consolidate,company_id:0
162msgid "Company"
163msgstr "Société"
164
165#. module: account_consolidation
166#: view:account.consolidation.check:0
167#: model:ir.actions.act_window,name:account_consolidation.action_consolidation_checks
168#: model:ir.ui.menu,name:account_consolidation.menu_consolidation_checks
169msgid "Consolidation: Checks"
170msgstr "Consolidation: Contrôle"
171
172#. module: account_consolidation
173#: view:account.account:0
174#: view:account.account.type:0
175#: model:ir.ui.menu,name:account_consolidation.menu_consolidation
176msgid "Consolidation"
177msgstr "Consolidation"
178
179#. module: account_consolidation
180#: code:addons/account_consolidation/wizard/consolidation_check.py:78
181#, python-format
182msgid "Periods are OK."
183msgstr "Periodes OK."
184
185#. module: account_consolidation
186#: view:account.move.line:0
187#: field:account.move.line,consol_company_id:0
188msgid "Subsidaries"
189msgstr "Filiales"
190
191#. module: account_consolidation
192#: code:addons/account_consolidation/wizard/consolidation_consolidate.py:186
193#, python-format
194msgid "Please set the \"Consolidation difference account\" in company %s"
195msgstr "Veuilez paramétrer le \"Compte d'écart de consolidation\" pour la société %s"
196
197#. module: account_consolidation
198#: field:res.company,consolidation_chart_account_id:0
199msgid "Chart of Accounts for Consolidation"
200msgstr "Plan comptable consolidé"
201
202#. module: account_consolidation
203#: code:addons/account_consolidation/wizard/consolidation_check.py:90
204#: code:addons/account_consolidation/wizard/consolidation_check.py:115
205#, python-format
206msgid "Invalid periods"
207msgstr "Périodes invalides"
208
209#. module: account_consolidation
210#: help:account.consolidation.consolidate,to_period_id:0
211msgid "The consolidation will be done at the very last date of the selected period."
212msgstr "Les écritures de consolidation seront passées le dernier jour de la période sélectionnée"
213
214#. module: account_consolidation
215#: field:res.company,consolidation_diff_account_id:0
216msgid "Consolidation difference account"
217msgstr "Compte d'écart de consolidation"
218
219#. module: account_consolidation
220#: view:res.company:0
221msgid "Accounts Consolidation"
222msgstr "Comptes de consolidation"
223
224#. module: account_consolidation
225#: view:res.company:0
226msgid "Configuration"
227msgstr "Configuration"
228
229#. module: account_consolidation
230#: field:account.consolidation.consolidate,target_move:0
231msgid "Target Moves"
232msgstr "Ecritures cibles"
233
234#. module: account_consolidation
235#: field:account.consolidation.consolidate,from_period_id:0
236msgid "Start Period"
237msgstr "Période de début"
238
239#. module: account_consolidation
240#: model:res.groups,name:account_consolidation.consolidation_manager
241msgid "Consolidation manager"
242msgstr "Responsable"
243
244#. module: account_consolidation
245#: help:res.company,consolidation_chart_account_id:0
246msgid "Current company root account to be used when consolidating"
247msgstr "Plan comptable consolidé de la société"
248
249#. module: account_consolidation
250#: model:ir.model,name:account_consolidation.model_account_account
251msgid "Account"
252msgstr "Compte"
253
254#. module: account_consolidation
255#: code:addons/account_consolidation/wizard/consolidation_base.py:350
256#, python-format
257msgid "No chart of accounts for company %s"
258msgstr "Pas de plan comptable pour la société %s"
259
260#. module: account_consolidation
261#: view:account.consolidation.check:0
262msgid "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."
263msgstr "Contrôle préalables au lancement des écritures de consolidation"
264
265#. module: account_consolidation
266#: code:addons/account_consolidation/wizard/consolidation_base.py:176
267#, python-format
268msgid "Period from %s to %s not found in holding company %s"
269msgstr "Périodes de %s à %s non trouvées dans la société holding"
270
271#. module: account_consolidation
272#: selection:account.consolidation.consolidate,target_move:0
273msgid "All Posted Entries"
274msgstr "Ecritures validées seulement"
275
276#. module: account_consolidation
277#: code:addons/account_consolidation/wizard/consolidation_base.py:162
278#, python-format
279msgid "Holding company has less periods than the subsidiary company %s!"
280msgstr "La holding a moins de périodes comptables créées que la filiale %s"
281
282#. module: account_consolidation
283#: model:ir.model,name:account_consolidation.model_res_company
284msgid "Companies"
285msgstr "Sociétés"
286
287#. module: account_consolidation
288#: field:account.consolidation.consolidate,to_period_id:0
289msgid "End Period"
290msgstr "Période de fin"
291
292#. module: account_consolidation
293#: model:ir.actions.act_window,help:account_consolidation.action_account_moves_all_a
294msgid "<p class=\"oe_view_nocontent_create\">\n"
295" Select the period and the journal you want to fill.\n"
296" </p><p>\n"
297" This view can be used by accountants in order to quickly record\n"
298" entries in OpenERP. If you want to record a supplier invoice,\n"
299" start by recording the line of the expense account. OpenERP\n"
300" will propose to you automatically the Tax related to this\n"
301" account and the counterpart \"Account Payable\".\n"
302" </p>\n"
303" "
304msgstr ""
305
306#. module: account_consolidation
307#: field:account.consolidation.base,fiscalyear_id:0
308#: field:account.consolidation.check,fiscalyear_id:0
309#: field:account.consolidation.consolidate,fiscalyear_id:0
310msgid "Fiscal Year"
311msgstr "Excercice comptable"
312
313#. module: account_consolidation
314#: help:account.account,consolidation_mode:0
315#: help:account.account.type,consolidation_mode:0
316msgid "This must be set on the holding company accounts only"
317msgstr "Ceci doit être paramétré au niveau des comptes de la holding seulement"
318
319#. module: account_consolidation
320#: code:addons/account_consolidation/wizard/consolidation_check.py:62
321#, python-format
322msgid "Account with code %s does not exist on the Holding company."
323msgstr "Le compte %s n'existe pas dans la holding"
324
325#. module: account_consolidation
326#: code:addons/account_consolidation/wizard/consolidation_base.py:380
327#, python-format
328msgid "Invalid charts, please launch the \"Consolidation: Checks\" wizard"
329msgstr "Plans comptables invalides, veuillez lancer le \"Consolidation: Contrôle\" "
330
331#. module: account_consolidation
332#: code:addons/account_consolidation/wizard/consolidation_base.py:349
333#: code:addons/account_consolidation/wizard/consolidation_base.py:374
334#: code:addons/account_consolidation/wizard/consolidation_base.py:379
335#, python-format
336msgid "Error"
337msgstr "Erreur"
338
339#. module: account_consolidation
340#: view:account.consolidation.check:0
341#: view:account.consolidation.consolidate:0
342msgid "Subsidiaries to Consolidate"
343msgstr "Filiales à consolider"
344
345#. module: account_consolidation
346#: view:account.consolidation.check:0
347msgid "Check Charts 1"
348msgstr "Plans comptables Contrôle1"
349
350#. module: account_consolidation
351#: selection:account.account,consolidation_mode:0
352#: selection:account.account.type,consolidation_mode:0
353msgid "YTD"
354msgstr "YTD"
355
356#. module: account_consolidation
357#: view:account.consolidation.check:0
358msgid "Check Period : Check consistency of accounting periods between subsidiaries and holding company."
359msgstr "Contrôle Period : Vérifie la cohérence des périodes comptables entre les filiales et la holding"
360
361#. module: account_consolidation
362#: view:account.consolidation.check:0
363msgid "Check Chart 1 : Check consistency between subsidiaries consolidation chart and Holding company chart."
364msgstr "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"
365
366#. module: account_consolidation
367#: field:account.move.line,is_current_company:0
368msgid "Current company"
369msgstr "Société courante"
370
371#. module: account_consolidation
372#: code:addons/account_consolidation/wizard/consolidation_consolidate.py:207
373#, python-format
374msgid "Consolidation difference in mode %s"
375msgstr "Ecart de consolidation du mode %s "
376
377#. module: account_consolidation
378#: view:account.consolidation.consolidate:0
379msgid "Consolidate"
380msgstr "Consolide"
381
382#. module: account_consolidation
383#: constraint:account.consolidation.consolidate:0
384msgid "Start Period and End Period must be of the same Fiscal Year !"
385msgstr "La période de début et de fin doivent appartenir au même excercice comptable"
386
387#. module: account_consolidation
388#: view:account.consolidation.consolidate:0
389#: model:ir.actions.act_window,name:account_consolidation.action_consolidation_consolidate
390#: model:ir.ui.menu,name:account_consolidation.menu_consolidation_consolidate
391msgid "Consolidation: Consolidate"
392msgstr "Consolidation : Génération des écritures"
393
394#. module: account_consolidation
395#: model:ir.model,name:account_consolidation.model_account_move
396msgid "Account Entry"
397msgstr "Ecriture"
398
399#. module: account_consolidation
400#: model:ir.ui.menu,name:account_consolidation.menu_conso_entries
401msgid "Consolidation Entries"
402msgstr "Ecritures de consolidation"
403
404#. module: account_consolidation
405#: help:res.company,consolidation_diff_account_id:0
406msgid "Conso. differences will be affected to this account"
407msgstr "Les écarts de consolidation seront passés sur ce compte "
408
409#. module: account_consolidation
410#: view:account.consolidation.check:0
411msgid "Check Charts 2"
412msgstr "Plans comptables Contrôle2"
413
414#. module: account_consolidation
415#: model:ir.model,name:account_consolidation.model_account_consolidation_check
416msgid "Consolidation Checks. Model used for views"
417msgstr "Contrôle pré-consolidation. Modèle utilisé pour les vues"
418
419#. module: account_consolidation
420#: code:addons/account_consolidation/wizard/consolidation_base.py:141
421#, python-format
422msgid "The fiscal year of the subsidiary company %s does not exists from %s to %s"
423msgstr "Pas excercice comptable dans la filiale %s pour les périodes de %s à %s."
424
425#. module: account_consolidation
426#: code:addons/account_consolidation/wizard/consolidation_consolidate.py:504
427#, python-format
428msgid "Consolidated Entries"
429msgstr "Ecritures de consolidation"
430
431#. module: account_consolidation
432#: code:addons/account_consolidation/wizard/consolidation_check.py:52
433#: code:addons/account_consolidation/wizard/consolidation_check.py:78
434#: code:addons/account_consolidation/wizard/consolidation_check.py:103
435#, python-format
436msgid "Validation"
437msgstr "Validation"
438
439#. module: account_consolidation
440#: model:res.groups,name:account_consolidation.consolidation_user
441msgid "Consolidation user"
442msgstr "Utilisateur"
443
444#. module: account_consolidation
445#: help:account.account.type,consolidation_rate_type_id:0
446msgid "Currency rate type used on this account type for the consolidation. Leave empty to use the 'spot' rate type."
447msgstr "Type de devise utilisé pour la consolidation de ce type de compte. Laisser vide pour utiliser le taux par défaut "
448
449#. module: account_consolidation
450#: view:account.consolidation.consolidate:0
451msgid "Holding Chart of Accounts"
452msgstr "Plan comptable Holding"
453
454#. module: account_consolidation
455#: view:account.consolidation.check:0
456#: view:account.consolidation.consolidate:0
457msgid "Cancel"
458msgstr "Annuler"
459
460#. module: account_consolidation
461#: code:addons/account_consolidation/wizard/consolidation_check.py:103
462#, python-format
463msgid "All account is mapped"
464msgstr "Tout les comptes sont bien liés à des comptes consolidés"
465
466#. module: account_consolidation
467#: field:account.account,consolidation_rate_type_id:0
468#: field:account.account.type,consolidation_rate_type_id:0
469msgid "Consolidation Currency Rate Type"
470msgstr "Type de taux de devise utilisé pour la consolidation"
471
472#. module: account_consolidation
473#: field:account.consolidation.consolidate,journal_id:0
474msgid "Journal"
475msgstr "Journal"
476
477#. module: account_consolidation
478#: selection:account.consolidation.consolidate,target_move:0
479msgid "All Entries"
480msgstr "Ecritures validées + brouillon"
481
482#. module: account_consolidation
483#: model:ir.actions.act_window,name:account_consolidation.action_account_moves_all_a
484#: model:ir.model,name:account_consolidation.model_account_move_line
485#: model:ir.ui.menu,name:account_consolidation.menu_action_account_moves_all
486msgid "Journal Items"
487msgstr "Ecritures comptables"
488
0489
=== modified file 'account_consolidation/test/consolidation_checks.yml'
--- account_consolidation/test/consolidation_checks.yml 2011-08-19 13:08:01 +0000
+++ account_consolidation/test/consolidation_checks.yml 2014-06-26 13:58:55 +0000
@@ -42,7 +42,8 @@
42 raise42 raise
4343
44-44-
45 In order to test the consolidation checks on misconfigured periods, I use the wizard on FY201245 In order to test the consolidation checks on misconfigured periods, I use the wizard on the next year
46 which is misconfigured
46-47-
47 !record {model: account.consolidation.check, id: conso_check_period_1}:48 !record {model: account.consolidation.check, id: conso_check_period_1}:
48 fiscalyear_id: account_fiscalyear_fy049 fiscalyear_id: account_fiscalyear_fy0
@@ -79,8 +80,8 @@
79 name: Virtual Account Spare80 name: Virtual Account Spare
80 parent_id: account_consolidation.virtual_chart_subsidiary_a81 parent_id: account_consolidation.virtual_chart_subsidiary_a
81 type: consolidation82 type: consolidation
82 user_type: account.account_type_expense83 user_type: account.data_account_type_expense
83 84
84-85-
85 In order to test the consolidation checks on misconfigured charts, I use the wizard86 In order to test the consolidation checks on misconfigured charts, I use the wizard
86-87-
8788
=== modified file 'account_consolidation/test/test_data.yml'
--- account_consolidation/test/test_data.yml 2011-08-19 13:08:01 +0000
+++ account_consolidation/test/test_data.yml 2014-06-26 13:58:55 +0000
@@ -3,14 +3,14 @@
3-3-
4 !record {model: account.move, id: account_move_0}:4 !record {model: account.move, id: account_move_0}:
5 company_id: subsidiary_b5 company_id: subsidiary_b
6 date: '2011-01-02'6 date: !eval "'%s-01-02' % datetime.now().year"
7 journal_id: account_journal_sale17 journal_id: account_journal_sale1
8 line_id:8 line_id:
9 - company_id: subsidiary_b9 - company_id: subsidiary_b
10 account_id: a_sale_b10 account_id: a_sale_b
11 amount_currency: 0.011 amount_currency: 0.0
12 credit: 0.012 credit: 0.0
13 date: '2011-01-01'13 date: !eval "'%s-01-02' % datetime.now().year"
14 debit: 1240.014 debit: 1240.0
15 journal_id: account_journal_sale115 journal_id: account_journal_sale1
16 name: Entry 016 name: Entry 0
@@ -22,7 +22,7 @@
22 account_id: cog_b22 account_id: cog_b
23 amount_currency: 0.023 amount_currency: 0.0
24 credit: 1240.024 credit: 1240.0
25 date: '2011-01-01'25 date: !eval "'%s-01-02' % datetime.now().year"
26 debit: 0.026 debit: 0.0
27 journal_id: account_journal_sale127 journal_id: account_journal_sale1
28 name: Entry 028 name: Entry 0
@@ -40,14 +40,14 @@
40-40-
41 !record {model: account.move, id: account_move_1}:41 !record {model: account.move, id: account_move_1}:
42 company_id: account_consolidation.subsidiary_a42 company_id: account_consolidation.subsidiary_a
43 date: '2011-01-20'43 date: !eval "'%s-01-20' % datetime.now().year"
44 journal_id: account_journal_sale044 journal_id: account_journal_sale0
45 line_id:45 line_id:
46 - account_id: account_consolidation.a_sale_a46 - account_id: account_consolidation.a_sale_a
47 amount_currency: 0.047 amount_currency: 0.0
48 company_id: account_consolidation.subsidiary_a48 company_id: account_consolidation.subsidiary_a
49 credit: 0.049 credit: 0.0
50 date: '2011-01-20'50 date: !eval "'%s-01-20' % datetime.now().year"
51 debit: 40.051 debit: 40.0
52 journal_id: account_journal_sale052 journal_id: account_journal_sale0
53 name: Entry 153 name: Entry 1
@@ -59,7 +59,7 @@
59 amount_currency: 0.059 amount_currency: 0.0
60 company_id: account_consolidation.subsidiary_a60 company_id: account_consolidation.subsidiary_a
61 credit: 40.061 credit: 40.0
62 date: '2011-01-20'62 date: !eval "'%s-01-20' % datetime.now().year"
63 debit: 0.063 debit: 0.0
64 journal_id: account_journal_sale064 journal_id: account_journal_sale0
65 name: Entry 165 name: Entry 1
@@ -77,14 +77,14 @@
77-77-
78 !record {model: account.move, id: account_move_2}:78 !record {model: account.move, id: account_move_2}:
79 company_id: account_consolidation.subsidiary_a79 company_id: account_consolidation.subsidiary_a
80 date: '2011-02-23'80 date: !eval "'%s-02-23' % datetime.now().year"
81 journal_id: account_journal_sale081 journal_id: account_journal_sale0
82 line_id:82 line_id:
83 - account_id: account_consolidation.a_sale_a83 - account_id: account_consolidation.a_sale_a
84 amount_currency: 0.084 amount_currency: 0.0
85 company_id: account_consolidation.subsidiary_a85 company_id: account_consolidation.subsidiary_a
86 credit: 0.086 credit: 0.0
87 date: '2011-02-01'87 date: !eval "'%s-02-23' % datetime.now().year"
88 debit: 200.088 debit: 200.0
89 journal_id: account_journal_sale089 journal_id: account_journal_sale0
90 name: Entry 290 name: Entry 2
@@ -96,7 +96,7 @@
96 amount_currency: 0.096 amount_currency: 0.0
97 company_id: account_consolidation.subsidiary_a97 company_id: account_consolidation.subsidiary_a
98 credit: 200.098 credit: 200.0
99 date: '2011-02-01'99 date: !eval "'%s-02-23' % datetime.now().year"
100 debit: 0.0100 debit: 0.0
101 journal_id: account_journal_sale0101 journal_id: account_journal_sale0
102 name: Entry 2102 name: Entry 2
@@ -114,14 +114,14 @@
114-114-
115 !record {model: account.move, id: account_move_3}:115 !record {model: account.move, id: account_move_3}:
116 company_id: account_consolidation.subsidiary_a116 company_id: account_consolidation.subsidiary_a
117 date: '2011-01-15'117 date: !eval "'%s-01-15' % datetime.now().year"
118 journal_id: account_journal_sale0118 journal_id: account_journal_sale0
119 line_id:119 line_id:
120 - account_id: account_consolidation.cog_a120 - account_id: account_consolidation.cog_a
121 amount_currency: 0.0121 amount_currency: 0.0
122 company_id: account_consolidation.subsidiary_a122 company_id: account_consolidation.subsidiary_a
123 credit: 300.0123 credit: 300.0
124 date: '2011-01-01'124 date: !eval "'%s-01-15' % datetime.now().year"
125 debit: 0.0125 debit: 0.0
126 journal_id: account_journal_sale0126 journal_id: account_journal_sale0
127 name: Entry 3127 name: Entry 3
@@ -133,7 +133,7 @@
133 amount_currency: 0.0133 amount_currency: 0.0
134 company_id: account_consolidation.subsidiary_a134 company_id: account_consolidation.subsidiary_a
135 credit: 0.0135 credit: 0.0
136 date: '2011-01-01'136 date: !eval "'%s-01-15' % datetime.now().year"
137 debit: 300.0137 debit: 300.0
138 journal_id: account_journal_sale0138 journal_id: account_journal_sale0
139 name: Entry 3139 name: Entry 3
@@ -150,94 +150,94 @@
150 Creating a account.fiscalyear record with a missing period for january150 Creating a account.fiscalyear record with a missing period for january
151-151-
152 !record {model: account.fiscalyear, id: account_fiscalyear_fy0}:152 !record {model: account.fiscalyear, id: account_fiscalyear_fy0}:
153 code: FY2012153 code: !eval "'FY%s' % (datetime.now().year + 1)"
154 company_id: base.main_company154 company_id: base.main_company
155 date_start: '2012-01-01'155 date_start: !eval "'%s-01-01' % (datetime.now().year + 1)"
156 date_stop: '2012-12-31'156 date_stop: !eval "'%s-12-31' % (datetime.now().year + 1)"
157 name: FY2012157 name: !eval "'FY%s' % (datetime.now().year + 1)"
158 period_ids:158 period_ids:
159 - code: 00/2012159 - code: !eval "'00/%s' % (datetime.now().year + 1)"
160 company_id: base.main_company160 company_id: base.main_company
161 date_start: '2012-01-01'161 date_start: !eval "'%s-01-01' % (datetime.now().year + 1)"
162 date_stop: '2012-01-01'162 date_stop: !eval "'%s-01-01' % (datetime.now().year + 1)"
163 name: Opening Period163 name: Opening Period
164 special: true164 special: true
165 - code: 01/2012165 - code: !eval "'01/%s' % (datetime.now().year + 1)"
166 company_id: base.main_company166 company_id: base.main_company
167 date_start: '2012-01-01'167 date_start: !eval "'%s-01-01' % (datetime.now().year + 1)"
168 date_stop: '2012-01-31'168 date_stop: !eval "'%s-01-31' % (datetime.now().year + 1)"
169 name: 01/2012169 name: !eval "'01/%s' % (datetime.now().year + 1)"
170 - code: 02/2012170 - code: !eval "'02/%s' % (datetime.now().year + 1)"
171 company_id: base.main_company171 company_id: base.main_company
172 date_start: '2012-02-01'172 date_start: !eval "'%s-02-01' % (datetime.now().year + 1)"
173 date_stop: '2012-02-29'173 date_stop: !eval "'%s-02-%s' % ((datetime.now().year + 1), (datetime((datetime.now().year + 1), 3, 1) - timedelta(days=1)).day)"
174 name: 02/2012174 name: !eval "'02/%s' % (datetime.now().year + 1)"
175 - code: 03/2012175 - code: !eval "'03/%s' % (datetime.now().year + 1)"
176 company_id: base.main_company176 company_id: base.main_company
177 date_start: '2012-03-01'177 date_start: !eval "'%s-03-01' % (datetime.now().year + 1)"
178 date_stop: '2012-03-31'178 date_stop: !eval "'%s-03-31' % (datetime.now().year + 1)"
179 name: 03/2012179 name: !eval "'03/%s' % (datetime.now().year + 1)"
180 - code: 04/2012180 - code: !eval "'04/%s' % (datetime.now().year + 1)"
181 company_id: base.main_company181 company_id: base.main_company
182 date_start: '2012-04-01'182 date_start: !eval "'%s-04-01' % (datetime.now().year + 1)"
183 date_stop: '2012-04-30'183 date_stop: !eval "'%s-04-30' % (datetime.now().year + 1)"
184 name: 04/2012184 name: !eval "'04/%s' % (datetime.now().year + 1)"
185 - code: 05/2012185 - code: !eval "'05/%s' % (datetime.now().year + 1)"
186 company_id: base.main_company186 company_id: base.main_company
187 date_start: '2012-05-01'187 date_start: !eval "'%s-05-01' % (datetime.now().year + 1)"
188 date_stop: '2012-05-31'188 date_stop: !eval "'%s-05-31' % (datetime.now().year + 1)"
189 name: 05/2012189 name: !eval "'05/%s' % (datetime.now().year + 1)"
190 - code: 06/2012190 - code: !eval "'06/%s' % (datetime.now().year + 1)"
191 company_id: base.main_company191 company_id: base.main_company
192 date_start: '2012-06-01'192 date_start: !eval "'%s-06-01' % (datetime.now().year + 1)"
193 date_stop: '2012-06-30'193 date_stop: !eval "'%s-06-30' % (datetime.now().year + 1)"
194 name: 06/2012194 name: !eval "'06/%s' % (datetime.now().year + 1)"
195 - code: 07/2012195 - code: !eval "'07/%s' % (datetime.now().year + 1)"
196 company_id: base.main_company196 company_id: base.main_company
197 date_start: '2012-07-01'197 date_start: !eval "'%s-07-01' % (datetime.now().year + 1)"
198 date_stop: '2012-07-31'198 date_stop: !eval "'%s-07-31' % (datetime.now().year + 1)"
199 name: 07/2012199 name: !eval "'07/%s' % (datetime.now().year + 1)"
200 - code: 08/2012200 - code: !eval "'08/%s' % (datetime.now().year + 1)"
201 company_id: base.main_company201 company_id: base.main_company
202 date_start: '2012-08-01'202 date_start: !eval "'%s-08-01' % (datetime.now().year + 1)"
203 date_stop: '2012-08-31'203 date_stop: !eval "'%s-08-31' % (datetime.now().year + 1)"
204 name: 08/2012204 name: !eval "'08/%s' % (datetime.now().year + 1)"
205 - code: 09/2012205 - code: !eval "'09/%s' % (datetime.now().year + 1)"
206 company_id: base.main_company206 company_id: base.main_company
207 date_start: '2012-09-01'207 date_start: !eval "'%s-09-01' % (datetime.now().year + 1)"
208 date_stop: '2012-09-30'208 date_stop: !eval "'%s-09-30' % (datetime.now().year + 1)"
209 name: 09/2012209 name: !eval "'09/%s' % (datetime.now().year + 1)"
210 - code: 10/2012210 - code: !eval "'10/%s' % (datetime.now().year + 1)"
211 company_id: base.main_company211 company_id: base.main_company
212 date_start: '2012-10-01'212 date_start: !eval "'%s-10-01' % (datetime.now().year + 1)"
213 date_stop: '2012-10-31'213 date_stop: !eval "'%s-10-31' % (datetime.now().year + 1)"
214 name: 10/2012214 name: !eval "'10/%s' % (datetime.now().year + 1)"
215 - code: 11/2012215 - code: !eval "'11/%s' % (datetime.now().year + 1)"
216 company_id: base.main_company216 company_id: base.main_company
217 date_start: '2012-11-01'217 date_start: !eval "'%s-11-01' % (datetime.now().year + 1)"
218 date_stop: '2012-11-30'218 date_stop: !eval "'%s-11-30' % (datetime.now().year + 1)"
219 name: 11/2012219 name: !eval "'11/%s' % (datetime.now().year + 1)"
220 - code: 12/2012220 - code: !eval "'12/%s' % (datetime.now().year + 1)"
221 company_id: base.main_company221 company_id: base.main_company
222 date_start: '2012-12-01'222 date_start: !eval "'%s-12-01' % (datetime.now().year + 1)"
223 date_stop: '2012-12-31'223 date_stop: !eval "'%s-12-31' % (datetime.now().year + 1)"
224 name: 12/2012224 name: !eval "'12/%s' % (datetime.now().year + 1)"
225225
226226
227-227-
228 Creating a account.fiscalyear record with a period in december but with different dates than the holding228 Creating a account.fiscalyear record with a period in december but with different dates than the holding
229-229-
230 !record {model: account.fiscalyear, id: account_fiscalyear_fy1}:230 !record {model: account.fiscalyear, id: account_fiscalyear_fy1}:
231 code: FY2012231 code: !eval "'FY%s' % (datetime.now().year + 1)"
232 company_id: account_consolidation.subsidiary_b232 company_id: account_consolidation.subsidiary_b
233 date_start: '2012-01-01'233 date_start: !eval "'%s-01-01' % (datetime.now().year + 1)"
234 date_stop: '2012-12-31'234 date_stop: !eval "'%s-12-31' % (datetime.now().year + 1)"
235 name: FY2012235 name: !eval "'FY%s' % (datetime.now().year + 1)"
236 period_ids:236 period_ids:
237 - code: diff_dates237 - code: diff_dates
238 company_id: account_consolidation.subsidiary_b238 company_id: account_consolidation.subsidiary_b
239 date_start: '2012-12-15'239 date_start: !eval "'%s-12-15' % (datetime.now().year + 1)"
240 date_stop: '2012-12-31'240 date_stop: !eval "'%s-12-31' % (datetime.now().year + 1)"
241 name: diff_dates241 name: diff_dates
242242
243243
@@ -245,70 +245,70 @@
245 Creating a account.fiscalyear record on subsidiary with a period for january (missing on holding)245 Creating a account.fiscalyear record on subsidiary with a period for january (missing on holding)
246-246-
247 !record {model: account.fiscalyear, id: account_fiscalyear_fy2}:247 !record {model: account.fiscalyear, id: account_fiscalyear_fy2}:
248 code: FY2012248 code: !eval "'FY%s' % (datetime.now().year + 1)"
249 company_id: account_consolidation.subsidiary_a249 company_id: account_consolidation.subsidiary_a
250 date_start: '2012-01-01'250 date_start: !eval "'%s-01-01' % (datetime.now().year + 1)"
251 date_stop: '2012-12-31'251 date_stop: !eval "'%s-12-31' % (datetime.now().year + 1)"
252 name: FY2012252 name: !eval "'FY%s' % (datetime.now().year + 1)"
253 period_ids:253 period_ids:
254 - code: 00/2012254 - code: !eval "'00/%s' % (datetime.now().year + 1)"
255 company_id: account_consolidation.subsidiary_a255 company_id: account_consolidation.subsidiary_a
256 date_start: '2012-01-01'256 date_start: !eval "'%s-01-01' % (datetime.now().year + 1)"
257 date_stop: '2012-01-01'257 date_stop: !eval "'%s-01-01' % (datetime.now().year + 1)"
258 name: Opening Period258 name: Opening Period
259 special: true259 special: true
260 - code: 01/2012260 - code: !eval "'01/%s' % (datetime.now().year + 1)"
261 company_id: account_consolidation.subsidiary_a261 company_id: account_consolidation.subsidiary_a
262 date_start: '2012-01-01'262 date_start: !eval "'%s-01-01' % (datetime.now().year + 1)"
263 date_stop: '2012-01-31'263 date_stop: !eval "'%s-01-31' % (datetime.now().year + 1)"
264 name: 01/2012264 name: !eval "'01/%s' % (datetime.now().year + 1)"
265 - code: 02/2012265 - code: !eval "'02/%s' % (datetime.now().year + 1)"
266 company_id: account_consolidation.subsidiary_a266 company_id: account_consolidation.subsidiary_a
267 date_start: '2012-02-01'267 date_start: !eval "'%s-02-01' % (datetime.now().year + 1)"
268 date_stop: '2012-02-29'268 date_stop: !eval "'%s-02-%s' % ((datetime.now().year + 1), (datetime((datetime.now().year + 1), 3, 1) - timedelta(days=1)).day)"
269 name: 02/2012269 name: !eval "'02/%s' % (datetime.now().year + 1)"
270 - code: 03/2012270 - code: !eval "'03/%s' % (datetime.now().year + 1)"
271 company_id: account_consolidation.subsidiary_a271 company_id: account_consolidation.subsidiary_a
272 date_start: '2012-03-01'272 date_start: !eval "'%s-03-01' % (datetime.now().year + 1)"
273 date_stop: '2012-03-31'273 date_stop: !eval "'%s-03-31' % (datetime.now().year + 1)"
274 name: 03/2012274 name: !eval "'03/%s' % (datetime.now().year + 1)"
275 - code: 04/2012275 - code: !eval "'04/%s' % (datetime.now().year + 1)"
276 company_id: account_consolidation.subsidiary_a276 company_id: account_consolidation.subsidiary_a
277 date_start: '2012-04-01'277 date_start: !eval "'%s-04-01' % (datetime.now().year + 1)"
278 date_stop: '2012-04-30'278 date_stop: !eval "'%s-04-30' % (datetime.now().year + 1)"
279 name: 04/2012279 name: !eval "'04/%s' % (datetime.now().year + 1)"
280 - code: 05/2012280 - code: !eval "'05/%s' % (datetime.now().year + 1)"
281 company_id: account_consolidation.subsidiary_a281 company_id: account_consolidation.subsidiary_a
282 date_start: '2012-05-01'282 date_start: !eval "'%s-05-01' % (datetime.now().year + 1)"
283 date_stop: '2012-05-31'283 date_stop: !eval "'%s-05-31' % (datetime.now().year + 1)"
284 name: 05/2012284 name: !eval "'05/%s' % (datetime.now().year + 1)"
285 - code: 06/2012285 - code: !eval "'06/%s' % (datetime.now().year + 1)"
286 company_id: account_consolidation.subsidiary_a286 company_id: account_consolidation.subsidiary_a
287 date_start: '2012-06-01'287 date_start: !eval "'%s-06-01' % (datetime.now().year + 1)"
288 date_stop: '2012-06-30'288 date_stop: !eval "'%s-06-30' % (datetime.now().year + 1)"
289 name: 06/2012289 name: !eval "'06/%s' % (datetime.now().year + 1)"
290 - code: 08/2012290 - code: !eval "'08/%s' % (datetime.now().year + 1)"
291 company_id: account_consolidation.subsidiary_a291 company_id: account_consolidation.subsidiary_a
292 date_start: '2012-08-01'292 date_start: !eval "'%s-08-01' % (datetime.now().year + 1)"
293 date_stop: '2012-08-31'293 date_stop: !eval "'%s-08-31' % (datetime.now().year + 1)"
294 name: 08/2012294 name: !eval "'08/%s' % (datetime.now().year + 1)"
295 - code: 09/2012295 - code: !eval "'09/%s' % (datetime.now().year + 1)"
296 company_id: account_consolidation.subsidiary_a296 company_id: account_consolidation.subsidiary_a
297 date_start: '2012-09-01'297 date_start: !eval "'%s-09-01' % (datetime.now().year + 1)"
298 date_stop: '2012-09-30'298 date_stop: !eval "'%s-09-30' % (datetime.now().year + 1)"
299 name: 09/2012299 name: !eval "'09/%s' % (datetime.now().year + 1)"
300 - code: 10/2012300 - code: !eval "'10/%s' % (datetime.now().year + 1)"
301 company_id: account_consolidation.subsidiary_a301 company_id: account_consolidation.subsidiary_a
302 date_start: '2012-10-01'302 date_start: !eval "'%s-10-01' % (datetime.now().year + 1)"
303 date_stop: '2012-10-31'303 date_stop: !eval "'%s-10-31' % (datetime.now().year + 1)"
304 name: 10/2012304 name: !eval "'10/%s' % (datetime.now().year + 1)"
305 - code: 11/2012305 - code: !eval "'11/%s' % (datetime.now().year + 1)"
306 company_id: account_consolidation.subsidiary_a306 company_id: account_consolidation.subsidiary_a
307 date_start: '2012-11-01'307 date_start: !eval "'%s-11-01' % (datetime.now().year + 1)"
308 date_stop: '2012-11-30'308 date_stop: !eval "'%s-11-30' % (datetime.now().year + 1)"
309 name: 11/2012309 name: !eval "'11/%s' % (datetime.now().year + 1)"
310 - code: 12/2012310 - code: !eval "'12/%s' % (datetime.now().year + 1)"
311 company_id: account_consolidation.subsidiary_a311 company_id: account_consolidation.subsidiary_a
312 date_start: '2012-12-01'312 date_start: !eval "'%s-12-01' % (datetime.now().year + 1)"
313 date_stop: '2012-12-31'313 date_stop: !eval "'%s-12-31' % (datetime.now().year + 1)"
314 name: 12/2012314 name: !eval "'12/%s' % (datetime.now().year + 1)"
315315
=== modified file 'account_consolidation/wizard/consolidation_base.py'
--- account_consolidation/wizard/consolidation_base.py 2012-04-18 14:35:42 +0000
+++ account_consolidation/wizard/consolidation_base.py 2014-06-26 13:58:55 +0000
@@ -1,75 +1,76 @@
1# -*- coding: utf-8 -*-1# -*- coding: utf-8 -*-
2##############################################################################2##############################################################################
3#3#
4# Copyright (c) 2011 Camptocamp SA (http://www.camptocamp.com)4# Author: Guewen Baconnier
5#5# Copyright 2011-2013 Camptocamp SA
6# Author : Guewen Baconnier (Camptocamp)6#
7#7# This program is free software: you can redistribute it and/or modify
8# WARNING: This program as such is intended to be used by professional8# it under the terms of the GNU Affero General Public License as
9# programmers who take the whole responsability of assessing all potential9# published by the Free Software Foundation, either version 3 of the
10# consequences resulting from its eventual inadequacies and bugs10# License, or (at your option) any later version.
11# End users who are looking for a ready-to-use solution with commercial11#
12# garantees and support are strongly adviced to contract a Free Software12# This program is distributed in the hope that it will be useful,
13# Service Company13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14#14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# This program is Free Software; you can redistribute it and/or15# GNU Affero General Public License for more details.
16# modify it under the terms of the GNU General Public License16#
17# as published by the Free Software Foundation; either version 217# You should have received a copy of the GNU Affero General Public License
18# of the License, or (at your option) any later version.18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20# This program is distributed in the hope that it will be useful,
21# but WITHOUT ANY WARRANTY; without even the implied warranty of
22# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23# GNU General Public License for more details.
24#
25# You should have received a copy of the GNU General Public License
26# along with this program; if not, write to the Free Software
27# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28#19#
29##############################################################################20##############################################################################
3021
31from osv import osv, fields22from openerp.osv import osv, orm, fields
32from tools.translate import _23from openerp.tools.translate import _
3324
3425
35class account_consolidation_base(osv.osv_memory):26class account_consolidation_base(orm.AbstractModel):
36 _name = 'account.consolidation.base'27 _name = 'account.consolidation.base'
37 _description = 'Common consolidation wizard. Intended to be inherited'28 _description = 'Common consolidation wizard. Intended to be inherited'
3829
39 def _default_company(self, cr, uid, context=None):30 def _default_company(self, cr, uid, context=None):
40 user = self.pool.get('res.users').browse(cr, uid, uid, context=context)31 comp_obj = self.pool['res.company']
41 if user.company_id:32 return comp_obj._company_default_get(cr, uid)
42 return user.company_id.id33
43 return self.pool.get('res.company').search(cr, uid, [('parent_id', '=', False)])[0]34 def _default_chart(self, cr, uid, context=None):
35 comp_obj = self.pool['res.company']
36 comp_id = comp_obj._company_default_get(cr, uid)
37 company = comp_obj.browse(cr, uid, comp_id)
38 return company.consolidation_chart_account_id.id
4439
45 _columns = {40 _columns = {
46 'fiscalyear_id': fields.many2one('account.fiscalyear', 'Fiscal Year', required=True,41 'fiscalyear_id': fields.many2one(
47 help="The checks will be done on the periods of the selected fiscal year."),42 'account.fiscalyear',
48 'company_id': fields.many2one('res.company', 'Company', required=True),43 'Fiscal Year',
49 'holding_chart_account_id': fields.many2one('account.account',44 required=True,
50 'Chart of Accounts',45 help="The checks will be done on the periods of "
51 required=True,46 "the selected fiscal year."),
52 domain=[('parent_id', '=', False)]),47 'company_id': fields.many2one(
53 'subsidiary_ids': fields.many2many('res.company', 'account_conso_comp_rel', 'conso_id', 'company_id',48 'res.company', 'Company', required=True),
54 'Subsidiaries', required=True)49 'holding_chart_account_id': fields.many2one(
50 'account.account',
51 'Chart of Accounts',
52 required=True,
53 domain=[('parent_id', '=', False)]),
54 'subsidiary_ids': fields.many2many(
55 'res.company',
56 'account_conso_comp_rel',
57 'conso_id',
58 'company_id',
59 'Subsidiaries',
60 required=True)
55 }61 }
5662
57 _defaults = {63 _defaults = {'company_id': _default_company,
58 'company_id': _default_company,64 'holding_chart_account_id': _default_chart,
59 }65 }
6066
61 def on_change_company_id(self, cr, uid, ids, company_id, context=None):67 def on_change_company_id(self, cr, uid, ids, company_id, context=None):
62 """68 """
63 On change of the company, set the chart of account and the subsidiaries69 On change of the company, set the chart of account and the subsidiaries
6470
65 @param self: The object pointer71 :param company_id: ID of the selected company
66 @param cr: the current row, from the database cursor,
67 @param uid: the current user’s ID for security checks,
68 @param ids: List of the wizard IDs (commonly the first element is the current ID)
69 @param company_id: ID of the selected company
70 @param context: A standard dictionary for contextual values
7172
72 @return: dict of values to change73 :return: dict of values to change
73 """74 """
74 company_obj = self.pool.get('res.company')75 company_obj = self.pool.get('res.company')
7576
@@ -82,21 +83,27 @@
8283
83 return {'value': result}84 return {'value': result}
8485
85 def check_subsidiary_periods(self, cr, uid, ids, holding_company_id, subs_company_id, fyear_id, context=None):86 def check_subsidiary_periods(self, cr, uid, ids, holding_company_id,
86 """87 subs_company_id, fyear_id, context=None):
87 Check Subsidiary company periods vs Holding company periods and returns a list of errors88 """ Check Subsidiary company periods vs Holding company periods and
88 All the periods defined within the group must be the same (same beginning and ending dates)89 returns a list of errors
8990
90 @param self: The object pointer91 The periods checked are the periods within the fiscal year of the
91 @param cr: the current row, from the database cursor,92 holding, and the periods of the subsidiary company in the same range of
92 @param uid: the current user’s ID for security checks,93 time.
93 @param ids: List of the wizard IDs (commonly the first element is the current ID)94
94 @param holding_company_id: ID of the holding company95 The fiscal year of the subsidiary is deduced from the start/stop date
95 @param subs_company_id: ID of the subsidiary company to check96 of the holding's fiscal year.
96 @param fyear_id: ID of the fiscal years to compare97
97 @param context: A standard dictionary for contextual values98 All the periods defined within the group must have the same beginning
9899 and ending dates to be valid.
99 @return: dict of list with errors for each company {company_id: ['error 1', 'error2']}100
101 :param holding_company_id: ID of the holding company
102 :param subs_company_id: ID of the subsidiary company to check
103 :param fyear_id: ID of the fiscal year of the holding.
104
105 :return: dict of list with errors for each company
106 {company_id: ['error 1', 'error2']}
100 """107 """
101 company_obj = self.pool.get('res.company')108 company_obj = self.pool.get('res.company')
102 period_obj = self.pool.get('account.period')109 period_obj = self.pool.get('account.period')
@@ -108,48 +115,69 @@
108 errors = []115 errors = []
109116
110 # get holding fiscal year and periods117 # get holding fiscal year and periods
111 holding = company_obj.browse(cr, uid, holding_company_id, context=context)118 holding = company_obj.browse(
112 subsidiary = company_obj.browse(cr, uid, subs_company_id, context=context)119 cr, uid, holding_company_id, context=context)
120 subsidiary = company_obj.browse(
121 cr, uid, subs_company_id, context=context)
113122
114 holding_periods_ids = period_obj.search(cr, uid,123 holding_periods_ids = period_obj.search(
124 cr, uid,
115 [('company_id', '=', holding.id),125 [('company_id', '=', holding.id),
116 ('fiscalyear_id', '=', holding_fiscal_year.id)],126 ('fiscalyear_id', '=', holding_fiscal_year.id)],
117 context=context)127 context=context)
118 holding_periods = period_obj.browse(cr, uid, holding_periods_ids, context=context)128 holding_periods = period_obj.browse(
129 cr, uid, holding_periods_ids, context=context)
119130
120 # get subsidiary fiscal year and periods131 # get subsidiary fiscal year and periods
121 subsidiary_fiscal_year = fy_obj.search(cr, uid,132 subsidiary_fiscal_year = fy_obj.search(
133 cr, uid,
122 [('company_id', '=', subsidiary.id),134 [('company_id', '=', subsidiary.id),
123 ('date_start', '=', holding_fiscal_year.date_start),135 ('date_start', '=', holding_fiscal_year.date_start),
124 ('date_stop', '=', holding_fiscal_year.date_stop),136 ('date_stop', '=', holding_fiscal_year.date_stop),
125 ])137 ],
138 context=context)
126 if not subsidiary_fiscal_year:139 if not subsidiary_fiscal_year:
127 errors.append(_('The fiscal year of the subsidiary company %s does not exists from %s to %s')140 errors.append(
128 % (subsidiary.name, holding_fiscal_year.date_start, holding_fiscal_year.date_stop))141 _('The fiscal year of the subsidiary company %s '
142 'does not exists from %s to %s') %
143 (subsidiary.name,
144 holding_fiscal_year.date_start,
145 holding_fiscal_year.date_stop))
129 else:146 else:
130 subsidiary_period_ids = period_obj.search(cr, uid,147 subsidiary_period_ids = period_obj.search(
148 cr, uid,
131 [('company_id', '=', subsidiary.id),149 [('company_id', '=', subsidiary.id),
132 ('fiscalyear_id', '=', subsidiary_fiscal_year[0])], # 0 because there can be only 1 fiscal year on the same dates as the holding150 # 0 because there can be only 1 fiscal year
151 # on the same dates than the holding
152 ('fiscalyear_id', '=', subsidiary_fiscal_year[0])],
133 context=context)153 context=context)
134 subsidiary_periods = period_obj.browse(cr, uid, subsidiary_period_ids, context=context)154 subsidiary_periods = period_obj.browse(
155 cr, uid, subsidiary_period_ids, context=context)
135156
136 # a holding fiscal year may have more periods than a subsidiary (a subsidiary created at the middle of the year for example)157 # a holding fiscal year may have more periods than a subsidiary
158 # (a subsidiary created at the middle of the year for example)
137 # but the reverse situation is not allowed159 # but the reverse situation is not allowed
138 if len(holding_periods) < len(subsidiary_periods):160 if len(holding_periods) < len(subsidiary_periods):
139 errors.append(_('Holding company has less periods than the subsidiary company %s!') % (subsidiary.name,))161 errors.append(
162 _('Holding company has less periods than the '
163 'subsidiary company %s!') % subsidiary.name)
140164
141 # check subsidiary periods dates vs holding periods for each period of the subsidiary165 # check subsidiary periods dates vs holding periods
166 # for each period of the subsidiary
142 for subsidiary_period in subsidiary_periods:167 for subsidiary_period in subsidiary_periods:
143 period_exists = False168 period_exists = False
144 for holding_period in holding_periods:169 for holding_period in holding_periods:
145 if subsidiary_period.date_start == holding_period.date_start \170 if (subsidiary_period.date_start == holding_period.date_start and
146 and subsidiary_period.date_stop == holding_period.date_stop:171 subsidiary_period.date_stop == holding_period.date_stop):
147 period_exists = True172 period_exists = True
148 break173 break
149 if not period_exists:174 if not period_exists:
150 errors.append(_('Period from %s to %s not found in holding company %s')175 errors.append(
151 % (subsidiary_period.date_start, subsidiary_period.date_stop, holding.name))176 _('Period from %s to %s not found '
152177 'in holding company %s') %
178 (subsidiary_period.date_start,
179 subsidiary_period.date_stop,
180 holding.name))
153 return errors181 return errors
154182
155 def check_all_periods(self, cr, uid, ids, context=None):183 def check_all_periods(self, cr, uid, ids, context=None):
@@ -157,24 +185,24 @@
157 Call the period check on each period of all subsidiaries185 Call the period check on each period of all subsidiaries
158 Returns the errors by subsidiary186 Returns the errors by subsidiary
159187
160 @param self: The object pointer188 :return: dict of list with errors for each company
161 @param cr: the current row, from the database cursor,189 {company_id: ['error 1', 'error2']}
162 @param uid: the current user’s ID for security checks,
163 @param ids: List of the wizard IDs (commonly the first element is the current ID)
164 @param context: A standard dictionary for contextual values
165
166 @return: dict of list with errors for each company {company_id: ['error 1', 'error2']}
167 """190 """
191 if isinstance(ids, (int, long)):
192 ids = [ids]
193 assert len(ids) == 1, "only 1 id expected"
194
168 form = self.browse(cr, uid, ids[0], context=context)195 form = self.browse(cr, uid, ids[0], context=context)
169196
170 errors_by_company = {}197 errors_by_company = {}
171 for subsidiary in form.subsidiary_ids:198 for subsidiary in form.subsidiary_ids:
172 errors = \199 errors = self.check_subsidiary_periods(
173 self.check_subsidiary_periods(cr, uid, ids,200 cr, uid,
174 form.company_id.id,201 ids,
175 subsidiary.id,202 form.company_id.id,
176 form.fiscalyear_id.id,203 subsidiary.id,
177 context=context)204 form.fiscalyear_id.id,
205 context=context)
178 if errors:206 if errors:
179 errors_by_company[subsidiary.id] = errors207 errors_by_company[subsidiary.id] = errors
180208
@@ -182,24 +210,23 @@
182210
183 def _chart_accounts_data(self, cr, uid, ids, chart_account_id, context=None):211 def _chart_accounts_data(self, cr, uid, ids, chart_account_id, context=None):
184 """212 """
185 Returns the list of accounts to use for the consolidation for the holding213 Returns the list of accounts to use for the consolidation
186 or the subsidiaries. Keys of the returned dict are the account codes and214 for the holding or the subsidiaries.
187 if the context is holding_coa, dict values are the browse instances of the accounts215 Keys of the returned dict are the account codes and
188216 if the context is holding_coa,
189 @param self: The object pointer217 dict values are the browse instances of the accounts
190 @param cr: the current row, from the database cursor,218
191 @param uid: the current user’s ID for security checks,219 :chart_account_id: ID of the Chart of Account for which
192 @param ids: List of the wizard IDs (commonly the first element is the current ID)220 we want the account codes
193 @chart_account_id: ID of the "Chart" Account for which we want the account codes221
194 @param context: A standard dictionary for contextual values222 :return: dict with {account codes: browse instances}
195
196 @return: dict with {account codes: browse instances}
197 """223 """
198 context = context or {}224 if context is None:
225 context = {}
199 account_obj = self.pool.get('account.account')226 account_obj = self.pool.get('account.account')
200 res = {}227 res = {}
201 account_ids = account_obj.\228 account_ids = account_obj._get_children_and_consol(
202 _get_children_and_consol(cr, uid, chart_account_id, context=context)229 cr, uid, chart_account_id, context=context)
203230
204 # do not consolidate chart root231 # do not consolidate chart root
205 account_ids.remove(chart_account_id)232 account_ids.remove(chart_account_id)
@@ -216,33 +243,92 @@
216 continue243 continue
217244
218 res[account.code] = {}245 res[account.code] = {}
219 # we'll need the browse object during the "consolidate wizard" for the holding246 # we'll need the browse object during the
220 res[account.code] = holding and account or True247 # "consolidate wizard" for the holding
248 res[account.code] = account if holding else True
221249
222 return res250 return res
223251
224 def check_subsidiary_chart(self, cr, uid, ids, holding_chart_account_id, subsidiary_chart_account_id, context=None):252 def check_subsidiary_mapping_account(self, cr, uid, ids, context=None):
225 """253 """ Call the period check on each period of all subsidiaries
226 Check a Holding Chart of Accounts vs a Subsidiary Virtual Chart of Accounts254 Returns the errors by subsidiary
255
256 :return: dict of list with errors for each company
257 {company_id: ['error 1', 'error2']}
258
259 """
260 if isinstance(ids, (int, long)):
261 ids = [ids]
262 assert len(ids) == 1, "only 1 id expected"
263
264 form = self.browse(cr, uid, ids[0], context=context)
265 errors_by_company = {}
266 for subsidiary in form.subsidiary_ids:
267 errors = self._check_subsidiary_mapping_account(
268 cr, uid,
269 ids,
270 subsidiary,
271 context=context)
272 if errors:
273 errors_by_company[subsidiary.id] = errors
274
275 return errors_by_company
276
277 def _check_subsidiary_mapping_account(self, cr, uid, ids,
278 company_id, context=None):
279 if context is None:
280 context = {}
281 errors = []
282 account_obj = self.pool.get('account.account')
283 normal_account_ids = account_obj.search(cr, uid,
284 [('company_id', '=', company_id.id),
285 ('type', 'not in', ['consolidation', 'view'])],
286 context=context)
287 consolidated_account_ids = account_obj.search(
288 cr, uid,
289 [('company_id', '=', company_id.id),
290 ('type', '=', 'consolidation')],
291 context=context)
292 consolidate_child_ids = []
293 for account_id in consolidated_account_ids:
294 child_consol_ids = account_obj._get_children_and_consol(
295 cr, uid, account_id, context=context)
296 consolidate_child_ids = consolidate_child_ids + child_consol_ids
297 for sub_id in normal_account_ids:
298 cpt_occur = consolidate_child_ids.count(sub_id)
299 if cpt_occur == 0 or cpt_occur > 1:
300 ## We read the code of account
301 code = account_obj.read(cr, uid, sub_id, ['code'],
302 context=context)['code']
303 message = _("Code %s is mapping %s times" % (code, cpt_occur))
304 errors.append(message)
305 return errors
306
307 def check_subsidiary_chart(self, cr, uid, ids, holding_chart_account_id,
308 subsidiary_chart_account_id, context=None):
309 """
310 Check a Holding Chart of Accounts vs a Subsidiary Virtual
311 Chart of Accounts
227 All the accounts of the Virtual CoA must exist in the Holding CoA.312 All the accounts of the Virtual CoA must exist in the Holding CoA.
228 The Holding's CoA may hold accounts which do not exist in the Subsidiary's Virtual CoA.313 The Holding's CoA may hold accounts which do not exist
229314 in the Subsidiary's Virtual CoA.
230 @param self: The object pointer315
231 @param cr: the current row, from the database cursor,316 :param holding_chart_account_id: ID of the Chart of Account
232 @param uid: the current user’s ID for security checks,317 of the holding company
233 @param ids: List of the wizard IDs (commonly the first element is the current ID)318 :param subsidiary_chart_account_id: ID of the Chart of Account
234 @param holding_chart_account_id: ID of the "Chart" Account of the holding company319 of the subsidiary company to check
235 @param subsidiary_chart_account_id: ID of the "Chart" Account of the subsidiary company to check320
236 @param context: A standard dictionary for contextual values321 :return: List of accounts existing on subsidiary but no on holding COA
237
238 @return: List of accounts existing on subsidiary but no on holding COA
239 """322 """
240 context = context or {}323 if context is None:
241 holding_ctx = context.copy()324 context = {}
242 holding_ctx.update({'holding_coa': True})325 holding_ctx = dict(context, holding_coa=True)
243 holding_accounts = self._chart_accounts_data(cr, uid, ids, holding_chart_account_id, context=holding_ctx)326 holding_accounts = self._chart_accounts_data(
244 subsidiary_accounts = self._chart_accounts_data(cr, uid, ids, subsidiary_chart_account_id, context=context)327 cr, uid, ids, holding_chart_account_id, context=holding_ctx)
245 # accounts which are configured on the subsidiary VCoA but not on the holding CoA328 subsidiary_accounts = self._chart_accounts_data(
329 cr, uid, ids, subsidiary_chart_account_id, context=context)
330 # accounts which are configured on the subsidiary
331 # Virtual CoA but not on the holding CoA
246 spare_accounts = [code for code332 spare_accounts = [code for code
247 in subsidiary_accounts333 in subsidiary_accounts
248 if code not in holding_accounts]334 if code not in holding_accounts]
@@ -250,26 +336,26 @@
250336
251 def check_account_charts(self, cr, uid, ids, context=None):337 def check_account_charts(self, cr, uid, ids, context=None):
252 """338 """
253 Check the chart of accounts of the holding vs each virtual chart of accounts of the subsidiaries339 Check the chart of accounts of the holding vs
254340 each virtual chart of accounts of the subsidiaries
255 @param self: The object pointer
256 @param cr: the current row, from the database cursor,
257 @param uid: the current user’s ID for security checks,
258 @param ids: List of the wizard IDs (commonly the first element is the current ID)
259 @param context: A standard dictionary for contextual values
260 """341 """
342 if isinstance(ids, (int, long)):
343 ids = [ids]
344 assert len(ids) == 1, "only 1 id expected"
261 form = self.browse(cr, uid, ids[0], context=context)345 form = self.browse(cr, uid, ids[0], context=context)
262346
263 invalid_items_per_company = {}347 invalid_items_per_company = {}
264 for subsidiary in form.subsidiary_ids:348 for subsidiary in form.subsidiary_ids:
265 if not subsidiary.consolidation_chart_account_id:349 if not subsidiary.consolidation_chart_account_id:
266 raise osv.except_osv(_('Error'), _('No chart of accounts for company %s') % (subsidiary,))350 raise osv.except_osv(
267351 _('Error'),
268 invalid_items = \352 _('No chart of accounts for company %s') % subsidiary.name)
269 self.check_subsidiary_chart(cr, uid, ids,353 invalid_items = self.check_subsidiary_chart(
270 form.holding_chart_account_id.id,354 cr, uid,
271 subsidiary.consolidation_chart_account_id.id,355 ids,
272 context=context)356 form.holding_chart_account_id.id,
357 subsidiary.consolidation_chart_account_id.id,
358 context=context)
273 if any(invalid_items):359 if any(invalid_items):
274 invalid_items_per_company[subsidiary.id] = invalid_items360 invalid_items_per_company[subsidiary.id] = invalid_items
275361
@@ -278,25 +364,24 @@
278 def run_consolidation(self, cr, uid, ids, context=None):364 def run_consolidation(self, cr, uid, ids, context=None):
279 """365 """
280 Proceed with all checks before launch any consolidation step366 Proceed with all checks before launch any consolidation step
281 This is a base method intended to be inherited with the next consolidation steps367 This is a base method intended to be inherited with the next
282368 consolidation steps
283 @param self: The object pointer
284 @param cr: the current row, from the database cursor,
285 @param uid: the current user’s ID for security checks,
286 @param ids: List of the wizard IDs (commonly the first element is the current ID)
287 @param context: A standard dictionary for contextual values
288 """369 """
370 if isinstance(ids, (int, long)):
371 ids = [ids]
372 assert len(ids) == 1, "only 1 id expected"
289373
290 if self.check_all_periods(cr, uid, ids, context=context):374 if self.check_all_periods(cr, uid, ids, context=context):
291 raise osv.except_osv(_('Error'),375 raise osv.except_osv(
292 _('Invalid periods, please launch the "Consolidation: Checks" wizard'))376 _('Error'),
377 _('Invalid periods, please launch the '
378 '"Consolidation: Checks" wizard'))
293 if self.check_account_charts(cr, uid, ids, context=context):379 if self.check_account_charts(cr, uid, ids, context=context):
294 raise osv.except_osv(_('Error'),380 raise osv.except_osv(
295 _('Invalid charts, please launch the "Consolidation: Checks" wizard'))381 _('Error'),
382 _('Invalid charts, please launch the '
383 '"Consolidation: Checks" wizard'))
296384
297 # inherit to add the next steps of the reconciliation385 # inherit to add the next steps of the reconciliation
298386
299 return {'type': 'ir.actions.act_window_close'}387 return {'type': 'ir.actions.act_window_close'}
300
301
302account_consolidation_base()
303388
=== modified file 'account_consolidation/wizard/consolidation_check.py'
--- account_consolidation/wizard/consolidation_check.py 2012-04-18 14:35:42 +0000
+++ account_consolidation/wizard/consolidation_check.py 2014-06-26 13:58:55 +0000
@@ -1,109 +1,116 @@
1# -*- coding: utf-8 -*-1# -*- coding: utf-8 -*-
2##############################################################################2##############################################################################
3#3#
4# Copyright (c) 2011 Camptocamp SA (http://www.camptocamp.com)4# Author: Guewen Baconnier
5#5# Copyright 2011-2013 Camptocamp SA
6# Author : Guewen Baconnier (Camptocamp)6#
7#7# This program is free software: you can redistribute it and/or modify
8# WARNING: This program as such is intended to be used by professional8# it under the terms of the GNU Affero General Public License as
9# programmers who take the whole responsability of assessing all potential9# published by the Free Software Foundation, either version 3 of the
10# consequences resulting from its eventual inadequacies and bugs10# License, or (at your option) any later version.
11# End users who are looking for a ready-to-use solution with commercial11#
12# garantees and support are strongly adviced to contract a Free Software12# This program is distributed in the hope that it will be useful,
13# Service Company13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14#14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# This program is Free Software; you can redistribute it and/or15# GNU Affero General Public License for more details.
16# modify it under the terms of the GNU General Public License16#
17# as published by the Free Software Foundation; either version 217# You should have received a copy of the GNU Affero General Public License
18# of the License, or (at your option) any later version.18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20# This program is distributed in the hope that it will be useful,
21# but WITHOUT ANY WARRANTY; without even the implied warranty of
22# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23# GNU General Public License for more details.
24#
25# You should have received a copy of the GNU General Public License
26# along with this program; if not, write to the Free Software
27# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28#19#
29##############################################################################20##############################################################################
3021
31from osv import osv, fields22from openerp.osv import osv, orm, fields
3223from openerp.tools.translate import _
33from tools.translate import _24
3425
3526class account_consolidation_check(orm.TransientModel):
36class account_consolidation_check(osv.osv_memory):
37 _name = 'account.consolidation.check'27 _name = 'account.consolidation.check'
38 _inherit = 'account.consolidation.base'28 _inherit = 'account.consolidation.base'
39 _description = 'Consolidation Checks. Model used for views'29 _description = 'Consolidation Checks. Model used for views'
4030
41 _columns = {31 _columns = {
42 'subsidiary_ids': fields.many2many('res.company', 'account_conso_check_comp_rel', 'conso_id', 'company_id',32 'subsidiary_ids': fields.many2many(
43 'Subsidiaries', required=True),33 'res.company',
34 'account_conso_check_comp_rel',
35 'conso_id',
36 'company_id',
37 'Subsidiaries',
38 required=True),
44 }39 }
4540
46 def check_account_charts(self, cr, uid, ids, context=None):41 def check_account_charts(self, cr, uid, ids, context=None):
47 """42 """
48 Action launched with the button on the view.43 Action launched with the button on the view.
49 Check the account charts and display a report of the errors44 Check the account charts and display a report of the errors
50
51 @param self: The object pointer
52 @param cr: the current row, from the database cursor,
53 @param uid: the current user’s ID for security checks,
54 @param ids: List of the wizard IDs (commonly the first element is the current ID)
55 @param context: A standard dictionary for contextual values
56 """45 """
57 invalid_items_per_company = \46 company_obj = self.pool.get('res.company')
58 super(account_consolidation_check, self).check_account_charts(cr, uid, ids, context=context)47 invalid_items_per_company = super(account_consolidation_check, self).\
59 if invalid_items_per_company:48 check_account_charts(cr, uid, ids, context=context)
60 err_lines = []49
61 for company_id, account_codes in invalid_items_per_company.iteritems():50 if not invalid_items_per_company:
62 company_obj = self.pool.get('res.company')51 raise osv.except_osv(
63 company = company_obj.browse(cr, uid, company_id, context=context)52 _('Validation'),
64 err_lines.append(_("%s :") % (company.name,))53 _('Chart of Accounts are OK.'))
65 [err_lines.append(_("Account with code %s does not exist on the Holding company.") % (account_code,))54
66 for account_code55 err_lines = []
67 in account_codes]56 for company_id, account_codes in invalid_items_per_company.iteritems():
68 err_lines.append('')57 company = company_obj.browse(
6958 cr, uid, company_id, context=context)
70 raise osv.except_osv(_('Invalid charts'),59 err_lines.append(_("%s :") % company.name)
71 '\n'.join(err_lines))60 for account_code in account_codes:
7261 err_lines.append(
73 else:62 _("Account with code %s does not exist on the "
74 raise osv.except_osv(_('Validation'), _('Chart of Accounts are OK.'))63 "Holding company.") % account_code)
75 # open a confirmation view ?64 err_lines.append('')
76 return True65
66 raise osv.except_osv(
67 _('Invalid charts'), '\n'.join(err_lines))
7768
78 def check_all_periods(self, cr, uid, ids, context=None):69 def check_all_periods(self, cr, uid, ids, context=None):
79 """70 """
80 Action launched with the button on the view.71 Action launched with the button on the view.
81 Check the periods and display a report of the errors72 Check the periods and display a report of the errors
82
83 @param self: The object pointer
84 @param cr: the current row, from the database cursor,
85 @param uid: the current user’s ID for security checks,
86 @param ids: List of the wizard IDs (commonly the first element is the current ID)
87 @param context: A standard dictionary for contextual values
88 """73 """
89 errors_by_company = \74 errors_by_company = super(account_consolidation_check, self).\
90 super(account_consolidation_check, self).check_all_periods(cr, uid, ids, context=context)75 check_all_periods(cr, uid, ids, context=context)
9176
92 if errors_by_company:77 if not errors_by_company:
93 company_obj = self.pool.get('res.company')
94
95 err_lines = []
96 for company_id, errors in errors_by_company.iteritems():
97 company = company_obj.browse(cr, uid, company_id, context=context)
98 err_lines.append(_("%s :") % (company.name,))
99 [err_lines.append(error) for error in errors]
100 err_lines.append('')
101
102 raise osv.except_osv(_('Invalid periods'),
103 '\n'.join(err_lines))
104 else:
105 raise osv.except_osv(_('Validation'), _('Periods are OK.'))78 raise osv.except_osv(_('Validation'), _('Periods are OK.'))
106 # open a confirmation view ?79
107 return True80 company_obj = self.pool.get('res.company')
10881
109account_consolidation_check()82 err_lines = []
83 for company_id, errors in errors_by_company.iteritems():
84 company = company_obj.browse(cr, uid, company_id, context=context)
85 err_lines.append(_("%s :") % company.name)
86 for error in errors:
87 err_lines.append(error)
88 err_lines.append('')
89
90 raise osv.except_osv(_('Invalid periods'),
91 '\n'.join(err_lines))
92
93 def check_subsidiary_mapping_account(self, cr, uid, ids, context=None):
94 """
95 Action launched with the button on the view.
96 Check the periods and display a report of the errors
97 """
98 errors_by_company = super(
99 account_consolidation_check, self
100 ).check_subsidiary_mapping_account(cr, uid, ids, context=context)
101
102 if not errors_by_company:
103 raise osv.except_osv(_('Validation'), _('All account is mapped'))
104
105 company_obj = self.pool.get('res.company')
106
107 err_lines = []
108 for company_id, errors in errors_by_company.iteritems():
109 company = company_obj.browse(cr, uid, company_id, context=context)
110 err_lines.append(_("%s :") % company.name)
111 for error in errors:
112 err_lines.append(error)
113 err_lines.append('')
114
115 raise osv.except_osv(_('Invalid accounts'),
116 '\n'.join(err_lines))
110117
=== modified file 'account_consolidation/wizard/consolidation_check_view.xml'
--- account_consolidation/wizard/consolidation_check_view.xml 2011-08-19 13:08:01 +0000
+++ account_consolidation/wizard/consolidation_check_view.xml 2014-06-26 13:58:55 +0000
@@ -2,32 +2,52 @@
2<openerp>2<openerp>
3 <data>3 <data>
44
5 <record id="view_consolidation_check_form" model="ir.ui.view">5 <record id="view_consolidation_check_form" model="ir.ui.view">
6 <field name="name">account.consolidation.check.form</field>6 <field name="name">account.consolidation.check.form</field>
7 <field name="model">account.consolidation.check</field>7 <field name="model">account.consolidation.check</field>
8 <field name="type">form</field>8 <field name="type">form</field>
9 <field name="arch" type="xml">9 <field name="arch" type="xml">
10 <form string="Consolidation: Checks">10 <form string="Consolidation: Checks" version="7.0">
11 <group col="4" colspan="6">11 <label string="Prepare your consolidation and make sure that your consolidation will be correct by proceeding with the checks. The 'Check Periods' verify if fiscal year exists for each subsidiary, and if the periods have the same beginning and ending dates. The 'Check Charts' verify if subsidiary accounts are missing in the Holding's Chart of Accounts."/>
12 <field name="company_id" on_change="on_change_company_id(company_id)" invisible="True"/>12 <group>
13 <field name="fiscalyear_id" domain="[('company_id', '=', company_id)]"/>13 <field name="company_id"
14 <newline/>14 on_change="on_change_company_id(company_id)"
15 <field name="holding_chart_account_id" domain="[('company_id', '=', company_id), ('parent_id', '=', False)]"/>15 invisible="True"/>
16 <separator string="Subsidiaries to Consolidate" colspan="4"/>16 <field name="fiscalyear_id"
17 <field name="subsidiary_ids" colspan="4" nolabel="1" required="True" domain="[('parent_id', '=', company_id)]">17 domain="[('company_id', '=', company_id)]"/>
18 <tree>18 <newline/>
19 <field name="name"/>19 <field name="holding_chart_account_id"
20 <field name="consolidation_chart_account_id"/>20 domain="[('company_id', '=', company_id), ('parent_id', '=', False)]"/>
21 </tree>21 <separator string="Subsidiaries to Consolidate" colspan="4"/>
22 </field>22 <field name="subsidiary_ids" colspan="4" nolabel="1"
23 </group>23 required="True"
24 <separator colspan="4"/>24 domain="[('parent_id', '=', company_id)]">
25 <group col="3" colspan="4">25 <tree>
26 <button special="cancel" string="Cancel" icon='gtk-cancel'/>26 <field name="name"/>
27 <button name="check_all_periods" string="Check Periods" colspan="1" type="object" icon="gtk-execute"/>27 <field name="consolidation_chart_account_id"/>
28 <button name="check_account_charts" string="Check Charts" colspan="1" type="object" icon="gtk-execute"/>28 </tree>
29 </group>29 </field>
30 </form> 30 </group>
31 <footer>
32 <button name="check_all_periods"
33 string="Check Periods" type="object"
34 class="oe_highlight"/>
35 or
36 <button name="check_account_charts"
37 string="Check Charts 1" type="object"
38 class="oe_highlight"/>
39 or
40 <button name="check_subsidiary_mapping_account"
41 string="Check Charts 2" type="object"
42 class="oe_highlight"/>
43 <button string="Cancel" class="oe_link" special="cancel"/>
44 </footer>
45 <group>
46 <label string="Check Period : Check consistency of accounting periods between subsidiaries and holding company." />
47 <label string="Check Chart 1 : Check consistency between subsidiaries consolidation chart and Holding company chart." />
48 <label string="Check Chart 2 : For each subsidiary, check consistency between the regular chart of accounts and the consolidation chart." />
49 </group>
50 </form>
31 </field>51 </field>
32 </record>52 </record>
3353
@@ -37,9 +57,8 @@
37 <field name="res_model">account.consolidation.check</field>57 <field name="res_model">account.consolidation.check</field>
38 <field name="view_type">form</field>58 <field name="view_type">form</field>
39 <field name="view_mode">form</field>59 <field name="view_mode">form</field>
40 <field name="help">Prepare your consolidation and make sure that your consolidation will be correct by proceeding with the checks. The "Check Periods" verify if fiscal year exists for each subsidiary, and if the periods have the same beginning and ending dates. The "Check Charts" verify if subsidiary accounts are missing in the Holding's Chart of Accounts.</field>
41 <field name="target">new</field>60 <field name="target">new</field>
42 </record>61 </record>
4362
44 </data>63 </data>
45</openerp>64</openerp>
4665
=== modified file 'account_consolidation/wizard/consolidation_consolidate.py'
--- account_consolidation/wizard/consolidation_consolidate.py 2012-04-11 07:57:56 +0000
+++ account_consolidation/wizard/consolidation_consolidate.py 2014-06-26 13:58:55 +0000
@@ -1,94 +1,113 @@
1# -*- coding: utf-8 -*-1# -*- coding: utf-8 -*-
2##############################################################################2##############################################################################
3#3#
4# Copyright (c) 2011 Camptocamp SA (http://www.camptocamp.com)4# Author: Guewen Baconnier
5#5# Copyright 2011-2013 Camptocamp SA
6# Author : Guewen Baconnier (Camptocamp)6#
7#7# This program is free software: you can redistribute it and/or modify
8# WARNING: This program as such is intended to be used by professional8# it under the terms of the GNU Affero General Public License as
9# programmers who take the whole responsability of assessing all potential9# published by the Free Software Foundation, either version 3 of the
10# consequences resulting from its eventual inadequacies and bugs10# License, or (at your option) any later version.
11# End users who are looking for a ready-to-use solution with commercial11#
12# garantees and support are strongly adviced to contract a Free Software12# This program is distributed in the hope that it will be useful,
13# Service Company13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14#14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# This program is Free Software; you can redistribute it and/or15# GNU Affero General Public License for more details.
16# modify it under the terms of the GNU General Public License16#
17# as published by the Free Software Foundation; either version 217# You should have received a copy of the GNU Affero General Public License
18# of the License, or (at your option) any later version.18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20# This program is distributed in the hope that it will be useful,
21# but WITHOUT ANY WARRANTY; without even the implied warranty of
22# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23# GNU General Public License for more details.
24#
25# You should have received a copy of the GNU General Public License
26# along with this program; if not, write to the Free Software
27# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28#19#
29##############################################################################20##############################################################################
3021
31from osv import osv, fields22from openerp.osv import orm, fields
32from tools.translate import _23from openerp.osv.osv import except_osv
33from tools import safe_eval as eval24from openerp.tools.translate import _
3425
35class account_consolidation_consolidate(osv.osv_memory):26class account_consolidation_consolidate(orm.TransientModel):
36 _name = 'account.consolidation.consolidate'27 _name = 'account.consolidation.consolidate'
37 _inherit = 'account.consolidation.base'28 _inherit = 'account.consolidation.base'
3829
30 def _default_journal(self, cr, uid, context=None):
31 comp_obj = self.pool['res.company']
32 journ_obj = self.pool['account.journal']
33 comp_id = comp_obj._company_default_get(cr, uid)
34 journal_id = journ_obj.search(cr, uid, [('company_id', '=', comp_id)], limit=1)
35 if journal_id:
36 return journal_id[0]
37 return False
38
39 _columns = {39 _columns = {
40 'from_period_id': fields.many2one('account.period', 'Start Period', required=True,40 'from_period_id': fields.many2one(
41 help="Select the same period in 'from' and 'to' if you want to proceed with a single period. Start Period is ignored for Year To Date accounts."),41 'account.period',
42 'to_period_id': fields.many2one('account.period', 'End Period', required=True,42 'Start Period',
43 help="The consolidation will be done at the very last date of the selected period."),43 required=True,
44 'journal_id': fields.many2one('account.journal', 'Journal', required=True),44 help="Select the same period in 'from' and 'to' "
45 # not sure that we'll use them, actually using centralised counterpart journal45 "if you want to proceed with a single period. "
46# 'gain_account_id': fields.many2one('account.account', 'Gain Account', required=True,),46 "Start Period is ignored for Year To Date accounts."),
47# 'loss_account_id': fields.many2one('account.account', 'Loss Account', required=True,),47
48 'target_move': fields.selection([('posted', 'All Posted Entries'),48 'to_period_id': fields.many2one(
49 ('all', 'All Entries'),49 'account.period',
50 ], 'Target Moves', required=True),50 'End Period',
51 'subsidiary_ids': fields.many2many('res.company', 'account_conso_conso_comp_rel', 'conso_id', 'company_id',51 required=True,
52 'Subsidiaries', required=True),52 help="The consolidation will be done at the very "
53 }53 "last date of the selected period."),
5454
55 _defaults = {55 'journal_id': fields.many2one(
56 'target_move': 'posted'56 'account.journal', 'Journal', required=True),
57 }57
58 'target_move': fields.selection(
59 [('posted', 'All Posted Entries'),
60 ('all', 'All Entries')],
61 'Target Moves',
62 required=True),
63
64 'subsidiary_ids': fields.many2many(
65 'res.company',
66 'account_conso_conso_comp_rel',
67 'conso_id',
68 'company_id',
69 string='Subsidiaries',
70 required=True),
71 }
72
73 _defaults = {'target_move': 'posted',
74 'journal_id': _default_journal,
75 }
5876
59 def _check_periods_fy(self, cr, uid, ids, context=None):77 def _check_periods_fy(self, cr, uid, ids, context=None):
60 if context is None:78 if isinstance(ids, (int, long)):
61 context = {}79 ids = [ids]
80 assert len(ids) == 1, "only 1 id expected"
81
62 form = self.browse(cr, uid, ids[0], context=context)82 form = self.browse(cr, uid, ids[0], context=context)
63 if form.from_period_id.fiscalyear_id.id != form.to_period_id.fiscalyear_id.id:83 return (form.from_period_id.fiscalyear_id.id ==
64 return False84 form.to_period_id.fiscalyear_id.id)
65 return True
6685
67 _constraints = [86 _constraints = [
68 (_check_periods_fy, 'Start Period and End Period must be of the same Fiscal Year !', ['from_period_id', 'to_period_id']),87 (_check_periods_fy,
88 'Start Period and End Period must be of the same Fiscal Year !',
89 ['from_period_id', 'to_period_id']),
69 ]90 ]
7091
71 def on_change_from_period_id(self, cr, uid, ids, from_period_id, to_period_id, context=None):92 def on_change_from_period_id(self, cr, uid, ids, from_period_id,
72 """93 to_period_id, context=None):
73 On change of the From period, set the To period to the same period if it is empty94 """ On change of the From period, set the To period
7495 to the same period if it is empty
75 @param self: The object pointer96
76 @param cr: the current row, from the database cursor,97 :param from_period_id: ID of the selected from period id
77 @param uid: the current user’s ID for security checks,98 :param to_period_id: ID of the current from period id
78 @param ids: List of the wizard IDs (commonly the first element is the current ID)99
79 @param from_period_id: ID of the selected from period id100 :return: dict of values to change
80 @param to_period_id: ID of the current from period id
81 @param context: A standard dictionary for contextual values
82
83 @return: dict of values to change
84 """101 """
85 result = {}102 result = {}
86 period_obj = self.pool.get('account.period')103 period_obj = self.pool.get('account.period')
87 from_period = period_obj.browse(cr, uid, from_period_id, context=context)104 from_period = period_obj.browse(cr, uid, from_period_id,
105 context=context)
88 if not to_period_id:106 if not to_period_id:
89 result['to_period_id'] = from_period_id107 result['to_period_id'] = from_period_id
90 else:108 else:
91 to_period = period_obj.browse(cr, uid, to_period_id, context=context)109 to_period = period_obj.browse(cr, uid, to_period_id,
110 context=context)
92 if to_period.date_start < from_period.date_start:111 if to_period.date_start < from_period.date_start:
93 result['to_period_id'] = from_period_id112 result['to_period_id'] = from_period_id
94113
@@ -99,97 +118,120 @@
99 """118 """
100 Returns the currency rate type to use119 Returns the currency rate type to use
101120
102 @param self: The object pointer121 :param account: browse_record instance of account.account
103 @param cr: the current row, from the database cursor,
104 @param uid: the current user’s ID for security checks,
105 @param ids: List of the wizard IDs (commonly the first element is the current ID)
106 @param account: browse instance of account.account
107 @param context: A standard dictionary for contextual values
108122
109 @return: 'spot' or 'average'123 :return: id of the currency rate type to use
110 """124 """
111 return account.consolidation_rate_type_id and account.consolidation_rate_type_id \125 if account.consolidation_rate_type_id:
112 or account.user_type.consolidation_rate_type_id and account.user_type.consolidation_rate_type_id.id \126 return account.consolidation_rate_type_id.id
113 or False127
128 elif account.user_type.consolidation_rate_type_id:
129 return account.user_type.consolidation_rate_type_id.id
130
131 else:
132 return False
114133
115 def _consolidation_mode(self, cr, uid, ids, account, context=None):134 def _consolidation_mode(self, cr, uid, ids, account, context=None):
116 """135 """
117 Returns the consolidation mode to use136 Returns the consolidation mode to use
118137
119 @param self: The object pointer138 :param account: browse instance of account.account
120 @param cr: the current row, from the database cursor,139
121 @param uid: the current user’s ID for security checks,140 :return: 'ytd' or 'period'
122 @param ids: List of the wizard IDs (commonly the first element is the current ID)141 """
123 @param account: browse instance of account.account142 return (account.consolidation_mode or
124 @param context: A standard dictionary for contextual values143 account.user_type.consolidation_mode)
125144
126 @return: 'ytd' or 'period'145 def _periods_holding_to_subsidiary(self, cr, uid, ids, period_ids,
127 """146 subsidiary_id, context=None):
128 return account.consolidation_mode or account.user_type.consolidation_mode147 """
129148 Returns the periods of a subsidiary company which
130 def _periods_holding_to_subsidiary(self, cr, uid, ids, period_ids, subsidiary_id, context=None):149 correspond to the holding periods (same beginning and ending dates)
131 """150
132 Returns the periods of a subsidiary company which correspond to the holding periods151 :param period_ids: list of periods of the holding
133 (same beginning and ending dates)152 :param subsidiary_id: ID of the subsidiary for which
134153 we want the period IDs
135 @param self: The object pointer154
136 @param cr: the current row, from the database cursor,155 :return: list of periods of the subsidiaries
137 @param uid: the current user’s ID for security checks,
138 @param ids: List of the wizard IDs (commonly the first element is the current ID)
139 @param period_ids: list of periods of the holding
140 @param subsidiary_id: ID of the subsidiary for which we want the period IDs
141 @param context: A standard dictionary for contextual values
142
143 @return: list of periods of the subsidiaries
144 """156 """
145 period_obj = self.pool.get('account.period')157 period_obj = self.pool.get('account.period')
146 if isinstance(period_ids, (int, long)):158 if isinstance(period_ids, (int, long)):
147 period_ids = [period_ids]159 period_ids = [period_ids]
160
148 subs_period_ids = []161 subs_period_ids = []
149 for period in period_obj.browse(cr, uid, period_ids, context=context):162 for period in period_obj.browse(cr, uid, period_ids, context=context):
150 subs_period_ids.extend(period_obj.search(cr, uid,163 subs_period_ids += period_obj.search(
164 cr, uid,
151 [('date_start', '=', period.date_start),165 [('date_start', '=', period.date_start),
152 ('date_stop', '=', period.date_stop),166 ('date_stop', '=', period.date_stop),
153 ('company_id', '=', subsidiary_id)])167 ('company_id', '=', subsidiary_id)],
154 )168 context=context)
155 return subs_period_ids169 return subs_period_ids
156170
157 def create_rate_difference_line(self, cr, uid, ids, move_id, context):171 def create_rate_difference_line(self, cr, uid, ids, move_id, consolidation_mode, context):
158 """172 """
159 Create a move line for the gain/loss currency difference173 We can have consolidation difference when a account is in YTD but in normal counterpart
160174 has a different setting.
161 @param self: The object pointer175 """
162 @param cr: the current row, from the database cursor,176 move_obj = self.pool['account.move']
163 @param uid: the current user’s ID for security checks,177 move_line_obj = self.pool['account.move.line']
164 @param ids: List of the wizard IDs (commonly the first element is the current ID)178 currency_obj = self.pool['res.currency']
165 @param move_id: ID of the move179 move = move_obj.browse(cr, uid, move_id, context=context)
166 @param context: A standard dictionary for contextual values180
167181 if not move.line_id:
168 @return:182 return False
169 """183 diff_account = move.company_id.consolidation_diff_account_id
170184 if not diff_account:
171 pass185 raise except_osv(_('Settings ERROR'),
172186 _('Please set the "Consolidation difference account"'
173 def consolidate_account(self, cr, uid, ids, consolidation_mode, subsidiary_period_ids, state, move_id,187 ' in company %s') % move.company_id.name)
188 debit = credit = 0.0
189 for line in move.line_id:
190 debit += line.debit
191 credit += line.credit
192 balance = debit - credit
193 # We do not want to create counter parts for amount smaller than
194 # "holding" company currency rounding policy.
195 # As generated lines are in draft state, accountant will be able to manage
196 # special cases
197 move_is_balanced = currency_obj.is_zero(cr, uid, move.company_id.currency_id, balance)
198 if not move_is_balanced:
199 diff_vals = {'account_id': diff_account.id,
200 'move_id': move.id,
201 'journal_id': move.journal_id.id,
202 'period_id': move.period_id.id,
203 'company_id': move.company_id.id,
204 'date': move.date,
205 'debit': abs(balance) if balance < 0.0 else 0.0,
206 'credit': balance if balance > 0.0 else 0.0,
207 'name': _('Consolidation difference in mode %s') % consolidation_mode
208 }
209 return move_line_obj.create(cr, uid, diff_vals, context=context)
210 return False
211
212 def consolidate_account(self, cr, uid, ids, consolidation_mode,
213 subsidiary_period_ids, state, move_id,
174 holding_account_id, subsidiary_id, context=None):214 holding_account_id, subsidiary_id, context=None):
175 """215 """
176 Consolidates the subsidiary account on the holding account216 Consolidates the subsidiary account on the holding account
177 Creates move lines on the move with id "move_id"217 Creates move lines on the move with id "move_id"
178218
179 @param self: The object pointer219 :param consolidation_mode: consolidate by Periods or
180 @param cr: the current row, from the database cursor,220 Year To Date ('period' or 'ytd')
181 @param uid: the current user’s ID for security checks,221 :param subsidiary_period_ids: IDs of periods for which we
182 @param ids: List of the wizard IDs (commonly the first element is the current ID)222 want to sum the debit/credit
183 @param consolidation_mode: consolidate by Periods or Year To Date ('period' or 'ytd')223 :param state: state of the moves to consolidate ('all' or 'posted')
184 @param subsidiary_period_ids: IDs of periods for which we want to sum the debit/credit224 :param move_id: ID of the move on which all the
185 @param state: state of the moves to consolidate ('all' or 'posted')225 created move lines will be linked
186 @param move_id: ID of the move on which all the created move lines will be linked226 :param holding_account_id: ID of the account to consolidate
187 @param holding_account_id: ID of the account to consolidate (on the holding), the method will find the subsidiary's corresponding account227 (on the holding), the method will
188 @param subsidiary_id: ID of the subsidiary to consolidate228 find the subsidiary's corresponding account
189 @param context: A standard dictionary for contextual values229 :param subsidiary_id: ID of the subsidiary to consolidate
190230
191 @return: list of IDs of the created move lines231 :return: list of IDs of the created move lines
192 """232 """
233 if context is None:
234 context = {}
193235
194 account_obj = self.pool.get('account.account')236 account_obj = self.pool.get('account.account')
195 move_obj = self.pool.get('account.move')237 move_obj = self.pool.get('account.move')
@@ -197,7 +239,8 @@
197 currency_obj = self.pool.get('res.currency')239 currency_obj = self.pool.get('res.currency')
198240
199 move = move_obj.browse(cr, uid, move_id, context=context)241 move = move_obj.browse(cr, uid, move_id, context=context)
200 holding_account = account_obj.browse(cr, uid, holding_account_id, context=context)242 holding_account = account_obj.browse(cr, uid, holding_account_id,
243 context=context)
201244
202 subsidiary_account_id = account_obj.search(cr, uid,245 subsidiary_account_id = account_obj.search(cr, uid,
203 [('code', '=', holding_account.code),246 [('code', '=', holding_account.code),
@@ -205,18 +248,17 @@
205 context=context)248 context=context)
206249
207 if not subsidiary_account_id:250 if not subsidiary_account_id:
208 return [] # an account may exist on the holding and not in the subsidiaries, nothing to do251 # an account may exist on the holding and not in the subsidiaries,
252 # nothing to do
253 return []
209254
210 browse_ctx = context.copy()255 browse_ctx = dict(context, state=state, periods=subsidiary_period_ids)
211 browse_ctx.update({256 # 1st item because the account's code is unique per company
212 'state': state,257 subs_account = account_obj.browse(cr, uid, subsidiary_account_id[0],
213 'periods': subsidiary_period_ids,258 context=browse_ctx)
214 })
215 # subsidiary_account_id[0] because only one account per company for one code is permitted
216 subs_account = account_obj.browse(cr, uid, subsidiary_account_id[0], context=browse_ctx)
217259
218 vals = {260 vals = {
219 'name': _("Consolidation line in %s mode") % (consolidation_mode,),261 'name': _("Consolidation line in %s mode") % consolidation_mode,
220 'account_id': holding_account.id,262 'account_id': holding_account.id,
221 'move_id': move.id,263 'move_id': move.id,
222 'journal_id': move.journal_id.id,264 'journal_id': move.journal_id.id,
@@ -225,47 +267,47 @@
225 'date': move.date267 'date': move.date
226 }268 }
227269
228 if holding_account.company_currency_id.id != subs_account.company_currency_id.id:270 balance = subs_account.balance
229 currency_rate_type = self._currency_rate_type(cr, uid, ids, holding_account, context=context)271 if not balance:
272 return False
273 if (holding_account.company_currency_id.id ==
274 subs_account.company_currency_id.id):
275 vals.update({
276 'debit': balance if balance > 0.0 else 0.0,
277 'credit': abs(balance) if balance < 0.0 else 0.0,
278 })
279 else:
280 currency_rate_type = self._currency_rate_type(cr, uid, ids,
281 holding_account, context=context)
230282
231 currency_value = currency_obj.compute(cr, uid,283 currency_value = currency_obj.compute(cr, uid,
232 holding_account.company_currency_id.id,284 holding_account.company_currency_id.id,
233 subs_account.company_currency_id.id,285 subs_account.company_currency_id.id,
234 subs_account.balance,286 balance,
235 currency_rate_type_from=False, # means spot287 currency_rate_type_from=False, # means spot
236 currency_rate_type_to=currency_rate_type,288 currency_rate_type_to=currency_rate_type,
237 context=context)289 context=context)
238 vals.update({290 vals.update({
239 'currency_id': subs_account.company_currency_id.id,291 'currency_id': subs_account.company_currency_id.id,
240 'amount_currency': subs_account.balance,292 'amount_currency': subs_account.balance,
241 'debit': currency_value > 0 and currency_value or 0.0,293 'debit': currency_value if currency_value > 0.0 else 0.0,
242 'credit': currency_value < 0 and -currency_value or 0.0294 'credit': abs(currency_value) if currency_value < 0.0 else 0.0,
243 })295 })
244296
245 else:297 return move_line_obj.create(cr, uid, vals, context=context)
246 vals.update({298
247 'debit': subs_account.debit,299 def reverse_moves(self, cr, uid, ids, subsidiary_id, journal_id,
248 'credit': subs_account.credit,300 reversal_date, context=None):
249 })
250
251 move_line_id = move_line_obj.create(cr, uid, vals, context=context)
252
253 return move_line_id
254
255 def reverse_moves(self, cr, uid, ids, subsidiary_id, journal_id, reversal_date, context):
256 """301 """
257 Reverse all account moves of a journal which have the "To be reversed" flag302 Reverse all account moves of a journal which have
258303 the "To be reversed" flag
259 @param self: The object pointer304
260 @param cr: the current row, from the database cursor,305 :param subsidiary_id: ID of the subsidiary moves to reverse
261 @param uid: the current user’s ID for security checks,306 :param journal_id: ID of the journal with moves to reverse
262 @param ids: List of the wizard IDs (commonly the first element is the current ID)307 :param reversal_date: date when to create the reversal
263 @param subsidiary_id: ID of the subsidiary moves to reverse308
264 @param journal_id: ID of the journal with moves to reverse309 :return: tuple with : list of IDs of the reversed moves,
265 @param reversal_date: date when to create the reversal310 list of IDs of the reversal moves
266 @param context: A standard dictionary for contextual values
267
268 @return: tuple with : list of IDs of the reversed moves, list of IDs of the reversal moves
269 """311 """
270 move_obj = self.pool.get('account.move')312 move_obj = self.pool.get('account.move')
271 reversed_ids = move_obj.search(cr, uid,313 reversed_ids = move_obj.search(cr, uid,
@@ -273,41 +315,49 @@
273 ('to_be_reversed', '=', True),315 ('to_be_reversed', '=', True),
274 ('consol_company_id', '=', subsidiary_id)],316 ('consol_company_id', '=', subsidiary_id)],
275 context=context)317 context=context)
276 reversal_ids = move_obj.create_reversals(cr, uid, reversed_ids, reversal_date, context=context)318 reversal_ids = move_obj.create_reversals(
319 cr, uid, reversed_ids, reversal_date, context=context)
277 return reversed_ids, reversal_ids320 return reversed_ids, reversal_ids
278321
279 def consolidate_subsidiary(self, cr, uid, ids, subsidiary_id, context=None):322 def consolidate_subsidiary(self, cr, uid, ids,
323 subsidiary_id, context=None):
280 """324 """
281 Consolidate one subsidiary on the Holding.325 Consolidate one subsidiary on the Holding.
282 Create a move per subsidiary and consolidation type (YTD/Period)326 Create a move per subsidiary and consolidation type (YTD/Period)
283 and an move line per account of the subsidiary327 and an move line per account of the subsidiary
284 Plus a move line for the currency gain / loss # FIXME to check!328
285 329 :param subsidiary_id: ID of the subsidiary to consolidate
286 @param self: The object pointer330 on the holding
287 @param cr: the current row, from the database cursor,331
288 @param uid: the current user’s ID for security checks,332 :return: Tuple of form:
289 @param ids: List of the wizard IDs (commonly the first element is the current ID)333 (list of IDs of the YTD moves,
290 @param subsidiary_id: ID of the subsidiary to consolidate on the holding334 list of IDs of the Period Moves)
291 @param context: A standard dictionary for contextual values
292
293 @return: Tuple of (list of IDs of the YTD moves, list of IDs of the Period Moves)
294 """335 """
295336 if context is None:
296 context = context or {}337 context = {}
338
339 if isinstance(ids, (int, long)):
340 ids = [ids]
341 assert len(ids) == 1, "only 1 id expected"
342
297 company_obj = self.pool.get('res.company')343 company_obj = self.pool.get('res.company')
298 move_obj = self.pool.get('account.move')344 move_obj = self.pool.get('account.move')
299 period_obj = self.pool.get('account.period')345 period_obj = self.pool.get('account.period')
346
300 form = self.browse(cr, uid, ids[0], context=context)347 form = self.browse(cr, uid, ids[0], context=context)
301 subsidiary = company_obj.browse(cr, uid, subsidiary_id, context=None)348 subsidiary = company_obj.browse(cr, uid, subsidiary_id, context=None)
302349
303 data_ctx = context.copy()350 data_ctx = dict(context, holding_coa=True)
304 data_ctx.update({'holding_coa': True})351 holding_accounts_data = self._chart_accounts_data(
305 holding_accounts_data = self._chart_accounts_data(cr, uid, ids,352 cr, uid,
306 form.holding_chart_account_id.id,353 ids,
307 context=data_ctx)354 form.holding_chart_account_id.id,
308 subs_accounts_codes = self._chart_accounts_data(cr, uid, ids,355 context=data_ctx)
309 subsidiary.consolidation_chart_account_id.id,356 subs_accounts_codes = self._chart_accounts_data(
310 context=context)357 cr, uid,
358 ids,
359 subsidiary.consolidation_chart_account_id.id,
360 context=context)
311 holding_accounts = [values for key, values361 holding_accounts = [values for key, values
312 in holding_accounts_data.iteritems()362 in holding_accounts_data.iteritems()
313 if key in subs_accounts_codes]363 if key in subs_accounts_codes]
@@ -316,12 +366,14 @@
316 # a move per type will be created366 # a move per type will be created
317 consolidation_modes = {'ytd': [], 'period': []}367 consolidation_modes = {'ytd': [], 'period': []}
318 for account in holding_accounts:368 for account in holding_accounts:
319 cm = self._consolidation_mode(cr, uid, ids, account, context=context)369 cm = self._consolidation_mode(
370 cr, uid, ids, account, context=context)
320 consolidation_modes[cm].append(account)371 consolidation_modes[cm].append(account)
321372
322 period_ids = period_obj.build_ctx_periods(cr, uid,373 period_ids = period_obj.build_ctx_periods(
323 form.from_period_id.id,374 cr, uid,
324 form.to_period_id.id)375 form.from_period_id.id,
376 form.to_period_id.id)
325377
326 generic_move_vals = {378 generic_move_vals = {
327 'journal_id': form.journal_id.id,379 'journal_id': form.journal_id.id,
@@ -337,15 +389,18 @@
337389
338 # get list of periods for which we have to create a move390 # get list of periods for which we have to create a move
339 # in period mode : a move per period391 # in period mode : a move per period
340 # in ytd mode : a move at the last period (which will contains lines from 1st january to last period)392 # in ytd mode : a move at the last period
341 move_period_ids = consolidation_mode == 'period' \393 # (which will contains lines from 1st january to last period)
342 and period_ids \394 move_period_ids = (period_ids
343 or [form.to_period_id.id]395 if consolidation_mode == 'period'
396 else [form.to_period_id.id])
344397
345 for move_period_id in move_period_ids:398 for move_period_id in move_period_ids:
346 period = period_obj.browse(cr, uid, move_period_id, context=context)399 period = period_obj.browse(
400 cr, uid, move_period_id, context=context)
347401
348 # in ytd we compute the amount from the first day of the fiscal year402 # in ytd we compute the amount from the first
403 # day of the fiscal year
349 # in period, only for the period404 # in period, only for the period
350 if consolidation_mode == 'ytd':405 if consolidation_mode == 'ytd':
351 date_from = period.fiscalyear_id.date_start406 date_from = period.fiscalyear_id.date_start
@@ -353,52 +408,61 @@
353 date_from = period.date_start408 date_from = period.date_start
354 date_to = period.date_stop409 date_to = period.date_stop
355410
356 period_ctx = context.copy()411 period_ctx = dict(context, company_id=subsidiary.id)
357 period_ctx.update({412 compute_from_period_id = period_obj.find(
358 'company_id': subsidiary.id,413 cr, uid, date_from, context=period_ctx)[0]
359 })414 compute_to_period_id = period_obj.find(
360 compute_from_period_id = period_obj.find(cr, uid, date_from, context=period_ctx)[0]415 cr, uid, date_to, context=period_ctx)[0]
361 compute_to_period_id = period_obj.find(cr, uid, date_to, context=period_ctx)[0]416 compute_period_ids = period_obj.build_ctx_periods(
362 compute_period_ids = period_obj.build_ctx_periods(cr, uid,417 cr, uid,
363 compute_from_period_id,418 compute_from_period_id,
364 compute_to_period_id)419 compute_to_period_id)
365420
366 # reverse previous entries with flag 'to_be_reversed' (YTD)421 # reverse previous entries with flag 'to_be_reversed' (YTD)
367 self.reverse_moves(cr, uid, ids, subsidiary.id, form.journal_id.id, date_to, context=context)422 self.reverse_moves(
368423 cr, uid,
369 # TODO if moves found for the same period : skip ?424 ids,
425 subsidiary.id,
426 form.journal_id.id,
427 date_to,
428 context=context)
370429
371 # create the account move430 # create the account move
372 # at the very last date of the end period431 # at the very last date of the end period
373 move_vals = generic_move_vals.copy()432 move_vals = dict(
374 move_vals.update({433 generic_move_vals,
375 'ref': _("Consolidation %s") % (consolidation_mode,),434 ref=_("Consolidation %s") % consolidation_mode,
376 'period_id': period.id,435 period_id=period.id,
377 'date': period.date_stop,436 date=period.date_stop)
378 })
379 move_id = move_obj.create(cr, uid, move_vals, context=context)437 move_id = move_obj.create(cr, uid, move_vals, context=context)
380438
381 move_line_ids = []
382 # create a move line per account439 # create a move line per account
440 has_move_line = False
383 for account in accounts:441 for account in accounts:
384 move_line_ids.append(442 m_id = self.consolidate_account(
385 self.consolidate_account(cr, uid, ids,443 cr, uid, ids,
386 consolidation_mode,444 consolidation_mode,
387 compute_period_ids,445 compute_period_ids,
388 form.target_move,446 form.target_move,
389 move_id,447 move_id,
390 account.id,448 account.id,
391 subsidiary.id,449 subsidiary.id,
392 context=context)450 context=context)
393 )451 if m_id:
394452 has_move_line = True
395 # TODO calculate currency rate difference (all move lines debit - all move lines credit) and post a move line453
396 # on the gain / loss account454 if has_move_line:
397 # will works IF : counterparts are always configured with the same mode (YTD/Periods)455 self.create_rate_difference_line(cr, uid, ids,
398 self.create_rate_difference_line(cr, uid, ids,456 move_id, consolidation_mode, context=context)
399 move_id, context=context)457 locals()[consolidation_mode + '_move_ids'].append(move_id)
400458
401 locals()[consolidation_mode + '_move_ids'].append(move_id)459 else:
460 # We delete created move if it has no line.
461 # As move are generated in draft mode they will be no gap in
462 # number if consolidation journal has correct settings.
463 # I agree it can be more efficient but size of refactoring
464 # is not in ressource scope
465 move_obj.unlink(cr, uid, [move_id])
402466
403 return ytd_move_ids, period_move_ids467 return ytd_move_ids, period_move_ids
404468
@@ -407,15 +471,10 @@
407 Consolidate all selected subsidiaries Virtual Chart of Accounts471 Consolidate all selected subsidiaries Virtual Chart of Accounts
408 on the Holding Chart of Account472 on the Holding Chart of Account
409473
410 @param self: The object pointer474 :return: dict to open an Entries view filtered on the created moves
411 @param cr: the current row, from the database cursor,
412 @param uid: the current user’s ID for security checks,
413 @param ids: List of the wizard IDs (commonly the first element is the current ID)
414 @param context: A standard dictionary for contextual values
415
416 @return: dict to open an Entries view filtered on the created moves
417 """475 """
418 super(account_consolidation_consolidate, self).run_consolidation(cr, uid, ids, context=context)476 super(account_consolidation_consolidate, self).run_consolidation(
477 cr, uid, ids, context=context)
419478
420 mod_obj = self.pool.get('ir.model.data')479 mod_obj = self.pool.get('ir.model.data')
421 act_obj = self.pool.get('ir.actions.act_window')480 act_obj = self.pool.get('ir.actions.act_window')
@@ -425,20 +484,23 @@
425 move_ids = []484 move_ids = []
426 ytd_move_ids = []485 ytd_move_ids = []
427 for subsidiary in form.subsidiary_ids:486 for subsidiary in form.subsidiary_ids:
428 new_move_ids = self.consolidate_subsidiary(cr, uid, ids, subsidiary.id, context=context)487 new_move_ids = self.consolidate_subsidiary(
429 ytd_move_ids.extend(new_move_ids[0])488 cr, uid, ids, subsidiary.id, context=context)
430 move_ids.extend(sum(new_move_ids, []))489 ytd_move_ids += new_move_ids[0]
490 move_ids += sum(new_move_ids, [])
431491
432 # YTD moves have to be reversed on the next consolidation492 # YTD moves have to be reversed on the next consolidation
433 move_obj.write(cr, uid, ytd_move_ids, {'to_be_reversed': True}, context=context)493 move_obj.write(
494 cr, uid,
495 ytd_move_ids,
496 {'to_be_reversed': True},
497 context=context)
434498
435 context.update({'move_ids': move_ids})499 context.update({'move_ids': move_ids})
436 action_ref = mod_obj.get_object_reference(cr, uid, 'account', 'action_move_journal_line')500 __, action_id = mod_obj.get_object_reference(
437 action_id = action_ref and action_ref[1] or False501 cr, uid, 'account', 'action_move_journal_line')
438 action = act_obj.read(cr, uid, [action_id], context=context)[0]502 action = act_obj.read(cr, uid, [action_id], context=context)[0]
439 action['domain'] = unicode([('id', 'in', move_ids)])503 action['domain'] = unicode([('id', 'in', move_ids)])
440 action['name'] = _('Consolidated Entries')504 action['name'] = _('Consolidated Entries')
441 action['context'] = unicode({'search_default_to_be_reversed': 0})505 action['context'] = unicode({'search_default_to_be_reversed': 0})
442 return action506 return action
443
444account_consolidation_consolidate()
445507
=== modified file 'account_consolidation/wizard/consolidation_consolidate_view.xml'
--- account_consolidation/wizard/consolidation_consolidate_view.xml 2011-08-29 05:45:40 +0000
+++ account_consolidation/wizard/consolidation_consolidate_view.xml 2014-06-26 13:58:55 +0000
@@ -2,39 +2,49 @@
2<openerp>2<openerp>
3 <data>3 <data>
44
5 <record id="view_consolidation_consolidate_form" model="ir.ui.view">5 <record id="view_consolidation_consolidate_form" model="ir.ui.view">
6 <field name="name">account.consolidation.consolidate.form</field>6 <field name="name">account.consolidation.consolidate.form</field>
7 <field name="model">account.consolidation.consolidate</field>7 <field name="model">account.consolidation.consolidate</field>
8 <field name="type">form</field>8 <field name="type">form</field>
9 <field name="arch" type="xml">9 <field name="arch" type="xml">
10 <form string="Consolidation: Consolidate">10 <form string="Consolidation: Consolidate" version="7.0">
11 <group col="4" colspan="6">11 <label string="Run the consolidation for the selected periods and subsidiaries."/>
12 <field name="company_id" on_change="on_change_company_id(company_id)" invisible="True"/>12 <group>
13 <field name="fiscalyear_id" invisible="True"/>13 <field name="company_id"
14 <field name="from_period_id" on_change="on_change_from_period_id(from_period_id, to_period_id)" domain="[('company_id', '=', company_id)]"/>14 on_change="on_change_company_id(company_id)"
15 <field name="to_period_id" domain="[('company_id', '=', company_id)]"/>15 invisible="True"/>
16 <field name="journal_id" domain="[('company_id', '=', company_id)]"/>16 <field name="fiscalyear_id" invisible="True"/>
17 <field name="target_move"/>17 <field name="from_period_id"
18 <separator string="Holding Chart of Accounts" colspan="4"/>18 on_change="on_change_from_period_id(from_period_id, to_period_id)"
19 <field name="holding_chart_account_id" domain="[('company_id', '=', company_id), ('parent_id', '=', False)]"/>19 domain="[('company_id', '=', company_id)]"/>
20 <field name="to_period_id"
21 domain="[('company_id', '=', company_id)]"/>
22 <field name="journal_id"
23 domain="[('company_id', '=', company_id)]"/>
24 <field name="target_move"/>
25 <separator string="Holding Chart of Accounts" colspan="4"/>
26 <field name="holding_chart_account_id"
27 domain="[('company_id', '=', company_id), ('parent_id', '=', False)]"/>
2028
21 <!--<separator string="Consolidation Difference Accounts" colspan="4"/>-->29 <separator string="Subsidiaries to Consolidate" colspan="4"/>
22 <!--<field name="gain_account_id" domain="[('type','&lt;&gt;','view'), ('id', 'child_of', [holding_chart_account_id])]"/>-->30 <field name="subsidiary_ids" colspan="4"
23 <!--<field name="loss_account_id" domain="[('type','&lt;&gt;','view'), ('id', 'child_of', [holding_chart_account_id])]"/>-->31 nolabel="1" required="True">
24 <separator string="Subsidiaries to Consolidate" colspan="4"/>32 <tree>
25 <field name="subsidiary_ids" colspan="4" nolabel="1" required="True">33 <field name="name"/>
26 <tree>34 <field name="consolidation_chart_account_id"/>
27 <field name="name"/>35 </tree>
28 <field name="consolidation_chart_account_id"/>36 </field>
29 </tree>37 </group>
30 </field>38 <separator colspan="4"/>
31 </group>39 <footer>
32 <separator colspan="4"/>40 <button name="run_consolidation"
33 <group col="2" colspan="4">41 string="Consolidate"
34 <button special="cancel" string="Cancel" icon='gtk-cancel'/>42 type="object"
35 <button name="run_consolidation" string="Consolidate" colspan="1" type="object" icon="gtk-execute"/>43 class="oe_highlight"/>
36 </group>44 or
37 </form>45 <button string="Cancel" class="oe_link" special="cancel"/>
46 </footer>
47 </form>
38 </field>48 </field>
39 </record>49 </record>
4050
@@ -44,9 +54,8 @@
44 <field name="res_model">account.consolidation.consolidate</field>54 <field name="res_model">account.consolidation.consolidate</field>
45 <field name="view_type">form</field>55 <field name="view_type">form</field>
46 <field name="view_mode">form</field>56 <field name="view_mode">form</field>
47 <field name="help">Run the consolidation for the selected periods and subsidiaries.</field>
48 <field name="target">new</field>57 <field name="target">new</field>
49 </record>58 </record>
5059
51 </data>60 </data>
52</openerp>61</openerp>
5362
=== added directory 'account_parallel_currency'
=== added file 'account_parallel_currency/AUTHORS.txt'
--- account_parallel_currency/AUTHORS.txt 1970-01-01 00:00:00 +0000
+++ account_parallel_currency/AUTHORS.txt 2014-06-26 13:58:55 +0000
@@ -0,0 +1,1 @@
1Lorenzo Battistini <lorenzo.battistini@agilebg.com>
02
=== added file 'account_parallel_currency/__init__.py'
--- account_parallel_currency/__init__.py 1970-01-01 00:00:00 +0000
+++ account_parallel_currency/__init__.py 2014-06-26 13:58:55 +0000
@@ -0,0 +1,23 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# Copyright (C) 2012 Agile Business Group sagl (<http://www.agilebg.com>)
5# Copyright (C) 2012 Domsense srl (<http://www.domsense.com>)
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as published
9# by the Free Software Foundation, either version 3 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21import account
22import res_company
23import wizard
024
=== added file 'account_parallel_currency/__openerp__.py'
--- account_parallel_currency/__openerp__.py 1970-01-01 00:00:00 +0000
+++ account_parallel_currency/__openerp__.py 2014-06-26 13:58:55 +0000
@@ -0,0 +1,56 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# Copyright (C) 2012-2013 Agile Business Group sagl
5# (<http://www.agilebg.com>)
6# Copyright (C) 2012 Domsense srl (<http://www.domsense.com>)
7#
8# This program is free software: you can redistribute it and/or modify
9# it under the terms of the GNU Affero General Public License as published
10# by the Free Software Foundation, either version 3 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU Affero General Public License for more details.
17#
18# You should have received a copy of the GNU Affero General Public License
19# along with this program. If not, see <http://www.gnu.org/licenses/>.
20#
21##############################################################################
22{
23 'name': "Account Parallel Currency",
24 'version': '0.2',
25 'category': 'Generic Modules/Accounting',
26 'description': """
27This module handles parallel accounting entries based on different currencies.
28It 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.
29
30In 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.
31
32A '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.
33
34When posting new journal entries, the system checks the configured parallel accounts and automatically generates the parallel entries.
35This 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.
36""",
37 'author': 'Agile Business Group',
38 'website': 'http://www.agilebg.com',
39 'license': 'AGPL-3',
40 "depends" : ['account'],
41 "data" : [
42 'account_view.xml',
43 'company_view.xml',
44 'wizard/do_mapping.xml',
45 'security/security.xml',
46 ],
47 "demo" : [
48 'account_demo.xml',
49 ],
50 'test': [
51 'test/mapping_parallel_accounts.yml',
52 'test/customer_invoice.yml',
53 ],
54 "active": False,
55 "installable": True
56}
057
=== added file 'account_parallel_currency/account.py'
--- account_parallel_currency/account.py 1970-01-01 00:00:00 +0000
+++ account_parallel_currency/account.py 2014-06-26 13:58:55 +0000
@@ -0,0 +1,506 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# Copyright (C) 2012-2013 Agile Business Group sagl
5# (<http://www.agilebg.com>)
6# Copyright (C) 2012 Domsense srl (<http://www.domsense.com>)
7#
8# This program is free software: you can redistribute it and/or modify
9# it under the terms of the GNU Affero General Public License as published
10# by the Free Software Foundation, either version 3 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU Affero General Public License for more details.
17#
18# You should have received a copy of the GNU Affero General Public License
19# along with this program. If not, see <http://www.gnu.org/licenses/>.
20#
21##############################################################################
22
23from openerp.osv import fields, orm
24from tools.translate import _
25import logging
26from openerp import SUPERUSER_ID
27
28_logger = logging.getLogger(__name__)
29
30
31class account_account(orm.Model):
32 _inherit = "account.account"
33
34 def _get_parallel_accounts_summary(self, cr, uid, ids, field_name, arg, context=None):
35 res = {}
36 for account in self.browse(cr, SUPERUSER_ID, ids, context):
37 text = 'Configured parallel accounts:\n'
38 text2 = ''
39 for parallel_account in account.parallel_account_ids:
40 text2 += _('Account code: %s. Company: %s\n') % (
41 parallel_account.code, parallel_account.company_id.name)
42 if text2:
43 res[account.id] = text + text2
44 else:
45 res[account.id] = _("No parallel accounts found")
46 return res
47
48 _columns = {
49 'parallel_account_ids': fields.many2many('account.account',
50 'parallel_account_rel', 'parent_id',
51 'child_id', 'Parallel Currency Accounts',
52 Help="""Set here the accounts you want to automatically move when
53 registering entries in this account"""),
54 'master_parallel_account_ids': fields.many2many('account.account',
55 'parallel_account_rel', 'child_id',
56 'parent_id', 'Master Parallel Currency Accounts',
57 Help="You can see here the accounts that automatically move this account",
58 readonly=True),
59 'parallel_accounts_summary': fields.function(
60 _get_parallel_accounts_summary, type='text',
61 string='Parallel accounts summary'),
62 }
63
64 def _search_parallel_account(self, cr, uid, account_code, parallel_company,
65 context=None):
66 parallel_acc_ids = self.search(cr, uid, [
67 ('company_id', '=', parallel_company.id),
68 ('code', '=', account_code),
69 ], context=context)
70 if len(parallel_acc_ids) > 1:
71 raise orm.except_orm(_('Error'), _('Too many accounts %s for company %s')
72 % (account_code, parallel_company.name))
73 return parallel_acc_ids and parallel_acc_ids[0] or False
74
75 def _build_account_vals(self, cr, uid, account_vals, parallel_company, context=None):
76 # build only fields I need
77 vals = {}
78 if 'name' in account_vals:
79 vals['name'] = account_vals['name']
80 if 'code' in account_vals:
81 vals['code'] = account_vals['code']
82 if 'type' in account_vals:
83 vals['type'] = account_vals['type']
84 if 'user_type' in account_vals:
85 vals['user_type'] = account_vals['user_type']
86 if 'active' in account_vals:
87 vals['active'] = account_vals['active']
88 if 'parent_id' in account_vals:
89 parent_account = self.browse(cr, uid, account_vals['parent_id'], context)
90 parent_parallel_acc_id = self._search_parallel_account(
91 cr, uid, parent_account.code, parallel_company, context=context)
92 if not parent_parallel_acc_id:
93 raise orm.except_orm(_('Error'),
94 _('No parent account %s found in company %s') %
95 (parent_account.code, parallel_company.name))
96 vals['parent_id'] = parent_parallel_acc_id
97 return vals
98
99 def _prepare_parallel_account(self, cr, uid, parallel_company, account, context):
100 parent_parallel_acc_id = self._search_parallel_account(
101 cr, SUPERUSER_ID, account.parent_id.code, parallel_company,
102 context=context)
103 return {'company_id': parallel_company.id,
104 'parent_id': parent_parallel_acc_id,
105 'name': account.name,
106 'code': account.code,
107 'type': account.type,
108 'user_type': account.user_type and account.user_type.id or False,
109 'active': account.active,
110 }
111
112 def create_parallel_accounts(self, cr, uid, ids, context=None):
113 for account in self.browse(cr, SUPERUSER_ID, ids, context):
114 for parallel_company in account.company_id.parallel_company_ids:
115 account_val = self._prepare_parallel_account(cr, uid,
116 parallel_company,
117 account,
118 context)
119 new_id = self.create(cr, SUPERUSER_ID, account_val, context=context)
120 cr.execute("INSERT INTO parallel_account_rel(parent_id, child_id) VALUES (%d, %d)",
121 (account.id, new_id))
122 return True
123
124 '''
125 def sync_parallel_accounts(self, cr, uid, ids, vals={}, context=None):
126 for account in self.browse(cr, uid, ids, context):
127 new_parallel_acc_ids = []
128 company_id = vals.get('company_id') or account.company_id.id
129 code = vals.get('code') or account.code
130 company = self.pool.get('res.company').browse(cr, uid, company_id, context)
131 for parallel_company in company.parallel_company_ids:
132 parallel_acc_id = self._search_parallel_account(
133 cr, uid, code, parallel_company, context=context)
134 if not parallel_acc_id:
135 # Then I create it, linked to parent account
136 #parallel_acc_id = self.create(cr, uid,
137 #self._build_account_vals(cr, uid,
138 #vals, parallel_company, context=context), context=context)
139 pass
140 else:
141 super(account_account,self).write(cr, uid, [parallel_acc_id],
142 self._build_account_vals(cr, uid,
143 vals, parallel_company, context=context), context)
144 _logger.info(
145 _("Parallel account %s (company %s) written") %
146 (code, parallel_company.name))
147 new_parallel_acc_ids.append(parallel_acc_id)
148 return new_parallel_acc_ids
149 '''
150
151 def write(self, cr, uid, ids, vals, context=None):
152 if 'parallel_account_ids' not in vals:
153 # write/create parallel accounts only if 'parallel_account_ids' not explicity written
154 for acc_id in ids:
155 account = self.browse(cr, SUPERUSER_ID, acc_id, context)
156 for parallel_account in account.parallel_account_ids:
157 parallel_vals = self._build_account_vals(
158 cr, SUPERUSER_ID, vals, parallel_account.company_id,
159 context=context)
160 parallel_account.write(parallel_vals)
161 res=super(account_account,self).write(cr, uid, ids, vals, context=context)
162 return res
163
164 def create(self, cr, uid, vals, context=None):
165 res=super(account_account,self).create(cr, uid, vals, context)
166 self.create_parallel_accounts(cr, uid, [res], context=None)
167 return res
168
169 def unlink(self, cr, uid, ids, context=None):
170 for account in self.browse(cr, SUPERUSER_ID, ids, context):
171 for parallel_account in account.parallel_account_ids:
172 parallel_account.unlink()
173 res=super(account_account,self).unlink(cr, uid, ids, context=context)
174 return res
175
176class account_move(orm.Model):
177 _inherit = "account.move"
178
179 _columns = {
180 'parallel_move_ids': fields.one2many('account.move', 'master_parallel_move_id', 'Parallel Entries',
181 readonly=True),
182 'master_parallel_move_id': fields.many2one('account.move', 'Master Parallel Entry'),
183 }
184
185 def button_cancel(self, cr, uid, ids, context=None):
186 res = super(account_move, self).button_cancel(cr, uid, ids, context=context)
187 for move in self.browse(cr, SUPERUSER_ID, ids, context=context):
188 for parallel_move in move.parallel_move_ids:
189 parallel_move.button_cancel(context=context)
190 parallel_move.unlink(context=context)
191 return res
192
193 def lines_balance(self, move_lines):
194 """
195 returns 0 if lines are balanced, difference if unbalanced
196 """
197 balance = 0.0
198 for line_tuple in move_lines:
199 balance += line_tuple[2]['debit'] or (- line_tuple[2]['credit']) or 0.0
200 return balance
201
202 def balance_lines(self, cr, uid, move_lines, currency_id, context=None):
203 """
204 Balance move lines that were unbalanced due to roundings.
205 """
206 balance = self.lines_balance(move_lines)
207 acc_pool = self.pool.get('account.account')
208 curr_pool = self.pool.get('res.currency')
209 if curr_pool.is_zero(cr, uid, curr_pool.browse(cr, uid, currency_id), balance):
210 return move_lines
211 else:
212 found = False
213 for line_tuple in move_lines:
214 account = acc_pool.browse(cr, uid, line_tuple[2]['account_id'], context)
215 # search for liquidity, receivable or payable accounts
216 # beacause usually they are the result of operations (invoice total).
217 # So, if we made the invoice in parallel currency, we'd get that different invoice total
218 if account.type == 'liquidity' or account.type == 'receivable' or account.type == 'payable':
219 if line_tuple[2]['debit']:
220 line_tuple[2]['debit'] -= balance
221 found = True
222 break
223 elif line_tuple[2]['credit']:
224 line_tuple[2]['credit'] += balance
225 found = True
226 break
227 if not found:
228 # if no liquidity, receivable or payable accounts are present, we use the first line (randomly).
229 # TODO check if this makes sense
230 if move_lines[0][2]['debit']:
231 move_lines[0][2]['debit'] -= balance
232 elif move_lines[0][2]['credit']:
233 move_lines[0][2]['credit'] += balance
234 return move_lines
235
236 def post(self, cr, uid, ids, context=None):
237 res = super(account_move, self).post(cr, uid, ids, context=context)
238 if context is None:
239 context = {}
240 curr_pool = self.pool.get('res.currency')
241 company_pool = self.pool.get('res.company')
242 uid = SUPERUSER_ID
243 for move in self.browse(cr, uid, ids, context=context):
244 if move.state == 'posted' and not move.parallel_move_ids:
245 # avoid double post in case of 'Skip Draft State for Manual Entries'