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"
}