Merge lp:~unifield-team/unifield-wm/UF_1981 into lp:unifield-wm

Proposed by jftempo
Status: Merged
Merged at revision: 1815
Proposed branch: lp:~unifield-team/unifield-wm/UF_1981
Merge into: lp:unifield-wm
Diff against target: 2503 lines (+1666/-613)
32 files modified
account_override/__init__.py (+0/-1)
account_override/__openerp__.py (+0/-4)
account_override/account.py (+2/-2)
account_override/account_export_mapping.py (+0/-65)
account_override/account_export_mapping_view.xml (+0/-74)
account_override/account_report.xml (+0/-13)
account_override/report/__init__.py (+1/-2)
account_override/report/report_hq_export.py (+0/-347)
account_override/security/ir.model.access.csv (+0/-2)
account_override/wizard/__init__.py (+0/-1)
account_override/wizard/wizard_hq_report.py (+0/-57)
account_override/wizard/wizard_hq_report_view.xml (+0/-35)
account_override/wizard/wizard_import_mapping.py (+26/-10)
msf_profile/__openerp__.py (+1/-0)
vertical_integration/__init__.py (+28/-0)
vertical_integration/__openerp__.py (+45/-0)
vertical_integration/account_export_mapping.py (+65/-0)
vertical_integration/account_export_mapping_view.xml (+74/-0)
vertical_integration/account_report.xml (+22/-0)
vertical_integration/country_export_mapping.py (+65/-0)
vertical_integration/country_export_mapping_view.xml (+61/-0)
vertical_integration/report/__init__.py (+2/-0)
vertical_integration/report/hq_report_oca.py (+335/-0)
vertical_integration/report/hq_report_ocg.py (+291/-0)
vertical_integration/report/open_invoices_xls.mako (+382/-0)
vertical_integration/report/report_open_invoices.py (+77/-0)
vertical_integration/security/ir.model.access.csv (+3/-0)
vertical_integration/wizard/__init__.py (+2/-0)
vertical_integration/wizard/wizard_hq_report_oca.py (+57/-0)
vertical_integration/wizard/wizard_hq_report_oca_view.xml (+35/-0)
vertical_integration/wizard/wizard_hq_report_ocg.py (+57/-0)
vertical_integration/wizard/wizard_hq_report_ocg_view.xml (+35/-0)
To merge this branch: bzr merge lp:~unifield-team/unifield-wm/UF_1981
Reviewer Review Type Date Requested Status
UniField Dev Team Pending
Review via email: mp+191955@code.launchpad.net
To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'account_override/__init__.py'
2--- account_override/__init__.py 2013-04-22 14:17:10 +0000
3+++ account_override/__init__.py 2013-10-21 09:56:54 +0000
4@@ -28,7 +28,6 @@
5 import account_move_line
6 import account_analytic_line
7 import account_bank_statement
8-import account_export_mapping
9 import report
10 import wizard
11
12
13=== modified file 'account_override/__openerp__.py'
14--- account_override/__openerp__.py 2013-04-22 14:17:10 +0000
15+++ account_override/__openerp__.py 2013-10-21 09:56:54 +0000
16@@ -32,16 +32,12 @@
17 "init_xml" : ["data.xml",],
18 "demo_xml" : [],
19 "update_xml" : [
20- 'security/ir.model.access.csv',
21 'account_invoice_workflow.xml',
22 'account_view.xml',
23 'account_invoice_view.xml',
24 'account_invoice_report.xml',
25 'account_analytic_line_view.xml',
26- 'account_export_mapping_view.xml',
27- 'account_report.xml',
28 'account_sequence.xml',
29- 'wizard/wizard_hq_report_view.xml',
30 ],
31 'test': [],
32 'installable': True,
33
34=== modified file 'account_override/account.py'
35--- account_override/account.py 2013-08-30 13:00:25 +0000
36+++ account_override/account.py 2013-10-21 09:56:54 +0000
37@@ -76,13 +76,13 @@
38 that could be attached. For an example make the account to be a transfer type will display only registers to the user in the Cash Register
39 when he add a new register line.
40 """),
41- 'is_settled_at_hq': fields.boolean("Settled at HQ"),
42+ 'shrink_entries_for_hq': fields.boolean("Shrink entries for HQ export", help="Check this attribute if you want to consolidate entries on this account before they are exported to the HQ system."),
43 'filter_active': fields.function(_get_active, fnct_search=_search_filter_active, type="boolean", method=True, store=False, string="Show only active accounts",),
44 }
45
46 _defaults = {
47 'type_for_register': lambda *a: 'none',
48- 'is_settled_at_hq': lambda *a: False,
49+ 'shrink_entries_for_hq': lambda *a: True,
50 }
51
52 # UTP-493: Add a dash between code and account name
53
54=== removed file 'account_override/account_export_mapping.py'
55--- account_override/account_export_mapping.py 2013-04-29 13:34:46 +0000
56+++ account_override/account_export_mapping.py 1970-01-01 00:00:00 +0000
57@@ -1,65 +0,0 @@
58-#!/usr/bin/env python
59-#-*- encoding:utf-8 -*-
60-##############################################################################
61-#
62-# OpenERP, Open Source Management Solution
63-# Copyright (C) 2011 TeMPO Consulting, MSF. All Rights Reserved
64-#
65-# This program is free software: you can redistribute it and/or modify
66-# it under the terms of the GNU Affero General Public License as
67-# published by the Free Software Foundation, either version 3 of the
68-# License, or (at your option) any later version.
69-#
70-# This program is distributed in the hope that it will be useful,
71-# but WITHOUT ANY WARRANTY; without even the implied warranty of
72-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
73-# GNU Affero General Public License for more details.
74-#
75-# You should have received a copy of the GNU Affero General Public License
76-# along with this program. If not, see <http://www.gnu.org/licenses/>.
77-#
78-##############################################################################
79-
80-from osv import osv, fields
81-
82-class account_export_mapping(osv.osv):
83- _name = 'account.export.mapping'
84- _description = 'Mapping of UF code into AX code'
85- _rec_name = 'account_id'
86-
87- _columns = {
88- 'account_id': fields.many2one('account.account', string="Unifield Account Code", required=True),
89- 'mapping_value': fields.char('HQ System Account Code', required=True, size=64)
90- }
91-
92- def _check_unicity(self, cr, uid, ids, context=None):
93- if not context:
94- context = {}
95- for line in self.browse(cr, uid, ids, context=context):
96- bad_ids = self.search(cr, uid, [('account_id', '=', line.account_id and line.account_id.id or False)])
97- if len(bad_ids) and len(bad_ids) > 1:
98- return False
99- return True
100-
101- _constraints = [
102- (_check_unicity, "A mapping already exists for this account", ['account_id']),
103- ]
104-
105- def menu_import_wizard(self, cr, uid, ids, context=None):
106- if context is None:
107- context = {}
108- wiz_obj = self.pool.get('wizard.import.mapping')
109- wiz_id = wiz_obj.create(cr, uid, {}, context=context)
110- # we open a wizard
111- return {
112- 'type': 'ir.actions.act_window',
113- 'res_model': 'wizard.import.mapping',
114- 'view_type': 'form',
115- 'view_mode': 'form',
116- 'target': 'new',
117- 'res_id': [wiz_id],
118- 'context': context,
119- }
120-
121-account_export_mapping()
122-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
123
124=== removed file 'account_override/account_export_mapping_view.xml'
125--- account_override/account_export_mapping_view.xml 2013-04-29 13:34:46 +0000
126+++ account_override/account_export_mapping_view.xml 1970-01-01 00:00:00 +0000
127@@ -1,74 +0,0 @@
128-<?xml version="1.0" encoding="UTF-8"?>
129-<openerp>
130- <data>
131-
132- <record model="ir.ui.view" id="export_mapping_search_view">
133- <field name="name">export.mapping.search</field>
134- <field name="model">account.export.mapping</field>
135- <field name="type">search</field>
136- <field name="arch" type="xml">
137- <search>
138- <field name="account_id"/>
139- <field name="mapping_value"/>
140- </search>
141- </field>
142- </record>
143-
144- <record model="ir.ui.view" id="export_mapping_tree_view">
145- <field name="name">export.mapping.tree</field>
146- <field name="model">account.export.mapping</field>
147- <field name="type">tree</field>
148- <field name="arch" type="xml">
149- <tree string="Account Mapping">
150- <field name="account_id" />
151- <field name="mapping_value"/>
152- </tree>
153- </field>
154- </record>
155-
156- <record model="ir.ui.view" id="export_mapping_form_view">
157- <field name="name">export.mapping.form</field>
158- <field name="model">account.export.mapping</field>
159- <field name="type">form</field>
160- <field name="arch" type="xml">
161- <form string="Account Mapping">
162- <field name="account_id" />
163- <field name="mapping_value"/>
164- </form>
165- </field>
166- </record>
167-
168- <record model="ir.actions.act_window" id="export_mapping_action">
169- <field name="name">Account Mapping</field>
170- <field name="res_model">account.export.mapping</field>
171- <field name="view_type">form</field>
172- <field name="view_mode">tree,form</field>
173- </record>
174-
175- <menuitem id="export_mapping_menu" name="Account Mapping" parent="account.account_account_menu"
176- action="export_mapping_action" />
177-
178- <record id="import_account_mappings_view" model="ir.ui.view">
179- <field name="name">Import Mappings</field>
180- <field name="model">wizard.import.mapping</field>
181- <field name="type">form</field>
182- <field name="arch" type="xml">
183- <form string="Import Mappings">
184- <field name="import_file"/>
185- <button icon="gtk-cancel" special="cancel" string="Cancel"/>
186- <button icon="terp-camera_test" string="Import" name="import_account_mappings" type="object" default_focus="1"/>
187- </form>
188- </field>
189- </record>
190-
191- <act_window name="Import Mappings"
192- res_model="wizard.import.mapping"
193- src_model="account.export.mapping"
194- view_mode="form"
195- target="new"
196- key2="client_action_multi"
197- empty_ids="1"
198- id="action_import_account_mappings"/>
199-
200- </data>
201-</openerp>
202\ No newline at end of file
203
204=== removed file 'account_override/account_report.xml'
205--- account_override/account_report.xml 2013-04-16 15:02:04 +0000
206+++ account_override/account_report.xml 1970-01-01 00:00:00 +0000
207@@ -1,13 +0,0 @@
208-<?xml version="1.0" encoding="utf-8"?>
209-<openerp>
210- <data>
211- <report id="hq_export"
212- string="Export to HQ system"
213- model="account.move.line"
214- name="hq.export"
215- report_type="txt"
216- auto="False"
217- menu="False"/>
218- </data>
219-</openerp>
220-
221
222=== modified file 'account_override/report/__init__.py'
223--- account_override/report/__init__.py 2013-04-16 15:02:04 +0000
224+++ account_override/report/__init__.py 2013-10-21 09:56:54 +0000
225@@ -1,2 +1,1 @@
226-import report_open_invoices
227-import report_hq_export
228\ No newline at end of file
229+import report_open_invoices
230\ No newline at end of file
231
232=== removed file 'account_override/report/report_hq_export.py'
233--- account_override/report/report_hq_export.py 2013-05-07 09:19:17 +0000
234+++ account_override/report/report_hq_export.py 1970-01-01 00:00:00 +0000
235@@ -1,347 +0,0 @@
236-# -*- coding: utf-8 -*-
237-##############################################################################
238-#
239-# OpenERP, Open Source Management Solution
240-# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
241-#
242-# This program is free software: you can redistribute it and/or modify
243-# it under the terms of the GNU Affero General Public License as
244-# published by the Free Software Foundation, either version 3 of the
245-# License, or (at your option) any later version.
246-#
247-# This program is distributed in the hope that it will be useful,
248-# but WITHOUT ANY WARRANTY; without even the implied warranty of
249-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
250-# GNU Affero General Public License for more details.
251-#
252-# You should have received a copy of the GNU Affero General Public License
253-# along with this program. If not, see <http://www.gnu.org/licenses/>.
254-#
255-##############################################################################
256-
257-import datetime
258-import csv
259-import StringIO
260-import pooler
261-import zipfile
262-from tempfile import NamedTemporaryFile
263-import os
264-
265-from report import report_sxw
266-
267-class report_hq_export(report_sxw.report_sxw):
268-
269- def __init__(self, name, table, rml=False, parser=report_sxw.rml_parse, header='external', store=False):
270- report_sxw.report_sxw.__init__(self, name, table, rml=rml, parser=parser, header=header, store=store)
271-
272- def _enc(self, st):
273- if isinstance(st, unicode):
274- return st.encode('utf8')
275- return st
276-
277- def translate_account(self, cr, uid, pool, browse_account, context={}):
278- mapping_obj = pool.get('account.export.mapping')
279- if browse_account:
280- mapping_ids = mapping_obj.search(cr, uid, [('account_id', '=', browse_account.id)], context=context)
281- if len(mapping_ids) > 0:
282- mapping = mapping_obj.browse(cr, uid, mapping_ids[0], context=context)
283- return mapping.mapping_value
284- else:
285- return browse_account.code
286- return ""
287-
288-# Commented for OCG, but can be useful for other OCs
289-# def create_counterpart(self, cr, uid, line_key, line_debit, counterpart_date, period_name):
290-# pool = pooler.get_pool(cr.dbname)
291-# # method to create counterpart line
292-# if len(line_key) > 3 and line_debit != 0.0:
293-# journal = pool.get('account.journal').browse(cr, uid, line_key[1])
294-# currency = pool.get('res.currency').browse(cr, uid, line_key[2])
295-# return [journal.instance_id and journal.instance_id.code or "",
296-# line_key[0],
297-# "",
298-# line_key[3],
299-# "",
300-# counterpart_date,
301-# counterpart_date,
302-# period_name,
303-# "10100055 - Buffer Account",
304-# "",
305-# "",
306-# "",
307-# line_debit > 0 and "0.00" or round(-line_debit, 2),
308-# line_debit > 0 and round(line_debit, 2) or "0.00",
309-# currency.name]
310-
311- def create_subtotal(self, cr, uid, line_key, line_debit, counterpart_date, period_name, department_info):
312- pool = pooler.get_pool(cr.dbname)
313- # method to create subtotal + counterpart line
314- if len(line_key) > 2 and line_debit != 0.0:
315- journal = pool.get('account.journal').browse(cr, uid, line_key[1])
316- currency = pool.get('res.currency').browse(cr, uid, line_key[2])
317- description = ""
318- # Description for the line
319- if line_key[0] == "1000 0000":
320- description = "Mvts_BANK_" + period_name + "_" + currency.name
321- elif line_key[0] == "1000 0001":
322- description = "Mvts_CASH_" + period_name + "_" + currency.name
323- else:
324- mapping_obj = pool.get('account.export.mapping')
325- account_values = ""
326- mapping_ids = mapping_obj.search(cr, uid, [('mapping_value', '=', line_key[0])], context={})
327- for mapping in mapping_obj.browse(cr, uid, mapping_ids, context={}):
328- if account_values != "":
329- account_values += "-"
330- account_values += mapping.account_id.code
331- description = "Mvts_" + account_values + period_name + journal.code + "_" + currency.name
332-
333- return [[journal.instance_id and journal.instance_id.code or "",
334- journal.code,
335- "",
336- description,
337- "",
338- counterpart_date,
339- counterpart_date,
340- period_name,
341- line_key[0],
342- "",
343- department_info,
344- "",
345- "",
346- line_debit > 0 and round(line_debit, 2) or "0.00",
347- line_debit > 0 and "0.00" or round(-line_debit, 2),
348- currency.name]]
349-# Commented for OCG, but can be useful for other OCs
350-# ,[journal.instance_id and journal.instance_id.code or "",
351-# journal.code,
352-# "",
353-# "",
354-# "",
355-# counterpart_date,
356-# counterpart_date,
357-# period_name,
358-# "10100055 - Buffer Account",
359-# "",
360-# "",
361-# "",
362-# line_debit > 0 and "0.00" or round(-line_debit, 2),
363-# line_debit > 0 and round(line_debit, 2) or "0.00",
364-# currency.name]]
365-
366- def create(self, cr, uid, ids, data, context=None):
367- pool = pooler.get_pool(cr.dbname)
368- # Create the header
369- first_header = ['Proprietary Instance',
370- 'Journal Code',
371- 'Entry Sequence',
372- 'Description',
373- 'Reference',
374- 'Document Date',
375- 'Posting Date',
376- 'Period',
377- 'G/L Account',
378- 'Unifield Account',
379- 'Destination',
380- 'Cost Centre',
381- 'Funding Pool',
382- 'Third Parties',
383- 'Booking Debit',
384- 'Booking Credit',
385- 'Booking Currency',
386- 'Functional Debit',
387- 'Functional Credit',
388- 'Functional Currency']
389-
390- second_header = ['Proprietary Instance',
391- 'Journal Code',
392- 'Entry Sequence',
393- 'Description',
394- 'Reference',
395- 'Document Date',
396- 'Posting Date',
397- 'Period',
398- 'G/L Account',
399- 'Destination',
400- 'Department',
401- 'Cost Centre',
402- 'Third Parties',
403- 'Booking Debit',
404- 'Booking Credit',
405- 'Booking Currency']
406-
407- # Initialize lists: one for the first report...
408- first_result_lines = []
409- # ...and subdivisions for the second report.
410- second_result_lines = []
411- main_lines = {}
412- main_lines_debit = {}
413- account_lines_debit = {}
414- # Get department info code: 3 first characters of main instance's code
415- department_info = ""
416- if len(data['form']['instance_ids']) > 0:
417- parent_instance = pool.get('msf.instance').browse(cr, uid, data['form']['instance_ids'][0], context=context)
418- if parent_instance:
419- department_info = parent_instance.code[:3]
420-
421-
422- move_line_ids = pool.get('account.move.line').search(cr, uid, [('period_id', '=', data['form']['period_id']),
423- ('instance_id', 'in', data['form']['instance_ids']),
424- ('analytic_distribution_id', '=', False),
425- ('journal_id.type', 'not in', ['hq', 'cur_adj', 'inkind'])], context=context)
426-
427- for move_line in pool.get('account.move.line').browse(cr, uid, move_line_ids, context=context):
428- journal = move_line.journal_id
429- account = move_line.account_id
430- currency = move_line.currency_id
431- # For first report: as if
432- formatted_data = [move_line.instance_id and move_line.instance_id.code or "",
433- journal and journal.code or "",
434- move_line.move_id and move_line.move_id.name or "",
435- move_line.name,
436- move_line.ref,
437- datetime.datetime.strptime(move_line.document_date, '%Y-%m-%d').date().strftime('%d/%m/%Y'),
438- datetime.datetime.strptime(move_line.date, '%Y-%m-%d').date().strftime('%d/%m/%Y'),
439- move_line.period_id and move_line.period_id.code or "",
440- self.translate_account(cr, uid, pool, account),
441- account and account.code + " " + account.name,
442- "",
443- "",
444- "",
445- move_line.partner_txt,
446- round(move_line.debit_currency, 2),
447- round(move_line.credit_currency, 2),
448- currency and currency.name or "",
449- round(move_line.debit, 2),
450- round(move_line.credit, 2),
451- move_line.functional_currency_id and move_line.functional_currency_id.name or ""]
452- first_result_lines.append(formatted_data)
453-
454- # For second report: add to corresponding sub
455- if journal.type in ['correction', 'intermission'] or account.is_settled_at_hq:
456- if (journal.code, journal.id, currency.id) not in main_lines:
457- main_lines[(journal.code, journal.id, currency.id)] = []
458- main_lines[(journal.code, journal.id, currency.id)].append(formatted_data[:9] + [formatted_data[10]] + [department_info] + formatted_data[11:12] + formatted_data[13:17])
459- else:
460- translated_account_code = self.translate_account(cr, uid, pool, account)
461- if (translated_account_code, journal.id, currency.id) not in account_lines_debit:
462- account_lines_debit[(translated_account_code, journal.id, currency.id)] = 0.0
463- account_lines_debit[(translated_account_code, journal.id, currency.id)] += (move_line.debit_currency - move_line.credit_currency)
464-
465-
466-
467- cur_adj_journal_ids = pool.get('account.journal').search(cr, uid, [('type', '=', 'cur_adj')], context=context)
468- ana_cur_journal_ids = []
469- for journal in pool.get('account.journal').browse(cr, uid, cur_adj_journal_ids, context=context):
470- if journal.analytic_journal_id and journal.analytic_journal_id.id not in ana_cur_journal_ids:
471- ana_cur_journal_ids.append(journal.analytic_journal_id.id)
472-
473- analytic_line_ids = pool.get('account.analytic.line').search(cr, uid, [('period_id', '=', data['form']['period_id']),
474- ('instance_id', 'in', data['form']['instance_ids']),
475- ('journal_id.type', 'not in', ['hq', 'engagement', 'inkind']),
476- ('journal_id', 'not in', ana_cur_journal_ids)], context=context)
477- for analytic_line in pool.get('account.analytic.line').browse(cr, uid, analytic_line_ids, context=context):
478- journal = analytic_line.move_id and analytic_line.move_id.journal_id
479- account = analytic_line.general_account_id
480- currency = analytic_line.currency_id
481- # For first report: as is
482- formatted_data = [analytic_line.instance_id and analytic_line.instance_id.code or "",
483- analytic_line.journal_id and analytic_line.journal_id.code or "",
484- analytic_line.move_id and analytic_line.move_id.move_id and analytic_line.move_id.move_id.name or "",
485- analytic_line.name or "",
486- analytic_line.ref or "",
487- datetime.datetime.strptime(analytic_line.document_date, '%Y-%m-%d').date().strftime('%d/%m/%Y'),
488- datetime.datetime.strptime(analytic_line.date, '%Y-%m-%d').date().strftime('%d/%m/%Y'),
489- analytic_line.period_id and analytic_line.period_id.code or "",
490- account and account.code,
491- account and account.code + " " + account.name or "",
492- analytic_line.destination_id and analytic_line.destination_id.code or "",
493- analytic_line.cost_center_id and analytic_line.cost_center_id.code or "",
494- analytic_line.account_id and analytic_line.account_id.code or "",
495- analytic_line.partner_txt or "",
496- analytic_line.amount_currency > 0 and "0.00" or round(-analytic_line.amount_currency, 2),
497- analytic_line.amount_currency > 0 and round(analytic_line.amount_currency, 2) or "0.00",
498- currency and currency.name or "",
499- analytic_line.amount > 0 and "0.00" or round(-analytic_line.amount, 2),
500- analytic_line.amount > 0 and round(analytic_line.amount, 2) or "0.00",
501- analytic_line.functional_currency_id and analytic_line.functional_currency_id.name or ""]
502- first_result_lines.append(formatted_data)
503-
504- # For second report: add to regular lines
505-
506-# Commented for OCG, but can be useful for other OCs
507-# line_name = ""
508-# if journal.type == 'cash':
509-# line_name = "Tresorerie des missions cash " + journal.code + " - Contrepartie compte d'expense"
510-# elif journal.type == 'bank':
511-# line_name = "Tresorerie des missions banque " + journal.code + " - Contrepartie compte d'expense"
512-# elif journal.type == 'cheque':
513-# line_name = "Tresorerie des missions cheque " + journal.code + " - Contrepartie compte d'expense"
514-# elif account.user_type and account.user_type.code == 'payable':
515-# line_name = "Local A/P - Contrepartie compte d'expense"
516-# elif account.user_type and account.user_type.code == 'receivable':
517-# line_name = "Local A/R - Contrepartie compte d'expense"
518-# elif account.accrual_account:
519-# line_name = "Local accrual - Contrepartie compte d'expense"
520- if (journal.code, journal.id, currency.id) not in main_lines:
521- main_lines[(journal.code, journal.id, currency.id)] = []
522- main_lines[(journal.code, journal.id, currency.id)].append(formatted_data[:9] + [formatted_data[10]] + [department_info] + formatted_data[11:12] + formatted_data[13:17])
523-
524- first_result_lines = sorted(first_result_lines, key=lambda line: line[2])
525- first_report = [first_header] + first_result_lines
526-
527- # Regroup second report lines
528- period = pool.get('account.period').browse(cr, uid, data['form']['period_id'])
529- counterpart_date = period and period.date_stop and \
530- datetime.datetime.strptime(period.date_stop, '%Y-%m-%d').date().strftime('%d/%m/%Y') or ""
531- period_name = period and period.code or ""
532-
533- for key in sorted(main_lines.iterkeys(), key=lambda tuple: tuple[0]):
534- second_result_lines += sorted(main_lines[key], key=lambda line: line[2])
535-
536- for key in sorted(account_lines_debit.iterkeys(), key=lambda tuple: tuple[0]):
537- subtotal_lines = self.create_subtotal(cr, uid, key,
538- account_lines_debit[key],
539- counterpart_date,
540- period_name,
541- department_info)
542- if subtotal_lines:
543- second_result_lines += subtotal_lines
544-
545- second_report = [second_header] + second_result_lines
546-
547- # file names
548- prefix = ""
549- for instance in pool.get('msf.instance').browse(cr, uid, data['form']['instance_ids'], context=context):
550- if instance.level == 'coordo':
551- prefix += instance.top_cost_center_id and instance.top_cost_center_id.code or "xxx"
552- break
553- prefix += "_"
554- period = pool.get('account.period').browse(cr, uid, data['form']['period_id'], context=context)
555- if period and period.date_start:
556- prefix += datetime.datetime.strptime(period.date_start, '%Y-%m-%d').date().strftime('%Y%m')
557- else:
558- prefix += "xxxxxx"
559- prefix += "_"
560-
561- zip_buffer = StringIO.StringIO()
562- first_fileobj = NamedTemporaryFile('w+b', delete=False)
563- second_fileobj = NamedTemporaryFile('w+b', delete=False)
564- writer = csv.writer(first_fileobj, quoting=csv.QUOTE_ALL)
565- for line in first_report:
566- writer.writerow(map(self._enc,line))
567- first_fileobj.close()
568- writer = csv.writer(second_fileobj, quoting=csv.QUOTE_ALL)
569- for line in second_report:
570- writer.writerow(map(self._enc,line))
571- second_fileobj.close()
572- out_zipfile = zipfile.ZipFile(zip_buffer, "w")
573- out_zipfile.write(first_fileobj.name, prefix + "raw data UF export.csv", zipfile.ZIP_DEFLATED)
574- out_zipfile.write(second_fileobj.name, prefix + "formatted data AX import.csv", zipfile.ZIP_DEFLATED)
575- out_zipfile.close()
576- out = zip_buffer.getvalue()
577- os.unlink(first_fileobj.name)
578- os.unlink(second_fileobj.name)
579- return (out, 'zip')
580-
581-report_hq_export('report.hq.export', 'account.move.line', False, parser=False)
582-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
583
584=== removed directory 'account_override/security'
585=== removed file 'account_override/security/ir.model.access.csv'
586--- account_override/security/ir.model.access.csv 2013-04-22 14:17:10 +0000
587+++ account_override/security/ir.model.access.csv 1970-01-01 00:00:00 +0000
588@@ -1,2 +0,0 @@
589-"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
590-"access_account_mapping_all","account.export.mapping","model_account_export_mapping","",1,1,1,1
591
592=== modified file 'account_override/wizard/__init__.py'
593--- account_override/wizard/__init__.py 2013-04-22 14:17:10 +0000
594+++ account_override/wizard/__init__.py 2013-10-21 09:56:54 +0000
595@@ -1,2 +1,1 @@
596-import wizard_hq_report
597 import wizard_import_mapping
598\ No newline at end of file
599
600=== removed file 'account_override/wizard/wizard_hq_report.py'
601--- account_override/wizard/wizard_hq_report.py 2013-04-16 15:02:04 +0000
602+++ account_override/wizard/wizard_hq_report.py 1970-01-01 00:00:00 +0000
603@@ -1,57 +0,0 @@
604-# -*- coding: utf-8 -*-
605-##############################################################################
606-#
607-# OpenERP, Open Source Management Solution
608-# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
609-#
610-# This program is free software: you can redistribute it and/or modify
611-# it under the terms of the GNU Affero General Public License as
612-# published by the Free Software Foundation, either version 3 of the
613-# License, or (at your option) any later version.
614-#
615-# This program is distributed in the hope that it will be useful,
616-# but WITHOUT ANY WARRANTY; without even the implied warranty of
617-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
618-# GNU Affero General Public License for more details.
619-#
620-# You should have received a copy of the GNU Affero General Public License
621-# along with this program. If not, see <http://www.gnu.org/licenses/>.
622-#
623-##############################################################################
624-
625-from osv import fields, osv
626-from tools.translate import _
627-
628-import datetime
629-import base64
630-import StringIO
631-import csv
632-
633-class wizard_hq_report(osv.osv_memory):
634- _name = "wizard.hq.report"
635-
636- _columns = {
637- 'instance_id': fields.many2one('msf.instance', 'Top proprietary instance', required=True),
638- 'fiscalyear_id': fields.many2one('account.fiscalyear', 'Fiscal year', required=True),
639- 'period_id': fields.many2one('account.period', 'Period', required=True)
640- }
641-
642- _defaults = {
643- 'fiscalyear_id': lambda self, cr, uid, c: self.pool.get('account.fiscalyear').find(cr, uid, datetime.datetime.today().strftime('%Y-%m-%d'), context=c)
644- }
645-
646- def button_create_report(self, cr, uid, ids, context=None):
647- wizard = self.browse(cr, uid, ids[0], context=context)
648- data = {}
649- # add parameters
650- data['form'] = {}
651- if wizard.instance_id:
652- # Get projects below instance
653- data['form'].update({'instance_ids': [wizard.instance_id.id] + [x.id for x in wizard.instance_id.child_ids]})
654- if wizard.period_id:
655- data['form'].update({'period_id': wizard.period_id.id})
656-
657- return {'type': 'ir.actions.report.xml', 'report_name': 'hq.export', 'datas': data}
658-
659-wizard_hq_report()
660-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
661
662=== removed file 'account_override/wizard/wizard_hq_report_view.xml'
663--- account_override/wizard/wizard_hq_report_view.xml 2013-04-16 15:02:04 +0000
664+++ account_override/wizard/wizard_hq_report_view.xml 1970-01-01 00:00:00 +0000
665@@ -1,35 +0,0 @@
666-<?xml version="1.0" encoding="UTF-8"?>
667-<openerp>
668- <data>
669-
670- <record id="hq_export_view" model="ir.ui.view">
671- <field name="name">Export to HQ system</field>
672- <field name="model">wizard.hq.report</field>
673- <field name="type">form</field>
674- <field name="arch" type="xml">
675- <form string="Export to HQ system">
676- <field name="instance_id" domain="[('level', '=', 'coordo')]"/>
677- <field name="fiscalyear_id"/>
678- <field name="period_id" domain="[('fiscalyear_id', '=', fiscalyear_id), ('state', 'in', ['mission-closed', 'done'])]"/>
679- <newline/>
680- <button icon="terp-camera_test" string="Export" name="button_create_report" type="object" default_focus="1"/>
681- </form>
682- </field>
683- </record>
684-
685- <record id="action_hq_export" model="ir.actions.act_window">
686- <field name="name">Export to HQ system</field>
687- <field name="type">ir.actions.act_window</field>
688- <field name="res_model">wizard.hq.report</field>
689- <field name="view_type">form</field>
690- <field name="view_mode">form</field>
691- <field name="view_id" ref="hq_export_view"/>
692- <field name="target">new</field>
693- </record>
694-
695- <menuitem parent="account.menu_finance_generic_reporting"
696- action="action_hq_export"
697- id="menu_action_hq_export" sequence="10"/>
698-
699- </data>
700-</openerp>
701\ No newline at end of file
702
703=== modified file 'account_override/wizard/wizard_import_mapping.py'
704--- account_override/wizard/wizard_import_mapping.py 2013-04-22 14:17:10 +0000
705+++ account_override/wizard/wizard_import_mapping.py 2013-10-21 09:56:54 +0000
706@@ -38,7 +38,12 @@
707 if context is None:
708 context = {}
709 account_obj = self.pool.get('account.account')
710- mapping_obj = self.pool.get('account.export.mapping')
711+ instance_obj = self.pool.get('msf.instance')
712+ # using the "active model" variable to determine which mapping is uploaded
713+ if 'active_model' in context:
714+ mapping_obj = self.pool.get(context['active_model'])
715+ else:
716+ raise osv.except_osv(_('Error'), _('The object to be imported is undertermined!'))
717
718 # Delete previous lines
719 mapping_ids = mapping_obj.search(cr, uid, [], context=context)
720@@ -49,15 +54,26 @@
721 import_string = StringIO.StringIO(import_file)
722 import_data = list(csv.reader(import_string, quoting=csv.QUOTE_ALL, delimiter=','))
723
724- for line in import_data[1:]:
725- if len(line) == 2:
726- account_ids = account_obj.search(cr, uid, [('code', '=', line[0])], context=context)
727- if len(account_ids) > 0:
728- mapping_obj.create(cr, uid, {'account_id': account_ids[0],
729- 'mapping_value': line[1]}, context=context)
730- else:
731- raise osv.except_osv(_('Error'), _('The account code %s is not in the database!') % line[0])
732- break
733+ if context['active_model'] == 'account.export.mapping':
734+ for line in import_data[1:]:
735+ if len(line) == 2:
736+ account_ids = account_obj.search(cr, uid, [('code', '=', line[0])], context=context)
737+ if len(account_ids) > 0:
738+ mapping_obj.create(cr, uid, {'account_id': account_ids[0],
739+ 'mapping_value': line[1]}, context=context)
740+ else:
741+ raise osv.except_osv(_('Error'), _('The account code %s is not in the database!') % line[0])
742+ break
743+ elif context['active_model'] == 'country.export.mapping':
744+ for line in import_data[1:]:
745+ if len(line) == 2:
746+ instance_ids = instance_obj.search(cr, uid, [('code', '=', line[0])], context=context)
747+ if len(instance_ids) > 0:
748+ mapping_obj.create(cr, uid, {'instance_id': instance_ids[0],
749+ 'mapping_value': line[1]}, context=context)
750+ else:
751+ raise osv.except_osv(_('Error'), _('The instance code %s is not in the database!') % line[0])
752+ break
753
754 return {'type': 'ir.actions.act_window_close'}
755
756
757=== modified file 'msf_profile/__openerp__.py'
758--- msf_profile/__openerp__.py 2013-03-22 13:35:49 +0000
759+++ msf_profile/__openerp__.py 2013-10-21 09:56:54 +0000
760@@ -114,6 +114,7 @@
761 "export_import_lang",
762 "msf_button_access_rights",
763 "msf_field_access_rights",
764+ "vertical_integration",
765 ],
766 "update_xml": [
767 "report.xml",
768
769=== added directory 'vertical_integration'
770=== added file 'vertical_integration/__init__.py'
771--- vertical_integration/__init__.py 1970-01-01 00:00:00 +0000
772+++ vertical_integration/__init__.py 2013-10-21 09:56:54 +0000
773@@ -0,0 +1,28 @@
774+#!/usr/bin/env python
775+#-*- encoding:utf-8 -*-
776+##############################################################################
777+#
778+# OpenERP, Open Source Management Solution
779+# Copyright (C) 2011 TeMPO Consulting, MSF. All Rights Reserved
780+# Developer: Olivier DOSSMANN
781+#
782+# This program is free software: you can redistribute it and/or modify
783+# it under the terms of the GNU Affero General Public License as
784+# published by the Free Software Foundation, either version 3 of the
785+# License, or (at your option) any later version.
786+#
787+# This program is distributed in the hope that it will be useful,
788+# but WITHOUT ANY WARRANTY; without even the implied warranty of
789+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
790+# GNU Affero General Public License for more details.
791+#
792+# You should have received a copy of the GNU Affero General Public License
793+# along with this program. If not, see <http://www.gnu.org/licenses/>.
794+#
795+##############################################################################
796+import account_export_mapping
797+import country_export_mapping
798+import report
799+import wizard
800+
801+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
802
803=== added file 'vertical_integration/__openerp__.py'
804--- vertical_integration/__openerp__.py 1970-01-01 00:00:00 +0000
805+++ vertical_integration/__openerp__.py 2013-10-21 09:56:54 +0000
806@@ -0,0 +1,45 @@
807+# -*- coding: utf-8 -*-
808+##############################################################################
809+#
810+# OpenERP, Open Source Management Solution
811+# Copyright (C) 2011 MSF, TeMPO Consulting
812+#
813+# This program is free software: you can redistribute it and/or modify
814+# it under the terms of the GNU Affero General Public License as
815+# published by the Free Software Foundation, either version 3 of the
816+# License, or (at your option) any later version.
817+#
818+# This program is distributed in the hope that it will be useful,
819+# but WITHOUT ANY WARRANTY; without even the implied warranty of
820+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
821+# GNU Affero General Public License for more details.
822+#
823+# You should have received a copy of the GNU Affero General Public License
824+# along with this program. If not, see <http://www.gnu.org/licenses/>.
825+#
826+##############################################################################
827+
828+{
829+ "name" : "Vertical Integration",
830+ "version" : "1.0",
831+ "author" : "MSF, TeMPO Consulting",
832+ "description" : """
833+ Add HQ exports of finance data for all sections
834+ """,
835+ "website": "http://unifield.msf.org",
836+ "depends" : ["base", "account", "msf_instance"],
837+ "category" : "Generic Modules/Accounting",
838+ "init_xml" : [],
839+ "demo_xml" : [],
840+ "update_xml" : [
841+ 'security/ir.model.access.csv',
842+ 'account_export_mapping_view.xml',
843+ 'country_export_mapping_view.xml',
844+ 'account_report.xml',
845+ 'wizard/wizard_hq_report_ocg_view.xml',
846+ 'wizard/wizard_hq_report_oca_view.xml',
847+ ],
848+ 'test': [],
849+ 'installable': True,
850+ 'active': False,
851+}
852
853=== added file 'vertical_integration/account_export_mapping.py'
854--- vertical_integration/account_export_mapping.py 1970-01-01 00:00:00 +0000
855+++ vertical_integration/account_export_mapping.py 2013-10-21 09:56:54 +0000
856@@ -0,0 +1,65 @@
857+#!/usr/bin/env python
858+#-*- encoding:utf-8 -*-
859+##############################################################################
860+#
861+# OpenERP, Open Source Management Solution
862+# Copyright (C) 2011 TeMPO Consulting, MSF. All Rights Reserved
863+#
864+# This program is free software: you can redistribute it and/or modify
865+# it under the terms of the GNU Affero General Public License as
866+# published by the Free Software Foundation, either version 3 of the
867+# License, or (at your option) any later version.
868+#
869+# This program is distributed in the hope that it will be useful,
870+# but WITHOUT ANY WARRANTY; without even the implied warranty of
871+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
872+# GNU Affero General Public License for more details.
873+#
874+# You should have received a copy of the GNU Affero General Public License
875+# along with this program. If not, see <http://www.gnu.org/licenses/>.
876+#
877+##############################################################################
878+
879+from osv import osv, fields
880+
881+class account_export_mapping(osv.osv):
882+ _name = 'account.export.mapping'
883+ _description = 'Mapping of UF code into AX code'
884+ _rec_name = 'account_id'
885+
886+ _columns = {
887+ 'account_id': fields.many2one('account.account', string="Unifield Account Code", required=True),
888+ 'mapping_value': fields.char('HQ System Account Code', required=True, size=64)
889+ }
890+
891+ def _check_unicity(self, cr, uid, ids, context=None):
892+ if not context:
893+ context = {}
894+ for line in self.browse(cr, uid, ids, context=context):
895+ bad_ids = self.search(cr, uid, [('account_id', '=', line.account_id and line.account_id.id or False)])
896+ if len(bad_ids) and len(bad_ids) > 1:
897+ return False
898+ return True
899+
900+ _constraints = [
901+ (_check_unicity, "A mapping already exists for this account", ['account_id']),
902+ ]
903+
904+ def menu_import_wizard(self, cr, uid, ids, context=None):
905+ if context is None:
906+ context = {}
907+ wiz_obj = self.pool.get('wizard.import.mapping')
908+ wiz_id = wiz_obj.create(cr, uid, {}, context=context)
909+ # we open a wizard
910+ return {
911+ 'type': 'ir.actions.act_window',
912+ 'res_model': 'wizard.import.mapping',
913+ 'view_type': 'form',
914+ 'view_mode': 'form',
915+ 'target': 'new',
916+ 'res_id': [wiz_id],
917+ 'context': context,
918+ }
919+
920+account_export_mapping()
921+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
922
923=== added file 'vertical_integration/account_export_mapping_view.xml'
924--- vertical_integration/account_export_mapping_view.xml 1970-01-01 00:00:00 +0000
925+++ vertical_integration/account_export_mapping_view.xml 2013-10-21 09:56:54 +0000
926@@ -0,0 +1,74 @@
927+<?xml version="1.0" encoding="UTF-8"?>
928+<openerp>
929+ <data>
930+
931+ <record model="ir.ui.view" id="export_mapping_search_view">
932+ <field name="name">export.mapping.search</field>
933+ <field name="model">account.export.mapping</field>
934+ <field name="type">search</field>
935+ <field name="arch" type="xml">
936+ <search>
937+ <field name="account_id"/>
938+ <field name="mapping_value"/>
939+ </search>
940+ </field>
941+ </record>
942+
943+ <record model="ir.ui.view" id="export_mapping_tree_view">
944+ <field name="name">export.mapping.tree</field>
945+ <field name="model">account.export.mapping</field>
946+ <field name="type">tree</field>
947+ <field name="arch" type="xml">
948+ <tree string="Account Mapping">
949+ <field name="account_id" />
950+ <field name="mapping_value"/>
951+ </tree>
952+ </field>
953+ </record>
954+
955+ <record model="ir.ui.view" id="export_mapping_form_view">
956+ <field name="name">export.mapping.form</field>
957+ <field name="model">account.export.mapping</field>
958+ <field name="type">form</field>
959+ <field name="arch" type="xml">
960+ <form string="Account Mapping">
961+ <field name="account_id" />
962+ <field name="mapping_value"/>
963+ </form>
964+ </field>
965+ </record>
966+
967+ <record model="ir.actions.act_window" id="export_mapping_action">
968+ <field name="name">Account Mapping</field>
969+ <field name="res_model">account.export.mapping</field>
970+ <field name="view_type">form</field>
971+ <field name="view_mode">tree,form</field>
972+ </record>
973+
974+ <menuitem id="export_mapping_menu" name="Account Mapping" parent="account.account_account_menu"
975+ action="export_mapping_action" />
976+
977+ <record id="import_account_mappings_view" model="ir.ui.view">
978+ <field name="name">Import Mappings</field>
979+ <field name="model">wizard.import.mapping</field>
980+ <field name="type">form</field>
981+ <field name="arch" type="xml">
982+ <form string="Import Mappings">
983+ <field name="import_file"/>
984+ <button icon="gtk-cancel" special="cancel" string="Cancel"/>
985+ <button icon="terp-camera_test" string="Import" name="import_account_mappings" type="object" default_focus="1"/>
986+ </form>
987+ </field>
988+ </record>
989+
990+ <act_window name="Import Mappings"
991+ res_model="wizard.import.mapping"
992+ src_model="account.export.mapping"
993+ view_mode="form"
994+ target="new"
995+ key2="client_action_multi"
996+ empty_ids="1"
997+ id="action_import_account_mappings"/>
998+
999+ </data>
1000+</openerp>
1001\ No newline at end of file
1002
1003=== added file 'vertical_integration/account_report.xml'
1004--- vertical_integration/account_report.xml 1970-01-01 00:00:00 +0000
1005+++ vertical_integration/account_report.xml 2013-10-21 09:56:54 +0000
1006@@ -0,0 +1,22 @@
1007+<?xml version="1.0" encoding="utf-8"?>
1008+<openerp>
1009+ <data>
1010+ <report id="hq_ocg"
1011+ string="Export to HQ system"
1012+ model="account.move.line"
1013+ name="hq.ocg"
1014+ report_type="txt"
1015+ auto="False"
1016+ menu="False"/>
1017+ </data>
1018+ <data>
1019+ <report id="hq_oca"
1020+ string="Export to HQ system"
1021+ model="account.move.line"
1022+ name="hq.oca"
1023+ report_type="txt"
1024+ auto="False"
1025+ menu="False"/>
1026+ </data>
1027+</openerp>
1028+
1029
1030=== added file 'vertical_integration/country_export_mapping.py'
1031--- vertical_integration/country_export_mapping.py 1970-01-01 00:00:00 +0000
1032+++ vertical_integration/country_export_mapping.py 2013-10-21 09:56:54 +0000
1033@@ -0,0 +1,65 @@
1034+#!/usr/bin/env python
1035+#-*- encoding:utf-8 -*-
1036+##############################################################################
1037+#
1038+# OpenERP, Open Source Management Solution
1039+# Copyright (C) 2011 TeMPO Consulting, MSF. All Rights Reserved
1040+#
1041+# This program is free software: you can redistribute it and/or modify
1042+# it under the terms of the GNU Affero General Public License as
1043+# published by the Free Software Foundation, either version 3 of the
1044+# License, or (at your option) any later version.
1045+#
1046+# This program is distributed in the hope that it will be useful,
1047+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1048+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1049+# GNU Affero General Public License for more details.
1050+#
1051+# You should have received a copy of the GNU Affero General Public License
1052+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1053+#
1054+##############################################################################
1055+
1056+from osv import osv, fields
1057+
1058+class country_export_mapping(osv.osv):
1059+ _name = 'country.export.mapping'
1060+ _description = 'Mapping of Instance into a Country Code'
1061+ _rec_name = 'instance_id'
1062+
1063+ _columns = {
1064+ 'instance_id': fields.many2one('msf.instance', string="Unifield Instance", required=True, domain=[('level', '=', 'coordo')]),
1065+ 'mapping_value': fields.char('HQ System Country Code', required=True, size=64)
1066+ }
1067+
1068+ def _check_unicity(self, cr, uid, ids, context=None):
1069+ if not context:
1070+ context = {}
1071+ for line in self.browse(cr, uid, ids, context=context):
1072+ bad_ids = self.search(cr, uid, [('instance_id', '=', line.instance_id and line.instance_id.id or False)])
1073+ if len(bad_ids) and len(bad_ids) > 1:
1074+ return False
1075+ return True
1076+
1077+ _constraints = [
1078+ (_check_unicity, "A mapping already exists for this instance", ['instance_id']),
1079+ ]
1080+
1081+ def menu_import_wizard(self, cr, uid, ids, context=None):
1082+ if context is None:
1083+ context = {}
1084+ wiz_obj = self.pool.get('wizard.import.mapping')
1085+ wiz_id = wiz_obj.create(cr, uid, {}, context=context)
1086+ # we open a wizard
1087+ return {
1088+ 'type': 'ir.actions.act_window',
1089+ 'res_model': 'wizard.import.mapping',
1090+ 'view_type': 'form',
1091+ 'view_mode': 'form',
1092+ 'target': 'new',
1093+ 'res_id': [wiz_id],
1094+ 'context': context,
1095+ }
1096+
1097+country_export_mapping()
1098+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
1099
1100=== added file 'vertical_integration/country_export_mapping_view.xml'
1101--- vertical_integration/country_export_mapping_view.xml 1970-01-01 00:00:00 +0000
1102+++ vertical_integration/country_export_mapping_view.xml 2013-10-21 09:56:54 +0000
1103@@ -0,0 +1,61 @@
1104+<?xml version="1.0" encoding="UTF-8"?>
1105+<openerp>
1106+ <data>
1107+
1108+ <record model="ir.ui.view" id="country_export_mapping_search_view">
1109+ <field name="name">country.export.mapping.search</field>
1110+ <field name="model">country.export.mapping</field>
1111+ <field name="type">search</field>
1112+ <field name="arch" type="xml">
1113+ <search>
1114+ <field name="instance_id"/>
1115+ <field name="mapping_value"/>
1116+ </search>
1117+ </field>
1118+ </record>
1119+
1120+ <record model="ir.ui.view" id="country_export_mapping_tree_view">
1121+ <field name="name">country.export.mapping.tree</field>
1122+ <field name="model">country.export.mapping</field>
1123+ <field name="type">tree</field>
1124+ <field name="arch" type="xml">
1125+ <tree string="Country Code Mapping">
1126+ <field name="instance_id" />
1127+ <field name="mapping_value"/>
1128+ </tree>
1129+ </field>
1130+ </record>
1131+
1132+ <record model="ir.ui.view" id="country_export_mapping_form_view">
1133+ <field name="name">country.export.mapping.form</field>
1134+ <field name="model">country.export.mapping</field>
1135+ <field name="type">form</field>
1136+ <field name="arch" type="xml">
1137+ <form string="Country Code Mapping">
1138+ <field name="instance_id" />
1139+ <field name="mapping_value"/>
1140+ </form>
1141+ </field>
1142+ </record>
1143+
1144+ <record model="ir.actions.act_window" id="country_export_mapping_action">
1145+ <field name="name">Country Code Mapping</field>
1146+ <field name="res_model">country.export.mapping</field>
1147+ <field name="view_type">form</field>
1148+ <field name="view_mode">tree,form</field>
1149+ </record>
1150+
1151+ <menuitem id="country_export_mapping_menu" name="Country Code Mapping" parent="account.account_account_menu"
1152+ action="country_export_mapping_action" />
1153+
1154+ <act_window name="Import Mappings"
1155+ res_model="wizard.import.mapping"
1156+ src_model="country.export.mapping"
1157+ view_mode="form"
1158+ target="new"
1159+ key2="client_action_multi"
1160+ empty_ids="1"
1161+ id="action_import_country_mappings"/>
1162+
1163+ </data>
1164+</openerp>
1165\ No newline at end of file
1166
1167=== added directory 'vertical_integration/report'
1168=== added file 'vertical_integration/report/__init__.py'
1169--- vertical_integration/report/__init__.py 1970-01-01 00:00:00 +0000
1170+++ vertical_integration/report/__init__.py 2013-10-21 09:56:54 +0000
1171@@ -0,0 +1,2 @@
1172+import hq_report_ocg
1173+import hq_report_oca
1174\ No newline at end of file
1175
1176=== added file 'vertical_integration/report/hq_report_oca.py'
1177--- vertical_integration/report/hq_report_oca.py 1970-01-01 00:00:00 +0000
1178+++ vertical_integration/report/hq_report_oca.py 2013-10-21 09:56:54 +0000
1179@@ -0,0 +1,335 @@
1180+# -*- coding: utf-8 -*-
1181+##############################################################################
1182+#
1183+# OpenERP, Open Source Management Solution
1184+# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
1185+#
1186+# This program is free software: you can redistribute it and/or modify
1187+# it under the terms of the GNU Affero General Public License as
1188+# published by the Free Software Foundation, either version 3 of the
1189+# License, or (at your option) any later version.
1190+#
1191+# This program is distributed in the hope that it will be useful,
1192+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1193+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1194+# GNU Affero General Public License for more details.
1195+#
1196+# You should have received a copy of the GNU Affero General Public License
1197+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1198+#
1199+##############################################################################
1200+
1201+import datetime
1202+import csv
1203+import StringIO
1204+import pooler
1205+import zipfile
1206+from tempfile import NamedTemporaryFile
1207+import os
1208+
1209+from report import report_sxw
1210+
1211+class hq_report_oca(report_sxw.report_sxw):
1212+
1213+ def __init__(self, name, table, rml=False, parser=report_sxw.rml_parse, header='external', store=False):
1214+ report_sxw.report_sxw.__init__(self, name, table, rml=rml, parser=parser, header=header, store=store)
1215+
1216+ def _enc(self, st):
1217+ if isinstance(st, unicode):
1218+ return st.encode('utf8')
1219+ return st
1220+
1221+ def translate_country(self, cr, uid, pool, browse_instance, context={}):
1222+ mapping_obj = pool.get('country.export.mapping')
1223+ if browse_instance:
1224+ mapping_ids = mapping_obj.search(cr, uid, [('instance_id', '=', browse_instance.id)], context=context)
1225+ if len(mapping_ids) > 0:
1226+ mapping = mapping_obj.browse(cr, uid, mapping_ids[0], context=context)
1227+ return mapping.mapping_value
1228+ return "0"
1229+
1230+ def create_counterpart(self, cr, uid, line):
1231+ pool = pooler.get_pool(cr.dbname)
1232+ # method to create counterpart line
1233+ return line[:2] + \
1234+ ["20750",
1235+ "0",
1236+ "0",
1237+ line[5],
1238+ line[6],
1239+ line[7],
1240+ line[9],
1241+ line[8]] + line[10:]
1242+
1243+ def create_subtotal(self, cr, uid, line_key, line_debit, line_functional_debit, counterpart_date, country_code, sequence_number):
1244+ pool = pooler.get_pool(cr.dbname)
1245+ # method to create subtotal + counterpart line
1246+ if len(line_key) > 2 and line_debit != 0.0 and line_functional_debit != 0.0:
1247+ return [["01",
1248+ country_code,
1249+ line_key[0],
1250+ "0",
1251+ "0",
1252+ counterpart_date,
1253+ line_key[1],
1254+ round(line_debit / line_functional_debit, 8),
1255+ line_debit > 0 and round(line_debit, 2) or "",
1256+ line_debit < 0 and round(-line_debit, 2) or "",
1257+ sequence_number,
1258+ "",
1259+ "Subtotal - " + line_key[0] + " - " + line_key[1] + " - " + line_key[2],
1260+ "0",
1261+ counterpart_date,
1262+ "0"]
1263+ ,["01",
1264+ country_code,
1265+ "20750",
1266+ "0",
1267+ "0",
1268+ counterpart_date,
1269+ line_key[1],
1270+ round(line_debit / line_functional_debit, 8),
1271+ line_debit < 0 and round(-line_debit, 2) or "",
1272+ line_debit > 0 and round(line_debit, 2) or "",
1273+ sequence_number,
1274+ "",
1275+ "Automatic counterpart for " + line_key[0] + " - " + line_key[1] + " - " + line_key[2],
1276+ "0",
1277+ counterpart_date,
1278+ "0"]]
1279+
1280+ def create(self, cr, uid, ids, data, context=None):
1281+ pool = pooler.get_pool(cr.dbname)
1282+
1283+ first_header = ['Proprietary Instance',
1284+ 'Journal Code',
1285+ 'Entry Sequence',
1286+ 'Description',
1287+ 'Reference',
1288+ 'Document Date',
1289+ 'Posting Date',
1290+ 'Period',
1291+ 'G/L Account',
1292+ 'Destination',
1293+ 'Cost Centre',
1294+ 'Funding Pool',
1295+ 'Third Parties',
1296+ 'Booking Debit',
1297+ 'Booking Credit',
1298+ 'Booking Currency',
1299+ 'Functional Debit',
1300+ 'Functional Credit',
1301+ 'Functional Currency',
1302+ 'Exchange Rate']
1303+
1304+ # Initialize lists: one for the first report...
1305+ first_result_lines = []
1306+ # ...one for the second report...
1307+ second_result_lines = []
1308+ # ...and subdivisions for the third report.
1309+ third_report = []
1310+ account_lines = []
1311+ account_lines_debit = {}
1312+ account_lines_functional_debit = {}
1313+ # General variables
1314+ period = pool.get('account.period').browse(cr, uid, data['form']['period_id'])
1315+ period_name = period and period.code or "0"
1316+ counterpart_date = period and period.date_stop and \
1317+ datetime.datetime.strptime(period.date_stop, '%Y-%m-%d').date().strftime('%d/%m/%Y') or ""
1318+ integration_ref = "0"
1319+ country_code = "0"
1320+ move_prefix = "0"
1321+ if len(data['form']['instance_ids']) > 0:
1322+ parent_instance = pool.get('msf.instance').browse(cr, uid, data['form']['instance_ids'][0], context=context)
1323+ if parent_instance:
1324+ country_code = self.translate_country(cr, uid, pool, parent_instance)
1325+ if period and period.date_start:
1326+ integration_ref = parent_instance.code[:2] + period.date_start[5:7]
1327+ move_prefix = parent_instance.move_prefix[:2]
1328+
1329+ move_line_ids = pool.get('account.move.line').search(cr, uid, [('period_id', '=', data['form']['period_id']),
1330+ ('instance_id', 'in', data['form']['instance_ids']),
1331+ ('analytic_distribution_id', '=', False),
1332+ ('journal_id.type', 'not in', ['hq', 'migration'])], context=context)
1333+
1334+ for move_line in pool.get('account.move.line').browse(cr, uid, move_line_ids, context=context):
1335+ journal = move_line.journal_id
1336+ account = move_line.account_id
1337+ currency = move_line.currency_id
1338+ func_currency = move_line.functional_currency_id
1339+ rate = "0.00"
1340+ if currency and func_currency:
1341+ cr.execute("SELECT rate FROM res_currency_rate WHERE currency_id = %s AND name <= %s ORDER BY name desc LIMIT 1" ,(move_line.functional_currency_id.id, move_line.date))
1342+ if cr.rowcount:
1343+ func_rate = cr.fetchall()[0][0]
1344+ cr.execute("SELECT rate FROM res_currency_rate WHERE currency_id = %s AND name <= %s ORDER BY name desc LIMIT 1" ,(currency.id, move_line.date))
1345+ if cr.rowcount:
1346+ curr_rate = cr.fetchall()[0][0]
1347+ if func_rate != 0.00:
1348+ rate = round(curr_rate / func_rate, 5)
1349+ # For first report: as if
1350+ formatted_data = [move_line.instance_id and move_line.instance_id.code or "",
1351+ journal and journal.code or "",
1352+ move_line.move_id and move_line.move_id.name or "",
1353+ move_line.name,
1354+ move_line.ref,
1355+ datetime.datetime.strptime(move_line.document_date, '%Y-%m-%d').date().strftime('%d/%m/%Y'),
1356+ datetime.datetime.strptime(move_line.date, '%Y-%m-%d').date().strftime('%d/%m/%Y'),
1357+ move_line.period_id and move_line.period_id.code or "",
1358+ account and account.code + " " + account.name,
1359+ "",
1360+ "",
1361+ "",
1362+ move_line.partner_txt,
1363+ round(move_line.debit_currency, 2),
1364+ round(move_line.credit_currency, 2),
1365+ currency and currency.name or "",
1366+ round(move_line.debit, 2),
1367+ round(move_line.credit, 2),
1368+ func_currency and func_currency.name or "",
1369+ rate]
1370+ first_result_lines.append(formatted_data)
1371+
1372+ # For third report: add to corresponding sub
1373+ if not account.shrink_entries_for_hq:
1374+ expat_employee = "0"
1375+ # Expat employees are the only third party in this report
1376+ if move_line.partner_txt and move_line.employee_id and move_line.employee_id.employee_type == 'ex':
1377+ expat_employee = move_line.partner_txt[:5]
1378+ other_formatted_data = ["01",
1379+ country_code,
1380+ account and account.code or "0",
1381+ "0",
1382+ "0",
1383+ move_line.date and datetime.datetime.strptime(move_line.date, '%Y-%m-%d').date().strftime('%d/%m/%Y') or "0",
1384+ currency and currency.name or "0",
1385+ rate,
1386+ move_line.debit_currency != 0.0 and round(move_line.debit_currency, 2) or "",
1387+ move_line.credit_currency != 0.0 and round(move_line.credit_currency, 2) or "",
1388+ move_line.move_id and move_line.move_id.name or "0",
1389+ "",
1390+ move_line.name or "0",
1391+ expat_employee,
1392+ move_line.document_date and datetime.datetime.strptime(move_line.document_date, '%Y-%m-%d').date().strftime('%d/%m/%Y') or "0",
1393+ move_line.ref or "0"]
1394+ account_lines.append(other_formatted_data)
1395+ else:
1396+ if (account.code, currency.name, period_name) not in account_lines_debit:
1397+ account_lines_debit[(account.code, currency.name, period_name)] = 0.0
1398+ account_lines_functional_debit[(account.code, currency.name, period_name)] = 0.0
1399+ account_lines_debit[(account.code, currency.name, period_name)] += (move_line.debit_currency - move_line.credit_currency)
1400+ account_lines_functional_debit[(account.code, currency.name, period_name)] += (move_line.debit - move_line.credit)
1401+
1402+ analytic_line_ids = pool.get('account.analytic.line').search(cr, uid, [('period_id', '=', data['form']['period_id']),
1403+ ('instance_id', 'in', data['form']['instance_ids']),
1404+ ('journal_id.type', 'not in', ['hq', 'engagement', 'migration'])], context=context)
1405+
1406+ for analytic_line in pool.get('account.analytic.line').browse(cr, uid, analytic_line_ids, context=context):
1407+ journal = analytic_line.move_id and analytic_line.move_id.journal_id
1408+ account = analytic_line.general_account_id
1409+ currency = analytic_line.currency_id
1410+ func_currency = move_line.functional_currency_id
1411+ rate = ""
1412+ if func_currency:
1413+ cr.execute("SELECT rate FROM res_currency_rate WHERE currency_id = %s AND name <= %s ORDER BY name desc LIMIT 1" ,(move_line.functional_currency_id.id, analytic_line.date))
1414+ if cr.rowcount:
1415+ rate = cr.fetchall()[0][0]
1416+ # For first report: as is
1417+ formatted_data = [analytic_line.instance_id and analytic_line.instance_id.code or "",
1418+ analytic_line.journal_id and analytic_line.journal_id.code or "",
1419+ analytic_line.move_id and analytic_line.move_id.move_id and analytic_line.move_id.move_id.name or "",
1420+ analytic_line.name or "",
1421+ analytic_line.ref or "",
1422+ datetime.datetime.strptime(analytic_line.document_date, '%Y-%m-%d').date().strftime('%d/%m/%Y'),
1423+ datetime.datetime.strptime(analytic_line.date, '%Y-%m-%d').date().strftime('%d/%m/%Y'),
1424+ analytic_line.period_id and analytic_line.period_id.code or "",
1425+ account and account.code + " " + account.name or "",
1426+ analytic_line.destination_id and analytic_line.destination_id.code or "",
1427+ analytic_line.cost_center_id and analytic_line.cost_center_id.code or "",
1428+ analytic_line.account_id and analytic_line.account_id.code or "",
1429+ analytic_line.partner_txt or "",
1430+ analytic_line.amount_currency > 0 and "0.00" or round(-analytic_line.amount_currency, 2),
1431+ analytic_line.amount_currency > 0 and round(analytic_line.amount_currency, 2) or "0.00",
1432+ currency and currency.name or "",
1433+ analytic_line.amount > 0 and "0.00" or round(-analytic_line.amount, 2),
1434+ analytic_line.amount > 0 and round(analytic_line.amount, 2) or "0.00",
1435+ func_currency and func_currency.name or "",
1436+ rate]
1437+ first_result_lines.append(formatted_data)
1438+
1439+ # Add to second report (expenses only)
1440+ other_formatted_data = [integration_ref ,
1441+ analytic_line.document_date and datetime.datetime.strptime(analytic_line.document_date, '%Y-%m-%d').date().strftime('%d/%m/%Y') or "0",
1442+ "0",
1443+ "0",
1444+ analytic_line.cost_center_id and analytic_line.cost_center_id.code or "0",
1445+ "1",
1446+ account and account.code + " " + account.name or "0",
1447+ currency and currency.name or "0",
1448+ analytic_line.amount_currency and round(-analytic_line.amount_currency, 2) or "0.00",
1449+ "0",
1450+ rate,
1451+ analytic_line.date and datetime.datetime.strptime(analytic_line.date, '%Y-%m-%d').date().strftime('%d/%m/%Y') or "0",
1452+ analytic_line.move_id and analytic_line.move_id.move_id and analytic_line.move_id.move_id.name or "0",
1453+ "0",
1454+ analytic_line.name or "0",
1455+ analytic_line.ref or "0",
1456+ analytic_line.destination_id and analytic_line.destination_id.code or "0"]
1457+ second_result_lines.append(other_formatted_data)
1458+
1459+ first_result_lines = sorted(first_result_lines, key=lambda line: line[2])
1460+ first_report = [first_header] + first_result_lines
1461+
1462+ second_report = sorted(second_result_lines, key=lambda line: line[12])
1463+
1464+ for line in sorted(account_lines, key=lambda line: line[10]):
1465+ third_report.append(line)
1466+ third_report.append(self.create_counterpart(cr, uid, line))
1467+
1468+ sequence_index = 1
1469+ for key in sorted(account_lines_debit.iterkeys(), key=lambda tuple: tuple[0]):
1470+ # create the sequence number for those lines
1471+ sequence_number = move_prefix + "-" + \
1472+ period.date_start[5:7] + "-" + \
1473+ period.date_start[:4] + "-" + \
1474+ key[0] + "-" + \
1475+ key[1]
1476+
1477+ subtotal_lines = self.create_subtotal(cr, uid, key,
1478+ account_lines_debit[key],
1479+ account_lines_functional_debit[key],
1480+ counterpart_date,
1481+ country_code,
1482+ sequence_number)
1483+ if subtotal_lines:
1484+ third_report += subtotal_lines
1485+
1486+ zip_buffer = StringIO.StringIO()
1487+ first_fileobj = NamedTemporaryFile('w+b', delete=False)
1488+ second_fileobj = NamedTemporaryFile('w+b', delete=False)
1489+ third_fileobj = NamedTemporaryFile('w+b', delete=False)
1490+ writer = csv.writer(first_fileobj, quoting=csv.QUOTE_ALL)
1491+ for line in first_report:
1492+ writer.writerow(map(self._enc,line))
1493+ first_fileobj.close()
1494+ writer = csv.writer(second_fileobj, quoting=csv.QUOTE_ALL)
1495+ for line in second_report:
1496+ writer.writerow(map(self._enc,line))
1497+ second_fileobj.close()
1498+ writer = csv.writer(third_fileobj, quoting=csv.QUOTE_ALL)
1499+ for line in third_report:
1500+ writer.writerow(map(self._enc,line))
1501+ third_fileobj.close()
1502+ out_zipfile = zipfile.ZipFile(zip_buffer, "w")
1503+ out_zipfile.write(first_fileobj.name, "Raw_Data.csv", zipfile.ZIP_DEFLATED)
1504+ out_zipfile.write(second_fileobj.name, "Up_Expenses.csv", zipfile.ZIP_DEFLATED)
1505+ out_zipfile.write(third_fileobj.name, "Up_Balances.csv", zipfile.ZIP_DEFLATED)
1506+ out_zipfile.close()
1507+ out = zip_buffer.getvalue()
1508+ os.unlink(first_fileobj.name)
1509+ os.unlink(second_fileobj.name)
1510+ os.unlink(third_fileobj.name)
1511+ return (out, 'zip')
1512+
1513+hq_report_oca('report.hq.oca', 'account.move.line', False, parser=False)
1514+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
1515
1516=== added file 'vertical_integration/report/hq_report_ocg.py'
1517--- vertical_integration/report/hq_report_ocg.py 1970-01-01 00:00:00 +0000
1518+++ vertical_integration/report/hq_report_ocg.py 2013-10-21 09:56:54 +0000
1519@@ -0,0 +1,291 @@
1520+# -*- coding: utf-8 -*-
1521+##############################################################################
1522+#
1523+# OpenERP, Open Source Management Solution
1524+# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
1525+#
1526+# This program is free software: you can redistribute it and/or modify
1527+# it under the terms of the GNU Affero General Public License as
1528+# published by the Free Software Foundation, either version 3 of the
1529+# License, or (at your option) any later version.
1530+#
1531+# This program is distributed in the hope that it will be useful,
1532+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1533+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1534+# GNU Affero General Public License for more details.
1535+#
1536+# You should have received a copy of the GNU Affero General Public License
1537+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1538+#
1539+##############################################################################
1540+
1541+import datetime
1542+import csv
1543+import StringIO
1544+import pooler
1545+import zipfile
1546+from tempfile import NamedTemporaryFile
1547+import os
1548+
1549+from report import report_sxw
1550+
1551+class hq_report_ocg(report_sxw.report_sxw):
1552+
1553+ def __init__(self, name, table, rml=False, parser=report_sxw.rml_parse, header='external', store=False):
1554+ report_sxw.report_sxw.__init__(self, name, table, rml=rml, parser=parser, header=header, store=store)
1555+
1556+ def _enc(self, st):
1557+ if isinstance(st, unicode):
1558+ return st.encode('utf8')
1559+ return st
1560+
1561+ def translate_account(self, cr, uid, pool, browse_account, context={}):
1562+ mapping_obj = pool.get('account.export.mapping')
1563+ if browse_account:
1564+ mapping_ids = mapping_obj.search(cr, uid, [('account_id', '=', browse_account.id)], context=context)
1565+ if len(mapping_ids) > 0:
1566+ mapping = mapping_obj.browse(cr, uid, mapping_ids[0], context=context)
1567+ return mapping.mapping_value
1568+ else:
1569+ return browse_account.code
1570+ return ""
1571+
1572+ def create_subtotal(self, cr, uid, line_key, line_debit, counterpart_date, period_name, department_info):
1573+ pool = pooler.get_pool(cr.dbname)
1574+ # method to create subtotal + counterpart line
1575+ if len(line_key) > 2 and line_debit != 0.0:
1576+ journal = pool.get('account.journal').browse(cr, uid, line_key[1])
1577+ currency = pool.get('res.currency').browse(cr, uid, line_key[2])
1578+ description = ""
1579+ # Description for the line
1580+ if line_key[0] == "1000 0000":
1581+ description = "Mvts_BANK_" + period_name + "_" + currency.name
1582+ elif line_key[0] == "1000 0001":
1583+ description = "Mvts_CASH_" + period_name + "_" + currency.name
1584+ else:
1585+ mapping_obj = pool.get('account.export.mapping')
1586+ account_values = ""
1587+ mapping_ids = mapping_obj.search(cr, uid, [('mapping_value', '=', line_key[0])], context={})
1588+ for mapping in mapping_obj.browse(cr, uid, mapping_ids, context={}):
1589+ if account_values != "":
1590+ account_values += "-"
1591+ account_values += mapping.account_id.code
1592+ description = "Mvts_" + account_values + period_name + journal.code + "_" + currency.name
1593+
1594+ return [[journal.instance_id and journal.instance_id.code or "",
1595+ journal.code,
1596+ "",
1597+ description,
1598+ "",
1599+ counterpart_date,
1600+ counterpart_date,
1601+ period_name,
1602+ line_key[0],
1603+ "",
1604+ department_info,
1605+ "",
1606+ "",
1607+ line_debit > 0 and round(line_debit, 2) or "0.00",
1608+ line_debit > 0 and "0.00" or round(-line_debit, 2),
1609+ currency.name]]
1610+
1611+ def create(self, cr, uid, ids, data, context=None):
1612+ pool = pooler.get_pool(cr.dbname)
1613+ # Create the header
1614+ first_header = ['Proprietary Instance',
1615+ 'Journal Code',
1616+ 'Entry Sequence',
1617+ 'Description',
1618+ 'Reference',
1619+ 'Document Date',
1620+ 'Posting Date',
1621+ 'Period',
1622+ 'G/L Account',
1623+ 'Unifield Account',
1624+ 'Destination',
1625+ 'Cost Centre',
1626+ 'Funding Pool',
1627+ 'Third Parties',
1628+ 'Booking Debit',
1629+ 'Booking Credit',
1630+ 'Booking Currency',
1631+ 'Functional Debit',
1632+ 'Functional Credit',
1633+ 'Functional Currency']
1634+
1635+ second_header = ['Proprietary Instance',
1636+ 'Journal Code',
1637+ 'Entry Sequence',
1638+ 'Description',
1639+ 'Reference',
1640+ 'Document Date',
1641+ 'Posting Date',
1642+ 'Period',
1643+ 'G/L Account',
1644+ 'Destination',
1645+ 'Department',
1646+ 'Cost Centre',
1647+ 'Third Parties',
1648+ 'Booking Debit',
1649+ 'Booking Credit',
1650+ 'Booking Currency']
1651+
1652+ # Initialize lists: one for the first report...
1653+ first_result_lines = []
1654+ # ...and subdivisions for the second report.
1655+ second_result_lines = []
1656+ main_lines = {}
1657+ account_lines_debit = {}
1658+ # Get department info code: 3 first characters of main instance's code
1659+ department_info = ""
1660+ if len(data['form']['instance_ids']) > 0:
1661+ parent_instance = pool.get('msf.instance').browse(cr, uid, data['form']['instance_ids'][0], context=context)
1662+ if parent_instance:
1663+ department_info = parent_instance.code[:3]
1664+
1665+
1666+ move_line_ids = pool.get('account.move.line').search(cr, uid, [('period_id', '=', data['form']['period_id']),
1667+ ('instance_id', 'in', data['form']['instance_ids']),
1668+ ('analytic_distribution_id', '=', False),
1669+ ('journal_id.type', 'not in', ['hq', 'cur_adj', 'inkind'])], context=context)
1670+
1671+ for move_line in pool.get('account.move.line').browse(cr, uid, move_line_ids, context=context):
1672+ journal = move_line.journal_id
1673+ account = move_line.account_id
1674+ currency = move_line.currency_id
1675+ # For first report: as if
1676+ formatted_data = [move_line.instance_id and move_line.instance_id.code or "",
1677+ journal and journal.code or "",
1678+ move_line.move_id and move_line.move_id.name or "",
1679+ move_line.name,
1680+ move_line.ref,
1681+ datetime.datetime.strptime(move_line.document_date, '%Y-%m-%d').date().strftime('%d/%m/%Y'),
1682+ datetime.datetime.strptime(move_line.date, '%Y-%m-%d').date().strftime('%d/%m/%Y'),
1683+ move_line.period_id and move_line.period_id.code or "",
1684+ self.translate_account(cr, uid, pool, account),
1685+ account and account.code + " " + account.name,
1686+ "",
1687+ "",
1688+ "",
1689+ move_line.partner_txt,
1690+ round(move_line.debit_currency, 2),
1691+ round(move_line.credit_currency, 2),
1692+ currency and currency.name or "",
1693+ round(move_line.debit, 2),
1694+ round(move_line.credit, 2),
1695+ move_line.functional_currency_id and move_line.functional_currency_id.name or ""]
1696+ first_result_lines.append(formatted_data)
1697+
1698+ # For second report: add to corresponding sub
1699+ if journal.type in ['correction', 'intermission'] or not account.shrink_entries_for_hq:
1700+ if (journal.code, journal.id, currency.id) not in main_lines:
1701+ main_lines[(journal.code, journal.id, currency.id)] = []
1702+ main_lines[(journal.code, journal.id, currency.id)].append(formatted_data[:9] + [formatted_data[10]] + [department_info] + formatted_data[11:12] + formatted_data[13:17])
1703+ else:
1704+ translated_account_code = self.translate_account(cr, uid, pool, account)
1705+ if (translated_account_code, journal.id, currency.id) not in account_lines_debit:
1706+ account_lines_debit[(translated_account_code, journal.id, currency.id)] = 0.0
1707+ account_lines_debit[(translated_account_code, journal.id, currency.id)] += (move_line.debit_currency - move_line.credit_currency)
1708+
1709+
1710+
1711+ cur_adj_journal_ids = pool.get('account.journal').search(cr, uid, [('type', '=', 'cur_adj')], context=context)
1712+ ana_cur_journal_ids = []
1713+ for journal in pool.get('account.journal').browse(cr, uid, cur_adj_journal_ids, context=context):
1714+ if journal.analytic_journal_id and journal.analytic_journal_id.id not in ana_cur_journal_ids:
1715+ ana_cur_journal_ids.append(journal.analytic_journal_id.id)
1716+
1717+ analytic_line_ids = pool.get('account.analytic.line').search(cr, uid, [('period_id', '=', data['form']['period_id']),
1718+ ('instance_id', 'in', data['form']['instance_ids']),
1719+ ('journal_id.type', 'not in', ['hq', 'engagement', 'inkind']),
1720+ ('journal_id', 'not in', ana_cur_journal_ids)], context=context)
1721+ for analytic_line in pool.get('account.analytic.line').browse(cr, uid, analytic_line_ids, context=context):
1722+ journal = analytic_line.move_id and analytic_line.move_id.journal_id
1723+ account = analytic_line.general_account_id
1724+ currency = analytic_line.currency_id
1725+ # For first report: as is
1726+ formatted_data = [analytic_line.instance_id and analytic_line.instance_id.code or "",
1727+ analytic_line.journal_id and analytic_line.journal_id.code or "",
1728+ analytic_line.move_id and analytic_line.move_id.move_id and analytic_line.move_id.move_id.name or "",
1729+ analytic_line.name or "",
1730+ analytic_line.ref or "",
1731+ datetime.datetime.strptime(analytic_line.document_date, '%Y-%m-%d').date().strftime('%d/%m/%Y'),
1732+ datetime.datetime.strptime(analytic_line.date, '%Y-%m-%d').date().strftime('%d/%m/%Y'),
1733+ analytic_line.period_id and analytic_line.period_id.code or "",
1734+ account and account.code,
1735+ account and account.code + " " + account.name or "",
1736+ analytic_line.destination_id and analytic_line.destination_id.code or "",
1737+ analytic_line.cost_center_id and analytic_line.cost_center_id.code or "",
1738+ analytic_line.account_id and analytic_line.account_id.code or "",
1739+ analytic_line.partner_txt or "",
1740+ analytic_line.amount_currency > 0 and "0.00" or round(-analytic_line.amount_currency, 2),
1741+ analytic_line.amount_currency > 0 and round(analytic_line.amount_currency, 2) or "0.00",
1742+ currency and currency.name or "",
1743+ analytic_line.amount > 0 and "0.00" or round(-analytic_line.amount, 2),
1744+ analytic_line.amount > 0 and round(analytic_line.amount, 2) or "0.00",
1745+ analytic_line.functional_currency_id and analytic_line.functional_currency_id.name or ""]
1746+ first_result_lines.append(formatted_data)
1747+
1748+ if (journal.code, journal.id, currency.id) not in main_lines:
1749+ main_lines[(journal.code, journal.id, currency.id)] = []
1750+ main_lines[(journal.code, journal.id, currency.id)].append(formatted_data[:9] + [formatted_data[10]] + [department_info] + formatted_data[11:12] + formatted_data[13:17])
1751+
1752+ first_result_lines = sorted(first_result_lines, key=lambda line: line[2])
1753+ first_report = [first_header] + first_result_lines
1754+
1755+ # Regroup second report lines
1756+ period = pool.get('account.period').browse(cr, uid, data['form']['period_id'])
1757+ counterpart_date = period and period.date_stop and \
1758+ datetime.datetime.strptime(period.date_stop, '%Y-%m-%d').date().strftime('%d/%m/%Y') or ""
1759+ period_name = period and period.code or ""
1760+
1761+ for key in sorted(main_lines.iterkeys(), key=lambda tuple: tuple[0]):
1762+ second_result_lines += sorted(main_lines[key], key=lambda line: line[2])
1763+
1764+ for key in sorted(account_lines_debit.iterkeys(), key=lambda tuple: tuple[0]):
1765+ subtotal_lines = self.create_subtotal(cr, uid, key,
1766+ account_lines_debit[key],
1767+ counterpart_date,
1768+ period_name,
1769+ department_info)
1770+ if subtotal_lines:
1771+ second_result_lines += subtotal_lines
1772+
1773+ second_report = [second_header] + second_result_lines
1774+
1775+ # file names
1776+ prefix = ""
1777+ for instance in pool.get('msf.instance').browse(cr, uid, data['form']['instance_ids'], context=context):
1778+ if instance.level == 'coordo':
1779+ prefix += instance.top_cost_center_id and instance.top_cost_center_id.code or "xxx"
1780+ break
1781+ prefix += "_"
1782+ period = pool.get('account.period').browse(cr, uid, data['form']['period_id'], context=context)
1783+ if period and period.date_start:
1784+ prefix += datetime.datetime.strptime(period.date_start, '%Y-%m-%d').date().strftime('%Y%m')
1785+ else:
1786+ prefix += "xxxxxx"
1787+ prefix += "_"
1788+
1789+ zip_buffer = StringIO.StringIO()
1790+ first_fileobj = NamedTemporaryFile('w+b', delete=False)
1791+ second_fileobj = NamedTemporaryFile('w+b', delete=False)
1792+ writer = csv.writer(first_fileobj, quoting=csv.QUOTE_ALL)
1793+ for line in first_report:
1794+ writer.writerow(map(self._enc,line))
1795+ first_fileobj.close()
1796+ writer = csv.writer(second_fileobj, quoting=csv.QUOTE_ALL)
1797+ for line in second_report:
1798+ writer.writerow(map(self._enc,line))
1799+ second_fileobj.close()
1800+ out_zipfile = zipfile.ZipFile(zip_buffer, "w")
1801+ out_zipfile.write(first_fileobj.name, prefix + "raw data UF export.csv", zipfile.ZIP_DEFLATED)
1802+ out_zipfile.write(second_fileobj.name, prefix + "formatted data AX import.csv", zipfile.ZIP_DEFLATED)
1803+ out_zipfile.close()
1804+ out = zip_buffer.getvalue()
1805+ os.unlink(first_fileobj.name)
1806+ os.unlink(second_fileobj.name)
1807+ return (out, 'zip')
1808+
1809+hq_report_ocg('report.hq.ocg', 'account.move.line', False, parser=False)
1810+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
1811
1812=== added file 'vertical_integration/report/open_invoices_xls.mako'
1813--- vertical_integration/report/open_invoices_xls.mako 1970-01-01 00:00:00 +0000
1814+++ vertical_integration/report/open_invoices_xls.mako 2013-10-21 09:56:54 +0000
1815@@ -0,0 +1,382 @@
1816+<?xml version="1.0"?>
1817+<?mso-application progid="Excel.Sheet"?>
1818+<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
1819+ xmlns:o="urn:schemas-microsoft-com:office:office"
1820+ xmlns:x="urn:schemas-microsoft-com:office:excel"
1821+ xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
1822+ xmlns:html="http://www.w3.org/TR/REC-html40">
1823+ <DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">
1824+ <LastAuthor>MSFUser</LastAuthor>
1825+ <Created>2013-01-08T16:00:30Z</Created>
1826+ <LastSaved>2013-01-08T16:06:38Z</LastSaved>
1827+ <Version>11.9999</Version>
1828+ </DocumentProperties>
1829+ <ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">
1830+ <WindowHeight>8385</WindowHeight>
1831+ <WindowWidth>14940</WindowWidth>
1832+ <WindowTopX>360</WindowTopX>
1833+ <WindowTopY>240</WindowTopY>
1834+ <ProtectStructure>False</ProtectStructure>
1835+ <ProtectWindows>False</ProtectWindows>
1836+ </ExcelWorkbook>
1837+ <Styles>
1838+
1839+
1840+ <Style ss:ID="Default" ss:Name="Normal">
1841+ <Alignment ss:Vertical="Bottom"/>
1842+ <Borders/>
1843+ <Font/>
1844+ <Interior/>
1845+ <NumberFormat/>
1846+ <Protection/>
1847+ </Style>
1848+
1849+
1850+ <Style ss:ID="s21">
1851+ <Alignment ss:Horizontal="Center"/>
1852+ <Font x:Family="Swiss" />
1853+ </Style>
1854+ <Style ss:ID="s23">
1855+ <Font x:Family="Swiss" ss:Color="#FFFFFF" ss:Bold="1"/>
1856+ <Interior ss:Color="#FF0000" ss:Pattern="Solid"/>
1857+ </Style>
1858+ <Style ss:ID="s24">
1859+ <Font x:Family="Swiss" ss:Bold="1"/>
1860+ <Interior ss:Color="#FF0000" ss:Pattern="Solid"/>
1861+ </Style>
1862+ <Style ss:ID="s25">
1863+ <Font/>
1864+ <Interior ss:Color="#FF0000" ss:Pattern="Solid"/>
1865+ </Style>
1866+ <Style ss:ID="s26">
1867+ <Alignment ss:Vertical="Center"/>
1868+ </Style>
1869+ <Style ss:ID="s27">
1870+ <Alignment ss:Vertical="Center"/>
1871+ <Borders>
1872+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>
1873+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1"/>
1874+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1"/>
1875+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>
1876+ </Borders>
1877+ <Font x:Family="Swiss" ss:Bold="1"/>
1878+ </Style>
1879+ <Style ss:ID="s28">
1880+ <Alignment ss:Vertical="Center" ss:WrapText="1"/>
1881+ <Borders>
1882+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>
1883+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1"/>
1884+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1"/>
1885+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>
1886+ </Borders>
1887+ <Font x:Family="Swiss" ss:Bold="1"/>
1888+ </Style>
1889+ <Style ss:ID="s29">
1890+ <Alignment ss:Vertical="Center" ss:WrapText="1"/>
1891+ <Borders>
1892+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>
1893+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1"/>
1894+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1"/>
1895+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>
1896+ </Borders>
1897+ <Font x:Family="Swiss" ss:Bold="1"/>
1898+ <Interior ss:Pattern="Solid"/>
1899+ </Style>
1900+ <Style ss:ID="s30">
1901+ <Alignment ss:Vertical="Center"/>
1902+ <Borders>
1903+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>
1904+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1"/>
1905+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1"/>
1906+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>
1907+ </Borders>
1908+ </Style>
1909+ <Style ss:ID="s31">
1910+ <Font x:Family="Swiss" ss:Color="#FFFFFF" ss:Bold="1"/>
1911+ <Interior ss:Color="#FF0000" ss:Pattern="Solid"/>
1912+ </Style>
1913+ <Style ss:ID="s32">
1914+ <Borders>
1915+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>
1916+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1"/>
1917+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1"/>
1918+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>
1919+ </Borders>
1920+ <NumberFormat ss:Format="Short Date"/>
1921+ </Style>
1922+ <Style ss:ID="s33">
1923+ <Borders>
1924+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>
1925+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1"/>
1926+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1"/>
1927+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>
1928+ </Borders>
1929+ <NumberFormat ss:Format="Standard"/>
1930+ </Style>
1931+
1932+
1933+ <Style ss:ID="s34">
1934+ <Borders>
1935+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>
1936+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1"/>
1937+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1"/>
1938+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>
1939+ </Borders>
1940+ <NumberFormat ss:Format="Fixed"/>
1941+ </Style>
1942+ <Style ss:ID="s35">
1943+ <Borders>
1944+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>
1945+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1"/>
1946+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1"/>
1947+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>
1948+ </Borders>
1949+ <Interior ss:Pattern="Solid"/>
1950+ <NumberFormat ss:Format="Fixed"/>
1951+ </Style>
1952+ <Style ss:ID="s36">
1953+ <Borders>
1954+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>
1955+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1"/>
1956+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1"/>
1957+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>
1958+ </Borders>
1959+ <NumberFormat ss:Format="Standard"/>
1960+ </Style>
1961+ <Style ss:ID="s37">
1962+ <Borders>
1963+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>
1964+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1"/>
1965+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1"/>
1966+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>
1967+ </Borders>
1968+ <Interior ss:Pattern="Solid"/>
1969+ <NumberFormat ss:Format="Standard"/>
1970+ </Style>
1971+ <Style ss:ID="s38">
1972+ <Interior ss:Color="#FF0000" ss:Pattern="Solid"/>
1973+ </Style>
1974+ <Style ss:ID="s39">
1975+ <Alignment ss:Vertical="Center"/>
1976+ <Borders/>
1977+ <Font x:Family="Swiss" ss:Bold="1"/>
1978+ </Style>
1979+ <Style ss:ID="s40">
1980+ <Alignment ss:Vertical="Center" ss:WrapText="1"/>
1981+ <Borders/>
1982+ <Font x:Family="Swiss" ss:Bold="1"/>
1983+ </Style>
1984+ <Style ss:ID="s42">
1985+ <Alignment ss:Vertical="Center"/>
1986+ <Borders/>
1987+ </Style>
1988+ <Style ss:ID="s44">
1989+ <Alignment ss:Horizontal="Right" ss:Vertical="Center"/>
1990+ <Borders/>
1991+ <Font x:Family="Swiss" ss:Bold="1"/>
1992+ </Style>
1993+
1994+ <Style ss:ID="s49">
1995+ <Alignment ss:Vertical="Center" ss:WrapText="1"/>
1996+ <Borders>
1997+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>
1998+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1"/>
1999+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1"/>
2000+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>
2001+ </Borders>
2002+ <Font x:Family="Swiss" ss:Bold="1"/>
2003+ <Interior ss:Pattern="Solid"/>
2004+ <NumberFormat ss:Format="Standard"/>
2005+ </Style>
2006+
2007+ <Style ss:ID="s50">
2008+ <Borders>
2009+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>
2010+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1"/>
2011+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1"/>
2012+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>
2013+ </Borders>
2014+ <Interior ss:Pattern="Solid"/>
2015+ <NumberFormat ss:Format="Standard"/>
2016+ </Style>
2017+
2018+ <Style ss:ID="s51">
2019+ <Font ss:Size="14"/>
2020+ <Interior ss:Pattern="Solid"/>
2021+ </Style>
2022+
2023+ <Style ss:ID="s25b">
2024+ <Font ss:Bold="1"/>
2025+ </Style>
2026+
2027+ <Style ss:ID="short_date2">
2028+ <Alignment ss:Horizontal="Center" ss:Vertical="Center" ss:WrapText="1"/>
2029+ <NumberFormat ss:Format="Short Date"/>
2030+ <Borders>
2031+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>
2032+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1"/>
2033+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1"/>
2034+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>
2035+ </Borders>
2036+ </Style>
2037+
2038+ <Style ss:ID="short_date2a">
2039+ <Alignment ss:Horizontal="Center" ss:Vertical="Center" ss:WrapText="1"/>
2040+ <NumberFormat ss:Format="Short Date"/>
2041+ </Style>
2042+
2043+ </Styles>
2044+
2045+<Worksheet ss:Name="${_('Open Invoices')}">
2046+ <Table>
2047+ <Column ss:AutoFitWidth="0" ss:Width="90.5" ss:Span="1"/>
2048+ <Column ss:Index="3" ss:Width="88.5"/>
2049+ <Column ss:Width="91.5"/>
2050+ <Column ss:Width="108"/>
2051+ <Column ss:Width="63"/>
2052+ <Column ss:Width="53.25"/>
2053+ <Column ss:Width="105.75"/>
2054+ <Column ss:Width="51"/>
2055+ <Column ss:Width="42.75"/>
2056+ <Column ss:Width="46.5" ss:Span="1"/>
2057+ <Column ss:Index="13" ss:Width="49.5"/>
2058+ <Column ss:Width="39.75"/>
2059+ <Column ss:Width="45.5"/>
2060+
2061+
2062+ <Row ss:AutoFitHeight="0" ss:Height="18">
2063+ <Cell ss:StyleID="s25b">
2064+ <Data ss:Type="String">${_('OPEN INVOICES')}</Data>
2065+ </Cell>
2066+ </Row>
2067+
2068+ <Row><Cell><Data ss:Type="String"></Data></Cell></Row>
2069+
2070+ <Row >
2071+ <Cell>
2072+ <Data ss:Type="String">${_('Prop. Instance')}:</Data>
2073+ </Cell>
2074+ <Cell ss:StyleID="s21">
2075+ <Data ss:Type="String">${(company.instance_id and company.instance_id.code or '')|x}</Data>
2076+ </Cell>
2077+ </Row>
2078+ <Row>
2079+ <Cell>
2080+ <Data ss:Type="String">${_('Report Date')}:</Data>
2081+ </Cell>
2082+ <Cell ss:StyleID="short_date2a" ><Data ss:Type="DateTime">${time.strftime('%Y-%m-%d')|n}T00:00:00.000</Data></Cell>
2083+ </Row>
2084+ <Row><Cell><Data ss:Type="String"></Data></Cell></Row>
2085+
2086+% for (type, title) in [('ci', _('Stock Transfer Vouchers')), ('si', _('Supplier Invoices')), ('cr', _('Customer Refunds')), ('sr', _('Supplier Refunds'))]:
2087+ <Row >
2088+ <Cell ss:StyleID="s23"><Data ss:Type="String">${title}</Data></Cell>
2089+ <Cell ss:StyleID="s24"/>
2090+ <Cell ss:StyleID="s24"/>
2091+ <Cell ss:StyleID="s24"/>
2092+ <Cell ss:StyleID="s24"/>
2093+ <Cell ss:StyleID="s24"/>
2094+ <Cell ss:StyleID="s24"/>
2095+ <Cell ss:StyleID="s24"/>
2096+ <Cell ss:StyleID="s24"/>
2097+ <Cell ss:StyleID="s24"/>
2098+ <Cell ss:StyleID="s24"/>
2099+ <Cell ss:StyleID="s24"/>
2100+ <Cell ss:StyleID="s24"/>
2101+ <Cell ss:StyleID="s24"/>
2102+ <Cell ss:StyleID="s25"/>
2103+ </Row>
2104+ <Row ss:AutoFitHeight="0" ss:Height="51" ss:StyleID="s26">
2105+ <Cell ss:StyleID="s27"><Data ss:Type="String">${_('Document Date')}</Data></Cell>
2106+ <Cell ss:StyleID="s27"><Data ss:Type="String">${_('Posting Date')}</Data></Cell>
2107+ <Cell ss:StyleID="s27"><Data ss:Type="String">${_('Number')}</Data></Cell>
2108+ <Cell ss:StyleID="s27"><Data ss:Type="String">${_('Customer')}</Data></Cell>
2109+ <Cell ss:StyleID="s27"><Data ss:Type="String">${_('Description')}</Data></Cell>
2110+ <Cell ss:StyleID="s27"><Data ss:Type="String">${_('Responsible')}</Data></Cell>
2111+ <Cell ss:StyleID="s27"><Data ss:Type="String">${_('Due Date')}</Data></Cell>
2112+ <Cell ss:StyleID="s27"><Data ss:Type="String">${_('Source Document')}</Data></Cell>
2113+ <Cell ss:StyleID="s28"><Data ss:Type="String">${_('Residual amt booking ccy')}</Data></Cell>
2114+ <Cell ss:StyleID="s28"><Data ss:Type="String">${_('Total amt booking ccy')}</Data></Cell>
2115+ <Cell ss:StyleID="s28"><Data ss:Type="String">${_('Booking Currency')}</Data></Cell>
2116+ <Cell ss:StyleID="s29"><Data ss:Type="String">${_('Residual amt func. ccy')}</Data></Cell>
2117+ <Cell ss:StyleID="s29"><Data ss:Type="String">${_('Total amt func. ccy')}</Data></Cell>
2118+ <Cell ss:StyleID="s29"><Data ss:Type="String">${_('Func. Ccy')}</Data></Cell>
2119+ <Cell ss:StyleID="s27"><Data ss:Type="String">${_('State')}</Data></Cell>
2120+ </Row>
2121+
2122+<% nb_line = 0 %>
2123+
2124+% for line in getLines(type):
2125+ <Row>
2126+ <% nb_line += 1 %>
2127+ % if line[1]:
2128+ <Cell ss:StyleID="short_date2" ><Data ss:Type="DateTime">${line[1] or ' ' |n}T00:00:00.000</Data></Cell>
2129+ % else:
2130+ <Cell ss:StyleID="short_date2" ><Data ss:Type="String"></Data></Cell>
2131+ % endif
2132+
2133+ % if line[2]:
2134+ <Cell ss:StyleID="short_date2" ><Data ss:Type="DateTime">${line[2] or ' ' |n}T00:00:00.000</Data></Cell>
2135+ % else:
2136+ <Cell ss:StyleID="short_date2" ><Data ss:Type="String"></Data></Cell>
2137+ % endif
2138+ <Cell ss:StyleID="s33"><Data ss:Type="String">${(line[3] or '')|x}</Data></Cell>
2139+ <Cell ss:StyleID="s33"><Data ss:Type="String">${(line[4] or '')|x}</Data></Cell>
2140+ <Cell ss:StyleID="s33"><Data ss:Type="String">${(line[5] or '')|x}</Data></Cell>
2141+ <Cell ss:StyleID="s33"><Data ss:Type="String">${(line[6] or '')|x}</Data></Cell>
2142+ % if line[7]:
2143+ <Cell ss:StyleID="short_date2" ><Data ss:Type="DateTime">${line[7] or ' ' |n}T00:00:00.000</Data></Cell>
2144+ % else:
2145+ <Cell ss:StyleID="short_date2" ><Data ss:Type="String"></Data></Cell>
2146+ % endif
2147+ <Cell ss:StyleID="s33"><Data ss:Type="String">${(line[8] or '')|x}</Data></Cell>
2148+ <Cell ss:StyleID="s33" ><Data ss:Type="Number">${(line[10] or 0.0)|x}</Data></Cell>
2149+ <Cell ss:StyleID="s33" ><Data ss:Type="Number">${(line[11] or 0.0)|x}</Data></Cell>
2150+ <Cell ss:StyleID="s33"><Data ss:Type="String">${(line[9] or '')|x}</Data></Cell>
2151+ <Cell ss:StyleID="s50" ><Data ss:Type="Number">${(getConvert(line[10], line) or 0.0 )|x}</Data></Cell>
2152+ <Cell ss:StyleID="s50" ><Data ss:Type="Number">${(getConvert(line[11], line) or 0.0 )|x}</Data></Cell>
2153+ <Cell ss:StyleID="s50"><Data ss:Type="String">${getFuncCur() |x}</Data></Cell>
2154+ <Cell ss:StyleID="s33"><Data ss:Type="String">${(line[12] and getSelValue('account.invoice', 'state', line[12]) or '')|x}</Data></Cell>
2155+ </Row>
2156+% endfor
2157+
2158+ <Row ss:AutoFitHeight="0" ss:StyleID="s26">
2159+ <Cell ss:StyleID="s39"/>
2160+ <Cell ss:StyleID="s39"/>
2161+ <Cell ss:StyleID="s39"/>
2162+ <Cell ss:StyleID="s39"/>
2163+ <Cell ss:StyleID="s39"/>
2164+ <Cell ss:StyleID="s39"/>
2165+ <Cell ss:StyleID="s39"/>
2166+ <Cell ss:StyleID="s39"/>
2167+ <Cell ss:StyleID="s40"/>
2168+ <Cell ss:StyleID="s40"/>
2169+ <Cell ss:StyleID="s44"><Data ss:Type="String">${_('Sub Total')} =</Data></Cell>
2170+ % if nb_line:
2171+ <Cell ss:StyleID="s49" ss:Formula="=SUM(R[-${nb_line}]C:R[-1]C)"><Data ss:Type="Number" ></Data></Cell>
2172+ <Cell ss:StyleID="s49" ss:Formula="=SUM(R[-${nb_line}]C:R[-1]C)"><Data ss:Type="Number"></Data></Cell>
2173+ % else:
2174+ <Cell ss:StyleID="s49" />
2175+ <Cell ss:StyleID="s49" />
2176+ % endif
2177+ <Cell ss:StyleID="s29"><Data ss:Type="String">${getFuncCur() |x}</Data></Cell>
2178+ <Cell ss:StyleID="s42"/>
2179+ </Row>
2180+
2181+ <Row><Cell><Data ss:Type="String"></Data></Cell></Row>
2182+ <Row><Cell><Data ss:Type="String"></Data></Cell></Row>
2183+% endfor
2184+ </Table>
2185+ <WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
2186+ <Print>
2187+ <ValidPrinterInfo/>
2188+ <PaperSizeIndex>9</PaperSizeIndex>
2189+ <HorizontalResolution>600</HorizontalResolution>
2190+ <VerticalResolution>0</VerticalResolution>
2191+ </Print>
2192+ <Selected/>
2193+ <ProtectObjects>False</ProtectObjects>
2194+ <ProtectScenarios>False</ProtectScenarios>
2195+ </WorksheetOptions>
2196+ </Worksheet>
2197+</Workbook>
2198
2199=== added file 'vertical_integration/report/report_open_invoices.py'
2200--- vertical_integration/report/report_open_invoices.py 1970-01-01 00:00:00 +0000
2201+++ vertical_integration/report/report_open_invoices.py 2013-10-21 09:56:54 +0000
2202@@ -0,0 +1,77 @@
2203+# -*- coding: utf-8 -*-
2204+##############################################################################
2205+#
2206+# Copyright (C) 2013 MSF, TeMPO Consulting
2207+#
2208+# This program is free software: you can redistribute it and/or modify
2209+# it under the terms of the GNU Affero General Public License as
2210+# published by the Free Software Foundation, either version 3 of the
2211+# License, or (at your option) any later version.
2212+#
2213+# This program is distributed in the hope that it will be useful,
2214+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2215+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2216+# GNU Affero General Public License for more details.
2217+#
2218+# You should have received a copy of the GNU Affero General Public License
2219+# along with this program. If not, see <http://www.gnu.org/licenses/>.
2220+#
2221+##############################################################################
2222+
2223+from spreadsheet_xml.spreadsheet_xml_write import SpreadsheetReport
2224+from report import report_sxw
2225+from tools.translate import _
2226+
2227+
2228+class report_open_invoices2(report_sxw.rml_parse):
2229+ def __init__(self, cr, uid, name, context=None):
2230+ super(report_open_invoices2, self).__init__(cr, uid, name, context=context)
2231+ self.funcCur = ''
2232+ self.localcontext.update({
2233+ 'getLines':self.getLines,
2234+ 'getConvert':self.getConvert,
2235+ 'getFuncCur':self.getFuncCur,
2236+ })
2237+ return
2238+
2239+ def getLines(self,option):
2240+ result = []
2241+ sql_request = """
2242+ SELECT DISTINCT invoice.id, invoice.document_date, invoice.date_invoice, move.name,
2243+ partner.name, invoice.name, responsible.name,
2244+ invoice.date_due, invoice.origin,
2245+ currency.name, invoice.residual,
2246+ invoice.amount_total, invoice.state,
2247+ currency.id
2248+ FROM
2249+ account_invoice invoice
2250+ LEFT JOIN account_move move ON invoice.move_id = move.id
2251+ LEFT JOIN res_partner partner ON invoice.partner_id = partner.id
2252+ LEFT JOIN res_users responsible ON invoice.user_id = responsible.id
2253+ LEFT JOIN res_currency currency ON invoice.currency_id = currency.id
2254+ WHERE
2255+ invoice.state NOT IN ('paid', 'cancel') AND
2256+ invoice.type = %s
2257+ ORDER BY invoice.date_invoice
2258+ """
2259+
2260+ option_type = {'ci': 'out_invoice', 'si': 'in_invoice', 'cr': 'out_refund', 'sr': 'in_refund'}
2261+ if option_type.get(option):
2262+ self.cr.execute(sql_request, (option_type[option], ))
2263+ result = self.cr.fetchall()
2264+
2265+ return result
2266+
2267+ def getConvert(self, amount, line):
2268+ company = self.localcontext['company']
2269+ func_cur_id = company and company.currency_id and company.currency_id.id or False
2270+ conv = self.pool.get('res.currency').compute(self.cr, self.uid, line[13], func_cur_id, amount or 0.0, round=True)
2271+ return conv
2272+
2273+ def getFuncCur(self, ):
2274+ company = self.localcontext['company']
2275+ return company and company.currency_id and company.currency_id.name or ''
2276+
2277+
2278+SpreadsheetReport('report.open.invoices.2','account.invoice','addons/account_override/report/open_invoices_xls.mako', parser=report_open_invoices2)
2279+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
2280
2281=== added directory 'vertical_integration/security'
2282=== added file 'vertical_integration/security/ir.model.access.csv'
2283--- vertical_integration/security/ir.model.access.csv 1970-01-01 00:00:00 +0000
2284+++ vertical_integration/security/ir.model.access.csv 2013-10-21 09:56:54 +0000
2285@@ -0,0 +1,3 @@
2286+"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
2287+"access_account_mapping_all","account.export.mapping","model_account_export_mapping","",1,1,1,1
2288+"access_country_mapping_all","country.export.mapping","model_country_export_mapping","",1,1,1,1
2289
2290=== added directory 'vertical_integration/wizard'
2291=== added file 'vertical_integration/wizard/__init__.py'
2292--- vertical_integration/wizard/__init__.py 1970-01-01 00:00:00 +0000
2293+++ vertical_integration/wizard/__init__.py 2013-10-21 09:56:54 +0000
2294@@ -0,0 +1,2 @@
2295+import wizard_hq_report_ocg
2296+import wizard_hq_report_oca
2297\ No newline at end of file
2298
2299=== added file 'vertical_integration/wizard/wizard_hq_report_oca.py'
2300--- vertical_integration/wizard/wizard_hq_report_oca.py 1970-01-01 00:00:00 +0000
2301+++ vertical_integration/wizard/wizard_hq_report_oca.py 2013-10-21 09:56:54 +0000
2302@@ -0,0 +1,57 @@
2303+# -*- coding: utf-8 -*-
2304+##############################################################################
2305+#
2306+# OpenERP, Open Source Management Solution
2307+# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
2308+#
2309+# This program is free software: you can redistribute it and/or modify
2310+# it under the terms of the GNU Affero General Public License as
2311+# published by the Free Software Foundation, either version 3 of the
2312+# License, or (at your option) any later version.
2313+#
2314+# This program is distributed in the hope that it will be useful,
2315+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2316+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2317+# GNU Affero General Public License for more details.
2318+#
2319+# You should have received a copy of the GNU Affero General Public License
2320+# along with this program. If not, see <http://www.gnu.org/licenses/>.
2321+#
2322+##############################################################################
2323+
2324+from osv import fields, osv
2325+from tools.translate import _
2326+
2327+import datetime
2328+import base64
2329+import StringIO
2330+import csv
2331+
2332+class wizard_hq_report_oca(osv.osv_memory):
2333+ _name = "wizard.hq.report.oca"
2334+
2335+ _columns = {
2336+ 'instance_id': fields.many2one('msf.instance', 'Top proprietary instance', required=True),
2337+ 'fiscalyear_id': fields.many2one('account.fiscalyear', 'Fiscal year', required=True),
2338+ 'period_id': fields.many2one('account.period', 'Period', required=True)
2339+ }
2340+
2341+ _defaults = {
2342+ 'fiscalyear_id': lambda self, cr, uid, c: self.pool.get('account.fiscalyear').find(cr, uid, datetime.datetime.today().strftime('%Y-%m-%d'), context=c)
2343+ }
2344+
2345+ def button_create_report(self, cr, uid, ids, context=None):
2346+ wizard = self.browse(cr, uid, ids[0], context=context)
2347+ data = {}
2348+ # add parameters
2349+ data['form'] = {}
2350+ if wizard.instance_id:
2351+ # Get projects below instance
2352+ data['form'].update({'instance_ids': [wizard.instance_id.id] + [x.id for x in wizard.instance_id.child_ids]})
2353+ if wizard.period_id:
2354+ data['form'].update({'period_id': wizard.period_id.id})
2355+
2356+ return {'type': 'ir.actions.report.xml', 'report_name': 'hq.oca', 'datas': data}
2357+
2358+wizard_hq_report_oca()
2359+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
2360
2361=== added file 'vertical_integration/wizard/wizard_hq_report_oca_view.xml'
2362--- vertical_integration/wizard/wizard_hq_report_oca_view.xml 1970-01-01 00:00:00 +0000
2363+++ vertical_integration/wizard/wizard_hq_report_oca_view.xml 2013-10-21 09:56:54 +0000
2364@@ -0,0 +1,35 @@
2365+<?xml version="1.0" encoding="UTF-8"?>
2366+<openerp>
2367+ <data>
2368+
2369+ <record id="hq_export_oca_view" model="ir.ui.view">
2370+ <field name="name">Export to HQ system (OCA)</field>
2371+ <field name="model">wizard.hq.report.oca</field>
2372+ <field name="type">form</field>
2373+ <field name="arch" type="xml">
2374+ <form string="Export to HQ system">
2375+ <field name="instance_id" domain="[('level', '=', 'coordo')]"/>
2376+ <field name="fiscalyear_id"/>
2377+ <field name="period_id" domain="[('fiscalyear_id', '=', fiscalyear_id), ('state', 'in', ['mission-closed', 'done'])]"/>
2378+ <newline/>
2379+ <button icon="terp-camera_test" string="Export" name="button_create_report" type="object" default_focus="1"/>
2380+ </form>
2381+ </field>
2382+ </record>
2383+
2384+ <record id="action_hq_export_oca" model="ir.actions.act_window">
2385+ <field name="name">Export to HQ system (OCA)</field>
2386+ <field name="type">ir.actions.act_window</field>
2387+ <field name="res_model">wizard.hq.report.oca</field>
2388+ <field name="view_type">form</field>
2389+ <field name="view_mode">form</field>
2390+ <field name="view_id" ref="hq_export_oca_view"/>
2391+ <field name="target">new</field>
2392+ </record>
2393+
2394+ <menuitem parent="account.menu_finance_generic_reporting"
2395+ action="action_hq_export_oca"
2396+ id="menu_action_hq_export_oca" sequence="10"/>
2397+
2398+ </data>
2399+</openerp>
2400\ No newline at end of file
2401
2402=== added file 'vertical_integration/wizard/wizard_hq_report_ocg.py'
2403--- vertical_integration/wizard/wizard_hq_report_ocg.py 1970-01-01 00:00:00 +0000
2404+++ vertical_integration/wizard/wizard_hq_report_ocg.py 2013-10-21 09:56:54 +0000
2405@@ -0,0 +1,57 @@
2406+# -*- coding: utf-8 -*-
2407+##############################################################################
2408+#
2409+# OpenERP, Open Source Management Solution
2410+# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
2411+#
2412+# This program is free software: you can redistribute it and/or modify
2413+# it under the terms of the GNU Affero General Public License as
2414+# published by the Free Software Foundation, either version 3 of the
2415+# License, or (at your option) any later version.
2416+#
2417+# This program is distributed in the hope that it will be useful,
2418+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2419+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2420+# GNU Affero General Public License for more details.
2421+#
2422+# You should have received a copy of the GNU Affero General Public License
2423+# along with this program. If not, see <http://www.gnu.org/licenses/>.
2424+#
2425+##############################################################################
2426+
2427+from osv import fields, osv
2428+from tools.translate import _
2429+
2430+import datetime
2431+import base64
2432+import StringIO
2433+import csv
2434+
2435+class wizard_hq_report_ocg(osv.osv_memory):
2436+ _name = "wizard.hq.report.ocg"
2437+
2438+ _columns = {
2439+ 'instance_id': fields.many2one('msf.instance', 'Top proprietary instance', required=True),
2440+ 'fiscalyear_id': fields.many2one('account.fiscalyear', 'Fiscal year', required=True),
2441+ 'period_id': fields.many2one('account.period', 'Period', required=True)
2442+ }
2443+
2444+ _defaults = {
2445+ 'fiscalyear_id': lambda self, cr, uid, c: self.pool.get('account.fiscalyear').find(cr, uid, datetime.datetime.today().strftime('%Y-%m-%d'), context=c)
2446+ }
2447+
2448+ def button_create_report(self, cr, uid, ids, context=None):
2449+ wizard = self.browse(cr, uid, ids[0], context=context)
2450+ data = {}
2451+ # add parameters
2452+ data['form'] = {}
2453+ if wizard.instance_id:
2454+ # Get projects below instance
2455+ data['form'].update({'instance_ids': [wizard.instance_id.id] + [x.id for x in wizard.instance_id.child_ids]})
2456+ if wizard.period_id:
2457+ data['form'].update({'period_id': wizard.period_id.id})
2458+
2459+ return {'type': 'ir.actions.report.xml', 'report_name': 'hq.ocg', 'datas': data}
2460+
2461+wizard_hq_report_ocg()
2462+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
2463
2464=== added file 'vertical_integration/wizard/wizard_hq_report_ocg_view.xml'
2465--- vertical_integration/wizard/wizard_hq_report_ocg_view.xml 1970-01-01 00:00:00 +0000
2466+++ vertical_integration/wizard/wizard_hq_report_ocg_view.xml 2013-10-21 09:56:54 +0000
2467@@ -0,0 +1,35 @@
2468+<?xml version="1.0" encoding="UTF-8"?>
2469+<openerp>
2470+ <data>
2471+
2472+ <record id="hq_export_ocg_view" model="ir.ui.view">
2473+ <field name="name">Export to HQ system (OCG)</field>
2474+ <field name="model">wizard.hq.report.ocg</field>
2475+ <field name="type">form</field>
2476+ <field name="arch" type="xml">
2477+ <form string="Export to HQ system">
2478+ <field name="instance_id" domain="[('level', '=', 'coordo')]"/>
2479+ <field name="fiscalyear_id"/>
2480+ <field name="period_id" domain="[('fiscalyear_id', '=', fiscalyear_id), ('state', 'in', ['mission-closed', 'done'])]"/>
2481+ <newline/>
2482+ <button icon="terp-camera_test" string="Export" name="button_create_report" type="object" default_focus="1"/>
2483+ </form>
2484+ </field>
2485+ </record>
2486+
2487+ <record id="action_hq_export_ocg" model="ir.actions.act_window">
2488+ <field name="name">Export to HQ system (OCG)</field>
2489+ <field name="type">ir.actions.act_window</field>
2490+ <field name="res_model">wizard.hq.report.ocg</field>
2491+ <field name="view_type">form</field>
2492+ <field name="view_mode">form</field>
2493+ <field name="view_id" ref="hq_export_ocg_view"/>
2494+ <field name="target">new</field>
2495+ </record>
2496+
2497+ <menuitem parent="account.menu_finance_generic_reporting"
2498+ action="action_hq_export_ocg"
2499+ id="menu_action_hq_export_ocg" sequence="10"/>
2500+
2501+ </data>
2502+</openerp>
2503\ No newline at end of file

Subscribers

People subscribed via source and target branches