profit-planet-frontend/src/app/coffee-abonnements/summary/hooks/getTaxRate.ts
2025-12-13 11:17:48 +01:00

93 lines
3.3 KiB
TypeScript

import { authFetch } from "../../../utils/authFetch";
interface VatRate {
countryCode: string;
standardRate: number;
}
const normalizeVatRate = (rate: number | null | undefined): number | null => {
if (rate == null || Number.isNaN(rate)) return null;
return rate > 1 ? rate / 100 : rate;
};
const toNumber = (v: any): number | null => {
if (v == null) return null;
const n = typeof v === 'string' ? Number(v) : (typeof v === 'number' ? v : Number(v));
return Number.isFinite(n) ? n : null;
};
const getCode = (row: any): string => {
const raw = row?.countryCode ?? row?.code ?? row?.country ?? row?.country_code;
return typeof raw === 'string' ? raw.toUpperCase() : '';
};
const getRateRaw = (row: any): number | null => {
// support multiple field names and string numbers
const raw = row?.standardRate ?? row?.rate ?? row?.ratePercent ?? row?.standard_rate;
const num = toNumber(raw);
return num;
};
const getRateNormalized = (row: any): number | null => {
const num = getRateRaw(row);
return normalizeVatRate(num);
};
/**
* Fetches the standard VAT rate for a given ISO country code.
* Returns null if not found or on any error.
*/
export async function getStandardVatRate(countryCode: string): Promise<number | null> {
try {
const url = `${process.env.NEXT_PUBLIC_API_BASE_URL}/api/tax/vat-rates`;
console.info('[VAT] getStandardVatRate -> GET', url, { countryCode });
const res = await authFetch(url, { method: "GET" });
console.info('[VAT] getStandardVatRate status:', res.status);
if (!res.ok) return null;
const raw = await res.json().catch(() => null);
const arr = Array.isArray(raw?.data) ? raw.data : (Array.isArray(raw) ? raw : []);
console.info('[VAT] getStandardVatRate parsed length:', Array.isArray(arr) ? arr.length : 0);
if (!Array.isArray(arr) || arr.length === 0) return null;
const upper = countryCode.toUpperCase();
const match = arr.find((r: any) => getCode(r) === upper);
const normalized = match ? getRateNormalized(match) : null;
console.info('[VAT] getStandardVatRate match:', {
upper,
resolvedCode: match ? getCode(match) : null,
rawRate: match ? getRateRaw(match) : null,
normalized
});
return normalized;
} catch (e) {
console.error('[VAT] getStandardVatRate error:', e);
return null;
}
}
export type VatRateEntry = { code: string; rate: number | null }
export async function getVatRates(): Promise<VatRateEntry[]> {
try {
const url = `${process.env.NEXT_PUBLIC_API_BASE_URL}/api/tax/vat-rates`;
console.info('[VAT] getVatRates -> GET', url);
const res = await authFetch(url, { method: 'GET' });
console.info('[VAT] getVatRates status:', res.status);
if (!res.ok) return [];
const raw = await res.json().catch(() => null);
const arr = Array.isArray(raw?.data) ? raw.data : (Array.isArray(raw) ? raw : []);
console.info('[VAT] getVatRates parsed length:', Array.isArray(arr) ? arr.length : 0);
if (!Array.isArray(arr) || arr.length === 0) return [];
const mapped = arr.map((r: any) => ({
code: getCode(r),
rate: getRateNormalized(r)
})).filter((r: VatRateEntry) => !!r.code);
console.info('[VAT] getVatRates mapped sample:', mapped.slice(0, 5));
return mapped;
} catch (e) {
console.error('[VAT] getVatRates error:', e);
return [];
}
}