import { api } from "src/boot/axios"; import { isProxy, toRaw } from "vue"; import { normalizeExpense, validateExpenseUI } from "../../utils/expenses-validators"; import type { ExpenseType } from "../../types/expense.types"; import { ExpensesApiError } from "../../types/expense-validation.interface"; import type { ExpensePayload, PayPeriodExpenses, TimesheetExpense, UpsertExpensesBody, UpsertExpensesResponse } from "../../types/expense.interfaces"; /* eslint-disable */ const toPlain = (obj:T): T => { const raw = isProxy(obj) ? toRaw(obj) : obj; if( typeof (globalThis as any).structuredClone === 'function') { return (globalThis as any).structuredClone(raw); } return JSON.parse(JSON.stringify(raw)); }; const normalizePayload = (expense: ExpensePayload): ExpensePayload => { const exp = normalizeExpense(expense as unknown as TimesheetExpense); const out: ExpensePayload = { date: exp.date, type: exp.type as ExpenseType, comment: exp.comment || '', }; if(typeof exp.amount === 'number') out.amount = exp.amount; if(typeof exp.mileage === 'number') out.mileage = exp.mileage; return out; } //GET by email, year and period no export const getPayPeriodExpenses = async ( email: string, pay_year: number, pay_period_no: number ) : Promise => { const encoded_email = encodeURIComponent(email); const encoded_year = encodeURIComponent(String(pay_year)); const encoded_pay_period_no = encodeURIComponent(String(pay_period_no)); try { const { data } = await api.get(`/expenses/${encoded_email}/${encoded_year}/${encoded_pay_period_no}`); const items = Array.isArray(data.expenses) ? data.expenses.map(normalizeExpense) : []; return { ...data, expenses: items, }; } catch(err:any) { const status_code: number = err?.response?.status ?? 500; const data = err?.response?.data ?? {}; throw new ExpensesApiError({ status_code, error_code: data.error_code, message: data.message || data.error || err.message, context: data.context, }); } }; //PUT by email, year and period no export const putPayPeriodExpenses = async ( email: string, pay_year: number, pay_period_no: number, expenses: TimesheetExpense[] ): Promise => { const encoded_email = encodeURIComponent(email); const encoded_year = encodeURIComponent(String(pay_year)); const encoded_pay_period_no = encodeURIComponent(String(pay_period_no)); const plain = Array.isArray(expenses) ? expenses.map(toPlain): []; const normalized: ExpensePayload[] = plain.map((exp) => { const norm = normalizeExpense(exp as TimesheetExpense); validateExpenseUI(norm, 'expense_item'); return normalizePayload(norm as unknown as ExpensePayload); }); const body: UpsertExpensesBody = {expenses: normalized}; try { const { data } = await api.put( `/expenses/${encoded_email}/${encoded_year}/${encoded_pay_period_no}`, body, { headers: {'Content-Type': 'application/json'}} ); const items = Array.isArray(data?.data?.expenses) ? data.data.expenses.map(normalizeExpense) : []; return { ...(data?.data ?? { pay_period_no, pay_year, employee_email: email, is_approved: false, expenses: [], totals: {amount: 0, mileage: 0}, }), expenses: items, }; } catch (err: any) { const status_code: number = err?.response?.status ?? 500; const data = err?.response?.data ?? {}; throw new ExpensesApiError({ status_code, error_code: data.error_code, message: data.message || data.error || err.message, context: data.context, }); } }; export const postPayPeriodExpenses = async ( email: string, pay_year: number, pay_period_no: number, new_expenses: TimesheetExpense[] ): Promise => { const encoded_email = encodeURIComponent(email); const encoded_year = encodeURIComponent(String(pay_year)); const encoded_pp = encodeURIComponent(String(pay_period_no)); const plain = Array.isArray(new_expenses) ? new_expenses.map(toPlain) : []; const normalized: ExpensePayload[] = plain.map((exp) => { const norm = normalizeExpense(exp as TimesheetExpense); validateExpenseUI(norm, 'expense_item'); return normalizePayload(norm as unknown as ExpensePayload); }); const body: UpsertExpensesBody = { expenses: normalized }; try { const { data } = await api.post( `/expenses/${encoded_email}/${encoded_year}/${encoded_pp}`, body, { headers: { 'content-type': 'application/json' } } ); const items = Array.isArray(data?.data?.expenses) ? data.data.expenses.map(normalizeExpense) : []; return { ...(data?.data ?? { pay_period_no, pay_year, employee_email: email, is_approved: false, expenses: [], totals: { amount: 0, mileage: 0 }, }), expenses: items, }; } catch (err: any) { const status_code: number = err?.response?.status ?? 500; const data = err?.response?.data ?? {}; throw new ExpensesApiError({ status_code, error_code: data.error_code, message: data.message || data.error || err.message, context: data.context, }); } };