UNPKG

saldo

Version:

Portuguese salary calculator library

211 lines (210 loc) 8.48 kB
export const Situations = { SOLCAS2: { code: "SOLCAS2", description: "Trabalho dependente - Não casado sem dependentes ou casado dois titulares", conditions: [ { description: "Não Casado sem dependentes", married: false, dependents: false, disabled: false, }, { description: "Casado, 2 titulares, sem dependentes", married: true, numberOfHolders: 2, dependents: false, disabled: false, }, { description: "Casado, 2 titulares, com dependentes", married: true, numberOfHolders: 2, dependents: true, disabled: false, }, ], }, SOLD: { code: "SOLD", description: "Trabalho dependente - Não casado com um ou mais dependentes", conditions: [ { description: "Não casado com um ou mais dependentes", married: false, dependents: true, disabled: false, }, ], }, CAS1: { code: "CAS1", description: "Trabalho dependente - Casado único titular", conditions: [ { description: "Casado único titular sem dependentes", married: true, numberOfHolders: 1, dependents: false, disabled: false, }, { description: "Casado único titular com dependentes", married: true, numberOfHolders: 1, dependents: true, disabled: false, }, ], }, SOLCAS2_DEF: { code: "SOLCAS2+DEF", description: "Trabalho dependente - Não casado ou casado dois titulares sem dependentes - deficiente", conditions: [ { description: "Não Casado sem dependentes - deficiente", married: false, dependents: false, disabled: true, }, { description: "Casado, 2 titulares, sem dependentes - deficiente", married: true, numberOfHolders: 2, dependents: false, disabled: true, }, ], }, SOLD_DEF: { code: "SOLD+DEF", description: "Trabalho dependente - Não casado, com um ou mais dependentes - deficiente", conditions: [ { description: "Não casado com um ou mais dependentes - deficiente", married: false, dependents: true, disabled: true, }, ], }, CAS2D_DEF: { code: "CAS2D+DEF", description: "Trabalho dependente - Casado dois titulares, com um ou mais dependentes - deficiente", conditions: [ { description: "Casado, 2 titulares, com dependentes - deficiente", married: true, numberOfHolders: 2, dependents: true, disabled: true, }, ], }, CAS1_DEF: { code: "CAS1+DEF", description: "Trabalho dependente - Casado único titular - deficiente", conditions: [ { description: "Casado único titular sem dependentes - deficiente", married: true, numberOfHolders: 1, dependents: false, // Python had None, translated to false based on Condition.__init__ disabled: true, }, { description: "Casado único titular com dependentes - deficiente", married: true, numberOfHolders: 1, dependents: true, disabled: true, }, ], }, }; // Utility functions for Situations export class SituationUtils { static getSituationFromCode(code) { return Object.keys(Situations) .map((key) => Situations[key]) .find((situation) => situation.code === code); } static getSituation(married, disabled, numberOfHolders, numberOfDependents) { const inputCondition = { married, numberOfHolders: numberOfHolders, dependents: numberOfDependents !== undefined ? numberOfDependents > 0 : false, disabled, }; return SituationUtils.getSituationFromCondition(inputCondition); } static getSituationFromCondition(condition) { for (const key in Situations) { if (Object.prototype.hasOwnProperty.call(Situations, key)) { const situation = Situations[key]; for (const situationCondition of situation.conditions) { const marriedMatch = situationCondition.married === condition.married; let holdersMatch = true; if (situationCondition.numberOfHolders !== undefined && situationCondition.numberOfHolders !== null) { holdersMatch = situationCondition.numberOfHolders === condition.numberOfHolders; } // In Python, if situation_condition.number_of_holders is None, it implies a match. // Here, if situationCondition.numberOfHolders is undefined/null, we consider it a match only if condition.numberOfHolders is also undefined/null. // This might need adjustment based on exact Python None semantics vs TypeScript undefined/null. // For now, if schema has no numberOfHolders, it matches any. // If schema *has* numberOfHolders, it must match. let dependentsMatch = true; if (situationCondition.dependents !== undefined) { // Python code treated None for dependents as a wildcard / match dependentsMatch = situationCondition.dependents === condition.dependents; } const disabledMatch = situationCondition.disabled === condition.disabled; if (marriedMatch && holdersMatch && dependentsMatch && disabledMatch) { return situation; } } } } // In Python, this raised ValueError. In TS, we return undefined. // console.error(`Situation with condition ${JSON.stringify(condition)} not found.`); return undefined; } } export class RetentionPathsSchema { identifier; // Renamed from yearPath, locationPath, etc. to a single identifier constructor(dateStart, dateEnd, location, situationCode, // This is the code like "SOLD", "CAS1" year) { const yearStr = String(year); const customPadStart = (str, targetLength, padString) => { targetLength = targetLength >> 0; // floor if number or convert non-number to 0 padString = String(typeof padString !== 'undefined' ? padString : ' '); if (str.length > targetLength) { return String(str); } else { targetLength = targetLength - str.length; if (targetLength > padString.length) { padString += padString.repeat(targetLength / padString.length); // append to original to ensure we are longer than needed } return padString.slice(0, targetLength) + String(str); } }; const formatDate = (date) => { const y = date.getFullYear(); const m = customPadStart(String(date.getMonth() + 1), 2, "0"); const d = customPadStart(String(date.getDate()), 2, "0"); return `${y}-${m}-${d}`; }; // Construct the identifier string matching the keys in taxTablesData // e.g., "2024/continente/2024-01-01_2024-12-31/SOLD" // Note: situationCode already comes without .json this.identifier = `${yearStr}/${location}/${formatDate(dateStart)}_${formatDate(dateEnd)}/${situationCode}`; } get path() { // but it now returns the identifier. return this.identifier; } }