@swan-io/shared-business 13.2.1 → 13.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swan-io/shared-business",
3
- "version": "13.2.1",
3
+ "version": "13.2.3",
4
4
  "engines": {
5
5
  "node": "^22.12.0"
6
6
  },
@@ -25,7 +25,7 @@
25
25
  ],
26
26
  "license": "MIT",
27
27
  "peerDependencies": {
28
- "@swan-io/lake": "13.2.1"
28
+ "@swan-io/lake": "13.2.3"
29
29
  },
30
30
  "dependencies": {
31
31
  "@formatjs/intl": "^3.1.6",
@@ -50,6 +50,6 @@
50
50
  "@types/react-dom": "^19.1.7",
51
51
  "@types/react-native": "^0.72.8",
52
52
  "type-fest": "^4.41.0",
53
- "@swan-io/lake": "13.2.1"
53
+ "@swan-io/lake": "13.2.3"
54
54
  }
55
55
  }
@@ -110,7 +110,7 @@ const logoStyle = {
110
110
  export const AccountStatementV1 = ({ partnerLogoUrl, style, accountHolderType, accountHolderName, accountHolderAddress, iban, bic, openingDate, closingDate, openingBalance, transactions, feesDebit, feesCredit, totalsCredit, totalsDebit, closingBalance, }) => {
111
111
  return (_jsxs(Box, { style: [styles.container, style], direction: "column", justifyContent: "spaceBetween", children: [_jsxs(Box, { children: [_jsx(Box, { direction: "row", justifyContent: "spaceBetween", children: _jsxs(Box, { direction: "row", alignItems: "center", children: [isNotNullishOrEmpty(partnerLogoUrl) ? (_jsx("img", { src: partnerLogoUrl, style: logoStyle })) : (_jsx(SwanLogo, { style: styles.defaultLogo })), _jsx(Separator, { horizontal: true, space: 8 }), _jsx(Text, { style: styles.partnershipText, children: t("accountStatement.partnership") }), _jsx(Space, { width: 4 }), _jsx(SwanLogo, { color: colors.gray[900], style: styles.swanLogo })] }) }), _jsx(Space, { height: 24 }), _jsx(Text, { style: styles.pageTitle, children: t("accountStatement.titleDocument") }), _jsx(Space, { height: 8 }), _jsx(Text, { style: styles.text, children: accountHolderType === "Company"
112
112
  ? t("accountStatement.titleDocument.companyDescription")
113
- : t("accountStatement.titleDocument.individualDescription") }), _jsx(Space, { height: 24 }), _jsxs(Box, { direction: "row", justifyContent: "spaceBetween", children: [_jsxs(Box, { direction: "column", children: [_jsx(Text, { style: styles.sectionTitle, children: accountHolderName.toUpperCase() }), _jsx(Text, { style: styles.text, children: accountHolderAddress.street }), _jsx(Text, { style: styles.text, children: accountHolderAddress.city }), isNotNullish(accountHolderAddress.country) && (_jsx(Text, { style: styles.text, children: getCountryName(accountHolderAddress.country) }))] }), _jsxs(Box, { direction: "column", alignItems: "end", children: [_jsx(Text, { style: styles.sectionTitle, children: t("accountStatement.contactSupport") }), _jsx(Text, { style: styles.text, children: "support@swan.io" })] })] }), _jsx(Space, { height: 24 }), _jsx(Text, { style: styles.sectionTitle, children: t("accountStatement.iban") }), _jsx(Text, { style: styles.text, children: iban }), _jsx(Space, { height: 12 }), _jsx(Text, { style: styles.sectionTitle, children: t("accountStatement.bic") }), _jsx(Text, { style: styles.text, children: bic }), _jsx(Space, { height: 48 }), _jsxs(Box, { direction: "row", justifyContent: "spaceBetween", children: [_jsx(Box, { direction: "column", children: _jsx(Text, { style: styles.sectionTitle, children: t("accountStatement.date", { openingDate, closingDate }) }) }), _jsxs(Box, { direction: "column", children: [_jsx(Text, { style: styles.openingBalanceText, children: t("accountStatement.openingBalance") }), _jsx(Text, { style: styles.totalAmount, children: formatCurrencyIso(Number(openingBalance.value), openingBalance.currency) })] })] }), _jsx(Space, { height: 24 }), _jsxs(_Fragment, { children: [_jsxs(Box, { direction: "row", style: { backgroundColor: colors.gray[50] }, children: [_jsx(Text, { style: [styles.titleColumn, { width: "15%" }], children: t("accountStatement.column.date") }), _jsx(Text, { style: [styles.titleColumn, { width: "22%" }], children: t("accountStatement.column.type") }), _jsx(Text, { style: [styles.titleColumn, { width: "33%" }], children: t("accountStatement.column.description") }), _jsx(Text, { style: [styles.titleColumn, { width: "15%", textAlign: "right" }], children: t("accountStatement.column.credit") }), _jsx(Text, { style: [styles.titleColumn, { width: "15%", textAlign: "right" }], children: t("accountStatement.column.debit") })] }), _jsx(Box, { direction: "column", children: transactions.map(transaction => (_jsxs(Box, { direction: "row", children: [_jsx(Text, { style: [styles.textColumn, { width: "15%" }], children: transaction.date }), _jsx(Text, { style: [styles.textColumn, { width: "22%" }], children: translateTransaction(transaction.type) }), _jsx(Text, { style: [styles.textColumn, { width: "33%" }], children: transaction.label }), _jsx(Text, { style: [styles.textColumn, { width: "15%", textAlign: "right" }], children: transaction.credit ? transaction.credit.value : "" }), _jsx(Text, { style: [styles.textColumn, { width: "15%", textAlign: "right" }], children: transaction.debit ? transaction.debit.value : "" })] }, transaction.id))) })] }), _jsxs(Box, { direction: "column", children: [_jsxs(Box, { direction: "row", justifyContent: "end", children: [_jsx(Text, { style: styles.row, children: t("accountStatement.column.fees") }), _jsx(Text, { style: styles.row, children: feesCredit.value }), _jsx(Text, { style: styles.row, children: feesDebit.value })] }), _jsxs(Box, { direction: "row", justifyContent: "end", children: [_jsx(Text, { style: styles.row, children: t("accountStatement.column.totals") }), _jsx(Text, { style: styles.row, children: totalsCredit.value }), _jsx(Text, { style: styles.row, children: totalsDebit.value })] })] }), _jsx(Box, { direction: "row", justifyContent: "end", children: _jsxs(Box, { direction: "row", alignItems: "center", style: styles.closingBalanceRow, justifyContent: "spaceBetween", children: [_jsx(Title, { text: t("accountStatement.closingBalance") }), _jsx(Title, { text: formatCurrencyIso(Number(closingBalance.value), closingBalance.currency), style: styles.totalAmount, align: "right" })] }) })] }), _jsxs(Box, { children: [_jsx(Separator, { space: 24 }), _jsx(Text, { style: styles.footer, children: t("transactionStatement.footer") })] })] }));
113
+ : t("accountStatement.titleDocument.individualDescription") }), _jsx(Space, { height: 24 }), _jsxs(Box, { direction: "row", justifyContent: "spaceBetween", children: [_jsxs(Box, { direction: "column", children: [_jsx(Text, { style: styles.sectionTitle, children: accountHolderName.toUpperCase() }), _jsx(Text, { style: styles.text, children: accountHolderAddress.street }), _jsx(Text, { style: styles.text, children: accountHolderAddress.city }), isNotNullish(accountHolderAddress.country) && (_jsx(Text, { style: styles.text, children: getCountryName(accountHolderAddress.country) }))] }), _jsxs(Box, { direction: "column", alignItems: "end", children: [_jsx(Text, { style: styles.sectionTitle, children: t("accountStatement.contactSupport") }), _jsx(Text, { style: styles.text, children: "support.swan.io" })] })] }), _jsx(Space, { height: 24 }), _jsx(Text, { style: styles.sectionTitle, children: t("accountStatement.iban") }), _jsx(Text, { style: styles.text, children: iban }), _jsx(Space, { height: 12 }), _jsx(Text, { style: styles.sectionTitle, children: t("accountStatement.bic") }), _jsx(Text, { style: styles.text, children: bic }), _jsx(Space, { height: 48 }), _jsxs(Box, { direction: "row", justifyContent: "spaceBetween", children: [_jsx(Box, { direction: "column", children: _jsx(Text, { style: styles.sectionTitle, children: t("accountStatement.date", { openingDate, closingDate }) }) }), _jsxs(Box, { direction: "column", children: [_jsx(Text, { style: styles.openingBalanceText, children: t("accountStatement.openingBalance") }), _jsx(Text, { style: styles.totalAmount, children: formatCurrencyIso(Number(openingBalance.value), openingBalance.currency) })] })] }), _jsx(Space, { height: 24 }), _jsxs(_Fragment, { children: [_jsxs(Box, { direction: "row", style: { backgroundColor: colors.gray[50] }, children: [_jsx(Text, { style: [styles.titleColumn, { width: "15%" }], children: t("accountStatement.column.date") }), _jsx(Text, { style: [styles.titleColumn, { width: "22%" }], children: t("accountStatement.column.type") }), _jsx(Text, { style: [styles.titleColumn, { width: "33%" }], children: t("accountStatement.column.description") }), _jsx(Text, { style: [styles.titleColumn, { width: "15%", textAlign: "right" }], children: t("accountStatement.column.credit") }), _jsx(Text, { style: [styles.titleColumn, { width: "15%", textAlign: "right" }], children: t("accountStatement.column.debit") })] }), _jsx(Box, { direction: "column", children: transactions.map(transaction => (_jsxs(Box, { direction: "row", children: [_jsx(Text, { style: [styles.textColumn, { width: "15%" }], children: transaction.date }), _jsx(Text, { style: [styles.textColumn, { width: "22%" }], children: translateTransaction(transaction.type) }), _jsx(Text, { style: [styles.textColumn, { width: "33%" }], children: transaction.label }), _jsx(Text, { style: [styles.textColumn, { width: "15%", textAlign: "right" }], children: transaction.credit ? transaction.credit.value : "" }), _jsx(Text, { style: [styles.textColumn, { width: "15%", textAlign: "right" }], children: transaction.debit ? transaction.debit.value : "" })] }, transaction.id))) })] }), _jsxs(Box, { direction: "column", children: [_jsxs(Box, { direction: "row", justifyContent: "end", children: [_jsx(Text, { style: styles.row, children: t("accountStatement.column.fees") }), _jsx(Text, { style: styles.row, children: feesCredit.value }), _jsx(Text, { style: styles.row, children: feesDebit.value })] }), _jsxs(Box, { direction: "row", justifyContent: "end", children: [_jsx(Text, { style: styles.row, children: t("accountStatement.column.totals") }), _jsx(Text, { style: styles.row, children: totalsCredit.value }), _jsx(Text, { style: styles.row, children: totalsDebit.value })] })] }), _jsx(Box, { direction: "row", justifyContent: "end", children: _jsxs(Box, { direction: "row", alignItems: "center", style: styles.closingBalanceRow, justifyContent: "spaceBetween", children: [_jsx(Title, { text: t("accountStatement.closingBalance") }), _jsx(Title, { text: formatCurrencyIso(Number(closingBalance.value), closingBalance.currency), style: styles.totalAmount, align: "right" })] }) })] }), _jsxs(Box, { children: [_jsx(Separator, { space: 24 }), _jsx(Text, { style: styles.footer, children: t("transactionStatement.footer") })] })] }));
114
114
  };
115
115
  export const AccountStatement = (props) => match(props)
116
116
  .with({ version: "v1" }, props => _jsx(AccountStatementV1, { ...props }))
@@ -5,7 +5,7 @@ import { LakeTextInput } from "@swan-io/lake/src/components/LakeTextInput";
5
5
  import { LakeTooltip } from "@swan-io/lake/src/components/LakeTooltip";
6
6
  import { colors } from "@swan-io/lake/src/constants/design";
7
7
  import { t } from "../utils/i18n";
