From abb7a95e23a63d69e0b4b5cf9d2606d7896df80f Mon Sep 17 00:00:00 2001 From: Ayaz Hussein Date: Sun, 29 Dec 2024 17:42:33 +0200 Subject: [PATCH] added srl taxes --- .gitignore | 2 +- app/HomePageContent.tsx | 156 +++++++---- app/setari/SettingsPageContent.tsx | 90 +++---- components/IncomeDetailsCard.tsx | 2 +- components/TaxationDetailsCard.tsx | 2 +- lib/config.ts | 2 + lib/state.ts | 65 +++-- lib/taxes.ts | 420 ++++++++++++++++++----------- package.json | 3 +- 9 files changed, 461 insertions(+), 281 deletions(-) diff --git a/.gitignore b/.gitignore index 3037373..de17a42 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - +.idea # dependencies /node_modules /.pnp diff --git a/app/HomePageContent.tsx b/app/HomePageContent.tsx index 568d2d6..8c36d9b 100644 --- a/app/HomePageContent.tsx +++ b/app/HomePageContent.tsx @@ -1,65 +1,109 @@ 'use client'; -import { useSnapshot } from 'valtio'; -import { IncomeDetailsCard } from '~/components/IncomeDetailsCard'; -import { InputCard } from '~/components/InputCard'; -import { SettingsInfoCard } from '~/components/SettingsInfoCard'; -import { TaxationDetailsCard } from '~/components/TaxationDetailsCard'; -import { state } from '~/lib/state'; -import { useTaxesCalculator } from '~/lib/taxes'; +import {useSnapshot} from 'valtio'; +import {IncomeDetailsCard} from '~/components/IncomeDetailsCard'; +import {InputCard} from '~/components/InputCard'; +import {SettingsInfoCard} from '~/components/SettingsInfoCard'; +import {TaxationDetailsCard} from '~/components/TaxationDetailsCard'; +import {state} from '~/lib/state'; +import {useTaxesCalculator} from '~/lib/taxes'; +import {Card, Text} from "@mantine/core"; export default function HomePageContent() { - const snap = useSnapshot(state); + const snap = useSnapshot(state); - const { - grossIncomeInBaseCurrency, - totalTaxAmountInBaseCurrency, - totalTaxPercentage, - pensionTaxAmountInBaseCurrency, - healthTaxAmountInBaseCurrency, - incomeTaxAmountInBaseCurrency, - netIncome, - totalNetIncomeInBaseCurrency, - exchangeRates, - exchangeRatesLoading, - } = useTaxesCalculator(snap); + const pfa = useTaxesCalculator({...snap, type: 'pfa'}); - const accentColor = totalTaxPercentage - ? totalTaxPercentage > 100 - ? 'red' - : totalTaxPercentage > 50 - ? 'orange' - : 'blue' - : 'blue'; + const srlVenit = useTaxesCalculator({...snap, type: 'srl-venit'}); + const srlProfit = useTaxesCalculator({...snap, type: 'srl-profit'}); - const grossIncomeOverVATThreshold = - grossIncomeInBaseCurrency !== undefined && grossIncomeInBaseCurrency > snap.vatThreshold; + const accentColor = pfa.totalTaxPercentage + ? pfa.totalTaxPercentage > 100 + ? 'red' + : pfa.totalTaxPercentage > 50 + ? 'orange' + : 'blue' + : 'blue'; - return ( - <> - - - - - - ); + const grossIncomeOverVATThreshold = + pfa.grossIncomeInBaseCurrency !== undefined && pfa.grossIncomeInBaseCurrency > snap.vatThreshold; + + return ( + <> + + + + Taxe PFA + + + + + + + + Taxe SRL (venit) + + + + + + + Taxe SRL (Profit) + + + + + + + + ); } diff --git a/app/setari/SettingsPageContent.tsx b/app/setari/SettingsPageContent.tsx index 4ccb3a6..92300a3 100644 --- a/app/setari/SettingsPageContent.tsx +++ b/app/setari/SettingsPageContent.tsx @@ -1,51 +1,51 @@ 'use client'; -import { Card, NumberInput, Stack, Text } from '@mantine/core'; -import { useSnapshot } from 'valtio'; -import { BASE_CURRENCY } from '~/lib/config'; -import { state } from '~/lib/state'; +import {Card, NumberInput, Stack, Text} from '@mantine/core'; +import {useSnapshot} from 'valtio'; +import {BASE_CURRENCY} from '~/lib/config'; +import {state} from '~/lib/state'; export default function SettingsPageContent() { - const snap = useSnapshot(state); + const snap = useSnapshot(state); - return ( - - - - {BASE_CURRENCY} - - } - value={snap.minimumWage} - onChange={(val) => (state.minimumWage = val === '' ? 0 : Number(val))} - error={snap.vatThreshold <= 0 ? 'Scrie o valoare pozitivă' : null} - /> - - {BASE_CURRENCY} - - } - value={snap.vatThreshold} - onChange={(val) => (state.vatThreshold = val === '' ? 0 : Number(val))} - error={snap.vatThreshold <= 0 ? 'Scrie o valoare pozitivă' : null} - /> - - - ); + return ( + + + + {BASE_CURRENCY} + + } + value={snap.minimumWage} + onChange={(val) => (state.minimumWage = val === '' ? 0 : Number(val))} + error={snap.vatThreshold <= 0 ? 'Scrie o valoare pozitivă' : null} + /> + + {BASE_CURRENCY} + + } + value={snap.vatThreshold} + onChange={(val) => (state.vatThreshold = val === '' ? 0 : Number(val))} + error={snap.vatThreshold <= 0 ? 'Scrie o valoare pozitivă' : null} + /> + + + ); } diff --git a/components/IncomeDetailsCard.tsx b/components/IncomeDetailsCard.tsx index 8d33004..1986503 100644 --- a/components/IncomeDetailsCard.tsx +++ b/components/IncomeDetailsCard.tsx @@ -28,7 +28,7 @@ export function IncomeDetailsCard({ const textAlign: MantineStyleProps['ta'] = { base: 'center', xs: 'left' }; return ( - + diff --git a/components/TaxationDetailsCard.tsx b/components/TaxationDetailsCard.tsx index ab8c5e6..023827d 100644 --- a/components/TaxationDetailsCard.tsx +++ b/components/TaxationDetailsCard.tsx @@ -25,7 +25,7 @@ export function TaxationDetailsCard({ }: TaxationDetailsCardProps) { const textAlign: MantineStyleProps['ta'] = { base: 'center', xs: 'left' }; return ( - + diff --git a/lib/config.ts b/lib/config.ts index 1a554d1..945b559 100644 --- a/lib/config.ts +++ b/lib/config.ts @@ -15,7 +15,9 @@ export const WEEKS_PER_MONTH = 4.34524; export const PENSION_PERCENTAGE = 0.25; export const HEALTH_PERCENTAGE = 0.1; +export const PERSONAL_DEDUCTIBLE = 0.2; export const INCOME_TAX_PERCENTAGE = 0.1; +export const WAGE_COMPANY_TAX_PERCENTAGE = 0.0225; export const BASE_CURRENCY = 'RON'; export const CURRENCIES = [BASE_CURRENCY, 'EUR', 'USD', 'GBP', 'CHF', 'CAD', 'AUD']; export const EXCHANGE_RATES_RELOAD_INTERVAL = 3_600_000; diff --git a/lib/state.ts b/lib/state.ts index 9d366b7..ca91b2d 100644 --- a/lib/state.ts +++ b/lib/state.ts @@ -1,32 +1,49 @@ -import { proxy } from 'valtio'; -import { BASE_CURRENCY, DeductibleExpensesInterval, IncomeInterval } from './config'; +import {proxy} from 'valtio'; +import {BASE_CURRENCY, DeductibleExpensesInterval, IncomeInterval} from './config'; export type State = { - income: number; - incomeCurrency: string; - incomeInterval: IncomeInterval; - workingHoursPerWeek: number; - workingDaysPerWeek: number; - vacationWeeksPerYear: number; - deductibleExpenses: number; - deductibleExpensesCurrency: string; - deductibleExpensesInterval: DeductibleExpensesInterval; - minimumWage: number; - vatThreshold: number; + income: number; + incomeCurrency: string; + incomeInterval: IncomeInterval; + workingHoursPerWeek: number; + workingDaysPerWeek: number; + vacationWeeksPerYear: number; + deductibleExpenses: number; + deductibleExpensesCurrency: string; + deductibleExpensesInterval: DeductibleExpensesInterval; + minimumWage: number; + minimumWageTaxFreeDeductible: number; + vatThreshold: number; + dividendsTax: number; + companyIncomeTax: number; + companyHighIncomeTax: number; + companyProfitTax: number; + companyIncomeTaxThreshold: number; + companyIncomeTaxToProfitThreshold: number; }; export const initialState: State = { - income: 12000, - incomeCurrency: BASE_CURRENCY, - incomeInterval: 'monthly', - workingHoursPerWeek: 40, - workingDaysPerWeek: 5, - vacationWeeksPerYear: 4, - deductibleExpenses: 0, - deductibleExpensesCurrency: BASE_CURRENCY, - deductibleExpensesInterval: 'monthly', - minimumWage: 3_300, - vatThreshold: 300_000, + minimumWageTaxFreeDeductible: 300, + income: 12000, + incomeCurrency: BASE_CURRENCY, + incomeInterval: 'monthly', + workingHoursPerWeek: 40, + workingDaysPerWeek: 5, + vacationWeeksPerYear: 4, + deductibleExpenses: 0, + deductibleExpensesCurrency: BASE_CURRENCY, + deductibleExpensesInterval: 'monthly', + minimumWage: 3_300, + vatThreshold: 300_000, + dividendsTax: 0.10, + companyIncomeTax: 0.01, + companyHighIncomeTax: 0.03, + companyProfitTax: 0.16, + // Values are in RON for 2024 + companyIncomeTaxThreshold: 298_476, + // Values are in RON for 2024 + companyIncomeTaxToProfitThreshold: 2_487_300 + }; export const state = proxy(initialState); diff --git a/lib/taxes.ts b/lib/taxes.ts index 7bdf11d..cd4f294 100644 --- a/lib/taxes.ts +++ b/lib/taxes.ts @@ -1,164 +1,280 @@ import { - BASE_CURRENCY, - CHART_STEPS, - HEALTH_PERCENTAGE, - INCOME_TAX_PERCENTAGE, - PENSION_PERCENTAGE, - WEEKS_PER_MONTH, - WEEKS_PER_YEAR, + BASE_CURRENCY, + CHART_STEPS, + HEALTH_PERCENTAGE, + INCOME_TAX_PERCENTAGE, + PENSION_PERCENTAGE, PERSONAL_DEDUCTIBLE, WAGE_COMPANY_TAX_PERCENTAGE, + WEEKS_PER_MONTH, + WEEKS_PER_YEAR, } from './config'; -import { ExchangeRates, useExchangeRates } from './exchangeRates'; -import { State } from './state'; +import {ExchangeRates, useExchangeRates} from './exchangeRates'; +import {State} from './state'; + +function calculatePensionTaxAmount(income: number, minimumWage: number, isPfaIncome = true) { + // calculate the pension tax amount (CAS) and percentage of the gross income + if (!isPfaIncome) { + return 0; + } + if (income >= minimumWage * 24) { + return minimumWage * 24 * PENSION_PERCENTAGE; + } + if (income >= minimumWage * 12) { + return minimumWage * 12 * PENSION_PERCENTAGE; + } + return 0; +} + +function calculateHealthTaxAmount(income: number, minimumWage: number, isPfaIncome = true) { + if (income >= minimumWage * 60 && isPfaIncome) { + return minimumWage * 60 * HEALTH_PERCENTAGE; + } + if (income >= minimumWage * 6 && isPfaIncome) { + return income * HEALTH_PERCENTAGE; + } + if (income >= minimumWage * 24 && !isPfaIncome) { + return minimumWage * 24 * HEALTH_PERCENTAGE; + } + if (income >= minimumWage * 12 && !isPfaIncome) { + return minimumWage * 12 * HEALTH_PERCENTAGE; + } + if (income >= minimumWage * 6) { + return minimumWage * 6 * HEALTH_PERCENTAGE; + } + return 0; +} + +function calculateTotalIncome(incomeInterval: "hourly" | "daily" | "monthly" | "yearly", income: number, workingHoursPerWeek: number, vacationWeeksPerYear: number, workingDaysPerWeek: number) { + if (incomeInterval === 'hourly') { + income *= workingHoursPerWeek * (WEEKS_PER_YEAR - vacationWeeksPerYear); + } else if (incomeInterval === 'daily') { + income *= workingDaysPerWeek * (WEEKS_PER_YEAR - vacationWeeksPerYear); + } else if (incomeInterval === 'monthly') { + income *= 12 - vacationWeeksPerYear / WEEKS_PER_MONTH; + } + return income; +} + +function splitMinimumWageIntoTaxesAndNet(minimumWage: number, taxFree: number) { + const wage = minimumWage - taxFree; + const pension = wage * PENSION_PERCENTAGE; + const health = wage * HEALTH_PERCENTAGE; + const personalDeductibleExpense = wage * PERSONAL_DEDUCTIBLE; + const base = wage - pension - health - personalDeductibleExpense; + const tax = base * INCOME_TAX_PERCENTAGE; + const income = wage - tax + taxFree; + const companyTax = wage * WAGE_COMPANY_TAX_PERCENTAGE + const taxes = pension + health + tax; + return { + income, + taxes, + companyTax, + } +} export function calculateTaxes({ - income, - incomeCurrency, - incomeInterval, - deductibleExpenses, - deductibleExpensesCurrency, - deductibleExpensesInterval, - workingHoursPerWeek, - workingDaysPerWeek, - vacationWeeksPerYear, - minimumWage, - vatThreshold, - exchangeRates, -}: State & { exchangeRates: ExchangeRates | undefined }) { - if ( - (incomeCurrency !== BASE_CURRENCY && !exchangeRates) || - (deductibleExpensesCurrency !== BASE_CURRENCY && !exchangeRates) - ) - return; - - // subtract vacation time and adjust the income accordingly - if (incomeInterval === 'hourly') income *= workingHoursPerWeek * (WEEKS_PER_YEAR - vacationWeeksPerYear); - else if (incomeInterval === 'daily') income *= workingDaysPerWeek * (WEEKS_PER_YEAR - vacationWeeksPerYear); - else if (incomeInterval === 'monthly') income *= 12 - vacationWeeksPerYear / WEEKS_PER_MONTH; - - // people could accidentally input too many vacation weeks, so we need to make sure the income is not negative - income = Math.max(income, 0); - - // convert income to base currency if needed - if (incomeCurrency !== BASE_CURRENCY) income *= exchangeRates![incomeCurrency]; - - // save the gross income to return it later - const grossIncomeInBaseCurrency = income; - - if (deductibleExpensesInterval === 'monthly') deductibleExpenses *= 12; - - // convert deductible expenses to base currency if needed - if (deductibleExpensesCurrency !== BASE_CURRENCY) deductibleExpenses *= exchangeRates![deductibleExpensesCurrency]; - - // subtract deductible expenses from the income - income -= deductibleExpenses; - - // calculate the pension tax amount (CAS) and percentage of the gross income - let pensionTaxAmountInBaseCurrency = 0; - if (income >= minimumWage * 24) pensionTaxAmountInBaseCurrency = minimumWage * 24 * PENSION_PERCENTAGE; - else if (income >= minimumWage * 12) pensionTaxAmountInBaseCurrency = minimumWage * 12 * PENSION_PERCENTAGE; - const pensionTaxPercentage = - grossIncomeInBaseCurrency === 0 ? 0 : (pensionTaxAmountInBaseCurrency / grossIncomeInBaseCurrency) * 100; - - // calculate the health tax amount (CASS) and percentage of the gross income - let healthTaxAmountInBaseCurrency = 0; - if (income >= minimumWage * 60) healthTaxAmountInBaseCurrency = minimumWage * 60 * HEALTH_PERCENTAGE; - else if (income >= minimumWage * 6) healthTaxAmountInBaseCurrency = income * HEALTH_PERCENTAGE; - else healthTaxAmountInBaseCurrency = minimumWage * 6 * HEALTH_PERCENTAGE; - const healthTaxPercentage = (healthTaxAmountInBaseCurrency / grossIncomeInBaseCurrency) * 100; - - // calculate the taxable income and make sure it's not negative - const taxableIncome = Math.max( - income - pensionTaxAmountInBaseCurrency - healthTaxAmountInBaseCurrency, - 0 - ); - - // calculate the income tax amount and percentage of the gross income - const incomeTaxAmountInBaseCurrency = taxableIncome * INCOME_TAX_PERCENTAGE; - const incomeTaxPercentage = - grossIncomeInBaseCurrency === 0 ? 0 : (incomeTaxAmountInBaseCurrency / grossIncomeInBaseCurrency) * 100; - - // calculate the total tax amount and percentage of the gross income - const totalTaxAmountInBaseCurrency = - pensionTaxAmountInBaseCurrency + healthTaxAmountInBaseCurrency + incomeTaxAmountInBaseCurrency; - const totalTaxPercentage = (totalTaxAmountInBaseCurrency / grossIncomeInBaseCurrency) * 100; - - // calculate the total net income in base currency - const totalNetIncomeInBaseCurrency = grossIncomeInBaseCurrency - totalTaxAmountInBaseCurrency; - - // convert the total net income to the income currency if needed and adjust it for the income interval - let netIncome = totalNetIncomeInBaseCurrency; - if (incomeCurrency !== BASE_CURRENCY) netIncome /= exchangeRates![incomeCurrency]; - if (incomeInterval === 'hourly') netIncome /= workingHoursPerWeek * (WEEKS_PER_YEAR - vacationWeeksPerYear); - else if (incomeInterval === 'daily') netIncome /= workingDaysPerWeek * (WEEKS_PER_YEAR - vacationWeeksPerYear); - else if (incomeInterval === 'monthly') netIncome /= 12 - vacationWeeksPerYear / WEEKS_PER_MONTH; - - return { - grossIncomeInBaseCurrency, - grossIncomeOverVATThreshold: grossIncomeInBaseCurrency > vatThreshold, - totalNetIncomeInBaseCurrency, - netIncome, - totalTaxAmountInBaseCurrency, - totalTaxPercentage, - pensionTaxAmountInBaseCurrency, - pensionTaxPercentage, - healthTaxAmountInBaseCurrency, - healthTaxPercentage, - incomeTaxAmountInBaseCurrency, - incomeTaxPercentage, - }; + income, + incomeCurrency, + incomeInterval, + deductibleExpenses, + deductibleExpensesCurrency, + deductibleExpensesInterval, + workingHoursPerWeek, + workingDaysPerWeek, + vacationWeeksPerYear, + minimumWage, + minimumWageTaxFreeDeductible, + vatThreshold, + dividendsTax, + companyIncomeTax, + companyHighIncomeTax, + companyProfitTax, + companyIncomeTaxThreshold, + exchangeRates, + type, + }: State & { + exchangeRates: ExchangeRates | undefined; + type: 'pfa' | 'srl-venit' | 'srl-profit' +}) { + if ( + (incomeCurrency !== BASE_CURRENCY && !exchangeRates) || + (deductibleExpensesCurrency !== BASE_CURRENCY && !exchangeRates) + ) { + return; + } + const isPfaIncome = type === 'pfa'; + // subtract vacation time and adjust the income accordingly + income = calculateTotalIncome(incomeInterval, income, workingHoursPerWeek, vacationWeeksPerYear, workingDaysPerWeek); + + // people could accidentally input too many vacation weeks, so we need to make sure the income is not negative + income = Math.max(income, 0); + + // convert income to base currency if needed + if (incomeCurrency !== BASE_CURRENCY) { + income *= exchangeRates![incomeCurrency]; + } + + // save the gross income to return it later + const grossIncomeInBaseCurrency = income; + + if (deductibleExpensesInterval === 'monthly') { + deductibleExpenses *= 12; + } + + if (type === 'srl-venit') { + deductibleExpenses += minimumWage * 12; + } + + // convert deductible expenses to base currency if needed + if (deductibleExpensesCurrency !== BASE_CURRENCY) { + deductibleExpenses *= exchangeRates![deductibleExpensesCurrency]; + } + let companyTaxes = 0; + + // subtract deductible expenses from the income + if (isPfaIncome) { + income -= deductibleExpenses; + + } else { + // Calculate Company Taxes + if (type === 'srl-venit') { + const companyIncomeTaxedTaxes = Math.max( + grossIncomeInBaseCurrency * companyHighIncomeTax, + 0 + ) + const companyIncomeTaxedProfits = grossIncomeInBaseCurrency - companyIncomeTaxedTaxes; + const companyIncomeTaxedDividendTax = companyIncomeTaxedProfits * dividendsTax; + income = companyIncomeTaxedProfits - companyIncomeTaxedDividendTax; + companyTaxes = companyIncomeTaxedTaxes + companyIncomeTaxedDividendTax; + + + } + if (type === 'srl-profit') { + const companyProfitTaxedTaxes = Math.max( + (grossIncomeInBaseCurrency - deductibleExpenses) * companyProfitTax, + 0 + ) + + const companyProfitTaxedProfits = (grossIncomeInBaseCurrency - deductibleExpenses) - companyProfitTaxedTaxes; + + const companyProfitTaxedDividendTax = companyProfitTaxedProfits * dividendsTax; + + income = companyProfitTaxedProfits - companyProfitTaxedDividendTax; + companyTaxes = companyProfitTaxedTaxes + companyProfitTaxedDividendTax; + } + const { income: salaryIncome }= splitMinimumWageIntoTaxesAndNet(minimumWage, minimumWageTaxFreeDeductible); + income += salaryIncome; + } + + const pensionTaxAmountInBaseCurrency = calculatePensionTaxAmount(income, minimumWage, isPfaIncome); + const pensionTaxPercentage = + grossIncomeInBaseCurrency === 0 ? 0 : (pensionTaxAmountInBaseCurrency / grossIncomeInBaseCurrency) * 100; + + // calculate the health tax amount (CASS) and percentage of the gross income + const healthTaxAmountInBaseCurrency = calculateHealthTaxAmount(income, minimumWage, isPfaIncome); + const healthTaxPercentage = (healthTaxAmountInBaseCurrency / grossIncomeInBaseCurrency) * 100; + + // calculate the taxable income and make sure it's not negative + const taxableIncome = Math.max( + income - pensionTaxAmountInBaseCurrency - healthTaxAmountInBaseCurrency - companyTaxes, + 0 + ); + + // calculate the income tax amount and percentage of the gross income + const incomeTaxAmountInBaseCurrency = isPfaIncome ? taxableIncome * INCOME_TAX_PERCENTAGE : income - taxableIncome; + const incomeTaxPercentage = + grossIncomeInBaseCurrency === 0 ? 0 : (incomeTaxAmountInBaseCurrency / grossIncomeInBaseCurrency) * 100; + + // calculate the total tax amount and percentage of the gross income + const totalTaxAmountInBaseCurrency = + pensionTaxAmountInBaseCurrency + healthTaxAmountInBaseCurrency + incomeTaxAmountInBaseCurrency; + const totalTaxPercentage = (totalTaxAmountInBaseCurrency / grossIncomeInBaseCurrency) * 100; + + // calculate the total net income in base currency + const totalNetIncomeInBaseCurrency = grossIncomeInBaseCurrency - totalTaxAmountInBaseCurrency; + + // convert the total net income to the income currency if needed and adjust it for the income interval + let netIncome = totalNetIncomeInBaseCurrency; + if (incomeCurrency !== BASE_CURRENCY) { + netIncome /= exchangeRates![incomeCurrency]; + } + if (incomeInterval === 'hourly') { + netIncome /= workingHoursPerWeek * (WEEKS_PER_YEAR - vacationWeeksPerYear); + } else if (incomeInterval === 'daily') { + netIncome /= workingDaysPerWeek * (WEEKS_PER_YEAR - vacationWeeksPerYear); + } else if (incomeInterval === 'monthly') { + netIncome /= 12 - vacationWeeksPerYear / WEEKS_PER_MONTH; + } + + + return { + grossIncomeInBaseCurrency, + grossIncomeOverVATThreshold: grossIncomeInBaseCurrency > vatThreshold, + totalNetIncomeInBaseCurrency, + netIncome, + totalTaxAmountInBaseCurrency, + totalTaxPercentage, + pensionTaxAmountInBaseCurrency, + pensionTaxPercentage, + healthTaxAmountInBaseCurrency, + healthTaxPercentage, + incomeTaxAmountInBaseCurrency, + incomeTaxPercentage, + }; } -export function useTaxesCalculator(params: State) { - const { exchangeRates, exchangeRatesLoading } = useExchangeRates(); - return { - ...calculateTaxes({ ...params, exchangeRates }), - exchangeRates, - exchangeRatesLoading, - }; +export function useTaxesCalculator(params: State & { type: 'pfa' | 'srl-venit' | 'srl-profit' }) { + const {exchangeRates, exchangeRatesLoading} = useExchangeRates(); + return { + ...calculateTaxes({...params, exchangeRates}), + exchangeRates, + exchangeRatesLoading, + }; } export type ChartDataPoint = { - income: number; - pensionTaxPercentage: number; - healthTaxPercentage: number; - incomeTaxPercentage: number; - netIncome: number; + income: number; + pensionTaxPercentage: number; + healthTaxPercentage: number; + incomeTaxPercentage: number; + netIncome: number; }; -export function useTaxesChart({ income, ...otherParams }: State) { - const { exchangeRates, exchangeRatesLoading } = useExchangeRates(); - - const data: ChartDataPoint[] = []; - - if (!exchangeRates || income === 0) return; - - const incomeTo = income * 2; - const step = incomeTo / CHART_STEPS; - - for (let i = 0; i <= incomeTo; i += step) { - const { pensionTaxPercentage, healthTaxPercentage, incomeTaxPercentage, netIncome } = calculateTaxes({ - income: i === 0 ? 0.1 : i, - ...otherParams, - exchangeRates, - })!; - - data.push({ - income: i, - pensionTaxPercentage, - healthTaxPercentage, - incomeTaxPercentage, - netIncome, - }); - } - - return { - data, - ...calculateTaxes({ - income, - ...otherParams, - exchangeRates, - }), - exchangeRates, - exchangeRatesLoading, - }; +export function useTaxesChart({income, ...otherParams}: State & { type: 'pfa' | 'srl-venit' | 'srl-profit' }) { + const {exchangeRates, exchangeRatesLoading} = useExchangeRates(); + + const data: ChartDataPoint[] = []; + + if (!exchangeRates || income === 0) { + return; + } + + const incomeTo = income * 2; + const step = incomeTo / CHART_STEPS; + + for (let i = 0; i <= incomeTo; i += step) { + const {pensionTaxPercentage, healthTaxPercentage, incomeTaxPercentage, netIncome} = calculateTaxes({ + income: i === 0 ? 0.1 : i, + ...otherParams, + exchangeRates, + })!; + + data.push({ + income: i, + pensionTaxPercentage, + healthTaxPercentage, + incomeTaxPercentage, + netIncome, + }); + } + + return { + data, + ...calculateTaxes({ + income, + ...otherParams, + exchangeRates, + }), + exchangeRates, + exchangeRatesLoading, + }; } diff --git a/package.json b/package.json index 26e048b..056b10d 100644 --- a/package.json +++ b/package.json @@ -33,5 +33,6 @@ "swr": "^2.2.5", "typescript": "5.7.2", "valtio": "^2.1.2" - } + }, + "packageManager": "yarn@1.22.19+sha1.4ba7fc5c6e704fce2066ecbfb0b0d8976fe62447" }