Commit 71a15fef authored by Tristan Cavelier's avatar Tristan Cavelier

erp5_payroll_l10n_fr: XXX

parent 3066c9aa
......@@ -26,7 +26,7 @@ if block_id == 'S20.G00.05':
rubric_value_dict['S20.G00.05.001'] = kw['dsn_type']
rubric_value_dict['S20.G00.05.002'] = '01'
rubric_value_dict['S20.G00.05.003'] = '11'
rubric_value_dict['S20.G00.05.004'] = '1' # TODO : to increment for each new event DSN
rubric_value_dict['S20.G00.05.004'] = kw['order']
rubric_value_dict['S20.G00.05.006'] = ''
rubric_value_dict['S20.G00.05.007'] = formatDate(DateTime(now.year(), now.month(), now.day()))
rubric_value_dict['S20.G00.05.009'] = ''
......@@ -54,11 +54,14 @@ elif block_id == 'S21.G00.11':
# Individu
if block_id == 'S21.G00.30':
rubric_value_dict["S21.G00.30.001"] = ''.join(target.getSocialCode().split(' '))[:13] # sometimes there are spaces in textfield
social_code = target.getSocialCode('')
rubric_value_dict["S21.G00.30.001"] = ("" if not social_code else "".join(social_code.split(' '))[:13])
rubric_value_dict["S21.G00.30.001"] = ''.join(target.getSocialCode('').split(' '))[:13] # sometimes there are spaces in textfield
rubric_value_dict["S21.G00.30.002"] = target.getLastName()
rubric_value_dict["S21.G00.30.003"] = '' # Nom d'usage
rubric_value_dict["S21.G00.30.004"] = ' '.join([target.getFirstName(), target.getMiddleName() or '']).strip()
rubric_value_dict["S21.G00.30.006"] = formatDate(target.getStartDate())
rubric_value_dict["S21.G00.30.020"] = target.getCareerReference('')
# Contrat
if block_id == 'S21.G00.40':
......
......@@ -212,6 +212,11 @@ if block_id == 'S21.G00.23':
if block_id == 'S21.G00.30':
birth_country_code = getCountryCode(target)
address = target.getDefaultAddressStreetAddress().strip().split('\n')
if ',' in address[0]:
address_complement = address[0].split(',', 1)[1].strip()
address[0] = address[0].split(',', 1)[0]
else:
address_complement = ''
social_code = target.getSocialCode('')
rubric_value_dict["S21.G00.30.001"] = ("" if not social_code else "".join(social_code.split(' '))[:13])
rubric_value_dict["S21.G00.30.002"] = target.getLastName()
......@@ -229,7 +234,7 @@ if block_id == 'S21.G00.30':
rubric_value_dict["S21.G00.30.013"] = enrollment_record.getUeCode()
rubric_value_dict["S21.G00.30.014"] = enrollment_record.getBirthDepartment()
rubric_value_dict["S21.G00.30.015"] = enrollment_record.getBirthCountryCode()
rubric_value_dict["S21.G00.30.016"] = ''
rubric_value_dict["S21.G00.30.016"] = address_complement
rubric_value_dict["S21.G00.30.017"] = (' '.join(address[1:]).strip() if len(address) > 1 else '')
rubric_value_dict["S21.G00.30.018"] = target.getDefaultEmailCoordinateText() or ''
rubric_value_dict["S21.G00.30.019"] = ''
......@@ -248,6 +253,8 @@ if block_id == 'S21.G00.40':
rubric_value_dict["S21.G00.40.008"] = enrollment_record.getSpecialContractType()
rubric_value_dict["S21.G00.40.009"] = '00000'
rubric_value_dict["S21.G00.40.010"] = ('' if enrollment_record.getContractType() not in ('02', '29') else formatDate(enrollment_record.getCareerStopDate()))
if enrollment_record.getCareerStopDate() and enrollment_record.getCareerStopDate() <= context.getEffectiveDate():
rubric_value_dict["S21.G00.40.010"] = formatDate(enrollment_record.getCareerStopDate())
rubric_value_dict["S21.G00.40.011"] = enrollment_record.getWorkingUnitType()
rubric_value_dict["S21.G00.40.012"] = formatFloat(enrollment_record.getStandardWorkingUnit())
rubric_value_dict["S21.G00.40.013"] = formatFloat(enrollment_record.getWorkingUnitQuantity())
......@@ -379,6 +386,10 @@ if block_id == 'S21.G00.71':
code = 'RETA'
elif enrollment_record.getComplementaryRetirementStatus() == '01':
code = 'RETC'
elif enrollment_record.getComplementaryRetirementStatus() == '99':
code = '90000'
else:
raise ValueError('Unsupported Code for Complementary Retirement Status in Enrollement Record %s' % enrollment_record.absolute_url())
rubric_value_dict['S21.G00.71.002'] = code
if block_id == 'S21.G00.78':
......
......@@ -70,7 +70,7 @@ if block_id == 'S10.G00.02':
if block_id == 'S10.G00.03':
rubric_value_dict['S10.G00.03.001'] = ''.join(target.getCorporateRegistrationCode().split(' '))[:9]
rubric_value_dict['S10.G00.03.002'] = ''.join(target.getCorporateRegistrationCode().split(' '))[-5:]
rubric_value_dict['S10.G00.03.003'] = target.getDefaultEmailUrlString()
rubric_value_dict['S10.G00.03.003'] = context.getSourceAdministrationValue().getDefaultEmailUrlString()
# Declaration
if block_id == 'S20.G00.05':
......@@ -133,20 +133,20 @@ if block_id == 'S21.G00.15':
# Versement organisme de protection sociale
if block_id == 'S21.G00.20':
bank_account = kw['bank_account']
rubric_value_dict['S21.G00.20.001'] = ''
rubric_value_dict['S21.G00.20.001'] = ''.join(kw['destination_payment'].getCorporateRegistrationCode().split(' '))
rubric_value_dict['S21.G00.20.002'] = ''.join(target.getCorporateRegistrationCode().split(' '))
rubric_value_dict['S21.G00.20.003'] = bank_account.getBicCode()
rubric_value_dict['S21.G00.20.004'] = bank_account.getIban()
rubric_value_dict['S21.G00.20.005'] = ''
rubric_value_dict['S21.G00.20.006'] = formatDate(DateTime(kw['year'], kw['month'], 1))
rubric_value_dict['S21.G00.20.007'] = formatDate(getLastDateOfMonth(DateTime(kw['year'], kw['month'])))
rubric_value_dict['S21.G00.20.007'] = formatDate(getLastDateOfMonth(context.getEffectiveDate()))
# Bordereau de cotisation due
if block_id == 'S21.G00.22':
rubric_value_dict['S21.G00.22.001'] = ''
rubric_value_dict['S21.G00.22.001'] = ''.join(kw['destination_payment'].getCorporateRegistrationCode().split(' '))
rubric_value_dict['S21.G00.22.002'] = ''.join(target.getCorporateRegistrationCode().split(' '))
rubric_value_dict['S21.G00.22.003'] = formatDate(DateTime(kw['year'], kw['month'], 1))
rubric_value_dict['S21.G00.22.004'] = formatDate(getLastDateOfMonth(DateTime(kw['year'], kw['month'])))
rubric_value_dict['S21.G00.22.004'] = formatDate(getLastDateOfMonth(context.getEffectiveDate()))
rubric_value_dict['S21.G00.22.005'] = '' # Sum of all contributions for the social services organisation
# Individu
......@@ -161,7 +161,7 @@ if block_id == 'S21.G00.30':
rubric_value_dict["S21.G00.30.006"] = formatDate(target.getStartDate())
rubric_value_dict["S21.G00.30.007"] = (target.getDefaultBirthplaceAddressCity() if enrollment_record.getBirthCountryCode() in france_territory_code else enrollment_record.getBirthCountryCode())
rubric_value_dict["S21.G00.30.008"] = address[0].strip()
rubric_value_dict["S21.G00.30.009"] = target.getDefaultAddressZipCode()
rubric_value_dict["S21.G00.30.009"] = ('' if enrollment_record.getDistributionCode() is not None else target.getDefaultAddressZipCode())
rubric_value_dict["S21.G00.30.010"] = target.getDefaultAddressCity()
rubric_value_dict["S21.G00.30.011"] = (birth_country_code if birth_country_code not in france_territory_code else '')
rubric_value_dict["S21.G00.30.012"] = enrollment_record.getDistributionCode() or ''
......@@ -186,7 +186,7 @@ if block_id == 'S21.G00.40':
rubric_value_dict["S21.G00.40.007"] = enrollment_record.getContractType()
rubric_value_dict["S21.G00.40.008"] = enrollment_record.getSpecialContractType()
rubric_value_dict["S21.G00.40.009"] = '00000'
rubric_value_dict["S21.G00.40.010"] = ('' if enrollment_record.getContractType() != '29' else formatDate(enrollment_record.getCareerStopDate()))
rubric_value_dict["S21.G00.40.010"] = ('' if enrollment_record.getContractType() not in ('02', '29') else formatDate(enrollment_record.getCareerStopDate()))
rubric_value_dict["S21.G00.40.011"] = enrollment_record.getWorkingUnitType()
rubric_value_dict["S21.G00.40.012"] = formatFloat(enrollment_record.getStandardWorkingUnit())
rubric_value_dict["S21.G00.40.013"] = formatFloat(enrollment_record.getWorkingUnitQuantity())
......@@ -197,7 +197,7 @@ if block_id == 'S21.G00.40':
rubric_value_dict["S21.G00.40.018"] = enrollment_record.getMedicalScheme()
rubric_value_dict["S21.G00.40.019"] = ''
rubric_value_dict["S21.G00.40.020"] = enrollment_record.getRetirementScheme()
rubric_value_dict["S21.G00.40.021"] = ''
rubric_value_dict["S21.G00.40.021"] = ('' if enrollment_record.getContractType() != '02' else '02')
rubric_value_dict["S21.G00.40.022"] = ''
rubric_value_dict["S21.G00.40.023"] = ''
rubric_value_dict["S21.G00.40.024"] = enrollment_record.getExpatriateStatus()
......@@ -234,14 +234,16 @@ if block_id == 'S21.G00.62':
rubric_value_dict['S21.G00.62.001'] = formatDate(enrollment_record.getCareerStopDate())
if enrollment_record.getContractType() == '29':
rubric_value_dict['S21.G00.62.002'] = '999'
# TODO : currently only works for end of training periods
return rubric_value_dict
# TODO : currently only works for end of training periods XXX (and CDD)
rubric_value_dict['S21.G00.62.002'] = '031'
rubric_value_dict['S21.G00.62.003'] = ''
rubric_value_dict['S21.G00.62.004'] = ''
rubric_value_dict['S21.G00.62.005'] = ''
rubric_value_dict['S21.G00.62.006'] = ''
rubric_value_dict['S21.G00.62.007'] = ''
rubric_value_dict['S21.G00.62.008'] = ''
rubric_value_dict['S21.G00.62.009'] = ''
rubric_value_dict['S21.G00.62.009'] = '02'
rubric_value_dict['S21.G00.62.010'] = ''
rubric_value_dict['S21.G00.62.011'] = ''
rubric_value_dict['S21.G00.62.012'] = ''
......
......@@ -11,6 +11,7 @@ catalog_kw = {'query': ComplexQuery(Query(start_date=">=%s" % from_date.strftime
Query(stop_date="<=%s" % to_date.strftime("%Y/%m/%d")),
Query(destination_trade_uid=Query(destination_trade_uid=destination_trade.getUid())),
Query(simulation_state='!=cancelled'),
Query(simulation_state='!=deleted'),
logical_operator="AND")}
paysheet_list = portal.accounting_module.searchFolder(portal_type="Pay Sheet Transaction", **catalog_kw)
......
......@@ -16,12 +16,12 @@ cice_relative_min_salary = {}
fillon_relative_min_salary = {}
fillon_individual_reduction = {}
# Social Entity corporate registration code
SOCIAL_ENTITY = ''
SOCIAL_ENTITY = ''.join(payment_transaction.getDestinationSectionValue().getCorporateRegistrationCode().split(' '))
# establishment paysheets belong to
current_establishement_code = portal.accounting_module[paysheet_list[0]].getDestinationSectionValue().getCorporateRegistrationCode()[-5:]
# Rate to apply to bases to calculate the final amount of fees
standard_rate_mapping = {'012D': 0.28, '027D': 0.00016, '100D': 0.1954, '100P': 0.1545,
standard_rate_mapping = {'012D': 0.20, '027D': 0.00016, '100D': 0.1954, '100P': 0.1545,
'260D': 0.08, '332P': 0.001, '343D': 0.024, '400D': 0., '430D': 0.018,
'479D': 0.08, '671P': 1., '772D': 0.064, '863D': 0.2134,
'863P': 0.1545, '937D': 0.0025}
......@@ -48,12 +48,12 @@ def updateIndividualFeeDict(paysheet_id, temp_individual_fee_dict):
('03', '100D'),
('03', '863D'),
('04', '260D'),
('04', '012D'),
#('04', '012D'),
('04', '0000'),
('07', '772D'),
('07', '343D'),
('10', '260D'), # "Base brute fiscale" is the same as "base CSG"
('10', '012D'),
#('10', '012D'),
('10', '0000'),
('12', '400D'),
('13', '479D'),
......@@ -84,17 +84,23 @@ for paysheet_id in paysheet_list:
establishment = paysheet.getDestinationSectionValue()
enrollment_record = employee.Person_getPayrollEnrollmentRecord(establishment)
gross_salary = paysheet.PaySheetTransaction_getMovementTotalPriceFromCategory(base_contribution="base_contribution/base_amount/payroll/report/salary/gross")
# Trainees don't contribute to aggregated fees
if enrollment_record.getContractType() == '29':
individual_fee_dict[paysheet_id] = {'02': 0., '03': 0.}
continue
# First we need to store the legal minimun salary, proportionally to the worked time
minimum_salary = float(paysheet.getRatioQuantityFromReference('salaire_minimum_mensuel'))
worked_time = float(enrollment_record.getWorkingUnitQuantity())
normal_working_time = float(enrollment_record.getStandardWorkingUnit())
relative_minimum_salary = minimum_salary * (worked_time / normal_working_time)
gross_salary = paysheet.PaySheetTransaction_getMovementTotalPriceFromCategory(base_contribution="base_contribution/base_amount/payroll/report/salary/gross")
#individual_fee_dict[paysheet_id] = {'02': 0., '03': 0.}
individual_fee_dict[paysheet_id] = {'02': gross_salary, '03': gross_salary}
if gross_salary == 0.0:
continue
else :
# First we need to store the legal minimun salary, proportionally to the worked time
minimum_salary = float(paysheet.getRatioQuantityFromReference('salaire_minimum_mensuel'))
worked_time = float(enrollment_record.getWorkingUnitQuantity())
normal_working_time = float(enrollment_record.getStandardWorkingUnit())
if normal_working_time != 0.0:
relative_minimum_salary = minimum_salary * (worked_time / normal_working_time)
else:
relative_minimum_salary = 0.0
for paysheet_line in paysheet_line_list:
# we only want paysheet lines contributing to a social service related to DSN
......@@ -115,16 +121,19 @@ for paysheet_id in paysheet_list:
if ctp[-1] not in ('P', 'D'):
standard_rate_mapping[ctp] = rate
current_ctp_set.add(ctp) # Employee already contributed to this category
if not SOCIAL_ENTITY:
SOCIAL_ENTITY = paysheet_line.getSourceSectionValue().getCorporateRegistrationCode()
#if not SOCIAL_ENTITY:
# SOCIAL_ENTITY = paysheet_line.getSourceSectionValue().getCorporateRegistrationCode()
# For transport fee
if ctp == '900T':
transport_individual_fee[paysheet_id] = (float(base), SOCIAL_ENTITY, abs(float(base)*float(rate)), INSEE_CODE)
# For "Fillon" reduction fee
if ctp == '671P':
if ctp == '671P' and enrollment_record.getContractType() != '29' :
fillon_relative_min_salary[paysheet_id] = relative_minimum_salary
fillon_individual_reduction[paysheet_id] = base
if enrollment_record.getContractType() == '29':
continue
# Let's compute CTP 400D, which doesn't appear on paysheet
# 400D only applies if gross salary is lower than a maximum
other_information_dict = paysheet.PaySheetTransaction_getOtherInformationsDataDict()
......@@ -182,7 +191,7 @@ def getFeeBlocAsDict(ctp, ctp_dict):
bloc["S21.G00.23.005"] = "%.02f" % round(ctp_dict[ctp])
# For 260D we need to add other "forfait social" bases too
elif ctp == '260D':
bloc["S21.G00.23.004"] = "%.02f" % round(ctp_dict[ctp] + ctp_dict.get('012D', 0.) + ctp_dict.get('0000', 0.))
bloc["S21.G00.23.004"] = "%.02f" % round(ctp_dict[ctp] + ctp_dict.get('0000', 0.)) #ctp_dict.get('012D', 0.) + ctp_dict.get('0000', 0.))
# All standard cases
else:
bloc["S21.G00.23.004"] = "%.02f" % round(ctp_dict[ctp])
......
......@@ -50,7 +50,7 @@
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>paysheet_list=None</string> </value>
<value> <string>paysheet_list=None, payment_transaction=None</string> </value>
</item>
<item>
<key> <string>id</string> </key>
......
......@@ -136,15 +136,15 @@ dsn_file.append(getDSNBlockDict(block_id='S21.G00.11', target=establishment, man
dsn_file.append(getDSNBlockDict(block_id='S21.G00.15', target=establishment))
# Print aggregated cotisations
cotisation_dict = context.DSNMonthlyReport_getSocialContributionDict(paysheet_id_list)
cotisation_dict = context.DSNMonthlyReport_getSocialContributionDict(paysheet_id_list, payment_transaction=payment_transaction)
bank_account = payment_transaction.getSourcePaymentValue()
bloc_versement = getDSNBlockDict(block_id='S21.G00.20', target=establishment, bank_account=bank_account, year=declared_year, month=declared_month)
bloc_versement = getDSNBlockDict(block_id='S21.G00.20', target=establishment, destination_payment=payment_transaction.getDestinationSectionValue(), bank_account=bank_account, year=declared_year, month=declared_month)
for rubric, value in cotisation_dict['payment']:
bloc_versement[rubric] = value
dsn_file.append(bloc_versement)
bloc_payment_slip = getDSNBlockDict(block_id='S21.G00.22', target=establishment, year=declared_year, month=declared_month)
bloc_payment_slip = getDSNBlockDict(block_id='S21.G00.22', target=establishment, destination_payment=payment_transaction.getDestinationSectionValue(), year=declared_year, month=declared_month)
for rubric, value in cotisation_dict['total_payment_slip']:
bloc_payment_slip[rubric] = value
dsn_file.append(bloc_payment_slip)
......
......@@ -191,6 +191,9 @@ else:
dsn_file.append(getDSNBlockDict(block_id='S21.G00.23',
target=aggregated_social_contribution_dict[ctp_code]))
dsn_file.append(getDSNBlockDict(block_id='S21.G00.42', target=establishment))
dsn_file.append(getDSNBlockDict(block_id='S21.G00.44', target=establishment))
for employee_data_dict, paysheet_data_dict in employee_result_list:
enrollment_record = employee_data_dict['enrollment_record']
employee = employee_data_dict['person_relative_url']
......
data = context.getTextContent().decode('utf-8').encode('iso-8859-1')
import unicodedata
data = unicodedata.normalize('NFKD', context.getTextContent().decode('utf-8')).encode('iso-8859-1', 'ignore')
# Update sending mode "on the fly"
dsn_line_list = data.split('\n')
......
......@@ -14,8 +14,18 @@
</item>
<item>
<key> <string>action</string> </key>
<value> <string>Base_edit</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>edit_order</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>encoding</string> </key>
<value> <string>UTF-8</string> </value>
......@@ -87,6 +97,10 @@
<key> <string>name</string> </key>
<value> <string>Organisation_viewDSNReportConfiguration</string> </value>
</item>
<item>
<key> <string>pt</string> </key>
<value> <string>form_view</string> </value>
</item>
<item>
<key> <string>row_length</string> </key>
<value> <int>4</int> </value>
......@@ -103,6 +117,14 @@
<key> <string>unicode_mode</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>update_action</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>update_action_title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
......
......@@ -109,7 +109,7 @@ def makeIndividualContributionBlock(movement, category):
if category in ('018', '063', '064', '059'):
quantity = (getattr(movement, 'employer_total_price', 0) + getattr(movement, 'employee_total_price', 0)) * -1
if category == '018':
assert quantity < 0.
assert quantity <= 0., "Quantity in %s should be negative" % movement.absolute_url()
base = movement.base
else:
base = movement.base
......@@ -139,6 +139,9 @@ def makeOtherBonusBlock(movement, category):
}
for movement in context.PaySheetTransaction_getMovementList():
if not movement.base:
continue
contribution_set = set(movement.getBaseContributionValueList())
ctp_set = all_ctp_set.intersection(contribution_set)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment