Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
erp5
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
138
Merge Requests
138
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Jobs
Commits
Open sidebar
nexedi
erp5
Commits
c48ce799
Commit
c48ce799
authored
Feb 05, 2020
by
Xiaowu Zhang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
erp5_payroll: payslip draft verison
parent
e04b05cf
Changes
10
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
346 additions
and
323 deletions
+346
-323
bt5/erp5_payroll/SkinTemplateItem/portal_skins/erp5_payroll/PaySheetTransaction_generatePayslipReport.py
...erp5_payroll/PaySheetTransaction_generatePayslipReport.py
+2
-3
bt5/erp5_payroll/SkinTemplateItem/portal_skins/erp5_payroll/PaySheetTransaction_generatePayslipReport.xml
...rp5_payroll/PaySheetTransaction_generatePayslipReport.xml
+1
-1
bt5/erp5_payroll/SkinTemplateItem/portal_skins/erp5_payroll/PaySheetTransaction_generatePayslipReportContent.zpt
...roll/PaySheetTransaction_generatePayslipReportContent.zpt
+65
-233
bt5/erp5_payroll/SkinTemplateItem/portal_skins/erp5_payroll/PaySheetTransaction_generatePayslipReportFooter.xml
...yroll/PaySheetTransaction_generatePayslipReportFooter.xml
+58
-0
bt5/erp5_payroll/SkinTemplateItem/portal_skins/erp5_payroll/PaySheetTransaction_generatePayslipReportFooter.zpt
...yroll/PaySheetTransaction_generatePayslipReportFooter.zpt
+2
-0
bt5/erp5_payroll/SkinTemplateItem/portal_skins/erp5_payroll/PaySheetTransaction_generatePayslipReportHeader.xml
...yroll/PaySheetTransaction_generatePayslipReportHeader.xml
+58
-0
bt5/erp5_payroll/SkinTemplateItem/portal_skins/erp5_payroll/PaySheetTransaction_generatePayslipReportHeader.zpt
...yroll/PaySheetTransaction_generatePayslipReportHeader.zpt
+39
-0
bt5/erp5_payroll/SkinTemplateItem/portal_skins/erp5_payroll/PaySheetTransaction_getLineListAsDict.py
...ins/erp5_payroll/PaySheetTransaction_getLineListAsDict.py
+3
-0
bt5/erp5_payroll/SkinTemplateItem/portal_skins/erp5_payroll/PaySheetTransaction_getPayslipData.py
..._skins/erp5_payroll/PaySheetTransaction_getPayslipData.py
+115
-83
bt5/erp5_payroll/SkinTemplateItem/portal_skins/erp5_payroll/PaySheetTransaction_printPayslipReport.py
...ns/erp5_payroll/PaySheetTransaction_printPayslipReport.py
+3
-3
No files found.
bt5/erp5_payroll/SkinTemplateItem/portal_skins/erp5_payroll/PaySheetTransaction_generatePayslipReport.py
View file @
c48ce799
kwargs
[
"report_data"
]
=
context
.
PaySheetTransaction_getPayslipData
()
rep_content
=
context
.
PaySheetTransaction_generatePayslipReportContent
(
*
args
,
**
kwargs
)
kw
[
"report_data"
]
=
context
.
PaySheetTransaction_getPayslipData
()
rep_content
=
context
.
PaySheetTransaction_generatePayslipReportContent
(
**
kw
)
if
isinstance
(
rep_content
,
unicode
):
rep_content
=
rep_content
.
encode
(
"utf8"
)
...
...
bt5/erp5_payroll/SkinTemplateItem/portal_skins/erp5_payroll/PaySheetTransaction_generatePayslipReport.xml
View file @
c48ce799
...
...
@@ -50,7 +50,7 @@
</item>
<item>
<key>
<string>
_params
</string>
</key>
<value>
<string>
*
args, **kwargs
</string>
</value>
<value>
<string>
*
*kw
</string>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
...
...
bt5/erp5_payroll/SkinTemplateItem/portal_skins/erp5_payroll/PaySheetTransaction_generatePayslipReportContent.zpt
View file @
c48ce799
This diff is collapsed.
Click to expand it.
bt5/erp5_payroll/SkinTemplateItem/portal_skins/erp5_payroll/PaySheetTransaction_generatePayslipReportFooter.xml
0 → 100644
View file @
c48ce799
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"ZopePageTemplate"
module=
"Products.PageTemplates.ZopePageTemplate"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_bind_names
</string>
</key>
<value>
<object>
<klass>
<global
name=
"NameAssignments"
module=
"Shared.DC.Scripts.Bindings"
/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key>
<string>
_asgns
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
name_subpath
</string>
</key>
<value>
<string>
traverse_subpath
</string>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key>
<string>
content_type
</string>
</key>
<value>
<string>
text/html
</string>
</value>
</item>
<item>
<key>
<string>
expand
</string>
</key>
<value>
<int>
0
</int>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
PaySheetTransaction_generatePayslipReportFooter
</string>
</value>
</item>
<item>
<key>
<string>
output_encoding
</string>
</key>
<value>
<string>
utf-8
</string>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<unicode></unicode>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
bt5/erp5_payroll/SkinTemplateItem/portal_skins/erp5_payroll/PaySheetTransaction_generatePayslipReportFooter.zpt
0 → 100644
View file @
c48ce799
<p>Dans votre intérêt et pour vous aider à faire valoir vos droits, conservez ce bulletin de paie sans limitation de durée.</p>
<p>Generated with ERP5 – Open Source ERP suite (www.erp5.org)</p>
\ No newline at end of file
bt5/erp5_payroll/SkinTemplateItem/portal_skins/erp5_payroll/PaySheetTransaction_generatePayslipReportHeader.xml
0 → 100644
View file @
c48ce799
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"ZopePageTemplate"
module=
"Products.PageTemplates.ZopePageTemplate"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
_bind_names
</string>
</key>
<value>
<object>
<klass>
<global
name=
"NameAssignments"
module=
"Shared.DC.Scripts.Bindings"
/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key>
<string>
_asgns
</string>
</key>
<value>
<dictionary>
<item>
<key>
<string>
name_subpath
</string>
</key>
<value>
<string>
traverse_subpath
</string>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key>
<string>
content_type
</string>
</key>
<value>
<string>
text/html
</string>
</value>
</item>
<item>
<key>
<string>
expand
</string>
</key>
<value>
<int>
0
</int>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
PaySheetTransaction_generatePayslipReportHeader
</string>
</value>
</item>
<item>
<key>
<string>
output_encoding
</string>
</key>
<value>
<string>
utf-8
</string>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<unicode></unicode>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
bt5/erp5_payroll/SkinTemplateItem/portal_skins/erp5_payroll/PaySheetTransaction_generatePayslipReportHeader.zpt
0 → 100644
View file @
c48ce799
<tal:block tal:define="data_dict here/PaySheetTransaction_getODTDataDict;
other_data_dict here/PaySheetTransaction_getOtherInformationsDataDict;
language python: options.get('language');
date_renderer nocall:here/Base_viewFieldLibrary/my_date_time_field/render_pdf;
">
<div class="ci-book-report-content-header-wrapper">
<span tal:content='python: here.Base_translateString("Payslip", lang=language)'></span>
<span tal:content='python: here.Base_translateString("From ${start_date} to ${stop_date}",
lang=language,
mapping={
"start_date": date_renderer(here.getStartDate()),
"stop_date": date_renderer(here.getStopDate())})'></span>
<table class="ci-book-table">
<tbody>
<tr>
<td style="background:#fff">
<div class="ci-book-report-content-card">
<span class='ci-book-report-emphasis ci-book-report-headline' tal:content='python:data_dict["destination_section_title"]'>destination_section</span>
<span tal:content='python:data_dict["destination_section_address"]'>address</span>
<span tal:condition='data_dict/destination_section_corporate_registration_codeid' tal:content='python:data_dict["destination_section_corporate_registration_codeid"]'>SIRET</span>
<span tal:condition='data_dict/destination_section_activity_codeid' tal:content='python:data_dict["destination_section_activity_codeid"]'>APE</span>
</div>
<td style="background:#fff">
<div class="ci-book-report-content-card">
<div class="ci-book-report-content-card">
<span class='ci-book-report-emphasis ci-book-report-headline' tal:content='python:data_dict["source_section_title"]'>source_section</span>
<span tal:content='python:data_dict["source_section_address"]'>address</span>
<span tal:condition='other_data_dict/source_section_default_career_social_code' tal:content='python:other_data_dict["source_section_default_career_social_code"]'>185897778270987</span>
<span tal:condition='other_data_dict/source_section_default_career_start_date' tal:content='python:other_data_dict["source_section_default_career_start_date"]'>12/09/2005</span>
<span tal:condition='other_data_dict/source_section_career_title' tal:content='python:other_data_dict["source_section_career_title"]'>Réceptionniste</span>
<span tal:condition='other_data_dict/source_section_default_career_coefficient' tal:content='python:other_data_dict["source_section_default_career_coefficient"]'>100</span>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</tal:block>
\ No newline at end of file
bt5/erp5_payroll/SkinTemplateItem/portal_skins/erp5_payroll/PaySheetTransaction_getLineListAsDict.py
View file @
c48ce799
...
...
@@ -25,6 +25,9 @@ for line in line_list:
if
line
.
getResourceId
()
==
'total_employee_contributions'
:
continue
line_dict
=
{
'report_section'
:
line
.
getReportSection
(),
'group_by_report_section'
:
line
.
getGroupByReportSection
(),
'resource_title'
:
line
.
getResourceTitle
(),
'group'
:
line
.
getSourceSectionTitle
(),
'source_section_title'
:
line
.
getSourceSectionTitle
(),
'title'
:
line
.
getTitle
(),
...
...
bt5/erp5_payroll/SkinTemplateItem/portal_skins/erp5_payroll/PaySheetTransaction_getPayslipData.py
View file @
c48ce799
"""
================================================================================
Get data to build a payslip report based on a person's paysheet transaction
================================================================================
"""
#
# parameters
# ------------------------------------------------------------------------------
# start_date start date of the report
# stop_date stop date of the report
#
# returns:
# {
# "general_data_dict": {
# "year": 2017,
# "net_salary": "2 300.93",
# "gross_salary": "3 085.28"
# },
# "cumulative_title_list": [
# {"value": "Gross Salary", "is_header": True},
# ...
# ],
# "cumulative_info_list":[
# {"value": "3 085.28", "is_header": True},
# ...
# ],
# 'destination_address_line_list': [
# {"value": "USERTEST Slicea", "is_header": True},
# {"value": "2 rue unerue"},
# ...
# ],
# 'destination_hiring_info_list': [
# {"value": "Hiring Date: 1990/10/10"},
# ...
# ],
# 'destination_attendance_info_list': [
# {"value": "Normal Working Hours": 151.67"},
# ...
# ]
# 'destination_vacation_info_list': [
# {"value": "Earned this period: "},
# ...
# ],
# 'destination_taxation_info_list': [
# {"value": "Price Currency: EUR"},
# ],
# 'source_address_line_list: [
# {"value": "Nexedi SA", "is_header": True},
# {"value": "147 Rue du Ballon"}
# ...
# ],
# source_corporate_info_line_list: [
# {"value": "Corporate Registration Code: 440047504 00020"},
# {"value": "Activity Code: 5829C"},
# ...
# ],
# "payslip_section_list": [
# [
# {"value": "Usertest Slicea", "is_header": True, "value_base": "", "value_employee_share_rate": "", "value_employee_share": "", "value_employer_share_rate": "", "value_employer_share": ""},
# {"value": "Salarie de Base", "value_base": "2 805.28", "value_employee_share_rate": "", "value_employee_share": "", "value_employer_share_rate": "", "value_employer_share": ""}
# ], [
# ...
# ]
# ]
#}
response
=
{
"general_data_dict"
:
{
"year"
:
""
,
"net_salary"
:
""
,
"gross_salary"
:
""
},
"cumulative_title_list"
:
[],
"cumulative_info_list"
:
[],
"destination_address_line_list"
:
[],
"destination_hiring_info_list"
:
[],
"destination_attendance_info_list"
:
[],
"destination_vacation_info_list"
:
[],
"destination_taxation_info_list"
:
[],
"source_address_line_list"
:
[],
"source_corporate_info_line_list"
:
[],
"payslip_section_list"
:
[]
from
DateTime
import
DateTime
line_dict_list
=
context
.
PaySheetTransaction_getLineListAsDict
()
new_line_dict_list
=
[]
previous_line_dict
=
None
previous_report_section
=
None
gross_category
=
'base_amount/payroll/report/salary/gross'
line_to_group_list
=
[]
exception_line
=
True
def
getReportSectionTitle
(
title
):
if
title
.
startswith
(
'report_section'
):
return
context
.
portal_categories
.
restrictedTraverse
(
title
).
getTitle
()
return
title
def
getFakeLineDictForNewSection
(
title
,
base
=
0
,
employer_price
=
0
,
employer_total_price
=
0
,
employee_price
=
0
,
employee_total_price
=
0
):
return
{
'title'
:
title
.
upper
(),
'base'
:
base
,
'employer_price'
:
employer_price
,
'employer_total_price'
:
employer_total_price
,
'employee_price'
:
employee_price
,
'employee_total_price'
:
employee_total_price
}
def
groupSameReportSectionLine
(
line_to_group_list
):
tmp_base_dict
=
{}
title
=
getReportSectionTitle
(
line_to_group_list
[
0
][
'report_section'
])
for
line_dict
in
line_to_group_list
:
base
=
line_dict
[
'base'
]
if
base
not
in
tmp_base_dict
:
tmp_base_dict
[
base
]
=
getFakeLineDictForNewSection
(
title
,
base
)
tmp_base_dict
[
base
][
'employer_price'
]
=
tmp_base_dict
[
base
][
'employer_price'
]
+
(
line_dict
[
'employer_price'
]
or
0
)
tmp_base_dict
[
base
][
'employer_total_price'
]
=
tmp_base_dict
[
base
][
'employer_total_price'
]
+
(
line_dict
[
'employer_total_price'
]
or
0
)
tmp_base_dict
[
base
][
'employee_price'
]
=
tmp_base_dict
[
base
][
'employee_price'
]
+
(
line_dict
[
'employee_price'
]
or
0
)
tmp_base_dict
[
base
][
'employee_total_price'
]
=
tmp_base_dict
[
base
][
'employee_total_price'
]
+
(
line_dict
[
'employee_total_price'
]
or
0
)
new_value_list
=
[]
for
_
,
value
in
tmp_base_dict
.
iteritems
():
new_value_list
.
append
(
value
)
return
new_value_list
employer_total_price
=
0
employee_total_price
=
0
for
current_line_dict
in
line_dict_list
:
if
current_line_dict
[
'resource_title'
].
startswith
(
'CSG'
):
csg_base
=
current_line_dict
[
'base'
]
current_report_section
=
current_line_dict
[
'report_section'
]
or
current_line_dict
[
'group'
]
# New section
if
previous_report_section
!=
current_report_section
:
if
len
(
line_to_group_list
):
new_line_dict_list
+=
groupSameReportSectionLine
(
line_to_group_list
)
exception_line
=
True
line_to_group_list
=
[]
if
current_report_section
==
'report_section/payroll/fr/amount_not_subject_to_contribution'
:
new_line_dict_list
.
append
(
getFakeLineDictForNewSection
(
context
.
Base_translateString
(
"TOTAL FEES AND CONTRIBUTIONS"
),
employer_total_price
=
employer_total_price
,
employee_total_price
=
employee_total_price
))
employer_total_price
=
0
employee_total_price
=
0
# add one line for gross salary
if
previous_line_dict
is
not
None
and
gross_category
in
previous_line_dict
[
'base_contribution_list'
]
and
gross_category
not
in
current_line_dict
[
'base_contribution_list'
]:
new_line_dict_list
.
append
(
getFakeLineDictForNewSection
(
context
.
Base_translateString
(
"Gross Salary"
),
base
=
context
.
PaySheetTransaction_getMovementTotalPriceFromCategory
(
base_contribution
=
"base_contribution/%s"
%
gross_category
)))
if
current_line_dict
[
'group_by_report_section'
]:
line_to_group_list
.
append
(
current_line_dict
)
else
:
if
previous_report_section
!=
current_report_section
:
new_line_dict_list
.
append
(
getFakeLineDictForNewSection
(
getReportSectionTitle
(
current_report_section
)))
if
len
(
line_to_group_list
)
and
exception_line
:
exception_line
=
False
new_line_dict_list
.
append
(
getFakeLineDictForNewSection
(
getReportSectionTitle
(
current_report_section
)))
new_line_dict_list
.
append
(
current_line_dict
)
employer_total_price
+=
(
current_line_dict
[
'employer_total_price'
]
or
0
)
employee_total_price
+=
(
current_line_dict
[
'employee_total_price'
]
or
0
)
previous_report_section
=
current_report_section
previous_line_dict
=
current_line_dict
new_line_dict_list
.
append
(
getFakeLineDictForNewSection
(
context
.
Base_translateString
(
"TOTAL AMOUNTS NOT SUBJECT TO CONTRIBUTIONS"
),
employer_total_price
=
employer_total_price
,
employee_total_price
=
employee_total_price
))
gross_salary
=
context
.
PaySheetTransaction_getMovementTotalPriceFromCategory
(
base_contribution
=
"base_contribution/%s"
%
gross_category
)
net_salary
=
context
.
PaySheetTransaction_getMovementTotalPriceFromCategory
(
base_contribution
=
'base_contribution/base_amount/payroll/report/salary/net'
,
contribution_share
=
'contribution_share/employee'
)
currency
=
context
.
getPriceCurrencyValue
()
is
not
None
and
context
.
getPriceCurrencyValue
().
getShortTitle
()
or
context
.
getPriceCurrencyReference
()
or
''
start_date
=
context
.
getStartDate
()
amount_benefit
=
0
if
DateTime
(
'2018/01/01'
)
<=
start_date
<=
DateTime
(
'2018/09/30'
):
amount_benefit
=
gross_salary
*
0.022
-
csg_base
*
0.017
elif
start_date
>=
DateTime
(
'2018/10/01'
):
amount_benefit
=
gross_salary
*
0.0315
-
csg_base
*
0.017
return
{
"payslip_line_list"
:
new_line_dict_list
,
"gross_salary"
:
gross_salary
,
"net_salary"
:
net_salary
,
"currency"
:
currency
,
"amount_benefit"
:
amount_benefit
}
return
response
bt5/erp5_payroll/SkinTemplateItem/portal_skins/erp5_payroll/PaySheetTransaction_printPayslipReport.py
View file @
c48ce799
...
...
@@ -11,12 +11,12 @@ Wire PaySheetTransaction through to erp5_corporate_identity Report
# format: output in html*, pdf
# international_form translate terms
# language target_language
return
context
.
Base_printAsReport
(
format
=
format
,
report_
title
=
"Payslip
"
,
report_
header
=
"PaySheetTransaction_generatePayslipReportHeader
"
,
report_name
=
"PaySheetTransaction_generatePayslipReport"
,
language
=
target_language
,
report_footer
=
"PaySheetTransaction_generatePayslipReportFooter"
,
document_language
=
target_language
,
start_date
=
context
.
getStartDate
()
or
None
,
stop_date
=
context
.
getStopDate
()
or
None
,
**
kw
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment