PageSourceSearch

https://dfsteuer.de/wp-content/cache/min/1/wp-content/themes/bvd-admin/loan-forms/js/index.js?ver=1791185524

js dfsteuer.de collected 2026-10-08 17:12:26 UTC 55,181 bytes, 301 lines download raw bytes

1jQuery(function($){const STORAGE_KEY="currentStep";const LOAN_DATA="remainingValue";const DATA_KEY="loanFormData";$(document).ready(function(){const container=document.querySelector("#loan-form-container");if(!container){sessionStorage.setItem(STORAGE_KEY,"1");sessionStorage.removeItem(DATA_KEY);["primary","secondary"].forEach((prefix)=>{sessionStorage.removeItem(`${LOAN_DATA}_${prefix}`)});return}else{loadStep(getStoredStep());setProgress();setTitle()}});function getStoredStep(){const step=parseInt(sessionStorage.getItem(STORAGE_KEY),10);return Number.isFinite(step)&&step>0?step:1}
2function radioButtonNextStep(step){const stepContainer=$(`.loan-step[data-step="${step}"]`);let button=stepContainer.find(".next-step");let employmentPosition=stepContainer.find("select.position");if(employmentPosition.length){let nextStep=employmentPosition.find("option:selected").data("next-form");if(nextStep!==undefined){button.attr("data-step",nextStep)}}else{let radios=stepContainer.find('input[type="radio"]');radios.each(function(){$(this).on("change",function(){let nextStep=$(this).data("next-form");button.attr("data-step",nextStep)})})}}
3function selectNextStep(step){const stepContainer=$(`.loan-step[data-step="${step}"]`);let button=stepContainer.find(".next-step");let selects=stepContainer.find("select");selects.each(function(){$(this).on("change",function(){let nextStep=$(this).find("option:selected").data("next-form");if(nextStep){button.attr("data-step",nextStep)}})})}
4function initCompanySearch(step){if(step!==161&&step!==291&&step!==341){return}
5const debtorType=step===341?"secondary":"primary";const nameInput=document.querySelector(`input[name="debtors.${debtorType}.currentEmployment.selfEmployed.name"]`,);const results=document.querySelector(".list__of-companies");const streetInput=document.querySelector(`input[name="debtors.${debtorType}.currentEmployment.selfEmployed.address.street"]`,);const houseNumberInput=document.querySelector(`input[name="debtors.${debtorType}.currentEmployment.selfEmployed.address.houseNumber"]`,);const zipInput=document.querySelector(`input[name="debtors.${debtorType}.currentEmployment.selfEmployed.address.zipCode"]`,);const cityInput=document.querySelector(`input[name="debtors.${debtorType}.currentEmployment.selfEmployed.address.city"]`,);if(!nameInput||!results){return}
6let timer=null;const fields={name:nameInput,results,street:streetInput,houseNumber:houseNumberInput,zip:zipInput,city:cityInput,};nameInput.addEventListener("input",function(){clearTimeout(timer);const name=this.value.trim();results.innerHTML="";if(name.length<2){return}
7results.style.display="";timer=setTimeout(()=>{searchCompany(name,fields)},400)})}
8function initCompanySearchSecond(step){if(step!==170&&step!==300&&step!==350){return}
9const debtorType=step===350?"secondary":"primary";const nameInput=document.querySelector(`input[name="debtors.${debtorType}.currentEmployment.employer"]`,);const results=document.querySelector(".list__of-companies");const streetInput=document.querySelector(`input[name="debtors.${debtorType}.currentEmployment.employed.address.street"]`,);const houseNumberInput=document.querySelector(`input[name="debtors.${debtorType}.currentEmployment.employed.address.houseNumber"]`,);const zipInput=document.querySelector(`input[name="debtors.${debtorType}.currentEmployment.employed.address.zipCode"]`,);const cityInput=document.querySelector(`input[name="debtors.${debtorType}.currentEmployment.employed.address.city"]`,);if(!nameInput||!results){return}
10let timer=null;const fields={name:nameInput,results,street:streetInput,houseNumber:houseNumberInput,zip:zipInput,city:cityInput,};nameInput.addEventListener("input",function(){clearTimeout(timer);const name=this.value.trim();results.innerHTML="";if(name.length<2){return}
11results.style.display="";timer=setTimeout(()=>{searchCompany(name,fields)},400)})}
12function splitStreetAddress(address){if(!address){return{street:"",houseNumber:"",}}
13const value=String(address).trim();const match=value.match(/^(.+?)\s+(\d+[a-zA-Z]?(?:[-/]\d+[a-zA-Z]?)?)$/);if(!match){return{street:value,houseNumber:"",}}
14return{street:match[1].trim(),houseNumber:match[2].trim(),}}
15function fillAddress(address,fields){if(!address||!fields){return}
16const parsed=splitStreetAddress(address.street||"");if(fields.street){fields.street.value=parsed.street}
17if(fields.houseNumber){fields.houseNumber.value=parsed.houseNumber}
18if(fields.zip){fields.zip.value=address.zip||""}
19if(fields.city){fields.city.value=address.city||""}[fields.street,fields.houseNumber,fields.zip,fields.city].forEach((input)=>{if(!input){return}
20input.dispatchEvent(new Event("input",{bubbles:!0}));input.dispatchEvent(new Event("change",{bubbles:!0}))},)}
21function displayResults(data,fields){const results=fields?.results;if(!results){return}
22results.innerHTML="";const companies=Array.isArray(data)?data:Array.isArray(data?.results)?data.results:Array.isArray(data?.data)?data.data:[];if(companies.length===0){results.innerHTML=`
23      <div class="result result--empty">
24        No companies found.
25      </div>
26    `;return}
27const fragment=document.createDocumentFragment();companies.forEach((company)=>{const div=document.createElement("div");div.className="result";div.setAttribute("role","button");div.setAttribute("tabindex","0");const name=company?.name||"Unknown company";const city=company?.city||"";const zip=company?.zip||"";const location=[zip,city].filter(Boolean).join(" ");div.innerHTML=`
28      <div class="result-name">
29        ${escapeHtml(name)}
30      </div>
31
32      <div class="result-info">
33        ${escapeHtml(location)}
34        ${company?.active === false ? " · Inactive" : ""}
35      </div>
36    `;const select=()=>{selectCompany(company,fields)};div.addEventListener("click",select);div.addEventListener("keydown",(event)=>{if(event.key==="Enter"||event.key===" "){event.preventDefault();select()}});fragment.appendChild(div)});results.appendChild(fragment)}
37async function selectCompany(company,fields){if(!company||!fields){return}
38if(fields.name){fields.name.value=company.name||"";fields.name.dispatchEvent(new Event("input",{bubbles:!0}));fields.name.dispatchEvent(new Event("change",{bubbles:!0}))}
39if(fields.results){fields.results.innerHTML="";fields.results.style.display="none"}
40if(!company.id){console.warn("Company does not have an ID:",company);return}
41try{const formData=new FormData();formData.append("action","implisense_company");formData.append("id",company.id);const response=await fetch(getAjaxUrl(),{method:"POST",body:formData,});if(!response.ok){throw new Error(`HTTP ${response.status}`)}
42const data=await response.json();if(!data?.success){throw new Error(data?.data?.message||"Could not load company")}
43const companyData=data.data;if(companyData?.address){fillAddress(companyData.address,fields)}}catch(error){console.error("Implisense company error:",error)}}
44async function searchCompany(name,fields){if(!name||!fields){return}
45try{const formData=new FormData();formData.append("action","implisense_search");formData.append("name",name);const response=await fetch(getAjaxUrl(),{method:"POST",body:formData,});if(!response.ok){throw new Error(`HTTP ${response.status}`)}
46const data=await response.json();if(!data?.success){throw new Error(data?.data?.message||"Search failed")}
47displayResults(data.data,fields)}catch(error){console.error("Implisense search error:",error);if(fields.results){fields.results.innerHTML=`
48        <div class="result result--error">
49          Could not search companies.
50        </div>
51      `}}}
52function getAjaxUrl(){if(typeof loanForms!=="undefined"&&loanForms.ajaxurl){return loanForms.ajaxurl}
53if(typeof ajaxUrl!=="undefined"){return ajaxUrl}
54throw new Error("WordPress AJAX URL is not configured.")}
55function escapeHtml(value){return String(value??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}
56function loadStep(step,currentStep=null){sessionStorage.setItem(STORAGE_KEY,step);$.ajax({url:loanForms.ajaxurl,type:"POST",data:{action:"load_loan_step",step:step,lang:document.documentElement.lang,},success:function(response){$("#loan-form-container__form-part").html(response.data.html);const stepContainer=$(`.loan-step[data-step="${step}"]`);restoreStepData(step);radioButtonNextStep(step);selectNextStep(step);stepContainer.find('input[type="number"]').on("keydown",function(e){if(e.key==="."||e.key==="Decimal"){e.preventDefault()}}).on("input",function(){this.value=this.value.replace(/\./g,"")});stepContainer.find('input[type="radio"].trigger:checked').trigger("change");bindAutoSave(step);if(currentStep){let prevButton=stepContainer.find(".prev-step");if(prevButton){prevButton.attr("data-step",currentStep)}}
57let radio=stepContainer.find('input[type="radio"]:checked').last();let button=stepContainer.find(".next-step");if(radio.length&&button.length){let nextStep=radio.data("next-form");button.attr("data-step",nextStep)}
58if(step===161||step===291||step===341){initCompanySearch(step)}
59if(step===170||step===300||step===350){initCompanySearchSecond(step)}
60if(step==400){const triggerGroupsPrimary=[...document.querySelectorAll(".loan__groups-primary"),];const triggerGroupsSecondary=[...document.querySelectorAll(".loan__groups-secondary"),];function updateCommonAmount(triggerGroups,prefix){let total=0;triggerGroups.forEach((group,i)=>{const wantedInput=group.querySelector(`input[name="debtors.${prefix}.activeLoans.${i}.isDebtConversionWanted"]:checked`,);const remainingInput=group.querySelector(`input[name="debtors.${prefix}.activeLoans.${i}
60.remainingAmount"]`,);if(!wantedInput||!remainingInput)return;if(wantedInput.dataset.value==="true"){total+=parseFloat(remainingInput.value)||0}});sessionStorage.setItem(`${LOAN_DATA}_${prefix}`,JSON.stringify(total),)}
61function updateRemainingAmount(group,i,prefix,triggerGroups){const inputAmount=group.querySelector(`input[name="debtors.${prefix}.activeLoans.${i}.amount"]`,);const inputMonthlyRate=group.querySelector(`input[name="debtors.${prefix}.activeLoans.${i}.monthlyRate"]`,);const inputStartOn=group.querySelector(`input[name="debtors.${prefix}.activeLoans.${i}.startedOn"]`,);const inputEndsOn=group.querySelector(`input[name="debtors.${prefix}.activeLoans.${i}.endsOn"]`,);const inputRemainingAmount=group.querySelector(`input[name="debtors.${prefix}.activeLoans.${i}.remainingAmount"]`,);if(!inputAmount||!inputMonthlyRate||!inputStartOn||!inputEndsOn||!inputRemainingAmount){return}
62if(!inputAmount.value.trim()||!inputMonthlyRate.value.trim()||!inputStartOn.value.trim()||!inputEndsOn.value.trim()){inputRemainingAmount.value="";updateCommonAmount(triggerGroups,prefix);return}
63const P=parseFloat(inputAmount.value);const A=parseFloat(inputMonthlyRate.value);const start=parseMonthYear(inputStartOn.value);const end=parseMonthYear(inputEndsOn.value);if(Number.isNaN(P)||Number.isNaN(A)||!start||!end){inputRemainingAmount.value="";updateCommonAmount(triggerGroups,prefix);return}
64const resultFinal=calculateLoan(P,A,start,end);let resultContainer=group.querySelector(".loan-result");if(!resultContainer){resultContainer=document.createElement("div");resultContainer.className="loan-result";group.appendChild(resultContainer)}
65if(resultFinal.showZins){let zinsDiv=document.getElementById("zinsBox");if(!zinsDiv){zinsDiv=document.createElement("div");zinsDiv.id="zinsBox";zinsDiv.className="zins-box";group.appendChild(zinsDiv)}
66zinsDiv.innerHTML=`
67    <strong>Zins:</strong> ${resultFinal.annualRate} %
68  `}else{const zinsDiv=document.getElementById("zinsBox");if(zinsDiv){zinsDiv.remove()}}
69inputRemainingAmount.value=resultFinal?.remainingAmount!=null?resultFinal.remainingAmount:"";updateCommonAmount(triggerGroups,prefix)}
70function initializeLoanGroups(triggerGroups,prefix){triggerGroups.forEach((group,i)=>{updateRemainingAmount(group,i,prefix,triggerGroups);[`input[name="debtors.${prefix}.activeLoans.${i}.amount"]`,`input[name="debtors.${prefix}.activeLoans.${i}.monthlyRate"]`,`input[name="debtors.${prefix}.activeLoans.${i}.startedOn"]`,`input[name="debtors.${prefix}.activeLoans.${i}.endsOn"]`,].forEach((selector)=>{const input=group.querySelector(selector);if(!input)return;input.addEventListener("input",()=>updateRemainingAmount(group,i,prefix,triggerGroups),);input.addEventListener("change",()=>updateRemainingAmount(group,i,prefix,triggerGroups),)});const remainingInput=group.querySelector(`input[name="debtors.${prefix}.activeLoans.${i}.remainingAmount"]`,);
70if(remainingInput){remainingInput.addEventListener("input",()=>updateCommonAmount(triggerGroups,prefix),);remainingInput.addEventListener("change",()=>updateCommonAmount(triggerGroups,prefix),)}
71const wantedInputs=group.querySelectorAll(`input[name="debtors.${prefix}.activeLoans.${i}.isDebtConversionWanted"]`,);wantedInputs.forEach((input)=>{input.addEventListener("change",()=>updateCommonAmount(triggerGroups,prefix),)})});updateCommonAmount(triggerGroups,prefix)}
72initializeLoanGroups(triggerGroupsPrimary,"primary");initializeLoanGroups(triggerGroupsSecondary,"secondary")}
73if(step==220){const triggerGroups=[...document.querySelectorAll(".loan__groups-primary"),];function updateCommonAmount(triggerGroups,prefix){let total=0;triggerGroups.forEach((group,i)=>{const wantedInput=group.querySelector(`input[name="debtors.${prefix}.activeLoans.${i}.isDebtConversionWanted"]:checked`,);const remainingInput=group.querySelector(`input[name="debtors.${prefix}.activeLoans.${i}.remainingAmount"]`,);if(!wantedInput||!remainingInput)return;const isWanted=wantedInput.dataset.value==="true";if(isWanted){total+=parseFloat(remainingInput.value)||0}});sessionStorage.setItem(`${LOAN_DATA}_${prefix}`,JSON.stringify(total),)}
74function updateRemainingAmount(group,i,prefix){const inputAmount=group.querySelector(`input[name="debtors.${prefix}.activeLoans.${i}.amount"]`,);const inputMonthlyRate=group.querySelector(`input[name="debtors.${prefix}.activeLoans.${i}.monthlyRate"]`,);const inputStartOn=group.querySelector(`input[name="debtors.${prefix}.activeLoans.${i}.startedOn"]`,);const inputEndsOn=group.querySelector(`input[name="debtors.${prefix}.activeLoans.${i}.endsOn"]`,);const inputRemainingAmount=group.querySelector(`input[name="debtors.${prefix}.activeLoans.${i}.remainingAmount"]`,);
74if(!inputAmount||!inputMonthlyRate||!inputStartOn||!inputEndsOn||!inputRemainingAmount){return}
75if(!inputAmount.value.trim()||!inputMonthlyRate.value.trim()||!inputStartOn.value.trim()||!inputEndsOn.value.trim()){inputRemainingAmount.value="";updateCommonAmount(triggerGroups,"primary");return}
76const P=parseInt(inputAmount.value,10);const A=parseInt(inputMonthlyRate.value,10);const start=parseMonthYear(inputStartOn.value);const end=parseMonthYear(inputEndsOn.value);if(Number.isNaN(P)||Number.isNaN(A)||!start||!end){inputRemainingAmount.value="";updateCommonAmount(triggerGroups,"primary");return}
77const resultFinal=calculateLoan(P,A,start,end);inputRemainingAmount.value=resultFinal?.remainingAmount!=null?resultFinal.remainingAmount:"";let resultContainer=group.querySelector(".loan-result");if(!resultContainer){resultContainer=document.createElement("div");resultContainer.className="loan-result";group.appendChild(resultContainer)}
78if(resultFinal.showZins){let zinsDiv=document.getElementById("zinsBox");if(!zinsDiv){zinsDiv=document.createElement("div");zinsDiv.id="zinsBox";zinsDiv.className="zins-box";group.appendChild(zinsDiv)}
79zinsDiv.innerHTML=`
80    <strong>Zins:</strong> ${resultFinal.annualRate} %
81  `}else{const zinsDiv=document.getElementById("zinsBox");if(zinsDiv){zinsDiv.remove()}}
82updateCommonAmount(triggerGroups,"primary")}
83triggerGroups.forEach((group,i)=>{updateRemainingAmount(group,i,"primary");[`input[name="debtors.primary.activeLoans.${i}.amount"]`,`input[name="debtors.primary.activeLoans.${i}.monthlyRate"]`,`input[name="debtors.primary.activeLoans.${i}.startedOn"]`,`input[name="debtors.primary.activeLoans.${i}.endsOn"]`,].forEach((selector)=>{const input=group.querySelector(selector);if(!input)return;input.addEventListener("input",()=>updateRemainingAmount(group,i,"primary"),);input.addEventListener("change",()=>updateRemainingAmount(group,i,"primary"),)});const remainingInput=group.querySelector(`input[name="debtors.primary.activeLoans.${i}.remainingAmount"]`,);
83if(remainingInput){remainingInput.addEventListener("input",()=>updateCommonAmount(triggerGroups,"primary"),);remainingInput.addEventListener("change",()=>updateCommonAmount(triggerGroups,"primary"),)}
84const wantedInputs=group.querySelectorAll(`input[name="debtors.primary.activeLoans.${i}.isDebtConversionWanted"]`,);wantedInputs.forEach((input)=>{input.addEventListener("change",()=>updateCommonAmount(triggerGroups,"primary"),)})});updateCommonAmount(triggerGroups,"primary")}
85if(step==180){const stepContainer=$(`.loan-step[data-step="${step}"]`);let button=stepContainer.find(".next-step");const purpose=new URLSearchParams(window.location.search).get("purpose",);const nextSteps={NEW_CAR:182,PRE_OWNED_CAR:181,};const nextStepValue=nextSteps[purpose];if(nextStepValue){button.attr("data-step",nextStepValue)}}
86if(step==360){const stepContainer=$(`.loan-step[data-step="${step}"]`);let button=stepContainer.find(".next-step");const purpose=new URLSearchParams(window.location.search).get("purpose",);const nextSteps={NEW_CAR:362,PRE_OWNED_CAR:361,};const nextStepValue=nextSteps[purpose];if(nextStepValue){button.attr("data-step",nextStepValue)}}
87if(step==190||step==370){const loanFormData=JSON.parse(sessionStorage.getItem("loanFormData"),);const result={};Object.values(loanFormData).forEach((section)=>{Object.entries(section).forEach(([path,value])=>{if(value===""||value==null)return;setNestedValue(result,path,normalizeValue(path,value))})});let positionVal=result.debtors.primary.currentEmployment.position;const civilStatus=document.querySelector("dd.summary__value.debtors\\.primary\\.personal\\.civilStatus",);let civilStatusValue=civilStatuses[document.documentElement.lang][result.debtors.primary.personal.civilStatus];if(civilStatus){civilStatus.innerText=civilStatusValue}
88const livingSituation=document.querySelector("dd.summary__value.debtors\\.primary\\.household\\.livingSituation",);let livingSituationValue=livingSituations[document.documentElement.lang][result.debtors.primary.household.livingSituation];if(livingSituation){livingSituation.innerText=livingSituationValue}
89const numberOfResidents=document.querySelector("dd.summary__value.debtors\\.primary\\.household\\.numberOfResidents",);if(numberOfResidents){numberOfResidents.innerText=result.debtors.primary.household.numberOfResidents}
90const position=document.querySelector("dd.summary__value.debtors\\.primary\\.currentEmployment\\.position",);const income=document.querySelector("dd.summary__value.debtors\\.primary\\.income\\.primary",);const isPensioner=positionVal==="RETIREE"||positionVal==="PENSIONER";const isFreelancer=new Set(["BOARD_MEMBER_OR_CEO","SELF_EMPLOYED_BUSINESSMAN","SELF_EMPLOYED_CEO","SELF_EMPLOYED_FREELANCER",]).has(positionVal);if(position){position.innerText=isPensioner?"Pensioner":isFreelancer?"Freelancer":result.debtors.primary.currentEmployment.jobTitle}
91const pension1=parseInt(result.debtors.primary.income.pensions?.[0]?.income,10)||0;const pension2=parseInt(result.debtors.primary.income.pensions?.[1]?.income,10)||0;const pension3=parseInt(result.debtors.primary.income.pensions?.[2]?.income,10)||0;if(income){income.innerText=isPensioner?pension1+pension2+pension3:result.debtors.primary.income.primary}}
92setTimeout(()=>{const data=computeStepData(stepContainer);saveStepData(step,data);const infoToggles=document.querySelectorAll(".info-toggle");infoToggles.forEach((toggle)=>{toggle.addEventListener("click",()=>{toggle.nextElementSibling.classList.toggle("show");toggle.classList.toggle("active")})});setProgress();setTitle();$("html, body").animate({scrollTop:0},"slow")},0)},})}
93function getAllFormData(){return JSON.parse(sessionStorage.getItem(DATA_KEY))||{}}
94function saveAllFormData(data){sessionStorage.setItem(DATA_KEY,JSON.stringify(data))}
95function saveStepData(step,data){const all=getAllFormData();all[String(step)]=data;saveAllFormData(all)}
96function getStepData(step){const all=getAllFormData();return all[String(step)]||{}}
97function computeStepData(stepContainer){const data={};stepContainer.find("input, select, textarea").each(function(){const field=$(this);const hiddenParentExists=field.parents(".content__radio-trigger").filter(function(){return $(this).css("display")==="none"}).length>0;const hiddenParentSelectExists=field.parents(".content__select-trigger").filter(function(){return $(this).css("display")==="none"}).length>0;const hiddenPartentSelectGroupExists=field.parents(".group__wrapper").filter(function(){return $(this).css("display")==="none"}).length>0;const hiddenSelectCount=field.parents(".target__select-count").filter(function(){return $(this).css("display")==="none"}).length>0;const hiddenCheckboxDiv=field.parents(".content__checkbox-trigger").filter(function(){return $(this).css("display")==="none"}).length>0;if(hiddenParentExists||hiddenParentSelectExists||hiddenPartentSelectGroupExists||hiddenSelectCount||hiddenCheckboxDiv){return}
98const name=field.attr("name");if(!name)return;const type=field.attr("type");const isRadio=type==="radio";const isChecked=field.is(":checked");const isVisible=field.is(":visible");if(isRadio){const group=stepContainer.find(`input[name="${name}"]`);const checked=group.filter(":checked");if(field.is(checked)){data[name]=field.data("value")}}else if(type==="checkbox"){data[name]=field.is(":checked")}else{let value=field.val();if(typeof value==="string"){value=value.trim()}
99if(field.hasClass("iban")){data[name]=value.replace(/\s/g,"").toUpperCase()}else if(field.hasClass("text__date-mm.yyyy")){if(value!==""){data[name]=formatShort(value)}}else if(field.hasClass("date__dd.mm.yyyy")){if(value!==""){data[name]=formatLong(value)}}else{data[name]=value}}
100const shouldApplyExtra=(isRadio&&isChecked&&isVisible)||(!isRadio&&isVisible);if(shouldApplyExtra){const extra=field.attr("data-extra");if(extra){try{const extraData=JSON.parse(extra);
100Object.entries(extraData).forEach(([key,value])=>{data[key]=value})}catch(e){console.warn("Invalid JSON in data-extra:",e)}}}});return data}
101function bindAutoSave(step){const stepContainer=$(`.loan-step[data-step="${step}"]`);function updateEmploymentVisibility(){const inputs=stepContainer.find(".employment__conditional");inputs.each(function(){const input=$(this);const value=input.val().trim();const target=input.closest(".group").find(".hidden__employment");if(!/^\d{2}\.\d{2}\.\d{4}$/.test(value)){target.hide();return}
102const inputYear=parseInt(value.split(".")[2],10);const currentYear=new Date().getFullYear();if(inputYear>=currentYear-2){target.show()}else{target.hide().find("input, textarea").each(function(){const type=$(this).attr("type");if(type==="radio"||type==="checkbox"){$(this).prop("checked",!1)}else{$(this).val("")}})}})}
103function setupCheckboxTrigger(group){const checkbox=group.querySelector(".trigger__checkbox");if(!checkbox)return;const parent=checkbox.closest(".group__wrapper");const target=parent.querySelector(`#${checkbox.value}`);if(!target)return;function update(){target.style.display=checkbox.checked?"block":"none"}
104checkbox.addEventListener("change",update);update()}
105function setupDependentSelect(group){const trigger=group.querySelector(".trigger__select-count");const target=group.querySelector(".target__select-count");const targetSelect=target.querySelector("select");if(!trigger||!target||!targetSelect)return;function update(useCurrentValue=!0){const max=Number(trigger.value);if(max===0){target.style.display="none";targetSelect.innerHTML="";targetSelect.add(new Option("0","0"));targetSelect.value="0";return}
106target.style.display="block";const currentValue=targetSelect.value;targetSelect.innerHTML="";for(let i=0;i<=max;i++){targetSelect.add(new Option(i,i))}
107if(useCurrentValue&&currentValue!==""&&Number(currentValue)<=max){targetSelect.value=currentValue}else{targetSelect.value=String(max);targetSelect.dispatchEvent(new Event("change",{bubbles:!0}))}}
108if(group.dataset.dependentInitialized==="true"){update();return}
109group.dataset.dependentInitialized="true";trigger.addEventListener("change",()=>update(!1));update(!0)}
110function updateSpecificValueVisibility(){const selects=stepContainer.find(".select__triger-specific-value");selects.each(function(){const select=$(this);const selectedValue=select.val();const specificValues=(select.data("specific-value")||"").toString().split(",").map((v)=>v.trim());const targetName=select.data("target");if(!targetName)return;const group=select.closest(".group__wrapper");const target=group.find(`#${targetName}`);if(!specificValues.includes(selectedValue)){target.show()}else{target.hide().find("input, select, textarea").each(function(){const type=$(this).attr("type");if(type==="radio"||type==="checkbox"){$(this).prop("checked",!1)}else{$(this).val("")}})}})}
111function updateSecondaryEmploymentVisibility(){stepContainer.find(".select_trigger").each(function(){const select=$(this);const value=parseInt(select.val(),10)||0;const container=select.closest(".group__wrapper");const wrappers=container.find(".trigger_group > .group__wrapper");wrappers.each(function(index){if(index<value){$(this).show()}else{$(this).hide().find("input, select, textarea").each(function(){const type=$(this).attr("type");
111const tag=$(this).prop("tagName").toLowerCase();if(type==="radio"||type==="checkbox"){$(this).prop("checked",!1)}else if(tag==="select"){const firstValue=$(this).find("option:first").val();$(this).val(firstValue)}else{$(this).val("")}})}})})}
112stepContainer.find("input, select, textarea").off("input.autoSave change.autoSave blur.autoSave").on("blur.autoSave",function(){if($(this).hasClass("text__date-mm.yyyy")){formatYearMonthInput($(this),!0)}
113if($(this).hasClass("date__dd.mm.yyyy")){formatDateInput($(this),!0)}
114if($(this).hasClass("date__yyyy-mm-dd")){formatDateInputAditional($(this),!0)}}).on("input.autoSave change.autoSave",function(){const name=$(this).attr("name");if(name){stepContainer.find(`.field-error[data-error-for="${name}"]`).text("");$(this).removeClass("error")}
115if($(this).hasClass("text__date-mm.yyyy")){formatYearMonthInput($(this))}
116if($(this).hasClass("date__dd.mm.yyyy")){formatDateInput($(this))}
117if($(this).hasClass("date__yyyy-mm-dd")){formatDateInputAditional($(this))}
118if($(this).hasClass("iban")){const iban=$(this).val().replace(/\s/g,"").toUpperCase();const bicElement=$(this).closest(".group").find(".bic");if(!iban.startsWith("DE")){bicElement.val("");return}
119const bic=bankdataGermany.bankDataByIBAN(iban)?.bic??"";bicElement.val(bic)}
120if($(this).hasClass("employment__conditional")){const value=$(this).val().trim();if(!/^\d{2}\.\d{2}\.\d{4}$/.test(value)){$(this).closest(".group").find(".hidden__employment").hide();return}
121const inputYear=parseInt(value.split(".")[2],10);const currentYear=new Date().getFullYear();if(inputYear>=currentYear-2){$(this).closest(".group").find(".hidden__employment").show()}else{$(this).closest(".group").find(".hidden__employment").hide()}}
122stepContainer.find('input[type="radio"].trigger').each(function(){const radio=$(this);const groupWrapper=radio.closest(".group__wrapper");if(radio.is(":checked")){const targetId=radio.val();groupWrapper.find(".content__radio-trigger").hide();if(targetId){groupWrapper.find(`#${targetId}`).show()}}});updateSpecificValueVisibility();updateSecondaryEmploymentVisibility();updateEmploymentVisibility();document.querySelectorAll(".select-count-group").forEach(setupDependentSelect);document.querySelectorAll(".group").forEach(setupCheckboxTrigger);const data=computeStepData(stepContainer);saveStepData(step,data)});updateSpecificValueVisibility();updateSecondaryEmploymentVisibility();updateEmploymentVisibility();document.querySelectorAll(".select-count-group").forEach(setupDependentSelect);document.querySelectorAll(".group").forEach(setupCheckboxTrigger);stepContainer.find('input[type="radio"].trigger:checked').trigger("change")}
123function formatLong(date){const[day,month,year]=date.split(".");return `${year}-${month}-${day}`}
124function formatShort(monthYear){const[month,year]=monthYear.split(".");return `${year}-${month}`}
125function formatLongReverse(date){const[year,month,day]=date.split("-");return `${day}.${month}.${year}`}
126function formatShortReverse(monthYear){const[year,month]=monthYear.split("-");return `${month}.${year}`}
127function restoreStepData(step){const data=getStepData(step);const stepContainer=$(`.loan-step[data-step="${step}"]`);Object.keys(data).forEach((name)=>{const value=data[name];const field=stepContainer.find(`[name="${name}"]`);if(!field.length)return;const type=field.attr("type");const tag=field.prop("tagName").toLowerCase();if(type==="checkbox"){field.prop("checked",value)}else if(type==="radio"){stepContainer.find(`[name="${name}"][data-value="${value}"]`).prop("checked",!0)}else if(tag==="select"){field.val(value)}else{if(field.hasClass("text__date-mm.yyyy")){field.val(formatShortReverse(value))}else if(field.hasClass("date__dd.mm.yyyy")){field.val(formatLongReverse(value))}else{field.val(value)}}})}
128function validateIBAN(iban){if(!iban)return!1;iban=iban.replace(/\s+/g,"").toUpperCase();if(!/^[A-Z]{2}[0-9]{2}[A-Z0-9]+$/.test(iban)){return!1}
129const country=iban.slice(0,2);if(!ibanLengths[country]||iban.length!==ibanLengths[country]){return!1}
130const rearranged=iban.slice(4)+iban.slice(0,4);let numeric="";
130for(const ch of rearranged){if(/[A-Z]/.test(ch)){numeric+=(ch.charCodeAt(0)-55).toString()}else{numeric+=ch}}
131let remainder=0;for(const digit of numeric){remainder=(remainder*10+Number(digit))%97}
132return remainder===1}
133function validateBIC(bic){if(!bic)return!1;bic=bic.replace(/\s+/g,"").toUpperCase();const match=bic.match(/^([A-Z]{4})([A-Z]{2})([A-Z0-9]{2})([A-Z0-9]{3})?$/,);if(!match)return!1;const country=match[2];return ISO_COUNTRIES.has(country)}
134function isValidInternationalPhoneNumber(value){try{value=value.trim();if(!value){return!1}
135const phoneNumber=libphonenumber.parsePhoneNumber(`+49${value}`);return phoneNumber.isValid();return!1}catch(error){return!1}}
136function validateStep(step){const stepContainer=$(`.loan-step[data-step="${step}"]`);let valid=!0;stepContainer.find(".field-error").text("");stepContainer.find(".error").removeClass("error");stepContainer.find("input, select, textarea").each(function(){const el=$(this);const name=el.attr("name");if(!name)return;if(!el.is(":visible"))return;if(isHiddenField(el))return;const value=el.val();const type=el.attr("type");const required=el.prop("required");let message="";if(el.hasClass("less_than-14")){const workDate=new Date(el.val());const today=new Date();const minWorkDate=new Date(today.getFullYear()-14,today.getMonth(),today.getDate(),);if(workDate>minWorkDate){message=validationMessages[document.documentElement.lang].MINIMUM_YEARS_14}}
137if(el.hasClass("birthday")){const[day,month,year]=el.val().split(".").map(Number);const birthDate=new Date(year,month-1,day);const today=new Date();const minAgeDate=new Date(today.getFullYear()-18,today.getMonth(),today.getDate(),);if(birthDate>minAgeDate){message=validationMessages[document.documentElement.lang].MINIMUM_YEARS_18}}
138if(el.hasClass("zip_code")){const country=el.closest(".zip-group").find(".country_zip_code").val();if(!isValidZipCode(country,value)){message=validationMessages[document.documentElement.lang].INVALID_ZIP_CODE}}
139if(el.hasClass("iban")&&!validateIBAN(value)){message=validationMessages[document.documentElement.lang].INVALID_IBAN}
140if(el.hasClass("bic")&&!validateBIC(value)){message=validationMessages[document.documentElement.lang].INVALID_BIC}
141if(el.hasClass("phone-num")&&!isValidInternationalPhoneNumber(value)){message=validationMessages[document.documentElement.lang].INVALID_PHONE}
142if(type==="checkbox"){if(required&&!el.is(":checked")){message=validationMessages[document.documentElement.lang].REQUIRED_FIELD}}else if(type==="radio"){if(required&&stepContainer.find(`[name="${name}"]:checked`).length===0){message=validationMessages[document.documentElement.lang].PLEASE_SELECT_OPTION}}else{if(required&&(!value||value.trim()==="")){message=validationMessages[document.documentElement.lang].REQUIRED_FIELD}
143if(!message&&type==="number"&&value!==""){const num=Number(value);const minAttr=el.attr("min");const maxAttr=el.attr("max");if(minAttr!==undefined){const min=Number(minAttr);if(!isNaN(min)&&num<min){message=`${validationMessages[document.documentElement.lang]["MINIMUM_VALUE_IS"]} ${min}`}}
144if(!message&&maxAttr!==undefined){const max=Number(maxAttr);if(!isNaN(max)&&num>max){message=`${validationMessages[document.documentElement.lang]["MAXIMUM_VALUE_IS"]} ${max}`}}}
145if(!message&&type==="email"&&value){const ok=validator.isEmail(value,{allow_utf8_local_part:!1,require_tld:!0,allow_ip_domain:!1,});if(!ok){message=validationMessages[document.documentElement.lang].INVALID_EMAIL_FORMAT}else{const domain=value.split("@")[1];const tld=domain.split(".").pop().toUpperCase();if(!validTlds.has(tld)){message=validationMessages[document.documentElement.lang].INVALID_EMAIL_FORMAT}}}}
146if(message){valid=!1;el.addClass("error");stepContainer.find(`.field-error[data-error-for="${name}"]`).text(message)}});return valid}
147function formatDateInputAditional(input,onBlur=!1){let value=input.val().replace(/\D/g,"").slice(0,8);if(value.length>4){value=value.slice(0,4)+"-"+value.slice(4)}
148if(value.length>7){value=value.slice(0,7)+"-"+value.slice(7)}
149input.val(value);if(onBlur&&value.length!==10){input.val("");return}
150if(value.length===10){const[year,month,day]=value.split("-").map(Number);const date=new Date(year,month-1,day);const isValid=year>=1900&&month>=1&&month<=12&&day>=1&&day<=31&&date.getFullYear()===year&&date.getMonth()===month-1&&date.getDate()===day;if(!isValid){input.val("")}}}
151function formatDateInput(input,onBlur=!1){let value=input.val().replace(/\D/g,"").slice(0,8);if(value.length>2){value=value.slice(0,2)+"."+value.slice(2)}
152if(value.length>5){value=value.slice(0,5)+"."+value.slice(5)}
153input.val(value);if(onBlur&&value.length!==10){input.val("");return}
154if(value.length===10){const[day,month,year]=value.split(".").map(Number);const date=new Date(year,month-1,day);const isValidDate=year>=1900&&month>=1&&month<=12&&day>=1&&day<=31&&date.getFullYear()===year&&date.getMonth()===month-1&&date.getDate()===day;if(!isValidDate){input.val("");return}
155const today=new Date();const currentDate=new Date(today.getFullYear(),today.getMonth(),today.getDate(),);const isFutureField=input.hasClass("future-date");const isPastField=input.hasClass("past-date");let isValid=!0;if(isFutureField){isValid=date>=currentDate}else if(isPastField){isValid=date<=currentDate}
156if(!isValid){input.val("")}}}
157function formatYearMonthInput(input,onBlur=!1){let value=input.val().replace(/\D/g,"").slice(0,6);if(value.length>2){value=value.slice(0,2)+"."+value.slice(2)}
158input.val(value);if(onBlur&&value.length!==7){input.val("");return}
159if(value.length===7){const[month,year]=value.split(".").map(Number);const date=new Date(year,month-1);const now=new Date();const isValidMonth=year>=1900&&month>=1&&month<=12;if(!isValidMonth){input.val("");return}
160const currentMonthDate=new Date(now.getFullYear(),now.getMonth());const isFutureField=input.hasClass("future-date");const isPastField=input.hasClass("past-date");let isValid=!0;if(isFutureField){isValid=date>=currentMonthDate}else if(isPastField){isValid=date<=currentMonthDate}
161if(!isValid){input.val("")}}}
162function setProgress(){const formData=JSON.parse(sessionStorage.getItem("loanFormData")||"{}");const filledSteps=new Set(Object.keys(formData).map(Number));let percent=bestPathPercentage(filledSteps);const bar=document.getElementById("bar");const label=document.getElementById("label");if(bar)bar.style.width=percent+"%";if(label)label.innerText=percent+"%"}
163function setTitle(){const loanStep=document.querySelector(".loan-step");if(!loanStep)return;const headerForm=document.querySelector(".header__form");if(!headerForm)return;const title=loanStep.dataset.stepHeaderForm;if(!title){headerForm.style.display="none";return}
164headerForm.style.display="";const titleElement=headerForm.querySelector("p.title");if(titleElement){titleElement.innerText=title}}
165function bestPathPercentage(filledSteps){let bestScore=0;let bestPathSteps=[];for(const steps of Object.values(paths)){const score=steps.filter((s)=>filledSteps.has(s)).length;if(score>bestScore){bestScore=score;bestPathSteps=steps}}
166const percent=bestPathSteps.length===0?0:Math.round((bestScore/bestPathSteps.length)*100);return percent}
167function getPreviousStep(){const data=JSON.parse(sessionStorage.getItem("loanFormData"))||{};const steps=Object.keys(data).map(Number).sort((a,b)=>a-b);const currentStep=Number(getStoredStep());const currentIndex=steps.indexOf(currentStep);if(currentIndex>0){return steps[currentIndex-1]}
168return null}
169$(document).on("click",".next-step",function(){let step=$(this).data("step");let currentStep=getStoredStep();if(!validateStep(currentStep)){$("html, body").animate({scrollTop:0},"slow");return}
170loadStep(step,currentStep)});$(document).on("click",".prev-step",function(){const prevStep=getPreviousStep();if(!prevStep)return;deleteStepData(getStoredStep());loadStep(prevStep)});function setNestedValue(obj,path,value){const keys=path.split(".");let current=obj;keys.forEach((key,index)=>
170{if(index===keys.length-1){current[key]=value}else{current[key]??={};current=current[key]}})}
171function normalizeValue(path,value){if(value===""||value===null||value===undefined){return value}
172return value}
173function showLoading(text="Processing, please wait..."){const overlay=document.getElementById("loadingOverlay");const message=overlay.querySelector("p");if(message)message.innerHTML=text;overlay.classList.remove("hidden")}
174function hideLoading(){const overlay=document.getElementById("loadingOverlay");overlay.classList.add("hidden")}
175function isValidZipCode(country,zip){zip=zip.trim().toUpperCase();if(country==="OTHER"){return!0}
176const rules={DE:/^\d{5}$/,BE:/^\d{4}$/,DK:/^\d{4}$/,FR:/^\d{5}$/,LU:/^\d{4}$/,NL:/^\d{4}\s?[A-Z]{2}$/,AT:/^\d{4}$/,PL:/^\d{2}-?\d{3}$/,CH:/^\d{4}$/,CZ:/^\d{3}\s?\d{2}$/,};return rules[country]?rules[country].test(zip):!0}
177function parseMonthYear(value){const[month,year]=value.split(".").map(Number);return new Date(year,month-1,1)}
178function monthsBetween(start,end){return((end.getFullYear()-start.getFullYear())*12+(end.getMonth()-start.getMonth()))}
179function solveMonthlyRate(P,A,n){if(A<=0||n<=0){return null}
180if(A*n<=P){return 0}
181let lo=0;let hi=1;for(let k=0;k<100;k++){const i=(lo+hi)/2;const Atest=(P*i)/(1-Math.pow(1+i,-n));if(Atest>A){hi=i}else{lo=i}}
182return(lo+hi)/2}
183function calculateLoan(P,A,startDate,endDate){if(P<=0||A<=0||!startDate||!endDate){return null}
184const n=monthsBetween(startDate,endDate);if(n<=0){return{valid:!1,}}
185const i=solveMonthlyRate(P,A,n);if(i===null){return{valid:!1,}}
186let Acheck;if(i===0){Acheck=P/n}else{Acheck=(P*i)/(1-Math.pow(1+i,-n))}
187if(Math.abs(Acheck-A)>0.5){return{valid:!1,showZins:!1,showSavings:!1,remainingAmount:null,n,}}
188const annualRate=(Math.pow(1+i,12)-1)*100;const today=new Date();let m=monthsBetween(startDate,today);m=Math.max(0,Math.min(m,n));let rest;if(i===0){rest=P-A*m}else{const factor=Math.pow(1+i,m);rest=P*factor-(A*(factor-1))/i}
189if(rest<0){rest=0}
190rest=Math.round(rest);return{valid:!0,n,monthlyRate:i,annualRate:Number(annualRate.toFixed(2)),remainingAmount:rest,showZins:!0,showSavings:!0,}}
191$(document).on("click",".submit",function(){const loanFormData=JSON.parse(sessionStorage.getItem("loanFormData"));const result={};Object.values(loanFormData).forEach((section)=>{Object.entries(section).forEach(([path,value])=>{if(value===""||value==null)return;setNestedValue(result,path,normalizeValue(path,value))})});const primary=result?.debtors?.primary;const userMail=primary.contact.email;const userBirthday=primary.personal.birthday;const params=new URLSearchParams(window.location.search);result.common.purpose=params.get("purpose")||"";result.common.term=params.get("loan_term")||"";result.common.loanPayout="AS_SOON_AS_POSSIBLE";if(params.has("ref")){result.common.externalTraversalId=params.get("ref")}
192const loanAmount=Number(params.get("loan_amount")||0);const remainingValuePrimary=Number(sessionStorage.getItem("remainingValue_primary")||0,);result.common.amount=loanAmount+remainingValuePrimary;if(primary){primary.expenses??={};primary.income??={};primary.personal??={};primary.currentEmployment??={};primary.household??={};let phoneNumber=primary.contact.mobilePhoneNumber?.trim();if(phoneNumber&&!phoneNumber.startsWith('+49')){primary.contact.mobilePhoneNumber='+49'+phoneNumber}
193const expenses=primary.expenses;const income=primary.income;const personal=primary.personal;const household=primary.household;const currentEmployment=primary.currentEmployment;const numberOfActiveLoans=parseInt(primary?.numberOfActiveLoans??0,10,);for(let i=0;i<numberOfActiveLoans;i++){const loan=primary?.activeLoans?.[i];if(loan?.bankAccount){loan.bankAccount.type="IBAN_BIC"}}
194result.common??={};result.common.hasAcceptedTerms=!0;expenses.hasBike=!1;income.interest=0;household.numberOfResidents=Number.parseInt(household.numberOfResidents||0,10)+Number.parseInt(household.numberOfChildren||0,10);if(Number.parseInt(household.numberOfChildren||0,10)===0){income.numberOfChildrenWithChildBenefits=0}
195personal.hasAdditionalNationalities=Number(personal.hasAdditionalNationalities)>0;if(!personal.hasAdditionalNationalities){personal.additionalNationalities=[]}
196expenses.cards=result?.primary?.expenses?.cards===!1?"NONE":expenses.cards;const positionVal=currentEmployment.position;const isPensioner=positionVal==="RETIREE"||positionVal==="PENSIONER";const isFreelancer=new Set(["BOARD_MEMBER_OR_CEO","SELF_EMPLOYED_BUSINESSMAN","SELF_EMPLOYED_CEO","SELF_EMPLOYED_FREELANCER",]).has(positionVal);currentEmployment.jobTitle=isPensioner?"Pensioner":isFreelancer?"Freelancer":currentEmployment.jobTitle;if(isFreelancer||isPensioner){income.numberOfSecondaryEmployments=0;if(income.hasFurtherIncome){income.pension=0}}
197if(isPensioner){if(result?.pension_country_primary){primary.pensionFund??={};primary.pensionFund.address??={};Object.assign(primary.pensionFund,{name:"Deutsche Rentenversicherung Bund",});Object.assign(primary.pensionFund.address,{street:"Ruhrstraße",houseNumber:"2",zipCode:"10709",city:"Berlin",country:"DE",})}}
198if(income.secondaryEmployments){const employments=Object.values(income.secondaryEmployments).filter((employment)=>employment?.isIncomeProvable,);income.secondaryEmployments=Object.fromEntries(employments.map((employment,index)=>[index,employment]),);income.numberOfSecondaryEmployments=employments.length}}
199if(result.debtors.count==2){const secondary=result?.debtors?.secondary;const remainingValueSecondary=Number(sessionStorage.getItem("remainingValue_secondary")||0,);result.common.amount+=remainingValueSecondary;if(secondary){secondary.expenses??={};secondary.income??={};secondary.personal??={};secondary.currentEmployment??={};secondary.household??={};const expenses=secondary.expenses;const income=secondary.income;const personal=secondary.personal;const household=secondary.household;const currentEmployment=secondary.currentEmployment;let phoneNumber=secondary.contact.mobilePhoneNumber?.trim();if(phoneNumber&&!phoneNumber.startsWith('+49')){secondary.contact.mobilePhoneNumber='+49'+phoneNumber}
200if(result.debtors.isCommonHousehold){household.numberOfResidents=result?.debtors?.primary?.household?.numberOfResidents}else{household.numberOfResidents=Number.parseInt(household.numberOfResidents||0,10)+Number.parseInt(household.numberOfChildren||0,10)}
201expenses.hasBike=!1;income.interest=0;const numberOfActiveLoans=parseInt(secondary?.numberOfActiveLoans??0,10,);for(let i=0;i<numberOfActiveLoans;i++){const loan=secondary?.activeLoans?.[i];if(loan?.bankAccount){loan.bankAccount.type="IBAN_BIC"}}
202if(Number.parseInt(household.numberOfChildren||0,10)===0){income.numberOfChildrenWithChildBenefits=0}
203personal.hasAdditionalNationalities=Number(personal.hasAdditionalNationalities)>0;if(!personal.hasAdditionalNationalities){personal.additionalNationalities=[]}
204expenses.cards=result?.secondary?.expenses?.cards===!1?"NONE":expenses.cards;const numOfActiveLoans=Number.parseInt(secondary.numberOfActiveLoans||0,10,);const activeLoans=expenses.activeLoans??[];for(let i=0;i<numOfActiveLoans;i++){if(activeLoans[i]){activeLoans[i].isCommonLoanWithOtherDebtor=!1}}
205expenses.activeLoans=activeLoans;const positionVal=currentEmployment.position;const isPensioner=positionVal==="RETIREE"||positionVal==="PENSIONER";const isFreelancer=new Set(["BOARD_MEMBER_OR_CEO","SELF_EMPLOYED_BUSINESSMAN","SELF_EMPLOYED_CEO","SELF_EMPLOYED_FREELANCER",]).has(positionVal);currentEmployment.jobTitle=isPensioner?"Pensioner":isFreelancer?"Freelancer":currentEmployment.jobTitle;if(isFreelancer||isPensioner){income.numberOfSecondaryEmployments=0;if(income.hasFurtherIncome){income.pension=0}}
206if(isPensioner){if(result?.pension_country_secondary){secondary.pensionFund??={};secondary.pensionFund.address??={};Object.assign(secondary.pensionFund,{name:"Deutsche Rentenversicherung Bund",});Object.assign(secondary.pensionFund.address,{street:"Ruhrstraße",houseNumber:"2",zipCode:"10709",city:"Berlin",country:"DE",})}}
207if(income.secondaryEmployments){const employments=Object.values(income.secondaryEmployments).filter((employment)=>employment?.isIncomeProvable,);income.secondaryEmployments=Object.fromEntries(employments.map((employment,index)=>[index,employment]),);income.numberOfSecondaryEmployments=employments.length}}}
208let step=$(this).data("step");let currentStep=getStoredStep();if(!validateStep(currentStep)){$("html, body").animate({scrollTop:0},"slow");return}
209$.ajax({url:loanForms.ajaxurl,type:"POST",dataType:"json",data:{action:"send_data_to_finanzcheck",common:result.common,debtors:result.debtors,},beforeSend:function(){showLoading(validationMessages[document.documentElement.lang].SENDING_DATA,)},success:function(response){showLoading(validationMessages[document.documentElement.lang].PROCESSING_PLEASE_WAIT,);const resultDiv=document.querySelector(".api-call__result");if(resultDiv){if(response?.data?.errors?.length){response.data.errors.forEac
209h((err)=>{showToast(`${err.message} (${err.code})`,"error")});const errorsData=response.data.errors.map((err)=>`<li>${err.message} (${err.code})</li>`).join("");resultDiv.innerHTML+=`
210            <div class="api-errors">
211              <h3>Errors</h3>
212              <ul>
213                ${errorsData}
214              </ul>
215            </div>
216          `;$.ajax({url:loanForms.ajaxurl,type:"POST",dataType:"json",data:{action:"send_errors_internal",errors:errorsData,mail:userMail,},success:function(response){console.log("Errors sent:",response)},error:function(xhr,status,error){console.error("Second request error:",error)},});hideLoading();return}}
217const traversalID=response.data.result.id;const params=new URLSearchParams(window.location.search);const externalID=params.get("ref")||"";const WAIT_TIME=150;let remaining=WAIT_TIME;function formatTime(seconds){const min=Math.floor(seconds/60);const sec=seconds%60;return `${String(min).padStart(2, "0")}:${String(sec).padStart(2, "0")}`}
218showLoading(`${
219            validationMessages[document.documentElement.lang][
220              "WAITING_FOR_BANK_OFFERS"
221            ]
222          } (${formatTime(remaining)})... <b>${
223            validationMessages[document.documentElement.lang][
224              "DONT_CLOSE_WINDOW"
225            ]
226          }</b>`,);const countdown=setInterval(()=>{remaining--;showLoading(`${
227              validationMessages[document.documentElement.lang][
228                "WAITING_FOR_BANK_OFFERS"
229              ]
230            } (${formatTime(remaining)})... <b>${
231              validationMessages[document.documentElement.lang][
232                "DONT_CLOSE_WINDOW"
233              ]
234            }</b>`,);if(remaining<=0){clearInterval(countdown)}},1000);setTimeout(()=>{clearInterval(countdown);showLoading(validationMessages[document.documentElement.lang].FETCHING_OFFERS,);$.ajax({url:loanForms.ajaxurl,type:"POST",dataType:"json",data:{action:"get_result_from_finanzcheck",data:JSON.stringify({...response.data,from_result_page:!0,user_mail:userMail,user_birthday:userBirthday,external_id:externalID,}),},success:function(response){const resultDiv=document.querySelector(".api-call__result");function createOfferCard(app){const bankImages={"SWK Bank":"/wp-content/themes/bvd-admin/assets/media/img/swk.png","PSD Bank":"/wp-content/themes/bvd-admin/assets/media/img/PSD_Bank_logo.png","SKG Bank":"/wp-content/themes/bvd-admin/assets/media/img/skg.png","Santander BestCredit":"/wp-content/themes/bvd-admin/assets/media/img/santander.png",DKB:"/wp-content/themes/bvd-admin/assets/media/img/dkb.png",Postbank:"/wp-content/themes/bvd-admin/assets/media/img/postbank.png",auxmoney:"/wp-content/themes/bvd-admin/assets/media/img/auxmoney.png","ING-DiBa":"/wp-content/themes/bvd-admin/assets/media/img/ingdiba.png",};const imageSrc=bankImages[app.bankName]||"";const ratingClass=app.rating?.toLowerCase()==="green"?"offer-card__rating--green":"offer-card__rating--red";const checkoutButton=app.checkoutUrl&&app.checkoutUrl.trim()!==""?`
235                    <a
236                      href="${app.checkoutUrl}"
237                      class="offer-card__button"
238                      target="_blank"
239                      rel="noopener noreferrer"
240                    >
241                      ${buttonText[document.documentElement.lang]["CHECKOUT"]}
242                    </a>
243                  `:"";const generatePDFButton=`
244                <button
245                  type="button"
246                  class="offer-card__button offer-card__button--ajax"
247                  data-bank-app-name="${app.bankName}"
248                  data-amount="${app.amountNet}"
249                  data-bank-app-id="${app.id}" data-traversal-id="${traversalID}"
250                >
251                  ${buttonText[document.documentElement.lang]["SELECT_OFFER"]}
252                </button>
253              `;return `
254        <aside class="offer-card" data-bank-app-id=${app.id}>
255          <div class="offer-card__content">
256            <div class="offer-card__main">
257              <img class="offer-card__logo" src="${imageSrc}" alt="${app.bankName}" />
258
259              <div class="offer-card__details">
260                <div class="offer-card__column">
261                  <span class="label"><strong>Kreditbetrag</strong></span>
262                  <span class="value">${app.amountNet ?? "-"} €</span>
263                </div>
264
265                <div class="offer-card__column">
266                  <span class="label"><strong>Monate</strong></span>
267                  <span class="value">${app.term ?? "-"}</span>
268                </div>
269
270                <div class="offer-card__column">
271                  <span class="label"><strong>Zins (eff.)</strong></span>
272                  <span class="value">${app.effectiveInterestRate ?? "-"}%</span>
273                </div>
274
275                <div class="offer-card__column">
276              <span class="label">Rating</span>
277              <span class="value ${ratingClass}">
278                ${app.rating ?? "-"}
279              </span>
280            </div>
281              </div>
282            </div>
283
284            <aside class="offer-card__sidebar">
285              <span class="label"><strong>mtl. Rate</strong></span>
286              <span class="value">${app.monthlyRate ?? "-"} €</span>
287              ${generatePDFButton}
288            </aside>
289          </div>
290        </aside>
291      `}
292if(resultDiv&&response.data){const validOffers=response.data.filter((item)=>{const app=item.result?.application;return app&&app.rating?.toLowerCase()==="green"});if(validOffers.length===0){const hiddenKreditKard=document.querySelector('#kredit__card-page');let resultUrl='';if(hiddenKreditKard){resultUrl=hiddenKreditKard.value+`?traversal_id=${traversalID}`}
293resultDiv.innerHTML+=`<div class="no-offers">${buttonText[document.documentElement.lang]["NO_OFFERS"]} </div>`;$.ajax({url:loanForms.ajaxurl,type:"POST",dataType:"json",data:{action:"send_email_for_credit_card",traversalId:traversalID,userMail:userMail},success:function(response){},error:function(xhr,status,error){console.error("Request error:",error)},});if(resultUrl){setTimeout(function(){window.location.href=resultUrl},400)}}else{validOffers.forEach((item)=>{resultDiv.innerHTML+=createOfferCard(item.result.application,)})}
294resultDiv.querySelectorAll(".offer-card__button--ajax").forEach((button)=>{button.addEventListener("click",handlePDFGeneration)})}
295hideLoading()},error:function(xhr,status,error){console.error("Second request error:",error);hideLoading()},})},WAIT_TIME*1000)},error:function(xhr){document.body.classList.remove("loading");const resultDiv=document.querySelector(".api-call__result");let message="Unknown error";try{const err=xhr.responseJSON||JSON.parse(xhr.responseText);message=err.message||JSON.stringify(err)}catch(e){message=xhr.statusText||message}
296if(resultDiv){resultDiv.textContent="Error: "+message}
297console.error("First request error:",message)},})});function handlePDFGeneration(e){const button=e.currentTarget;button.disabled=!0;const bankApplicationId=button.dataset.bankAppId;const traversalId=button.dataset.traversalId;const bankAppName=button.dataset.bankAppName;const amount=button.dataset.amount;const params=new URLSearchParams(window.location.search);const externalID=params.get("ref")||"";const loanFormData=JSON.parse(sessionStorage.getItem("loanFormData"));const result={};Object.values(loanFormData).forEach((section)=>{Object.entries(section).forEach(([path,value])=>{if(value===""||value==null)return;setNestedValue(result,path,normalizeValue(path,value))})});const mail=result.debtors.primary.contact.email;const userBirthday=result.debtors.primary.personal.birthday;$.ajax({url:loanForms.ajaxurl,type:"POST",dataType:"json",data:{action:"get_pdf_from_finanzcheck",bankApplicationId:bankApplicationId,traversalId:traversalId,bank_app_name:bankAppName,user_mail:mail,user_birthday:userBirthday,external_id:externalID,kredit_amount:amount,},success:function(response){showToast(`${validationMessages[document.documentElement.lang]["SUCCESS_POPUP"]}`,"success",)},error:function(xhr,status,error){console.error("Request error:",error)},})}
298function showToast(message,type="info"){let container=document.getElementById("toast-container");if(!container){container=document.createElement("div");container.id="toast-container";document.body.appendChild(container)}
299const toast=document.createElement("div");toast.className=`toast__custom ${type}`;toast.textContent=message;container.appendChild(toast);setTimeout(()=>{toast.classList.add("show")},10);setTimeout(()=>{toast.classList.remove("show");setTimeout(()=>{toast.remove()},300)},16000)}
300function deleteStepData(step){const all=getAllFormData();delete all[String(step)];saveAllFormData(all)}
300
301function isHiddenField(el){return(el.parents(".content__radio-trigger, .content__select-trigger, .group__wrapper",).filter(function(){return $(this).css("display")==="none"}).length>0)}})

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.