1033 lines
45 KiB
Python
1033 lines
45 KiB
Python
from copy import deepcopy
|
|
import datetime
|
|
from odoo import fields
|
|
from odoo.tools.misc import format_date
|
|
from odoo.tools.float_utils import float_round
|
|
import re
|
|
import uuid
|
|
from collections import defaultdict
|
|
|
|
|
|
SALARY_TYPE_MAPPING = {
|
|
"AHV-AVS-Salaries": "AHV-AVS-Salary",
|
|
"FAK-CAF-Salaries": "FAK-CAF-Salary",
|
|
"UVG-LAA-Salaries": "UVG-LAA-Salary",
|
|
"UVGZ-LAAC-Salaries": "UVGZ-LAAC-Salary",
|
|
"KTG-AMC-Salaries": "KTG-AMC-Salary",
|
|
"BVG-LPP-Salaries": "BVG-LPP-Salary",
|
|
"TaxCrossborderSalaries": "TaxCrossborderSalary",
|
|
"TaxSalaries": "TaxSalary",
|
|
"TaxAtSourceSalaries": "TaxAtSourceSalary",
|
|
"StatisticSalaries": "StatisticSalary"
|
|
}
|
|
XSD_SKIP_VALUE = "XSDSKIP"
|
|
|
|
INSTITUTION_MODEL_MAPPING = {
|
|
"l10n.ch.social.insurance": "AHV-AVS",
|
|
"l10n.ch.compensation.fund": "FAK-CAF",
|
|
"l10n.ch.sickness.insurance": "KTG-AMC",
|
|
"l10n.ch.accident.insurance": "UVG-LAA",
|
|
"l10n.ch.additional.accident.insurance": "UVGZ-LAAC",
|
|
"l10n.ch.lpp.insurance": "BVG-LPP",
|
|
"l10n.ch.location.unit": "TaxCrossborder",
|
|
"l10n.ch.source.tax.institution": "TaxAtSource",
|
|
"BFS": "Statistic",
|
|
"Tax": "Tax"
|
|
}
|
|
|
|
MAPPED_DOMAIN_IDENTIFICATION = {
|
|
"AHV-AVS": "AHV-AVS-Identification",
|
|
"FAK-CAF": "FAK-CAF-Identification",
|
|
"UVG-LAA": "UVG-LAA-Identification",
|
|
"UVGZ-LAAC": "UVGZ-LAAC-Identification",
|
|
"KTG-AMC": "KTG-AMC-Identification",
|
|
"BVG-LPP": "BVG-LPP-Identification",
|
|
"Tax": "TaxIdentification",
|
|
"TaxAtSource": "TaxAtSourceIdentification",
|
|
"TaxCrossborder": "TaxCrossborderIdentification",
|
|
"Statistic": "StatisticIdentification"
|
|
}
|
|
|
|
IS_REASON_MAPPING = {
|
|
'entryCompany': ('Entry', 'entryCompany'),
|
|
'entryCanton': ('Entry', 'cantonChange'),
|
|
'entryOther': ('Entry', 'others'),
|
|
'withdrawalCompany': ('Withdrawal', 'withdrawalCompany'),
|
|
'withdrawalNat': ('Withdrawal', 'naturalization'),
|
|
'withdrawalSettled': ('Withdrawal', 'settled-C'),
|
|
'withdrawalCanton': ('Withdrawal', 'cantonChange'),
|
|
'withdrawalOther': ('Withdrawal', 'others'),
|
|
'civilstate': ('Mutation', 'civilstate'),
|
|
'partnerWork': ('Mutation', 'partnerWork'),
|
|
'partnerWorkplaceChangeCHAbroad': ('Mutation', 'partnerWorkplaceChangeCHAbroad'),
|
|
'residence': ('Mutation', 'residence'),
|
|
'childrenDeduction': ('Mutation', 'childrenDeduction'),
|
|
'churchTax': ('Mutation', 'churchTax'),
|
|
'others': ('Mutation', 'others')
|
|
}
|
|
|
|
|
|
IS_CODE_PATTERN = r"^[ABCDEFGHLNMPQRSTU][0-9][YN]$"
|
|
|
|
missing_value = "XSDMISSING"
|
|
XSD_YMONTH = "XSDGYEARMONTH"
|
|
|
|
|
|
class SwissdecInstitution:
|
|
def __init__(self, institution, pay_agreement=None, payroll_unit=None):
|
|
if institution:
|
|
assert isinstance(institution, str)
|
|
if pay_agreement:
|
|
assert isinstance(pay_agreement, str)
|
|
if payroll_unit:
|
|
assert isinstance(payroll_unit, str)
|
|
self._name = institution
|
|
self.pay_agreement = pay_agreement
|
|
self.payroll_unit = payroll_unit
|
|
|
|
|
|
class SwissdecDeclaration:
|
|
"""
|
|
Helper Class to Display and perform operations on Swissdec declare salary objects
|
|
documentation : https://www.swissdec.ch/fr/elm
|
|
"""
|
|
|
|
@staticmethod
|
|
def amount2str(amount):
|
|
return f"{amount:.2f}"
|
|
|
|
def create_ahv_avs_ema(self, institution_id, declaration_category, valid_as_of, month, year, acc_from, acc_until, ceo_rel=False):
|
|
ema = {
|
|
"institutionIDRef": self.get_institution_id_ref(institution_id),
|
|
"DeclarationCategory": {
|
|
declaration_category: {"ValidAsOf": valid_as_of}
|
|
},
|
|
"AccountingTime": {
|
|
"from": acc_from,
|
|
"until": acc_until,
|
|
},
|
|
"AHV-AVS-Income": "0.00",
|
|
"ALV-AC-Income": "0.00"
|
|
}
|
|
if ceo_rel:
|
|
ema["DegreeOfRelationship"] = ceo_rel
|
|
return ema
|
|
|
|
def create_ahv_avs_salary(self, institution_id, accounting_from, accounting_to, avs_salary, ac_salary, acc_salary, avs_open, ac_open, splits, ceo_rel=False):
|
|
if not (avs_salary or ac_salary or acc_salary or avs_open or ac_open):
|
|
return False
|
|
|
|
avs_salaries = {
|
|
"AHV-AVS-Income": self.amount2str(avs_salary),
|
|
"ALV-AC-Income": self.amount2str(ac_salary)
|
|
}
|
|
|
|
if acc_salary:
|
|
avs_salaries["ALVZ-ACS-Income"] = self.amount2str(acc_salary)
|
|
if avs_open:
|
|
avs_salaries["AHV-AVS-Open"] = self.amount2str(avs_open)
|
|
if ac_open:
|
|
avs_salaries["ALV-AC-Open"] = self.amount2str(ac_open)
|
|
if ceo_rel:
|
|
avs_salaries["DegreeOfRelationship"] = ceo_rel
|
|
if splits:
|
|
if splits.additional_delivery_date:
|
|
income_splits = {
|
|
"AdditionalDeliveryDate": format_date(splits.env, splits.additional_delivery_date, date_format='yyyy-MM-dd'),
|
|
}
|
|
else:
|
|
income_splits = {
|
|
"Splits": [{
|
|
"SplitCurrentYearIncome": self.amount2str(splits.income_to_split - sum(splits.avs_split_lines.mapped('income'))),
|
|
"SplitPreviousYear": {
|
|
"Period": {
|
|
"from": format_date(line.env, line.date_from, date_format='yyyy-MM-dd'),
|
|
"until": format_date(line.env, line.date_to, date_format='yyyy-MM-dd'),
|
|
},
|
|
"Income": self.amount2str(line.income)
|
|
}
|
|
} for line in splits.avs_split_lines]
|
|
}
|
|
avs_salaries["AHV-AVS-IncomeSplits"] = income_splits
|
|
|
|
return {
|
|
"institutionIDRef": self.get_institution_id_ref(institution=institution_id),
|
|
"AccountingTime": {
|
|
"from": accounting_from,
|
|
"until": accounting_to,
|
|
},
|
|
**avs_salaries
|
|
}
|
|
|
|
def create_fak_caf_ema(self, institution_id, canton, declaration_category, valid_as_of, reason, period_from, period_until):
|
|
return {
|
|
"institutionIDRef": self.get_institution_id_ref(institution_id),
|
|
"DeclarationCategory": {
|
|
declaration_category: {
|
|
"ValidAsOf": valid_as_of,
|
|
"Reason": reason
|
|
},
|
|
},
|
|
"FAK-CAF-Period": {
|
|
"from": period_from,
|
|
"until": period_until,
|
|
},
|
|
"FAK-CAF-ContributorySalary": "0.00",
|
|
"FAK-CAF-WorkplaceCanton": canton
|
|
}
|
|
|
|
def create_bvg_lpp_ema(self, institution_id, declarations, codes, bvg_lpp_annual_basis):
|
|
|
|
declaration_category = {}
|
|
if declarations.get("Entry"):
|
|
declaration_category["Entry"] = declarations.get("Entry")
|
|
if declarations.get("Withdrawal"):
|
|
declaration_category["Withdrawal"] = declarations.get("Withdrawal")
|
|
if declarations.get("Mutation"):
|
|
declaration_category["Mutation"] = declarations.get("Mutation")
|
|
|
|
ema = {
|
|
"institutionIDRef": self.get_institution_id_ref(institution_id),
|
|
"BVG-LPP-AnnualBasis": self.amount2str(bvg_lpp_annual_basis),
|
|
}
|
|
|
|
if declaration_category:
|
|
ema["DeclarationCategory"] = declaration_category
|
|
|
|
if codes:
|
|
ema["BVG-LPP-Code"] = codes[0]
|
|
|
|
return ema
|
|
|
|
@staticmethod
|
|
def source_tax_ema_to_dict(st_ema_objects):
|
|
declaration_category = {}
|
|
for ema in st_ema_objects:
|
|
ema_declaration_category, reason = IS_REASON_MAPPING[ema.reason]
|
|
declaration_category[ema_declaration_category] = declaration_category.get(
|
|
ema_declaration_category, []) + [{"Reason": reason, "ValidAsOf": format_date(ema.env, ema.valid_as_of,
|
|
date_format='yyyy-MM-dd')}]
|
|
if declaration_category:
|
|
return {
|
|
"DeclarationCategory": declaration_category
|
|
}
|
|
else:
|
|
return {}
|
|
|
|
@staticmethod
|
|
def get_salary_tag_counter(staff):
|
|
counters = {
|
|
("NumberOf-AHV-AVS-Salary-Tags", "AHV-AVS-Salaries"): 0,
|
|
("NumberOf-FAK-CAF-Salary-Tags", "FAK-CAF-Salaries"): 0,
|
|
("NumberOf-UVG-LAA-Salary-Tags", "UVG-LAA-Salaries"): 0,
|
|
("NumberOf-UVGZ-LAAC-Salary-Tags", "UVGZ-LAAC-Salaries"): 0,
|
|
("NumberOf-BVG-LPP-Salary-Tags", "BVG-LPP-Salaries"): 0,
|
|
("NumberOf-KTG-AMC-Salary-Tags", "KTG-AMC-Salaries"): 0,
|
|
("NumberOf-TaxSalary-Tags", "TaxSalaries"): 0,
|
|
("NumberOf-TaxCrossborderSalary-Tags", "TaxCrossborderSalaries"): 0,
|
|
("NumberOf-TaxAtSourceSalary-Tags", "TaxAtSourceSalaries"): 0,
|
|
("NumberOf-StatisticSalary-Tags", "StatisticSalaries"): 0
|
|
}
|
|
|
|
for person in staff["Staff"]["Person"]:
|
|
for tag in counters:
|
|
if tag[1] in person:
|
|
counters[tag] += len(person[tag[1]][SALARY_TYPE_MAPPING[tag[1]]])
|
|
return {
|
|
tag[0]: counters[tag] for tag in counters if counters[tag] > 0
|
|
}
|
|
|
|
@staticmethod
|
|
def _reverse_is_code_type(is_code):
|
|
if is_code:
|
|
if is_code in ['NON', 'NOY', 'HEN', 'HEY', 'MEN', 'MEY', 'SFN']:
|
|
return "CategoryPredefined"
|
|
elif re.match(IS_CODE_PATTERN, is_code):
|
|
return "TaxAtSourceCode"
|
|
else:
|
|
return "CategoryOpen"
|
|
else:
|
|
return "CategoryPredefined"
|
|
|
|
@staticmethod
|
|
def _round_to_5_cents(total):
|
|
return SwissdecDeclaration.amount2str(float_round(total, precision_rounding=0.05, rounding_method="HALF-UP"))
|
|
|
|
@staticmethod
|
|
def get_salary_totals(staff, **kwargs):
|
|
def convert_floats_to_str(data):
|
|
for key, value in data.items():
|
|
if key != "CurrentMonth" and key != "Month":
|
|
if isinstance(value, float):
|
|
data[key] = SwissdecDeclaration.amount2str(value)
|
|
elif isinstance(value, dict):
|
|
convert_floats_to_str(value)
|
|
elif isinstance(value, list):
|
|
for item in value:
|
|
if isinstance(item, dict):
|
|
convert_floats_to_str(item)
|
|
else:
|
|
data[key] = value
|
|
|
|
salary_totals = dict()
|
|
avs_totals = defaultdict(lambda: {
|
|
"Total-AHV-AVS-Incomes": 0,
|
|
"Total-AHV-AVS-Open": 0,
|
|
"Total-ALV-AC-Incomes": 0,
|
|
"Total-ALVZ-ACS-Incomes": 0,
|
|
"Total-ALV-AC-Open": 0,
|
|
})
|
|
|
|
# Institution - Canton - Totals
|
|
fak_totals = defaultdict(lambda: defaultdict(lambda: {
|
|
"Total-FAK-CAF-ContributorySalary": 0,
|
|
"Total-FAK-CAF-FamilyIncomeSupplement": 0,
|
|
}))
|
|
|
|
# Institution - Branch - Sex - Code
|
|
uvg_totals = defaultdict(lambda: defaultdict(lambda: defaultdict(lambda: defaultdict(float))))
|
|
uvg_gender_totals = defaultdict(lambda: {
|
|
"F": set(),
|
|
"M": set()
|
|
})
|
|
|
|
# Institution - Code - Sex - Total
|
|
uvgz_totals = defaultdict(lambda: defaultdict(lambda: defaultdict(float)))
|
|
|
|
# Institution - Code - Sex - Total
|
|
ijm_totals = defaultdict(lambda: defaultdict(lambda: defaultdict(float)))
|
|
|
|
# QST
|
|
source_tax_totals = defaultdict(lambda: {
|
|
"TotalTaxableEarning": "0.00",
|
|
"TotalTaxAtSource": "0.00",
|
|
"TotalCommission": "0.00",
|
|
"CurrentMonth": kwargs.get("CurrentMonth", False)
|
|
})
|
|
# QST - month
|
|
source_tax_correction_totals = defaultdict(lambda: defaultdict(lambda: {
|
|
"TotalTaxableEarning": "0.00",
|
|
"TotalTaxAtSource": "0.00",
|
|
"TotalCommission": "0.00",
|
|
}))
|
|
|
|
source_tax_commission_rates = kwargs.get("source_tax_commission_rates", defaultdict(float))
|
|
|
|
# Txb totals: QST - Taxable earning
|
|
|
|
txb_totals = defaultdict(defaultdict)
|
|
|
|
for person in staff:
|
|
particular = person.get("Particulars", {})
|
|
sex = particular["Sex"]
|
|
for avs_salary in person.get("AHV-AVS-Salaries", {}).get("AHV-AVS-Salary", []):
|
|
avs_totals[avs_salary["institutionIDRef"]]["Total-AHV-AVS-Incomes"] += float(avs_salary.get("AHV-AVS-Income", 0))
|
|
avs_totals[avs_salary["institutionIDRef"]]["Total-AHV-AVS-Open"] += float(avs_salary.get("AHV-AVS-Open", 0))
|
|
avs_totals[avs_salary["institutionIDRef"]]["Total-ALV-AC-Incomes"] += float(avs_salary.get("ALV-AC-Income", 0))
|
|
avs_totals[avs_salary["institutionIDRef"]]["Total-ALVZ-ACS-Incomes"] += float(avs_salary.get("ALVZ-ACS-Income", 0))
|
|
avs_totals[avs_salary["institutionIDRef"]]["Total-ALV-AC-Open"] += float(avs_salary.get("ALV-AC-Open", 0))
|
|
|
|
for caf_salary in person.get("FAK-CAF-Salaries", {}).get("FAK-CAF-Salary", []):
|
|
fak_totals[caf_salary["institutionIDRef"]][caf_salary["FAK-CAF-WorkplaceCanton"]]["Total-FAK-CAF-ContributorySalary"] += float(caf_salary.get("FAK-CAF-ContributorySalary", 0))
|
|
fak_totals[caf_salary["institutionIDRef"]][caf_salary["FAK-CAF-WorkplaceCanton"]]["Total-FAK-CAF-FamilyIncomeSupplement"] += float(caf_salary.get("FAK-CAF-FamilyIncomeSupplement", {}).get("FAK-CAF-FamilyIncomeSupplementPerPerson", 0))
|
|
|
|
for uvg_salary in person.get("UVG-LAA-Salaries", {}).get("UVG-LAA-Salary", []):
|
|
if kwargs.get("uvg_month", False) >= 9:
|
|
current_valid_from = uvg_salary.get("AccountingTime", {}).get("from", False)
|
|
current_valid_until = uvg_salary.get("AccountingTime", {}).get("until", False)
|
|
if current_valid_from and current_valid_until:
|
|
valid_from_date_time = fields.Date.from_string(current_valid_from)
|
|
valid_until_date_time = fields.Date.from_string(current_valid_until)
|
|
current_withdrawal = person.get("Work", {}).get("WithdrawalDate", False)
|
|
current_withdrawal_date_time = fields.Date.from_string(current_withdrawal) if current_withdrawal else False
|
|
end_of_september = datetime.date(kwargs.get("uvg_year", valid_from_date_time.year), 9, 30)
|
|
if valid_from_date_time <= end_of_september and valid_until_date_time >= end_of_september and (not current_withdrawal_date_time or current_withdrawal_date_time > end_of_september):
|
|
uvg_gender_totals[uvg_salary["institutionIDRef"]][sex].add(person["Particulars"]["EmployeeNumber"])
|
|
uvg_totals[uvg_salary["institutionIDRef"]][uvg_salary["UVG-LAA-Code"][0]][sex][uvg_salary["UVG-LAA-Code"][1]] += float(uvg_salary.get("UVG-LAA-ContributorySalary", 0))
|
|
|
|
for uvgz_salary in person.get("UVGZ-LAAC-Salaries", {}).get("UVGZ-LAAC-Salary", []):
|
|
uvgz_totals[uvgz_salary["institutionIDRef"]][uvgz_salary["UVGZ-LAAC-Code"]][sex] += float(uvgz_salary.get("UVGZ-LAAC-ContributorySalary", 0))
|
|
|
|
for ijm_salary in person.get("KTG-AMC-Salaries", {}).get("KTG-AMC-Salary", []):
|
|
ijm_totals[ijm_salary["institutionIDRef"]][ijm_salary["KTG-AMC-Code"]][sex] += float(ijm_salary.get("KTG-AMC-ContributorySalary", 0))
|
|
|
|
for qst_salary in person.get("TaxAtSourceSalaries", {}).get("TaxAtSourceSalary", []):
|
|
qst_id_ref = qst_salary["institutionIDRef"]
|
|
current_taxable_earning = float(source_tax_totals[qst_id_ref]["TotalTaxableEarning"])
|
|
current_tax_at_souce = float(source_tax_totals[qst_id_ref]["TotalTaxAtSource"])
|
|
source_tax_totals[qst_id_ref]["TotalTaxableEarning"] = SwissdecDeclaration.amount2str(current_taxable_earning + float(qst_salary.get("Current", {}).get("TaxableEarning", 0)))
|
|
source_tax_totals[qst_id_ref]["TotalTaxAtSource"] = SwissdecDeclaration.amount2str(current_tax_at_souce + float(qst_salary.get("Current", {}).get("TaxAtSource", 0)))
|
|
|
|
for correction in qst_salary.get("Correction", []):
|
|
month = tuple(correction["Month"])
|
|
new = correction.get("New", dict())
|
|
old = correction.get("Old", dict())
|
|
for key, value in new.items():
|
|
total_key = f"Total{key}"
|
|
if total_key in source_tax_correction_totals[qst_id_ref][month]:
|
|
source_tax_correction_totals[qst_id_ref][month][total_key] = SwissdecDeclaration.amount2str(float(source_tax_correction_totals[qst_id_ref][month][total_key]) + float(value))
|
|
for key, value in old.items():
|
|
total_key = f"Total{key}"
|
|
if total_key in source_tax_correction_totals[qst_id_ref][month]:
|
|
source_tax_correction_totals[qst_id_ref][month][total_key] = SwissdecDeclaration.amount2str(float(source_tax_correction_totals[qst_id_ref][month][total_key]) + float(value))
|
|
for correction in qst_salary.get("CorrectionConfirmed", []):
|
|
month = tuple(correction["Month"])
|
|
for key, value in correction.items():
|
|
if key != "Month":
|
|
total_key = f"Total{key}"
|
|
if total_key in source_tax_correction_totals[qst_id_ref][month]:
|
|
source_tax_correction_totals[qst_id_ref][month][total_key] = SwissdecDeclaration.amount2str(float(source_tax_correction_totals[qst_id_ref][month][total_key]) + float(value))
|
|
|
|
for qst_institution in source_tax_totals:
|
|
source_tax_totals[qst_institution]['TotalCommission'] = SwissdecDeclaration._round_to_5_cents(total=float(source_tax_totals[qst_institution]['TotalTaxAtSource']) * source_tax_commission_rates[qst_institution])
|
|
|
|
for qst_institution in source_tax_correction_totals:
|
|
for month in source_tax_correction_totals[qst_institution]:
|
|
source_tax_correction_totals[qst_institution][month]['TotalCommission'] = SwissdecDeclaration._round_to_5_cents(total=float(source_tax_correction_totals[qst_institution][month]['TotalTaxAtSource']) * source_tax_commission_rates[qst_institution])
|
|
|
|
global_txb_period = kwargs.get("global_txb_periods", {})
|
|
for txb_salary in person.get("TaxCrossborderSalaries", {}).get("TaxCrossborderSalary", []):
|
|
existing_txb = txb_totals[txb_salary["institutionIDRef"]]
|
|
if existing_txb:
|
|
current_from = global_txb_period[int(existing_txb["Period"]["from"].split("-")[0])]["from"]
|
|
current_until = global_txb_period[int(existing_txb["Period"]["until"].split("-")[0])]["until"]
|
|
if txb_salary["Period"]["from"] > current_from:
|
|
txb_totals[txb_salary["institutionIDRef"]]["Period"]["from"] = current_from
|
|
if txb_salary["Period"]["until"] < current_until:
|
|
txb_totals[txb_salary["institutionIDRef"]]["Period"]["until"] = current_until
|
|
else:
|
|
txb_totals[txb_salary["institutionIDRef"]]["Period"] = {
|
|
"from": global_txb_period[int(txb_salary["Period"]["from"].split('-')[0])]["from"],
|
|
"until": global_txb_period[int(txb_salary["Period"]["from"].split('-')[0])]["until"]
|
|
}
|
|
txb_totals[txb_salary["institutionIDRef"]]["TaxableEarning"] = "0.00"
|
|
txb_totals[txb_salary["institutionIDRef"]]["TaxAtSourceCanton"] = txb_salary["TaxAtSourceCanton"]
|
|
|
|
txb_totals[txb_salary["institutionIDRef"]]["TaxableEarning"] = SwissdecDeclaration.amount2str(float(txb_salary.get("TaxableEarning", "0.00")) + float(txb_totals[txb_salary["institutionIDRef"]]["TaxableEarning"]))
|
|
|
|
qst_totals = []
|
|
for institution in source_tax_totals:
|
|
qst_total = {
|
|
"TotalMonth": source_tax_totals[institution],
|
|
"institutionIDRef": institution
|
|
}
|
|
if source_tax_correction_totals[institution]:
|
|
qst_total["CorrectionMonth"] = sorted([{"Month": corr_month, **source_tax_correction_totals[institution][corr_month]} for corr_month in source_tax_correction_totals[institution]], key=lambda corr_d: (corr_d["Month"][1], corr_d["Month"][2]))
|
|
qst_totals.append(qst_total)
|
|
|
|
txb_totals_l = [{"institutionIDRef": institution, **txb_totals[institution]} for institution in txb_totals]
|
|
|
|
ahv_total = [{
|
|
**{key: SwissdecDeclaration.amount2str(avs_totals[institution][key]) for key in avs_totals[institution]},
|
|
"institutionIDRef": institution
|
|
} for institution in avs_totals]
|
|
|
|
fak_caf_totals = [
|
|
{
|
|
"institutionIDRef": institution,
|
|
"Total-FAK-CAF-PerCanton": [
|
|
{
|
|
"Canton": canton,
|
|
**{
|
|
key: SwissdecDeclaration.amount2str(fak_totals[institution][canton].get(key, 0))
|
|
for key in fak_totals[institution][canton]
|
|
},
|
|
} for canton in fak_totals[institution]
|
|
]
|
|
}
|
|
for institution in fak_totals
|
|
]
|
|
if ahv_total:
|
|
salary_totals["AHV-AVS-Totals"] = ahv_total
|
|
|
|
if fak_caf_totals:
|
|
salary_totals["FAK-CAF-Totals"] = fak_caf_totals
|
|
|
|
uvg_laa_totals = []
|
|
for institution in uvg_totals:
|
|
result = {
|
|
"institutionIDRef": institution,
|
|
"UVG-LAA-BranchTotals": {
|
|
"UVG-LAA-BranchTotal": []
|
|
},
|
|
"UVG-LAA-MasterTotal": 0.0,
|
|
"NumberOfFemalePersons": 0,
|
|
"NumberOfMalePersons": 0
|
|
}
|
|
master_total = 0.0
|
|
female_count = 0
|
|
male_count = 0
|
|
|
|
# Iterate over branches and gender totals in `uvg_totals`
|
|
for branch, genders in uvg_totals[institution].items():
|
|
branch_total = {
|
|
"BranchIdentifier": branch,
|
|
"Female-Totals": {"NBU-BU-ANP-AP-Total": 0.0, "BU-AP-Total": 0.0},
|
|
"Male-Totals": {"NBU-BU-ANP-AP-Total": 0.0, "BU-AP-Total": 0.0}
|
|
}
|
|
|
|
for gender, codes in genders.items():
|
|
gender_totals = {"NBU-BU-ANP-AP-Total": 0.0, "BU-AP-Total": 0.0}
|
|
|
|
for code, amount in codes.items():
|
|
if code in ["1", "2"]: # Map to NBU-BU-ANP-AP-Total
|
|
gender_totals["NBU-BU-ANP-AP-Total"] += amount
|
|
elif code == "3": # Map to BU-AP-Total
|
|
gender_totals["BU-AP-Total"] += amount
|
|
|
|
# Add gender totals to branch totals
|
|
if gender == "F":
|
|
branch_total["Female-Totals"] = gender_totals
|
|
female_count += 1
|
|
elif gender == "M":
|
|
branch_total["Male-Totals"] = gender_totals
|
|
male_count += 1
|
|
|
|
# Accumulate to master total
|
|
master_total += sum(gender_totals.values())
|
|
|
|
# Append the branch total to the branch totals list
|
|
result["UVG-LAA-BranchTotals"]["UVG-LAA-BranchTotal"].append(branch_total)
|
|
|
|
# Populate master total and counts
|
|
result["UVG-LAA-MasterTotal"] = master_total
|
|
result["NumberOfFemalePersons"] = len(uvg_gender_totals[institution]["F"])
|
|
result["NumberOfMalePersons"] = len(uvg_gender_totals[institution]["M"])
|
|
convert_floats_to_str(result)
|
|
uvg_laa_totals.append(deepcopy(result))
|
|
|
|
uvgz_laac_totals = []
|
|
for institution in uvgz_totals:
|
|
result = {
|
|
"institutionIDRef": institution,
|
|
"UVGZ-LAAC-CategoryTotals": {
|
|
"UVGZ-LAAC-CategoryTotal": []
|
|
},
|
|
"UVGZ-LAAC-MasterTotal": 0.0
|
|
}
|
|
|
|
# Variable to accumulate the master total
|
|
master_total = 0.0
|
|
|
|
# Iterate over categories and gender totals in `uvgz_totals`
|
|
for category_code, genders in uvgz_totals[institution].items():
|
|
# Initialize totals for the current category
|
|
category_total = {
|
|
"CategoryCode": category_code,
|
|
"Female-Total": 0.0,
|
|
"Male-Total": 0.0
|
|
}
|
|
|
|
# Calculate totals for each gender
|
|
for gender, total in genders.items():
|
|
if gender == "F":
|
|
category_total["Female-Total"] += total
|
|
elif gender == "M":
|
|
category_total["Male-Total"] += total
|
|
|
|
# Add category totals to the master total
|
|
master_total += category_total["Female-Total"] + category_total["Male-Total"]
|
|
|
|
# Append category total to the category totals list
|
|
result["UVGZ-LAAC-CategoryTotals"]["UVGZ-LAAC-CategoryTotal"].append(category_total)
|
|
|
|
# Set the master total in the result
|
|
result["UVGZ-LAAC-MasterTotal"] = master_total
|
|
convert_floats_to_str(result)
|
|
uvgz_laac_totals.append(deepcopy(result))
|
|
|
|
ktg_amc_totals = []
|
|
for institution in ijm_totals:
|
|
result = {
|
|
"institutionIDRef": institution,
|
|
"KTG-AMC-CategoryTotals": {
|
|
"KTG-AMC-CategoryTotal": []
|
|
},
|
|
"KTG-AMC-MasterTotal": 0.0
|
|
}
|
|
|
|
# Variable to accumulate the master total
|
|
master_total = 0.0
|
|
|
|
# Iterate over categories and gender totals in `uvgz_totals`
|
|
for category_code, genders in ijm_totals[institution].items():
|
|
# Initialize totals for the current category
|
|
category_total = {
|
|
"CategoryCode": category_code,
|
|
"Female-Total": 0.0,
|
|
"Male-Total": 0.0
|
|
}
|
|
|
|
# Calculate totals for each gender
|
|
for gender, total in genders.items():
|
|
if gender == "F":
|
|
category_total["Female-Total"] += total
|
|
elif gender == "M":
|
|
category_total["Male-Total"] += total
|
|
|
|
# Add category totals to the master total
|
|
master_total += category_total["Female-Total"] + category_total["Male-Total"]
|
|
|
|
# Append category total to the category totals list
|
|
result["KTG-AMC-CategoryTotals"]["KTG-AMC-CategoryTotal"].append(category_total)
|
|
|
|
# Set the master total in the result
|
|
result["KTG-AMC-MasterTotal"] = master_total
|
|
convert_floats_to_str(result)
|
|
ktg_amc_totals.append(deepcopy(result))
|
|
|
|
if uvg_laa_totals:
|
|
salary_totals["UVG-LAA-Totals"] = uvg_laa_totals
|
|
|
|
if uvgz_laac_totals:
|
|
salary_totals["UVGZ-LAAC-Totals"] = uvgz_laac_totals
|
|
|
|
if ktg_amc_totals:
|
|
salary_totals["KTG-AMC-Totals"] = ktg_amc_totals
|
|
|
|
if qst_totals:
|
|
salary_totals["TaxAtSourceTotals"] = qst_totals
|
|
|
|
if txb_totals_l:
|
|
salary_totals["TaxCrossborderTotals"] = txb_totals_l
|
|
|
|
return salary_totals
|
|
|
|
def get_instution_description(self, institution, **kwargs):
|
|
description = {}
|
|
if INSTITUTION_MODEL_MAPPING[institution._name] == "AHV-AVS":
|
|
description = {
|
|
"AK-CC-BranchNumber": institution.insurance_code,
|
|
"AK-CC-CustomerNumber": institution.member_number,
|
|
}
|
|
|
|
if not kwargs.get('skip_id_ref'):
|
|
if institution.laa_insurance_id:
|
|
uvg_laa = {
|
|
"Name": institution.laa_insurance_id.name,
|
|
"ValidAsOf": format_date(institution.env, institution.laa_insurance_from,
|
|
date_format='yyyy-MM-dd')
|
|
}
|
|
if institution.laa_insurance_id.uid_bfs_number:
|
|
uvg_laa["UID-BFS"] = {
|
|
"UID": institution.laa_insurance_id.uid_bfs_number
|
|
}
|
|
else:
|
|
uvg_laa["UID-BFS"] = {
|
|
"Unknown": XSD_SKIP_VALUE
|
|
}
|
|
else:
|
|
uvg_laa = {
|
|
"NoneWithReason": institution.no_laa_reason
|
|
}
|
|
|
|
if institution.lpp_insurance_id:
|
|
bvg_lpp = {
|
|
"Name": institution.lpp_insurance_id.name,
|
|
"ValidAsOf": format_date(institution.env, institution.lpp_insurance_from,
|
|
date_format='yyyy-MM-dd')
|
|
}
|
|
if institution.lpp_insurance_id.uid_bfs:
|
|
bvg_lpp["UID-BFS"] = {
|
|
"UID": institution.lpp_insurance_id.uid_bfs
|
|
}
|
|
else:
|
|
bvg_lpp["UID-BFS"] = {
|
|
"Unknown": XSD_SKIP_VALUE
|
|
}
|
|
else:
|
|
bvg_lpp = {
|
|
"NoneWithReason": institution.no_lpp_reason
|
|
}
|
|
description.update({
|
|
"UVG-LAA-Insurance": uvg_laa,
|
|
"BVG-LPP-Insurance": bvg_lpp
|
|
})
|
|
|
|
if institution.member_subnumber:
|
|
description["AK-CC-SubNumber"] = institution.member_subnumber
|
|
|
|
elif INSTITUTION_MODEL_MAPPING[institution._name] == "FAK-CAF":
|
|
description = {
|
|
"FAK-CAF-BranchNumber": institution.insurance_code,
|
|
"FAK-CAF-CustomerNumber": institution.member_number,
|
|
}
|
|
if institution.member_subnumber:
|
|
description["FAK-CAF-SubNumber"] = institution.member_subnumber
|
|
|
|
elif INSTITUTION_MODEL_MAPPING[institution._name] == "BVG-LPP":
|
|
description = {
|
|
"InsuranceID": institution.insurance_code,
|
|
"InsuranceCompanyName": institution.name,
|
|
"CustomerIdentity": institution.customer_number,
|
|
"ContractIdentity": institution.contract_number,
|
|
}
|
|
if not kwargs.get('skip_id_ref'):
|
|
description["GeneralValidAsOf"] = kwargs.get("general_validasof", missing_value)
|
|
|
|
if institution.fund_number and not kwargs.get('skip_bvg_payroll_unit'):
|
|
description["PayrollUnit"] = institution.fund_number
|
|
|
|
elif INSTITUTION_MODEL_MAPPING[institution._name] in ["UVG-LAA", "KTG-AMC", "UVGZ-LAAC"]:
|
|
|
|
description = {
|
|
"InsuranceID": institution.insurance_code,
|
|
"InsuranceCompanyName": institution.name,
|
|
"CustomerIdentity": institution.customer_number,
|
|
"ContractIdentity": institution.contract_number,
|
|
}
|
|
if kwargs.get("incomplete_declaration"):
|
|
description['DeclarationIncomplete'] = [XSD_SKIP_VALUE]
|
|
|
|
elif INSTITUTION_MODEL_MAPPING[institution._name] == "TaxCrossborder":
|
|
description = {
|
|
"CantonID": institution.canton,
|
|
"CustomerIdentity": institution.dpi_number,
|
|
}
|
|
"""
|
|
todo: still
|
|
if institution.company_number:
|
|
txb["PayrollUnit"] = institution.company_number
|
|
return txb
|
|
"""
|
|
elif INSTITUTION_MODEL_MAPPING[institution._name] == "TaxAtSource":
|
|
description = {
|
|
"CantonID": institution.canton,
|
|
"CustomerIdentity": institution.dpi_number,
|
|
}
|
|
|
|
if institution.company_number:
|
|
description["PayrollUnit"] = institution.company_number
|
|
|
|
elif INSTITUTION_MODEL_MAPPING[institution._name] == "Statistic":
|
|
description = {
|
|
"PayAgreement": institution.pay_agreement
|
|
}
|
|
if institution.payroll_unit:
|
|
description["PayrollUnit"] = institution.payroll_unit
|
|
|
|
if not kwargs.get('skip_id_ref'):
|
|
description["institutionID"] = self.get_institution_id_ref(institution)
|
|
|
|
return description
|
|
|
|
def get_workplace_id_ref(self, workplace):
|
|
workplace_id_ref = f"{workplace.bur_ree_number or workplace.in_house_id or workplace.id}"
|
|
return f"#W_{workplace_id_ref}"
|
|
|
|
def get_workplace_working_hours(self, workplace):
|
|
workplace_id_ref = self.get_workplace_id_ref(workplace)
|
|
if workplace.weekly_hours > 0 and workplace.weekly_lessons == 0:
|
|
return {
|
|
"WeeklyHours": {
|
|
"_value_1": self.amount2str(workplace.weekly_hours),
|
|
"companyWeeklyHoursID": f"#WT_{workplace_id_ref}"
|
|
}
|
|
}
|
|
elif workplace.weekly_hours == 0 and workplace.weekly_lessons > 0:
|
|
return {
|
|
"WeeklyLessons": {
|
|
"_value_1": self.amount2str(workplace.weekly_lessons),
|
|
"companyWeeklyLessonsID": f"#WT_{workplace_id_ref}"
|
|
}
|
|
}
|
|
elif workplace.weekly_hours > 0 and workplace.weekly_lessons > 0:
|
|
return {
|
|
"WeeklyHoursAndLessons": {
|
|
"WeeklyHours": self.amount2str(workplace.weekly_hours),
|
|
"WeeklyLessons": self.amount2str(workplace.weekly_lessons),
|
|
"companyWeeklyHoursAndLessonsID": f"#WT_{workplace_id_ref}"
|
|
},
|
|
}
|
|
else:
|
|
return missing_value
|
|
|
|
def get_institution_id_ref(self, institution):
|
|
if institution:
|
|
if INSTITUTION_MODEL_MAPPING[institution._name] not in ["FAK-CAF", "TaxCrossborder", "TaxAtSource", "Tax", "Statistic"]:
|
|
return f"#{INSTITUTION_MODEL_MAPPING.get(institution._name)}_{institution.insurance_code}"
|
|
elif INSTITUTION_MODEL_MAPPING[institution._name] == "FAK-CAF":
|
|
return f"#{INSTITUTION_MODEL_MAPPING.get(institution._name)}_{institution.insurance_code}_{institution.member_number}"
|
|
elif INSTITUTION_MODEL_MAPPING[institution._name] == "TaxCrossborder":
|
|
return f"#{INSTITUTION_MODEL_MAPPING.get(institution._name)}_{institution.canton}"
|
|
elif INSTITUTION_MODEL_MAPPING[institution._name] == "TaxAtSource":
|
|
return f"#QST_{institution.canton}"
|
|
elif INSTITUTION_MODEL_MAPPING[institution._name] in ["Tax", "Statistic"]:
|
|
return f"#{institution._name}"
|
|
else:
|
|
return False
|
|
|
|
def get_institution_job(self, institution):
|
|
return {
|
|
"institutionIDRef": self.get_institution_id_ref(institution),
|
|
"ProcessByDistributor": "true"
|
|
}
|
|
|
|
def get_institutions(self, institutions, **kwargs):
|
|
institution_description = {}
|
|
for institution in institutions:
|
|
institution_type = INSTITUTION_MODEL_MAPPING.get(institution._name, False)
|
|
if institution._name == "l10n.ch.source.tax.institution":
|
|
if kwargs.get("txb"):
|
|
institution_type = "TaxCrossborder"
|
|
if institution_type and institution_type not in ["Tax", "Statistic"]:
|
|
if institution_type in institution_description:
|
|
institution_description[institution_type].append(self.get_instution_description(institution, **kwargs))
|
|
else:
|
|
institution_description[institution_type] = [self.get_instution_description(institution, **kwargs)]
|
|
elif institution_type == "Statistic":
|
|
institution_description[institution_type] = self.get_instution_description(institution, **kwargs)
|
|
|
|
return {
|
|
"Institutions": institution_description
|
|
}
|
|
|
|
def get_mapped_institution_descriptions(self, institutions, **kwargs):
|
|
institution_description = dict()
|
|
for institution in institutions:
|
|
id_ref = self.get_institution_id_ref(institution)
|
|
institution_description[id_ref] = self.get_instution_description(institution, skip_id_ref=True, **kwargs)
|
|
|
|
return institution_description
|
|
|
|
def get_job(self, institutions, staff_institutions):
|
|
job = {}
|
|
to_process = [self.get_institution_id_ref(i) for i in institutions]
|
|
for domain, i_true in staff_institutions.items():
|
|
if domain != "Statistic":
|
|
job[domain] = []
|
|
for id_ref in i_true:
|
|
job[domain].append({
|
|
"institutionIDRef": id_ref,
|
|
"ProcessByDistributor": id_ref in to_process
|
|
})
|
|
else:
|
|
job["Statistic"] = {
|
|
"institutionIDRef": "#BFS",
|
|
"ProcessByDistributor": "#BFS" in to_process
|
|
}
|
|
if "#Tax" in to_process:
|
|
job["Tax"] = {
|
|
"ProcessByDistributor": True
|
|
}
|
|
return {
|
|
"Addressees": [job]
|
|
}
|
|
|
|
def get_company_description(self, company_id):
|
|
company_description = {
|
|
"Name": {
|
|
"HR-RC-Name": company_id.name
|
|
}
|
|
}
|
|
|
|
if company_id.l10n_ch_uid:
|
|
company_description["UID-BFS"] = {
|
|
"UID": company_id.l10n_ch_uid
|
|
}
|
|
else:
|
|
company_description["UID-BFS"] = {
|
|
"Unknown": XSD_SKIP_VALUE
|
|
}
|
|
|
|
address = {
|
|
"ZIP-Code": company_id.zip or missing_value,
|
|
"City": company_id.city or missing_value
|
|
}
|
|
|
|
if company_id.street:
|
|
address["Street"] = company_id.street
|
|
if company_id.street2:
|
|
address["ComplementaryLine"]: company_id.street2
|
|
if company_id.l10n_ch_post_box:
|
|
address["Postbox"] = company_id.l10n_ch_post_box
|
|
if company_id.country_id:
|
|
address["Country"] = company_id.country_id.name.upper()
|
|
|
|
workplaces = []
|
|
for workplace in company_id.l10n_ch_work_location_ids:
|
|
workplace_description = dict()
|
|
workplace_id_ref = self.get_workplace_id_ref(workplace)
|
|
workplace_description["workplaceID"] = workplace_id_ref
|
|
if workplace.bur_ree_number:
|
|
workplace_description["BUR-REE-Number"] = workplace.bur_ree_number
|
|
if workplace.in_house_id and not workplace.bur_ree_number:
|
|
workplace_description["InHouseID"] = workplace.in_house_id
|
|
address_extended = {
|
|
"ComplementaryLine": workplace.partner_id.name,
|
|
"ZIP-Code": workplace.partner_id.zip or missing_value,
|
|
"City": workplace.partner_id.city or missing_value
|
|
}
|
|
if workplace.partner_id.street:
|
|
address_extended["Street"] = workplace.partner_id.street
|
|
if workplace.partner_id.country_id:
|
|
address_extended["Country"] = workplace.partner_id.country_id.name.upper()
|
|
if workplace.canton:
|
|
address_extended["Canton"] = workplace.canton
|
|
if workplace.municipality:
|
|
address_extended["MunicipalityID"] = workplace.municipality
|
|
|
|
workplaces.append({
|
|
**workplace_description,
|
|
"AddressExtended": address_extended,
|
|
"CompanyWorkingTime": self.get_workplace_working_hours(workplace)
|
|
})
|
|
|
|
if company_id.l10n_ch_uses_delegate:
|
|
delegate_desc = {
|
|
"Name": {
|
|
"HR-RC-Name": company_id.l10n_ch_swissdec_delegate_name or missing_value,
|
|
},
|
|
"Address": {
|
|
"ZIP-Code": company_id.l10n_ch_delegate_zip or missing_value,
|
|
"City": company_id.l10n_ch_delegate_city or missing_value
|
|
},
|
|
}
|
|
|
|
if company_id.l10n_ch_swissdec_delegate_ch_uid:
|
|
delegate_desc["UID-BFS"] = company_id.l10n_ch_swissdec_delegate_ch_uid
|
|
if company_id.l10n_ch_delegate_street:
|
|
delegate_desc["Address"]["Street"] = company_id.l10n_ch_delegate_street
|
|
if company_id.l10n_ch_delegate_street2:
|
|
delegate_desc["Address"]["ComplementaryLine"] = company_id.l10n_ch_delegate_street2
|
|
if company_id.l10n_ch_delegate_Po_Box:
|
|
delegate_desc["Address"]["Postbox"] = company_id.l10n_ch_delegate_Po_Box
|
|
if company_id.l10n_ch_delegate_country_id:
|
|
delegate_desc["Address"]["Country"] = company_id.l10n_ch_delegate_country_id.name.upper()
|
|
|
|
company_description["Delegate"] = delegate_desc
|
|
|
|
return {
|
|
"CompanyDescription": {
|
|
**company_description,
|
|
"Address": address,
|
|
"Workplace": workplaces
|
|
}
|
|
}
|
|
|
|
def _get_contact_person(self, company_id):
|
|
contact_person = dict()
|
|
if company_id.l10n_ch_contact_person_name and company_id.l10n_ch_contact_person_email and company_id.l10n_ch_contact_person_phone:
|
|
contact_person["Name"] = company_id.l10n_ch_contact_person_name
|
|
contact_person["EmailAddress"] = company_id.l10n_ch_contact_person_email
|
|
contact_person["PhoneNumber"] = company_id.l10n_ch_contact_person_phone
|
|
return {
|
|
"ContactPerson": contact_person
|
|
}
|
|
else:
|
|
return {}
|
|
|
|
def create_declare_salary(self, institutions_to_process, company_id, staff, declaration_year, test_case=False, substitution_declaration_id=None, **kwargs):
|
|
staff_institutions = {}
|
|
if staff:
|
|
for domain, institutions in staff.get("Institutions", {}).items():
|
|
if isinstance(institutions, list):
|
|
staff_institutions[domain] = []
|
|
for institution in institutions:
|
|
staff_institutions[domain].append(institution.get("institutionID"))
|
|
else:
|
|
staff_institutions[domain] = [institutions.get("institutionID")]
|
|
job = {
|
|
"Job": self.get_job(institutions_to_process, staff_institutions)
|
|
}
|
|
|
|
salary_declaration = {"SalaryDeclaration": {
|
|
"schemaVersion": "3.0",
|
|
"Company": {
|
|
**staff
|
|
},
|
|
"GeneralSalaryDeclarationDescription": {
|
|
"CreationDate": datetime.datetime.utcnow().isoformat() + 'Z',
|
|
"AccountingPeriod": [XSD_YMONTH, declaration_year, False],
|
|
**self._get_contact_person(company_id)
|
|
},
|
|
}}
|
|
|
|
if substitution_declaration_id:
|
|
declaration = {
|
|
**job,
|
|
"Substitution": {
|
|
"PredecessorDeclarationIDWithAcceptedState": substitution_declaration_id
|
|
},
|
|
**salary_declaration
|
|
}
|
|
else:
|
|
declaration = {
|
|
**job,
|
|
**salary_declaration
|
|
}
|
|
|
|
return declaration
|
|
else:
|
|
return {}
|
|
|
|
def create_get_status_from_declare_salary(self, job_key):
|
|
return {
|
|
"JobKey": job_key
|
|
}
|
|
|
|
def create_get_result_from_declare_salary(self, domain, key, password, institution_description):
|
|
domain_data = {
|
|
MAPPED_DOMAIN_IDENTIFICATION[domain]: {
|
|
"Key": key,
|
|
"Password": password,
|
|
}
|
|
}
|
|
if institution_description:
|
|
domain_data[MAPPED_DOMAIN_IDENTIFICATION[domain]]["Institution"] = institution_description
|
|
|
|
return {
|
|
"Domain": domain_data
|
|
}
|
|
|
|
def create_reply_dialog(self, domain, key, password, institution_description, dialog):
|
|
domain_data = {
|
|
MAPPED_DOMAIN_IDENTIFICATION[domain]: {
|
|
"Key": key,
|
|
"Password": password,
|
|
}
|
|
}
|
|
if institution_description:
|
|
domain_data[MAPPED_DOMAIN_IDENTIFICATION[domain]]["Institution"] = institution_description
|
|
|
|
return {
|
|
"Domain": domain_data,
|
|
"DialogMessages": {
|
|
"DialogMessage": [dialog]
|
|
}
|
|
}
|
|
|
|
def create_poll_dialog(self, domain, key, password, institution_description, dialog_story_id):
|
|
polling_dialog = {
|
|
"Creation": fields.Datetime.now().isoformat(),
|
|
"StoryID": str(uuid.uuid4().hex),
|
|
"StandardDialogID": "0000.0002.0001-001",
|
|
"Title": "Polling DialogMessage ELM",
|
|
"Description": "Polling of a DialogMessage in ProcessingState",
|
|
"Paragraph": [
|
|
{
|
|
"ID": "100",
|
|
"Label": "StoryID of DialogMessage to poll",
|
|
"Value": {
|
|
"String": dialog_story_id
|
|
}
|
|
}
|
|
]
|
|
}
|
|
|
|
domain_data = {
|
|
MAPPED_DOMAIN_IDENTIFICATION[domain]: {
|
|
"Key": key,
|
|
"Password": password,
|
|
}
|
|
}
|
|
if institution_description:
|
|
domain_data[MAPPED_DOMAIN_IDENTIFICATION[domain]]["Institution"] = institution_description
|
|
|
|
return {
|
|
"Domain": domain_data,
|
|
"DialogMessages": {
|
|
"DialogMessage": [polling_dialog]
|
|
}
|
|
}
|