@jjlmoya/utils-finance 1.1.0
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 +64 -0
- package/src/category/i18n/en.ts +159 -0
- package/src/category/i18n/es.ts +159 -0
- package/src/category/i18n/fr.ts +159 -0
- package/src/category/index.ts +24 -0
- package/src/category/seo.astro +15 -0
- package/src/components/PreviewNavSidebar.astro +116 -0
- package/src/components/PreviewToolbar.astro +143 -0
- package/src/data.ts +11 -0
- package/src/env.d.ts +5 -0
- package/src/index.ts +32 -0
- package/src/layouts/PreviewLayout.astro +117 -0
- package/src/pages/[locale]/[slug].astro +146 -0
- package/src/pages/[locale].astro +251 -0
- package/src/pages/index.astro +4 -0
- package/src/tests/faq_count.test.ts +19 -0
- package/src/tests/locale_completeness.test.ts +39 -0
- package/src/tests/mocks/astro_mock.js +2 -0
- package/src/tests/no_h1_in_components.test.ts +48 -0
- package/src/tests/schemas_fulfillment.test.ts +23 -0
- package/src/tests/seo_length.test.ts +23 -0
- package/src/tests/title_quality.test.ts +55 -0
- package/src/tests/tool_validation.test.ts +17 -0
- package/src/tool/compoundInterest/bibliography.astro +14 -0
- package/src/tool/compoundInterest/component.astro +697 -0
- package/src/tool/compoundInterest/i18n/en.ts +212 -0
- package/src/tool/compoundInterest/i18n/es.ts +212 -0
- package/src/tool/compoundInterest/i18n/fr.ts +212 -0
- package/src/tool/compoundInterest/index.ts +34 -0
- package/src/tool/compoundInterest/logic.ts +40 -0
- package/src/tool/compoundInterest/seo.astro +14 -0
- package/src/tool/compoundInterest/ui.ts +19 -0
- package/src/tool/courtFeeCalculator/bibliography.astro +14 -0
- package/src/tool/courtFeeCalculator/component.astro +427 -0
- package/src/tool/courtFeeCalculator/i18n/en.ts +268 -0
- package/src/tool/courtFeeCalculator/i18n/es.ts +268 -0
- package/src/tool/courtFeeCalculator/i18n/fr.ts +268 -0
- package/src/tool/courtFeeCalculator/index.ts +33 -0
- package/src/tool/courtFeeCalculator/logic.ts +86 -0
- package/src/tool/courtFeeCalculator/seo.astro +14 -0
- package/src/tool/courtFeeCalculator/ui.ts +31 -0
- package/src/tool/debtSnowball/bibliography.astro +14 -0
- package/src/tool/debtSnowball/component.astro +1052 -0
- package/src/tool/debtSnowball/i18n/en.ts +288 -0
- package/src/tool/debtSnowball/i18n/es.ts +288 -0
- package/src/tool/debtSnowball/i18n/fr.ts +288 -0
- package/src/tool/debtSnowball/index.ts +37 -0
- package/src/tool/debtSnowball/logic.ts +156 -0
- package/src/tool/debtSnowball/seo.astro +14 -0
- package/src/tool/debtSnowball/ui.ts +49 -0
- package/src/tool/fireCalculator/bibliography.astro +14 -0
- package/src/tool/fireCalculator/component.astro +689 -0
- package/src/tool/fireCalculator/i18n/en.ts +261 -0
- package/src/tool/fireCalculator/i18n/es.ts +261 -0
- package/src/tool/fireCalculator/i18n/fr.ts +261 -0
- package/src/tool/fireCalculator/index.ts +33 -0
- package/src/tool/fireCalculator/logic.ts +108 -0
- package/src/tool/fireCalculator/seo.astro +14 -0
- package/src/tool/fireCalculator/ui.ts +33 -0
- package/src/tool/ibanBicSwiftConverter/bibliography.astro +14 -0
- package/src/tool/ibanBicSwiftConverter/component.astro +581 -0
- package/src/tool/ibanBicSwiftConverter/i18n/en.ts +167 -0
- package/src/tool/ibanBicSwiftConverter/i18n/es.ts +216 -0
- package/src/tool/ibanBicSwiftConverter/i18n/fr.ts +167 -0
- package/src/tool/ibanBicSwiftConverter/index.ts +33 -0
- package/src/tool/ibanBicSwiftConverter/logic.ts +101 -0
- package/src/tool/ibanBicSwiftConverter/seo.astro +14 -0
- package/src/tool/ibanBicSwiftConverter/ui.ts +17 -0
- package/src/tool/inflation/bibliography.astro +14 -0
- package/src/tool/inflation/component.astro +400 -0
- package/src/tool/inflation/i18n/en.ts +301 -0
- package/src/tool/inflation/i18n/es.ts +301 -0
- package/src/tool/inflation/i18n/fr.ts +301 -0
- package/src/tool/inflation/index.ts +34 -0
- package/src/tool/inflation/logic.ts +92 -0
- package/src/tool/inflation/seo.astro +14 -0
- package/src/tool/inflation/ui.ts +17 -0
- package/src/tool/lateInterest/bibliography.astro +14 -0
- package/src/tool/lateInterest/component.astro +655 -0
- package/src/tool/lateInterest/i18n/en.ts +255 -0
- package/src/tool/lateInterest/i18n/es.ts +224 -0
- package/src/tool/lateInterest/i18n/fr.ts +224 -0
- package/src/tool/lateInterest/index.ts +34 -0
- package/src/tool/lateInterest/logic.ts +89 -0
- package/src/tool/lateInterest/seo.astro +14 -0
- package/src/tool/lateInterest/ui.ts +33 -0
- package/src/tool/legalInterestRate/bibliography.astro +14 -0
- package/src/tool/legalInterestRate/component.astro +650 -0
- package/src/tool/legalInterestRate/i18n/en.ts +159 -0
- package/src/tool/legalInterestRate/i18n/es.ts +159 -0
- package/src/tool/legalInterestRate/i18n/fr.ts +159 -0
- package/src/tool/legalInterestRate/index.ts +33 -0
- package/src/tool/legalInterestRate/logic.ts +29 -0
- package/src/tool/legalInterestRate/seo.astro +14 -0
- package/src/tool/legalInterestRate/ui.ts +23 -0
- package/src/tool/lotteryOptimizer/bibliography.astro +14 -0
- package/src/tool/lotteryOptimizer/component.astro +863 -0
- package/src/tool/lotteryOptimizer/i18n/en.ts +188 -0
- package/src/tool/lotteryOptimizer/i18n/es.ts +281 -0
- package/src/tool/lotteryOptimizer/i18n/fr.ts +188 -0
- package/src/tool/lotteryOptimizer/index.ts +33 -0
- package/src/tool/lotteryOptimizer/logic.ts +133 -0
- package/src/tool/lotteryOptimizer/seo.astro +14 -0
- package/src/tool/lotteryOptimizer/ui.ts +33 -0
- package/src/tool/mortgage/bibliography.astro +14 -0
- package/src/tool/mortgage/component.astro +1030 -0
- package/src/tool/mortgage/i18n/en.ts +227 -0
- package/src/tool/mortgage/i18n/es.ts +227 -0
- package/src/tool/mortgage/i18n/fr.ts +227 -0
- package/src/tool/mortgage/index.ts +34 -0
- package/src/tool/mortgage/logic.ts +118 -0
- package/src/tool/mortgage/seo.astro +14 -0
- package/src/tool/mortgage/ui.ts +35 -0
- package/src/tool/percentageCalculator/bibliography.astro +14 -0
- package/src/tool/percentageCalculator/component.astro +640 -0
- package/src/tool/percentageCalculator/i18n/en.ts +233 -0
- package/src/tool/percentageCalculator/i18n/es.ts +233 -0
- package/src/tool/percentageCalculator/i18n/fr.ts +233 -0
- package/src/tool/percentageCalculator/index.ts +34 -0
- package/src/tool/percentageCalculator/logic.ts +48 -0
- package/src/tool/percentageCalculator/seo.astro +14 -0
- package/src/tool/percentageCalculator/ui.ts +30 -0
- package/src/tool/rentIncreaseCalculator/bibliography.astro +14 -0
- package/src/tool/rentIncreaseCalculator/component.astro +587 -0
- package/src/tool/rentIncreaseCalculator/i18n/en.ts +159 -0
- package/src/tool/rentIncreaseCalculator/i18n/es.ts +220 -0
- package/src/tool/rentIncreaseCalculator/i18n/fr.ts +159 -0
- package/src/tool/rentIncreaseCalculator/index.ts +33 -0
- package/src/tool/rentIncreaseCalculator/logic.ts +43 -0
- package/src/tool/rentIncreaseCalculator/seo.astro +14 -0
- package/src/tool/rentIncreaseCalculator/ui.ts +19 -0
- package/src/tools.ts +16 -0
- package/src/types.ts +74 -0
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
|
|
2
|
+
import type { ToolLocaleContent } from '../../../types';
|
|
3
|
+
import type { LateInterestUI } from '../ui';
|
|
4
|
+
|
|
5
|
+
const slug = 'calculatrice-interets-retard';
|
|
6
|
+
const title = 'Calculatrice d\'Intérêts de Retard: Calcul des Pénalités';
|
|
7
|
+
const description =
|
|
8
|
+
'Calculez les intérêts de retard sur les paiements en retard. Outil pour calculer les intérêts simples, composés ou mensuels. Utile pour les factures impayées et les dettes.';
|
|
9
|
+
|
|
10
|
+
const faqData = [
|
|
11
|
+
{
|
|
12
|
+
question: 'Qu\'est-ce que l\'intérêt de retard ou les pénalités de retard?',
|
|
13
|
+
answer:
|
|
14
|
+
'C\'est l\'intérêt facturé sur une somme non payée dans le délai convenu. Il s\'applique à la dette originale et s\'accumule jusqu\'à ce que le paiement complet soit effectué.',
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
question: 'Quelle est la différence entre les intérêts simples et composés?',
|
|
18
|
+
answer:
|
|
19
|
+
'L\'intérêt simple est calculé uniquement sur le capital original chaque jour. L\'intérêt composé est calculé sur le capital plus les intérêts accumulés, générant une croissance plus rapide de la dette.',
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
question: 'Comment les intérêts quotidiens sont-ils calculés?',
|
|
23
|
+
answer:
|
|
24
|
+
'Divisez le taux annuel par 365 jours et appliquez-le au capital original. Par exemple, 10% annuel = 0,0274% quotidien.',
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
question: 'Quel taux d\'intérêt de retard dois-je appliquer?',
|
|
28
|
+
answer:
|
|
29
|
+
'Cela dépend de la législation locale et des termes du contrat. La France a des limites légales sur les taux de pénalité. Consultez un conseil juridique pour votre cas spécifique.',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
question: 'Puis-je utiliser cette calculatrice pour les dettes légales?',
|
|
33
|
+
answer:
|
|
34
|
+
'C\'est un outil informatif. Pour les dettes réelles, vérifiez les conditions contractuelles et la législation locale. Consultez un avocat si vous avez des doutes.',
|
|
35
|
+
},
|
|
36
|
+
];
|
|
37
|
+
|
|
38
|
+
const howToData = [
|
|
39
|
+
{
|
|
40
|
+
name: 'Choisissez le type de calcul',
|
|
41
|
+
text: 'Sélectionnez entre intérêt simple, composé ou mensuel selon votre situation.',
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: 'Entrez les données',
|
|
45
|
+
text: 'Saisissez le montant original, le taux d\'intérêt et la période de retard.',
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
name: 'Obtenez votre résultat',
|
|
49
|
+
text: 'La calculatrice affiche l\'intérêt quotidien accumulé, l\'intérêt total, le montant final et le taux effectif.',
|
|
50
|
+
},
|
|
51
|
+
];
|
|
52
|
+
|
|
53
|
+
const faqSchema: WithContext<FAQPage> = {
|
|
54
|
+
'@context': 'https://schema.org',
|
|
55
|
+
'@type': 'FAQPage',
|
|
56
|
+
mainEntity: faqData.map((item) => ({
|
|
57
|
+
'@type': 'Question',
|
|
58
|
+
name: item.question,
|
|
59
|
+
acceptedAnswer: { '@type': 'Answer', text: item.answer },
|
|
60
|
+
})),
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const howToSchema: WithContext<HowTo> = {
|
|
64
|
+
'@context': 'https://schema.org',
|
|
65
|
+
'@type': 'HowTo',
|
|
66
|
+
name: title,
|
|
67
|
+
description,
|
|
68
|
+
step: howToData.map((step, i) => ({
|
|
69
|
+
'@type': 'HowToStep',
|
|
70
|
+
position: i + 1,
|
|
71
|
+
name: step.name,
|
|
72
|
+
text: step.text,
|
|
73
|
+
})),
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const appSchema: WithContext<SoftwareApplication> = {
|
|
77
|
+
'@context': 'https://schema.org',
|
|
78
|
+
'@type': 'SoftwareApplication',
|
|
79
|
+
name: title,
|
|
80
|
+
description,
|
|
81
|
+
applicationCategory: 'FinanceApplication',
|
|
82
|
+
operatingSystem: 'All',
|
|
83
|
+
offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
|
|
84
|
+
inLanguage: 'fr',
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export const content: ToolLocaleContent<LateInterestUI> = {
|
|
88
|
+
slug,
|
|
89
|
+
title,
|
|
90
|
+
description,
|
|
91
|
+
faqTitle: 'Questions Fréquemment Posées',
|
|
92
|
+
faq: faqData,
|
|
93
|
+
bibliographyTitle: 'Sources et Références',
|
|
94
|
+
bibliography: [
|
|
95
|
+
{
|
|
96
|
+
name: 'Légifrance: Code du Commerce',
|
|
97
|
+
url: 'https://www.legifrance.gouv.fr/',
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
name: 'Banque de France: Taux Directeurs',
|
|
101
|
+
url: 'https://www.banque-france.fr/',
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
name: 'Calcul des Intérêts Composés',
|
|
105
|
+
url: 'https://www.investopedia.com/terms/c/compoundinterest.asp',
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
howTo: howToData,
|
|
109
|
+
schemas: [faqSchema, howToSchema, appSchema],
|
|
110
|
+
seo: [
|
|
111
|
+
{
|
|
112
|
+
type: 'title',
|
|
113
|
+
text: 'Calculatrice des Intérêts de Retard et Légaux: Guide Complet',
|
|
114
|
+
level: 2,
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
type: 'paragraph',
|
|
118
|
+
html: 'Dans le cadre juridique et fiscal complexe de l\'Espagne, l\'écoulement du temps sur une dette n\'est pas gratuit. L\'<strong>intérêt de retard</strong> et l\'<strong>intérêt légal de l\'argent</strong> sont les mécanismes que la loi utilise pour dédommager le préjudice causé par le non-respect d\'une obligation dineraire dans les délais. Qu\'il s\'agisse d\'une dette envers l\'administration fiscale, d\'un non-paiement entre entreprises ou d\'une réclamation judiciaire, comprendre comment ces intérêts s\'accumulent est essentiel.',
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
type: 'title',
|
|
122
|
+
text: 'Qu\'est-ce que l\'Intérêt Légal de l\'Argent?',
|
|
123
|
+
level: 3,
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
type: 'paragraph',
|
|
127
|
+
html: 'L\'intérêt légal de l\'argent est le surcoût appliqué à une dette lorsque les parties n\'ont pas convenu d\'un intérêt spécifique ou lorsque la loi le détermine. Pour les années <strong>2024, 2025 et 2026</strong>, ce taux est resté stable à <strong>3,25%</strong>. Ce pourcentage sert de base à de nombreux calculs juridiques.',
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
type: 'title',
|
|
131
|
+
text: 'Intérêt de Retard Fiscal (Autorité Fiscale)',
|
|
132
|
+
level: 3,
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
type: 'paragraph',
|
|
136
|
+
html: 'Lorsque la dette est envers l\'Administration, l\'<strong>intérêt de retard fiscal</strong> est supérieur à l\'intérêt légal pour décourager les retards de paiement d\'impôts. Pour la période <strong>2024-2026</strong>, il a été fixé à <strong>4,0625%</strong>. C\'est le surcoût que l\'administration fiscale vous facturera si vous produisez une auto-déclaration hors délai.',
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
type: 'tip',
|
|
140
|
+
title: 'Nature Compensatoire, Non Punitive',
|
|
141
|
+
html: '<p><strong>Point clé:</strong> Contrairement aux amendes, les intérêts de retard ont une nature compensatoire, non punitive. L\'administration ne vous "punit" pas avec eux, mais vous facture le temps que vous avez eu de l\'argent qui aurait dû être dans les caisses publiques.</p>',
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
type: 'title',
|
|
145
|
+
text: 'Comment Calculer les Intérêts Étape par Étape',
|
|
146
|
+
level: 3,
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
type: 'paragraph',
|
|
150
|
+
html: 'Le calcul de ces intérêts suit une formule d\'intérêt simple, où le temps est compté en jours civils: <strong>Intérêts = (Principal × Jours × Taux d\'Intérêt) / 36 500</strong>',
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
type: 'list',
|
|
154
|
+
items: [
|
|
155
|
+
'<strong>Principal:</strong> Le montant total de la dette originale.',
|
|
156
|
+
'<strong>Jours:</strong> Le nombre de jours écoulés depuis le jour suivant la date d\'échéance jusqu\'au jour du paiement effectif.',
|
|
157
|
+
'<strong>Taux d\'Intérêt:</strong> Le pourcentage annuel applicable (p. ex. 3,25 ou 4,0625).',
|
|
158
|
+
'<strong>36 500:</strong> Le facteur diviseur pour convertir le pourcentage annuel en quotidien (365 jours x 100).',
|
|
159
|
+
],
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
type: 'card',
|
|
163
|
+
icon: 'mdi:calculator',
|
|
164
|
+
title: 'Exemple Pratique: Dette Fiscale',
|
|
165
|
+
html: '<p>Imaginez que vous devez 5 000 € suite à une déclaration d\'impôt qui était due il y a 180 jours:</p><ul><li>Intérêt applicable (Retard): 4,0625%</li><li>Calcul: (5 000 × 180 × 4,0625) / 36 500</li><li><strong>Intérêts résultants:</strong> 100,17 €</li><li>Total à payer: 5 100,17 €</li></ul>',
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
type: 'title',
|
|
169
|
+
text: 'Différences Selon le Type de Dette',
|
|
170
|
+
level: 3,
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
type: 'list',
|
|
174
|
+
items: [
|
|
175
|
+
'<strong>Dettes Civiles:</strong> Entre particuliers, 3,25% (légal) s\'applique.',
|
|
176
|
+
'<strong>Dettes Commerciales:</strong> Régies par la Loi de Lutte contre le Retard de Paiement, atteignant 10,15% - 11,15% en 2025-2026.',
|
|
177
|
+
'<strong>Dettes à la Sécurité Sociale:</strong> Appliquent 4,0625% plus des surcharges de 10% à 20%.',
|
|
178
|
+
'<strong>Intérêts Judiciaires:</strong> Lorsqu\'il y a une décision judiciaire, 5,25% à partir de la date du jugement.',
|
|
179
|
+
],
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
type: 'title',
|
|
183
|
+
text: 'Intérêts dans les Opérations Commerciales: Attention au Délai de 60 Jours!',
|
|
184
|
+
level: 3,
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
type: 'paragraph',
|
|
188
|
+
html: 'Si vous êtes travailleur indépendant ou entreprise, la Loi de Lutte contre le Retard de Paiement établit un délai maximum de paiement de 60 jours. Si votre client dépasse cette date, vous pouvez exiger automatiquement des intérêts de retard commerciaux, sans avoir besoin d\'un rappel, et vous pouvez également percevoir un montant forfaitaire de 40 € pour frais de recouvrement.',
|
|
189
|
+
},
|
|
190
|
+
],
|
|
191
|
+
ui: {
|
|
192
|
+
labelTitle: 'Calculatrice d\'Intérêts de Retard',
|
|
193
|
+
labelSimpleTitle: 'Simple',
|
|
194
|
+
labelCompoundTitle: 'Composé',
|
|
195
|
+
labelMonthlyTitle: 'Mensuel',
|
|
196
|
+
labelSimpleQuestion: 'Calculer avec intérêt simple',
|
|
197
|
+
labelCompoundQuestion: 'Calculer avec intérêt composé',
|
|
198
|
+
labelMonthlyQuestion: 'Calculer avec périodes mensuelles',
|
|
199
|
+
labelPrincipal: 'Montant Original',
|
|
200
|
+
labelAnnualRate: 'Taux Annuel',
|
|
201
|
+
labelDays: 'Jours de Retard',
|
|
202
|
+
labelMonths: 'Mois de Retard',
|
|
203
|
+
labelMonthlyRate: 'Taux Mensuel',
|
|
204
|
+
labelDailyInterest: 'Intérêt Quotidien',
|
|
205
|
+
labelTotalInterest: 'Intérêt Total',
|
|
206
|
+
labelTotalAmount: 'Montant Total à Payer',
|
|
207
|
+
labelEffectiveRate: 'Taux Effectif',
|
|
208
|
+
labelCopyTooltip: 'Copier le résultat',
|
|
209
|
+
currencySymbol: '€',
|
|
210
|
+
percentSymbol: '%',
|
|
211
|
+
labelFormula: 'Formule appliquée',
|
|
212
|
+
reportTitle: 'RAPPORT DE CALCUL DES INTÉRÊTS',
|
|
213
|
+
reportLabelPrincipal: 'Principal',
|
|
214
|
+
reportLabelType: 'Type',
|
|
215
|
+
reportLabelPeriod: 'Période',
|
|
216
|
+
reportLabelDays: 'Jours écoulés',
|
|
217
|
+
reportLabelInterest: 'INTÉRÊTS COURUS',
|
|
218
|
+
reportLabelTotal: 'TOTAL DÛ',
|
|
219
|
+
reportDaysSuffix: 'jours',
|
|
220
|
+
formulaDescription: 'Ce calcul utilise les taux en vigueur. Si la période s\'étend sur des années antérieures avec des taux différents, le calcul réel devrait être divisé par périodes.',
|
|
221
|
+
currencyCode: 'EUR',
|
|
222
|
+
currencyLocale: 'fr-FR',
|
|
223
|
+
},
|
|
224
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { FinanceToolEntry, ToolLocaleContent, ToolDefinition } from '../../types';
|
|
2
|
+
import LateInterestComponent from './component.astro';
|
|
3
|
+
import LateInterestSEO from './seo.astro';
|
|
4
|
+
import LateInterestBibliography from './bibliography.astro';
|
|
5
|
+
|
|
6
|
+
import type { LateInterestUI } from './ui';
|
|
7
|
+
|
|
8
|
+
export type LateInterestLocaleContent = ToolLocaleContent<LateInterestUI>;
|
|
9
|
+
|
|
10
|
+
import { content as es } from './i18n/es';
|
|
11
|
+
import { content as en } from './i18n/en';
|
|
12
|
+
import { content as fr } from './i18n/fr';
|
|
13
|
+
|
|
14
|
+
export const lateInterest: FinanceToolEntry<LateInterestUI> = {
|
|
15
|
+
id: 'intereses-demora',
|
|
16
|
+
icons: {
|
|
17
|
+
bg: 'mdi:calendar-alert',
|
|
18
|
+
fg: 'mdi:percent',
|
|
19
|
+
},
|
|
20
|
+
i18n: {
|
|
21
|
+
es: async () => es,
|
|
22
|
+
en: async () => en,
|
|
23
|
+
fr: async () => fr,
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export { LateInterestComponent, LateInterestSEO, LateInterestBibliography };
|
|
28
|
+
|
|
29
|
+
export const LATE_INTEREST_TOOL: ToolDefinition = {
|
|
30
|
+
entry: lateInterest,
|
|
31
|
+
Component: LateInterestComponent,
|
|
32
|
+
SEOComponent: LateInterestSEO,
|
|
33
|
+
BibliographyComponent: LateInterestBibliography,
|
|
34
|
+
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
export interface LateInterestResults {
|
|
2
|
+
dailyInterest: number;
|
|
3
|
+
totalInterest: number;
|
|
4
|
+
totalAmount: number;
|
|
5
|
+
effectiveRate: number;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export class LateInterestCalculator {
|
|
9
|
+
static formatNumber(num: number): string {
|
|
10
|
+
if (isNaN(num) || !isFinite(num)) return '0';
|
|
11
|
+
if (Number.isInteger(num)) return num.toString();
|
|
12
|
+
|
|
13
|
+
let formatted = num.toFixed(2);
|
|
14
|
+
formatted = formatted.replace(/0+$/, '');
|
|
15
|
+
if (formatted.endsWith('.')) {
|
|
16
|
+
formatted = formatted.slice(0, -1);
|
|
17
|
+
}
|
|
18
|
+
return formatted;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
static calculateSimpleInterest(
|
|
22
|
+
principal: number,
|
|
23
|
+
annualRate: number,
|
|
24
|
+
days: number
|
|
25
|
+
): LateInterestResults {
|
|
26
|
+
if (isNaN(principal) || isNaN(annualRate) || isNaN(days)) {
|
|
27
|
+
return { dailyInterest: 0, totalInterest: 0, totalAmount: 0, effectiveRate: 0 };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const dailyRate = annualRate / 365 / 100;
|
|
31
|
+
const dailyInterestAmount = principal * dailyRate;
|
|
32
|
+
const totalInterest = dailyInterestAmount * days;
|
|
33
|
+
const totalAmount = principal + totalInterest;
|
|
34
|
+
const effectiveRate = (totalInterest / principal) * 100;
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
dailyInterest: dailyInterestAmount,
|
|
38
|
+
totalInterest,
|
|
39
|
+
totalAmount,
|
|
40
|
+
effectiveRate,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
static calculateCompoundInterest(
|
|
45
|
+
principal: number,
|
|
46
|
+
annualRate: number,
|
|
47
|
+
days: number
|
|
48
|
+
): LateInterestResults {
|
|
49
|
+
if (isNaN(principal) || isNaN(annualRate) || isNaN(days)) {
|
|
50
|
+
return { dailyInterest: 0, totalInterest: 0, totalAmount: 0, effectiveRate: 0 };
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const dailyRate = annualRate / 365 / 100;
|
|
54
|
+
const totalAmount = principal * Math.pow(1 + dailyRate, days);
|
|
55
|
+
const totalInterest = totalAmount - principal;
|
|
56
|
+
const dailyInterestAmount = principal * dailyRate;
|
|
57
|
+
const effectiveRate = (totalInterest / principal) * 100;
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
dailyInterest: dailyInterestAmount,
|
|
61
|
+
totalInterest,
|
|
62
|
+
totalAmount,
|
|
63
|
+
effectiveRate,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
static calculateMonthlyCompoundInterest(
|
|
68
|
+
principal: number,
|
|
69
|
+
monthlyRate: number,
|
|
70
|
+
months: number
|
|
71
|
+
): LateInterestResults {
|
|
72
|
+
if (isNaN(principal) || isNaN(monthlyRate) || isNaN(months)) {
|
|
73
|
+
return { dailyInterest: 0, totalInterest: 0, totalAmount: 0, effectiveRate: 0 };
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const rate = monthlyRate / 100;
|
|
77
|
+
const totalAmount = principal * Math.pow(1 + rate, months);
|
|
78
|
+
const totalInterest = totalAmount - principal;
|
|
79
|
+
const dailyInterestAmount = totalInterest / (months * 30);
|
|
80
|
+
const effectiveRate = (totalInterest / principal) * 100;
|
|
81
|
+
|
|
82
|
+
return {
|
|
83
|
+
dailyInterest: dailyInterestAmount,
|
|
84
|
+
totalInterest,
|
|
85
|
+
totalAmount,
|
|
86
|
+
effectiveRate,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { SEORenderer } from '@jjlmoya/utils-shared';
|
|
3
|
+
import { lateInterest } from './index';
|
|
4
|
+
import type { KnownLocale } from '../../types';
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
locale?: KnownLocale;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const { locale = 'es' } = Astro.props;
|
|
11
|
+
const content = await lateInterest.i18n[locale]?.();
|
|
12
|
+
if (!content) return null;
|
|
13
|
+
---
|
|
14
|
+
<SEORenderer content={{ locale: locale as string, sections: content.seo }} />
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export interface LateInterestUI {
|
|
2
|
+
labelTitle: string;
|
|
3
|
+
labelSimpleTitle: string;
|
|
4
|
+
labelCompoundTitle: string;
|
|
5
|
+
labelMonthlyTitle: string;
|
|
6
|
+
labelSimpleQuestion: string;
|
|
7
|
+
labelCompoundQuestion: string;
|
|
8
|
+
labelMonthlyQuestion: string;
|
|
9
|
+
labelPrincipal: string;
|
|
10
|
+
labelAnnualRate: string;
|
|
11
|
+
labelDays: string;
|
|
12
|
+
labelMonths: string;
|
|
13
|
+
labelMonthlyRate: string;
|
|
14
|
+
labelDailyInterest: string;
|
|
15
|
+
labelTotalInterest: string;
|
|
16
|
+
labelTotalAmount: string;
|
|
17
|
+
labelEffectiveRate: string;
|
|
18
|
+
labelCopyTooltip: string;
|
|
19
|
+
currencySymbol: string;
|
|
20
|
+
percentSymbol: string;
|
|
21
|
+
labelFormula: string;
|
|
22
|
+
reportTitle: string;
|
|
23
|
+
reportLabelPrincipal: string;
|
|
24
|
+
reportLabelType: string;
|
|
25
|
+
reportLabelPeriod: string;
|
|
26
|
+
reportLabelDays: string;
|
|
27
|
+
reportLabelInterest: string;
|
|
28
|
+
reportLabelTotal: string;
|
|
29
|
+
reportDaysSuffix: string;
|
|
30
|
+
formulaDescription: string;
|
|
31
|
+
currencyCode: string;
|
|
32
|
+
currencyLocale: string;
|
|
33
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { Bibliography as SharedBibliography } from '@jjlmoya/utils-shared';
|
|
3
|
+
import { legalInterestRate } from './index';
|
|
4
|
+
import type { KnownLocale } from '../../types';
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
locale?: KnownLocale;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const { locale = 'es' } = Astro.props;
|
|
11
|
+
const content = await legalInterestRate.i18n[locale]?.();
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
{content && <SharedBibliography links={content.bibliography} />}
|