8
- import { getCompanyTaxNumberHelp, getCompanyTaxNumberPlaceholder, getIndividualTaxNumberHelp, getIndividualTaxNumberPlaceholder, getTaxNumberTooltip, } from "../utils/templateTranslations";
8
+ import { getCompanyTaxNumberHelp, getCompanyTaxNumberPlaceholder, getIndividualTaxNumberHelp, getIndividualTaxNumberPlaceholder, getTaxNumberTooltip, } from "../utils/validation";
9
9
  export const TaxIdentificationNumberInput = ({ ref, value, error, valid, disabled, onChange, onBlur, country, isCompany, required, label = t("taxIdentificationNumber.label"), placeholder = isCompany
10
10
  ? getCompanyTaxNumberPlaceholder(country)
11
11
  : getIndividualTaxNumberPlaceholder(country), }) => {
@@ -1506,6 +1506,14 @@ export declare const individualCountries: ("BEL" | "CZE" | "DNK" | "DEU" | "EST"
1506
1506
  export type IndividualCountryCCA3 = (typeof individualCountries)[number];
1507
1507
  export declare const companyCountries: ("BEL" | "CZE" | "DNK" | "DEU" | "EST" | "IRL" | "ESP" | "FRA" | "HRV" | "ISL" | "ITA" | "LVA" | "LIE" | "LTU" | "LUX" | "HUN" | "MLT" | "NLD" | "NOR" | "AUT" | "POL" | "PRT" | "ROU" | "SVN" | "SVK" | "FIN" | "SWE" | "GRC" | "CYP" | "BGR")[];
1508
1508
  export type CompanyCountryCCA3 = (typeof companyCountries)[number];
1509
+ type TaxNumberValidationRule = {
1510
+ pattern: RegExp;
1511
+ message: string;
1512
+ };
1513
+ export type TaxNumberValidation = {
1514
+ individual: Partial<Record<IndividualCountryCCA3, TaxNumberValidationRule>>;
1515
+ company: Partial<Record<CompanyCountryCCA3, TaxNumberValidationRule>>;
1516
+ };
1509
1517
  export declare const countriesWithMultipleCCA3: Partial<Record<CountryCCA3, CountryCCA3[]>>;
1510
1518
  export declare const isCountryCCA3: (value: unknown) => value is CountryCCA3;
1511
1519
  export declare const isCountryCCA2: (value: unknown) => value is CountryCCA2;
@@ -54,7 +54,7 @@
54
54
  "common.form.help.nbDigits": "{nbDigits} Ziffern",
55
55
  "common.form.invalidTaxIdentificationNumber": "Dieses Feld ist ungültig",
56
56
  "common.form.taxIdentificationNumber.placeholder": "Steueridentifikationsnummer",
57
- "common.form.taxIdentificationNumber.tooltip.deu": "Identifikationsnummer (auch Steuerliche Identifikationsnummer, Persönliche Identificationsnummer, Identifikationsnummer, Steuer-IdNr., IdNr oder Steuer-ID gemäß § 139b AO)",
57
+ "common.form.taxIdentificationNumber.tooltip.deu": "Steuernummer des Unternehmens",
58
58
  "common.form.taxIdentificationNumber.tooltip.ita": "Steuer-ID (Codice fiscale)",
59
59
  "common.next": "Weiter",
60
60
  "common.noResult": "Leeres Ergebnis",
@@ -67,12 +67,12 @@
67
67
  "common.skipToContent": "Zum Inhalt springen",
68
68
  "copyButton.copiedTooltip": "In die Zwischenablage kopiert",
69
69
  "copyButton.copyTooltip": "Zum Kopieren anklicken",
70
- "creditStatement.additionalDetails": "Der Kontoauszug vom <bold>{openingDate}</bold> bis <bold>{closingDate}</bold> enthält alle Gebühren und erhaltenen Zahlungen bis zum {closingDate}. Ihre nächste automatische Lastschrift erfolgt ab {repaymentDate}.\n\nIm Falle einer abgelehnten Bankabbuchung aufgrund unzureichender Mittel können wir diese Abbuchung mindestens <bold>3 bis 4 Tage</bold> nach der Benachrichtigung durch Ihre Bank erneut einreichen.",
70
+ "creditStatement.additionalDetails": "Der Kontoauszug vom <bold>{openingDate}</bold> bis <bold>{closingDate}</bold> enthält alle Gebühren und erhaltenen Zahlungen bis zum {closingDate}. Ihre nächste automatische Lastschrift erfolgt ab {repaymentDate}.\n\nIm Falle einer abgelehnten Bankabbuchung aufgrund unzureichender Guthaben können wir diese Abbuchung mindestens <bold>3 bis 4 Tage</bold> nach der Benachrichtigung durch Ihre Bank erneut einreichen.",
71
71
  "creditStatement.column.credit": "Gutschrift",
72
72
  "creditStatement.column.debit": "Lastschrift",
73
- "creditStatement.issueDate": "Ausgabedatum {issueDate}",
73
+ "creditStatement.issueDate": "Ausstellungsdatum {issueDate}",
74
74
  "creditStatement.siret": "SIRET",
75
- "creditStatement.titleDocument": "Rückzahlungsaufstellung",
75
+ "creditStatement.titleDocument": "Rückzahlungserklärung",
76
76
  "datePicker.day": "Tag",
77
77
  "datePicker.day.friday": "Freitag",
78
78
  "datePicker.day.monday": "Montag",
@@ -114,10 +114,10 @@
114
114
  "fileTile.status.Refused": "Abgelehnt",
115
115
  "fileTile.status.Validated": "Validiert",
116
116
  "fileTile.uploading": "Hochladen…",
117
- "monthlyPaymentVolume.between10000And50000": "Zwischen 10.000 und 50.000 € pro Monat",
118
- "monthlyPaymentVolume.between50000And100000": "Zwischen 50.000 und 100.000 € pro Monat",
119
- "monthlyPaymentVolume.lessThan10000": "Weniger als 10.000 pro Monat",
120
- "monthlyPaymentVolume.moreThan100000": "Mehr als 100.000 pro Monat",
117
+ "monthlyPaymentVolume.between10000And50000": "Zwischen 10.000 und 50.000 € pro Monat",
118
+ "monthlyPaymentVolume.between50000And100000": "Zwischen 50.000 und 100.000 € pro Monat",
119
+ "monthlyPaymentVolume.lessThan10000": "Weniger als 10.000 monatlich",
120
+ "monthlyPaymentVolume.moreThan100000": "Mehr als 100.000 monatlich",
121
121
  "registrationPage.defaultNumberLabel": "Registrierungsnummer",
122
122
  "registrationPage.withOrganismLabel": "Ist Ihre Firma bereits im {organismName} eingetragen?",
123
123
  "registrationPage.withoutOrganismNameLabel": "Sind Sie registriert?",
@@ -384,7 +384,7 @@
384
384
  "transactionStatement.debtor.bankIdentifier": "Bankleitzahl des Schuldners",
385
385
  "transactionStatement.debtor.bankName": "Name der Bank des Schuldners",
386
386
  "transactionStatement.debtor.name": "Name des Schuldners",
387
- "transactionStatement.footer": "SWAN ist eine vereinfachte Aktiengesellschaft (SAS), eingetragen im Handelsregister von Bobigny unter der Nummer 853 827 103, mit einem Kapital von 16.999,66 Euro, USt-IdNr. FR90853827103 und Firmensitz in 95 Avenue du Président Wilson, 93100 Montreuil, FRANKREICH.\nAls E-Geld-Institut, das Zahlungsdienstleistungen gemäß französischem Recht anbietet und von der ACPR genehmigt wurde, ist SWAN unter der Nummer 17328 bei dieser registriert.",
387
+ "transactionStatement.footer": "SWAN ist eine vereinfachte Aktiengesellschaft (SAS), eingetragen im Handelsregister von Bobigny unter der Nummer 853 827 103, mit einem Kapital von 16.999,66 Euro, USt-IdNr. FR90853827103 und Firmensitz in 91 rue du Faubourg Saint-Honoré, 75008 Paris, FRANKREICH.\nAls E-Geld-Institut, das Zahlungsdienstleistungen gemäß französischem Recht anbietet und von der ACPR genehmigt wurde, ist SWAN unter der Nummer 17328 bei dieser registriert.",
388
388
  "transactionStatement.generationDate": "Generiert am: {date}",
389
389
  "transactionStatement.generationInfos": "Dieses Dokument bestätigt Ihren Transaktionsantrag. Es stellt keinen Nachweis der Transaktionsausführung dar. Ihre Transaktion wird nach Bestehen eines obligatorischen Verifizierungsprozesses ausgeführt.",
390
390
  "transactionStatement.information.amount": "Betrag",
@@ -21,12 +21,6 @@
21
21
  "accountStatement.titleDocument": "Account statement",
22
22
  "accountStatement.titleDocument.companyDescription": "Business account - in euros",
23
23
  "accountStatement.titleDocument.individualDescription": "Personal account - in euros",
24
- "creditStatement.titleDocument": "Repayment statement",
25
- "creditStatement.column.credit": "Credit",
26
- "creditStatement.column.debit": "Debit",
27
- "creditStatement.issueDate": "Issue date {issueDate}",
28
- "creditStatement.siret": "SIRET",
29
- "creditStatement.additionalDetails": "The statement from <bold>{openingDate}</bold> to <bold>{closingDate}</bold> includes all fees and payments received up to {closingDate}. Your next automatic debit will occur starting from {repaymentDate}.\n\nIn the event of a rejected bank withdrawal due to insufficient funds, we may represent this withdrawal at least <bold>3 to 4 days</bold> after the rejection notified by your bank.",
30
24
  "addressFormPart.addressLabel": "Type your address",
31
25
  "addressFormPart.cityLabel": "City",
32
26
  "addressFormPart.placeholder": "Start typing…",
@@ -60,7 +54,7 @@
60
54
  "common.form.help.nbDigits": "{nbDigits} digits",
61
55
  "common.form.invalidTaxIdentificationNumber": "This field is invalid",
62
56
  "common.form.taxIdentificationNumber.placeholder": "Tax ID",
63
- "common.form.taxIdentificationNumber.tooltip.deu": "Identifikationsnummer (also Steuerliche Identifikationsnummer, Persönliche Identificationsnummer, Identifikationsnummer, Steuer-IdNr., IdNr or Steuer-ID, according to § 139b AO)",
57
+ "common.form.taxIdentificationNumber.tooltip.deu": "Steuernummer des Unternehmens",
64
58
  "common.form.taxIdentificationNumber.tooltip.ita": "Tax ID (Codice fiscale)",
65
59
  "common.next": "Next",
66
60
  "common.noResult": "Empty result",
@@ -73,6 +67,12 @@
73
67
  "common.skipToContent": "Skip to content",
74
68
  "copyButton.copiedTooltip": "Copied to clipboard",
75
69
  "copyButton.copyTooltip": "Click to copy",
70
+ "creditStatement.additionalDetails": "The statement from <bold>{openingDate}</bold> to <bold>{closingDate}</bold> includes all fees and payments received up to {closingDate}. Your next automatic debit will occur starting from {repaymentDate}.\n\nIn the event of a rejected bank withdrawal due to insufficient funds, we may represent this withdrawal at least <bold>3 to 4 days</bold> after the rejection notified by your bank.",
71
+ "creditStatement.column.credit": "Credit",
72
+ "creditStatement.column.debit": "Debit",
73
+ "creditStatement.issueDate": "Issue date {issueDate}",
74
+ "creditStatement.siret": "SIRET",
75
+ "creditStatement.titleDocument": "Repayment statement",
76
76
  "datePicker.day": "Day",
77
77
  "datePicker.day.friday": "Friday",
78
78
  "datePicker.day.monday": "Monday",
@@ -295,10 +295,10 @@
295
295
  "supportingDocuments.downloadTemplate": "Download template",
296
296
  "supportingDocuments.errorUpload": "Failed to upload file",
297
297
  "supportingDocuments.help.downloadTemplate": "Download a template",
298
+ "supportingDocuments.help.howToSendAGoodDocument": "How to send a good document?",
298
299
  "supportingDocuments.help.whatIsThis": "What is this?",
299
300
  "supportingDocuments.informations": "Document details",
300
301
  "supportingDocuments.noDocuments": "No documents.",
301
- "supportingDocuments.help.howToSendAGoodDocument": "How to send a good document?",
302
302
  "supportingDocuments.powerOfAttorneyModal.description": "A signed and dated document authorizing an individual to represent or act on behalf of a company's legal representative.",
303
303
  "supportingDocuments.powerOfAttorneyModal.title": "Power of attorney signed by the legal representative",
304
304
  "supportingDocuments.purpose.AdministratorDecisionOfAppointment": "Administrator appointment letter",
@@ -384,7 +384,7 @@
384
384
  "transactionStatement.debtor.bankIdentifier": "Debtor's bank identifier",
385
385
  "transactionStatement.debtor.bankName": "Debtor’s bank name",
386
386
  "transactionStatement.debtor.name": "Debtor’s name",
387
- "transactionStatement.footer": "SWAN is a simplified joint-stock company (SAS) registered with the Bobigny Trade and Companies Register under number 853 827 103, with a capital of 16,999.66 Euros, VAT number FR90853827103 and whose registered office is located at 95 Avenue du Président Wilson, 93100 Montreuil, FRANCE.\nIn its capacity as an Electronic Money institution offering payment services under French law approved by the ACPR, SWAN is registered with the latter under number 17328.",
387
+ "transactionStatement.footer": "SWAN is a simplified joint-stock company (SAS) registered with the Bobigny Trade and Companies Register under number 853 827 103, with a capital of 16,999.66 Euros, VAT number FR90853827103 and whose registered office is located at 91 rue du Faubourg Saint-Honoré, 75008 Paris, FRANCE.\nIn its capacity as an Electronic Money institution offering payment services under French law approved by the ACPR, SWAN is registered with the latter under number 17328.",
388
388
  "transactionStatement.generationDate": "Generated on: {date}",
389
389
  "transactionStatement.generationInfos": "This document is confirmation of your transaction request. It doesn't constitute proof of transaction execution. Your transaction will be executed after passing a mandatory verification process.",
390
390
  "transactionStatement.information.amount": "Amount",
@@ -54,7 +54,7 @@
54
54
  "common.form.help.nbDigits": "{nbDigits} dígitos",
55
55
  "common.form.invalidTaxIdentificationNumber": "Este campo es inválido",
56
56
  "common.form.taxIdentificationNumber.placeholder": "Número de identificación fiscal",
57
- "common.form.taxIdentificationNumber.tooltip.deu": "Identifikationsnummer (también Steuerliche Identifikationsnummer, Persönliche Identificationsnummer, Identifikationsnummer, Steuer-IdNr., IdNr o Steuer-ID, según § 139b AO)",
57
+ "common.form.taxIdentificationNumber.tooltip.deu": "Steuernummer des Unternehmens",
58
58
  "common.form.taxIdentificationNumber.tooltip.ita": "Número de identificación fiscal (Codice fiscale)",
59
59
  "common.next": "Siguiente",
60
60
  "common.noResult": "No hay resultados",
@@ -67,12 +67,12 @@
67
67
  "common.skipToContent": "Saltar al contenido",
68
68
  "copyButton.copiedTooltip": "Copiado al portapapeles",
69
69
  "copyButton.copyTooltip": "Haz clic para copiar",
70
- "creditStatement.additionalDetails": "El estado de cuenta desde <bold>{openingDate}</bold> hasta <bold>{closingDate}</bold> incluye todas las comisiones y pagos recibidos hasta el {closingDate}. Tu próximo débito automático se realizará a partir del {repaymentDate}.\n\nEn caso de un rechazo de retiro bancario debido a fondos insuficientes, podemos representar este retiro al menos <bold>3 a 4 días</bold> después del rechazo notificado por tu banco.",
70
+ "creditStatement.additionalDetails": "El extracto del <bold>{openingDate}</bold> al <bold>{closingDate}</bold> incluye todas las tasas y pagos recibidos hasta el {closingDate}. Tu próximo pago domiciliado se realizará a partir del {repaymentDate}.\n\nSi el pago se rechaza por fondos insuficientes, podemos intentar procesarlo de nuevo <bold>3 a 4 días</bold> después de que tu banco te haya notificado el rechazo.",
71
71
  "creditStatement.column.credit": "Crédito",
72
72
  "creditStatement.column.debit": "Débito",
73
73
  "creditStatement.issueDate": "Fecha de emisión {issueDate}",
74
74
  "creditStatement.siret": "SIRET",
75
- "creditStatement.titleDocument": "Estado de reembolso",
75
+ "creditStatement.titleDocument": "Estado de amortización",
76
76
  "datePicker.day": "Día",
77
77
  "datePicker.day.friday": "Viernes",
78
78
  "datePicker.day.monday": "Lunes",
@@ -114,10 +114,10 @@
114
114
  "fileTile.status.Refused": "Rechazado",
115
115
  "fileTile.status.Validated": "Validado",
116
116
  "fileTile.uploading": "Subiendo…",
117
- "monthlyPaymentVolume.between10000And50000": "Entre 10 000 y 50 000 euros por mes",
118
- "monthlyPaymentVolume.between50000And100000": "Entre 50 000 y 100 000 euros por mes",
119
- "monthlyPaymentVolume.lessThan10000": "Menos de 10 000 euros por mes",
120
- "monthlyPaymentVolume.moreThan100000": "Más de 100 000 euros por mes",
117
+ "monthlyPaymentVolume.between10000And50000": "Entre 10 000 y 50 000 por mes",
118
+ "monthlyPaymentVolume.between50000And100000": "Entre 50 000 y 100 000 por mes",
119
+ "monthlyPaymentVolume.lessThan10000": "Menos de 10 000 por mes",
120
+ "monthlyPaymentVolume.moreThan100000": "Más de 100 000 por mes",
121
121
  "registrationPage.defaultNumberLabel": "Número de registro",
122
122
  "registrationPage.withOrganismLabel": "¿Estás registrado en {organismName}?",
123
123
  "registrationPage.withoutOrganismNameLabel": "¿Estás registrado?",
@@ -384,7 +384,7 @@
384
384
  "transactionStatement.debtor.bankIdentifier": "Identificador bancario del deudor",
385
385
  "transactionStatement.debtor.bankName": "Nombre del banco del deudor",
386
386
  "transactionStatement.debtor.name": "Nombre del deudor",
387
- "transactionStatement.footer": "SWAN es una sociedad anónima simplificada (SAS) registrada en el Registro Mercantil de Bobigny con el número 853 827 103, con un capital de 16.999,66 euros, número de IVA FR90853827103 y con domicilio social en 95 Avenue du Président Wilson, 93100 Montreuil, FRANCIA.\nEn su calidad de institución de dinero electrónico que ofrece servicios de pago conforme a la ley francesa aprobada por la ACPR, SWAN está registrada bajo el número 17328.",
387
+ "transactionStatement.footer": "SWAN es una sociedad anónima simplificada (SAS) registrada en el Registro Mercantil de Bobigny con el número 853 827 103, con un capital de 16.999,66 euros, número de IVA FR90853827103 y con domicilio social en 91 rue du Faubourg Saint-Honoré, 75008 Paris, FRANCIA.\nEn su calidad de institución de dinero electrónico que ofrece servicios de pago conforme a la ley francesa aprobada por la ACPR, SWAN está registrada bajo el número 17328.",
388
388
  "transactionStatement.generationDate": "Generado el: {date}",
389
389
  "transactionStatement.generationInfos": "Este documento es la confirmación de tu solicitud de transacción. No constituye una prueba de la ejecución de la transacción. La transacción se ejecutará tras pasar un proceso de verificación obligatorio.",
390
390
  "transactionStatement.information.amount": "Importe",
@@ -412,5 +412,5 @@
412
412
  "transactionStatement.type.SepaInstantCreditTransferOut": "Transferencia SEPA instantánea enviada",
413
413
  "validation.birthdateCannotBeFuture": "La fecha de nacimiento no puede estar en el futuro",
414
414
  "validation.invalidBirthDate": "Por favor, introduce una fecha de nacimiento válida.",
415
- "validation.invalidDate": "Por favor, introduce una fecha válida."
415
+ "validation.invalidDate": "Introduce una fecha válida."
416
416
  }
@@ -54,7 +54,7 @@
54
54
  "common.form.help.nbDigits": "{nbDigits} numeroa",
55
55
  "common.form.invalidTaxIdentificationNumber": "Tämä kenttä ei ole kelvollinen",
56
56
  "common.form.taxIdentificationNumber.placeholder": "verotunnus",
57
- "common.form.taxIdentificationNumber.tooltip.deu": "Identifikationsnummer (also Steuerliche Identifikationsnummer, Persönliche Identificationsnummer, Identifikationsnummer, Steuer-IdNr., IdNr or Steuer-ID, according to § 139b AO)",
57
+ "common.form.taxIdentificationNumber.tooltip.deu": "Steuernummer des Unternehmens",
58
58
  "common.form.taxIdentificationNumber.tooltip.ita": "Verotunnus (Codice fiscale)",
59
59
  "common.next": "Seuraava",
60
60
  "common.noResult": "Ei tuloksia",
@@ -67,12 +67,12 @@
67
67
  "common.skipToContent": "Ohita ja siirry sisältöön",
68
68
  "copyButton.copiedTooltip": "Kopioitu leikepöydälle",
69
69
  "copyButton.copyTooltip": "Kopioi napsauttamalla",
70
- "creditStatement.additionalDetails": "Tiliote ajalta <bold>{openingDate}</bold> - <bold>{closingDate}</bold> sisältää kaikki maksut ja saapuneet maksut {closingDate} asti. Seuraava automaattinen veloitus tapahtuu {repaymentDate} alkaen.\n\nJos pankkisiirto hylätään riittämättömien varojen vuoksi, voimme edustaa tätä siirtoa vähintään <bold>3-4 päivää</bold> hylkäyksen jälkeen, jonka pankkisi on ilmoittanut.",
71
- "creditStatement.column.credit": "Hyvitys",
72
- "creditStatement.column.debit": "Velka",
73
- "creditStatement.issueDate": "Päiväys {issueDate}",
70
+ "creditStatement.additionalDetails": "<bold>{openingDate}</bold>{openingDate}<bold>{closingDate}</bold> -tilinpäätös sisältää kaikki kulut ja maksut, jotka on vastaanotettu {closingDate} asti. Seuraava automaattinen veloitus tapahtuu {repaymentDate} alkaen.\n\nJos pankkisiirto hylätään varojen puutteen vuoksi, voimme esittää tämän siirron uudelleen vähintään <bold>34 päivää</bold> sen jälkeen, kun pankkisi on ilmoittanut hylkäämisestä.",
71
+ "creditStatement.column.credit": "Luotto",
72
+ "creditStatement.column.debit": "Veloittaa",
73
+ "creditStatement.issueDate": "Julkaisupäivä {issueDate}",
74
74
  "creditStatement.siret": "SIRET",
75
- "creditStatement.titleDocument": "Takaisinmaksuilmoitus",
75
+ "creditStatement.titleDocument": "Takaisinmaksuerittely",
76
76
  "datePicker.day": "Päivä",
77
77
  "datePicker.day.friday": "Perjantai",
78
78
  "datePicker.day.monday": "Maanantai",
@@ -114,10 +114,10 @@
114
114
  "fileTile.status.Refused": "Hylätty",
115
115
  "fileTile.status.Validated": "Vahvistettu",
116
116
  "fileTile.uploading": "Ladataan...",
117
- "monthlyPaymentVolume.between10000And50000": "10 000 euron ja 50 000 euron välillä per kuukausi",
118
- "monthlyPaymentVolume.between50000And100000": "50 000 euron ja 100 000 euron välillä per kuukausi",
119
- "monthlyPaymentVolume.lessThan10000": "Vähemmän kuin 10 000 euroa per kuukausi",
120
- "monthlyPaymentVolume.moreThan100000": "Enemmän kuin 100 000 euroa per kuukausi",
117
+ "monthlyPaymentVolume.between10000And50000": "10 000 euron ja 50 000 euron välillä",
118
+ "monthlyPaymentVolume.between50000And100000": "50 000 euron ja 100 000 euron välillä",
119
+ "monthlyPaymentVolume.lessThan10000": "Vähemmän kuin 10 000 euroa",
120
+ "monthlyPaymentVolume.moreThan100000": "Enemmän kuin 100 000 euroa",
121
121
  "registrationPage.defaultNumberLabel": "Rekisteröintinumero",
122
122
  "registrationPage.withOrganismLabel": "Oletko yrityksesi rekisteröity kohteeseen {organismName}?",
123
123
  "registrationPage.withoutOrganismNameLabel": "Onko yrityksesi rekisteröity?",
@@ -384,7 +384,7 @@
384
384
  "transactionStatement.debtor.bankIdentifier": "Velallisen pankkitunnus",
385
385
  "transactionStatement.debtor.bankName": "Velallisen pankin nimi",
386
386
  "transactionStatement.debtor.name": "Velallisen nimi",
387
- "transactionStatement.footer": "SWAN on ranskalainen osakeyhtiö (SAS), joka on rekisteröity Bobigny:n kaupparekisteriin numerolla 853 827 103, pääomanaan 16 999,66 euroa, ALV-numero FR90853827103 ja kotipaikkanaan 95 Avenue du Président Wilson, 93100 Montreuil, RANSKA.\nSWAN toimii elektronisen rahan liikkeellelaskijana, tarjoten maksupalveluita Ranskan lain mukaisesti, ja on hyväksytty ACPR:n toimesta rekisteröitynä numerolla 17328.",
387
+ "transactionStatement.footer": "SWAN on ranskalainen osakeyhtiö (SAS), joka on rekisteröity Bobigny:n kaupparekisteriin numerolla 853 827 103, pääomanaan 16 999,66 euroa, ALV-numero FR90853827103 ja kotipaikkanaan 91 rue du Faubourg Saint-Honoré, 75008 Paris, RANSKA.\nSWAN toimii elektronisen rahan liikkeellelaskijana, tarjoten maksupalveluita Ranskan lain mukaisesti, ja on hyväksytty ACPR:n toimesta rekisteröitynä numerolla 17328.",
388
388
  "transactionStatement.generationDate": "Luotu: {date}",
389
389
  "transactionStatement.generationInfos": "Tämä asiakirja on vahvistus maksupyynnöstänne. Se ei ole kuitti tehdystä maksusuorituksesta. Maksusuoritus toteutetaan pakollisen vahvistusprosessin jälkeen.",
390
390
  "transactionStatement.information.amount": "Summa",
@@ -412,5 +412,5 @@
412
412
  "transactionStatement.type.SepaInstantCreditTransferOut": "SEPA Instant -tilisiirto lähetetty",
413
413
  "validation.birthdateCannotBeFuture": "Syntymäaika ei voi olla tulevaisuudessa",
414
414
  "validation.invalidBirthDate": "Syötä syntymäaika oikeassa muodossa.",
415
- "validation.invalidDate": "Syötä kelvollinen päivämäärä."
415
+ "validation.invalidDate": "Anna kelvollinen päivämäärä."
416
416
  }
@@ -54,7 +54,7 @@
54
54
  "common.form.help.nbDigits": "{nbDigits} chiffres",
55
55
  "common.form.invalidTaxIdentificationNumber": "Ce champ n’est pas valide",
56
56
  "common.form.taxIdentificationNumber.placeholder": "Numéro d'identification fiscale",
57
- "common.form.taxIdentificationNumber.tooltip.deu": "Identifikationsnummer (également Steuerliche Identifikationsnummer, Persönliche Identificationsnummer, Identifikationsnummer, Steuer-IdNr., IdNr ou Steuer-ID, selon § 139b AO)",
57
+ "common.form.taxIdentificationNumber.tooltip.deu": "Steuernummer des Unternehmens",
58
58
  "common.form.taxIdentificationNumber.tooltip.ita": "Numéro d'identification fiscale (Codice fiscale)",
59
59
  "common.next": "Suivant",
60
60
  "common.noResult": "Résultat vide",
@@ -384,7 +384,7 @@
384
384
  "transactionStatement.debtor.bankIdentifier": "Identifiant bancaire du débiteur",
385
385
  "transactionStatement.debtor.bankName": "Nom de la banque du débiteur",
386
386
  "transactionStatement.debtor.name": "Nom du débiteur",
387
- "transactionStatement.footer": "SWAN est une société par actions simplifiée (SAS) immatriculée au Registre du Commerce et des Sociétés de Bobigny sous le numéro 853 827 103, avec un capital de 16 999,66 euros, numéro de TVA FR90853827103 et dont le siège social est situé au 95 Avenue du Président Wilson, 93100 Montreuil, FRANCE.\nEn tant qu'établissement de monnaie électronique offrant des services de paiement en vertu du droit français approuvé par l'ACPR, SWAN est inscrite auprès de ce dernier sous le numéro 17328.",
387
+ "transactionStatement.footer": "SWAN est une société par actions simplifiée (SAS) immatriculée au Registre du Commerce et des Sociétés de Bobigny sous le numéro 853 827 103, avec un capital de 16 999,66 euros, numéro de TVA FR90853827103 et dont le siège social est situé au 91 rue du Faubourg Saint-Honoré, 75008 Paris, FRANCE.\nEn tant qu'établissement de monnaie électronique offrant des services de paiement en vertu du droit français approuvé par l'ACPR, SWAN est inscrite auprès de ce dernier sous le numéro 17328.",
388
388
  "transactionStatement.generationDate": "Généré le : {date}",
389
389
  "transactionStatement.generationInfos": "Ce document atteste de votre demande de transaction. En aucun cas il ne constitue une preuve de son exécution. Votre transaction sera exécutée après un processus de vérification obligatoire.",
390
390
  "transactionStatement.information.amount": "Montant",
@@ -11,7 +11,7 @@
11
11
  "accountStatement.column.totals": "Totali",
12
12
  "accountStatement.column.type": "Tipo",
13
13
  "accountStatement.contactSupport": "Contatta Swan",
14
- "accountStatement.creditTransfer": "Credit transfer",
14
+ "accountStatement.creditTransfer": "Bonifico",
15
15
  "accountStatement.date": "Dal {openingDate} al {closingDate}",
16
16
  "accountStatement.directDebit": "Addebito diretto",
17
17
  "accountStatement.fees": "Commissioni",
@@ -54,7 +54,7 @@
54
54
  "common.form.help.nbDigits": "{nbDigits} cifre",
55
55
  "common.form.invalidTaxIdentificationNumber": "Questo campo non è valido",
56
56
  "common.form.taxIdentificationNumber.placeholder": "Codice fiscale",
57
- "common.form.taxIdentificationNumber.tooltip.deu": "Identifikationsnummer (anche Steuerliche Identifikationsnummer, Persönliche Identificationsnummer, Steuer-IDNr., Steuer-ID o Steuer-ID, secondo § 139b AO)",
57
+ "common.form.taxIdentificationNumber.tooltip.deu": "Steuernummer des Unternehmens",
58
58
  "common.form.taxIdentificationNumber.tooltip.ita": "Codice fiscale (Tax ID)",
59
59
  "common.next": "Avanti",
60
60
  "common.noResult": "Risultato vuoto",
@@ -67,7 +67,7 @@
67
67
  "common.skipToContent": "Salta al contenuto",
68
68
  "copyButton.copiedTooltip": "Copiato negli appunti",
69
69
  "copyButton.copyTooltip": "Clicca per copiare",
70
- "creditStatement.additionalDetails": "Il rendiconto dal <bold>{openingDate}</bold> al <bold>{closingDate}</bold> include tutte le commissioni e i pagamenti ricevuti fino al {closingDate}. Il prossimo addebito automatico avverrà a partire dal {repaymentDate}.\n\nIn caso di mancato prelievo bancario a causa di fondi insufficienti, potremmo rappresentare questo prelievo almeno <bold>3 o 4 giorni</bold> dopo il rifiuto comunicato dalla tua banca.",
70
+ "creditStatement.additionalDetails": "Il rendiconto dal <bold>{openingDate}</bold> al <bold>{closingDate}</bold> include tutte le commissioni e i pagamenti ricevuti fino al {closingDate}. Il prossimo addebito automatico verrà effettuato a partire dal {repaymentDate}.\n\nIn caso di mancato addebito bancario per insufficienza di fondi, potremmo ripresentare l’addebito entro <bold>3 o 4 giorni</bold> dal rifiuto comunicato dalla tua banca.",
71
71
  "creditStatement.column.credit": "Credito",
72
72
  "creditStatement.column.debit": "Addebito",
73
73
  "creditStatement.issueDate": "Data di emissione {issueDate}",
@@ -295,7 +295,7 @@
295
295
  "supportingDocuments.downloadTemplate": "Scarica modello",
296
296
  "supportingDocuments.errorUpload": "Impossibile caricare file",
297
297
  "supportingDocuments.help.downloadTemplate": "Scarica un modello",
298
- "supportingDocuments.help.howToSendAGoodDocument": "Come inviare un buon documento?",
298
+ "supportingDocuments.help.howToSendAGoodDocument": "Come inviare un documento valido?",
299
299
  "supportingDocuments.help.whatIsThis": "Che cos'è?",
300
300
  "supportingDocuments.informations": "Dettagli documento",
301
301
  "supportingDocuments.noDocuments": "Nessun documento.",
@@ -314,17 +314,17 @@
314
314
  "supportingDocuments.purpose.CompanyRegistration.description": "Un documento che attesti la registrazione legale di un'azienda o entità commerciale presso l'autorità governativa competente. Il documento deve essere risalente a meno di 3 mesi.",
315
315
  "supportingDocuments.purpose.CorporateIncomeTaxReturn": "Dichiarazione dei redditi della società",
316
316
  "supportingDocuments.purpose.FinancialStatements": "Ultima dichiarazione dei redditi dell'azienda",
317
- "supportingDocuments.purpose.FinancialStatements.description": "Una copia del documento inviato al tuo ufficio delle imposte alla fine dell'ultimo periodo commerciale.",
317
+ "supportingDocuments.purpose.FinancialStatements.description": "Una copia del documento presentato all'Agenzia delle Entrate al termine dell'ultimo periodo fiscale.",
318
318
  "supportingDocuments.purpose.GeneralAssemblyMinutes": "Verbale dell’assemblea generale",
319
319
  "supportingDocuments.purpose.GeneralAssemblyMinutes.description": "Il verbale della riunione è un resoconto formale scritto delle discussioni, decisioni e azioni intraprese durante una riunione dell'organizzazione o dell'azienda. La lista del consiglio associativo deve comparire nel verbale. Il verbale deve essere risalente all'ultima versione disponibile.",
320
320
  "supportingDocuments.purpose.LegalRepresentativeProofOfIdentity": "Documento d'identità del vostro rappresentante legale",
321
321
  "supportingDocuments.purpose.LegalRepresentativeProofOfIdentity.description": "Documento che attesti l'identità del rappresentante legale.\n\nDocumenti accettati:\n- Passaporto\n- Carta d'identità (solo per i cittadini dei paesi membri dello Spazio Economico Europeo)\n- Permesso di soggiorno (solo per i residenti dei paesi membri dello Spazio Economico Europeo)\n- Per effettuare depositi di capitale in Francia, è necessario fornire una carta d'identità.",
322
322
  "supportingDocuments.purpose.NIFAccreditationCard": "Carta di accreditamento del NIF (Numero di Identificazione Fiscale)",
323
- "supportingDocuments.purpose.NIFAccreditationCard.description": "Copia della tua carta di accreditamento del NIF per fornire il tuo numero di identificazione fiscale.",
323
+ "supportingDocuments.purpose.NIFAccreditationCard.description": "Copia della sua carta di accreditamento del NIF per fornire il numero di identificazione fiscale.",
324
324
  "supportingDocuments.purpose.Other": "Altro",
325
325
  "supportingDocuments.purpose.Other.description": "Carica qualsiasi documento di supporto che ritieni possa essere utile nel processo di integrazione.",
326
326
  "supportingDocuments.purpose.PowerOfAttorney": "Procura firmata dal rappresentante legale",
327
- "supportingDocuments.purpose.PowerOfAttorney.description": "A signed and dated document authorizing an individual to represent or act on behalf of a company's legal representative.\n\nPlease use the attached template.",
327
+ "supportingDocuments.purpose.PowerOfAttorney.description": "Documento firmato e datato che autorizza una persona a rappresentare o agire per conto del rappresentante legale della società.\n\nSi prega di utilizzare il modello allegato.",
328
328
  "supportingDocuments.purpose.PresidentDecisionOfAppointment": "Lettera di nomina del Presidente",
329
329
  "supportingDocuments.purpose.PresidentDecisionOfAppointment.description": "Documento che attesta la decisione di nominare un individuo come presidente della vostra organizzazione.",
330
330
  "supportingDocuments.purpose.ProofOfCompanyAddress": "Prova dell'indirizzo dell'azienda",
@@ -334,9 +334,9 @@
334
334
  "supportingDocuments.purpose.ProofOfIdentity": "Documento di identità",
335
335
  "supportingDocuments.purpose.ProofOfIdentity.description": "Documenti accettabili:\n- Passaporto\n- Carta d'identità (applicabile solo ai cittadini dei paesi membri della zona EEE)\n- Permesso di soggiorno (applicabile solo ai residenti dei paesi membri della zona EEE)",
336
336
  "supportingDocuments.purpose.ProofOfIndividualAddress": "Prova di residenza (risalente a meno di 3 mesi)",
337
- "supportingDocuments.purpose.ProofOfIndividualAddress.description": "Qualsiasi documento che attesti l'indirizzo di residenza dell'individuo. Deve includere il nome e l'indirizzo dell'individuo e essere datato di meno di 3 mesi.\n\nDocumenti accettabili:\n- Documenti relativi alla casa (contratto di locazione, estratto conto del mutuo, ecc.)\n- Bollette dei servizi domestici (per elettricità, telefono, servizi Internet, gas, acqua, ecc.)\n- Busta paga (se include l'indirizzo del lavoratore)",
337
+ "supportingDocuments.purpose.ProofOfIndividualAddress.description": "Qualsiasi documento che attesti l'indirizzo di residenza dell'individuo. Il documento deve includere il nome e l'indirizzo dell'individuo ed essere stato emesso da meno di 3 mesi.\n\nDocumenti accettabili:\n- Documenti relativi all'abitazione (contratto di locazione, estratto conto del mutuo, ecc.)\n- Bollette delle utenze domestiche (elettricità, telefono, servizi Internet, gas, acqua, ecc.)\n- Busta paga (se include l'indirizzo del lavoratore)",
338
338
  "supportingDocuments.purpose.ProofOfIndividualIncome": "Prova di reddito ",
339
- "supportingDocuments.purpose.ProofOfIndividualIncome.description": "A document or set of documents that demonstrates a person's income over a specific period of time.\n\nAcceptable documents:\n- An income-tax return dating less than 2 years\n- A pay slip dating less than 3 months",
339
+ "supportingDocuments.purpose.ProofOfIndividualIncome.description": "Un documento o una serie di documenti che dimostrano il reddito di un soggetto in un determinato periodo di tempo.\n\nDocumenti accettabili:\n- Una dichiarazione dei redditi risalente a meno di 2 anni fa\n- Una busta paga risalente a meno di 3 mesi fa",
340
340
  "supportingDocuments.purpose.ProofOfOriginOfFunds": "Prova dei fondi",
341
341
  "supportingDocuments.purpose.ProofOfOriginOfFunds.description": "Documento ufficiale che attesti l'origine dei fondi.\n\nDocumenti accettabili:\n- Busta paga (datata di meno di 3 mesi)\n- Rendiconto fiscale (datato di meno di 2 anni)",
342
342
  "supportingDocuments.purpose.RegisterExtract": "Estratti del registro",
@@ -347,7 +347,7 @@
347
347
  "supportingDocuments.purpose.UBODeclaration": "Prova del certificato del Beneficiario Effettivo Ultimo (UBO)",
348
348
  "supportingDocuments.purpose.UBODeclaration.description": "Un documento che identifica e verifica gli individui che possiedono o controllano in ultima istanza un'azienda o un'entità commerciale. Gli azionari effettivi sono individui che possiedono più del 25% delle azioni o dei diritti di voto dell'azienda. Se non ce ne sono, i Beneficiari Effettivi Ultimi sono i rappresentanti legali dell'organizzazione.",
349
349
  "supportingDocuments.purpose.UltimateBeneficialOwnerProofOfAddress": "Prova dell'indirizzo per ciascun beneficiario effettivo",
350
- "supportingDocuments.purpose.UltimateBeneficialOwnerProofOfAddress.description": "Includere un documento per ciascuna persona che possiede almeno il 25% del capitale o dei diritti di voto, o qualsiasi persona che controlla gli organi esecutivi o amministrativi della vostra azienda. Un qualsiasi documento che attesti l'indirizzo di residenza dell'individuo. Questi documenti devono includere il nome e l'indirizzo dell'individuo e essere datati di meno di 3 mesi fa.\n\nDocumenti accettabili:\n- Documenti relativi alla casa (contratto d’affitto, estratto conto del mutuo, ecc.)\n- Bollette dei servizi domestici (per elettricità, telefono, servizi Internet, gas, acqua, ecc.)\n- Busta paga (se include l'indirizzo del lavoratore)",
350
+ "supportingDocuments.purpose.UltimateBeneficialOwnerProofOfAddress.description": "Si prega di allegare un documento per ogni persona che possiede almeno il 25% del capitale o dei diritti di voto, o per qualsiasi persona che controlla gli organi esecutivi o la direzione della sua azienda. Qualsiasi documento che attesti l'indirizzo di residenza della persona. I documenti devono includere il nome e l'indirizzo della persona ed essere stati emessi da meno di 3 mesi.\n\nDocumenti accettabili:\n- Documenti relativi all'abitazione (contratto di locazione, estratto conto del mutuo, ecc.)\n- Bollette delle utenze domestiche (elettricità, telefono, servizi Internet, gas, acqua, ecc.)\n- Busta paga (se include l'indirizzo del lavoratore)",
351
351
  "supportingDocuments.purpose.UltimateBeneficialOwnerProofOfIdentity": "Documento di identità per ciascun azionario effettivo",
352
352
  "supportingDocuments.purpose.UltimateBeneficialOwnerProofOfIdentity.description": "Documento di identità per ciascuna persona che possieda almeno il 25% del capitale o dei diritti di voto, o qualsiasi persona che controlli gli organi esecutivi o amministrativi della vostra azienda.\n\nDocumenti accettabili:\n- Passaporto\n- Carta d'identità (applicabile solo ai cittadini dei paesi membri della zona EEE)\n- Permesso di soggiorno (applicabile solo ai residenti dei paesi membri della zona EEE)\n- Patente di guida (applicabile solo ai residenti dei paesi membri della zona EEE)",
353
353
  "supportingDocuments.rejectionReason.BadDocumentQuality": "La qualità del documento è davvero bassa",
@@ -384,7 +384,7 @@
384
384
  "transactionStatement.debtor.bankIdentifier": "Identificativo bancario del debitore",
385
385
  "transactionStatement.debtor.bankName": "Nome della banca del debitore",
386
386
  "transactionStatement.debtor.name": "Nome del debitore",
387
- "transactionStatement.footer": "SWAN è una società per azioni semplificata (SAS) registrata presso il Registro delle imprese di Bobigny con il numero 853 827 103, con un capitale di 16.999,66 euro, partita IVA FR90853827103 e sede legale in 95 Avenue du Président Wilson, 93100 Montreuil, FRANCIA.\nIn qualità di istituto di moneta elettronica che offre servizi di pagamento ai sensi della legge francese approvata dall'ACPR, SWAN è registrata presso quest'ultima con il numero 17328.",
387
+ "transactionStatement.footer": "SWAN è una società per azioni semplificata (SAS) registrata presso il Registro delle imprese di Bobigny con il numero 853 827 103, con un capitale di 16.999,66 euro, partita IVA FR90853827103 e sede legale in 91 rue du Faubourg Saint-Honoré, 75008 Paris, FRANCIA.\nIn qualità di istituto di moneta elettronica che offre servizi di pagamento ai sensi della legge francese approvata dall'ACPR, SWAN è registrata presso quest'ultima con il numero 17328.",
388
388
  "transactionStatement.generationDate": "Generato il: {date}",
389
389
  "transactionStatement.generationInfos": "Questo documento è la conferma della tua richiesta di transazione. Non costituisce prova dell'esecuzione della transazione. La tua transazione verrà eseguita dopo aver superato un obbligatorio processo di verifica.",
390
390
  "transactionStatement.information.amount": "Importo",
@@ -412,5 +412,5 @@
412
412
  "transactionStatement.type.SepaInstantCreditTransferOut": "Bonifico istantaneo SEPA inviato",
413
413
  "validation.birthdateCannotBeFuture": "La data di nascita non può essere nel futuro",
414
414
  "validation.invalidBirthDate": "Inserisci una data di nascita valida.",
415
- "validation.invalidDate": "Inserisci una data valida."
415
+ "validation.invalidDate": "Inserire una data valida."
416
416
  }
@@ -3,7 +3,7 @@
3
3
  "accountStatement.card": "Kaart",
4
4
  "accountStatement.check": "Cheque",
5
5
  "accountStatement.closingBalance": "Eindsaldo",
6
- "accountStatement.column.credit": "Tegoed (€)",
6
+ "accountStatement.column.credit": "Krediet (€)",
7
7
  "accountStatement.column.date": "Datum",
8
8
  "accountStatement.column.debit": "Debet (€)",
9
9
  "accountStatement.column.description": "Omschrijving",
@@ -54,7 +54,7 @@
54
54
  "common.form.help.nbDigits": "{nbDigits} cijfers",
55
55
  "common.form.invalidTaxIdentificationNumber": "Dit veld is ongeldig",
56
56
  "common.form.taxIdentificationNumber.placeholder": "BTW-nummer",
57
- "common.form.taxIdentificationNumber.tooltip.deu": "Identifikationsnummer (ook Steuerliche Identifikationsnummer, Persönliche Identificationsnummer, Identifikationsnummer, Steuer-IDnr., IDnr of Steuer-ID, volgens § 139b AO)",
57
+ "common.form.taxIdentificationNumber.tooltip.deu": "Steuernummer des Unternehmens",
58
58
  "common.form.taxIdentificationNumber.tooltip.ita": "Btw-nummer (Codice fiscale)",
59
59
  "common.next": "Volgende",
60
60
  "common.noResult": "Leeg resultaat",
@@ -67,12 +67,12 @@
67
67
  "common.skipToContent": "Doorgaan naar artikel",
68
68
  "copyButton.copiedTooltip": "Gekopieerd naar klembord",
69
69
  "copyButton.copyTooltip": "Klik om te kopiëren",
70
- "creditStatement.additionalDetails": "Het overzicht van <bold>{openingDate}</bold> tot <bold>{closingDate}</bold> omvat alle kosten en ontvangen betalingen tot {closingDate}. Uw volgende automatische incasso zal starten vanaf {repaymentDate}.\n\nBij een geweigerde bankafschrijving wegens onvoldoende saldo, kunnen wij deze afschrijving op zijn vroegst <bold>3 tot 4 dagen</bold> na de melding van uw bank opnieuw aanbieden.",
70
+ "creditStatement.additionalDetails": "De afrekening van bold>{openingDate}</bold> tot <bold>{closingDate}</bold> bevat alle kosten en betalingen die we tot {closingDate} hebben ontvangen. De volgende automatische afschrijving gebeurt vanaf {repaymentDate}.\n\n\nAls een automatische incasso wordt geweigerd omdat er niet genoeg geld op je rekening staat, kunnen we deze incasso minstens <bold>3 tot 4 dagen</bold> na de weigering door je bank opnieuw proberen.",
71
71
  "creditStatement.column.credit": "Credit",
72
- "creditStatement.column.debit": "Debit",
73
- "creditStatement.issueDate": "Uitgiftedatum {issueDate}",
72
+ "creditStatement.column.debit": "Debet",
73
+ "creditStatement.issueDate": "Uitgiftedatum: {issueDate}",
74
74
  "creditStatement.siret": "SIRET",
75
- "creditStatement.titleDocument": "Terugbetalingsverklaring",
75
+ "creditStatement.titleDocument": "Terugbetalingsoverzicht",
76
76
  "datePicker.day": "Dag",
77
77
  "datePicker.day.friday": "Vrijdag",
78
78
  "datePicker.day.monday": "Maandag",
@@ -384,7 +384,7 @@
384
384
  "transactionStatement.debtor.bankIdentifier": "Bank-ID van de debiteur",
385
385
  "transactionStatement.debtor.bankName": "Banknaam van de debiteur",
386
386
  "transactionStatement.debtor.name": "Naam van de debiteur",
387
- "transactionStatement.footer": "SWAN is een vereenvoudigde naamloze vennootschap (SAS) geregistreerd bij de Kamer van Koophandel van Bobigny onder nummer 853 827 103, met een kapitaal van 16.999,66 euro, btw-nummer FR90853827103 en met maatschappelijke zetel gevestigd aan 95 Avenue du Président Wilson, 93100 Montreuil, FRANKRIJK.\nIn zijn hoedanigheid van een elektronisch geldinstelling die betalingsdiensten aanbiedt onder Frans recht goedgekeurd door de ACPR, is SWAN geregistreerd bij laatstgenoemde onder nummer 17328.",
387
+ "transactionStatement.footer": "SWAN is een vereenvoudigde naamloze vennootschap (SAS) geregistreerd bij de Kamer van Koophandel van Bobigny onder nummer 853 827 103, met een kapitaal van 16.999,66 euro, btw-nummer FR90853827103 en met maatschappelijke zetel gevestigd aan 91 rue du Faubourg Saint-Honoré, 75008 Paris, FRANKRIJK.\nIn zijn hoedanigheid van een elektronisch geldinstelling die betalingsdiensten aanbiedt onder Frans recht goedgekeurd door de ACPR, is SWAN geregistreerd bij laatstgenoemde onder nummer 17328.",
388
388
  "transactionStatement.generationDate": "Gegenereerd op: {date}",
389
389
  "transactionStatement.generationInfos": "Dit document bevestigt je transactieverzoek. Het vormt geen bewijs van transactie-uitvoering. Je transactie zal worden uitgevoerd na het doorlopen van een verplicht verificatieproces.",
390
390
  "transactionStatement.information.amount": "Bedrag",
@@ -412,5 +412,5 @@
412
412
  "transactionStatement.type.SepaInstantCreditTransferOut": "SEPA Instant-overschrijving verzonden",
413
413
  "validation.birthdateCannotBeFuture": "Geboortedatum kan niet in de toekomst liggen",
414
414
  "validation.invalidBirthDate": "Voer een geldige geboortedatum in.",
415
- "validation.invalidDate": "Voer alstublieft een geldige datum in."
415
+ "validation.invalidDate": "Voer een geldige datum in."
416
416
  }
@@ -54,7 +54,7 @@
54
54
  "common.form.help.nbDigits": "{nbDigits} dígitos",
55
55
  "common.form.invalidTaxIdentificationNumber": "Este campo é inválido",
56
56
  "common.form.taxIdentificationNumber.placeholder": "Número de Identificação Fiscal",
57
- "common.form.taxIdentificationNumber.tooltip.deu": "Identifikationsnummer (também Steuerliche Identificationsnummer, Persönliche Identificationsnummer, Identifikationsnummer, Steuer-IdNr., IdNr ou Steuer-ID, conforme § 139b AO)",
57
+ "common.form.taxIdentificationNumber.tooltip.deu": "Steuernummer des Unternehmens",
58
58
  "common.form.taxIdentificationNumber.tooltip.ita": "NIF (Número de Identificação Fiscal)",
59
59
  "common.next": "Próximo",
60
60
  "common.noResult": "Resultado vazio",
@@ -72,7 +72,7 @@
72
72
  "creditStatement.column.debit": "Débito",
73
73
  "creditStatement.issueDate": "Data de emissão {issueDate}",
74
74
  "creditStatement.siret": "SIRET",
75
- "creditStatement.titleDocument": "Declaração de reembolso",
75
+ "creditStatement.titleDocument": "Declaração de amortização",
76
76
  "datePicker.day": "Dia",
77
77
  "datePicker.day.friday": "Sexta-feira",
78
78
  "datePicker.day.monday": "Segunda-feira",
@@ -384,7 +384,7 @@
384
384
  "transactionStatement.debtor.bankIdentifier": "Identificador bancário do devedor",
385
385
  "transactionStatement.debtor.bankName": "Nome do banco do devedor",
386
386
  "transactionStatement.debtor.name": "Nome do devedor",
387
- "transactionStatement.footer": "A SWAN é uma sociedade anônima simplificada (SAS) registrada no Registro de Comércio e Empresas de Bobigny sob o número 853 827 103, com capital de 16.999,66 euros, número de IVA FR90853827103 e cuja sede está localizada em 95 Avenue du Président Wilson, 93100 Montreuil, FRANÇA.\nNa qualidade de instituição de dinheiro eletrônico que oferece serviços de pagamento ao abrigo da lei francesa aprovada pela ACPR, a SWAN está registrada junto deste sob o número 17328.",
387
+ "transactionStatement.footer": "A SWAN é uma sociedade anônima simplificada (SAS) registrada no Registro de Comércio e Empresas de Bobigny sob o número 853 827 103, com capital de 16.999,66 euros, número de IVA FR90853827103 e cuja sede está localizada em 91 rue du Faubourg Saint-Honoré, 75008 Paris, FRANÇA.\nNa qualidade de instituição de dinheiro eletrônico que oferece serviços de pagamento ao abrigo da lei francesa aprovada pela ACPR, a SWAN está registrada junto deste sob o número 17328.",
388
388
  "transactionStatement.generationDate": "Gerado em:{date}",
389
389
  "transactionStatement.generationInfos": "Este documento é a confirmação do seu pedido de transação. Não constitui prova da execução da transação. A sua transação será executada ao completar o processo de verificação obrigatório.",
390
390
  "transactionStatement.information.amount": "Valor",
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,291 @@
1
+ import { describe, expect, test } from "vitest";
2
+ import { getCompanyTaxNumberHelp, getCompanyTaxNumberPlaceholder, getIndividualTaxNumberHelp, getIndividualTaxNumberPlaceholder, getTaxNumberTooltip, isValidEmail, validateBooleanRequired, validateCompanyTaxNumber, validateIndividualTaxNumber, validateNullableRequired, validateRequired, } from "../validation";
3
+ describe("isValidEmail", () => {
4
+ test("validates correct email addresses", () => {
5
+ expect(isValidEmail("test@example.com")).toBe(true);
6
+ expect(isValidEmail("user.name+tag@example.co.uk")).toBe(true);
7
+ expect(isValidEmail("test_email@domain.io")).toBe(true);
8
+ expect(isValidEmail("TEST@EXAMPLE.COM")).toBe(true);
9
+ expect(isValidEmail("test@proton.me")).toBe(true);
10
+ });
11
+ test("rejects invalid email addresses", () => {
12
+ expect(isValidEmail("invalid")).toBe(false);
13
+ expect(isValidEmail("@example.com")).toBe(false);
14
+ expect(isValidEmail("test@")).toBe(false);
15
+ expect(isValidEmail("test@.com")).toBe(false);
16
+ expect(isValidEmail("")).toBe(false);
17
+ });
18
+ });
19
+ describe("validateRequired", () => {
20
+ test("returns error for empty strings", () => {
21
+ expect(validateRequired("")).toBeDefined();
22
+ });
23
+ test("returns undefined for non-empty strings", () => {
24
+ expect(validateRequired("value")).toBeUndefined();
25
+ });
26
+ });
27
+ describe("validateNullableRequired", () => {
28
+ test("returns error for undefined or empty values", () => {
29
+ expect(validateNullableRequired(undefined)).toBeDefined();
30
+ expect(validateNullableRequired("")).toBeDefined();
31
+ });
32
+ test("returns undefined for non-empty strings", () => {
33
+ expect(validateNullableRequired("value")).toBeUndefined();
34
+ });
35
+ });
36
+ describe("validateBooleanRequired", () => {
37
+ test("returns error for undefined or false", () => {
38
+ expect(validateBooleanRequired(undefined)).toBeDefined();
39
+ expect(validateBooleanRequired(false)).toBeDefined();
40
+ });
41
+ test("returns undefined for true", () => {
42
+ expect(validateBooleanRequired(true)).toBeUndefined();
43
+ });
44
+ });
45
+ describe("validateIndividualTaxNumber", () => {
46
+ describe("BEL (Belgium)", () => {
47
+ const validator = validateIndividualTaxNumber("BEL");
48
+ test("accepts valid 10-digit tax numbers", () => {
49
+ expect(validator("1234567890")).toBeUndefined();
50
+ });
51
+ test("rejects invalid formats", () => {
52
+ expect(validator("123456789")).toBeDefined(); // 9 digits
53
+ expect(validator("12345678901")).toBeDefined(); // 11 digits
54
+ expect(validator("123456789A")).toBeDefined(); // contains letter
55
+ });
56
+ test("allows undefined or empty values", () => {
57
+ expect(validator(undefined)).toBeUndefined();
58
+ expect(validator("")).toBeUndefined();
59
+ });
60
+ });
61
+ describe("DEU (Germany)", () => {
62
+ const validator = validateIndividualTaxNumber("DEU");
63
+ test("accepts valid 11-digit tax numbers", () => {
64
+ expect(validator("12345678901")).toBeUndefined();
65
+ });
66
+ test("rejects invalid formats", () => {
67
+ expect(validator("1234567890")).toBeDefined(); // 10 digits
68
+ expect(validator("123456789012")).toBeDefined(); // 12 digits
69
+ });
70
+ });
71
+ describe("ESP (Spain)", () => {
72
+ const validator = validateIndividualTaxNumber("ESP");
73
+ test("accepts valid 9-character tax numbers", () => {
74
+ expect(validator("123456789")).toBeUndefined();
75
+ expect(validator("A1234567B")).toBeUndefined();
76
+ });
77
+ test("rejects invalid formats", () => {
78
+ expect(validator("12345678")).toBeDefined(); // 8 characters
79
+ expect(validator("1234567890")).toBeDefined(); // 10 characters
80
+ });
81
+ });
82
+ describe("FIN (Finland)", () => {
83
+ const validator = validateIndividualTaxNumber("FIN");
84
+ test("accepts valid 11-character tax numbers", () => {
85
+ expect(validator("12345678901")).toBeUndefined();
86
+ expect(validator("A234567890B")).toBeUndefined();
87
+ });
88
+ test("rejects invalid formats", () => {
89
+ expect(validator("1234567890")).toBeDefined(); // 10 characters
90
+ expect(validator("123456789012")).toBeDefined(); // 12 characters
91
+ });
92
+ });
93
+ describe("FRA (France)", () => {
94
+ const validator = validateIndividualTaxNumber("FRA");
95
+ test("accepts valid 13-digit tax numbers", () => {
96
+ expect(validator("1234567890123")).toBeUndefined();
97
+ });
98
+ test("rejects invalid formats", () => {
99
+ expect(validator("123456789012")).toBeDefined(); // 12 digits
100
+ expect(validator("12345678901234")).toBeDefined(); // 14 digits
101
+ expect(validator("123456789012A")).toBeDefined(); // contains letter
102
+ });
103
+ });
104
+ describe("ITA (Italy)", () => {
105
+ const validator = validateIndividualTaxNumber("ITA");
106
+ test("accepts valid 16-character tax numbers", () => {
107
+ expect(validator("1234567890123456")).toBeUndefined();
108
+ expect(validator("ABCDEF12G34H567I")).toBeUndefined();
109
+ });
110
+ test("rejects invalid formats", () => {
111
+ expect(validator("123456789012345")).toBeDefined(); // 15 characters
112
+ expect(validator("12345678901234567")).toBeDefined(); // 17 characters
113
+ });
114
+ });
115
+ describe("NLD (Netherlands)", () => {
116
+ const validator = validateIndividualTaxNumber("NLD");
117
+ test("accepts valid 9-digit tax numbers", () => {
118
+ expect(validator("123456789")).toBeUndefined();
119
+ });
120
+ test("rejects invalid formats", () => {
121
+ expect(validator("12345678")).toBeDefined(); // 8 digits
122
+ expect(validator("1234567890")).toBeDefined(); // 10 digits
123
+ expect(validator("12345678A")).toBeDefined(); // contains letter
124
+ });
125
+ });
126
+ describe("PRT (Portugal)", () => {
127
+ const validator = validateIndividualTaxNumber("PRT");
128
+ test("accepts valid 9-digit tax numbers", () => {
129
+ expect(validator("123456789")).toBeUndefined();
130
+ });
131
+ test("rejects invalid formats", () => {
132
+ expect(validator("12345678")).toBeDefined(); // 8 digits
133
+ expect(validator("1234567890")).toBeDefined(); // 10 digits
134
+ });
135
+ });
136
+ });
137
+ describe("validateCompanyTaxNumber", () => {
138
+ describe("BEL (Belgium)", () => {
139
+ const validator = validateCompanyTaxNumber("BEL");
140
+ test("accepts valid 10-12 digit tax numbers", () => {
141
+ expect(validator("1234567890")).toBeUndefined(); // 10 digits
142
+ expect(validator("12345678901")).toBeUndefined(); // 11 digits
143
+ expect(validator("123456789012")).toBeUndefined(); // 12 digits
144
+ });
145
+ test("rejects invalid formats", () => {
146
+ expect(validator("123456789")).toBeDefined(); // 9 digits
147
+ expect(validator("1234567890123")).toBeDefined(); // 13 digits
148
+ expect(validator("123456789A")).toBeDefined(); // contains letter
149
+ });
150
+ test("allows undefined or empty values", () => {
151
+ expect(validator(undefined)).toBeUndefined();
152
+ expect(validator("")).toBeUndefined();
153
+ });
154
+ });
155
+ describe("DEU (Germany)", () => {
156
+ const validator = validateCompanyTaxNumber("DEU");
157
+ test("accepts valid 10-13 digit tax numbers", () => {
158
+ expect(validator("1234567890")).toBeUndefined(); // 10 digits
159
+ expect(validator("12345678901")).toBeUndefined(); // 11 digits
160
+ expect(validator("123456789012")).toBeUndefined(); // 12 digits
161
+ expect(validator("1234567890123")).toBeUndefined(); // 13 digits
162
+ });
163
+ test("rejects invalid formats", () => {
164
+ expect(validator("123456789")).toBeDefined(); // 9 digits
165
+ expect(validator("12345678901234")).toBeDefined(); // 14 digits
166
+ });
167
+ });
168
+ describe("ESP (Spain)", () => {
169
+ const validator = validateCompanyTaxNumber("ESP");
170
+ test("accepts valid 9-character tax numbers", () => {
171
+ expect(validator("123456789")).toBeUndefined();
172
+ expect(validator("A1234567B")).toBeUndefined();
173
+ });
174
+ test("rejects invalid formats", () => {
175
+ expect(validator("12345678")).toBeDefined(); // 8 characters
176
+ expect(validator("1234567890")).toBeDefined(); // 10 characters
177
+ });
178
+ });
179
+ describe("FIN (Finland)", () => {
180
+ const validator = validateCompanyTaxNumber("FIN");
181
+ test("accepts valid 8-9 character tax numbers", () => {
182
+ expect(validator("12345678")).toBeUndefined(); // 8 characters
183
+ expect(validator("123456789")).toBeUndefined(); // 9 characters
184
+ expect(validator("A2345678")).toBeUndefined();
185
+ });
186
+ test("rejects invalid formats", () => {
187
+ expect(validator("1234567")).toBeDefined(); // 7 characters
188
+ expect(validator("1234567890")).toBeDefined(); // 10 characters
189
+ });
190
+ });
191
+ describe("FRA (France)", () => {
192
+ const validator = validateCompanyTaxNumber("FRA");
193
+ test("accepts valid 9-digit tax numbers", () => {
194
+ expect(validator("123456789")).toBeUndefined();
195
+ });
196
+ test("rejects invalid formats", () => {
197
+ expect(validator("12345678")).toBeDefined(); // 8 digits
198
+ expect(validator("1234567890")).toBeDefined(); // 10 digits
199
+ expect(validator("12345678A")).toBeDefined(); // contains letter
200
+ });
201
+ });
202
+ describe("ITA (Italy)", () => {
203
+ const validator = validateCompanyTaxNumber("ITA");
204
+ test("accepts valid 11-digit tax numbers", () => {
205
+ expect(validator("12345678901")).toBeUndefined();
206
+ });
207
+ test("rejects invalid formats", () => {
208
+ expect(validator("1234567890")).toBeDefined(); // 10 digits
209
+ expect(validator("123456789012")).toBeDefined(); // 12 digits
210
+ expect(validator("1234567890A")).toBeDefined(); // contains letter
211
+ });
212
+ });
213
+ describe("NLD (Netherlands)", () => {
214
+ const validator = validateCompanyTaxNumber("NLD");
215
+ test("accepts valid 9-digit tax numbers", () => {
216
+ expect(validator("123456789")).toBeUndefined();
217
+ });
218
+ test("rejects invalid formats", () => {
219
+ expect(validator("12345678")).toBeDefined(); // 8 digits
220
+ expect(validator("1234567890")).toBeDefined(); // 10 digits
221
+ });
222
+ });
223
+ describe("PRT (Portugal)", () => {
224
+ const validator = validateCompanyTaxNumber("PRT");
225
+ test("accepts valid 9-digit tax numbers", () => {
226
+ expect(validator("123456789")).toBeUndefined();
227
+ });
228
+ test("rejects invalid formats", () => {
229
+ expect(validator("12345678")).toBeDefined(); // 8 digits
230
+ expect(validator("1234567890")).toBeDefined(); // 10 digits
231
+ });
232
+ });
233
+ });
234
+ describe("Tax number helper functions", () => {
235
+ describe("getIndividualTaxNumberPlaceholder", () => {
236
+ test("returns country-specific placeholders", () => {
237
+ expect(getIndividualTaxNumberPlaceholder("DEU")).toContain("Steueridentifikationsnummer");
238
+ expect(getIndividualTaxNumberPlaceholder("ESP")).toContain("Número de Identificación Fiscal");
239
+ expect(getIndividualTaxNumberPlaceholder("ITA")).toContain("Codice fiscale");
240
+ });
241
+ test("returns generic placeholder for other countries", () => {
242
+ const placeholder = getIndividualTaxNumberPlaceholder("FRA");
243
+ expect(placeholder).toBeTypeOf("string");
244
+ });
245
+ });
246
+ describe("getCompanyTaxNumberPlaceholder", () => {
247
+ test("returns country-specific placeholders", () => {
248
+ expect(getCompanyTaxNumberPlaceholder("DEU")).toContain("Steuer-Nummer");
249
+ expect(getCompanyTaxNumberPlaceholder("ESP")).toContain("Número de Identificación Fiscal");
250
+ expect(getCompanyTaxNumberPlaceholder("ITA")).toContain("Codice fiscale");
251
+ });
252
+ test("returns generic placeholder for other countries", () => {
253
+ const placeholder = getCompanyTaxNumberPlaceholder("FRA");
254
+ expect(placeholder).toBeTypeOf("string");
255
+ });
256
+ });
257
+ describe("getTaxNumberTooltip", () => {
258
+ test("returns tooltips for specific countries", () => {
259
+ expect(getTaxNumberTooltip("DEU")).toBeTypeOf("string");
260
+ expect(getTaxNumberTooltip("ESP")).toBe("Número de Identificación Fiscal");
261
+ expect(getTaxNumberTooltip("ITA")).toBeTypeOf("string");
262
+ });
263
+ test("returns undefined for countries without specific tooltips", () => {
264
+ expect(getTaxNumberTooltip("FRA")).toBeUndefined();
265
+ });
266
+ });
267
+ describe("getIndividualTaxNumberHelp", () => {
268
+ test("returns correct help text for all countries", () => {
269
+ expect(getIndividualTaxNumberHelp("BEL")).toBeTypeOf("string");
270
+ expect(getIndividualTaxNumberHelp("DEU")).toBeTypeOf("string");
271
+ expect(getIndividualTaxNumberHelp("ESP")).toBeTypeOf("string");
272
+ expect(getIndividualTaxNumberHelp("FIN")).toBeTypeOf("string");
273
+ expect(getIndividualTaxNumberHelp("FRA")).toBeTypeOf("string");
274
+ expect(getIndividualTaxNumberHelp("ITA")).toBeTypeOf("string");
275
+ expect(getIndividualTaxNumberHelp("NLD")).toBeTypeOf("string");
276
+ expect(getIndividualTaxNumberHelp("PRT")).toBeTypeOf("string");
277
+ });
278
+ });
279
+ describe("getCompanyTaxNumberHelp", () => {
280
+ test("returns correct help text for all countries", () => {
281
+ expect(getCompanyTaxNumberHelp("BEL")).toBeTypeOf("string");
282
+ expect(getCompanyTaxNumberHelp("DEU")).toBeTypeOf("string");
283
+ expect(getCompanyTaxNumberHelp("ESP")).toBeTypeOf("string");
284
+ expect(getCompanyTaxNumberHelp("FIN")).toBeTypeOf("string");
285
+ expect(getCompanyTaxNumberHelp("FRA")).toBeTypeOf("string");
286
+ expect(getCompanyTaxNumberHelp("ITA")).toBeTypeOf("string");
287
+ expect(getCompanyTaxNumberHelp("NLD")).toBeTypeOf("string");
288
+ expect(getCompanyTaxNumberHelp("PRT")).toBeTypeOf("string");
289
+ });
290
+ });
291
+ });
@@ -12,3 +12,8 @@ export { printFormat as printIbanFormat } from "iban";
12
12
  export declare const validateIban: (iban: string) => string | undefined;
13
13
  export declare const validateDate: (value: ExtractedDate | undefined) => string | undefined;
14
14
  export declare const validateBirthdate: (value: ExtractedDate | undefined) => string | undefined;
15
+ export declare const getIndividualTaxNumberPlaceholder: (country: IndividualCountryCCA3 | CompanyCountryCCA3) => string;
16
+ export declare const getCompanyTaxNumberPlaceholder: (country: IndividualCountryCCA3 | CompanyCountryCCA3) => string;
17
+ export declare const getTaxNumberTooltip: (country: IndividualCountryCCA3 | CompanyCountryCCA3) => string | undefined;
18
+ export declare const getCompanyTaxNumberHelp: (country: CompanyCountryCCA3) => string;
19
+ export declare const getIndividualTaxNumberHelp: (country: IndividualCountryCCA3) => string;
@@ -1,4 +1,3 @@
1
- import { noop } from "@swan-io/lake/src/utils/function";
2
1
  import { isNullish } from "@swan-io/lake/src/utils/nullish";
3
2
  import dayjs from "dayjs";
4
3
  import { isValid as isValidIban } from "iban";
@@ -34,6 +33,76 @@ const VAT_NUMBER_REGEX = /^((AT)?U[0-9]{8}|(BE)?0[0-9]{9}|(BG)?[0-9]{9,10}|(CY)?
34
33
  // (SE)?[0-9]{12} | # Sweden
35
34
  // (SI)?[0-9]{8} | # Slovenia
36
35
  // (SK)?[0-9]{10} # Slovakia
36
+ const TAX_NUMBER_REGEX = {
37
+ individual: {
38
+ BEL: {
39
+ pattern: /^\d{10}$/,
40
+ message: t("common.form.help.nbDigits", { nbDigits: "10" }),
41
+ },
42
+ DEU: {
43
+ pattern: /^\d{11}$/,
44
+ message: t("common.form.help.nbDigits", { nbDigits: "11" }),
45
+ },
46
+ ESP: {
47
+ pattern: /^[a-zA-Z0-9]{9}$/,
48
+ message: t("common.form.help.nbCharacters", { nbCharacters: "9" }),
49
+ },
50
+ FIN: {
51
+ pattern: /^[a-zA-Z0-9]{11}$/,
52
+ message: t("common.form.help.nbCharacters", { nbCharacters: "11" }),
53
+ },
54
+ FRA: {
55
+ pattern: /^\d{13}$/,
56
+ message: t("common.form.help.nbDigits", { nbDigits: "13" }),
57
+ },
58
+ ITA: {
59
+ pattern: /^[a-zA-Z0-9]{16}$/,
60
+ message: t("common.form.help.nbCharacters", { nbCharacters: "16" }),
61
+ },
62
+ NLD: {
63
+ pattern: /^\d{9}$/,
64
+ message: t("common.form.help.nbDigits", { nbDigits: "9" }),
65
+ },
66
+ PRT: {
67
+ pattern: /^\d{9}$/,
68
+ message: t("common.form.help.nbDigits", { nbDigits: "9" }),
69
+ },
70
+ },
71
+ company: {
72
+ BEL: {
73
+ pattern: /^\d{10,12}$/,
74
+ message: t("common.form.help.nbDigits", { nbDigits: "10-12" }),
75
+ },
76
+ DEU: {
77
+ pattern: /^\d{10,13}$/,
78
+ message: t("common.form.help.nbDigits", { nbDigits: "10-13" }),
79
+ },
80
+ ESP: {
81
+ pattern: /^[a-zA-Z0-9]{9}$/,
82
+ message: t("common.form.help.nbCharacters", { nbCharacters: "9" }),
83
+ },
84
+ FIN: {
85
+ pattern: /^[a-zA-Z0-9]{8,9}$/,
86
+ message: t("common.form.help.nbCharacters", { nbCharacters: "8-9" }),
87
+ },
88
+ FRA: {
89
+ pattern: /^\d{9}$/,
90
+ message: t("common.form.help.nbDigits", { nbDigits: "9" }),
91
+ },
92
+ ITA: {
93
+ pattern: /^\d{11}$/,
94
+ message: t("common.form.help.nbDigits", { nbDigits: "11" }),
95
+ },
96
+ NLD: {
97
+ pattern: /^\d{9}$/,
98
+ message: t("common.form.help.nbDigits", { nbDigits: "9" }),
99
+ },
100
+ PRT: {
101
+ pattern: /^\d{9}$/,
102
+ message: t("common.form.help.nbDigits", { nbDigits: "9" }),
103
+ },
104
+ },
105
+ };
37
106
  export const isValidVatNumber = (maybeVat) => {
38
107
  return VAT_NUMBER_REGEX.test(maybeVat);
39
108
  };
@@ -59,111 +128,19 @@ export const validateIndividualTaxNumber = (country) => value => {
59
128
  if (value == null || !value) {
60
129
  return;
61
130
  }
62
- return match(country)
63
- .with("BEL", () => {
64
- // accept 10 digits
65
- if (!/^\d{10}$/.test(value)) {
66
- return t("common.form.invalidTaxIdentificationNumber");
67
- }
68
- })
69
- .with("DEU", () => {
70
- // accept 11 digits
71
- if (!/^\d{11}$/.test(value)) {
72
- return t("common.form.invalidTaxIdentificationNumber");
73
- }
74
- })
75
- .with("ESP", () => {
76
- // accept 9 characters
77
- if (!/^[a-zA-Z0-9]{9}$/.test(value)) {
78
- return t("common.form.invalidTaxIdentificationNumber");
79
- }
80
- })
81
- .with("FIN", () => {
82
- // accept 11 characters
83
- if (!/^[a-zA-Z0-9]{11}$/.test(value)) {
84
- return t("common.form.invalidTaxIdentificationNumber");
85
- }
86
- })
87
- .with("FRA", () => {
88
- // accept 13 digits
89
- if (!/^\d{13}$/.test(value)) {
90
- return t("common.form.invalidTaxIdentificationNumber");
91
- }
92
- })
93
- .with("ITA", () => {
94
- // accept 16 characters
95
- if (!/^[a-zA-Z0-9]{16}$/.test(value)) {
96
- return t("common.form.invalidTaxIdentificationNumber");
97
- }
98
- })
99
- .with("NLD", () => {
100
- // accept 9 digits
101
- if (!/^\d{9}$/.test(value)) {
102
- return t("common.form.invalidTaxIdentificationNumber");
103
- }
104
- })
105
- .with("PRT", () => {
106
- // accept 9 digits
107
- if (!/^\d{9}$/.test(value)) {
108
- return t("common.form.invalidTaxIdentificationNumber");
109
- }
110
- })
111
- .otherwise(noop);
131
+ const rule = TAX_NUMBER_REGEX.individual[country];
132
+ if (rule && !rule.pattern.test(value)) {
133
+ return t("common.form.invalidTaxIdentificationNumber");
134
+ }
112
135
  };
113
136
  export const validateCompanyTaxNumber = (country) => value => {
114
137
  if (value == null || !value) {
115
138
  return;
116
139
  }
117
- return match(country)
118
- .with("BEL", () => {
119
- // accept 10 to 12 digits
120
- if (!/^\d{10,12}$/.test(value)) {
121
- return t("common.form.invalidTaxIdentificationNumber");
122
- }
123
- })
124
- .with("DEU", () => {
125
- // accept 10 to 13 digits
126
- if (!/^\d{10,13}$/.test(value)) {
127
- return t("common.form.invalidTaxIdentificationNumber");
128
- }
129
- })
130
- .with("ESP", () => {
131
- // accept 9 characters
132
- if (!/^[a-zA-Z0-9]{9}$/.test(value)) {
133
- return t("common.form.invalidTaxIdentificationNumber");
134
- }
135
- })
136
- .with("FIN", () => {
137
- // accept 8 to 9 characters
138
- if (!/^[a-zA-Z0-9]{8,9}$/.test(value)) {
139
- return t("common.form.invalidTaxIdentificationNumber");
140
- }
141
- })
142
- .with("FRA", () => {
143
- // accept 9 digits
144
- if (!/^\d{9}$/.test(value)) {
145
- return t("common.form.invalidTaxIdentificationNumber");
146
- }
147
- })
148
- .with("ITA", () => {
149
- // accept 11 digits
150
- if (!/^\d{11}$/.test(value)) {
151
- return t("common.form.invalidTaxIdentificationNumber");
152
- }
153
- })
154
- .with("NLD", () => {
155
- // accept 9 digits
156
- if (!/^\d{9}$/.test(value)) {
157
- return t("common.form.invalidTaxIdentificationNumber");
158
- }
159
- })
160
- .with("PRT", () => {
161
- // accept 9 digits
162
- if (!/^\d{9}$/.test(value)) {
163
- return t("common.form.invalidTaxIdentificationNumber");
164
- }
165
- })
166
- .otherwise(noop);
140
+ const rule = TAX_NUMBER_REGEX.company[country];
141
+ if (rule && !rule.pattern.test(value)) {
142
+ return t("common.form.invalidTaxIdentificationNumber");
143
+ }
167
144
  };
168
145
  export { printFormat as printIbanFormat } from "iban";
169
146
  export const validateIban = (iban) => {
@@ -194,3 +171,23 @@ export const validateBirthdate = (value) => {
194
171
  return t("validation.birthdateCannotBeFuture");
195
172
  }
196
173
  };
174
+ /*
175
+ * Translation helpers for tax validation
176
+ */
177
+ export const getIndividualTaxNumberPlaceholder = (country) => match(country)
178
+ .with("DEU", () => `${t("common.form.taxIdentificationNumber.placeholder")} (Steueridentifikationsnummer)`)
179
+ .with("ESP", () => `${t("common.form.taxIdentificationNumber.placeholder")} (Número de Identificación Fiscal)`)
180
+ .with("ITA", () => `${t("common.form.taxIdentificationNumber.placeholder")} (Codice fiscale)`)
181
+ .otherwise(() => t("common.form.taxIdentificationNumber.placeholder"));
182
+ export const getCompanyTaxNumberPlaceholder = (country) => match(country)
183
+ .with("DEU", () => `${t("common.form.taxIdentificationNumber.placeholder")} (Steuer-Nummer)`)
184
+ .with("ESP", () => `${t("common.form.taxIdentificationNumber.placeholder")} (Número de Identificación Fiscal)`)
185
+ .with("ITA", () => `${t("common.form.taxIdentificationNumber.placeholder")} (Codice fiscale)`)
186
+ .otherwise(() => t("common.form.taxIdentificationNumber.placeholder"));
187
+ export const getTaxNumberTooltip = (country) => match(country)
188
+ .with("DEU", () => t("common.form.taxIdentificationNumber.tooltip.deu"))
189
+ .with("ESP", () => "Número de Identificación Fiscal") // no need to translate
190
+ .with("ITA", () => t("common.form.taxIdentificationNumber.tooltip.ita"))
191
+ .otherwise(() => undefined);
192
+ export const getCompanyTaxNumberHelp = (country) => { var _a, _b; return (_b = (_a = TAX_NUMBER_REGEX.company[country]) === null || _a === void 0 ? void 0 : _a.message) !== null && _b !== void 0 ? _b : ""; };
193
+ export const getIndividualTaxNumberHelp = (country) => { var _a, _b; return (_b = (_a = TAX_NUMBER_REGEX.individual[country]) === null || _a === void 0 ? void 0 : _a.message) !== null && _b !== void 0 ? _b : ""; };
@@ -1,7 +0,0 @@
1
- import { CompanyCountryCCA3, IndividualCountryCCA3 } from "../constants/countries";
2
- export type AccountCountry = "DEU" | "ESP" | "FRA" | "NLD" | "ITA" | "BEL";
3
- export declare const getIndividualTaxNumberPlaceholder: (country: IndividualCountryCCA3 | CompanyCountryCCA3) => string;
4
- export declare const getCompanyTaxNumberPlaceholder: (country: IndividualCountryCCA3 | CompanyCountryCCA3) => string;
5
- export declare const getTaxNumberTooltip: (country: IndividualCountryCCA3 | CompanyCountryCCA3) => string | undefined;
6
- export declare const getCompanyTaxNumberHelp: (country: IndividualCountryCCA3 | CompanyCountryCCA3) => string;
7
- export declare const getIndividualTaxNumberHelp: (country: IndividualCountryCCA3 | CompanyCountryCCA3) => string;
@@ -1,37 +0,0 @@
1
- import { match } from "ts-pattern";
2
- import { t } from "./i18n";
3
- export const getIndividualTaxNumberPlaceholder = (country) => match(country)
4
- .with("DEU", () => `${t("common.form.taxIdentificationNumber.placeholder")} (Steueridentifikationsnummer)`)
5
- .with("ESP", () => `${t("common.form.taxIdentificationNumber.placeholder")} (Número de Identificación Fiscal)`)
6
- .with("ITA", () => `${t("common.form.taxIdentificationNumber.placeholder")} (Codice fiscale)`)
7
- .otherwise(() => t("common.form.taxIdentificationNumber.placeholder"));
8
- export const getCompanyTaxNumberPlaceholder = (country) => match(country)
9
- .with("DEU", () => `${t("common.form.taxIdentificationNumber.placeholder")} (Steuer-Nummer)`)
10
- .with("ESP", () => `${t("common.form.taxIdentificationNumber.placeholder")} (Número de Identificación Fiscal)`)
11
- .with("ITA", () => `${t("common.form.taxIdentificationNumber.placeholder")} (Codice fiscale)`)
12
- .otherwise(() => t("common.form.taxIdentificationNumber.placeholder"));
13
- export const getTaxNumberTooltip = (country) => match(country)
14
- .with("DEU", () => t("common.form.taxIdentificationNumber.tooltip.deu"))
15
- .with("ESP", () => "Número de Identificación Fiscal") // no need to translate
16
- .with("ITA", () => t("common.form.taxIdentificationNumber.tooltip.ita"))
17
- .otherwise(() => undefined);
18
- export const getCompanyTaxNumberHelp = (country) => match(country)
19
- .with("BEL", () => t("common.form.help.nbDigits", { nbDigits: "10-12" }))
20
- .with("DEU", () => t("common.form.help.nbDigits", { nbDigits: "10-13" }))
21
- .with("FIN", () => t("common.form.help.nbCharacters", { nbCharacters: "8-9" }))
22
- .with("FRA", () => t("common.form.help.nbDigits", { nbDigits: "9" }))
23
- .with("ESP", () => t("common.form.help.nbCharacters", { nbCharacters: "9" }))
24
- .with("ITA", () => t("common.form.help.nbDigits", { nbDigits: "11" }))
25
- .with("NLD", () => t("common.form.help.nbDigits", { nbDigits: "9" }))
26
- .with("PRT", () => t("common.form.help.nbDigits", { nbDigits: "9" }))
27
- .otherwise(() => "");
28
- export const getIndividualTaxNumberHelp = (country) => match(country)
29
- .with("BEL", () => t("common.form.help.nbDigits", { nbDigits: "10" }))
30
- .with("DEU", () => t("common.form.help.nbDigits", { nbDigits: "11" }))
31
- .with("ESP", () => t("common.form.help.nbCharacters", { nbCharacters: "9" }))
32
- .with("FIN", () => t("common.form.help.nbCharacters", { nbCharacters: "11" }))
33
- .with("FRA", () => t("common.form.help.nbDigits", { nbDigits: "13" }))
34
- .with("ITA", () => t("common.form.help.nbCharacters", { nbCharacters: "16" }))
35
- .with("NLD", () => t("common.form.help.nbDigits", { nbDigits: "9" }))
36
- .with("PRT", () => t("common.form.help.nbDigits", { nbDigits: "9" }))
37
- .otherwise(() => "");