Merge lp:~mukunde/unifield-server/US-6392 into lp:unifield-server

Proposed by jftempo
Status: Merged
Merged at revision: 6259
Proposed branch: lp:~mukunde/unifield-server/US-6392
Merge into: lp:unifield-server
Diff against target: 6067 lines (+5298/-12) (has conflicts)
24 files modified
bin/addons/account/__openerp__.py (+1/-0)
bin/addons/account/account_menuitem.xml (+1/-0)
bin/addons/account/account_report.xml (+19/-0)
bin/addons/account/report/__init__.py (+1/-0)
bin/addons/account/report/account_employee_balance.rml (+360/-0)
bin/addons/account/report/account_employee_ledger.mako (+486/-0)
bin/addons/account/report/account_employee_ledger.py (+558/-0)
bin/addons/account/report/account_employee_ledger.rml (+777/-0)
bin/addons/account/report/account_employee_ledger_other.rml (+653/-0)
bin/addons/account/wizard/__init__.py (+3/-2)
bin/addons/account/wizard/account_report_common_employee.py (+86/-0)
bin/addons/account/wizard/account_report_employee_balance.py (+55/-0)
bin/addons/account/wizard/account_report_employee_ledger.py (+127/-0)
bin/addons/account/wizard/account_report_employee_ledger_view.xml (+85/-0)
bin/addons/finance/__openerp__.py (+1/-0)
bin/addons/finance/account_view.xml (+11/-1)
bin/addons/finance/report/__init__.py (+1/-0)
bin/addons/finance/report/account_employee_balance_tree.py (+311/-0)
bin/addons/finance/report/account_employee_balance_tree_xls.mako (+530/-0)
bin/addons/finance/report/account_report_name.py (+24/-0)
bin/addons/finance/wizard/__init__.py (+1/-0)
bin/addons/finance/wizard/account_report_employee_balance_tree.py (+553/-0)
bin/addons/finance/wizard/account_report_employee_balance_tree_view.xml (+177/-0)
bin/addons/msf_profile/i18n/fr_MF.po (+477/-9)
Text conflict in bin/addons/msf_profile/i18n/fr_MF.po
To merge this branch: bzr merge lp:~mukunde/unifield-server/US-6392
Reviewer Review Type Date Requested Status
UniField Reviewer Team Pending
Review via email: mp+422841@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 'bin/addons/account/__openerp__.py'
2--- bin/addons/account/__openerp__.py 2020-04-16 14:07:13 +0000
3+++ bin/addons/account/__openerp__.py 2022-06-01 15:15:45 +0000
4@@ -112,6 +112,7 @@
5 "wizard/account_report_profit_loss_view.xml",
6 "wizard/account_report_balance_sheet_view.xml",
7 "wizard/account_report_liquidity_balance_view.xml",
8+ "wizard/account_report_employee_ledger_view.xml",
9 ],
10 'demo_xml': [
11 'account_demo.xml',
12
13=== modified file 'bin/addons/account/account_menuitem.xml'
14--- bin/addons/account/account_menuitem.xml 2021-10-14 12:15:46 +0000
15+++ bin/addons/account/account_menuitem.xml 2022-06-01 15:15:45 +0000
16@@ -52,6 +52,7 @@
17 groups="group_account_user,group_account_manager"
18 name="Journals"/>
19 <menuitem id="next_id_22" name="Partners" parent="final_accounting_reports" sequence="120"/>
20+ <menuitem id="employee_menu" name="Employees" parent="final_accounting_reports" sequence="130"/>
21
22 </data>
23 </openerp>
24
25=== modified file 'bin/addons/account/account_report.xml'
26--- bin/addons/account/account_report.xml 2020-04-22 09:04:55 +0000
27+++ bin/addons/account/account_report.xml 2022-06-01 15:15:45 +0000
28@@ -36,6 +36,25 @@
29 attachment="(object.state in ('open','paid', 'inv_close')) and ('INV'+(object.number or '').replace('/',''))"
30 attachment_use="1"
31 multi="True"/>
32+
33+ <report auto="False" id="account_employee_ledger" menu="False" model="hr.employee" name="account.employee_ledger" rml="account/report/account_employee_ledger.rml" string="Employee Ledger" target_filename="Employee Ledger_%(instance_code)s_%(year)s%(month)s%(day)s" />
34+ <report auto="False" id="account_employee_ledger_other" menu="False" model="hr.employee" name="account.employee_ledger_other" rml="account/report/account_employee_ledger_other.rml" string="Employee Ledger" target_filename="Employee Ledger_%(instance_code)s_%(year)s%(month)s%(day)s"/>
35+
36+ <report id="account_employee_ledger_xls"
37+ auto="False"
38+ menu="False"
39+ header="False"
40+ model="account.account"
41+ name="account.employee_ledger_xls"
42+ file="account/report/account_employee_ledger.mako"
43+ report_type="webkit"
44+ target_filename="Employee Ledger_%(instance_code)s_%(year)s%(month)s%(day)s"
45+ string="Employee Ledger xls"/>
46+
47+ <report auto="False" id="account_employee_account_balance" menu="False" model="account.employee.balance.tree"
48+ name="account.employee.balance" rml="account/report/account_employee_balance.rml"
49+ string="Employee Balance" target_filename="Employee Balance_%(instance_code)s_%(year)s%(month)s%(day)s" />
50+
51 <report id="account_transfers" model="account.transfer" name="account.transfer" string="Transfers" xml="account/report/transfer.xml" xsl="account/report/transfer.xsl"/>
52 <report auto="False" id="account_intracom" menu="False" model="account.move.line" name="account.intracom" string="IntraCom"/>
53
54
55=== modified file 'bin/addons/account/report/__init__.py'
56--- bin/addons/account/report/__init__.py 2020-04-14 13:50:39 +0000
57+++ bin/addons/account/report/__init__.py 2022-06-01 15:15:45 +0000
58@@ -44,6 +44,7 @@
59 import free_allocation_report
60 import invoice_excel_export
61 import export_invoice
62+import account_employee_ledger
63
64 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
65
66
67=== added file 'bin/addons/account/report/account_employee_balance.rml'
68--- bin/addons/account/report/account_employee_balance.rml 1970-01-01 00:00:00 +0000
69+++ bin/addons/account/report/account_employee_balance.rml 2022-06-01 15:15:45 +0000
70@@ -0,0 +1,360 @@
71+<?xml version="1.0"?>
72+<document filename="Employee Balance.pdf">
73+ <template pageSize="(595.0,842.0)" title="Employee Balance" author="Tempo Consulting" allowSplitting="20">
74+ <pageTemplate id="first">
75+ <frame id="first" x1="57.0" y1="57.0" width="481" height="728"/>
76+ </pageTemplate>
77+ </template>
78+ <stylesheet>
79+ <blockTableStyle id="Standard_Outline">
80+ <blockAlignment value="LEFT"/>
81+ <blockValign value="TOP"/>
82+ </blockTableStyle>
83+ <blockTableStyle id="Table1">
84+ <blockAlignment value="LEFT"/>
85+ <blockValign value="TOP"/>
86+ <blockBackground colorName="#e6e6e6" start="0,0" stop="0,0"/>
87+ <blockBackground colorName="#e6e6e6" start="1,0" stop="1,0"/>
88+ <blockBackground colorName="#e6e6e6" start="2,0" stop="2,0"/>
89+ <blockBackground colorName="#e6e6e6" start="0,1" stop="0,1"/>
90+ <blockBackground colorName="#e6e6e6" start="1,1" stop="1,1"/>
91+ <blockBackground colorName="#e6e6e6" start="2,1" stop="2,1"/>
92+ </blockTableStyle>
93+ <blockTableStyle id="Table6">
94+ <blockAlignment value="LEFT"/>
95+ <blockValign value="TOP"/>
96+ <lineStyle kind="GRID" colorName="black"/>
97+ </blockTableStyle>
98+ <blockTableStyle id="Table_Company_Name">
99+ <blockAlignment value="LEFT"/>
100+ <blockValign value="TOP"/>
101+ </blockTableStyle>
102+ <blockTableStyle id="Table2">
103+ <lineStyle kind="LINEBELOW" colorName="#000000" start="0,0" stop="-1,0"/>
104+ <lineStyle kind="LINEBELOW" colorName="#000000" start="0,1" stop="-1,1"/>
105+ <lineStyle kind="LINEBELOW" colorName="#000000" start="0,2" stop="-1,2"/>
106+ <lineStyle kind="LINEBELOW" colorName="#000000" start="0,3" stop="-1,-1"/>
107+ <blockValign value="TOP"/>
108+ <blockAlignment value="RIGHT" start="2,1" stop="-1,-1"/>
109+ </blockTableStyle>
110+ <blockTableStyle id="Table3">
111+ <blockAlignment value="LEFT"/>
112+ <blockValign value="TOP"/>
113+ <lineStyle kind="LINEBEFORE" colorName="#cccccc" start="1,0" stop="1,-1"/>
114+ </blockTableStyle>
115+ <blockTableStyle id="Table4">
116+ <blockAlignment value="LEFT"/>
117+ <blockValign value="TOP"/>
118+ <lineStyle kind="GRID" colorName="black"/>
119+ </blockTableStyle>
120+ <blockTableStyle id="Tableau3">
121+ <blockAlignment value="LEFT"/>
122+ <blockValign value="TOP"/>
123+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" />
124+ <lineStyle kind="OUTLINE" colorName="#e6e6e6" />
125+ <blockBackground colorName="white" start="0,0" stop="-1,0"/>
126+ </blockTableStyle>
127+ <blockTableStyle id="Table_Sub_Header_Content">
128+ <blockAlignment value="LEFT"/>
129+ <blockValign value="TOP"/>
130+ <lineStyle kind="LINEBEFORE" colorName="#cccccc" start="0,0" stop="0,-1"/>
131+ <lineStyle kind="LINEABOVE" colorName="#cccccc" start="0,0" stop="0,0"/>
132+ <lineStyle kind="LINEBELOW" colorName="#cccccc" start="0,-1" stop="0,-1"/>
133+ <lineStyle kind="LINEBEFORE" colorName="#cccccc" start="1,0" stop="1,-1"/>
134+ <lineStyle kind="LINEABOVE" colorName="#cccccc" start="1,0" stop="1,0"/>
135+ <lineStyle kind="LINEBELOW" colorName="#cccccc" start="1,-1" stop="1,-1"/>
136+ <lineStyle kind="LINEBEFORE" colorName="#cccccc" start="2,0" stop="2,-1"/>
137+ <lineStyle kind="LINEAFTER" colorName="#cccccc" start="2,0" stop="2,-1"/>
138+ <lineStyle kind="LINEABOVE" colorName="#cccccc" start="2,0" stop="2,0"/>
139+ <lineStyle kind="LINEBELOW" colorName="#cccccc" start="2,-1" stop="2,-1"/>
140+ <lineStyle kind="LINEBEFORE" colorName="#cccccc" start="3,0" stop="3,-1"/>
141+ <lineStyle kind="LINEAFTER" colorName="#cccccc" start="3,0" stop="3,-1"/>
142+ <lineStyle kind="LINEABOVE" colorName="#cccccc" start="3,0" stop="3,0"/>
143+ <lineStyle kind="LINEBELOW" colorName="#cccccc" start="3,-1" stop="3,-1"/>
144+ <lineStyle kind="LINEAFTER" colorName="#cccccc" start="4,0" stop="4,-1"/>
145+ <lineStyle kind="LINEABOVE" colorName="#cccccc" start="4,0" stop="4,0"/>
146+ <lineStyle kind="LINEBELOW" colorName="#cccccc" start="4,-1" stop="4,-1"/>
147+ <lineStyle kind="LINEAFTER" colorName="#cccccc" start="5,0" stop="5,-1"/>
148+ <lineStyle kind="LINEABOVE" colorName="#cccccc" start="5,0" stop="5,0"/>
149+ <lineStyle kind="LINEBELOW" colorName="#cccccc" start="5,-1" stop="5,-1"/>
150+ </blockTableStyle>
151+ <blockTableStyle id="Table2_header">
152+ <blockAlignment value="LEFT"/>
153+ <blockValign value="TOP"/>
154+ <lineStyle kind="LINEBELOW" colorName="#cccccc" start="0,0" stop="-1,0"/>
155+ <lineStyle kind="LINEBEFORE" colorName="#cccccc" start="0,0" stop="0,-1"/>
156+ <lineStyle kind="LINEABOVE" colorName="#cccccc" start="0,0" stop="0,0"/>
157+ <lineStyle kind="LINEBELOW" colorName="#cccccc" start="0,-1" stop="0,-1"/>
158+ <lineStyle kind="LINEBEFORE" colorName="#cccccc" start="1,0" stop="1,-1"/>
159+ <lineStyle kind="LINEABOVE" colorName="#cccccc" start="1,0" stop="1,0"/>
160+ <lineStyle kind="LINEBELOW" colorName="#cccccc" start="1,-1" stop="1,-1"/>
161+ <lineStyle kind="LINEBEFORE" colorName="#cccccc" start="2,0" stop="2,-1"/>
162+ <lineStyle kind="LINEAFTER" colorName="#cccccc" start="2,0" stop="2,-1"/>
163+ <lineStyle kind="LINEABOVE" colorName="#cccccc" start="2,0" stop="2,0"/>
164+ <lineStyle kind="LINEBELOW" colorName="#cccccc" start="2,-1" stop="2,-1"/>
165+ <lineStyle kind="LINEBEFORE" colorName="#cccccc" start="3,0" stop="3,-1"/>
166+ <lineStyle kind="LINEAFTER" colorName="#cccccc" start="3,0" stop="3,-1"/>
167+ <lineStyle kind="LINEABOVE" colorName="#cccccc" start="3,0" stop="3,0"/>
168+ <lineStyle kind="LINEBELOW" colorName="#cccccc" start="3,-1" stop="3,-1"/>
169+ <lineStyle kind="LINEBEFORE" colorName="#cccccc" start="4,0" stop="4,-1"/>
170+ <lineStyle kind="LINEABOVE" colorName="#cccccc" start="4,0" stop="4,0"/>
171+ <lineStyle kind="LINEBELOW" colorName="#cccccc" start="4,-1" stop="4,-1"/>
172+ <lineStyle kind="LINEBEFORE" colorName="#cccccc" start="5,0" stop="5,-1"/>
173+ <lineStyle kind="LINEABOVE" colorName="#cccccc" start="5,0" stop="5,0"/>
174+ <lineStyle kind="LINEBELOW" colorName="#cccccc" start="5,-1" stop="5,-1"/>
175+ <lineStyle kind="LINEBEFORE" colorName="#cccccc" start="6,0" stop="6,-1"/>
176+ <lineStyle kind="LINEAFTER" colorName="#cccccc" start="6,0" stop="6,-1"/>
177+ <lineStyle kind="LINEABOVE" colorName="#cccccc" start="6,0" stop="6,0"/>
178+ <lineStyle kind="LINEBELOW" colorName="#cccccc" start="6,-1" stop="6,-1"/>
179+ <lineStyle kind="LINEBEFORE" colorName="#cccccc" start="7,0" stop="7,-1"/>
180+ <lineStyle kind="LINEAFTER" colorName="#cccccc" start="7,0" stop="7,-1"/>
181+ <lineStyle kind="LINEABOVE" colorName="#cccccc" start="7,0" stop="7,0"/>
182+ <lineStyle kind="LINEBELOW" colorName="#cccccc" start="7,-1" stop="7,-1"/>
183+ </blockTableStyle>
184+
185+ <blockTableStyle id="Table_Subheader_Content_detail">
186+ <blockAlignment value="LEFT"/>
187+ <blockValign value="TOP"/>
188+ <lineStyle kind="LINEBEFORE" colorName="#cccccc" start="0,0" stop="0,-1"/>
189+ <lineStyle kind="LINEABOVE" colorName="#cccccc" start="0,0" stop="0,0"/>
190+ <lineStyle kind="LINEBELOW" colorName="#cccccc" start="0,-1" stop="0,-1"/>
191+ <lineStyle kind="LINEBEFORE" colorName="#cccccc" start="1,0" stop="1,-1"/>
192+ <lineStyle kind="LINEABOVE" colorName="#cccccc" start="1,0" stop="1,0"/>
193+ <lineStyle kind="LINEBELOW" colorName="#cccccc" start="1,-1" stop="1,-1"/>
194+ <lineStyle kind="LINEBEFORE" colorName="#cccccc" start="2,0" stop="2,-1"/>
195+ <lineStyle kind="LINEAFTER" colorName="#cccccc" start="2,0" stop="2,-1"/>
196+ <lineStyle kind="LINEABOVE" colorName="#cccccc" start="2,0" stop="2,0"/>
197+ <lineStyle kind="LINEBELOW" colorName="#cccccc" start="2,-1" stop="2,-1"/>
198+ <lineStyle kind="LINEBEFORE" colorName="#cccccc" start="3,0" stop="3,-1"/>
199+ <lineStyle kind="LINEAFTER" colorName="#cccccc" start="3,0" stop="3,-1"/>
200+ <lineStyle kind="LINEABOVE" colorName="#cccccc" start="3,0" stop="3,0"/>
201+ <lineStyle kind="LINEBELOW" colorName="#cccccc" start="3,-1" stop="3,-1"/>
202+ <lineStyle kind="LINEAFTER" colorName="#cccccc" start="4,0" stop="4,-1"/>
203+ <lineStyle kind="LINEABOVE" colorName="#cccccc" start="4,0" stop="4,0"/>
204+ <lineStyle kind="LINEBELOW" colorName="#cccccc" start="4,-1" stop="4,-1"/>
205+ <lineStyle kind="LINEAFTER" colorName="#cccccc" start="5,0" stop="5,-1"/>
206+ <lineStyle kind="LINEABOVE" colorName="#cccccc" start="5,0" stop="5,0"/>
207+ <lineStyle kind="LINEBELOW" colorName="#cccccc" start="5,-1" stop="5,-1"/>
208+ </blockTableStyle>
209+
210+ <initialize>
211+ <paraStyle name="all" alignment="justify"/>
212+ </initialize>
213+
214+ <paraStyle name="P3" fontName="Helvetica" fontSize="8.0" leading="10" alignment="LEFT" spaceBefore="0.0" spaceAfter="6.0"/>
215+ <paraStyle name="P4" fontName="Helvetica" fontSize="8.0" leading="10" alignment="RIGHT" spaceBefore="0.0" spaceAfter="6.0"/>
216+ <paraStyle name="P4Bold" fontName="Helvetica-Bold" fontSize="8.0" leading="10" alignment="RIGHT" spaceBefore="0.0" spaceAfter="6.0"/>
217+ <paraStyle name="P5" fontName="Helvetica" alignment="CENTER" spaceBefore="0.0" spaceAfter="6.0"/>
218+ <paraStyle name="P6" fontName="Helvetica" fontSize="11.0" leading="12" alignment="RIGHT" spaceBefore="0.0" spaceAfter="6.0"/>
219+ <paraStyle name="P7" fontName="Helvetica-Bold" fontSize="9" leading="10" alignment="LEFT" spaceBefore="0.0" spaceAfter="6.0"/>
220+ <paraStyle name="P8" fontName="Helvetica-Bold" fontSize="9" leading="10" alignment="RIGHT" spaceBefore="0.0" spaceAfter="6.0"/>
221+ <paraStyle name="P9" fontName="Helvetica" alignment="LEFT" spaceBefore="0.0" spaceAfter="6.0"/>
222+ <paraStyle name="P9b" fontName="Helvetica-Bold" alignment="RIGHT" spaceBefore="0.0" spaceAfter="6.0"/>
223+ <paraStyle name="P10" fontName="Helvetica" alignment="CENTER"/>
224+ <paraStyle name="P11" fontName="Helvetica" fontSize="8.0" leading="10"/>
225+ <paraStyle name="P12" fontName="Helvetica-Bold" fontSize="9.0" leading="10" alignment="CENTER" spaceBefore="0.0" spaceAfter="6.0"/>
226+ <paraStyle name="P12a" fontName="Helvetica-Bold" fontSize="9.0" leading="10" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
227+ <paraStyle name="P12b" fontName="Helvetica-Bold" fontSize="9.0" leading="10" alignment="RIGHT" spaceBefore="0.0" spaceAfter="6.0"/>
228+ <paraStyle name="P13" fontName="Helvetica" fontSize="8.0" leading="10" spaceBefore="0.0" spaceAfter="6.0"/>
229+ <paraStyle name="P14" rightIndent="17.0" leftIndent="-0.0" fontName="Times-Bold" fontSize="8.0" leading="10" spaceBefore="0.0" spaceAfter="6.0"/>
230+ <paraStyle name="P15" fontName="Helvetica-Bold" fontSize="8.5" leading="10" alignment="LEFT" spaceBefore="0.0" spaceAfter="6.0"/>
231+ <paraStyle name="Standard" fontName="Helvetica"/>
232+ <paraStyle name="terp_header_Centre" fontName="Helvetica-Bold" fontSize="15.0" leading="19" alignment="CENTER" spaceBefore="12.0" spaceAfter="6.0"/>
233+ <paraStyle name="terp_default_Centre_9" fontName="Helvetica" fontSize="9.0" leading="11" alignment="CENTER" spaceBefore="0.0" spaceAfter="0.0"/>
234+ <paraStyle name="Text body" fontName="Helvetica" spaceBefore="0.0" spaceAfter="6.0"/>
235+ <paraStyle name="List" fontName="Helvetica" spaceBefore="0.0" spaceAfter="6.0"/>
236+ <paraStyle name="Table Contents" fontName="Helvetica" spaceBefore="0.0" spaceAfter="6.0"/>
237+ <paraStyle name="Table Heading" fontName="Helvetica" alignment="CENTER" spaceBefore="0.0" spaceAfter="6.0"/>
238+ <paraStyle name="Caption" fontName="Helvetica" fontSize="10.0" leading="11" spaceBefore="6.0" spaceAfter="6.0"/>
239+ <paraStyle name="Index" fontName="Helvetica"/>
240+ <paraStyle name="terp_default_8" fontName="Helvetica" fontSize="8.0" leading="10" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
241+ <paraStyle name="terp_default_Centre_8" fontName="Helvetica" fontSize="8.0" leading="10" alignment="CENTER" spaceBefore="0.0" spaceAfter="0.0"/>
242+ <paraStyle name="terp_tblheader_General_Centre" fontName="Helvetica-Bold" fontSize="8.0" leading="10" alignment="CENTER" spaceBefore="6.0" spaceAfter="6.0"/>
243+ <paraStyle name="terp_tblheader_Details_Centre" fontName="Helvetica-Bold" fontSize="8.0" leading="11" alignment="CENTER" spaceBefore="6.0" spaceAfter="6.0"/>
244+ </stylesheet>
245+
246+ <story>
247+ <blockTable colWidths="539.0" style="Table_Company_Name">
248+ <tr>
249+ <td>
250+ <para style="terp_header_Centre">Employee Balance</para>
251+ </td>
252+ </tr>
253+ </blockTable>
254+ <para style="terp_default_8">
255+ <font color="white"> </font>
256+ </para>
257+ <section>
258+ [[ repeatIn(get_employees(data), 'p_entries') ]]
259+ <!-- NOTE: if this HEADER has to be modified: modify also the "no data" version (below) -->
260+ <blockTable colWidths="50.0,37.0,81.0,50.0,91.0,118.0,90.0,43.0" style="Table2_header">
261+ <tr>
262+ <td><para style="terp_tblheader_General_Centre">Chart of Account</para></td>
263+ <td><para style="terp_tblheader_General_Centre">Fiscal Year</para></td>
264+ <td><para style="terp_tblheader_General_Centre">Journals</para></td>
265+ <td><para style="terp_tblheader_General_Centre">Accounts</para></td>
266+ <td><para style="terp_tblheader_General_Centre">Proprietary Instances</para></td>
267+ <td><para style="terp_tblheader_General_Centre">Filter By [[ get_filter(data)!=translate('No Filter') and get_filter(data) ]]</para></td>
268+ <td><para style="terp_tblheader_General_Centre">Display</para></td>
269+ <td><para style="terp_tblheader_General_Centre">Func. Currency</para></td>
270+ </tr>
271+ <tr>
272+ <td><para style="terp_default_Centre_8">[[ get_account(data) or removeParentNode('para') ]]</para></td>
273+ <td><para style="terp_default_Centre_8">[[ get_fiscalyear(data) or '' ]]</para></td>
274+ <td> <para style="terp_default_Centre_8">[[ get_journals_str(data) ]] </para></td>
275+ <td><para style="terp_default_Centre_8">[[ get_accounts_str(data) ]]</para></td>
276+ <td><para style="terp_default_Centre_8">[[ get_prop_instances_str(data, pdf=True) ]]</para></td>
277+
278+ <td><para style="terp_default_Centre_8">[[ get_filter(data)==translate('No Filter') and get_filter(data) or removeParentNode('para') ]] </para>
279+ <blockTable colWidths="55.0,55.0" style="Table3">[[ get_filter(data)==translate('Date') or removeParentNode('blockTable') ]]
280+ <tr>
281+ <td><para style="terp_tblheader_General_Centre">Start Date</para></td>
282+ <td><para style="terp_tblheader_General_Centre">End Date</para></td>
283+ </tr>
284+ <tr>
285+ <td><para style="terp_default_Centre_8">[[ formatLang(get_start_date(data),date=True) ]]</para></td>
286+ <td><para style="terp_default_Centre_8">[[ formatLang(get_end_date(data),date=True) ]]</para></td>
287+ </tr>
288+ </blockTable>
289+ <blockTable colWidths="55.0,55.0" style="Table3">[[ get_filter(data)==translate('Periods') or removeParentNode('blockTable') ]]
290+ <tr>
291+ <td><para style="terp_tblheader_General_Centre">Start Period</para></td>
292+ <td><para style="terp_tblheader_General_Centre">End Period</para></td>
293+ </tr>
294+ <tr>
295+ <td><para style="terp_default_Centre_8">[[ get_start_period(data) or removeParentNode('para') ]]</para></td>
296+ <td><para style="terp_default_Centre_8">[[ get_end_period(data) or removeParentNode('para') ]]</para></td>
297+ </tr>
298+ </blockTable>
299+ </td>
300+ <td>
301+ <para style="terp_default_Centre_8">[[ "%s: %s, %s: %s, %s: %s, %s: %s, %s: %s, %s: %s" % (translate("Employee's"), get_type_of_accounts(), translate('Target Moves'), get_target_move(data), translate('Reconciled'), get_reconcile_selection(data), translate('Display Employees'), get_display_employees_selection(data), translate('Employee Type'), get_employee_type(data), translate('Payment Method'), get_payment_methods(data)) ]]</para>
302+ </td>
303+ <td>
304+ <para style="terp_default_Centre_8">[[ company.currency_id.name ]]</para>
305+ </td>
306+ </tr>
307+ </blockTable>
308+
309+ <para style="terp_default_8">
310+ <font color="white"> </font>
311+ </para>
312+ <blockTable colWidths="140.0,55.0,75.0,65.0,70.0,70.0,69.0" repeatRows="1" style="Table2">
313+ <tr>
314+ <td><para style="P12a">Employee</para></td>
315+ <td><para style="P12b">Account</para></td>
316+ <td><para style="P12b">Currency</para></td>
317+ <td><para style="P12b">Debit</para></td>
318+ <td><para style="P12b">Credit</para></td>
319+ <td><para style="P12b">Booking Balance</para></td>
320+ <td><para style="P12b">Balance [[ company.currency_id.name ]]</para></td>
321+ </tr>
322+ <tr>
323+ <td><para style="P7">TOTAL EMPLOYEES:</para></td>
324+ <td><para style="P8"></para></td>
325+ <td><para style="P8"><u>[[ company.currency_id.name ]]</u></para></td>
326+ <td><para style="P8"><u>[[ formatLang(get_employees_total_debit_credit_balance(data)[0] or 0.0) ]]</u></para></td>
327+ <td><para style="P8"><u>[[ formatLang(get_employees_total_debit_credit_balance(data)[1] or 0.0) ]]</u></para></td>
328+ <td><para style="P10">-</para></td>
329+ <td><para style="P8"><u>[[ formatLang(get_employees_total_debit_credit_balance(data)[2] or 0.0) ]]</u></para></td>
330+ </tr>
331+ <tr>
332+ [[ repeatIn(p_entries, 'p_obj') ]]
333+ <!-- For each employee: show one header line and the detail per account -->
334+ <td>
335+ <blockTable colWidths="135.0,69.0,60.0,63.0,71.0,68.0,68.0">
336+ <tr>
337+ <td><para style="P15">[[ p_obj.name or '' ]]</para></td>
338+ <td><para style="P15"></para></td>
339+ <td><para style="P4Bold">[[ company.currency_id.name ]]</para></td>
340+ <td><para style="P4Bold" fontSize="8.5">[[ formatLang(p_obj.debit or 0.0) ]]</para></td>
341+ <td><para style="P4Bold" fontSize="8.5">[[ formatLang(p_obj.credit or 0.0) ]]</para></td>
342+ <td><para style="P4Bold" fontSize="8.5">[[ formatLang(p_obj.balance or 0.0) ]]</para></td>
343+ <td><para style="P4Bold" fontSize="8.5">[[ formatLang(p_obj.balance or 0.0) ]]</para></td>
344+ </tr>
345+ <tr>
346+ [[ repeatIn(get_employee_account_move_lines(p_obj.employee_id.id, data), 'aml') ]]
347+ <!-- For each account: display one line with the total in functional currency,
348+ and one line per booking currency used -->
349+ <td>
350+ <blockTable colWidths="151.0,28.0,79.0,64.0,72.0,67.0,67.0">
351+ <tr>
352+ <td><para style="P4Bold"></para></td>
353+ <td><para style="P4Bold">[[ aml.get('account', '') ]]</para></td>
354+ <td><para style="P4Bold">[[ company.currency_id.name ]]</para></td>
355+ <td><para style="P4Bold">[[ formatLang(aml.get('deb') or 0.0) ]]</para></td>
356+ <td><para style="P4Bold">[[ formatLang(aml.get('cred') or 0.0) ]]</para></td>
357+ <td><para style="P4Bold">[[ formatLang(aml.get('total') or 0.0) ]]</para></td>
358+ <td><para style="P4Bold">[[ formatLang(aml.get('total') or 0.0) ]]</para></td>
359+ </tr>
360+ <tr>
361+ [[ repeatIn(get_lines_per_currency(p_obj.employee_id.id, data, aml.get('account')), 'detail_line') ]]
362+ <td><para style="P4"></para></td>
363+ <td><para style="P4">Subtotal</para></td>
364+ <td><para style="P4">[[ detail_line.get('currency_booking', '') ]]</para></td>
365+ <td><para style="P4">[[ formatLang(detail_line.get('debit_booking') or 0.0) ]]</para></td>
366+ <td><para style="P4">[[ formatLang(detail_line.get('credit_booking') or 0.0) ]]</para></td>
367+ <td><para style="P4">[[ formatLang(detail_line.get('total_booking') or 0.0) ]]</para></td>
368+ <td><para style="P4">[[ formatLang(detail_line.get('total_functional') or 0.0) ]]</para></td>
369+ </tr>
370+ </blockTable>
371+ </td>
372+ </tr>
373+ </blockTable>
374+ </td>
375+ </tr>
376+ </blockTable>
377+ </section>
378+ <!-- if there is NO DATA to be displayed: display the header only -->
379+ <blockTable colWidths="50.0,37.0,81.0,50.0,91.0,118.0,90.0,43.0" style="Table2_header">
380+ [[ get_has_data() and removeParentNode('blockTable') ]]
381+ <tr>
382+ <td><para style="terp_tblheader_General_Centre">Chart of Account</para></td>
383+ <td><para style="terp_tblheader_General_Centre">Fiscal Year</para></td>
384+ <td><para style="terp_tblheader_General_Centre">Journals</para></td>
385+ <td><para style="terp_tblheader_General_Centre">Accounts</para></td>
386+ <td><para style="terp_tblheader_General_Centre">Proprietary Instances</para></td>
387+ <td><para style="terp_tblheader_General_Centre">Filter By [[ get_filter(data)!=translate('No Filter') and get_filter(data) ]]</para></td>
388+ <td><para style="terp_tblheader_General_Centre">Display</para></td>
389+ <td><para style="terp_tblheader_General_Centre">Func. Currency</para></td>
390+ </tr>
391+ <tr>
392+ <td><para style="terp_default_Centre_8">[[ get_account(data) or removeParentNode('para') ]]</para></td>
393+ <td><para style="terp_default_Centre_8">[[ get_fiscalyear(data) or '' ]]</para></td>
394+ <td> <para style="terp_default_Centre_8">[[ get_journals_str(data) ]] </para></td>
395+ <td><para style="terp_default_Centre_8">[[ get_accounts_str(data) ]]</para></td>
396+ <td><para style="terp_default_Centre_8">[[ get_prop_instances_str(data, pdf=True) ]]</para></td>
397+
398+ <td><para style="terp_default_Centre_8">[[ get_filter(data)==translate('No Filter') and get_filter(data) or removeParentNode('para') ]] </para>
399+ <blockTable colWidths="55.0,55.0" style="Table3">[[ get_filter(data)==translate('Date') or removeParentNode('blockTable') ]]
400+ <tr>
401+ <td><para style="terp_tblheader_General_Centre">Start Date</para></td>
402+ <td><para style="terp_tblheader_General_Centre">End Date</para></td>
403+ </tr>
404+ <tr>
405+ <td><para style="terp_default_Centre_8">[[ formatLang(get_start_date(data),date=True) ]]</para></td>
406+ <td><para style="terp_default_Centre_8">[[ formatLang(get_end_date(data),date=True) ]]</para></td>
407+ </tr>
408+ </blockTable>
409+ <blockTable colWidths="55.0,55.0" style="Table3">[[ get_filter(data)==translate('Periods') or removeParentNode('blockTable') ]]
410+ <tr>
411+ <td><para style="terp_tblheader_General_Centre">Start Period</para></td>
412+ <td><para style="terp_tblheader_General_Centre">End Period</para></td>
413+ </tr>
414+ <tr>
415+ <td><para style="terp_default_Centre_8">[[ get_start_period(data) or removeParentNode('para') ]]</para></td>
416+ <td><para style="terp_default_Centre_8">[[ get_end_period(data) or removeParentNode('para') ]]</para></td>
417+ </tr>
418+ </blockTable>
419+ </td>
420+ <td>
421+ <para style="terp_default_Centre_8">[[ "%s: %s, %s: %s, %s: %s, %s: %s, %s: %s, %s: %s" % (translate("Employee's"), get_type_of_accounts(), translate('Target Moves'), get_target_move(data), translate('Reconciled'), get_reconcile_selection(data), translate('Display Employees'), get_display_employees_selection(data), translate('Employee Type'), get_employee_type(data), translate('Payment Method'), get_payment_methods(data)) ]]</para>
422+ </td>
423+ <td>
424+ <para style="terp_default_Centre_8">[[ company.currency_id.name ]]</para>
425+ </td>
426+ </tr>
427+ </blockTable>
428+
429+ </story>
430+</document>
431
432=== added file 'bin/addons/account/report/account_employee_ledger.mako'
433--- bin/addons/account/report/account_employee_ledger.mako 1970-01-01 00:00:00 +0000
434+++ bin/addons/account/report/account_employee_ledger.mako 2022-06-01 15:15:45 +0000
435@@ -0,0 +1,486 @@
436+<?xml version="1.0"?>
437+<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
438+xmlns:o="urn:schemas-microsoft-com:office:office"
439+xmlns:x="urn:schemas-microsoft-com:office:excel"
440+xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
441+xmlns:html="http://www.w3.org/TR/REC-html40">
442+<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">
443+<Title>Employee</Title>
444+</DocumentProperties>
445+<Styles>
446+<Style ss:ID="ssCell">
447+<Alignment ss:Vertical="Top" ss:WrapText="1"/>
448+</Style>
449+<Style ss:ID="ssCellRight">
450+<Alignment ss:Horizontal="Right" ss:Vertical="Top" ss:WrapText="1"/>
451+</Style>
452+<Style ss:ID="ssCellRightBold">
453+<Alignment ss:Horizontal="Right" ss:Vertical="Top" ss:WrapText="1"/>
454+<Font ss:Bold="1" />
455+</Style>
456+<Style ss:ID="ssH">
457+<Alignment ss:Horizontal="Center" ss:Vertical="Center" ss:WrapText="1"/>
458+<Font ss:Bold="1" />
459+<Borders>
460+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" />
461+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
462+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
463+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" />
464+</Borders>
465+</Style>
466+<Style ss:ID="ssBorder">
467+<Alignment ss:Vertical="Center" ss:WrapText="1"/>
468+<Borders>
469+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" />
470+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
471+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
472+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" />
473+</Borders>
474+</Style>
475+<Style ss:ID="ssBorderDate">
476+<Alignment ss:Vertical="Center" ss:WrapText="1"/>
477+<Borders>
478+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" />
479+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
480+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
481+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" />
482+</Borders>
483+<NumberFormat ss:Format="Short Date" />
484+</Style>
485+<Style ss:ID="ssNumber">
486+<Borders>
487+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" />
488+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
489+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
490+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" />
491+</Borders>
492+<Alignment ss:Horizontal="Right" ss:Vertical="Center" ss:WrapText="1"/>
493+<NumberFormat ss:Format="#,##0.00"/>
494+</Style>
495+<Style ss:ID="ssHeader">
496+<Alignment ss:Vertical="Top" ss:Horizontal="Center" ss:WrapText="1"/>
497+<Font ss:Bold="1" />
498+<Borders>
499+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" />
500+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
501+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
502+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" />
503+</Borders>
504+</Style>
505+<Style ss:ID="ssHeaderNumber">
506+<Font ss:Bold="1" />
507+<Alignment ss:Horizontal="Right" ss:Vertical="Top" ss:WrapText="1"/>
508+<Borders>
509+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" />
510+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
511+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
512+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" />
513+</Borders>
514+<NumberFormat ss:Format="#,##0.00"/>
515+</Style>
516+<Style ss:ID="ssHeaderRight">
517+<Font ss:Bold="1" />
518+<Alignment ss:Horizontal="Right" ss:Vertical="Top" ss:WrapText="1"/>
519+<Borders>
520+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" />
521+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
522+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
523+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" />
524+</Borders>
525+</Style>
526+<Style ss:ID="ssHeaderCell">
527+<Alignment ss:Vertical="Top" ss:Horizontal="Center" ss:WrapText="1"/>
528+<Borders>
529+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" />
530+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
531+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
532+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" />
533+</Borders>
534+</Style>
535+<Style ss:ID="ssHeaderNumberCell">
536+<Alignment ss:Horizontal="Right" ss:Vertical="Top" ss:WrapText="1"/>
537+<Borders>
538+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" />
539+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
540+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
541+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" />
542+</Borders>
543+<NumberFormat ss:Format="#,##0.00"/>
544+</Style>
545+<Style ss:ID="ssEmployee">
546+<Alignment ss:Vertical="Top" ss:WrapText="1"/>
547+<Font ss:Bold="1" />
548+<Borders>
549+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" />
550+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
551+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
552+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" />
553+</Borders>
554+</Style>
555+<Style ss:ID="ssEmployeeNumber">
556+<Font ss:Bold="1" />
557+<Alignment ss:Horizontal="Right" ss:Vertical="Top" ss:WrapText="1"/>
558+<Borders>
559+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" />
560+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
561+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
562+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" />
563+</Borders>
564+<NumberFormat ss:Format="#,##0.00"/>
565+</Style>
566+<Style ss:ID="ssEmployeeRight">
567+<Font ss:Bold="1" />
568+<Alignment ss:Horizontal="Right" ss:Vertical="Top" ss:WrapText="1"/>
569+<Borders>
570+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" />
571+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
572+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
573+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" />
574+</Borders>
575+</Style>
576+<Style ss:ID="ssAccountLine">
577+<Alignment ss:Vertical="Top" ss:Horizontal="Left" ss:WrapText="1"/>
578+<Font ss:Size="8"/>
579+<Borders>
580+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" />
581+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
582+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
583+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" />
584+</Borders>
585+</Style>
586+<Style ss:ID="ssSubtotalLineLeft">
587+<Alignment ss:Vertical="Top" ss:Horizontal="Left" ss:WrapText="1"/>
588+<Font ss:Size="10"/>
589+<Borders>
590+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" />
591+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
592+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
593+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" />
594+</Borders>
595+</Style>
596+<Style ss:ID="ssSubtotalLineRight">
597+<Alignment ss:Vertical="Top" ss:Horizontal="Right" ss:WrapText="1"/>
598+<Font ss:Size="10"/>
599+<Borders>
600+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" />
601+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
602+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
603+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" />
604+</Borders>
605+</Style>
606+<Style ss:ID="ssAccountLineWrap">
607+ <Alignment ss:Horizontal="Left" ss:Vertical="Center" ss:WrapText="1"/>
608+ <Borders>
609+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>
610+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1"/>
611+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1"/>
612+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>
613+ </Borders>
614+ <Font ss:Size="8"/>
615+ <Interior/>
616+ <NumberFormat/>
617+ <Protection/>
618+</Style>
619+<Style ss:ID="ssAccountLineNumber">
620+<Alignment ss:Horizontal="Right" ss:Vertical="Top" ss:WrapText="1"/>
621+<Font ss:Size="8"/>
622+<Borders>
623+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" />
624+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
625+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
626+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" />
627+</Borders>
628+<NumberFormat ss:Format="#,##0.00"/>
629+</Style>
630+<Style ss:ID="ssSubtotalLineNumber">
631+<Alignment ss:Horizontal="Right" ss:Vertical="Top" ss:WrapText="1"/>
632+<Font ss:Size="10"/>
633+<Borders>
634+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" />
635+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
636+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
637+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" />
638+</Borders>
639+<NumberFormat ss:Format="#,##0.00"/>
640+</Style>
641+<Style ss:ID="ssAccountLineAccountCode">
642+<Alignment ss:Horizontal="Right" ss:Vertical="Top" ss:WrapText="1"/>
643+<Font ss:Size="8"/>
644+<Borders>
645+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" />
646+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
647+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
648+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" />
649+</Borders>
650+<Interior/>
651+<NumberFormat ss:Format="0" />
652+<Protection/>
653+</Style>
654+</Styles>
655+<Worksheet ss:Name="${( get_employees() )|x}">
656+<Table x:FullColumns="1" x:FullRows="1">
657+<Column ss:AutoFitWidth="1" ss:Width="140" />
658+<Column ss:AutoFitWidth="1" ss:Width="60" />
659+<Column ss:AutoFitWidth="1" ss:Width="70" />
660+<Column ss:AutoFitWidth="1" ss:Width="80" />
661+<Column ss:AutoFitWidth="1" ss:Width="45" />
662+<Column ss:AutoFitWidth="1" ss:Width="125" />
663+<Column ss:AutoFitWidth="1" ss:Width="60" />
664+<Column ss:AutoFitWidth="1" ss:Width="80" />
665+<Column ss:AutoFitWidth="1" ss:Width="80" />
666+<Column ss:AutoFitWidth="1" ss:Width="80" />
667+<Column ss:AutoFitWidth="1" ss:Width="80" />
668+<Column ss:AutoFitWidth="1" ss:Width="80" />
669+<!-- LIST OF SELECTED FILTERS -->
670+<%
671+selected_filter = get_filter(data) or ''
672+%>
673+<Row>
674+ <Cell ss:StyleID="ssHeader"><Data ss:Type="String">${_('Chart of Account')}</Data></Cell>
675+ <Cell ss:StyleID="ssHeader"><Data ss:Type="String">${_('Fiscal Year')}</Data></Cell>
676+ <Cell ss:StyleID="ssHeader" ss:MergeAcross="1"><Data ss:Type="String">${_('Journals')}</Data></Cell>
677+ <Cell ss:StyleID="ssHeader" ss:MergeAcross="1"><Data ss:Type="String">${_('Accounts')}</Data></Cell>
678+ <Cell ss:StyleID="ssHeader" ss:MergeAcross="1"><Data ss:Type="String">${_('Proprietary Instances')}</Data></Cell>
679+ <Cell ss:StyleID="ssHeader"><Data ss:Type="String">${'%s %s' % (_('Filter By'), (selected_filter != _('No Filter') and selected_filter or ''))|x}</Data></Cell>
680+ <Cell ss:StyleID="ssHeader" ss:MergeAcross="1"><Data ss:Type="String">${_('Display')}</Data></Cell>
681+ <Cell ss:StyleID="ssHeader"><Data ss:Type="String">${_('Func. Currency')}</Data></Cell>
682+</Row>
683+<%
684+if selected_filter == _('Date'):
685+ filter = '%s - %s' % (formatLang(get_start_date(data), date=True), formatLang(get_end_date(data), date=True))
686+elif selected_filter == _('Periods'):
687+ filter = '%s - %s' % (get_start_period(data), get_end_period(data))
688+else:
689+ filter = selected_filter
690+%>
691+<Row>
692+ <Cell ss:StyleID="ssHeaderCell">
693+ <Data ss:Type="String">${ get_account(data) or ''|x}</Data>
694+ </Cell>
695+ <Cell ss:StyleID="ssHeaderCell">
696+ <Data ss:Type="String">${ get_fiscalyear(data) or ''|x}</Data>
697+ </Cell>
698+ <Cell ss:StyleID="ssHeaderCell" ss:MergeAcross="1">
699+ <Data ss:Type="String">${ get_journals_str(data)|x}</Data>
700+ </Cell>
701+ <Cell ss:StyleID="ssHeaderCell" ss:MergeAcross="1">
702+ <Data ss:Type="String">${ get_accounts_str(data)|x}</Data>
703+ </Cell>
704+ <Cell ss:StyleID="ssHeaderCell" ss:MergeAcross="1">
705+ <Data ss:Type="String">${ get_instances_str(data)|x}</Data>
706+ </Cell>
707+ <Cell ss:StyleID="ssHeaderCell">
708+ <Data ss:Type="String">${ filter|x}</Data>
709+ </Cell>
710+ <Cell ss:StyleID="ssHeaderCell" ss:MergeAcross="1">
711+ <Data ss:Type="String">${ "%s: %s, %s: %s, %s: %s, %s: %s, %s: %s, %s: %s" % (
712+ _("Employee's"), get_employees(),
713+ _('Target Moves'), get_target_move(data),
714+ _('Reconciled'), get_reconcile_selection(),
715+ _('Display Employees'), get_display_employees_selection(),
716+ _('Employee Type'), get_employee_type(data) or '-',
717+ _('Payment Method'), get_payment_methods(data) or '-',
718+ )|x}</Data>
719+ </Cell>
720+ <Cell ss:StyleID="ssHeaderCell">
721+ <Data ss:Type="String">${ company.currency_id.name |x}</Data>
722+ </Cell>
723+</Row>
724+
725+<!-- TABLE HEADER -->
726+<Row></Row>
727+<Row>
728+<Cell ss:StyleID="ssHeader">
729+ <Data ss:Type="String">${_('Employee')}</Data>
730+</Cell>
731+<Cell ss:StyleID="ssHeader">
732+ <Data ss:Type="String">${_('Date')}</Data>
733+</Cell>
734+<Cell ss:StyleID="ssHeader">
735+ <Data ss:Type="String">${_('JRNL')}</Data>
736+</Cell>
737+<Cell ss:StyleID="ssHeader">
738+ <Data ss:Type="String">${_('Entry Sequence')}</Data>
739+</Cell>
740+<Cell ss:StyleID="ssHeader">
741+ <Data ss:Type="String">${_('Account')}</Data>
742+</Cell>
743+<Cell ss:StyleID="ssHeader">
744+ <Data ss:Type="String">${_('Entry Label')}</Data>
745+</Cell>
746+<Cell ss:StyleID="ssHeader">
747+ <Data ss:Type="String">${_('Reconcile Number')}</Data>
748+</Cell>
749+<Cell ss:StyleID="ssHeader">
750+ <Data ss:Type="String">${_('Currency')}</Data>
751+</Cell>
752+<Cell ss:StyleID="ssHeaderRight">
753+ <Data ss:Type="String">${_('Debit')}</Data>
754+</Cell>
755+<Cell ss:StyleID="ssHeaderRight">
756+ <Data ss:Type="String">${_('Credit')}</Data>
757+</Cell>
758+<Cell ss:StyleID="ssHeaderRight">
759+ <Data ss:Type="String">${_('Booking Balance')}</Data>
760+</Cell>
761+<Cell ss:StyleID="ssHeaderRight">
762+ <Data ss:Type="String">${'%s %s' % (_('Balance'), company.currency_id.name)|x}</Data>
763+</Cell>
764+</Row>
765+
766+% for p in employees_to_display(objects):
767+<!-- EMPLOYEE HEADER -->
768+<Row>
769+<Cell ss:StyleID="ssEmployee">
770+ <Data ss:Type="String">${p.name_resource or ''|x}</Data>
771+</Cell>
772+<Cell ss:StyleID="ssEmployee" ss:MergeAcross="5">
773+ <Data ss:Type="String"></Data>
774+</Cell>
775+<Cell ss:StyleID="ssEmployee">
776+ <Data ss:Type="String">${company.currency_id.name|x}</Data>
777+</Cell>
778+<Cell ss:StyleID="ssEmployeeNumber">
779+ <Data ss:Type="Number">${sum_debit_employee(p) or 0.|x}</Data>
780+</Cell>
781+<Cell ss:StyleID="ssEmployeeNumber">
782+ <Data ss:Type="Number">${sum_credit_employee(p) or 0.|x}</Data>
783+</Cell>
784+<Cell ss:StyleID="ssEmployeeNumber">
785+ <Data ss:Type="Number">${(sum_debit_employee(p) or 0.) - (sum_credit_employee(p) or 0.)|x}</Data>
786+</Cell>
787+<Cell ss:StyleID="ssEmployeeNumber">
788+ <Data ss:Type="Number">${(sum_debit_employee(p) or 0.) - (sum_credit_employee(p) or 0.)|x}</Data>
789+</Cell>
790+</Row>
791+
792+% for account_code in get_accounts_to_display(p):
793+ <!-- TOTALS IN FUNCTIONAL -->
794+ <%
795+ fctal_totals = get_fctal_totals(p, account_code)
796+ %>
797+ <Row>
798+ <Cell ss:StyleID="ssSubtotalLineRight">
799+ <Data ss:Type="String">${p.name_resource or ''|x}</Data>
800+ </Cell>
801+ <Cell ss:MergeAcross="5" ss:StyleID="ssSubtotalLineRight">
802+ <Data ss:Type="String">${ account_code |x}</Data>
803+ </Cell>
804+ <Cell ss:StyleID="ssSubtotalLineLeft">
805+ <Data ss:Type="String">${ company.currency_id.name |x}</Data>
806+ </Cell>
807+ <Cell ss:StyleID="ssSubtotalLineNumber">
808+ <Data ss:Type="Number">${ fctal_totals['debit_functional'] or 0.0|x}</Data>
809+ </Cell>
810+ <Cell ss:StyleID="ssSubtotalLineNumber">
811+ <Data ss:Type="Number">${ fctal_totals['credit_functional'] or 0.0|x}</Data>
812+ </Cell>
813+ <Cell ss:StyleID="ssSubtotalLineNumber">
814+ <Data ss:Type="Number">${ fctal_totals['total_functional'] or 0.0|x}</Data>
815+ </Cell>
816+ <Cell ss:StyleID="ssSubtotalLineNumber">
817+ <Data ss:Type="Number">${ fctal_totals['total_functional'] or 0.0|x}</Data>
818+ </Cell>
819+ </Row>
820+ <!-- SUBTOTAL LINES IN BOOKING -->
821+ <%
822+ subtotals = get_subtotals(p, account_code)
823+ %>
824+ % for curr in subtotals:
825+ <Row>
826+ <Cell ss:StyleID="ssSubtotalLineRight">
827+ <Data ss:Type="String">${p.name_resource or ''|x}</Data>
828+ </Cell>
829+ <Cell ss:MergeAcross="5" ss:StyleID="ssSubtotalLineRight">
830+ <Data ss:Type="String">${ _('Subtotal') |x}</Data>
831+ </Cell>
832+ <Cell ss:StyleID="ssSubtotalLineLeft">
833+ <Data ss:Type="String">${ curr or '' |x}</Data>
834+ </Cell>
835+ <Cell ss:StyleID="ssSubtotalLineNumber">
836+ <Data ss:Type="Number">${ subtotals[curr]['debit'] or 0.0|x}</Data>
837+ </Cell>
838+ <Cell ss:StyleID="ssSubtotalLineNumber">
839+ <Data ss:Type="Number">${ subtotals[curr]['credit'] or 0.0|x}</Data>
840+ </Cell>
841+ <Cell ss:StyleID="ssSubtotalLineNumber">
842+ <Data ss:Type="Number">${ subtotals[curr]['amount_currency'] or 0.0|x}</Data>
843+ </Cell>
844+ <Cell ss:StyleID="ssSubtotalLineNumber">
845+ <Data ss:Type="Number">${ subtotals[curr]['total_functional'] or 0.0|x}</Data>
846+ </Cell>
847+ </Row>
848+ % endfor
849+ <!-- EMPLOYEE LINES -->
850+ % for line in lines(p, account_code):
851+ <Row>
852+ <Cell ss:StyleID="ssAccountLine">
853+ <Data ss:Type="String"></Data>
854+ </Cell>
855+ <Cell ss:StyleID="ssAccountLine">
856+ <Data ss:Type="String">${formatLang(line['date'], date=True)|x}</Data>
857+ </Cell>
858+ <Cell ss:StyleID="ssAccountLine">
859+ <Data ss:Type="String">${line['code']|x}</Data>
860+ </Cell>
861+ <Cell ss:StyleID="ssAccountLine">
862+ <Data ss:Type="String">${line['move_name']|x}</Data>
863+ </Cell>
864+ <Cell ss:StyleID="ssAccountLine">
865+ <Data ss:Type="String">${line['a_code']|x}</Data>
866+ </Cell>
867+ <%
868+ entry_label = '%s - %s' % (line['ref'] or '', line['name'] or '')
869+ %>
870+ <Cell ss:StyleID="ssAccountLine">
871+ <Data ss:Type="String">${ entry_label |x}</Data>
872+ </Cell>
873+ <Cell ss:StyleID="ssAccountLine">
874+ <Data ss:Type="String">${ line['reconcile_txt'] or '' |x}</Data>
875+ </Cell>
876+ <Cell ss:StyleID="ssAccountLine">
877+ <Data ss:Type="String">${ line['currency_code'] or '' |x}</Data>
878+ </Cell>
879+ <Cell ss:StyleID="ssAccountLineNumber">
880+ <Data ss:Type="Number">${ line['debit'] or 0.0|x}</Data>
881+ </Cell>
882+ <Cell ss:StyleID="ssAccountLineNumber">
883+ <Data ss:Type="Number">${ line['credit'] or 0.0|x}</Data>
884+ </Cell>
885+ <Cell ss:StyleID="ssAccountLineNumber">
886+ <Data ss:Type="Number">${ line['amount_currency'] or 0.0|x}</Data>
887+ </Cell>
888+ <Cell ss:StyleID="ssAccountLineNumber">
889+ <Data ss:Type="Number">${ line['total_functional'] or 0.0|x}</Data>
890+ </Cell>
891+ </Row>
892+ % endfor
893+% endfor
894+% endfor
895+
896+</Table>
897+<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
898+ <FitToPage/>
899+ <PageSetup>
900+ <Layout x:Orientation="Landscape"/>
901+ <Header x:Data="&amp;C&amp;&quot;Arial,Bold&quot;&amp;14Employee Ledger"/>
902+ <Footer x:Data="Page &amp;P of &amp;N"/>
903+ </PageSetup>
904+ <Print>
905+ <ValidPrinterInfo/>
906+ <PaperSizeIndex>9</PaperSizeIndex>
907+ <HorizontalResolution>600</HorizontalResolution>
908+ <VerticalResolution>600</VerticalResolution>
909+ </Print>
910+ <Selected/>
911+ <Panes>
912+ <Pane>
913+ <Number>3</Number>
914+ <ActiveRow>17</ActiveRow>
915+ </Pane>
916+ </Panes>
917+ <ProtectObjects>False</ProtectObjects>
918+ <ProtectScenarios>False</ProtectScenarios>
919+</WorksheetOptions>
920+</Worksheet>
921+</Workbook>
922
923=== added file 'bin/addons/account/report/account_employee_ledger.py'
924--- bin/addons/account/report/account_employee_ledger.py 1970-01-01 00:00:00 +0000
925+++ bin/addons/account/report/account_employee_ledger.py 2022-06-01 15:15:45 +0000
926@@ -0,0 +1,558 @@
927+# -*- coding: utf-8 -*-
928+##############################################################################
929+#
930+# OpenERP, Open Source Management Solution
931+# Copyright (C) 2022 TeMPO Consulting, MSF. All Rights Reserved
932+#
933+# This program is free software: you can redistribute it and/or modify
934+# it under the terms of the GNU Affero General Public License as
935+# published by the Free Software Foundation, either version 3 of the
936+# License, or (at your option) any later version.
937+#
938+# This program is distributed in the hope that it will be useful,
939+# but WITHOUT ANY WARRANTY; without even the implied warranty of
940+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
941+# GNU Affero General Public License for more details.
942+#
943+# You should have received a copy of the GNU Affero General Public License
944+# along with this program. If not, see <http://www.gnu.org/licenses/>.
945+#
946+##############################################################################
947+
948+import time
949+import re
950+from report import report_sxw
951+from common_report_header import common_report_header
952+import pooler
953+from spreadsheet_xml.spreadsheet_xml_write import SpreadsheetReport
954+from tools.translate import _
955+
956+
957+class employee_ledger(report_sxw.rml_parse, common_report_header):
958+
959+ def __init__(self, cr, uid, name, context=None):
960+ super(employee_ledger, self).__init__(cr, uid, name, context=context)
961+ self.fctal_totals = {} # to store the totals in functional currency
962+ self.subtotals = {} # to store the subtotals per booking currency
963+ self.accounts_to_display = {}
964+ self.report_lines = {}
965+ self.debit_balances = {}
966+ self.credit_balances = {}
967+ self.current_employee_number = 0
968+ self.localcontext.update({
969+ 'employees_to_display': self._employees_to_display,
970+ 'time': time,
971+ 'lines': self.lines,
972+ 'sum_debit_employee': self._sum_debit_employee,
973+ 'sum_credit_employee': self._sum_credit_employee,
974+ 'get_currency': self._get_currency,
975+ 'comma_me': self.comma_me,
976+ 'get_start_period': self.get_start_period,
977+ 'get_end_period': self.get_end_period,
978+ 'get_account': self._get_account,
979+ 'get_filter': self._get_filter,
980+ 'get_start_date': self._get_start_date,
981+ 'get_end_date': self._get_end_date,
982+ 'get_fiscalyear': self._get_fiscalyear,
983+ 'get_journals_str': self._get_journals_str,
984+ 'get_employees':self._get_employees,
985+ 'get_target_move': self._get_target_move,
986+ 'get_reconcile_selection': self._get_reconcile_selection,
987+ 'get_display_employees_selection': self._get_display_employees_selection,
988+ 'get_instances_str': self._get_instances_str,
989+ 'get_accounts_str': self._get_accounts_str,
990+ 'format_entry_label': self._format_entry_label,
991+ 'get_accounts_to_display': self._get_accounts_to_display,
992+ 'get_fctal_totals': self._get_fctal_totals,
993+ 'get_subtotals': self._get_subtotals,
994+ 'nb_employees': lambda employees: len(self._employees_to_display(employees)),
995+ 'update_current_employee_number': self._update_current_employee_number,
996+ 'get_current_employee_number': lambda: self.current_employee_number,
997+ 'get_employee_type': self._get_employee_type,
998+ 'get_payment_methods': self._get_payment_methods,
999+ })
1000+
1001+ def _get_employee_type(self, data):
1002+ """
1003+ Returns the String to display in the "Employee Type" section of the report header
1004+ """
1005+ emp_type = _('All')
1006+ # if specific employees are selected don't display emp type
1007+ if data['form'].get('employee_ids', False):
1008+ emp_type = '-'
1009+ else:
1010+ emp = data['form'].get('employee_type', False)
1011+ if emp == 'local':
1012+ emp_type = _('Local Staff')
1013+ if emp == 'ex':
1014+ emp_type = _('Expatriate Staff')
1015+ return emp_type
1016+
1017+ def _get_payment_methods(self, data):
1018+ """
1019+ Returns the String to display in the "Payment Method" section of the report header
1020+ """
1021+ pay_method = _('All')
1022+ # if specific employees are selected don't display payment method
1023+ if data['form'].get('employee_ids', False):
1024+ pay_method = '-'
1025+ else:
1026+ method = data['form'].get('payment_method')
1027+ if method != 'blank':
1028+ return method
1029+ return pay_method
1030+
1031+ def set_context(self, objects, data, ids, report_type=None):
1032+ obj_move = self.pool.get('account.move.line')
1033+ obj_employee = self.pool.get('hr.employee')
1034+ obj_fy = self.pool.get('account.fiscalyear')
1035+ used_context = data['form'].get('used_context', {})
1036+ self.reconciled = data['form'].get('reconciled', False)
1037+ self.result_selection = data['form'].get('result_selection', 'customer_supplier')
1038+ self.target_move = data['form'].get('target_move', 'all')
1039+ self.period_id = data['form'].get('period_from', False)
1040+ self.date_from = data['form'].get('date_from', False)
1041+ self.instance_ids = data['form'].get('instance_ids', False)
1042+ self.account_ids = data['form'].get('account_ids', False)
1043+ self.display_employee = data['form'].get('display_employee', '')
1044+ self.fiscalyear_id = data['form'].get('fiscalyear_id', False)
1045+ self.employee_type = data['form'].get('employee_type', '')
1046+ self.payment_method = data['form'].get('payment_method', '')
1047+ if self.fiscalyear_id:
1048+ fy = obj_fy.read(self.cr, self.uid, [self.fiscalyear_id], ['date_start'], context=used_context)
1049+ else:
1050+ # by default all FY taken into account
1051+ used_context.update({'all_fiscalyear': True})
1052+ self.query = obj_move._query_get(self.cr, self.uid, obj='l', context=used_context)
1053+
1054+ #+ To have right employee balance, we have to take all next lines after a specific date.
1055+ #+ To do that, we need to make requests regarding a date. So first we take date_from
1056+ #+ then period_from (if no date_from)
1057+ #+ finally fisalyear_id (if no period)
1058+ #+ If no date, the report is wrong.
1059+ pool = pooler.get_pool(self.cr.dbname)
1060+ self.DATE_FROM = ''
1061+ if self.fiscalyear_id or self.period_id or self.date_from:
1062+ if self.date_from:
1063+ self.DATE_FROM = "AND l.date >= '%s'" % self.date_from
1064+ elif self.period_id:
1065+ period_obj = pool.get('account.period')
1066+ period = period_obj.read(self.cr, self.uid, [self.period_id], ['date_start'])
1067+ self.DATE_FROM = "AND l.date >= '%s'" % period[0].get('date_start')
1068+ elif self.fiscalyear_id:
1069+ self.DATE_FROM = "AND l.date >= '%s'" % fy[0].get('date_start')
1070+
1071+
1072+ # Create the part of the request concerning instances
1073+ if not self.instance_ids:
1074+ # select all instances by default
1075+ self.instance_ids = self.pool.get('msf.instance').search(self.cr, self.uid, [], order='NO_ORDER')
1076+ if len(self.instance_ids) == 1:
1077+ self.INSTANCE_REQUEST = "AND l.instance_id = %s" % self.instance_ids[0]
1078+ else:
1079+ self.INSTANCE_REQUEST = "AND l.instance_id IN %s" % (tuple(self.instance_ids),)
1080+
1081+ if self.result_selection == 'supplier':
1082+ self.ACCOUNT_TYPE = ['payable']
1083+ elif self.result_selection == 'customer':
1084+ self.ACCOUNT_TYPE = ['receivable']
1085+ else:
1086+ self.ACCOUNT_TYPE = ['payable','receivable']
1087+
1088+ # get the account list (if some accounts have been specifically selected use them directly)
1089+ if not self.account_ids:
1090+ self.cr.execute(
1091+ "SELECT a.id "
1092+ "FROM account_account a "
1093+ "LEFT JOIN account_account_type t "
1094+ "ON (a.user_type=t.id) "
1095+ 'WHERE a.type IN %s'
1096+ " " + "AND a.active", (tuple(self.ACCOUNT_TYPE), ))
1097+ self.account_ids = [a for (a,) in self.cr.fetchall()]
1098+ if data['form'].get('employee_ids', False):
1099+ new_ids = data['form']['employee_ids'] # some employees are specifically selected
1100+ else:
1101+ employee_to_use = []
1102+ pay_method_request = ''
1103+ emp_request = ''
1104+ active_selection = "IN ('t','f')"
1105+ # check if we should display all employees or only active ones
1106+ if data['form'].get('only_active_employees'):
1107+ active_selection = "= 't'"
1108+ # check if we should include only a selected type of employees
1109+ emp_type = data['form'].get('employee_type', '')
1110+ if emp_type != '':
1111+ emp_request += "AND emp.employee_type = '%s' " % emp_type.encode("utf-8")
1112+ # check if we should include only employees using a selected method of payment
1113+ pay_method = data['form'].get('payment_method')
1114+ if pay_method != 'blank':
1115+ emp_request += "AND pay.name = '%s' " % pay_method.encode("utf-8")
1116+ # do join with payment_method only when local staff is selected because exp staff don't always have payment method registered
1117+ if emp_type == 'local':
1118+ pay_method_request = "JOIN hr_payment_method pay ON (emp.payment_method_id = pay.id) "
1119+ emp_query = """SELECT emp.id as employee_id, emp.name_resource
1120+ FROM hr_employee emp
1121+ INNER JOIN resource_resource res ON emp.resource_id = res.id %s
1122+ WHERE res.active %s %s
1123+ ORDER BY emp.name_resource;""" % (pay_method_request, active_selection, emp_request,)
1124+ self.cr.execute(emp_query)
1125+ res = self.cr.dictfetchall()
1126+ for res_line in res:
1127+ employee_to_use.append(res_line['employee_id'])
1128+ new_ids = employee_to_use
1129+ self.employee_ids = new_ids
1130+ objects = obj_employee.browse(self.cr, self.uid, new_ids)
1131+ res = super(employee_ledger, self).set_context(objects, data, new_ids, report_type)
1132+ common_report_header._set_context(self, data)
1133+ if data['model'] == 'ir.ui.menu':
1134+ # US-324: use of user LG instead of each employee in the report
1135+ lang_dict = self.pool.get('res.users').read(self.cr,self.uid,self.uid,['context_lang'])
1136+ data['lang'] = lang_dict.get('context_lang') or False
1137+
1138+ return res
1139+
1140+ def comma_me(self, amount):
1141+ if type(amount) is float:
1142+ amount = str('%.2f'%amount)
1143+ else:
1144+ amount = str(amount)
1145+ if (amount == '0'):
1146+ return ' '
1147+ orig = amount
1148+ new = re.sub("^(-?\d+)(\d{3})", "\g<1>'\g<2>", amount)
1149+ if orig == new:
1150+ return new
1151+ else:
1152+ return self.comma_me(new)
1153+
1154+ def _format_entry_label(self, label, index):
1155+ """
1156+ Formats the entry label:
1157+ adds a line break every (index) character
1158+ """
1159+ x = 0
1160+ parts = []
1161+ while x < len(label):
1162+ parts.append(label[x:x+index])
1163+ x += index
1164+ return "\n".join(parts)
1165+
1166+ def _get_accounts_to_display(self, employee):
1167+ """
1168+ Returns the list of account codes to be displayed for the employee in parameter
1169+ """
1170+ if self.accounts_to_display:
1171+ return self.accounts_to_display.get(employee.id, [])
1172+ move_state = ['draft', 'posted']
1173+ if self.target_move == 'posted':
1174+ move_state = ['posted']
1175+ if self.reconciled == 'yes':
1176+ reconcile_tag = "AND l.reconcile_id IS NOT NULL"
1177+ elif self.reconciled == 'no':
1178+ reconcile_tag = "AND l.reconcile_id IS NULL AND acc.reconcile='t'" # reconcilable entries not reconciled
1179+ else: # 'empty'
1180+ reconcile_tag = " "
1181+ self.cr.execute(
1182+ "SELECT l.employee_id, acc.code "
1183+ "FROM account_move_line l "
1184+ "LEFT JOIN account_journal j ON l.journal_id = j.id "
1185+ "LEFT JOIN account_account acc ON l.account_id = acc.id "
1186+ "LEFT JOIN res_currency c ON l.currency_id = c.id "
1187+ "LEFT JOIN account_move m ON m.id = l.move_id "
1188+ "WHERE "
1189+ " l.account_id IN %s AND " + self.query + " "
1190+ "AND m.state IN %s "
1191+ " " + reconcile_tag + " "
1192+ " " + self.DATE_FROM + " "
1193+ " " + self.INSTANCE_REQUEST + " "
1194+ "GROUP BY l.employee_id, acc.code ORDER BY acc.code;",
1195+ (tuple(self.account_ids), tuple(move_state)))
1196+ for x in self.cr.fetchall():
1197+ self.accounts_to_display.setdefault(x[0], []).append(x[1])
1198+ return self.accounts_to_display.get(employee.id, [])
1199+
1200+ def lines(self, employee, account_code):
1201+ if employee.id in self.report_lines and account_code in self.report_lines[employee.id]:
1202+ return self.report_lines[employee.id][account_code]
1203+ move_state = ['draft','posted']
1204+ if self.target_move == 'posted':
1205+ move_state = ['posted']
1206+
1207+ if self.reconciled == 'yes':
1208+ RECONCILE_TAG = "AND l.reconcile_id IS NOT NULL"
1209+ elif self.reconciled == 'no':
1210+ RECONCILE_TAG = "AND l.reconcile_id IS NULL AND acc.reconcile='t'" # reconcilable entries not reconciled
1211+ else: # 'empty'
1212+ RECONCILE_TAG = " "
1213+ self.cr.execute(
1214+ "SELECT l.id, l.date, j.code, acc.code as a_code, acc.name as a_name, l.ref, m.name as move_name, l.name, "
1215+ "COALESCE(l.debit_currency, 0) as debit, COALESCE(l.credit_currency, 0) as credit, "
1216+ "COALESCE(l.debit, 0) AS debit_functional, COALESCE(l.credit, 0) AS credit_functional, "
1217+ "l.debit - l.credit as total_functional, l.amount_currency, l.currency_id, c.name AS currency_code, "
1218+ "l.reconcile_txt "
1219+ "FROM account_move_line l " \
1220+ "LEFT JOIN account_journal j " \
1221+ "ON (l.journal_id = j.id) " \
1222+ "LEFT JOIN account_account acc " \
1223+ "ON (l.account_id = acc.id) " \
1224+ "LEFT JOIN res_currency c ON (l.currency_id=c.id)" \
1225+ "LEFT JOIN account_move m ON (m.id=l.move_id)" \
1226+ "WHERE l.employee_id = %s " \
1227+ "AND l.account_id = (SELECT id FROM account_account WHERE code = %s LIMIT 1) "
1228+ "AND " + self.query + " " \
1229+ "AND m.state IN %s " \
1230+ " " + RECONCILE_TAG + " "\
1231+ " " + self.DATE_FROM + " "\
1232+ " " + self.INSTANCE_REQUEST + " "
1233+ "ORDER BY l.date;",
1234+ (employee.id, account_code, tuple(move_state)))
1235+ if employee.id not in self.report_lines:
1236+ self.report_lines[employee.id] = {}
1237+ self.report_lines[employee.id][account_code] = self.cr.dictfetchall()
1238+ # initialize totals in functional currency
1239+ if employee.id not in self.fctal_totals:
1240+ self.fctal_totals[employee.id] = {}
1241+ if account_code not in self.fctal_totals[employee.id]:
1242+ self.fctal_totals[employee.id][account_code] = {
1243+ 'debit_functional': 0.0,
1244+ 'credit_functional': 0.0,
1245+ 'total_functional': 0.0,
1246+ }
1247+ # initialize subtotals in booking currency
1248+ if employee.id not in self.subtotals:
1249+ self.subtotals[employee.id] = {}
1250+ if account_code not in self.subtotals[employee.id]:
1251+ self.subtotals[employee.id][account_code] = {}
1252+ # fill in fctal_totals/subtotals
1253+ for line in self.report_lines[employee.id][account_code]:
1254+ self.fctal_totals[employee.id][account_code]['debit_functional'] += line['debit_functional'] or 0.0
1255+ self.fctal_totals[employee.id][account_code]['credit_functional'] += line['credit_functional'] or 0.0
1256+ self.fctal_totals[employee.id][account_code]['total_functional'] += line['total_functional'] or 0.0
1257+ if line['currency_code'] not in self.subtotals[employee.id][account_code]:
1258+ self.subtotals[employee.id][account_code][line['currency_code']] = {
1259+ 'debit': 0.0,
1260+ 'credit': 0.0,
1261+ 'amount_currency': 0.0,
1262+ 'total_functional': 0.0,
1263+ }
1264+ self.subtotals[employee.id][account_code][line['currency_code']]['debit'] += line['debit'] or 0.0
1265+ self.subtotals[employee.id][account_code][line['currency_code']]['credit'] += line['credit'] or 0.0
1266+ self.subtotals[employee.id][account_code][line['currency_code']]['amount_currency'] += line['amount_currency'] or 0.0
1267+ self.subtotals[employee.id][account_code][line['currency_code']]['total_functional'] += line['total_functional'] or 0.0
1268+ return self.report_lines[employee.id][account_code]
1269+
1270+ def _get_subtotals(self, employee, account_code):
1271+ """
1272+ Returns a dictionary with key = currency code, and value = dict. of the subtotals values for the
1273+ employee/account_code, i.e. {'credit': xxx, 'debit': xxx, 'amount_currency': xxx, 'total_functional': xxx}
1274+ """
1275+ if employee.id not in self.subtotals or account_code not in self.subtotals[employee.id]:
1276+ self.lines(employee, account_code) # fills in the self.subtotals dictionary
1277+ return self.subtotals[employee.id][account_code]
1278+
1279+ def _get_fctal_totals(self, employee, account_code):
1280+ """
1281+ Returns a dictionary with the total values in functional currency for the employee/code in param:
1282+ {'credit_functional': xxx, 'debit_functional': xxx, 'total_functional': xxx}
1283+ """
1284+ if employee.id not in self.fctal_totals or account_code not in self.fctal_totals[employee.id]:
1285+ self.lines(employee, account_code) # fills in the self.fctal_totals dictionary
1286+ return self.fctal_totals[employee.id][account_code]
1287+
1288+ def _update_current_employee_number(self):
1289+ """
1290+ Increments the current employee number and always returns True (used for the display in rml template)
1291+ """
1292+ self.current_employee_number += 1
1293+ return True
1294+
1295+ def _sum_debit_employee(self, employee):
1296+ if employee.id in self.debit_balances:
1297+ # compute the result only once per employee
1298+ return self.debit_balances[employee.id]
1299+ move_state = ['draft','posted']
1300+ if self.target_move == 'posted':
1301+ move_state = ['posted']
1302+
1303+ result_tmp = 0.0
1304+ if self.reconciled == 'yes':
1305+ RECONCILE_TAG = "AND l.reconcile_id IS NOT NULL"
1306+ elif self.reconciled == 'no':
1307+ RECONCILE_TAG = "AND l.reconcile_id IS NULL AND acc.reconcile='t'" # reconcilable entries not reconciled
1308+ else: # 'empty'
1309+ RECONCILE_TAG = " "
1310+
1311+ self.cr.execute(
1312+ "SELECT sum(debit) " \
1313+ "FROM account_move_line AS l, " \
1314+ "account_move AS m, "
1315+ "account_account AS acc "
1316+ "WHERE l.employee_id = %s " \
1317+ "AND m.id = l.move_id " \
1318+ "AND l.account_id = acc.id "
1319+ "AND m.state IN %s "
1320+ "AND account_id IN %s" \
1321+ " " + RECONCILE_TAG + " " \
1322+ " " + self.DATE_FROM + " " \
1323+ " " + self.INSTANCE_REQUEST + " "
1324+ "AND " + self.query + " ",
1325+ (employee.id, tuple(move_state), tuple(self.account_ids),))
1326+
1327+ contemp = self.cr.fetchone()
1328+ if contemp != None:
1329+ result_tmp = contemp[0] or 0.0
1330+ else:
1331+ result_tmp = result_tmp + 0.0
1332+ self.debit_balances[employee.id] = result_tmp
1333+ return result_tmp
1334+
1335+ def _sum_credit_employee(self, employee):
1336+ if employee.id in self.credit_balances:
1337+ # compute the result only once per employee
1338+ return self.credit_balances[employee.id]
1339+ move_state = ['draft','posted']
1340+ if self.target_move == 'posted':
1341+ move_state = ['posted']
1342+
1343+ result_tmp = 0.0
1344+ if self.reconciled == 'yes':
1345+ RECONCILE_TAG = "AND l.reconcile_id IS NOT NULL"
1346+ elif self.reconciled == 'no':
1347+ RECONCILE_TAG = "AND l.reconcile_id IS NULL AND acc.reconcile='t'" # reconcilable entries not reconciled
1348+ else: # 'empty'
1349+ RECONCILE_TAG = " "
1350+
1351+ self.cr.execute(
1352+ "SELECT sum(credit) " \
1353+ "FROM account_move_line AS l, " \
1354+ "account_move AS m, "
1355+ "account_account AS acc "
1356+ "WHERE l.employee_id=%s " \
1357+ "AND m.id = l.move_id " \
1358+ "AND l.account_id = acc.id "
1359+ "AND m.state IN %s "
1360+ "AND account_id IN %s" \
1361+ " " + RECONCILE_TAG + " " \
1362+ " " + self.DATE_FROM + " " \
1363+ " " + self.INSTANCE_REQUEST + " "\
1364+ "AND " + self.query + " ",
1365+ (employee.id, tuple(move_state), tuple(self.account_ids),))
1366+
1367+ contemp = self.cr.fetchone()
1368+ if contemp != None:
1369+ result_tmp = contemp[0] or 0.0
1370+ else:
1371+ result_tmp = result_tmp + 0.0
1372+ self.credit_balances[employee.id] = result_tmp
1373+ return result_tmp
1374+
1375+ def _employees_to_display(self, employees):
1376+ """
1377+ Returns the employees to be displayed in the report as a list of hr.employee browse records
1378+ """
1379+ to_display = employees
1380+ if self.display_employee == 'non-zero_balance':
1381+ for p in employees:
1382+ # fill in the dictionaries self.debit_balances and self.credit_balances
1383+ self._sum_debit_employee(p)
1384+ self._sum_credit_employee(p)
1385+ to_display = [p for p in employees if abs(self.debit_balances[p.id] - self.credit_balances[p.id]) > 10**-3]
1386+ elif self.display_employee == 'with_movements':
1387+ for p in employees:
1388+ for account_code in self._get_accounts_to_display(p):
1389+ # fill in the dictionary self.report_lines
1390+ self.lines(p, account_code)
1391+ to_display = [p for p in employees if p.id in self.report_lines and self.report_lines[p.id]]
1392+ return to_display
1393+
1394+ def _get_employees(self):
1395+ if self.result_selection == 'customer':
1396+ return _('Receivable Accounts')
1397+ elif self.result_selection == 'supplier':
1398+ return _('Payable Accounts')
1399+ elif self.result_selection == 'customer_supplier':
1400+ return _('Receivable and Payable Accounts')
1401+ return ''
1402+
1403+ def _get_reconcile_selection(self):
1404+ """
1405+ Returns "Yes" if "Reconciled: Yes" is selected in the wizard
1406+ """
1407+ selection = _('All')
1408+ if self.reconciled == 'yes':
1409+ selection = _('Yes')
1410+ elif self.reconciled == 'no':
1411+ selection = _('No')
1412+ return selection
1413+
1414+ def _get_display_employees_selection(self):
1415+ """
1416+ Returns the String to display in the "Display Employees" section of the report header
1417+ """
1418+ selection = '-'
1419+ if self.display_employee == 'all':
1420+ selection = _('All Employees')
1421+ elif self.display_employee == 'with_movements':
1422+ selection = _('With movements')
1423+ elif self.display_employee == 'non-zero_balance':
1424+ selection = _('With balance is not equal to 0')
1425+ return selection
1426+
1427+ def _sum_currency_amount_account(self, account, form):
1428+ self._set_get_account_currency_code(account.id)
1429+ self.cr.execute("SELECT sum(aml.amount_currency) FROM account_move_line as aml,res_currency as rc WHERE aml.currency_id = rc.id AND aml.account_id= %s ", (account.id,))
1430+ total = self.cr.fetchone()
1431+ if self.account_currency:
1432+ return_field = str(total[0]) + self.account_currency
1433+ return return_field
1434+ else:
1435+ currency_total = self.tot_currency = 0.0
1436+ return currency_total
1437+
1438+ def _get_journal(self, data, instance_ids=False):
1439+ """
1440+ If all journals have been selected: display "All Journals" instead of listing all of them
1441+ """
1442+ journal_ids = data.get('form', False) and data['form'].get('journal_ids', False)
1443+ if journal_ids:
1444+ journal_obj = pooler.get_pool(self.cr.dbname).get('account.journal')
1445+ nb_journals = journal_obj.search(self.cr, self.uid, [], order='NO_ORDER', count=True, context=data.get('context', {}))
1446+ if len(journal_ids) == nb_journals:
1447+ return [_('All Journals')]
1448+ instance_ids = instance_ids or data.get('form', False) and data['form'].get('instance_ids', False)
1449+ journal_list = super(employee_ledger, self)._get_journal(data, instance_ids)
1450+ return set(journal_list) # exclude duplications
1451+
1452+ def _get_journals_str(self, data):
1453+ """
1454+ Returns the list of journals as a String (cut if > 300 characters)
1455+ """
1456+ data_tools_obj = self.pool.get('data.tools')
1457+ return data_tools_obj.truncate_list(self._get_journal(data))
1458+
1459+ def _get_instances_str(self, data):
1460+ """
1461+ Returns the list of instances as a String (cut if > 300 characters)
1462+ """
1463+ data_tools_obj = self.pool.get('data.tools')
1464+ return data_tools_obj.truncate_list(self._get_instances_from_data(data))
1465+
1466+ def _get_accounts_str(self, data):
1467+ """
1468+ Returns the list of accounts as a String (cut if > 300 characters)
1469+ """
1470+ data_tools_obj = self.pool.get('data.tools')
1471+ return data_tools_obj.truncate_list(self._get_accounts(data))
1472+
1473+# PDF report with one employee per page
1474+report_sxw.report_sxw('report.account.employee_ledger', 'hr.employee',
1475+ 'addons/account/report/account_employee_ledger.rml',parser=employee_ledger,
1476+ header='internal landscape')
1477+# PDF report with employees displayed one after another
1478+report_sxw.report_sxw('report.account.employee_ledger_other', 'hr.employee',
1479+ 'addons/account/report/account_employee_ledger_other.rml',parser=employee_ledger,
1480+ header='internal landscape')
1481+# XLS report
1482+SpreadsheetReport('report.account.employee_ledger_xls', 'hr.employee',
1483+ 'addons/account/report/account_employee_ledger.mako', parser=employee_ledger)
1484+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
1485\ No newline at end of file
1486
1487=== added file 'bin/addons/account/report/account_employee_ledger.rml'
1488--- bin/addons/account/report/account_employee_ledger.rml 1970-01-01 00:00:00 +0000
1489+++ bin/addons/account/report/account_employee_ledger.rml 2022-06-01 15:15:45 +0000
1490@@ -0,0 +1,777 @@
1491+<?xml version="1.0"?>
1492+<document filename="Employee Ledger.pdf">
1493+ <template pageSize="(842.0,595.0)" title="Employee Ledger" author="Tempo Consulting" allowSplitting="20">
1494+ <pageTemplate id="first">
1495+ <frame id="first" x1="28.0" y1="57.0" width="772" height="481"/>
1496+ </pageTemplate>
1497+ </template>
1498+ <stylesheet>
1499+ <blockTableStyle id="Standard_Outline">
1500+ <blockAlignment value="LEFT"/>
1501+ <blockValign value="TOP"/>
1502+ </blockTableStyle>
1503+ <blockTableStyle id="Table1">
1504+ <blockAlignment value="LEFT"/>
1505+ <blockValign value="TOP"/>
1506+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="0,0" stop="0,-1"/>
1507+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="0,0" stop="0,0"/>
1508+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="0,-1" stop="0,-1"/>
1509+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="1,0" stop="1,-1"/>
1510+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="1,0" stop="1,0"/>
1511+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="1,-1" stop="1,-1"/>
1512+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="2,0" stop="2,-1"/>
1513+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="2,0" stop="2,0"/>
1514+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="2,-1" stop="2,-1"/>
1515+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="3,0" stop="3,-1"/>
1516+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="3,0" stop="3,0"/>
1517+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="3,-1" stop="3,-1"/>
1518+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="4,0" stop="4,-1"/>
1519+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="4,0" stop="4,0"/>
1520+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="4,-1" stop="4,-1"/>
1521+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="5,0" stop="5,-1"/>
1522+ <lineStyle kind="LINEAFTER" colorName="#e6e6e6" start="5,0" stop="5,-1"/>
1523+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="5,0" stop="5,0"/>
1524+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="5,-1" stop="5,-1"/>
1525+ <lineStyle kind="LINEAFTER" colorName="#e6e6e6" start="6,0" stop="6,-1"/>
1526+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="6,0" stop="6,0"/>
1527+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="7,0" stop="7,0"/>
1528+ <lineStyle kind="LINEAFTER" colorName="#e6e6e6" start="7,0" stop="7,-1"/>
1529+ </blockTableStyle>
1530+ <blockTableStyle id="Table4">
1531+ <blockAlignment value="LEFT"/>
1532+ <blockValign value="TOP"/>
1533+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="0,0" stop="0,-1"/>
1534+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="0,0" stop="0,0"/>
1535+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="0,-1" stop="0,-1"/>
1536+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="1,0" stop="1,-1"/>
1537+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="1,0" stop="1,0"/>
1538+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="1,-1" stop="1,-1"/>
1539+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="2,0" stop="2,-1"/>
1540+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="2,0" stop="2,0"/>
1541+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="2,-1" stop="2,-1"/>
1542+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="3,0" stop="3,-1"/>
1543+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="3,0" stop="3,0"/>
1544+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="3,-1" stop="3,-1"/>
1545+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="4,0" stop="4,-1"/>
1546+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="4,0" stop="4,0"/>
1547+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="4,-1" stop="4,-1"/>
1548+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="5,0" stop="5,-1"/>
1549+ <lineStyle kind="LINEAFTER" colorName="#e6e6e6" start="5,0" stop="5,-1"/>
1550+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="5,0" stop="5,0"/>
1551+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="5,-1" stop="5,-1"/>
1552+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="6,0" stop="6,-1"/>
1553+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="6,0" stop="6,0"/>
1554+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="6,-1" stop="6,-1"/>
1555+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="7,0" stop="7,-1"/>
1556+ <lineStyle kind="LINEAFTER" colorName="#e6e6e6" start="7,0" stop="7,-1"/>
1557+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="7,0" stop="7,0"/>
1558+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="7,-1" stop="7,-1"/>
1559+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="8,0" stop="8,-1"/>
1560+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="8,0" stop="8,0"/>
1561+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="8,-1" stop="8,-1"/>
1562+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="9,0" stop="9,-1"/>
1563+ <lineStyle kind="LINEAFTER" colorName="#e6e6e6" start="9,0" stop="9,-1"/>
1564+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="9,0" stop="9,0"/>
1565+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="9,-1" stop="9,-1"/>
1566+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="10,0" stop="10,-1"/>
1567+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="10,0" stop="10,0"/>
1568+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="10,-1" stop="10,-1"/>
1569+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="11,0" stop="11,-1"/>
1570+ <lineStyle kind="LINEAFTER" colorName="#e6e6e6" start="11,0" stop="11,-1"/>
1571+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="11,0" stop="11,0"/>
1572+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="11,-1" stop="11,-1"/>
1573+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="12,0" stop="12,-1"/>
1574+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="12,0" stop="12,0"/>
1575+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="12,-1" stop="12,-1"/>
1576+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="13,0" stop="13,-1"/>
1577+ <lineStyle kind="LINEAFTER" colorName="#e6e6e6" start="13,0" stop="13,-1"/>
1578+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="13,0" stop="13,0"/>
1579+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="13,-1" stop="13,-1"/>
1580+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="0,1" stop="0,-1"/>
1581+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="0,1" stop="0,1"/>
1582+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="0,-1" stop="0,-1"/>
1583+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="1,1" stop="1,-1"/>
1584+ <lineStyle kind="LINEAFTER" colorName="#e6e6e6" start="1,1" stop="1,-1"/>
1585+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="1,1" stop="1,1"/>
1586+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="1,-1" stop="1,-1"/>
1587+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="0,2" stop="0,-1"/>
1588+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="0,2" stop="0,2"/>
1589+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="0,-1" stop="0,-1"/>
1590+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="1,2" stop="1,-1"/>
1591+ <lineStyle kind="LINEAFTER" colorName="#e6e6e6" start="1,2" stop="1,-1"/>
1592+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="1,2" stop="1,2"/>
1593+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="1,-1" stop="1,-1"/>
1594+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="0,3" stop="0,-1"/>
1595+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="0,3" stop="0,3"/>
1596+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="0,-1" stop="0,-1"/>
1597+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="1,3" stop="1,-1"/>
1598+ <lineStyle kind="LINEAFTER" colorName="#e6e6e6" start="1,3" stop="1,-1"/>
1599+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="1,3" stop="1,3"/>
1600+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="1,-1" stop="1,-1"/>
1601+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="0,4" stop="0,-1"/>
1602+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="0,4" stop="0,4"/>
1603+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="0,-1" stop="0,-1"/>
1604+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="1,4" stop="1,-1"/>
1605+ <lineStyle kind="LINEAFTER" colorName="#e6e6e6" start="1,4" stop="1,-1"/>
1606+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="1,4" stop="1,4"/>
1607+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="1,-1" stop="1,-1"/>
1608+ </blockTableStyle>
1609+ <blockTableStyle id="Table7">
1610+ <blockAlignment value="LEFT"/>
1611+ <blockValign value="TOP"/>
1612+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="0,0" stop="0,-1"/>
1613+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="0,0" stop="0,0"/>
1614+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="0,-1" stop="0,-1"/>
1615+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="1,0" stop="1,-1"/>
1616+ <lineStyle kind="LINEAFTER" colorName="#e6e6e6" start="1,0" stop="1,-1"/>
1617+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="1,0" stop="1,0"/>
1618+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="1,-1" stop="1,-1"/>
1619+ </blockTableStyle>
1620+ <blockTableStyle id="Table9">
1621+ <blockAlignment value="LEFT"/>
1622+ <blockValign value="TOP"/>
1623+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="0,0" stop="0,-1"/>
1624+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="0,0" stop="0,0"/>
1625+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="0,-1" stop="0,-1"/>
1626+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="1,0" stop="1,-1"/>
1627+ <lineStyle kind="LINEAFTER" colorName="#e6e6e6" start="1,0" stop="1,-1"/>
1628+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="1,0" stop="1,0"/>
1629+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="1,-1" stop="1,-1"/>
1630+ </blockTableStyle>
1631+ <blockTableStyle id="Table10">
1632+ <blockAlignment value="LEFT"/>
1633+ <blockValign value="TOP"/>
1634+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="0,0" stop="0,-1"/>
1635+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="0,0" stop="0,0"/>
1636+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="0,-1" stop="0,-1"/>
1637+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="1,0" stop="1,-1"/>
1638+ <lineStyle kind="LINEAFTER" colorName="#e6e6e6" start="1,0" stop="1,-1"/>
1639+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="1,0" stop="1,0"/>
1640+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="1,-1" stop="1,-1"/>
1641+ </blockTableStyle>
1642+ <blockTableStyle id="Table11">
1643+ <blockAlignment value="LEFT"/>
1644+ <blockValign value="TOP"/>
1645+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="0,0" stop="0,-1"/>
1646+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="0,0" stop="0,0"/>
1647+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="0,-1" stop="0,-1"/>
1648+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="1,0" stop="1,-1"/>
1649+ <lineStyle kind="LINEAFTER" colorName="#e6e6e6" start="1,0" stop="1,-1"/>
1650+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="1,0" stop="1,0"/>
1651+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="1,-1" stop="1,-1"/>
1652+ </blockTableStyle>
1653+ <blockTableStyle id="Table2">
1654+ <blockAlignment value="LEFT"/>
1655+ <blockValign value="TOP"/>
1656+ <lineStyle kind="LINEBELOW" colorName="#000000" start="0,-1" stop="0,-1"/>
1657+ <lineStyle kind="LINEBELOW" colorName="#000000" start="1,-1" stop="1,-1"/>
1658+ <lineStyle kind="LINEBELOW" colorName="#000000" start="2,-1" stop="2,-1"/>
1659+ <lineStyle kind="LINEBELOW" colorName="#000000" start="3,-1" stop="3,-1"/>
1660+ <lineStyle kind="LINEBELOW" colorName="#000000" start="4,-1" stop="4,-1"/>
1661+ <lineStyle kind="LINEBELOW" colorName="#000000" start="5,-1" stop="5,-1"/>
1662+ <lineStyle kind="LINEBELOW" colorName="#000000" start="6,-1" stop="6,-1"/>
1663+ <lineStyle kind="LINEBELOW" colorName="#000000" start="7,-1" stop="7,-1"/>
1664+ <lineStyle kind="LINEBELOW" colorName="#000000" start="8,-1" stop="8,-1"/>
1665+ <lineStyle kind="LINEBELOW" colorName="#000000" start="9,-1" stop="9,-1"/>
1666+ <lineStyle kind="LINEBELOW" colorName="#000000" start="10,-1" stop="10,-1"/>
1667+ </blockTableStyle>
1668+ <blockTableStyle id="Table3">
1669+ <blockAlignment value="LEFT"/>
1670+ <blockValign value="TOP"/>
1671+ <lineStyle kind="LINEBELOW" colorName="#999999" start="0,-1" stop="0,-1"/>
1672+ </blockTableStyle>
1673+ <blockTableStyle id="Table5">
1674+ <blockAlignment value="LEFT"/>
1675+ <blockValign value="TOP"/>
1676+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="0,-1" stop="0,-1"/>
1677+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="1,-1" stop="1,-1"/>
1678+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="2,-1" stop="2,-1"/>
1679+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="3,-1" stop="3,-1"/>
1680+ </blockTableStyle>
1681+ <blockTableStyle id="Table6">
1682+ <blockAlignment value="LEFT"/>
1683+ <blockValign value="TOP"/>
1684+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="0,-1" stop="0,-1"/>
1685+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="1,-1" stop="1,-1"/>
1686+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="2,-1" stop="2,-1"/>
1687+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="3,-1" stop="3,-1"/>
1688+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="4,-1" stop="4,-1"/>
1689+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="5,-1" stop="5,-1"/>
1690+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="6,-1" stop="6,-1"/>
1691+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="7,-1" stop="7,-1"/>
1692+ </blockTableStyle>
1693+ <blockTableStyle id="Table8">
1694+ <blockAlignment value="LEFT"/>
1695+ <blockValign value="TOP"/>
1696+ <lineStyle kind="LINEBELOW" colorName="#000000" start="0,-1" stop="0,-1"/>
1697+ <lineStyle kind="LINEBELOW" colorName="#000000" start="1,-1" stop="1,-1"/>
1698+ <lineStyle kind="LINEBELOW" colorName="#000000" start="2,-1" stop="2,-1"/>
1699+ <lineStyle kind="LINEBELOW" colorName="#000000" start="3,-1" stop="3,-1"/>
1700+ <lineStyle kind="LINEBELOW" colorName="#000000" start="4,-1" stop="4,-1"/>
1701+ <lineStyle kind="LINEBELOW" colorName="#000000" start="5,-1" stop="5,-1"/>
1702+ <lineStyle kind="LINEBELOW" colorName="#000000" start="6,-1" stop="6,-1"/>
1703+ <lineStyle kind="LINEBELOW" colorName="#000000" start="7,-1" stop="7,-1"/>
1704+ <lineStyle kind="LINEBELOW" colorName="#000000" start="8,-1" stop="8,-1"/>
1705+ </blockTableStyle>
1706+ <blockTableStyle id="Table12">
1707+ <blockAlignment value="LEFT"/>
1708+ <blockValign value="TOP"/>
1709+ <lineStyle kind="LINEBELOW" colorName="#999999" start="0,-1" stop="0,-1"/>
1710+ </blockTableStyle>
1711+ <blockTableStyle id="Table13">
1712+ <blockAlignment value="LEFT"/>
1713+ <blockValign value="TOP"/>
1714+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="0,-1" stop="0,-1"/>
1715+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="1,-1" stop="1,-1"/>
1716+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="2,-1" stop="2,-1"/>
1717+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="3,-1" stop="3,-1"/>
1718+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="4,-1" stop="4,-1"/>
1719+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="5,-1" stop="5,-1"/>
1720+ </blockTableStyle>
1721+ <blockTableStyle id="Table14">
1722+ <blockAlignment value="LEFT"/>
1723+ <blockValign value="TOP"/>
1724+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="0,-1" stop="0,-1"/>
1725+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="1,-1" stop="1,-1"/>
1726+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="2,-1" stop="2,-1"/>
1727+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="3,-1" stop="3,-1"/>
1728+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="4,-1" stop="4,-1"/>
1729+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="5,-1" stop="5,-1"/>
1730+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="6,-1" stop="6,-1"/>
1731+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="7,-1" stop="7,-1"/>
1732+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="8,-1" stop="8,-1"/>
1733+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="9,-1" stop="9,-1"/>
1734+ </blockTableStyle>
1735+ <initialize>
1736+ <paraStyle name="all" alignment="justify"/>
1737+ </initialize>
1738+ <paraStyle name="P1" fontName="Helvetica" fontSize="7.0" leading="9" alignment="RIGHT" spaceBefore="0.0" spaceAfter="0.0"/>
1739+ <paraStyle name="P2" fontName="Helvetica" fontSize="8.0" leading="10" alignment="RIGHT" spaceBefore="0.0" spaceAfter="0.0"/>
1740+ <paraStyle name="P3" fontName="Helvetica" fontSize="7.0" leading="9" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
1741+ <paraStyle name="P4" fontName="Helvetica" fontSize="7.0" leading="9" alignment="CENTER" spaceBefore="0.0" spaceAfter="0.0"/>
1742+ <paraStyle name="P5" fontName="Helvetica" fontSize="8.0" leading="10" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
1743+ <paraStyle name="P6" fontName="Helvetica" fontSize="8.0" leading="10" alignment="RIGHT" spaceBefore="0.0" spaceAfter="0.0"/>
1744+ <paraStyle name="P7" fontName="Helvetica" fontSize="7.0" leading="9" alignment="RIGHT" spaceBefore="0.0" spaceAfter="0.0"/>
1745+ <paraStyle name="P8" fontName="Helvetica" fontSize="7.0" leading="9" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
1746+ <paraStyle name="P9" fontName="Helvetica" fontSize="7.0" leading="9" alignment="RIGHT" spaceBefore="0.0" spaceAfter="0.0"/>
1747+ <paraStyle name="PRightBold" fontName="Helvetica-Bold" fontSize="7.0" leading="9" alignment="RIGHT" spaceBefore="0.0" spaceAfter="0.0"/>
1748+ <paraStyle name="PCenteredBold" fontName="Helvetica-Bold" fontSize="7.0" leading="9" alignment="CENTER" spaceBefore="0.0" spaceAfter="0.0"/>
1749+ <paraStyle name="Standard" fontName="Helvetica"/>
1750+ <paraStyle name="Heading" fontName="Helvetica" fontSize="12.0" leading="15" spaceBefore="12.0" spaceAfter="6.0"/>
1751+ <paraStyle name="Text body" fontName="Helvetica" spaceBefore="0.0" spaceAfter="6.0"/>
1752+ <paraStyle name="List" fontName="Helvetica" spaceBefore="0.0" spaceAfter="6.0"/>
1753+ <paraStyle name="Caption" fontName="Helvetica-Oblique" fontSize="8.0" leading="10" spaceBefore="6.0" spaceAfter="6.0"/>
1754+ <paraStyle name="Index" fontName="Helvetica" fontSize="9.0" leading="11"/>
1755+ <paraStyle name="Footer" fontName="Helvetica"/>
1756+ <paraStyle name="Table Contents" fontName="Helvetica"/>
1757+ <paraStyle name="Table Heading" fontName="Helvetica" alignment="CENTER"/>
1758+ <paraStyle name="Horizontal Line" fontName="Helvetica" fontSize="6.0" leading="8" spaceBefore="0.0" spaceAfter="14.0"/>
1759+ <paraStyle name="terp_header" fontName="Helvetica-Bold" fontSize="15.0" leading="19" alignment="LEFT" spaceBefore="12.0" spaceAfter="6.0"/>
1760+ <paraStyle name="Heading 9" fontName="Helvetica-Bold" fontSize="75%" leading="NaN" spaceBefore="12.0" spaceAfter="6.0"/>
1761+ <paraStyle name="terp_tblheader_General" fontName="Helvetica-Bold" fontSize="8.0" leading="10" alignment="LEFT" spaceBefore="6.0" spaceAfter="6.0"/>
1762+ <paraStyle name="terp_tblheader_Details" fontName="Helvetica-Bold" fontSize="9.0" leading="11" alignment="LEFT" spaceBefore="6.0" spaceAfter="6.0"/>
1763+ <paraStyle name="terp_default_8" fontName="Helvetica" fontSize="7.0" leading="9" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
1764+ <paraStyle name="terp_default_Bold_8" fontName="Helvetica-Bold" fontSize="7.0" leading="9" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
1765+ <paraStyle name="terp_tblheader_General_Centre" fontName="Helvetica-Bold" fontSize="8.0" leading="10" alignment="CENTER" spaceBefore="6.0" spaceAfter="6.0"/>
1766+ <paraStyle name="terp_tblheader_General_Right" fontName="Helvetica-Bold" fontSize="8.0" leading="10" alignment="RIGHT" spaceBefore="6.0" spaceAfter="6.0"/>
1767+ <paraStyle name="terp_tblheader_Details_Centre" fontName="Helvetica-Bold" fontSize="9.0" leading="11" alignment="CENTER" spaceBefore="6.0" spaceAfter="6.0"/>
1768+ <paraStyle name="terp_tblheader_Details_Right" fontName="Helvetica-Bold" fontSize="9.0" leading="11" alignment="RIGHT" spaceBefore="6.0" spaceAfter="6.0"/>
1769+ <paraStyle name="terp_default_Right_8" fontName="Helvetica" fontSize="7.0" leading="9" alignment="RIGHT" spaceBefore="0.0" spaceAfter="0.0"/>
1770+ <paraStyle name="terp_default_Centre_8" fontName="Helvetica" fontSize="7.0" leading="9" alignment="CENTER" spaceBefore="0.0" spaceAfter="0.0"/>
1771+ <paraStyle name="terp_header_Right" fontName="Helvetica-Bold" fontSize="15.0" leading="19" alignment="LEFT" spaceBefore="12.0" spaceAfter="6.0"/>
1772+ <paraStyle name="terp_header_Centre" fontName="Helvetica-Bold" fontSize="12.0" leading="15" alignment="CENTER" spaceBefore="12.0" spaceAfter="6.0"/>
1773+ <paraStyle name="terp_default_address" fontName="Helvetica" fontSize="10.0" leading="13" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
1774+ <paraStyle name="terp_default_9" fontName="Helvetica" fontSize="8.0" leading="10" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
1775+ <paraStyle name="terp_default_Bold_9" fontName="Helvetica-Bold" fontSize="9.0" leading="11" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
1776+ <paraStyle name="terp_default_Centre_9" fontName="Helvetica" fontSize="8.0" leading="10" alignment="CENTER" spaceBefore="0.0" spaceAfter="0.0"/>
1777+ <paraStyle name="terp_default_Right_9" fontName="Helvetica" fontSize="8.0" leading="10" alignment="RIGHT" spaceBefore="0.0" spaceAfter="0.0"/>
1778+ <paraStyle name="terp_default_9_italic" fontName="Helvetica-Oblique" fontSize="8.0" leading="10" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
1779+ <paraStyle name="terp_default_Bold_9_Right" fontName="Helvetica-Bold" fontSize="9.0" leading="11" alignment="RIGHT" spaceBefore="0.0" spaceAfter="0.0"/>
1780+ <paraStyle name="terp_default_2" fontName="Helvetica" fontSize="2.0" leading="3" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
1781+ <paraStyle name="Heading 3" fontName="Helvetica-Bold" fontSize="14.0" leading="17" spaceBefore="12.0" spaceAfter="6.0"/>
1782+ <images/>
1783+ </stylesheet>
1784+ <story>
1785+ <para style="terp_default_8">[[ setLang(data['lang']) ]]</para>
1786+ <section>
1787+ <para style="terp_default_8">[[ repeatIn(employees_to_display(objects), 'p') ]]</para>
1788+ <para style="terp_default_8">
1789+ <font color="white"> </font>
1790+ </para>
1791+ <!-- update the number of the current employee displayed -->
1792+ <para style="terp_header_Centre">[[ update_current_employee_number() and translate('Employee Ledger') ]]</para>
1793+ <para style="terp_default_8">
1794+ <font color="white"> </font>
1795+ </para>
1796+ <!-- NOTE: if this HEADER has to be modified: modify also the "no data" version (below) and the "employees
1797+ displayed one after another" version -->
1798+ <blockTable colWidths="65.0,40.0,125.0,85.0,85.0,167.0,165.0,45.0" style="Table1">
1799+ <tr>
1800+ <td>
1801+ <para style="terp_tblheader_General_Centre">Chart of Account</para>
1802+ </td>
1803+ <td>
1804+ <para style="terp_tblheader_General_Centre">Fiscal Year</para>
1805+ </td>
1806+ <td>
1807+ <para style="terp_tblheader_General_Centre">Journals</para>
1808+ </td>
1809+ <td>
1810+ <para style="terp_tblheader_General_Centre">Accounts</para>
1811+ </td>
1812+ <td>
1813+ <para style="terp_tblheader_General_Centre">Proprietary Instances</para>
1814+ </td>
1815+ <td>
1816+ <para style="terp_tblheader_General_Centre">Filter By [[ get_filter(data)!=translate('No Filter') and get_filter(data) ]]</para>
1817+ </td>
1818+ <td>
1819+ <para style="terp_tblheader_General_Centre">Display</para>
1820+ </td>
1821+ <td>
1822+ <para style="terp_tblheader_General_Centre">Func. Currency</para>
1823+ </td>
1824+ </tr>
1825+ </blockTable>
1826+ <blockTable colWidths="65.0,40.0,125.0,85.0,85.0,167.0,165.0,45.0" style="Table4">
1827+ <tr>
1828+ <td>
1829+ <para style="terp_default_Centre_8">[[ get_account(data) or '' ]]</para>
1830+ </td>
1831+ <td>
1832+ <para style="terp_default_Centre_8">[[ get_fiscalyear(data) or '' ]]</para>
1833+ </td>
1834+ <td>
1835+ <para style="terp_default_Centre_8">[[ get_journals_str(data) ]]</para>
1836+ </td>
1837+ <td>
1838+ <para style="terp_default_Centre_8">[[ get_accounts_str(data) ]]</para>
1839+ </td>
1840+ <td>
1841+ <para style="terp_default_Centre_8">[[ get_instances_str(data) ]]</para>
1842+ </td>
1843+ <td>
1844+ <para style="terp_default_Centre_8">[[ get_filter(data)==translate('No Filter') and get_filter(data) or removeParentNode('para') ]]</para>
1845+ <blockTable colWidths="79.0,79.0" style="Table7">
1846+ <tr>
1847+ <td>
1848+ <para style="terp_tblheader_General_Centre">[[ get_filter(data)==translate('Date') and translate('Start Date') or removeParentNode('blockTable') ]]</para>
1849+ </td>
1850+ <td>
1851+ <para style="terp_tblheader_General_Centre">End Date</para>
1852+ </td>
1853+ </tr>
1854+ </blockTable>
1855+ <blockTable colWidths="79.0,79.0" style="Table9">
1856+ <tr>
1857+ <td>
1858+ <para style="terp_default_Centre_8">[[ get_filter(data)==translate('Date') and ' ' or removeParentNode('blockTable') ]] [[ formatLang(get_start_date(data),date=True) ]]</para>
1859+ </td>
1860+ <td>
1861+ <para style="terp_default_Centre_8">[[ formatLang(get_end_date(data),date=True) ]]</para>
1862+ </td>
1863+ </tr>
1864+ </blockTable>
1865+ <blockTable colWidths="79.0,79.0" style="Table10">
1866+ <tr>
1867+ <td>
1868+ <para style="terp_tblheader_General_Centre">[[ get_filter(data)==translate('Periods') and translate('Start Period') or removeParentNode('blockTable') ]]</para>
1869+ </td>
1870+ <td>
1871+ <para style="terp_tblheader_General_Centre">End Period</para>
1872+ </td>
1873+ </tr>
1874+ </blockTable>
1875+ <blockTable colWidths="79.0,79.0" style="Table11">
1876+ <tr>
1877+ <td>
1878+ <para style="terp_default_Centre_8">[[ get_filter(data)==translate('Periods') and ' ' or removeParentNode('blockTable') ]] [[ get_start_period(data) or removeParentNode('para') ]]</para>
1879+ </td>
1880+ <td>
1881+ <para style="terp_default_Centre_8">[[ get_end_period(data) or removeParentNode('para') ]]</para>
1882+ </td>
1883+ </tr>
1884+ </blockTable>
1885+ <para style="terp_default_8">
1886+ <font color="white"> </font>
1887+ </para>
1888+ </td>
1889+ <td>
1890+ <para style="terp_default_Centre_8">[[ "%s: %s, %s: %s, %s: %s, %s: %s, %s: %s, %s: %s" % (translate("Employee's"), get_employees(), translate('Target Moves'), get_target_move(data), translate('Reconciled'), get_reconcile_selection(), translate('Display Employees'), get_display_employees_selection(), translate('Employee Type'), get_employee_type(data),translate('Payment Method'), get_payment_methods(data)) ]]</para>
1891+ </td>
1892+ <td>
1893+ <para style="terp_default_Centre_8">[[ company.currency_id.name ]]</para>
1894+ </td>
1895+ </tr>
1896+ </blockTable>
1897+ <para style="terp_default_8">
1898+ <font color="white"> </font>
1899+ </para>
1900+ <para style="terp_default_8">
1901+ <font color="white"> </font>
1902+ </para>
1903+ <section>
1904+ <blockTable colWidths="72.0,25.0,101.0,46.0,104.0,60.0,51.0,67.0,67.0,77.0,89.0" style="Table2">
1905+ <tr>
1906+ <td>
1907+ <para style="terp_tblheader_Details">Date</para>
1908+ </td>
1909+ <td>
1910+ <para style="terp_tblheader_Details">JRNL</para>
1911+ </td>
1912+ <td>
1913+ <para style="terp_tblheader_Details_Centre">Entry Sequence</para>
1914+ </td>
1915+ <td>
1916+ <para style="terp_tblheader_Details_Centre">Account</para>
1917+ </td>
1918+ <td>
1919+ <para style="terp_tblheader_Details_Centre">Entry Label</para>
1920+ </td>
1921+ <td>
1922+ <para style="terp_tblheader_Details">Reconcile Number</para>
1923+ </td>
1924+ <td>
1925+ <para style="terp_tblheader_Details">Currency</para>
1926+ </td>
1927+ <td>
1928+ <para style="terp_tblheader_Details_Centre">Debit</para>
1929+ </td>
1930+ <td>
1931+ <para style="terp_tblheader_Details_Centre">Credit</para>
1932+ </td>
1933+ <td>
1934+ <para style="terp_tblheader_Details_Right">Booking Balance</para>
1935+ </td>
1936+ <td>
1937+ <para style="terp_tblheader_Details_Right">Balance [[ company.currency_id.name ]]</para>
1938+ </td>
1939+ </tr>
1940+ </blockTable>
1941+ <blockTable colWidths="370.0,40.0,80.0,80.0,90.0,102.0" style="Table8">
1942+ <tr>
1943+ <td>
1944+ <para style="terp_tblheader_Details">
1945+ <font color="white"> </font>
1946+ </para>
1947+ </td>
1948+ <td>
1949+ <para style="terp_tblheader_Details">
1950+ <font color="white"> </font>
1951+ </para>
1952+ </td>
1953+ <td>
1954+ <para style="terp_tblheader_Details_Centre">
1955+ <font color="white"> </font>
1956+ </para>
1957+ </td>
1958+ <td>
1959+ <para style="terp_tblheader_Details_Centre">
1960+ <font color="white"> </font>
1961+ </para>
1962+ </td>
1963+ <td>
1964+ <para style="terp_tblheader_Details">
1965+ <font color="white"> </font>
1966+ </para>
1967+ </td>
1968+ <td>
1969+ <para style="terp_tblheader_Details_Right">
1970+ <font color="white"> </font>
1971+ </para>
1972+ </td>
1973+ </tr>
1974+ </blockTable>
1975+ <blockTable colWidths="420.0,30.0,70.0,70.0,80.0,92.0" style="Table12">
1976+ <tr>
1977+ <td>
1978+ <para style="terp_default_Bold_9">[[ p.name_resource ]]</para>
1979+ </td>
1980+ <td>
1981+ <para style="terp_default_Bold_9">[[ company.currency_id.name ]]</para>
1982+ </td>
1983+ <td>
1984+ <para style="terp_default_Bold_9_Right">[[ formatLang(sum_debit_employee(p) or 0.0) ]]</para>
1985+ </td>
1986+ <td>
1987+ <para style="terp_default_Bold_9_Right">[[ formatLang(sum_credit_employee(p) or 0.0) ]]</para>
1988+ </td>
1989+ <td>
1990+ <para style="terp_default_Bold_9_Right">[[ formatLang((sum_debit_employee(p) or 0.0) - (sum_credit_employee(p) or 0.0)) ]]</para>
1991+ </td>
1992+ <td>
1993+ <para style="terp_default_Bold_9_Right">[[ formatLang((sum_debit_employee(p) or 0.0) - (sum_credit_employee(p) or 0.0)) ]]</para>
1994+ </td>
1995+ </tr>
1996+ </blockTable>
1997+
1998+ <section>
1999+ <para style="terp_default_8">[[ repeatIn(get_accounts_to_display(p), 'account_code') ]]</para>
2000+ <!-- TOTALS IN FUNCTIONAL -->
2001+ <section>
2002+ <blockTable colWidths="296.0,124.0,30.0,70.0,70.0,80.0,92.0" style="Table14">
2003+ <tr>
2004+ <td>
2005+ <para style="PCenteredBold">[[ p.name_resource or '' ]]</para>
2006+ </td>
2007+ <td>
2008+ <para style="PRightBold">[[ account_code ]]</para>
2009+ </td>
2010+ <td>
2011+ <para style="terp_default_Bold_8">[[ company.currency_id.name ]]</para>
2012+ </td>
2013+ <td>
2014+ <para style="PRightBold">[[ formatLang(get_fctal_totals(p, account_code)['debit_functional'] or 0.0) ]]</para>
2015+ </td>
2016+ <td>
2017+ <para style="PRightBold">[[ formatLang(get_fctal_totals(p, account_code)['credit_functional'] or 0.0) ]]</para>
2018+ </td>
2019+ <td>
2020+ <para style="PRightBold">[[ formatLang(get_fctal_totals(p, account_code)['total_functional'] or 0.0) ]]</para>
2021+ </td>
2022+ <td>
2023+ <para style="PRightBold">[[ formatLang(get_fctal_totals(p, account_code)['total_functional'] or 0.0) ]]</para>
2024+ </td>
2025+ </tr>
2026+ </blockTable>
2027+ <para style="terp_default_2">
2028+ <font color="white"> </font>
2029+ </para>
2030+ </section>
2031+ <!-- SUBTOTAL LINES IN BOOKING -->
2032+ <section>
2033+ <para style="terp_default_8">[[ repeatIn(get_subtotals(p, account_code), 'curr') ]]</para>
2034+ <blockTable colWidths="296.0,124.0,30.0,70.0,70.0,80.0,92.0" style="Table14">
2035+ <tr>
2036+ <td>
2037+ <para style="PCenteredBold">[[ p.name_resource or '' ]]</para>
2038+ </td>
2039+ <td>
2040+ <para style="PRightBold">Subtotal</para>
2041+ </td>
2042+ <td>
2043+ <para style="terp_default_Bold_8">[[ curr or '' ]]</para>
2044+ </td>
2045+ <td>
2046+ <para style="PRightBold">[[ formatLang(get_subtotals(p, account_code)[curr]['debit'] or 0.0) ]]</para>
2047+ </td>
2048+ <td>
2049+ <para style="PRightBold">[[ formatLang(get_subtotals(p, account_code)[curr]['credit'] or 0.0) ]]</para>
2050+ </td>
2051+ <td>
2052+ <para style="PRightBold">[[ formatLang(get_subtotals(p, account_code)[curr]['amount_currency'] or 0.0) ]]</para>
2053+ </td>
2054+ <td>
2055+ <para style="PRightBold">[[ formatLang(get_subtotals(p, account_code)[curr]['total_functional'] or 0.0) ]]</para>
2056+ </td>
2057+ </tr>
2058+ </blockTable>
2059+ <para style="terp_default_2">
2060+ <font color="white"> </font>
2061+ </para>
2062+ </section>
2063+ <!-- LINES -->
2064+ <section>
2065+ <para style="terp_default_8">[[ repeatIn(lines(p, account_code), 'line') ]]</para>
2066+ <blockTable colWidths="77.0,25.0,88.0,41.0,139.0,50.0,30.0,70.0,70.0,80.0,92.0" style="Table14">
2067+ <tr>
2068+ <td>
2069+ <para style="P3">[[ formatLang(line['date'], date=True) ]]</para>
2070+ </td>
2071+ <td>
2072+ <para style="P7">[[ line['code'] ]]</para>
2073+ </td>
2074+ <td>
2075+ <para style="P8">[[ line['move_name'] ]]</para>
2076+ </td>
2077+ <td>
2078+ <para style="P7">[[ line['a_code'] ]]</para>
2079+ </td>
2080+ <td>
2081+ <para style="P3">[[ format_entry_label('%s - %s' % (line['ref'] or '', line['name'] or ''), 29) ]]</para>
2082+ </td>
2083+ <td>
2084+ <para style="P3">[[ line['reconcile_txt'] or '' ]]</para>
2085+ </td>
2086+ <td>
2087+ <para style="P3">[[ line['currency_code'] or '' ]]</para>
2088+ </td>
2089+ <td>
2090+ <para style="P7">[[ formatLang(line['debit'] or 0.0) ]]</para>
2091+ </td>
2092+ <td>
2093+ <para style="P7">[[ formatLang(line['credit'] or 0.0) ]]</para>
2094+ </td>
2095+ <td>
2096+ <para style="P7">[[ (line['currency_id'] == None or line['amount_currency']==None) and removeParentNode('font') ]] [[ formatLang(line['amount_currency'] or 0.0) ]]</para>
2097+ </td>
2098+ <td>
2099+ <para style="P7">[[ formatLang(line['total_functional'] or 0.0) ]]</para>
2100+ </td>
2101+ </tr>
2102+ </blockTable>
2103+ <para style="terp_default_2">
2104+ <font color="white"> </font>
2105+ </para>
2106+ </section>
2107+ </section>
2108+ <para style="terp_default_2">
2109+ <font color="white"> </font>
2110+ </para>
2111+ </section>
2112+ <pageBreak>[[ (nb_employees(objects) == 0 or get_current_employee_number() == nb_employees(objects)) and removeParentNode('pageBreak')]]</pageBreak>
2113+ </section>
2114+ <section> <!-- if there is NO DATA to be displayed: display the header only -->
2115+ <para style="terp_default_8">
2116+ [[ nb_employees(objects) > 0 and removeParentNode('section') ]]
2117+ <font color="white"> </font>
2118+ </para>
2119+ <para style="terp_header_Centre">Employee Ledger</para>
2120+ <para style="terp_default_8">
2121+ <font color="white"> </font>
2122+ </para>
2123+ <blockTable colWidths="65.0,40.0,125.0,85.0,85.0,167.0,165.0,45.0" style="Table1">
2124+ <tr>
2125+ <td>
2126+ <para style="terp_tblheader_General_Centre">Chart of Account</para>
2127+ </td>
2128+ <td>
2129+ <para style="terp_tblheader_General_Centre">Fiscal Year</para>
2130+ </td>
2131+ <td>
2132+ <para style="terp_tblheader_General_Centre">Journals</para>
2133+ </td>
2134+ <td>
2135+ <para style="terp_tblheader_General_Centre">Accounts</para>
2136+ </td>
2137+ <td>
2138+ <para style="terp_tblheader_General_Centre">Proprietary Instances</para>
2139+ </td>
2140+ <td>
2141+ <para style="terp_tblheader_General_Centre">Filter By [[ get_filter(data)!=translate('No Filter') and get_filter(data) ]]</para>
2142+ </td>
2143+ <td>
2144+ <para style="terp_tblheader_General_Centre">Display</para>
2145+ </td>
2146+ <td>
2147+ <para style="terp_tblheader_General_Centre">Func. Currency</para>
2148+ </td>
2149+ </tr>
2150+ </blockTable>
2151+ <blockTable colWidths="65.0,40.0,125.0,85.0,85.0,167.0,165.0,45.0" style="Table4">
2152+ <tr>
2153+ <td>
2154+ <para style="terp_default_Centre_8">[[ get_account(data) or '' ]]</para>
2155+ </td>
2156+ <td>
2157+ <para style="terp_default_Centre_8">[[ get_fiscalyear(data) or '' ]]</para>
2158+ </td>
2159+ <td>
2160+ <para style="terp_default_Centre_8">[[ get_journals_str(data) ]]</para>
2161+ </td>
2162+ <td>
2163+ <para style="terp_default_Centre_8">[[ get_accounts_str(data) ]]</para>
2164+ </td>
2165+ <td>
2166+ <para style="terp_default_Centre_8">[[ get_instances_str(data) ]]</para>
2167+ </td>
2168+ <td>
2169+ <para style="terp_default_Centre_8">[[ get_filter(data)==translate('No Filter') and get_filter(data) or removeParentNode('para') ]]</para>
2170+ <blockTable colWidths="79.0,79.0" style="Table7">
2171+ <tr>
2172+ <td>
2173+ <para style="terp_tblheader_General_Centre">[[ get_filter(data)==translate('Date') and translate('Start Date') or removeParentNode('blockTable') ]]</para>
2174+ </td>
2175+ <td>
2176+ <para style="terp_tblheader_General_Centre">End Date</para>
2177+ </td>
2178+ </tr>
2179+ </blockTable>
2180+ <blockTable colWidths="79.0,79.0" style="Table9">
2181+ <tr>
2182+ <td>
2183+ <para style="terp_default_Centre_8">[[ get_filter(data)==translate('Date') and ' ' or removeParentNode('blockTable') ]] [[ formatLang(get_start_date(data),date=True) ]]</para>
2184+ </td>
2185+ <td>
2186+ <para style="terp_default_Centre_8">[[ formatLang(get_end_date(data),date=True) ]]</para>
2187+ </td>
2188+ </tr>
2189+ </blockTable>
2190+ <blockTable colWidths="79.0,79.0" style="Table10">
2191+ <tr>
2192+ <td>
2193+ <para style="terp_tblheader_General_Centre">[[ get_filter(data)==translate('Periods') and translate('Start Period') or removeParentNode('blockTable') ]]</para>
2194+ </td>
2195+ <td>
2196+ <para style="terp_tblheader_General_Centre">End Period</para>
2197+ </td>
2198+ </tr>
2199+ </blockTable>
2200+ <blockTable colWidths="79.0,79.0" style="Table11">
2201+ <tr>
2202+ <td>
2203+ <para style="terp_default_Centre_8">[[ get_filter(data)==translate('Periods') and ' ' or removeParentNode('blockTable') ]] [[ get_start_period(data) or removeParentNode('para') ]]</para>
2204+ </td>
2205+ <td>
2206+ <para style="terp_default_Centre_8">[[ get_end_period(data) or removeParentNode('para') ]]</para>
2207+ </td>
2208+ </tr>
2209+ </blockTable>
2210+ <para style="terp_default_8">
2211+ <font color="white"> </font>
2212+ </para>
2213+ </td>
2214+ <td>
2215+ <para style="terp_default_Centre_8">[[ "%s: %s, %s: %s, %s: %s, %s: %s" % (translate("Employee's"), get_employees(), translate('Target Moves'), get_target_move(data), translate('Reconciled'), get_reconcile_selection(), translate('Display Employees'), get_display_employees_selection()) ]]</para>
2216+ </td>
2217+ <td>
2218+ <para style="terp_default_Centre_8">[[ company.currency_id.name ]]</para>
2219+ </td>
2220+ </tr>
2221+ </blockTable>
2222+ <para style="terp_default_8">
2223+ <font color="white"> </font>
2224+ </para>
2225+ <para style="terp_default_8">
2226+ <font color="white"> </font>
2227+ </para>
2228+ <blockTable colWidths="72.0,25.0,101.0,46.0,104.0,60.0,51.0,67.0,67.0,77.0,89.0" style="Table2">
2229+ <tr>
2230+ <td>
2231+ <para style="terp_tblheader_Details">Date</para>
2232+ </td>
2233+ <td>
2234+ <para style="terp_tblheader_Details">JRNL</para>
2235+ </td>
2236+ <td>
2237+ <para style="terp_tblheader_Details_Centre">Entry Sequence</para>
2238+ </td>
2239+ <td>
2240+ <para style="terp_tblheader_Details_Centre">Account</para>
2241+ </td>
2242+ <td>
2243+ <para style="terp_tblheader_Details_Centre">Entry Label</para>
2244+ </td>
2245+ <td>
2246+ <para style="terp_tblheader_Details">Reconcile Number</para>
2247+ </td>
2248+ <td>
2249+ <para style="terp_tblheader_Details">Currency</para>
2250+ </td>
2251+ <td>
2252+ <para style="terp_tblheader_Details_Centre">Debit</para>
2253+ </td>
2254+ <td>
2255+ <para style="terp_tblheader_Details_Centre">Credit</para>
2256+ </td>
2257+ <td>
2258+ <para style="terp_tblheader_Details_Right">Booking Balance</para>
2259+ </td>
2260+ <td>
2261+ <para style="terp_tblheader_Details_Right">Balance [[ company.currency_id.name ]]</para>
2262+ </td>
2263+ </tr>
2264+ </blockTable>
2265+ </section>
2266+ </story>
2267+</document>
2268
2269=== added file 'bin/addons/account/report/account_employee_ledger_other.rml'
2270--- bin/addons/account/report/account_employee_ledger_other.rml 1970-01-01 00:00:00 +0000
2271+++ bin/addons/account/report/account_employee_ledger_other.rml 2022-06-01 15:15:45 +0000
2272@@ -0,0 +1,653 @@
2273+<?xml version="1.0"?>
2274+<document filename="Employee Ledger.pdf">
2275+ <template pageSize="(842.0,595.0)" title="Employee Ledger" author="Tempo Consulting" allowSplitting="20">
2276+ <pageTemplate id="first">
2277+ <frame id="first" x1="28.0" y1="57.0" width="772" height="481"/>
2278+ </pageTemplate>
2279+ </template>
2280+ <stylesheet>
2281+ <blockTableStyle id="Standard_Outline">
2282+ <blockAlignment value="LEFT"/>
2283+ <blockValign value="TOP"/>
2284+ </blockTableStyle>
2285+ <blockTableStyle id="Table1">
2286+ <blockAlignment value="LEFT"/>
2287+ <blockValign value="TOP"/>
2288+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="0,0" stop="0,-1"/>
2289+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="0,0" stop="0,0"/>
2290+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="0,-1" stop="0,-1"/>
2291+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="1,0" stop="1,-1"/>
2292+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="1,0" stop="1,0"/>
2293+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="1,-1" stop="1,-1"/>
2294+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="2,0" stop="2,-1"/>
2295+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="2,0" stop="2,0"/>
2296+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="2,-1" stop="2,-1"/>
2297+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="3,0" stop="3,-1"/>
2298+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="3,0" stop="3,0"/>
2299+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="3,-1" stop="3,-1"/>
2300+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="4,0" stop="4,-1"/>
2301+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="4,0" stop="4,0"/>
2302+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="4,-1" stop="4,-1"/>
2303+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="5,0" stop="5,-1"/>
2304+ <lineStyle kind="LINEAFTER" colorName="#e6e6e6" start="5,0" stop="5,-1"/>
2305+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="5,0" stop="5,0"/>
2306+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="5,-1" stop="5,-1"/>
2307+ <lineStyle kind="LINEAFTER" colorName="#e6e6e6" start="6,0" stop="6,-1"/>
2308+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="6,0" stop="6,0"/>
2309+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="7,0" stop="7,0"/>
2310+ <lineStyle kind="LINEAFTER" colorName="#e6e6e6" start="7,0" stop="7,-1"/>
2311+ </blockTableStyle>
2312+ <blockTableStyle id="Table4">
2313+ <blockAlignment value="LEFT"/>
2314+ <blockValign value="TOP"/>
2315+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="0,0" stop="0,-1"/>
2316+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="0,0" stop="0,0"/>
2317+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="0,-1" stop="0,-1"/>
2318+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="1,0" stop="1,-1"/>
2319+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="1,0" stop="1,0"/>
2320+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="1,-1" stop="1,-1"/>
2321+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="2,0" stop="2,-1"/>
2322+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="2,0" stop="2,0"/>
2323+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="2,-1" stop="2,-1"/>
2324+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="3,0" stop="3,-1"/>
2325+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="3,0" stop="3,0"/>
2326+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="3,-1" stop="3,-1"/>
2327+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="4,0" stop="4,-1"/>
2328+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="4,0" stop="4,0"/>
2329+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="4,-1" stop="4,-1"/>
2330+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="5,0" stop="5,-1"/>
2331+ <lineStyle kind="LINEAFTER" colorName="#e6e6e6" start="5,0" stop="5,-1"/>
2332+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="5,0" stop="5,0"/>
2333+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="5,-1" stop="5,-1"/>
2334+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="6,0" stop="6,-1"/>
2335+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="6,0" stop="6,0"/>
2336+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="6,-1" stop="6,-1"/>
2337+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="7,0" stop="7,-1"/>
2338+ <lineStyle kind="LINEAFTER" colorName="#e6e6e6" start="7,0" stop="7,-1"/>
2339+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="7,0" stop="7,0"/>
2340+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="7,-1" stop="7,-1"/>
2341+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="8,0" stop="8,-1"/>
2342+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="8,0" stop="8,0"/>
2343+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="8,-1" stop="8,-1"/>
2344+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="9,0" stop="9,-1"/>
2345+ <lineStyle kind="LINEAFTER" colorName="#e6e6e6" start="9,0" stop="9,-1"/>
2346+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="9,0" stop="9,0"/>
2347+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="9,-1" stop="9,-1"/>
2348+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="10,0" stop="10,-1"/>
2349+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="10,0" stop="10,0"/>
2350+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="10,-1" stop="10,-1"/>
2351+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="11,0" stop="11,-1"/>
2352+ <lineStyle kind="LINEAFTER" colorName="#e6e6e6" start="11,0" stop="11,-1"/>
2353+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="11,0" stop="11,0"/>
2354+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="11,-1" stop="11,-1"/>
2355+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="12,0" stop="12,-1"/>
2356+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="12,0" stop="12,0"/>
2357+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="12,-1" stop="12,-1"/>
2358+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="13,0" stop="13,-1"/>
2359+ <lineStyle kind="LINEAFTER" colorName="#e6e6e6" start="13,0" stop="13,-1"/>
2360+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="13,0" stop="13,0"/>
2361+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="13,-1" stop="13,-1"/>
2362+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="0,1" stop="0,-1"/>
2363+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="0,1" stop="0,1"/>
2364+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="0,-1" stop="0,-1"/>
2365+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="1,1" stop="1,-1"/>
2366+ <lineStyle kind="LINEAFTER" colorName="#e6e6e6" start="1,1" stop="1,-1"/>
2367+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="1,1" stop="1,1"/>
2368+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="1,-1" stop="1,-1"/>
2369+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="0,2" stop="0,-1"/>
2370+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="0,2" stop="0,2"/>
2371+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="0,-1" stop="0,-1"/>
2372+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="1,2" stop="1,-1"/>
2373+ <lineStyle kind="LINEAFTER" colorName="#e6e6e6" start="1,2" stop="1,-1"/>
2374+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="1,2" stop="1,2"/>
2375+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="1,-1" stop="1,-1"/>
2376+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="0,3" stop="0,-1"/>
2377+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="0,3" stop="0,3"/>
2378+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="0,-1" stop="0,-1"/>
2379+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="1,3" stop="1,-1"/>
2380+ <lineStyle kind="LINEAFTER" colorName="#e6e6e6" start="1,3" stop="1,-1"/>
2381+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="1,3" stop="1,3"/>
2382+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="1,-1" stop="1,-1"/>
2383+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="0,4" stop="0,-1"/>
2384+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="0,4" stop="0,4"/>
2385+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="0,-1" stop="0,-1"/>
2386+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="1,4" stop="1,-1"/>
2387+ <lineStyle kind="LINEAFTER" colorName="#e6e6e6" start="1,4" stop="1,-1"/>
2388+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="1,4" stop="1,4"/>
2389+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="1,-1" stop="1,-1"/>
2390+ </blockTableStyle>
2391+ <blockTableStyle id="Table7">
2392+ <blockAlignment value="LEFT"/>
2393+ <blockValign value="TOP"/>
2394+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="0,0" stop="0,-1"/>
2395+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="0,0" stop="0,0"/>
2396+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="0,-1" stop="0,-1"/>
2397+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="1,0" stop="1,-1"/>
2398+ <lineStyle kind="LINEAFTER" colorName="#e6e6e6" start="1,0" stop="1,-1"/>
2399+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="1,0" stop="1,0"/>
2400+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="1,-1" stop="1,-1"/>
2401+ </blockTableStyle>
2402+ <blockTableStyle id="Table9">
2403+ <blockAlignment value="LEFT"/>
2404+ <blockValign value="TOP"/>
2405+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="0,0" stop="0,-1"/>
2406+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="0,0" stop="0,0"/>
2407+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="0,-1" stop="0,-1"/>
2408+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="1,0" stop="1,-1"/>
2409+ <lineStyle kind="LINEAFTER" colorName="#e6e6e6" start="1,0" stop="1,-1"/>
2410+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="1,0" stop="1,0"/>
2411+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="1,-1" stop="1,-1"/>
2412+ </blockTableStyle>
2413+ <blockTableStyle id="Table10">
2414+ <blockAlignment value="LEFT"/>
2415+ <blockValign value="TOP"/>
2416+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="0,0" stop="0,-1"/>
2417+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="0,0" stop="0,0"/>
2418+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="0,-1" stop="0,-1"/>
2419+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="1,0" stop="1,-1"/>
2420+ <lineStyle kind="LINEAFTER" colorName="#e6e6e6" start="1,0" stop="1,-1"/>
2421+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="1,0" stop="1,0"/>
2422+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="1,-1" stop="1,-1"/>
2423+ </blockTableStyle>
2424+ <blockTableStyle id="Table11">
2425+ <blockAlignment value="LEFT"/>
2426+ <blockValign value="TOP"/>
2427+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="0,0" stop="0,-1"/>
2428+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="0,0" stop="0,0"/>
2429+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="0,-1" stop="0,-1"/>
2430+ <lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="1,0" stop="1,-1"/>
2431+ <lineStyle kind="LINEAFTER" colorName="#e6e6e6" start="1,0" stop="1,-1"/>
2432+ <lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="1,0" stop="1,0"/>
2433+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="1,-1" stop="1,-1"/>
2434+ </blockTableStyle>
2435+ <blockTableStyle id="Table15">
2436+ <blockAlignment value="LEFT"/>
2437+ <blockValign value="TOP"/>
2438+ <lineStyle kind="LINEBELOW" colorName="#000000" start="0,-1" stop="0,-1"/>
2439+ <lineStyle kind="LINEBELOW" colorName="#000000" start="1,-1" stop="1,-1"/>
2440+ <lineStyle kind="LINEBELOW" colorName="#000000" start="2,-1" stop="2,-1"/>
2441+ <lineStyle kind="LINEBELOW" colorName="#000000" start="3,-1" stop="3,-1"/>
2442+ <lineStyle kind="LINEBELOW" colorName="#000000" start="4,-1" stop="4,-1"/>
2443+ <lineStyle kind="LINEBELOW" colorName="#000000" start="5,-1" stop="5,-1"/>
2444+ <lineStyle kind="LINEBELOW" colorName="#000000" start="6,-1" stop="6,-1"/>
2445+ <lineStyle kind="LINEBELOW" colorName="#000000" start="7,-1" stop="7,-1"/>
2446+ </blockTableStyle>
2447+ <blockTableStyle id="Table3">
2448+ <blockAlignment value="LEFT"/>
2449+ <blockValign value="TOP"/>
2450+ <lineStyle kind="LINEBELOW" colorName="#999999" start="0,-1" stop="0,-1"/>
2451+ </blockTableStyle>
2452+ <blockTableStyle id="Table5">
2453+ <blockAlignment value="LEFT"/>
2454+ <blockValign value="TOP"/>
2455+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="0,-1" stop="0,-1"/>
2456+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="1,-1" stop="1,-1"/>
2457+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="2,-1" stop="2,-1"/>
2458+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="3,-1" stop="3,-1"/>
2459+ </blockTableStyle>
2460+ <blockTableStyle id="Table6">
2461+ <blockAlignment value="LEFT"/>
2462+ <blockValign value="TOP"/>
2463+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="0,-1" stop="0,-1"/>
2464+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="1,-1" stop="1,-1"/>
2465+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="2,-1" stop="2,-1"/>
2466+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="3,-1" stop="3,-1"/>
2467+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="4,-1" stop="4,-1"/>
2468+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="5,-1" stop="5,-1"/>
2469+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="6,-1" stop="6,-1"/>
2470+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="7,-1" stop="7,-1"/>
2471+ </blockTableStyle>
2472+ <blockTableStyle id="Table2">
2473+ <blockAlignment value="LEFT"/>
2474+ <blockValign value="TOP"/>
2475+ <lineStyle kind="LINEBELOW" colorName="#000000" start="0,-1" stop="0,-1"/>
2476+ <lineStyle kind="LINEBELOW" colorName="#000000" start="1,-1" stop="1,-1"/>
2477+ <lineStyle kind="LINEBELOW" colorName="#000000" start="2,-1" stop="2,-1"/>
2478+ <lineStyle kind="LINEBELOW" colorName="#000000" start="3,-1" stop="3,-1"/>
2479+ <lineStyle kind="LINEBELOW" colorName="#000000" start="4,-1" stop="4,-1"/>
2480+ <lineStyle kind="LINEBELOW" colorName="#000000" start="5,-1" stop="5,-1"/>
2481+ <lineStyle kind="LINEBELOW" colorName="#000000" start="6,-1" stop="6,-1"/>
2482+ <lineStyle kind="LINEBELOW" colorName="#000000" start="7,-1" stop="7,-1"/>
2483+ <lineStyle kind="LINEBELOW" colorName="#000000" start="8,-1" stop="8,-1"/>
2484+ <lineStyle kind="LINEBELOW" colorName="#000000" start="9,-1" stop="9,-1"/>
2485+ <lineStyle kind="LINEBELOW" colorName="#000000" start="10,-1" stop="10,-1"/>
2486+ </blockTableStyle>
2487+ <blockTableStyle id="Table8">
2488+ <blockAlignment value="LEFT"/>
2489+ <blockValign value="TOP"/>
2490+ <lineStyle kind="LINEBELOW" colorName="#000000" start="0,-1" stop="0,-1"/>
2491+ <lineStyle kind="LINEBELOW" colorName="#000000" start="1,-1" stop="1,-1"/>
2492+ <lineStyle kind="LINEBELOW" colorName="#000000" start="2,-1" stop="2,-1"/>
2493+ <lineStyle kind="LINEBELOW" colorName="#000000" start="3,-1" stop="3,-1"/>
2494+ <lineStyle kind="LINEBELOW" colorName="#000000" start="4,-1" stop="4,-1"/>
2495+ <lineStyle kind="LINEBELOW" colorName="#000000" start="5,-1" stop="5,-1"/>
2496+ <lineStyle kind="LINEBELOW" colorName="#000000" start="6,-1" stop="6,-1"/>
2497+ <lineStyle kind="LINEBELOW" colorName="#000000" start="7,-1" stop="7,-1"/>
2498+ <lineStyle kind="LINEBELOW" colorName="#000000" start="8,-1" stop="8,-1"/>
2499+ <lineStyle kind="LINEBELOW" colorName="#000000" start="9,-1" stop="9,-1"/>
2500+ </blockTableStyle>
2501+ <blockTableStyle id="Table12">
2502+ <blockAlignment value="LEFT"/>
2503+ <blockValign value="TOP"/>
2504+ <lineStyle kind="LINEBELOW" colorName="#999999" start="0,-1" stop="0,-1"/>
2505+ </blockTableStyle>
2506+ <blockTableStyle id="Table13">
2507+ <blockAlignment value="LEFT"/>
2508+ <blockValign value="TOP"/>
2509+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="0,-1" stop="0,-1"/>
2510+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="1,-1" stop="1,-1"/>
2511+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="2,-1" stop="2,-1"/>
2512+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="3,-1" stop="3,-1"/>
2513+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="4,-1" stop="4,-1"/>
2514+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="5,-1" stop="5,-1"/>
2515+ </blockTableStyle>
2516+ <blockTableStyle id="Table14">
2517+ <blockAlignment value="LEFT"/>
2518+ <blockValign value="TOP"/>
2519+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="0,-1" stop="0,-1"/>
2520+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="1,-1" stop="1,-1"/>
2521+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="2,-1" stop="2,-1"/>
2522+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="3,-1" stop="3,-1"/>
2523+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="4,-1" stop="4,-1"/>
2524+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="5,-1" stop="5,-1"/>
2525+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="6,-1" stop="6,-1"/>
2526+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="7,-1" stop="7,-1"/>
2527+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="8,-1" stop="8,-1"/>
2528+ <lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="9,-1" stop="9,-1"/>
2529+ </blockTableStyle>
2530+ <initialize>
2531+ <paraStyle name="all" alignment="justify"/>
2532+ </initialize>
2533+ <paraStyle name="P1" fontName="Helvetica" fontSize="7.0" leading="9" alignment="RIGHT" spaceBefore="0.0" spaceAfter="0.0"/>
2534+ <paraStyle name="P2" fontName="Helvetica" fontSize="8.0" leading="10" alignment="RIGHT" spaceBefore="0.0" spaceAfter="0.0"/>
2535+ <paraStyle name="P3" fontName="Helvetica" fontSize="7.0" leading="9" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
2536+ <paraStyle name="P4" fontName="Helvetica" fontSize="7.0" leading="9" alignment="CENTER" spaceBefore="0.0" spaceAfter="0.0"/>
2537+ <paraStyle name="P5" fontName="Helvetica" fontSize="8.0" leading="10" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
2538+ <paraStyle name="P6" fontName="Helvetica" fontSize="8.0" leading="10" alignment="RIGHT" spaceBefore="0.0" spaceAfter="0.0"/>
2539+ <paraStyle name="P7" fontName="Helvetica" fontSize="7.0" leading="9" alignment="RIGHT" spaceBefore="0.0" spaceAfter="0.0"/>
2540+ <paraStyle name="P8" fontName="Helvetica" fontSize="7.0" leading="9" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
2541+ <paraStyle name="P9" fontName="Helvetica" fontSize="7.0" leading="9" alignment="RIGHT" spaceBefore="0.0" spaceAfter="0.0"/>
2542+ <paraStyle name="PRightBold" fontName="Helvetica-Bold" fontSize="7.0" leading="9" alignment="RIGHT" spaceBefore="0.0" spaceAfter="0.0"/>
2543+ <paraStyle name="PCenteredBold" fontName="Helvetica-Bold" fontSize="7.0" leading="9" alignment="CENTER" spaceBefore="0.0" spaceAfter="0.0"/>
2544+ <paraStyle name="Standard" fontName="Helvetica"/>
2545+ <paraStyle name="Heading" fontName="Helvetica" fontSize="12.0" leading="15" spaceBefore="12.0" spaceAfter="6.0"/>
2546+ <paraStyle name="Text body" fontName="Helvetica" spaceBefore="0.0" spaceAfter="6.0"/>
2547+ <paraStyle name="List" fontName="Helvetica" spaceBefore="0.0" spaceAfter="6.0"/>
2548+ <paraStyle name="Caption" fontName="Helvetica-Oblique" fontSize="8.0" leading="10" spaceBefore="6.0" spaceAfter="6.0"/>
2549+ <paraStyle name="Index" fontName="Helvetica" fontSize="9.0" leading="11"/>
2550+ <paraStyle name="Footer" fontName="Helvetica"/>
2551+ <paraStyle name="Table Contents" fontName="Helvetica"/>
2552+ <paraStyle name="Table Heading" fontName="Helvetica" alignment="CENTER"/>
2553+ <paraStyle name="Horizontal Line" fontName="Helvetica" fontSize="6.0" leading="8" spaceBefore="0.0" spaceAfter="14.0"/>
2554+ <paraStyle name="terp_header" fontName="Helvetica-Bold" fontSize="15.0" leading="19" alignment="LEFT" spaceBefore="12.0" spaceAfter="6.0"/>
2555+ <paraStyle name="Heading 9" fontName="Helvetica-Bold" fontSize="75%" leading="NaN" spaceBefore="12.0" spaceAfter="6.0"/>
2556+ <paraStyle name="terp_tblheader_General" fontName="Helvetica-Bold" fontSize="8.0" leading="10" alignment="LEFT" spaceBefore="6.0" spaceAfter="6.0"/>
2557+ <paraStyle name="terp_tblheader_Details" fontName="Helvetica-Bold" fontSize="9.0" leading="11" alignment="LEFT" spaceBefore="6.0" spaceAfter="6.0"/>
2558+ <paraStyle name="terp_default_8" fontName="Helvetica" fontSize="7.0" leading="9" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
2559+ <paraStyle name="terp_default_Bold_8" fontName="Helvetica-Bold" fontSize="7.0" leading="9" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
2560+ <paraStyle name="terp_tblheader_General_Centre" fontName="Helvetica-Bold" fontSize="8.0" leading="10" alignment="CENTER" spaceBefore="6.0" spaceAfter="6.0"/>
2561+ <paraStyle name="terp_tblheader_General_Right" fontName="Helvetica-Bold" fontSize="8.0" leading="10" alignment="RIGHT" spaceBefore="6.0" spaceAfter="6.0"/>
2562+ <paraStyle name="terp_tblheader_Details_Centre" fontName="Helvetica-Bold" fontSize="9.0" leading="11" alignment="CENTER" spaceBefore="6.0" spaceAfter="6.0"/>
2563+ <paraStyle name="terp_tblheader_Details_Right" fontName="Helvetica-Bold" fontSize="9.0" leading="11" alignment="RIGHT" spaceBefore="6.0" spaceAfter="6.0"/>
2564+ <paraStyle name="terp_default_Right_8" fontName="Helvetica" fontSize="7.0" leading="9" alignment="RIGHT" spaceBefore="0.0" spaceAfter="0.0"/>
2565+ <paraStyle name="terp_default_Centre_8" fontName="Helvetica" fontSize="7.0" leading="9" alignment="CENTER" spaceBefore="0.0" spaceAfter="0.0"/>
2566+ <paraStyle name="terp_header_Right" fontName="Helvetica-Bold" fontSize="15.0" leading="19" alignment="LEFT" spaceBefore="12.0" spaceAfter="6.0"/>
2567+ <paraStyle name="terp_header_Centre" fontName="Helvetica-Bold" fontSize="12.0" leading="15" alignment="CENTER" spaceBefore="12.0" spaceAfter="6.0"/>
2568+ <paraStyle name="terp_default_address" fontName="Helvetica" fontSize="10.0" leading="13" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
2569+ <paraStyle name="terp_default_9" fontName="Helvetica" fontSize="8.0" leading="10" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
2570+ <paraStyle name="terp_default_Bold_9" fontName="Helvetica-Bold" fontSize="9.0" leading="11" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
2571+ <paraStyle name="terp_default_Centre_9" fontName="Helvetica" fontSize="8.0" leading="10" alignment="CENTER" spaceBefore="0.0" spaceAfter="0.0"/>
2572+ <paraStyle name="terp_default_Right_9" fontName="Helvetica" fontSize="8.0" leading="10" alignment="RIGHT" spaceBefore="0.0" spaceAfter="0.0"/>
2573+ <paraStyle name="terp_default_9_italic" fontName="Helvetica-Oblique" fontSize="8.0" leading="10" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
2574+ <paraStyle name="terp_default_Bold_9_Right" fontName="Helvetica-Bold" fontSize="9.0" leading="11" alignment="RIGHT" spaceBefore="0.0" spaceAfter="0.0"/>
2575+ <paraStyle name="terp_default_2" fontName="Helvetica" fontSize="2.0" leading="3" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
2576+ <paraStyle name="Heading 3" fontName="Helvetica-Bold" fontSize="14.0" leading="17" spaceBefore="12.0" spaceAfter="6.0"/>
2577+ <images/>
2578+ </stylesheet>
2579+ <story>
2580+ <para style="terp_default_8">
2581+ <font color="white"> </font>
2582+ </para>
2583+ <para style="terp_default_8">[[ setLang(data['lang']) ]]</para>
2584+ <para style="terp_header_Centre">Employee Ledger</para>
2585+ <para style="terp_default_8">
2586+ <font color="white"> </font>
2587+ </para>
2588+ <!-- NOTE: if this HEADER has to be modified: modify also the "One employee per page" version -->
2589+ <blockTable colWidths="65.0,40.0,125.0,85.0,85.0,167.0,165.0,45.0" style="Table1">
2590+ <tr>
2591+ <td>
2592+ <para style="terp_tblheader_General_Centre">Chart of Account</para>
2593+ </td>
2594+ <td>
2595+ <para style="terp_tblheader_General_Centre">Fiscal Year</para>
2596+ </td>
2597+ <td>
2598+ <para style="terp_tblheader_General_Centre">Journals</para>
2599+ </td>
2600+ <td>
2601+ <para style="terp_tblheader_General_Centre">Accounts</para>
2602+ </td>
2603+ <td>
2604+ <para style="terp_tblheader_General_Centre">Proprietary Instances</para>
2605+ </td>
2606+ <td>
2607+ <para style="terp_tblheader_General_Centre">Filter By [[ get_filter(data)!=translate('No Filter') and get_filter(data) ]]</para>
2608+ </td>
2609+ <td>
2610+ <para style="terp_tblheader_General_Centre">Display</para>
2611+ </td>
2612+ <td>
2613+ <para style="terp_tblheader_General_Centre">Func. Currency</para>
2614+ </td>
2615+ </tr>
2616+ </blockTable>
2617+ <blockTable colWidths="65.0,40.0,125.0,85.0,85.0,167.0,165.0,45.0" style="Table4">
2618+ <tr>
2619+ <td>
2620+ <para style="terp_default_Centre_8">[[ get_account(data) or '' ]]</para>
2621+ </td>
2622+ <td>
2623+ <para style="terp_default_Centre_8">[[ get_fiscalyear(data) or '' ]]</para>
2624+ </td>
2625+ <td>
2626+ <para style="terp_default_Centre_8">[[ get_journals_str(data) ]]</para>
2627+ </td>
2628+ <td>
2629+ <para style="terp_default_Centre_8">[[ get_accounts_str(data) ]]</para>
2630+ </td>
2631+ <td>
2632+ <para style="terp_default_Centre_8">[[ get_instances_str(data) ]]</para>
2633+ </td>
2634+ <td>
2635+ <para style="terp_default_Centre_8">[[ get_filter(data)==translate('No Filter') and get_filter(data) or removeParentNode('para') ]]</para>
2636+ <blockTable colWidths="79.0,79.0" style="Table7">
2637+ <tr>
2638+ <td>
2639+ <para style="terp_tblheader_General_Centre">[[ get_filter(data)==translate('Date') and translate('Start Date') or removeParentNode('blockTable') ]]</para>
2640+ </td>
2641+ <td>
2642+ <para style="terp_tblheader_General_Centre">End Date</para>
2643+ </td>
2644+ </tr>
2645+ </blockTable>
2646+ <blockTable colWidths="79.0,79.0" style="Table9">
2647+ <tr>
2648+ <td>
2649+ <para style="terp_default_Centre_8">[[ get_filter(data)==translate('Date') and ' ' or removeParentNode('blockTable') ]] [[ formatLang(get_start_date(data),date=True) ]]</para>
2650+ </td>
2651+ <td>
2652+ <para style="terp_default_Centre_8">[[ formatLang(get_end_date(data),date=True) ]]</para>
2653+ </td>
2654+ </tr>
2655+ </blockTable>
2656+ <blockTable colWidths="79.0,79.0" style="Table10">
2657+ <tr>
2658+ <td>
2659+ <para style="terp_tblheader_General_Centre">[[ get_filter(data)==translate('Periods') and translate('Start Period') or removeParentNode('blockTable') ]]</para>
2660+ </td>
2661+ <td>
2662+ <para style="terp_tblheader_General_Centre">End Period</para>
2663+ </td>
2664+ </tr>
2665+ </blockTable>
2666+ <blockTable colWidths="79.0,79.0" style="Table11">
2667+ <tr>
2668+ <td>
2669+ <para style="terp_default_Centre_8">[[ get_filter(data)==translate('Periods') and ' ' or removeParentNode('blockTable') ]] [[ get_start_period(data) or removeParentNode('para') ]]</para>
2670+ </td>
2671+ <td>
2672+ <para style="terp_default_Centre_8">[[ get_end_period(data) or removeParentNode('para') ]]</para>
2673+ </td>
2674+ </tr>
2675+ </blockTable>
2676+ <para style="terp_default_8">
2677+ <font color="white"> </font>
2678+ </para>
2679+ </td>
2680+ <td>
2681+ <para style="terp_default_Centre_8">[[ "%s: %s, %s: %s, %s: %s, %s: %s, %s: %s, %s: %s" % (translate("Employee's"), get_employees(), translate('Target Moves'), get_target_move(data), translate('Reconciled'), get_reconcile_selection(), translate('Display Employees'), get_display_employees_selection(), translate('Employee Type'), get_employee_type(data),translate('Payment Method'), get_payment_methods(data)) ]]</para>
2682+ </td>
2683+ <td>
2684+ <para style="terp_default_Centre_8">[[ company.currency_id.name ]]</para>
2685+ </td>
2686+ </tr>
2687+ </blockTable>
2688+ <para style="terp_default_8">
2689+ <font color="white"> </font>
2690+ </para>
2691+ <para style="terp_default_8">
2692+ <font color="white"> </font>
2693+ </para>
2694+ <blockTable colWidths="72.0,25.0,101.0,46.0,104.0,60.0,51.0,67.0,67.0,77.0,89.0" style="Table2">
2695+ <tr>
2696+ <td>
2697+ <para style="terp_tblheader_Details">Date</para>
2698+ </td>
2699+ <td>
2700+ <para style="terp_tblheader_Details">JRNL</para>
2701+ </td>
2702+ <td>
2703+ <para style="terp_tblheader_Details_Centre">Entry Sequence</para>
2704+ </td>
2705+ <td>
2706+ <para style="terp_tblheader_Details_Centre">Account</para>
2707+ </td>
2708+ <td>
2709+ <para style="terp_tblheader_Details_Centre">Entry Label</para>
2710+ </td>
2711+ <td>
2712+ <para style="terp_tblheader_Details">Reconcile Number</para>
2713+ </td>
2714+ <td>
2715+ <para style="terp_tblheader_Details">Currency</para>
2716+ </td>
2717+ <td>
2718+ <para style="terp_tblheader_Details_Centre">Debit</para>
2719+ </td>
2720+ <td>
2721+ <para style="terp_tblheader_Details_Centre">Credit</para>
2722+ </td>
2723+ <td>
2724+ <para style="terp_tblheader_Details_Right">Booking Balance</para>
2725+ </td>
2726+ <td>
2727+ <para style="terp_tblheader_Details_Right">Balance [[ company.currency_id.name ]]</para>
2728+ </td>
2729+ </tr>
2730+ </blockTable>
2731+ <section>
2732+ <para style="terp_default_8">[[ repeatIn(employees_to_display(objects), 'p') ]]</para>
2733+ <blockTable colWidths="59.0,44.0,89.0,89.0,89.0,40.0,80.0,80.0,90.0,102.0" style="Table8">
2734+ <tr>
2735+ <td>
2736+ <para style="terp_tblheader_Details">
2737+ <font color="white"> </font>
2738+ </para>
2739+ </td>
2740+ <td>
2741+ <para style="terp_tblheader_Details">
2742+ <font color="white"> </font>
2743+ </para>
2744+ </td>
2745+ <td>
2746+ <para style="terp_tblheader_Details_Centre">
2747+ <font color="white"> </font>
2748+ </para>
2749+ </td>
2750+ <td>
2751+ <para style="terp_tblheader_Details_Centre">
2752+ <font color="white"> </font>
2753+ </para>
2754+ </td>
2755+ <td>
2756+ <para style="terp_tblheader_Details">
2757+ <font color="white"> </font>
2758+ </para>
2759+ </td>
2760+ <td>
2761+ <para style="terp_tblheader_Details_Right">
2762+ <font color="white"> </font>
2763+ </para>
2764+ </td>
2765+ <td>
2766+ <para style="terp_tblheader_Details_Right">
2767+ <font color="white"> </font>
2768+ </para>
2769+ </td>
2770+ <td>
2771+ <para style="terp_tblheader_Details_Right">
2772+ <font color="white"> </font>
2773+ </para>
2774+ </td>
2775+ <td>
2776+ <para style="terp_tblheader_Details_Right">
2777+ <font color="white"> </font>
2778+ </para>
2779+ </td>
2780+ <td>
2781+ <para style="terp_tblheader_Details_Right">
2782+ <font color="white"> </font>
2783+ </para>
2784+ </td>
2785+ </tr>
2786+ </blockTable>
2787+ <blockTable colWidths="420.0,30.0,70.0,70.0,80.0,92.0" style="Table12">
2788+ <tr>
2789+ <td>
2790+ <para style="terp_default_Bold_9">[[p.name_resource ]]</para>
2791+ </td>
2792+ <td>
2793+ <para style="terp_default_Bold_9">[[ company.currency_id.name ]]</para>
2794+ </td>
2795+ <td>
2796+ <para style="terp_default_Bold_9_Right">[[ formatLang(sum_debit_employee(p) or 0.0) ]]</para>
2797+ </td>
2798+ <td>
2799+ <para style="terp_default_Bold_9_Right">[[ formatLang(sum_credit_employee(p) or 0.0) ]]</para>
2800+ </td>
2801+ <td>
2802+ <para style="terp_default_Bold_9_Right">[[ formatLang((sum_debit_employee(p) or 0.0) - (sum_credit_employee(p) or 0.0)) ]]</para>
2803+ </td>
2804+ <td>
2805+ <para style="terp_default_Bold_9_Right">[[ formatLang((sum_debit_employee(p) or 0.0) - (sum_credit_employee(p) or 0.0)) ]]</para>
2806+ </td>
2807+ </tr>
2808+ </blockTable>
2809+
2810+ <section>
2811+ <para style="terp_default_8">[[ repeatIn(get_accounts_to_display(p), 'account_code') ]]</para>
2812+ <!-- TOTALS IN FUNCTIONAL -->
2813+ <section>
2814+ <blockTable colWidths="296.0,124.0,30.0,70.0,70.0,80.0,92.0" style="Table14">
2815+ <tr>
2816+ <td>
2817+ <para style="PCenteredBold">[[p.name_resource or '' ]]</para>
2818+ </td>
2819+ <td>
2820+ <para style="PRightBold">[[ account_code ]]</para>
2821+ </td>
2822+ <td>
2823+ <para style="terp_default_Bold_8">[[ company.currency_id.name ]]</para>
2824+ </td>
2825+ <td>
2826+ <para style="PRightBold">[[ formatLang(get_fctal_totals(p, account_code)['debit_functional'] or 0.0) ]]</para>
2827+ </td>
2828+ <td>
2829+ <para style="PRightBold">[[ formatLang(get_fctal_totals(p, account_code)['credit_functional'] or 0.0) ]]</para>
2830+ </td>
2831+ <td>
2832+ <para style="PRightBold">[[ formatLang(get_fctal_totals(p, account_code)['total_functional'] or 0.0) ]]</para>
2833+ </td>
2834+ <td>
2835+ <para style="PRightBold">[[ formatLang(get_fctal_totals(p, account_code)['total_functional'] or 0.0) ]]</para>
2836+ </td>
2837+ </tr>
2838+ </blockTable>
2839+ <para style="terp_default_2">
2840+ <font color="white"> </font>
2841+ </para>
2842+ </section>
2843+ <!-- SUBTOTAL LINES IN BOOKING -->
2844+ <section>
2845+ <para style="terp_default_8">[[ repeatIn(get_subtotals(p, account_code), 'curr') ]]</para>
2846+ <blockTable colWidths="296.0,124.0,30.0,70.0,70.0,80.0,92.0" style="Table14">
2847+ <tr>
2848+ <td>
2849+ <para style="PCenteredBold">[[p.name_resource or '' ]]</para>
2850+ </td>
2851+ <td>
2852+ <para style="PRightBold">Subtotal</para>
2853+ </td>
2854+ <td>
2855+ <para style="terp_default_Bold_8">[[ curr or '' ]]</para>
2856+ </td>
2857+ <td>
2858+ <para style="PRightBold">[[ formatLang(get_subtotals(p, account_code)[curr]['debit'] or 0.0) ]]</para>
2859+ </td>
2860+ <td>
2861+ <para style="PRightBold">[[ formatLang(get_subtotals(p, account_code)[curr]['credit'] or 0.0) ]]</para>
2862+ </td>
2863+ <td>
2864+ <para style="PRightBold">[[ formatLang(get_subtotals(p, account_code)[curr]['amount_currency'] or 0.0) ]]</para>
2865+ </td>
2866+ <td>
2867+ <para style="PRightBold">[[ formatLang(get_subtotals(p, account_code)[curr]['total_functional'] or 0.0) ]]</para>
2868+ </td>
2869+ </tr>
2870+ </blockTable>
2871+ <para style="terp_default_2">
2872+ <font color="white"> </font>
2873+ </para>
2874+ </section>
2875+ <!-- LINES -->
2876+ <section>
2877+ <para style="terp_default_8">[[ repeatIn(lines(p, account_code), 'line') ]]</para>
2878+ <blockTable colWidths="77.0,25.0,88.0,41.0,139.0,50.0,30.0,70.0,70.0,80.0,92.0" style="Table14">
2879+ <tr>
2880+ <td>
2881+ <para style="P3">[[ formatLang(line['date'], date=True) ]]</para>
2882+ </td>
2883+ <td>
2884+ <para style="P7">[[ line['code'] ]]</para>
2885+ </td>
2886+ <td>
2887+ <para style="P8">[[ line['move_name'] ]]</para>
2888+ </td>
2889+ <td>
2890+ <para style="P7">[[ line['a_code'] ]]</para>
2891+ </td>
2892+ <td>
2893+ <para style="P3">[[ format_entry_label('%s - %s' % (line['ref'] or '', line['name'] or ''), 29) ]]</para>
2894+ </td>
2895+ <td>
2896+ <para style="P3">[[ line['reconcile_txt'] or '' ]]</para>
2897+ </td>
2898+ <td>
2899+ <para style="P3">[[ line['currency_code'] or '' ]]</para>
2900+ </td>
2901+ <td>
2902+ <para style="P7">[[ formatLang(line['debit'] or 0.0) ]]</para>
2903+ </td>
2904+ <td>
2905+ <para style="P7">[[ formatLang(line['credit'] or 0.0) ]]</para>
2906+ </td>
2907+ <td>
2908+ <para style="P7">[[ (line['currency_id'] == None or line['amount_currency']==None) and removeParentNode('font') ]] [[ formatLang(line['amount_currency'] or 0.0) ]]</para>
2909+ </td>
2910+ <td>
2911+ <para style="P7">[[ formatLang(line['total_functional'] or 0.0) ]]</para>
2912+ </td>
2913+ </tr>
2914+ </blockTable>
2915+ <para style="terp_default_2">
2916+ <font color="white"> </font>
2917+ </para>
2918+ </section>
2919+ </section>
2920+ <para style="terp_default_2">
2921+ <font color="white"> </font>
2922+ </para>
2923+ </section>
2924+ </story>
2925+</document>
2926
2927=== modified file 'bin/addons/account/wizard/__init__.py'
2928--- bin/addons/account/wizard/__init__.py 2020-04-16 14:07:13 +0000
2929+++ bin/addons/account/wizard/__init__.py 2022-06-01 15:15:45 +0000
2930@@ -67,6 +67,7 @@
2931
2932 import free_allocation_wizard
2933 import account_invoice_import
2934+import account_report_common_employee
2935+import account_report_employee_balance
2936+import account_report_employee_ledger
2937 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
2938-
2939-
2940
2941=== added file 'bin/addons/account/wizard/account_report_common_employee.py'
2942--- bin/addons/account/wizard/account_report_common_employee.py 1970-01-01 00:00:00 +0000
2943+++ bin/addons/account/wizard/account_report_common_employee.py 2022-06-01 15:15:45 +0000
2944@@ -0,0 +1,86 @@
2945+# -*- coding: utf-8 -*-
2946+##############################################################################
2947+#
2948+# OpenERP, Open Source Management Solution
2949+# Copyright (C) 2022 TeMPO Consulting,MSF
2950+#
2951+# This program is free software: you can redistribute it and/or modify
2952+# it under the terms of the GNU Affero General Public License as
2953+# published by the Free Software Foundation, either version 3 of the
2954+# License, or (at your option) any later version.
2955+#
2956+# This program is distributed in the hope that it will be useful,
2957+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2958+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2959+# GNU Affero General Public License for more details.
2960+#
2961+# You should have received a copy of the GNU Affero General Public License
2962+# along with this program. If not, see <http://www.gnu.org/licenses/>.
2963+#
2964+##############################################################################
2965+
2966+from osv import osv, fields
2967+import pooler
2968+from tools.translate import _
2969+
2970+
2971+class account_common_employee_report(osv.osv_memory):
2972+ _name = 'account.common.employee.report'
2973+ _description = 'Account Common Employee Report'
2974+ _inherit = "account.common.partner.report"
2975+ _columns = {
2976+ 'result_selection': fields.selection([('customer', 'Receivable Accounts'),
2977+ ('supplier', 'Payable Accounts'),
2978+ ('customer_supplier', 'Receivable and Payable Accounts')],
2979+ "Employee's", required=True),
2980+ 'account_domain': fields.char('Account domain', size=250, required=False),
2981+ }
2982+
2983+ def onchange_result_selection(self, cr, uid, ids, result_selection, context=None):
2984+ """
2985+ Adapts the domain of the account according to the selections made by the user
2986+ Note: directly changing the domain on the many2many field "account_ids" doesn't work in that case so we use the
2987+ invisible field "account_domain" to store the domain and use it in the view...
2988+ """
2989+ if context is None:
2990+ context = {}
2991+ res = {}
2992+ if result_selection == 'supplier':
2993+ account_domain = [('type', 'in', ['payable'])]
2994+ elif result_selection == 'customer':
2995+ account_domain = [('type', 'in', ['receivable'])]
2996+ else:
2997+ account_domain = [('type', 'in', ['payable', 'receivable'])]
2998+ res['value'] = {'account_domain': '%s' % account_domain}
2999+ return res
3000+
3001+ def onchange_payment_method(self, cr, uid, ids, payment_method, context=None):
3002+ """
3003+ Exclude expatriate when one method of payment is chosen and only display Nat staff using this method of payment.
3004+ """
3005+ if context is None:
3006+ context = {}
3007+ res = {}
3008+ if payment_method and payment_method != 'blank':
3009+ res['value'] = {'employee_type': 'local'}
3010+ return res
3011+
3012+ def onchange_employee_type(self, cr, uid, ids, employee_type, context=None):
3013+ """
3014+ When expatriate is selected set method of payment to blank
3015+ """
3016+ if context is None:
3017+ context = {}
3018+ res = {}
3019+ if not employee_type or employee_type in ('', 'ex'):
3020+ res['value'] = {'payment_method': 'blank'}
3021+ return res
3022+
3023+ _defaults = {
3024+ 'result_selection': 'customer',
3025+ }
3026+
3027+
3028+account_common_employee_report()
3029+
3030+#vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
3031
3032=== added file 'bin/addons/account/wizard/account_report_employee_balance.py'
3033--- bin/addons/account/wizard/account_report_employee_balance.py 1970-01-01 00:00:00 +0000
3034+++ bin/addons/account/wizard/account_report_employee_balance.py 2022-06-01 15:15:45 +0000
3035@@ -0,0 +1,55 @@
3036+# -*- coding: utf-8 -*-
3037+##############################################################################
3038+#
3039+# OpenERP, Open Source Management Solution
3040+# Copyright (C) 2022 TeMPO Consulting, MSF
3041+#
3042+# This program is free software: you can redistribute it and/or modify
3043+# it under the terms of the GNU Affero General Public License as
3044+# published by the Free Software Foundation, either version 3 of the
3045+# License, or (at your option) any later version.
3046+#
3047+# This program is distributed in the hope that it will be useful,
3048+# but WITHOUT ANY WARRANTY; without even the implied warranty of
3049+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3050+# GNU Affero General Public License for more details.
3051+#
3052+# You should have received a copy of the GNU Affero General Public License
3053+# along with this program. If not, see <http://www.gnu.org/licenses/>.
3054+#
3055+##############################################################################
3056+
3057+from osv import fields, osv
3058+
3059+
3060+class account_employee_balance(osv.osv_memory):
3061+ """
3062+ This wizard will provide the employee balance report by periods, between any two dates.
3063+ """
3064+ _inherit = 'account.common.employee.report'
3065+ _name = 'account.employee.balance'
3066+ _description = 'Print Account Employee Balance'
3067+ _columns = {
3068+ 'display_employee': fields.selection([('non-zero_balance', 'With balance is not equal to 0'),
3069+ ('all', 'All Employees')], 'Display Employees'),
3070+ }
3071+
3072+ _defaults = {
3073+ 'display_employee': 'non-zero_balance',
3074+ }
3075+
3076+ def _print_report(self, cr, uid, ids, data, context=None):
3077+ if context is None:
3078+ context = {}
3079+ data = self.pre_print_report(cr, uid, ids, data, context=context)
3080+ data['form'].update(self.read(cr, uid, ids, ['display_employee'])[0])
3081+ return {
3082+ 'type': 'ir.actions.report.xml',
3083+ 'report_name': 'account.employee.balance',
3084+ 'datas': data,
3085+ }
3086+
3087+
3088+account_employee_balance()
3089+
3090+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
3091
3092=== added file 'bin/addons/account/wizard/account_report_employee_ledger.py'
3093--- bin/addons/account/wizard/account_report_employee_ledger.py 1970-01-01 00:00:00 +0000
3094+++ bin/addons/account/wizard/account_report_employee_ledger.py 2022-06-01 15:15:45 +0000
3095@@ -0,0 +1,127 @@
3096+# -*- coding: utf-8 -*-
3097+##############################################################################
3098+#
3099+# OpenERP, Open Source Management Solution
3100+# Copyright (C) 2022 TeMPO Consulting, MSF. All Rights Reserved
3101+#
3102+# This program is free software: you can redistribute it and/or modify
3103+# it under the terms of the GNU Affero General Public License as
3104+# published by the Free Software Foundation, either version 3 of the
3105+# License, or (at your option) any later version.
3106+#
3107+# This program is distributed in the hope that it will be useful,
3108+# but WITHOUT ANY WARRANTY; without even the implied warranty of
3109+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3110+# GNU Affero General Public License for more details.
3111+#
3112+# You should have received a copy of the GNU Affero General Public License
3113+# along with this program. If not, see <http://www.gnu.org/licenses/>.
3114+#
3115+##############################################################################
3116+
3117+from osv import fields, osv
3118+
3119+
3120+class account_employee_ledger(osv.osv_memory):
3121+ """
3122+ This wizard will provide the employee Ledger report by periods, between any two dates.
3123+ """
3124+ _name = 'account.employee.ledger'
3125+ _inherit = 'account.common.employee.report'
3126+ _description = 'Account Employee Ledger'
3127+
3128+ def get_payment_methods(self, cr, uid, context):
3129+ pm_obj = self.pool.get('hr.payment.method')
3130+ pm_ids = pm_obj.search(cr, uid, [], context=context)
3131+ pm_names = pm_obj.read(cr, uid, pm_ids, ['name'], context=context)
3132+ res = [('blank', '')]
3133+ res += [(pm_name['name'], pm_name['name']) for pm_name in pm_names]
3134+ return res
3135+
3136+ def get_employee_type(self, cr, uid, context):
3137+ return self.pool.get('hr.employee').fields_get(cr, uid, ['employee_type'], context=context)['employee_type']['selection']
3138+
3139+ _columns = {
3140+ 'reconciled': fields.selection([
3141+ ('empty', ''),
3142+ ('yes', 'Yes'),
3143+ ('no', 'No'),
3144+ ], string='Reconciled'),
3145+ 'page_split': fields.boolean('One Employee Per Page', help='Display Ledger Report with One employee per page (PDF version only)'),
3146+ 'employee_ids': fields.many2many('hr.employee', 'account_employee_ledger_employee_rel', 'wizard_id', 'identification_id', string='Employees',
3147+ help='Display the report for specific employees only'),
3148+ 'only_active_employees': fields.boolean('Only active employees', help='Display the report for active employees only'),
3149+ 'instance_ids': fields.many2many('msf.instance', 'account_employee_ledger_instance_rel', 'wizard_id', 'instance_id', string='Proprietary Instances',
3150+ help='Display the report for specific proprietary instances only'),
3151+ 'account_ids': fields.many2many('account.account', 'account_employee_ledger_account_rel', 'wizard_id', 'account_id', string='Accounts',
3152+ help='Display the report for specific accounts only'),
3153+ 'display_employee': fields.selection([('all', 'All Employees'), ('with_movements', 'With movements'),
3154+ ('non-zero_balance', 'With balance is not equal to 0')],
3155+ string='Display Employees', required=True),
3156+ 'employee_type': fields.selection(get_employee_type, string='Employee Type', required=False),
3157+ 'payment_method': fields.selection(get_payment_methods, string='Method of Payment', required=False),
3158+ }
3159+
3160+ _defaults = {
3161+ 'reconciled': 'empty',
3162+ 'page_split': False,
3163+ 'result_selection': 'customer_supplier',
3164+ 'account_domain': "[('type', 'in', ['payable', 'receivable'])]",
3165+ 'only_active_employees': False,
3166+ 'fiscalyear_id': False,
3167+ 'display_employee': 'with_movements',
3168+ 'employee_type': '',
3169+ 'payment_method': 'blank',
3170+ }
3171+
3172+ def _print_report(self, cr, uid, ids, data, context=None):
3173+ if context is None:
3174+ context = {}
3175+ data = self.pre_print_report(cr, uid, ids, data, context=context)
3176+ data['form'].update(self.read(cr, uid, ids, ['reconciled', 'page_split', 'employee_ids',
3177+ 'only_active_employees', 'instance_ids', 'account_ids',
3178+ 'display_employee', 'employee_type', 'payment_method'])[0])
3179+ if not data['form']['employee_type']:
3180+ data['form']['employee_type'] = ''
3181+ self._check_dates_fy_consistency(cr, uid, data, context)
3182+ if data['form']['page_split']:
3183+ return {
3184+ 'type': 'ir.actions.report.xml',
3185+ 'report_name': 'account.employee_ledger',
3186+ 'datas': data,
3187+ }
3188+ return {
3189+ 'type': 'ir.actions.report.xml',
3190+ 'report_name': 'account.employee_ledger_other',
3191+ 'datas': data,
3192+ }
3193+
3194+ def print_report_xls(self, cr, uid, ids, data, context=None):
3195+ if context is None:
3196+ context = {}
3197+ data = {'keep_open': 1, 'ids': context.get('active_ids', []),
3198+ 'model': context.get('active_model', 'ir.ui.menu'), 'form': self.read(cr, uid, ids,
3199+ ['date_from', 'date_to',
3200+ 'fiscalyear_id', 'journal_ids',
3201+ 'period_from', 'period_to',
3202+ 'filter', 'chart_account_id',
3203+ 'target_move'])[0]}
3204+ used_context = self._build_contexts(cr, uid, ids, data, context=context)
3205+ data['form']['periods'] = used_context.get('periods', False) and used_context['periods'] or []
3206+ data['form']['used_context'] = used_context
3207+
3208+ data = self.pre_print_report(cr, uid, ids, data, context=context)
3209+ data['form'].update(self.read(cr, uid, ids, ['reconciled', 'page_split', 'employee_ids',
3210+ 'only_active_employees', 'instance_ids', 'account_ids',
3211+ 'display_employee', 'employee_type', 'payment_method'])[0])
3212+ if not data['form']['employee_type']:
3213+ data['form']['employee_type'] = ''
3214+ self._check_dates_fy_consistency(cr, uid, data, context)
3215+ return {
3216+ 'type': 'ir.actions.report.xml',
3217+ 'report_name': 'account.employee_ledger_xls',
3218+ 'datas': data,
3219+ }
3220+
3221+
3222+account_employee_ledger()
3223
3224=== added file 'bin/addons/account/wizard/account_report_employee_ledger_view.xml'
3225--- bin/addons/account/wizard/account_report_employee_ledger_view.xml 1970-01-01 00:00:00 +0000
3226+++ bin/addons/account/wizard/account_report_employee_ledger_view.xml 2022-06-01 15:15:45 +0000
3227@@ -0,0 +1,85 @@
3228+<?xml version="1.0" encoding="utf-8"?>
3229+<openerp>
3230+ <data>
3231+
3232+ <record id="account_employee_ledger_view" model="ir.ui.view">
3233+ <field name="name">Employee Ledger</field>
3234+ <field name="model">account.employee.ledger</field>
3235+ <field name="type">form</field>
3236+ <field name="inherit_id" ref="account_common_report_view" />
3237+ <field name="arch" type="xml">
3238+ <data>
3239+ <xpath expr="/form/label[@string='']" position="replace">
3240+ <separator string="Employee Ledger" colspan="4"/>
3241+ <label nolabel="1" colspan="4" string="This report is an analysis done by employee. It is a report containing one line per employee representing the cumulative credit balance."/>
3242+ </xpath>
3243+ <xpath expr="//field[@name='target_move']" position="after">
3244+ <field name="result_selection" on_change="onchange_result_selection(result_selection)"/>
3245+ <field name="display_employee"/>
3246+ <field name="page_split"/>
3247+ <field name="reconciled"/>
3248+ <field name="only_active_employees"/>
3249+ <field name="employee_type" on_change="onchange_employee_type(employee_type)"/>
3250+ <field name="payment_method" on_change="onchange_payment_method(payment_method)"/>
3251+ <newline/>
3252+ <field name="instance_ids" domain="[('instance_to_display_ids','=',True)]">
3253+ <tree noteditable="1">
3254+ <field name="code"/>
3255+ <field name="name"/>
3256+ </tree>
3257+ </field>
3258+ <field name="employee_ids">
3259+ <tree noteditable="1">
3260+ <field name="name_resource"/>
3261+ <field name="identification_id"/>
3262+ <field name="employee_type"/>
3263+ </tree>
3264+ </field>
3265+ <field name="account_domain" invisible="1"/>
3266+ <field name="account_ids" domain="account_domain">
3267+ <tree noteditable="1">
3268+ <field name="code"/>
3269+ <field name="name"/>
3270+ </tree>
3271+ </field>
3272+ </xpath>
3273+ <xpath expr="//field[@name='fiscalyear_id']" position="attributes">
3274+ <attribute name="on_change">onchange_fiscalyear(fiscalyear_id)</attribute>
3275+ </xpath>
3276+ <xpath expr="//field[@name='period_from']" position="attributes">
3277+ <attribute name="domain">[]</attribute>
3278+ </xpath>
3279+ <xpath expr="//field[@name='period_to']" position="attributes">
3280+ <attribute name="domain">[]</attribute>
3281+ </xpath>
3282+ <xpath expr="//group[1]" position="replace">
3283+ <group col="4" colspan="4">
3284+ <button icon="gtk-print" name="check_report" string="Print PDF" type="object" colspan="2" default_focus="1" />
3285+ <button icon="gtk-print" name="print_report_xls" string="Print Excel" type="object" colspan="2" />
3286+ <button icon="gtk-cancel" special="cancel" string="Cancel" colspan="4"/>
3287+ </group>
3288+ </xpath>
3289+ </data>
3290+ </field>
3291+ </record>
3292+
3293+ <record id="action_account_employee_ledger" model="ir.actions.act_window">
3294+ <field name="name">Employee Ledger</field>
3295+ <field name="res_model">account.employee.ledger</field>
3296+ <field name="type">ir.actions.act_window</field>
3297+ <field name="view_type">form</field>
3298+ <field name="view_mode">form</field>
3299+ <field name="view_id" ref="account_employee_ledger_view"/>
3300+ <field name="context">{'record_id':active_id}</field>
3301+ <field name="target">new</field>
3302+ </record>
3303+
3304+ <menuitem icon="STOCK_PRINT"
3305+ name="Employee Ledger"
3306+ action="action_account_employee_ledger"
3307+ id="menu_account_employee_ledger"
3308+ parent="account.employee_menu"
3309+ sequence="1999" />
3310+
3311+ </data>
3312+ </openerp>
3313
3314=== modified file 'bin/addons/finance/__openerp__.py'
3315--- bin/addons/finance/__openerp__.py 2020-12-14 16:46:05 +0000
3316+++ bin/addons/finance/__openerp__.py 2022-06-01 15:15:45 +0000
3317@@ -42,6 +42,7 @@
3318 'wizard/fo_follow_up_finance_wizard_view.xml',
3319 'cash_request_data.xml',
3320 'cash_request_view.xml',
3321+ 'wizard/account_report_employee_balance_tree_view.xml', # US-6392
3322 ],
3323 'test': [],
3324 'installable': True,
3325
3326=== modified file 'bin/addons/finance/account_view.xml'
3327--- bin/addons/finance/account_view.xml 2022-04-28 08:30:46 +0000
3328+++ bin/addons/finance/account_view.xml 2022-06-01 15:15:45 +0000
3329@@ -143,9 +143,19 @@
3330 model="account.partner.balance.tree"
3331 name="account.partner.balance.tree_xls"
3332 file="finance/report/account_partner_balance_tree_xls.mako"
3333- report_type="webkit"
3334+ report_type="webkit"
3335 string="Partner Balance"/>
3336
3337+ <report id="account_employee_balance_tree_xls"
3338+ auto="False"
3339+ menu="False"
3340+ header="False"
3341+ model="account.employee.balance.tree"
3342+ name="account.employee.balance.tree_xls"
3343+ file="finance/report/account_employee_balance_tree_xls.mako"
3344+ report_type="webkit"
3345+ string="Employee Balance"/>
3346+
3347 <record id="account.action_account_moves_all_a" model="ir.actions.act_window">
3348 <field name="context">{'search_default_posted': 1, 'target_filename_prefix': 'Journal Items'}</field>
3349 </record>
3350
3351=== modified file 'bin/addons/finance/report/__init__.py'
3352--- bin/addons/finance/report/__init__.py 2020-12-15 14:17:25 +0000
3353+++ bin/addons/finance/report/__init__.py 2022-06-01 15:15:45 +0000
3354@@ -2,3 +2,4 @@
3355 import account_report_name
3356 import cash_request_parser
3357 import fo_follow_up_finance
3358+import account_employee_balance_tree
3359
3360=== added file 'bin/addons/finance/report/account_employee_balance_tree.py'
3361--- bin/addons/finance/report/account_employee_balance_tree.py 1970-01-01 00:00:00 +0000
3362+++ bin/addons/finance/report/account_employee_balance_tree.py 2022-06-01 15:15:45 +0000
3363@@ -0,0 +1,311 @@
3364+# -*- coding: utf-8 -*-
3365+##############################################################################
3366+#
3367+# OpenERP, Open Source Management Solution
3368+# Copyright (C) 2022 TeMPO Consulting
3369+#
3370+# This program is free software: you can redistribute it and/or modify
3371+# it under the terms of the GNU Affero General Public License as
3372+# published by the Free Software Foundation, either version 3 of the
3373+# License, or (at your option) any later version.
3374+#
3375+# This program is distributed in the hope that it will be useful,
3376+# but WITHOUT ANY WARRANTY; without even the implied warranty of
3377+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3378+# GNU Affero General Public License for more details.
3379+#
3380+# You should have received a copy of the GNU Affero General Public License
3381+# along with this program. If not, see <http://www.gnu.org/licenses/>.
3382+#
3383+##############################################################################
3384+
3385+from tools.translate import _
3386+from report import report_sxw
3387+from spreadsheet_xml.spreadsheet_xml_write import SpreadsheetReport
3388+import pooler
3389+
3390+
3391+class account_employee_balance_tree(report_sxw.rml_parse):
3392+
3393+ def __init__(self, cr, uid, name, context=None):
3394+ super(account_employee_balance_tree, self).__init__(cr, uid, name, context=context)
3395+ self.aebt_obj = self.pool.get('account.employee.balance.tree')
3396+ self.uid = uid
3397+ self.has_data = True
3398+ self.localcontext.update({
3399+ # header
3400+ 'get_account': self._get_account,
3401+ 'get_fiscalyear': self._get_fiscalyear,
3402+ 'get_journals_str': self._get_journals_str,
3403+ 'get_filter': self._get_filter,
3404+ 'get_filter_info': self._get_filter_info,
3405+ 'get_start_date':self._get_start_date,
3406+ 'get_end_date':self._get_end_date,
3407+ 'get_start_period': self.get_start_period,
3408+ 'get_end_period': self.get_end_period,
3409+ 'get_target_move': self._get_target_move,
3410+ 'get_prop_instances_str': self._get_prop_instances_str,
3411+ 'get_type_of_accounts': self._get_type_of_accounts,
3412+ 'get_accounts_str': self._get_accounts_str,
3413+ 'get_reconcile_selection': self._get_reconcile_selection,
3414+ 'get_display_employees_selection': self._get_display_employees_selection,
3415+ 'get_employee_type': self._get_employee_type,
3416+ 'get_payment_methods': self._get_payment_methods,
3417+
3418+ # data
3419+ 'get_employees': self._get_employees,
3420+ 'get_employee_account_move_lines': self._get_employee_account_move_lines,
3421+ 'get_lines_per_currency': self._get_lines_per_currency,
3422+ 'get_employees_total_debit_credit_balance': self._get_employees_total_debit_credit_balance,
3423+ 'get_has_data': self._get_has_data,
3424+ })
3425+
3426+ def set_context(self, objects, data, ids, report_type=None):
3427+ self.display_employee = data['form'].get('display_employee', 'non-zero_balance')
3428+ self.result_selection = data['form'].get('result_selection')
3429+ self.target_move = data['form'].get('target_move', 'all')
3430+ return super(account_employee_balance_tree, self).set_context(objects, data, ids, report_type=report_type)
3431+
3432+ def _get_employee_type(self, data):
3433+ """
3434+ Returns the String to display in the "Employee Type" section of the report header
3435+ """
3436+ emp_type = _('All')
3437+ # if specific employees are selected don't display emp type
3438+ if data['form'].get('employee_ids', False):
3439+ emp_type = '-'
3440+ else:
3441+ emp = data['form'].get('employee_type', False)
3442+ if emp == 'local':
3443+ emp_type = _('Local Staff')
3444+ if emp == 'ex':
3445+ emp_type = _('Expatriate Staff')
3446+ return emp_type
3447+
3448+ def _get_payment_methods(self, data):
3449+ """
3450+ Returns the String to display in the "Payment Method" section of the report header
3451+ """
3452+ pay_method = _('All')
3453+ # if specific employees are selected don't display payment method
3454+ if data['form'].get('employee_ids', False):
3455+ pay_method = '-'
3456+ else:
3457+ method = data['form'].get('payment_method')
3458+ if method != 'blank':
3459+ return method
3460+ return pay_method
3461+
3462+ def _get_type_of_accounts(self):
3463+ if self.result_selection == 'customer':
3464+ return _('Receivable Accounts')
3465+ elif self.result_selection == 'supplier':
3466+ return _('Payable Accounts')
3467+ elif self.result_selection == 'customer_supplier':
3468+ return _('Receivable and Payable Accounts')
3469+ return ''
3470+
3471+ def _get_has_data(self):
3472+ """
3473+ Returns True if there is data to display in the report
3474+ """
3475+ return bool(self.has_data)
3476+
3477+ def _get_employees(self, data):
3478+ """ return a list of 1 or 2 elements each element containing browse objects
3479+ only [payable] or only [receivable] or [payable, receivable]
3480+ """
3481+ res = []
3482+ objects = self.aebt_obj.get_employee_data(self.cr, self.uid, data)
3483+ if objects:
3484+ res.append(objects)
3485+ self.has_data = len(res)
3486+ return res
3487+
3488+ def _get_reconcile_selection(self, data):
3489+ """
3490+ Returns "Yes" if "Reconciled: Yes" is selected in the wizard
3491+ """
3492+ selection = _('All')
3493+ if data['form'].get('reconciled', '') == 'yes':
3494+ selection = _('Yes')
3495+ elif data['form'].get('reconciled', '') == 'no':
3496+ selection = _('No')
3497+ return selection
3498+
3499+ def _get_display_employees_selection(self, data):
3500+ """
3501+ Returns the String to display in the "Display Employees" section of the report header
3502+ """
3503+ selection = ''
3504+ display_employee = data['form'].get('display_employee', '')
3505+ if display_employee == 'all':
3506+ selection = _('All Employees')
3507+ elif display_employee == 'with_movements':
3508+ selection = _('With movements')
3509+ elif display_employee == 'non-zero_balance':
3510+ selection = _('With balance is not equal to 0')
3511+ return selection
3512+
3513+ def _get_employee_account_move_lines(self, employee_id, data):
3514+ return self.aebt_obj.get_employee_account_move_lines_data(self.cr, self.uid, employee_id, data)
3515+
3516+ def _get_lines_per_currency(self, employee_id, data, account_code):
3517+ return self.aebt_obj.get_lines_per_currency(self.cr, self.uid, employee_id, data, account_code)
3518+
3519+ def _get_employees_total_debit_credit_balance(self, data):
3520+ return self.aebt_obj.get_employees_total_debit_credit_balance(self.cr, self.uid, data)
3521+
3522+ def _get_filter_info(self, data):
3523+ """ get filter info
3524+ _get_filter, _get_start_date, _get_end_date,
3525+ get_start_period, get_end_period
3526+ are from common_report_header
3527+ """
3528+ res = ''
3529+ f = self._get_filter(data)
3530+ if not f:
3531+ return res
3532+
3533+ if f == _('No Filter'):
3534+ res = f
3535+ elif f == _('Date'):
3536+ res = self.formatLang(self._get_start_date(data), date=True) + ' - ' + self.formatLang(self._get_end_date(data), date=True)
3537+ elif f == _('Periods'):
3538+ res = self.get_start_period(data) + ' - ' + self.get_end_period(data)
3539+ return res
3540+
3541+ def _get_start_date(self, data):
3542+ if data.get('form', False) and data['form'].get('date_from', False):
3543+ return data['form']['date_from']
3544+ return ''
3545+
3546+ def _get_target_move(self, data):
3547+ if data.get('form', False) and data['form'].get('target_move', False):
3548+ if data['form']['target_move'] == 'all':
3549+ return _('All Entries')
3550+ return _('All Posted Entries')
3551+ return ''
3552+
3553+ def _get_end_date(self, data):
3554+ if data.get('form', False) and data['form'].get('date_to', False):
3555+ return data['form']['date_to']
3556+ return ''
3557+
3558+ def get_start_period(self, data):
3559+ if data.get('form', False) and data['form'].get('period_from', False):
3560+ return self.pool.get('account.period').browse(self.cr,self.uid,data['form']['period_from']).name
3561+ return ''
3562+
3563+ def get_end_period(self, data):
3564+ if data.get('form', False) and data['form'].get('period_to', False):
3565+ return self.pool.get('account.period').browse(self.cr, self.uid, data['form']['period_to']).name
3566+ return ''
3567+
3568+ def _get_account(self, data):
3569+ if data.get('form', False) and data['form'].get('chart_account_id', False):
3570+ return self.pool.get('account.account').browse(self.cr, self.uid, data['form']['chart_account_id']).name
3571+ return ''
3572+
3573+ def _get_accounts(self, data):
3574+ """
3575+ Returns:
3576+ - "All Accounts" if no specific account is selected
3577+ - or the codes of all accounts selected
3578+ """
3579+ account_ids = data.get('form', False) and data['form'].get('account_ids', False)
3580+ if account_ids:
3581+ account_obj = pooler.get_pool(self.cr.dbname).get('account.account')
3582+ return [i.code for i in account_obj.browse(self.cr, self.uid, account_ids,
3583+ fields_to_fetch=['code'], context=data.get('context', {}))]
3584+ return [_('All Accounts')]
3585+
3586+ def _get_accounts_str(self, data):
3587+ """
3588+ Returns the list of accounts as a String (cut if > 300 characters)
3589+ """
3590+ data_tools_obj = self.pool.get('data.tools')
3591+ return data_tools_obj.truncate_list(self._get_accounts(data))
3592+
3593+ def _get_filter(self, data):
3594+ if data.get('form', False) and data['form'].get('filter', False):
3595+ if data['form']['filter'] == 'filter_date':
3596+ return _('Date')
3597+ elif data['form']['filter'] == 'filter_period':
3598+ return _('Periods')
3599+ return _('No Filter')
3600+
3601+ def _get_fiscalyear(self, data):
3602+ if data.get('form', False) and data['form'].get('fiscalyear_id', False):
3603+ return self.pool.get('account.fiscalyear').browse(self.cr, self.uid, data['form']['fiscalyear_id']).name
3604+ return ''
3605+
3606+ def _get_company(self, data):
3607+ if data.get('form', False) and data['form'].get('chart_account_id', False):
3608+ return self.pool.get.get('account.account').browse(self.cr, self.uid, data['form']['chart_account_id']).company_id.name
3609+ return ''
3610+
3611+ def _get_journal(self, data):
3612+ """
3613+ Returns the codes of the journals selected (or "All Journals")
3614+ """
3615+ if data.get('form', False) and 'all_journals' in data['form']:
3616+ return [_('All Journals')]
3617+ codes = []
3618+ if data.get('form', False) and data['form'].get('journal_ids', False):
3619+ self.cr.execute('select distinct(code) from account_journal where id IN %s', (tuple(data['form']['journal_ids']),))
3620+ codes = [x for x, in self.cr.fetchall()]
3621+ return codes
3622+
3623+ def _get_journals_str(self, data):
3624+ """
3625+ Returns the list of journals as a String (cut if > 300 characters)
3626+ """
3627+ data_tools_obj = self.pool.get('data.tools')
3628+ return data_tools_obj.truncate_list(self._get_journal(data))
3629+
3630+ def _get_prop_instances(self, data):
3631+ """
3632+ Returns the codes of the instances selected (or "All Instances")
3633+ """
3634+ if data.get('form', False) and data['form'].get('instance_ids', False):
3635+ self.cr.execute('select code from msf_instance where id IN %s',(tuple(data['form']['instance_ids']),))
3636+ return [lt or '' for lt, in self.cr.fetchall()]
3637+ return [_('All Instances')]
3638+
3639+ def _get_prop_instances_str(self, data, pdf=False):
3640+ """
3641+ Returns the list of instances as a String (cut if > 300 characters)
3642+ """
3643+ display_limit = 300
3644+ if pdf:
3645+ # in the PDF version instances are listed one below the other and instance names are cut if > 20 characters
3646+ instances_str = ',\n'.join([(len(inst) <= 20) and inst or ("%s%s" % (inst[:17], '...'))
3647+ for inst in self._get_prop_instances(data)])
3648+ if len(instances_str) > display_limit:
3649+ instances_str = "%s%s" % (instances_str[:display_limit-3], '...')
3650+ else:
3651+ # otherwise instances are simply separated by a comma
3652+ data_tools_obj = self.pool.get('data.tools')
3653+ instances_str = data_tools_obj.truncate_list(self._get_prop_instances(data), limit=display_limit)
3654+ return instances_str
3655+
3656+
3657+class account_employee_balance_tree_xls(SpreadsheetReport):
3658+ def __init__(self, name, table, rml=False, parser=report_sxw.rml_parse, header='external', store=False):
3659+ super(account_employee_balance_tree_xls, self).__init__(name, table, rml=rml, parser=parser, header=header, store=store)
3660+
3661+ def create(self, cr, uid, ids, data, context=None):
3662+ a = super(account_employee_balance_tree_xls, self).create(cr, uid, ids, data, context)
3663+ return (a[0], 'xls')
3664+
3665+
3666+# XLS report
3667+account_employee_balance_tree_xls('report.account.employee.balance.tree_xls', 'account.employee.balance.tree',
3668+ 'finance/report/account_employee_balance_tree_xls.mako',
3669+ parser=account_employee_balance_tree, header='internal')
3670+# PDF report
3671+report_sxw.report_sxw('report.account.employee.balance', 'hr.employee', 'account/report/account_employee_balance.rml',
3672+ parser=account_employee_balance_tree, header='internal')
3673+
3674+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
3675
3676=== added file 'bin/addons/finance/report/account_employee_balance_tree_xls.mako'
3677--- bin/addons/finance/report/account_employee_balance_tree_xls.mako 1970-01-01 00:00:00 +0000
3678+++ bin/addons/finance/report/account_employee_balance_tree_xls.mako 2022-06-01 15:15:45 +0000
3679@@ -0,0 +1,530 @@
3680+<?xml version="1.0"?>
3681+<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
3682+xmlns:o="urn:schemas-microsoft-com:office:office"
3683+xmlns:x="urn:schemas-microsoft-com:office:excel"
3684+xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
3685+xmlns:html="http://www.w3.org/TR/REC-html40">
3686+<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">
3687+<Title>Employee</Title>
3688+</DocumentProperties>
3689+<Styles>
3690+<Style ss:ID="ssCell">
3691+<Alignment ss:Vertical="Top" ss:WrapText="1"/>
3692+</Style>
3693+<Style ss:ID="ssCellRight">
3694+<Alignment ss:Horizontal="Right" ss:Vertical="Top" ss:WrapText="1"/>
3695+</Style>
3696+<Style ss:ID="ssCellRightBold">
3697+<Alignment ss:Horizontal="Right" ss:Vertical="Top" ss:WrapText="1"/>
3698+<Font ss:Bold="1" />
3699+</Style>
3700+<Style ss:ID="ssH">
3701+<Alignment ss:Horizontal="Center" ss:Vertical="Center" ss:WrapText="1"/>
3702+<Font ss:Bold="1" />
3703+<Borders>
3704+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" />
3705+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
3706+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
3707+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" />
3708+</Borders>
3709+</Style>
3710+<Style ss:ID="ssBorder">
3711+<Alignment ss:Vertical="Center" ss:WrapText="1"/>
3712+<Borders>
3713+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" />
3714+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
3715+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
3716+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" />
3717+</Borders>
3718+</Style>
3719+<Style ss:ID="ssBorderTop">
3720+<Borders>
3721+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" />
3722+</Borders>
3723+</Style>
3724+<Style ss:ID="ssBorderDate">
3725+<Alignment ss:Vertical="Center" ss:WrapText="1"/>
3726+<Borders>
3727+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" />
3728+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
3729+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
3730+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" />
3731+</Borders>
3732+<NumberFormat ss:Format="Short Date" />
3733+</Style>
3734+<Style ss:ID="ssNumber">
3735+<Borders>
3736+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" />
3737+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
3738+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
3739+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" />
3740+</Borders>
3741+<Alignment ss:Horizontal="Right" ss:Vertical="Center" ss:WrapText="1"/>
3742+<NumberFormat ss:Format="#,##0.00"/>
3743+</Style>
3744+<Style ss:ID="ssHeader">
3745+<Alignment ss:Vertical="Top" ss:Horizontal="Center" ss:WrapText="1"/>
3746+<Font ss:Bold="1" />
3747+<Borders>
3748+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" />
3749+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
3750+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
3751+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" />
3752+</Borders>
3753+</Style>
3754+<Style ss:ID="ssHeaderNumber">
3755+<Font ss:Bold="1" />
3756+<Alignment ss:Horizontal="Right" ss:Vertical="Top" ss:WrapText="1"/>
3757+<Borders>
3758+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" />
3759+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
3760+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
3761+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" />
3762+</Borders>
3763+<NumberFormat ss:Format="#,##0.00"/>
3764+</Style>
3765+<Style ss:ID="ssHeaderRight">
3766+<Font ss:Bold="1" />
3767+<Alignment ss:Horizontal="Right" ss:Vertical="Top" ss:WrapText="1"/>
3768+<Borders>
3769+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" />
3770+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
3771+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
3772+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" />
3773+</Borders>
3774+</Style>
3775+<Style ss:ID="ssHeaderCell">
3776+<Alignment ss:Vertical="Top" ss:Horizontal="Center" ss:WrapText="1"/>
3777+<Borders>
3778+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" />
3779+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
3780+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
3781+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" />
3782+</Borders>
3783+</Style>
3784+<Style ss:ID="ssHeaderNumberCell">
3785+<Alignment ss:Horizontal="Right" ss:Vertical="Top" ss:WrapText="1"/>
3786+<Borders>
3787+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" />
3788+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
3789+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
3790+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" />
3791+</Borders>
3792+<NumberFormat ss:Format="#,##0.00"/>
3793+</Style>
3794+<Style ss:ID="ssEmployee">
3795+<Alignment ss:Vertical="Top" ss:WrapText="1"/>
3796+<Font ss:Bold="1" />
3797+<Borders>
3798+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" />
3799+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
3800+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
3801+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" />
3802+</Borders>
3803+</Style>
3804+<Style ss:ID="ssEmployeeNumber">
3805+<Font ss:Bold="1" />
3806+<Alignment ss:Horizontal="Right" ss:Vertical="Top" ss:WrapText="1"/>
3807+<Borders>
3808+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" />
3809+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
3810+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
3811+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" />
3812+</Borders>
3813+<NumberFormat ss:Format="#,##0.00"/>
3814+</Style>
3815+<Style ss:ID="ssEmployeeRight">
3816+<Font ss:Bold="1" />
3817+<Alignment ss:Horizontal="Right" ss:Vertical="Top" ss:WrapText="1"/>
3818+<Borders>
3819+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" />
3820+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
3821+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
3822+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" />
3823+</Borders>
3824+</Style>
3825+<Style ss:ID="ssAccountLine">
3826+<Alignment ss:Vertical="Top" ss:Horizontal="Left" ss:WrapText="1"/>
3827+<Font ss:Size="8"/>
3828+<Borders>
3829+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" />
3830+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
3831+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
3832+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" />
3833+</Borders>
3834+</Style>
3835+<Style ss:ID="ssAccountLineRight">
3836+<Alignment ss:Vertical="Top" ss:Horizontal="Right" ss:WrapText="1"/>
3837+<Font ss:Size="8"/>
3838+<Borders>
3839+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" />
3840+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
3841+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
3842+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" />
3843+</Borders>
3844+</Style>
3845+<Style ss:ID="ssSubtotalLine">
3846+<Alignment ss:Vertical="Top" ss:Horizontal="Right" ss:WrapText="1"/>
3847+<Font ss:FontName="Calibri" x:Family="Swiss" ss:Size="11"/>
3848+<Borders>
3849+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
3850+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
3851+</Borders>
3852+</Style>
3853+<Style ss:ID="ssAccountLineWrap">
3854+ <Alignment ss:Horizontal="Left" ss:Vertical="Center" ss:WrapText="1"/>
3855+ <Borders>
3856+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>
3857+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1"/>
3858+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1"/>
3859+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>
3860+ </Borders>
3861+ <Font ss:Size="8"/>
3862+ <Interior/>
3863+ <NumberFormat/>
3864+ <Protection/>
3865+</Style>
3866+<Style ss:ID="ssAccountLineNumber">
3867+<Alignment ss:Horizontal="Right" ss:Vertical="Top" ss:WrapText="1"/>
3868+<Font ss:Size="8"/>
3869+<Borders>
3870+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" />
3871+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
3872+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
3873+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" />
3874+</Borders>
3875+<NumberFormat ss:Format="#,##0.00"/>
3876+</Style>
3877+<Style ss:ID="ssAccountLineNumberBold">
3878+<Alignment ss:Horizontal="Right" ss:Vertical="Top" ss:WrapText="1"/>
3879+<Font ss:Size="8" ss:Bold="1"/>
3880+<Borders>
3881+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" />
3882+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
3883+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
3884+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" />
3885+</Borders>
3886+<NumberFormat ss:Format="#,##0.00"/>
3887+</Style>
3888+<Style ss:ID="ssSubtotalLineNumber">
3889+<Alignment ss:Horizontal="Right" ss:Vertical="Top" ss:WrapText="1"/>
3890+<Font ss:FontName="Calibri" x:Family="Swiss" ss:Size="11"/>
3891+<Borders>
3892+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
3893+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
3894+</Borders>
3895+<NumberFormat ss:Format="#,##0.00"/>
3896+</Style>
3897+<Style ss:ID="ssAccountLineAccountCode">
3898+<Alignment ss:Horizontal="Right" ss:Vertical="Top" ss:WrapText="1"/>
3899+<Font ss:Size="8"/>
3900+<Borders>
3901+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" />
3902+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
3903+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
3904+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" />
3905+</Borders>
3906+<Interior/>
3907+<NumberFormat ss:Format="0" />
3908+<Protection/>
3909+</Style>
3910+<Style ss:ID="ssAccountLineAccountCodeBold">
3911+<Alignment ss:Horizontal="Right" ss:Vertical="Top" ss:WrapText="1"/>
3912+<Font ss:Size="8" ss:Bold="1"/>
3913+<Borders>
3914+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" />
3915+ <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1" />
3916+ <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1" />
3917+ <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1" />
3918+</Borders>
3919+<Interior/>
3920+<NumberFormat ss:Format="0" />
3921+<Protection/>
3922+</Style>
3923+</Styles>
3924+<%
3925+entries = get_employees(data)
3926+%>
3927+% if not entries:
3928+<Worksheet ss:Name="No entries">
3929+<Table x:FullColumns="1" x:FullRows="1">
3930+ <Column ss:AutoFitWidth="1" ss:Width="300" />
3931+ <Row>
3932+ <Cell ss:StyleID="ssHeader"><Data ss:Type="String">No entries</Data></Cell>
3933+ </Row>
3934+</Table>
3935+</Worksheet>
3936+% else:
3937+% for p_entries in entries:
3938+<%
3939+worksheet_name = get_type_of_accounts()
3940+%>
3941+<Worksheet ss:Name="${worksheet_name}">
3942+<%
3943+ col_count = 9
3944+ if data['model'] == 'account.account':
3945+ header_company_or_chart_of_account = _('Company')
3946+ else:
3947+ header_company_or_chart_of_account = _('Chart of Account')
3948+%>
3949+<Table x:FullColumns="1" x:FullRows="1">
3950+<Column ss:AutoFitWidth="1" ss:Width="150" />
3951+<Column ss:AutoFitWidth="1" ss:Width="60" />
3952+<Column ss:AutoFitWidth="1" ss:Width="120" />
3953+<Column ss:AutoFitWidth="1" ss:Width="120" />
3954+<Column ss:AutoFitWidth="1" ss:Width="120" />
3955+<Column ss:AutoFitWidth="1" ss:Width="100" />
3956+<Column ss:AutoFitWidth="1" ss:Width="100" />
3957+<Column ss:AutoFitWidth="1" ss:Width="100" />
3958+<Column ss:AutoFitWidth="1" ss:Width="100" />
3959+## header
3960+<%
3961+header_col_merge_count = col_count - 1
3962+selected_filter = get_filter(data) or ''
3963+%>
3964+<Row>
3965+ <Cell ss:StyleID="ssHeader"><Data ss:Type="String">${header_company_or_chart_of_account}</Data></Cell>
3966+ <Cell ss:StyleID="ssHeader"><Data ss:Type="String">${_('Fiscal Year')}</Data></Cell>
3967+ <Cell ss:StyleID="ssHeader"><Data ss:Type="String">${_('Journals')}</Data></Cell>
3968+ <Cell ss:StyleID="ssHeader"><Data ss:Type="String">${_('Accounts')}</Data></Cell>
3969+ <Cell ss:StyleID="ssHeader"><Data ss:Type="String">${_('Proprietary Instances')}</Data></Cell>
3970+ <Cell ss:StyleID="ssHeader"><Data ss:Type="String">${'%s %s' % (_('Filter By'), (selected_filter != _('No Filter') and selected_filter or ''))|x}</Data></Cell>
3971+ <Cell ss:StyleID="ssHeader" ss:MergeAcross="1"><Data ss:Type="String">${_('Display')}</Data></Cell>
3972+ <Cell ss:StyleID="ssHeader"><Data ss:Type="String">${_('Func. Currency')}</Data></Cell>
3973+</Row>
3974+<Row>
3975+ <Cell ss:StyleID="ssHeaderCell">
3976+ <Data ss:Type="String">${(get_account(data) or '')|x}</Data>
3977+ </Cell>
3978+ <Cell ss:StyleID="ssHeaderCell">
3979+ <Data ss:Type="String">${(get_fiscalyear(data) or '')|x}</Data>
3980+ </Cell>
3981+ <Cell ss:StyleID="ssHeaderCell">
3982+ <Data ss:Type="String">${ get_journals_str(data)|x}</Data>
3983+ </Cell>
3984+ <Cell ss:StyleID="ssHeaderCell">
3985+ <Data ss:Type="String">${ get_accounts_str(data)|x}</Data>
3986+ </Cell>
3987+ <Cell ss:StyleID="ssHeaderCell">
3988+ <Data ss:Type="String">${ get_prop_instances_str(data)|x}</Data>
3989+ </Cell>
3990+ <Cell ss:StyleID="ssHeaderCell">
3991+ <Data ss:Type="String">${(get_filter_info(data) or '')|x}</Data>
3992+ </Cell>
3993+ <Cell ss:StyleID="ssHeaderCell" ss:MergeAcross="1">
3994+ <Data ss:Type="String">${ "%s: %s, %s: %s, %s: %s, %s: %s, %s: %s, %s: %s" % (
3995+ _("Employee's"), get_type_of_accounts() or '',
3996+ _('Target Moves'), get_target_move(data) or '',
3997+ _('Reconciled'), get_reconcile_selection(data),
3998+ _('Display Employees'), get_display_employees_selection(data),
3999+ _('Employee Type'), get_employee_type(data) or '-',
4000+ _('Payment Method'), get_payment_methods(data) or '-',
4001+ )|x}</Data>
4002+ </Cell>
4003+ <Cell ss:StyleID="ssHeaderCell">
4004+ <Data ss:Type="String">${company.currency_id.name|x}</Data>
4005+ </Cell>
4006+</Row>
4007+## separation line after header
4008+<Row>
4009+% for n in range(col_count):
4010+<Cell ss:StyleID="ssCell">
4011+ <Data ss:Type="String"></Data>
4012+</Cell>
4013+% endfor
4014+</Row>
4015+## employee header
4016+<Row>
4017+<Cell ss:StyleID="ssHeader" ss:MergeAcross="2">
4018+ <Data ss:Type="String">${_('Employee')}</Data>
4019+</Cell>
4020+<Cell ss:StyleID="ssHeaderRight">
4021+ <Data ss:Type="String">${_('Account')}</Data>
4022+</Cell>
4023+<Cell ss:StyleID="ssHeaderRight">
4024+ <Data ss:Type="String">${_('Currency')}</Data>
4025+</Cell>
4026+<Cell ss:StyleID="ssHeaderRight">
4027+ <Data ss:Type="String">${_('Debit')}</Data>
4028+</Cell>
4029+<Cell ss:StyleID="ssHeaderRight">
4030+ <Data ss:Type="String">${_('Credit')}</Data>
4031+</Cell>
4032+<Cell ss:StyleID="ssHeaderRight">
4033+ <Data ss:Type="String">${_('Booking Balance')}</Data>
4034+</Cell>
4035+<Cell ss:StyleID="ssHeaderRight">
4036+ <Data ss:Type="String">${'%s %s' % (_('Balance'), company.currency_id.name)|x}</Data>
4037+</Cell>
4038+</Row>
4039+
4040+<Row>
4041+## total debit / credit / balance row
4042+<%
4043+debit, credit, balance = get_employees_total_debit_credit_balance(data)
4044+%>
4045+<Cell ss:StyleID="ssCellRightBold" ss:MergeAcross="3">
4046+ <Data ss:Type="String">${_('TOTAL EMPLOYEES')}</Data>
4047+</Cell>
4048+<Cell ss:StyleID="ssEmployeeRight">
4049+ <Data ss:Type="String">${company.currency_id.name|x}</Data>
4050+</Cell>
4051+<Cell ss:StyleID="ssHeaderNumber">
4052+ <Data ss:Type="Number">${debit or 0.|x}</Data>
4053+</Cell>
4054+<Cell ss:StyleID="ssHeaderNumber">
4055+ <Data ss:Type="Number">${credit or 0.|x}</Data>
4056+</Cell>
4057+<Cell ss:StyleID="ssHeaderNumber">
4058+ <Data ss:Type="String">-</Data>
4059+</Cell>
4060+<Cell ss:StyleID="ssHeaderNumber">
4061+ <Data ss:Type="Number">${balance or 0.|x}</Data>
4062+</Cell>
4063+</Row>
4064+
4065+## employee row
4066+% for p_obj in p_entries:
4067+<%
4068+employee_name = (p_obj.name or '')
4069+%>
4070+<Row>
4071+<Cell ss:StyleID="ssEmployee" ss:MergeAcross="3">
4072+ <Data ss:Type="String">${employee_name|x}</Data>
4073+</Cell>
4074+<Cell ss:StyleID="ssEmployeeRight">
4075+ <Data ss:Type="String">${company.currency_id.name|x}</Data>
4076+</Cell>
4077+<Cell ss:StyleID="ssEmployeeNumber">
4078+ <Data ss:Type="Number">${p_obj.debit or 0.|x}</Data>
4079+</Cell>
4080+<Cell ss:StyleID="ssEmployeeNumber">
4081+ <Data ss:Type="Number">${p_obj.credit or 0.|x}</Data>
4082+</Cell>
4083+ <Cell ss:StyleID="ssEmployeeNumber">
4084+ <Data ss:Type="Number">${p_obj.balance or 0.|x}</Data>
4085+</Cell>
4086+<Cell ss:StyleID="ssEmployeeNumber">
4087+ <Data ss:Type="Number">${p_obj.balance or 0.|x}</Data>
4088+</Cell>
4089+</Row>
4090+
4091+## account move line row
4092+% for aml in get_employee_account_move_lines(p_obj.employee_id.id, data):
4093+<Row>
4094+<Cell ss:StyleID="ssAccountLine">
4095+ <Data ss:Type="String"></Data>
4096+</Cell>
4097+<Cell ss:StyleID="ssAccountLine">
4098+ <Data ss:Type="String"></Data>
4099+</Cell>
4100+<Cell ss:StyleID="ssAccountLine">
4101+ <Data ss:Type="String"></Data>
4102+</Cell>
4103+<Cell ss:StyleID="ssAccountLineAccountCodeBold">
4104+ <Data ss:Type="String">${aml.get('account', '')|x}</Data>
4105+</Cell>
4106+<Cell ss:StyleID="ssAccountLineAccountCodeBold">
4107+ <Data ss:Type="String">${company.currency_id.name|x}</Data>
4108+</Cell>
4109+<Cell ss:StyleID="ssAccountLineNumberBold">
4110+ <Data ss:Type="Number">${aml.get('deb') or 0.|x}</Data>
4111+</Cell>
4112+<Cell ss:StyleID="ssAccountLineNumberBold">
4113+ <Data ss:Type="Number">${aml.get('cred') or 0.|x}</Data>
4114+</Cell>
4115+<Cell ss:StyleID="ssAccountLineNumberBold">
4116+ <Data ss:Type="Number">${aml.get('total') or 0.|x}</Data>
4117+</Cell>
4118+<Cell ss:StyleID="ssAccountLineNumberBold">
4119+ <Data ss:Type="Number">${aml.get('total') or 0.|x}</Data>
4120+</Cell>
4121+</Row>
4122+
4123+<!-- SUBTOTALS per currency -->
4124+% for detail_line in get_lines_per_currency(p_obj.employee_id.id, data, aml.get('account', '')):
4125+<Row>
4126+<Cell ss:StyleID="ssSubtotalLine" ss:MergeAcross="2">
4127+ <Data ss:Type="String"></Data>
4128+</Cell>
4129+<Cell ss:StyleID="ssSubtotalLine">
4130+ <Data ss:Type="String">${_('Subtotal')}</Data>
4131+</Cell>
4132+<Cell ss:StyleID="ssSubtotalLine">
4133+ <Data ss:Type="String">${detail_line.get('currency_booking', '')|x}</Data>
4134+</Cell>
4135+<Cell ss:StyleID="ssSubtotalLineNumber">
4136+ <Data ss:Type="Number">${detail_line.get('debit_booking') or 0.|x}</Data>
4137+</Cell>
4138+<Cell ss:StyleID="ssSubtotalLineNumber">
4139+ <Data ss:Type="Number">${detail_line.get('credit_booking') or 0.|x}</Data>
4140+</Cell>
4141+<Cell ss:StyleID="ssSubtotalLineNumber">
4142+ <Data ss:Type="Number">${detail_line.get('total_booking') or 0.|x}</Data>
4143+</Cell>
4144+<Cell ss:StyleID="ssSubtotalLineNumber">
4145+ <Data ss:Type="Number">${detail_line.get('total_functional') or 0.|x}</Data>
4146+</Cell>
4147+</Row>
4148+% endfor
4149+% endfor
4150+% endfor
4151+<Row>
4152+<Cell ss:StyleID="ssBorderTop">
4153+ <Data ss:Type="String"></Data>
4154+</Cell>
4155+<Cell ss:StyleID="ssBorderTop">
4156+ <Data ss:Type="String"></Data>
4157+</Cell>
4158+<Cell ss:StyleID="ssBorderTop">
4159+ <Data ss:Type="String"></Data>
4160+</Cell>
4161+<Cell ss:StyleID="ssBorderTop">
4162+ <Data ss:Type="String"></Data>
4163+</Cell>
4164+<Cell ss:StyleID="ssBorderTop">
4165+ <Data ss:Type="String"></Data>
4166+</Cell>
4167+<Cell ss:StyleID="ssBorderTop">
4168+ <Data ss:Type="String"></Data>
4169+</Cell>
4170+<Cell ss:StyleID="ssBorderTop">
4171+ <Data ss:Type="String"></Data>
4172+</Cell>
4173+<Cell ss:StyleID="ssBorderTop">
4174+ <Data ss:Type="String"></Data>
4175+</Cell>
4176+<Cell ss:StyleID="ssBorderTop">
4177+ <Data ss:Type="String"></Data>
4178+</Cell>
4179+</Row>
4180+</Table>
4181+<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
4182+ <FitToPage/>
4183+ <PageSetup>
4184+ <Layout x:Orientation="Landscape"/>
4185+ <Header x:Data="&amp;C&amp;&quot;Arial,Bold&quot;&amp;14Employee Balance"/>
4186+ <Footer x:Data="Page &amp;P of &amp;N"/>
4187+ </PageSetup>
4188+ <Print>
4189+ <ValidPrinterInfo/>
4190+ <PaperSizeIndex>9</PaperSizeIndex>
4191+ <HorizontalResolution>600</HorizontalResolution>
4192+ <VerticalResolution>600</VerticalResolution>
4193+ </Print>
4194+ <Selected/>
4195+ <Panes>
4196+ <Pane>
4197+ <Number>3</Number>
4198+ <ActiveRow>17</ActiveRow>
4199+ </Pane>
4200+ </Panes>
4201+ <ProtectObjects>False</ProtectObjects>
4202+ <ProtectScenarios>False</ProtectScenarios>
4203+</WorksheetOptions>
4204+</Worksheet>
4205+% endfor
4206+## endfor Worksheet
4207+% endif
4208+## endif if not entries
4209+</Workbook>
4210
4211=== modified file 'bin/addons/finance/report/account_report_name.py'
4212--- bin/addons/finance/report/account_report_name.py 2014-03-14 15:47:48 +0000
4213+++ bin/addons/finance/report/account_report_name.py 2022-06-01 15:15:45 +0000
4214@@ -50,4 +50,28 @@
4215 return update_name(self, cr, uid, _('Partner Ledger'), ret, context)
4216
4217 account_partner_ledger()
4218+
4219+
4220+class account_employee_balance(osv.osv_memory):
4221+ _name = 'account.employee.balance'
4222+ _inherit = 'account.employee.balance'
4223+
4224+ def _print_report(self, cr, uid, ids, data, context=None):
4225+ ret = super(account_employee_balance, self)._print_report(cr, uid, ids, data, context)
4226+ return update_name(self, cr, uid, _('Employee Balance'), ret, context)
4227+
4228+
4229+account_employee_balance()
4230+
4231+
4232+class account_employee_ledger(osv.osv_memory):
4233+ _name = 'account.employee.ledger'
4234+ _inherit = 'account.employee.ledger'
4235+
4236+ def _print_report(self, cr, uid, ids, data, context=None):
4237+ ret = super(account_employee_ledger, self)._print_report(cr, uid, ids, data, context)
4238+ return update_name(self, cr, uid, _('Employee Ledger'), ret, context)
4239+
4240+
4241+account_employee_ledger()
4242 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
4243
4244=== modified file 'bin/addons/finance/wizard/__init__.py'
4245--- bin/addons/finance/wizard/__init__.py 2020-12-14 16:46:05 +0000
4246+++ bin/addons/finance/wizard/__init__.py 2022-06-01 15:15:45 +0000
4247@@ -1,2 +1,3 @@
4248 import account_report_partner_balance_tree # uf-1715
4249 import fo_follow_up_finance_wizard
4250+import account_report_employee_balance_tree # US-6392
4251
4252=== added file 'bin/addons/finance/wizard/account_report_employee_balance_tree.py'
4253--- bin/addons/finance/wizard/account_report_employee_balance_tree.py 1970-01-01 00:00:00 +0000
4254+++ bin/addons/finance/wizard/account_report_employee_balance_tree.py 2022-06-01 15:15:45 +0000
4255@@ -0,0 +1,553 @@
4256+# -*- coding: utf-8 -*-
4257+##############################################################################
4258+#
4259+# OpenERP, Open Source Management Solution
4260+# Copyright (C) 2022 TeMPO Consulting, MSF
4261+#
4262+# This program is free software: you can redistribute it and/or modify
4263+# it under the terms of the GNU Affero General Public License as
4264+# published by the Free Software Foundation, either version 3 of the
4265+# License, or (at your option) any later version.
4266+#
4267+# This program is distributed in the hope that it will be useful,
4268+# but WITHOUT ANY WARRANTY; without even the implied warranty of
4269+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4270+# GNU Affero General Public License for more details.
4271+#
4272+# You should have received a copy of the GNU Affero General Public License
4273+# along with this program. If not, see <http://www.gnu.org/licenses/>.
4274+#
4275+##############################################################################
4276+
4277+from osv import fields, osv
4278+from tools.translate import _
4279+import decimal_precision as dp
4280+import datetime
4281+from datetime import timedelta
4282+
4283+
4284+class account_employee_balance_tree(osv.osv):
4285+ _name = 'account.employee.balance.tree'
4286+ _description = 'Print Account Employee Balance View'
4287+ _columns = {
4288+ 'uid': fields.many2one('res.users', 'Uid', invisible=True),
4289+ 'build_ts': fields.datetime('Build timestamp', invisible=True),
4290+ 'account_type': fields.selection([
4291+ ('payable', 'Payable'),
4292+ ('receivable', 'Receivable')
4293+ ],
4294+ 'Account type'), # not used since US-3873
4295+ 'employee_id': fields.many2one('hr.employee', 'Employee', invisible=True),
4296+ 'name': fields.char('Employee', size=168), # employee name
4297+ 'employee_identification_id': fields.char('Employee Identification number', size=64 ),
4298+ 'debit': fields.float('Debit', digits_compute=dp.get_precision('Account')),
4299+ 'credit': fields.float('Credit', digits_compute=dp.get_precision('Account')),
4300+ 'balance': fields.float('Balance', digits_compute=dp.get_precision('Account')),
4301+ 'ib_debit': fields.float('Initial Balance Debit', digits_compute=dp.get_precision('Account')), # not used since US-3873
4302+ 'ib_credit': fields.float('Initial Balance Credit', digits_compute=dp.get_precision('Account')), # not used since US-3873
4303+ 'ib_balance': fields.float('IB Balance', digits_compute=dp.get_precision('Account')), # not used since US-3873
4304+ }
4305+
4306+ _order = "name, employee_id"
4307+
4308+ def __init__(self, pool, cr):
4309+ super(account_employee_balance_tree, self).__init__(pool, cr)
4310+ self.total_debit_credit_balance = {}
4311+ self.move_line_ids = {}
4312+
4313+ def _execute_query_employees(self, cr, uid, data):
4314+ """
4315+ Returns a list of dicts, each containing data for one employee
4316+ """
4317+ obj_move = self.pool.get('account.move.line')
4318+ used_context = data['form'].get('used_context', {})
4319+
4320+ result_selection = data['form'].get('result_selection', '')
4321+ if (result_selection == 'customer'):
4322+ account_type = "('receivable')"
4323+ elif (result_selection == 'supplier'):
4324+ account_type = "('payable')"
4325+ else:
4326+ account_type = "('payable', 'receivable')"
4327+
4328+ move_state = "('draft','posted')"
4329+ if data['form'].get('target_move', 'all') == 'posted':
4330+ move_state = "('posted')"
4331+
4332+ fiscalyear_id = data['form'].get('fiscalyear_id', False)
4333+ if not fiscalyear_id:
4334+ # by default all FY taken into account
4335+ used_context.update({'all_fiscalyear': True})
4336+
4337+ where = obj_move._query_get(cr, uid, obj='l', context=used_context) or ''
4338+
4339+ # reconciliation filter
4340+ reconcile_filter = data['form'].get('reconciled', '')
4341+ if reconcile_filter == 'yes':
4342+ self.RECONCILE_REQUEST = "AND l.reconcile_id IS NOT NULL"
4343+ elif reconcile_filter == 'no':
4344+ self.RECONCILE_REQUEST = "AND l.reconcile_id IS NULL AND ac.reconcile='t'" # reconcilable entries not reconciled
4345+ else: # 'empty'
4346+ self.RECONCILE_REQUEST = ""
4347+
4348+ # proprietary instances filter
4349+ self.INSTANCE_REQUEST = ''
4350+ instance_ids = data['form'].get('instance_ids', False)
4351+ if instance_ids:
4352+ self.INSTANCE_REQUEST = " AND l.instance_id in(%s)" % (",".join(map(str, instance_ids)))
4353+
4354+ self.EMPLOYEE_PAY_METHOD = ''
4355+ self.EMPLOYEE_REQUEST = ' AND l.employee_id IS NOT NULL'
4356+ if data['form'].get('employee_ids', False): # some employees are specifically selected
4357+ employee_ids = data['form']['employee_ids']
4358+ if len(employee_ids) == 1:
4359+ self.EMPLOYEE_REQUEST = ' AND p.id = %s' % employee_ids[0]
4360+ else:
4361+ self.EMPLOYEE_REQUEST = ' AND p.id IN %s' % (tuple(employee_ids),)
4362+ else: # if there is not specifically selected employees
4363+ if data['form'].get('only_active_employees'): # check if we should include only active employees
4364+ self.EMPLOYEE_REQUEST = " AND res.active = 't'"
4365+ # check if we should include only a selected type of employees
4366+ emp_type = data['form'].get('employee_type')
4367+ if emp_type != '':
4368+ self.EMPLOYEE_REQUEST += " AND p.employee_type = '%s'" % emp_type.encode("utf-8")
4369+ # check if we should include only employees using a selected method of payment
4370+ pay_method = data['form'].get('payment_method')
4371+ if pay_method != 'blank':
4372+ self.EMPLOYEE_REQUEST += " AND pay.name = '%s'" % pay_method
4373+ # do join with payment_method only when local staff is selected because exp staff don't always have payment method registered
4374+ if emp_type == 'local':
4375+ self.EMPLOYEE_PAY_METHOD = " JOIN hr_payment_method pay ON (p.payment_method_id = pay.id)"
4376+
4377+
4378+ self.ACCOUNT_REQUEST = ''
4379+ if data['form'].get('account_ids', False): # some accounts are specifically selected
4380+ self.ACCOUNT_REQUEST = " AND ac.id IN (%s)" % (",".join(map(str, data['form']['account_ids'])))
4381+
4382+ where = where and 'AND %s' % where or ''
4383+ query = """SELECT p.id as employee_id, p.identification_id as employee_identification_id, p.name_resource as employee_name,
4384+ COALESCE(sum(debit),0) AS debit, COALESCE(sum(credit), 0) AS credit,
4385+ CASE WHEN sum(debit) > sum(credit) THEN sum(debit) - sum(credit) ELSE 0 END AS sdebit,
4386+ CASE WHEN sum(debit) < sum(credit) THEN sum(credit) - sum(debit) ELSE 0 END AS scredit
4387+ FROM account_move_line l INNER JOIN hr_employee p ON (l.employee_id=p.id)
4388+ INNER JOIN resource_resource res ON p.resource_id = res.id
4389+ JOIN account_account ac ON (l.account_id = ac.id)
4390+ JOIN account_move am ON (am.id = l.move_id)
4391+ %s
4392+ WHERE ac.type IN %s
4393+ AND am.state IN %s
4394+ %s %s %s %s %s
4395+ GROUP BY p.id, p.identification_id, p.name_resource
4396+ ORDER BY p.name_resource;""" % (self.EMPLOYEE_PAY_METHOD, account_type, move_state, # not_a_user_entry
4397+ where, self.INSTANCE_REQUEST, self.EMPLOYEE_REQUEST, self.ACCOUNT_REQUEST,
4398+ self.RECONCILE_REQUEST)
4399+ cr.execute(query)
4400+ res = cr.dictfetchall()
4401+
4402+ if data['form'].get('display_employee', '') == 'non-zero_balance':
4403+ res2 = [r for r in res if r['sdebit'] > 0.0001 or r['scredit'] > 0.0001] # 0.0001 instead of 0 to fix float rounding errors
4404+ else: # with_movements or all
4405+ res2 = [r for r in res]
4406+ return res2
4407+
4408+ def _execute_query_selected_employee_move_line_ids(self, cr, uid, employee_id, data):
4409+ # if this method is re-called with the same arguments don't recompute the result
4410+ if not self.move_line_ids or employee_id != self.move_line_ids['employee_id'] or data != self.move_line_ids['data']:
4411+ obj_move = self.pool.get('account.move.line')
4412+ where = obj_move._query_get(cr, uid, obj='l', context=data['form'].get('used_context', {})) or ''
4413+
4414+ result_selection = data['form'].get('result_selection', '')
4415+ if result_selection == 'customer':
4416+ account_type = "('receivable')"
4417+ elif result_selection == 'supplier':
4418+ account_type = "('payable')"
4419+ else:
4420+ account_type = "('payable', 'receivable')"
4421+
4422+ move_state = "('draft','posted')"
4423+ if data['form'].get('target_move', 'all') == 'posted':
4424+ move_state = "('posted')"
4425+
4426+ query = "SELECT l.id FROM account_move_line l" \
4427+ " JOIN account_account ac ON (l.account_id = ac.id)" \
4428+ " JOIN account_move am ON (am.id = l.move_id) WHERE "
4429+ if employee_id:
4430+ query += "l.employee_id = " + str(employee_id) + "" \
4431+ " AND ac.type IN " + account_type + "" \
4432+ " AND am.state IN " + move_state + ""
4433+ else:
4434+ query += "ac.type IN " + account_type + "" \
4435+ " AND am.state IN " + move_state + ""
4436+
4437+ reconcile_filter = data['form'].get('reconciled', '')
4438+ if reconcile_filter == 'yes':
4439+ query += " AND l.reconcile_id IS NOT NULL"
4440+ elif reconcile_filter == 'no':
4441+ query += " AND l.reconcile_id IS NULL AND ac.reconcile='t'" # reconcilable entries not reconciled
4442+
4443+ if data['form'].get('instance_ids', False):
4444+ query += " AND l.instance_id in(%s)" % (",".join(map(str, data['form']['instance_ids'])))
4445+ if data['form'].get('account_ids', False): # some accounts are specifically selected
4446+ query += " AND ac.id IN (%s)" % (",".join(map(str, data['form']['account_ids'])))
4447+ if where:
4448+ query += " AND " + where + ""
4449+
4450+ cr.execute(query)
4451+ res = cr.fetchall()
4452+ if res:
4453+ res2 = []
4454+ for r in res:
4455+ res2.append(r[0])
4456+ self.move_line_ids['res'] = res2
4457+ else:
4458+ self.move_line_ids['res'] = False
4459+ self.move_line_ids['employee_id'] = employee_id
4460+ self.move_line_ids['data'] = data
4461+ return self.move_line_ids['res']
4462+
4463+ def _delete_previous_data(self, cr, uid, context=None):
4464+ """ delete older user request than 15 days"""
4465+ dt = datetime.datetime.now() - timedelta(days=15)
4466+ dt_orm = dt.strftime(self.pool.get('date.tools').get_db_datetime_format(cr, uid, context=context))
4467+ domain = [
4468+ ('uid', '=', uid),
4469+ ('build_ts', '<', dt_orm),
4470+ ]
4471+ ids = self.search(cr, uid, domain, context=context)
4472+ if ids:
4473+ if isinstance(ids, (int, long)):
4474+ ids = [ids]
4475+ self.unlink(cr, uid, ids, context=context)
4476+
4477+ def build_data(self, cr, uid, data, context=None):
4478+ """
4479+ data
4480+ {'model': 'ir.ui.menu', 'ids': [494], 'build_ts': build_timestamp,
4481+ 'form': {
4482+ 'display_employee': 'non-zero_balance', 'chart_account_id': 1,
4483+ 'result_selection': 'customer', 'date_from': False,
4484+ 'period_to': False,
4485+ 'journal_ids': [16, 9, 10, 11, 12, 13, 14, 6, 7, 17, 18, 20, 15, 5, 1, 2, 3, 4, 8, 19],
4486+ 'used_context': {
4487+ 'chart_account_id': 1,
4488+ 'journal_ids': [16, 9, 10, 11, 12, 13, 14, 6, 7, 17, 18, 20, 15, 5, 1, 2, 3, 4, 8, 19],
4489+ 'fiscalyear': 1},
4490+ 'filter': 'filter_no', 'period_from': False,
4491+ 'fiscalyear_id': 1, 'periods': [], 'date_to': False, 'id': 1, 'target_move': 'posted'
4492+ }
4493+ }
4494+ """
4495+ if context is None:
4496+ context = {}
4497+ context['data'] = data
4498+ self._delete_previous_data(cr, uid, context=context)
4499+
4500+ res = self._execute_query_employees(cr, uid, data)
4501+
4502+ p_seen = {} # store every employee handled
4503+ for r in res:
4504+ debit = r['debit']
4505+ credit = r['credit']
4506+ if r['employee_id'] not in p_seen:
4507+ p_seen[r['employee_id']] = {}
4508+ p_seen[r['employee_id']]['name'] = r['employee_name']
4509+ p_seen[r['employee_id']]['employee_identification_id'] = r['employee_identification_id']
4510+ vals = {
4511+ 'uid': uid,
4512+ 'build_ts': data['build_ts'],
4513+ 'employee_id': r['employee_id'],
4514+ 'name': r['employee_name'],
4515+ 'employee_identification_id': r['employee_identification_id'],
4516+ 'debit': debit,
4517+ 'credit': credit,
4518+ 'balance': debit - credit,
4519+ }
4520+ self.create(cr, uid, vals, context=context)
4521+
4522+ # if "Display Employees: All employees" has been selected, add the employees without movements
4523+ # ONLY IF NO specific employee has been selected
4524+ if data['form'].get('display_employee', '') == 'all' and not data['form'].get('employee_ids', False):
4525+ # create entries at zero for employees where no result was found
4526+ active_selection = data['form'].get('only_active_employees') and ('t',) or ('t', 'f')
4527+ other_employees_sql_end = ""
4528+ other_employees_sql_end_params = []
4529+ if p_seen:
4530+ # exclude employees already found if any
4531+ other_employees_sql_end = " AND emp.id NOT IN %s "
4532+ other_employees_sql_end_params.append(tuple(p_seen.keys()))
4533+ other_employees_sql = """
4534+ SELECT emp.id , emp.identification_id, emp.name_resource
4535+ FROM hr_employee emp
4536+ INNER JOIN resource_resource res ON emp.resource_id = res.id
4537+ WHERE res.active IN %s """ + other_employees_sql_end + """ ;
4538+ """
4539+ other_employees_params = (active_selection,) + tuple(other_employees_sql_end_params)
4540+ cr.execute(other_employees_sql, other_employees_params) # not_a_user_entry
4541+ other_employees = cr.dictfetchall()
4542+ for employee in other_employees:
4543+ vals = {
4544+ 'uid': uid,
4545+ 'build_ts': data['build_ts'],
4546+ 'employee_id': employee['id'],
4547+ 'name': employee['name_resource'],
4548+ 'employee_identification_id': employee['identification_id'] or '',
4549+ 'debit': 0.0,
4550+ 'credit': 0.0,
4551+ 'balance': 0.0,
4552+ }
4553+ self.create(cr, uid, vals, context=context)
4554+
4555+ def open_journal_items(self, cr, uid, ids, context=None):
4556+ # get related employee
4557+ res = {}
4558+ if context is None:
4559+ context = {}
4560+ if ids:
4561+ if isinstance(ids, (int, long)):
4562+ ids = [ids]
4563+ r = self.read(cr, uid, ids, ['employee_id'], context=context)
4564+ if r and r[0] and r[0]['employee_id']:
4565+ if context and 'data' in context and 'form' in context['data']:
4566+ move_line_ids = self._execute_query_selected_employee_move_line_ids(
4567+ cr, uid,
4568+ r[0]['employee_id'][0],
4569+ context['data'])
4570+ if move_line_ids:
4571+ new_context = {}
4572+ if context:
4573+ ctx_key_2copy = ('lang', 'tz', 'department_id', 'client', 'name')
4574+ for k in ctx_key_2copy:
4575+ if k in context:
4576+ new_context[k] = context[k]
4577+ view_id = self.pool.get('ir.model.data').get_object_reference(
4578+ cr, uid, 'finance',
4579+ 'view_account_employee_balance_tree_move_line_tree')[1]
4580+ res = {
4581+ 'name': 'Journal Items',
4582+ 'type': 'ir.actions.act_window',
4583+ 'res_model': 'account.move.line',
4584+ 'view_mode': 'tree,form',
4585+ 'view_type': 'form',
4586+ 'domain': [('id', 'in', tuple(move_line_ids))],
4587+ 'context': new_context,
4588+ }
4589+ if view_id:
4590+ res['view_id'] = [view_id]
4591+ if not res:
4592+ raise osv.except_osv(_('Warning !'), _('No Journal Items to show.'))
4593+ return res
4594+
4595+ def get_employee_data(self, cr, uid, data, context=None):
4596+ """
4597+ Gets the "account_employee_balance_trees" which have just been created
4598+ """
4599+ domain = [
4600+ ('uid', '=', uid),
4601+ ('build_ts', '=', data['build_ts']),
4602+ ]
4603+ ids = self.search(cr, uid, domain, context=context, order='name, id')
4604+ if ids:
4605+ if isinstance(ids, (int, long)):
4606+ ids = [ids]
4607+ return self.browse(cr, uid, ids, context=context)
4608+ return []
4609+
4610+ def get_employee_account_move_lines_data(self, cr, uid, employee_id, data, context=None):
4611+ ids = self._execute_query_selected_employee_move_line_ids(cr, uid, employee_id, data)
4612+ if ids:
4613+ if isinstance(ids, (int, long)):
4614+ ids = [ids]
4615+ sql = """SELECT a.code as account, SUM(aml.debit) as deb, SUM(aml.credit) as cred, SUM(debit) - SUM(credit) as total
4616+ FROM account_move_line as aml, account_account as a
4617+ WHERE aml.id in %s
4618+ AND aml.account_id = a.id
4619+ GROUP BY a.code"""
4620+ cr.execute(sql, (tuple(ids), ))
4621+ res = cr.dictfetchall()
4622+ return res
4623+ return []
4624+
4625+ def get_lines_per_currency(self, cr, uid, employee_id, data, account_code):
4626+ """
4627+ Returns a list of dicts, each containing the subtotal per currency for the given employee and account
4628+ """
4629+ res = []
4630+ if employee_id and data and account_code:
4631+ # the subtotal lines for the selected employee must be limited to the ids corresponding to
4632+ # the criteria selected in the wizard
4633+ ids = self._execute_query_selected_employee_move_line_ids(cr, uid, employee_id, data)
4634+ if ids:
4635+ sql = """SELECT c.name as currency_booking,
4636+ SUM(aml.debit_currency) as debit_booking, SUM(aml.credit_currency) as credit_booking,
4637+ SUM(debit_currency) - SUM(credit_currency) as total_booking,
4638+ SUM(aml.debit) - SUM(aml.credit) as total_functional
4639+ FROM account_move_line AS aml
4640+ INNER JOIN account_account AS a ON aml.account_id = a.id
4641+ INNER JOIN res_currency AS c ON aml.currency_id = c.id
4642+ WHERE aml.id in %s
4643+ AND a.code = %s
4644+ GROUP BY a.code, c.name
4645+ ORDER BY c.name;"""
4646+ cr.execute(sql, (tuple(ids), account_code))
4647+ res = cr.dictfetchall()
4648+ return res
4649+
4650+ def get_employees_total_debit_credit_balance(self, cr, uid, data):
4651+ """Compute all employees total debit/credit from self data
4652+ return total_debit, total_credit (tuple)
4653+ """
4654+ # recalculate the result only if the criteria have changed
4655+ if not self.total_debit_credit_balance or data != self.total_debit_credit_balance['data']:
4656+ query = """SELECT sum(debit) AS debit, sum(credit) AS credit, sum(balance) as balance
4657+ FROM account_employee_balance_tree
4658+ WHERE uid = %s
4659+ AND build_ts = %s;
4660+ """
4661+ cr.execute(query, (uid, data['build_ts']))
4662+ res = cr.dictfetchall()
4663+ self.total_debit_credit_balance['data'] = data
4664+ self.total_debit_credit_balance['res'] = res[0]['debit'], res[0]['credit'], res[0]['balance']
4665+ return self.total_debit_credit_balance['res']
4666+
4667+
4668+account_employee_balance_tree()
4669+
4670+
4671+class wizard_account_employee_balance_tree(osv.osv_memory):
4672+ """
4673+ This wizard will provide the employee balance report by periods, between any two dates.
4674+ """
4675+ _inherit = 'account.common.employee.report'
4676+ _name = 'wizard.account.employee.balance.tree'
4677+ _description = 'Print Account Employee Balance View'
4678+
4679+ def get_payment_methods(self, cr, uid, context):
4680+ return self.pool.get('account.employee.ledger').get_payment_methods(cr, uid, context)
4681+
4682+ def get_employee_type(self, cr, uid, context):
4683+ return self.pool.get('account.employee.ledger').get_employee_type(cr, uid, context)
4684+
4685+ _columns = {
4686+ 'display_employee': fields.selection([('all', 'All Employees'),
4687+ ('with_movements', 'With movements'),
4688+ ('non-zero_balance', 'With balance is not equal to 0')],
4689+ string='Display Employees', required=True),
4690+ 'instance_ids': fields.many2many('msf.instance', 'account_report_general_ledger_instance_rel', 'instance_id',
4691+ 'argl_id', 'Proprietary Instances'),
4692+ 'employee_ids': fields.many2many('hr.employee', 'account_employee_balance_employee_rel', 'wizard_id',
4693+ 'employee_id', string='Employees',
4694+ help='Display the report for specific employees only'),
4695+ 'only_active_employees': fields.boolean('Only active employees',
4696+ help='Display the report for active employees only'),
4697+ 'account_ids': fields.many2many('account.account', 'account_employee_balance_account_rel', 'wizard_id',
4698+ 'account_id', string='Accounts',
4699+ help='Display the report for specific accounts only'),
4700+ 'reconciled': fields.selection([
4701+ ('empty', ''),
4702+ ('yes', 'Yes'),
4703+ ('no', 'No'),
4704+ ], string='Reconciled'),
4705+ 'employee_type': fields.selection(get_employee_type, string='Employee Type', required=False),
4706+ 'payment_method': fields.selection(get_payment_methods, string='Method of Payment', required=False),
4707+ }
4708+
4709+ def _get_journals(self, cr, uid, context=None):
4710+ """exclude extra-accounting journals from this report (IKD, ODX)."""
4711+ domain = [('type', 'not in', ['inkind', 'extra'])]
4712+ return self.pool.get('account.journal').search(cr, uid, domain, context=context)
4713+
4714+ _defaults = {
4715+ 'display_employee': 'with_movements',
4716+ 'result_selection': 'customer_supplier',
4717+ 'account_domain': "[('type', 'in', ['payable', 'receivable'])]",
4718+ 'journal_ids': _get_journals,
4719+ 'only_active_employees': False,
4720+ 'reconciled': 'empty',
4721+ 'fiscalyear_id': False,
4722+ 'employee_type': '',
4723+ 'payment_method': 'blank',
4724+ }
4725+
4726+ def _get_data(self, cr, uid, ids, context=None):
4727+ if context is None:
4728+ context = {}
4729+
4730+ data = {}
4731+ data['keep_open'] = 1
4732+ data['ids'] = context.get('active_ids', [])
4733+ data['model'] = context.get('active_model', 'ir.ui.menu')
4734+ data['build_ts'] = datetime.datetime.now().strftime(self.pool.get('date.tools').get_db_datetime_format(cr, uid, context=context))
4735+ data['form'] = self.read(cr, uid, ids, ['date_from', 'date_to', 'fiscalyear_id', 'journal_ids', 'period_from',
4736+ 'period_to', 'filter', 'chart_account_id', 'target_move', 'display_employee',
4737+ 'instance_ids', 'employee_ids', 'employee_type', 'payment_method',
4738+ 'only_active_employees', 'account_ids', 'reconciled'])[0]
4739+ if not data['form']['employee_type']:
4740+ data['form']['employee_type'] = ''
4741+ if data['form']['journal_ids']:
4742+ default_journals = self._get_journals(cr, uid, context=context)
4743+ if default_journals:
4744+ if len(default_journals) == len(data['form']['journal_ids']):
4745+ data['form']['all_journals'] = True
4746+ used_context = self._build_contexts(cr, uid, ids, data, context=context)
4747+ data['form']['periods'] = used_context.get('periods', False) and used_context['periods'] or []
4748+ data['form']['used_context'] = used_context
4749+
4750+ data = self.pre_print_report(cr, uid, ids, data, context=context)
4751+ return data
4752+
4753+ def show(self, cr, buid, ids, context=None):
4754+ uid = hasattr(buid, 'realUid') and buid.realUid or buid
4755+ data = self._get_data(cr, uid, ids, context=context)
4756+ self.pool.get('account.employee.balance.tree').build_data(cr, uid, data, context=context)
4757+ self._check_dates_fy_consistency(cr, uid, data, context)
4758+ return {
4759+ 'type': 'ir.actions.act_window',
4760+ 'name': _('Employee Balance'),
4761+ 'res_model': 'account.employee.balance.tree',
4762+ 'view_type': 'form',
4763+ 'view_mode': 'tree,form',
4764+ 'keep_open': 1,
4765+ 'ref': 'view_account_employee_balance_tree',
4766+ 'domain': [
4767+ ('uid', '=', uid),
4768+ ('build_ts', '=', data['build_ts']),
4769+ ],
4770+ 'context': context,
4771+ }
4772+
4773+ def print_pdf(self, cr, buid, ids, context=None):
4774+ if context is None:
4775+ context = {}
4776+ uid = hasattr(buid, 'realUid') and buid.realUid or buid
4777+ data = self._get_data(cr, uid, ids, context=context)
4778+ self._check_dates_fy_consistency(cr, uid, data, context)
4779+ self.pool.get('account.employee.balance.tree').build_data(cr, uid, data, context=context)
4780+ return {
4781+ 'type': 'ir.actions.report.xml',
4782+ 'report_name': 'account.employee.balance',
4783+ 'datas': data,
4784+ }
4785+
4786+ def print_xls(self, cr, buid, ids, context=None):
4787+ if context is None:
4788+ context = {}
4789+ uid = hasattr(buid, 'realUid') and buid.realUid or buid
4790+ data = self._get_data(cr, uid, ids, context=context)
4791+ self._check_dates_fy_consistency(cr, uid, data, context)
4792+ self.pool.get('account.employee.balance.tree').build_data(cr, uid, data, context=context)
4793+ return {
4794+ 'type': 'ir.actions.report.xml',
4795+ 'report_name': 'account.employee.balance.tree_xls',
4796+ 'datas': data,
4797+ }
4798+
4799+ def remove_journals(self, cr, uid, ids, context=None):
4800+ if ids:
4801+ self.write(cr, uid, ids, {'journal_ids': [(6, 0, [])]},
4802+ context=context)
4803+ return {}
4804+
4805+
4806+wizard_account_employee_balance_tree()
4807+
4808+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
4809
4810=== added file 'bin/addons/finance/wizard/account_report_employee_balance_tree_view.xml'
4811--- bin/addons/finance/wizard/account_report_employee_balance_tree_view.xml 1970-01-01 00:00:00 +0000
4812+++ bin/addons/finance/wizard/account_report_employee_balance_tree_view.xml 2022-06-01 15:15:45 +0000
4813@@ -0,0 +1,177 @@
4814+<?xml version="1.0" encoding="utf-8"?>
4815+<openerp>
4816+ <data>
4817+
4818+ <record model="ir.ui.view" id="view_account_employee_balance_search" >
4819+ <field name="name">account.employee.balance.tree.search</field>
4820+ <field name="model">account.employee.balance.tree</field>
4821+ <field name="type">search</field>
4822+ <field name="arch" type="xml">
4823+ <search string="Employee Balance Search">
4824+ <field name="employee_id" string="Employee" />
4825+ </search>
4826+ </field>
4827+ </record>
4828+
4829+ <record model="ir.ui.view" id="view_account_employee_balance_tree">
4830+ <field name="name">account.employee.balance.tree.view</field>
4831+ <field name="model">account.employee.balance.tree</field>
4832+ <field name="type">tree</field>
4833+ <field name="priority" eval="300"/>
4834+ <field name="arch" type="xml">
4835+ <tree string="Employee Balance View"
4836+ editable="top" noteditable="1"
4837+ hide_new_button="1" hide_delete_button="1">
4838+ <button
4839+ name="open_journal_items"
4840+ string="Open journal items"
4841+ type="object"
4842+ icon="terp-gtk-go-back-rtl"
4843+ />
4844+ <field name="employee_id" invisible="1"/>
4845+ <field name="name"/>
4846+ <field name="debit" sum="Debit" />
4847+ <field name="credit" sum="Credit" />
4848+ <field name="balance" sum="Balance" />
4849+ </tree>
4850+ </field>
4851+ </record>
4852+
4853+ <!-- journal items from view_account_employee_balance_tree !-->
4854+ <record model="ir.ui.view" id="view_account_employee_balance_tree_move_line_tree">
4855+ <field name="name">account.move.line.tree</field>
4856+ <field name="model">account.move.line</field>
4857+ <field name="type">tree</field>
4858+ <field name="priority" eval="301"/>
4859+ <field name="arch" type="xml">
4860+ <tree string="Account Entry Line" editable="bottom" noteditable="1" colors="red:state in ('draft');black:state in ('valid')" hide_new_button="1">
4861+ <field name="journal_id"/>
4862+ <field name="move_id"/>
4863+ <!--
4864+ <field name="name"/>
4865+ <field name="ref"/>
4866+ -->
4867+ <field name="document_date"/>
4868+ <field name="date"/>
4869+ <field name="period_id" domain="[('state','=','draft')]"/>
4870+ <field name="account_id"/>
4871+ <field name="move_state" invisible="1"/>
4872+ <field name="partner_id" invisible="1"/>
4873+ <field name="employee_id" invisible="1"/>
4874+ <field name="transfer_journal_id" invisible="1"/>
4875+ <field name="partner_txt" invisible="1"/>
4876+ <field name="partner_type"/>
4877+ <field name="debit_currency" sum="Total Book. Debit"/>
4878+ <field name="credit_currency" sum="Total Book. Credit"/>
4879+ <field name="currency_id"/>
4880+ <field name="debit" sum="Total Func. Debit"/>
4881+ <field name="credit" sum="Total Func. Credit"/>
4882+ <field name="output_amount_debit" invisible="1" />
4883+ <field name="output_amount_credit" invisible="1" />
4884+ <field name="functional_currency_id"/>
4885+ <field name="reconcile_txt"/>
4886+ <field name="state"/>
4887+ </tree>
4888+ </field>
4889+ </record>
4890+
4891+ <record id="wizard_account_report_employee_balance_tree_view" model="ir.ui.view">
4892+ <field name="name">Employee Balance View</field>
4893+ <field name="model">wizard.account.employee.balance.tree</field>
4894+ <field name="type">form</field>
4895+ <field name="inherit_id" ref="account.account_common_report_view" />
4896+ <field name="arch" type="xml">
4897+ <data>
4898+ <xpath expr="/form/label[@string='']" position="replace">
4899+ <separator string="Employee Balance Tree" colspan="4"/>
4900+ </xpath>
4901+ <xpath expr="//field[@name='target_move']" position="after">
4902+ <field name="result_selection" on_change="onchange_result_selection(result_selection)"/>
4903+ <field name="display_employee"/>
4904+ <field name="reconciled"/>
4905+ <field name="only_active_employees"/>
4906+ <field name="employee_type" on_change="onchange_employee_type(employee_type)"/>
4907+ <field name="payment_method" on_change="onchange_payment_method(payment_method)"/>
4908+ <field name="instance_ids" domain="[('instance_to_display_ids','=',True)]">
4909+ <tree noteditable="1" editable="top" string="Proprietary Instances">
4910+ <field name="code" />
4911+ <field name="name" />
4912+ </tree>
4913+ </field>
4914+ <field name="employee_ids" >
4915+ <tree noteditable="1">
4916+ <field name="name_resource"/>
4917+ <field name="identification_id"/>
4918+ <field name="employee_type"/>
4919+ </tree>
4920+ </field>
4921+ <field name="account_domain" invisible="1"/>
4922+ <field name="account_ids" domain="account_domain">
4923+ <tree noteditable="1">
4924+ <field name="code"/>
4925+ <field name="name"/>
4926+ </tree>
4927+ </field>
4928+ </xpath>
4929+ <xpath expr="//field[@name='fiscalyear_id']" position="attributes">
4930+ <attribute name="on_change">onchange_fiscalyear(fiscalyear_id)</attribute>
4931+ </xpath>
4932+ <xpath expr="//field[@name='period_from']" position="attributes">
4933+ <attribute name="domain">[]</attribute>
4934+ </xpath>
4935+ <xpath expr="//field[@name='period_to']" position="attributes">
4936+ <attribute name="domain">[]</attribute>
4937+ </xpath>
4938+
4939+ <xpath expr="//group[1]" position="replace">
4940+ <group col="4" colspan="4">
4941+ <button icon="gtk-cancel" special="cancel" string="Cancel" colspan="2"/>
4942+ <button icon="terp-gtk-go-back-rtl" name="show" string="Balance View" type="object" colspan="2" default_focus="1" />
4943+ <button icon="gtk-print" name="print_pdf" string="Print PDF" type="object" colspan="2" />
4944+ <button icon="gtk-print" name="print_xls" string="Print Excel" type="object" colspan="2" />
4945+ </group>
4946+ </xpath>
4947+
4948+ <xpath expr="//field[@name='journal_ids']" position="replace">
4949+ <group col="4" colspan="4">
4950+ <button name="remove_journals" string="Remove all journals" type="object" colspan="1" />
4951+ <label string="" colspan="3" />
4952+ <!-- exclude extra-accounting journals from this report (IKD, ODX). -->
4953+ <field name="journal_ids" colspan="4" nolabel="1" noteditable="1"
4954+ domain="[('type', 'not in', ['inkind', 'extra'])]">
4955+ <tree noteditable="1" editable="top" string="Account Journal" colors="red:is_active==False;black:is_active==True">
4956+ <field name="is_active" invisible="1" />
4957+ <field name="instance_id" />
4958+ <field name="code" />
4959+ <field name="name" />
4960+ <field name="type" />
4961+ </tree>
4962+ </field>
4963+ </group>
4964+ </xpath>
4965+
4966+ </data>
4967+ </field>
4968+ </record>
4969+
4970+ <record id="action_account_employee_balance_tree" model="ir.actions.act_window">
4971+ <field name="name">Employee Balance View</field>
4972+ <field name="res_model">wizard.account.employee.balance.tree</field>
4973+ <field name="type">ir.actions.act_window</field>
4974+ <field name="view_type">form</field>
4975+ <field name="view_mode">form</field>
4976+ <field name="view_id" ref="wizard_account_report_employee_balance_tree_view"/>
4977+ <field name="context">{'record_id': active_id}</field>
4978+ <field name="target">new</field>
4979+ </record>
4980+
4981+
4982+ <menuitem icon="STOCK_PRINT"
4983+ name="Employee Balance"
4984+ action="action_account_employee_balance_tree"
4985+ id="menu_account_employee_balance_tree"
4986+ parent="account.employee_menu"
4987+ sequence="2000" />
4988+
4989+ </data>
4990+ </openerp>
4991
4992=== modified file 'bin/addons/msf_profile/i18n/fr_MF.po'
4993--- bin/addons/msf_profile/i18n/fr_MF.po 2022-05-25 14:15:34 +0000
4994+++ bin/addons/msf_profile/i18n/fr_MF.po 2022-06-01 15:15:45 +0000
4995@@ -1938,6 +1938,9 @@
4996 #: report:account.third_party_ledger:0
4997 #: report:account.third_party_ledger_other:0
4998 #: report:addons/account/report/account_partner_ledger.mako:278
4999+#: report:account.employee_ledger:0
5000+#: report:account.employee_ledger_other:0
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches