Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/cli/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -440,8 +440,8 @@ function formatReport(report: ReturnType<typeof generateTaxReport>) {
"0027_intereses_cuentas": report.interest.earned.toFixed(2),
"0327_valor_transmision": report.capitalGains.transmissionValue.toFixed(2),
"0328_valor_adquisicion": report.capitalGains.acquisitionValue.toFixed(2),
"1626_valor_transmision_fx": report.fxGains.transmissionValue.toFixed(2),
"1631_valor_adquisicion_fx": report.fxGains.acquisitionValue.toFixed(2),
"1633_valor_transmision_fx": report.fxGains.transmissionValue.toFixed(2),
"1637_valor_adquisicion_fx": report.fxGains.acquisitionValue.toFixed(2),
"0588_deduccion_doble_imposicion": report.doubleTaxation.deduction.toFixed(2),
},
resumen: {
Expand Down Expand Up @@ -515,8 +515,8 @@ function printSummary(report: ReturnType<typeof generateTaxReport>) {
if (report.fxGains.disposals.length > 0) {
console.error("");
console.error(" GANANCIAS FX — MONEDA EXTRANJERA (Art. 37.1.l)");
console.error(` Casilla 1626 (Valor transmisión): ${report.fxGains.transmissionValue.toFixed(2)} EUR`);
console.error(` Casilla 1631 (Valor adquisición): ${report.fxGains.acquisitionValue.toFixed(2)} EUR`);
console.error(` Casilla 1633 (Valor transmisión): ${report.fxGains.transmissionValue.toFixed(2)} EUR`);
console.error(` Casilla 1637 (Valor adquisición): ${report.fxGains.acquisitionValue.toFixed(2)} EUR`);
console.error(` Ganancia/Pérdida neta FX: ${report.fxGains.netGainLoss.toFixed(2)} EUR`);
}
console.error("");
Expand Down
4 changes: 2 additions & 2 deletions src/generators/csv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ export function formatCsv(report: TaxSummary): string {
lines.push("Casilla,Concepto,Valor_EUR");
lines.push(`0327,Valor de transmision,${report.capitalGains.transmissionValue.toFixed(2)}`);
lines.push(`0328,Valor de adquisicion,${report.capitalGains.acquisitionValue.toFixed(2)}`);
lines.push(`1626,Valor de transmision FX,${report.fxGains.transmissionValue.toFixed(2)}`);
lines.push(`1631,Valor de adquisicion FX,${report.fxGains.acquisitionValue.toFixed(2)}`);
lines.push(`1633,Valor de transmision FX,${report.fxGains.transmissionValue.toFixed(2)}`);
lines.push(`1637,Valor de adquisicion FX,${report.fxGains.acquisitionValue.toFixed(2)}`);
lines.push(`0029,Dividendos brutos,${report.dividends.grossIncome.toFixed(2)}`);
lines.push(`—,Intereses pagados al broker (margen no deducible — informativo),${report.interest.paid.toFixed(2)}`);
lines.push(`0027,Intereses de cuentas,${report.interest.earned.toFixed(2)}`);
Expand Down
6 changes: 3 additions & 3 deletions src/generators/pdf-web.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,10 @@ export async function generatePdfWebReport(
["0588", t("casilla.double_taxation"), eur(report.doubleTaxation.deduction)],
];

// FX gains (Casillas 1626/1631) — only shown when multi-currency FX events exist
// FX gains (Casillas 1633/1637) — only shown when multi-currency FX events exist
if (report.fxGains.disposals.length > 0) {
casillasBody.push(["1626", t("casilla.fx_transmission_value"), eur(report.fxGains.transmissionValue)]);
casillasBody.push(["1631", t("casilla.fx_acquisition_value"), eur(report.fxGains.acquisitionValue)]);
casillasBody.push(["1633", t("casilla.fx_transmission_value"), eur(report.fxGains.transmissionValue)]);
casillasBody.push(["1637", t("casilla.fx_acquisition_value"), eur(report.fxGains.acquisitionValue)]);
casillasBody.push(["", t("casilla.fx_net_gain_loss"), eur(report.fxGains.netGainLoss)]);
}

Expand Down
2 changes: 1 addition & 1 deletion src/i18n/locales/ca.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ const ca: TranslationKeys = {
"profile.phone_label": "Telèfon:",
"profile.phone_placeholder": "600123456",
"profile.monodivisa_label": "Mode simplificat (monodivisa EUR)",
"profile.monodivisa_detail": "No calcula guanys per tipus de canvi de forma separada (caselles 1626/1631). Compatible amb Autodeclaro, Taxdown i altres serveis que tracten totes les operacions com a moneda única EUR.",
"profile.monodivisa_detail": "No calcula guanys per tipus de canvi de forma separada (caselles 1633/1637). Compatible amb Autodeclaro, Taxdown i altres serveis que tracten totes les operacions com a moneda única EUR.",
"profile.monodivisa_warning": "⚠ Aquest mode pot distorsionar els guanys patrimonials declarats (infraestimar o sobreestimar). El mode complet (per defecte) és més rigorós segons l'Art. 37.1.l LIRPF (DGT V2324-10).",
"profile.saved": "Perfil desat",
"profile.save_btn": "Desar perfil",
Expand Down
2 changes: 1 addition & 1 deletion src/i18n/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ const en: TranslationKeys = {
"profile.phone_label": "Phone:",
"profile.phone_placeholder": "600123456",
"profile.monodivisa_label": "Simplified mode (single-currency EUR)",
"profile.monodivisa_detail": "Does not calculate FX gains separately (casillas 1626/1631). Compatible with Autodeclaro, Taxdown, and other services that treat all operations as single-currency EUR.",
"profile.monodivisa_detail": "Does not calculate FX gains separately (casillas 1633/1637). Compatible with Autodeclaro, Taxdown, and other services that treat all operations as single-currency EUR.",
"profile.monodivisa_warning": "⚠ This mode may distort reported capital gains (understate or overstate). The full mode (default) is more rigorous per Art. 37.1.l LIRPF (DGT V2324-10).",
"profile.saved": "Profile saved",
"profile.save_btn": "Save profile",
Expand Down
2 changes: 1 addition & 1 deletion src/i18n/locales/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ const es = {
"profile.phone_label": "Teléfono:",
"profile.phone_placeholder": "600123456",
"profile.monodivisa_label": "Modo simplificado (monodivisa EUR)",
"profile.monodivisa_detail": "No calcula ganancias por tipo de cambio de forma separada (casillas 1626/1631). Compatible con el enfoque de Autodeclaro, Taxdown y otros servicios que tratan todas las operaciones como moneda única EUR.",
"profile.monodivisa_detail": "No calcula ganancias por tipo de cambio de forma separada (casillas 1633/1637). Compatible con el enfoque de Autodeclaro, Taxdown y otros servicios que tratan todas las operaciones como moneda única EUR.",
"profile.monodivisa_warning": "⚠ Este modo puede distorsionar las ganancias patrimoniales declaradas (infraestimar o sobreestimar). El modo completo (por defecto) es más riguroso según el Art. 37.1.l LIRPF (DGT V2324-10).",
"profile.saved": "Perfil guardado",
"profile.save_btn": "Guardar perfil",
Expand Down
2 changes: 1 addition & 1 deletion src/i18n/locales/eu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ const eu: TranslationKeys = {
"profile.phone_label": "Telefonoa:",
"profile.phone_placeholder": "600123456",
"profile.monodivisa_label": "Modu sinplifikatua (monodibisa EUR)",
"profile.monodivisa_detail": "Ez ditu kanbio-tasaren irabaziak bereizita kalkulatzen (1626/1631 laukitxoak). Autodeclaro, Taxdown eta eragiketa guztiak EUR moneta bakar gisa tratatzen dituzten beste zerbitzu batzuekin bateragarria.",
"profile.monodivisa_detail": "Ez ditu kanbio-tasaren irabaziak bereizita kalkulatzen (1633/1637 laukitxoak). Autodeclaro, Taxdown eta eragiketa guztiak EUR moneta bakar gisa tratatzen dituzten beste zerbitzu batzuekin bateragarria.",
"profile.monodivisa_warning": "⚠ Modu honek adierazitako ondare-irabaziak distortsionatu ditzake (gutxietsi edo gehiegietsi). Modu osoa (lehenetsita) zorrotzagoa da 37.1.l Art. LIRPF (DGT V2324-10) arabera.",
"profile.saved": "Profila gordeta",
"profile.save_btn": "Profila gorde",
Expand Down
2 changes: 1 addition & 1 deletion src/i18n/locales/gl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ const gl: TranslationKeys = {
"profile.phone_label": "Teléfono:",
"profile.phone_placeholder": "600123456",
"profile.monodivisa_label": "Modo simplificado (monodivisa EUR)",
"profile.monodivisa_detail": "Non calcula ganancias por tipo de cambio de forma separada (casillas 1626/1631). Compatible con Autodeclaro, Taxdown e outros servizos que tratan todas as operacións como moeda única EUR.",
"profile.monodivisa_detail": "Non calcula ganancias por tipo de cambio de forma separada (casillas 1633/1637). Compatible con Autodeclaro, Taxdown e outros servizos que tratan todas as operacións como moeda única EUR.",
"profile.monodivisa_warning": "⚠ Este modo pode distorsionar as ganancias patrimoniais declaradas (infraestimar ou sobreestimar). O modo completo (por defecto) é máis rigoroso segundo o Art. 37.1.l LIRPF (DGT V2324-10).",
"profile.saved": "Perfil gardado",
"profile.save_btn": "Gardar perfil",
Expand Down
8 changes: 4 additions & 4 deletions src/types/tax.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,13 +154,13 @@ export interface TaxSummary {
byCountry: Record<string, { taxPaid: Decimal; deductionAllowed: Decimal }>;
};

/** FX gains: Ganancias/pérdidas por transmisión de moneda extranjera (Casillas 1626/1631) */
/** FX gains: Ganancias/pérdidas por transmisión de moneda extranjera (Casillas 1633/1637) */
fxGains: {
/** Casilla 1626: Valor de transmisión (FX) */
/** Casilla 1633: Valor de transmisión (FX) */
transmissionValue: Decimal;
/** Casilla 1631: Valor de adquisición (FX) */
/** Casilla 1637: Valor de adquisición (FX) */
acquisitionValue: Decimal;
/** Net gain/loss (1626 - 1631) */
/** Net gain/loss (1633 - 1637) */
netGainLoss: Decimal;
/** Individual FX disposals */
disposals: FxDisposal[];
Expand Down
6 changes: 3 additions & 3 deletions src/web/casilla-detail.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ function renderDoubleTaxDetail(report: TaxSummary): string {
</table>`;
}

/** Render a detail table of FX disposals for casilla 1626/1631 drill-down. */
/** Render a detail table of FX disposals for casilla 1633/1637 drill-down. */
function renderFxDisposalsDetail(disposals: FxDisposal[], label: string): string {
if (disposals.length === 0) return `<p class="muted">${t("casilla.no_operations")}</p>`;
return `
Expand Down Expand Up @@ -154,14 +154,14 @@ const CASILLAS: CasillaConfig[] = [
getDetail: (r) => renderDisposalsDetail(r.capitalGains.disposals, t("casilla.acquisition_value")),
},
{
code: "1626",
code: "1633",
i18nKey: "casilla.fx_transmission_value",
getValue: (r) => r.fxGains.transmissionValue.toFixed(2),
getClass: () => "",
getDetail: (r) => renderFxDisposalsDetail(r.fxGains.disposals, t("casilla.fx_transmission_value")),
},
{
code: "1631",
code: "1637",
i18nKey: "casilla.fx_acquisition_value",
getValue: (r) => r.fxGains.acquisitionValue.toFixed(2),
getClass: () => "",
Expand Down
2 changes: 1 addition & 1 deletion src/web/docs.html
Original file line number Diff line number Diff line change
Expand Up @@ -962,7 +962,7 @@ <h3>Forex (CASH) — Art. 37.1.l LIRPF</h3>
<p>Las operaciones de compraventa de divisas tributan como ganancias y pérdidas patrimoniales (DGT V2324-10, Art. 37.1.l LIRPF). DeclaRenta implementa un <strong>motor FX FIFO independiente</strong> que genera dos eventos fiscales al operar en divisa extranjera:</p>
<ol>
<li><strong>Ganancia/pérdida del valor</strong> (casillas 0327/0328): calculada sobre el precio del activo × tipo ECB en cada fecha.</li>
<li><strong>Ganancia/pérdida FX</strong> (casillas 1626/1631): diferencia entre el tipo de cambio al adquirir la divisa y el tipo al disponer de ella.</li>
<li><strong>Ganancia/pérdida FX</strong> (casillas 1633/1637): diferencia entre el tipo de cambio al adquirir la divisa y el tipo al disponer de ella.</li>
</ol>
<p>Cada adquisición de divisa extranjera (depósito EUR→USD, venta de acciones que genera USD) crea un lote en la cola FIFO de esa divisa. Cada disposición (conversión USD→EUR, compra de acciones en USD) consume lotes por orden cronológico.</p>
<p>Las conversiones automáticas del broker para liquidación (FXCONV) se excluyen automáticamente — solo las operaciones de forex deliberadas generan eventos fiscales.</p>
Expand Down
Loading