From e4b61cfe050347fe2ba42478e801f08799966d79 Mon Sep 17 00:00:00 2001 From: ValdiANS Date: Thu, 6 Nov 2025 15:30:22 +0700 Subject: [PATCH] chore(FE-199): create Expense API service with dummy data --- src/services/api/expense.ts | 290 ++++++++++++++++++++++++++++++++++-- 1 file changed, 277 insertions(+), 13 deletions(-) diff --git a/src/services/api/expense.ts b/src/services/api/expense.ts index ec42743c..92e87c43 100644 --- a/src/services/api/expense.ts +++ b/src/services/api/expense.ts @@ -1,19 +1,283 @@ +import { sleep } from '@/lib/helper'; import { BaseApiService } from '@/services/api/base'; -import { - CreateExpensePayload, - Expense, - UpdateExpensePayload, -} from '@/types/api/expense'; +import { BaseApiResponse } from '@/types/api/api-general'; +import { CreateExpensePayload, Expense } from '@/types/api/expense'; +const DUMMY_EXPENSE: Expense = { + created_user: { + id: 1, + id_user: 101, + email: 'admin@example.com', + name: 'Admin User', + }, + created_at: '2025-11-05T10:30:00Z', + updated_at: '2025-11-05T12:00:00Z', + + id: 1, + location: { + id: 10, + name: 'Farm A', + address: 'Jl. Raya Peternakan No. 45, Bandung', + area: { + id: 100, + name: 'Jawa Barat', + }, + created_user: { + id: 2, + id_user: 102, + email: 'manager@example.com', + name: 'Farm Manager', + }, + created_at: '2025-10-01T08:00:00Z', + updated_at: '2025-10-05T09:30:00Z', + }, + transaction_date: '2025-11-04', + + kandangs: [ + { + id: 201, + name: 'Kandang 1', + status: 'ACTIVE', + location: { + id: 10, + name: 'Farm A', + address: 'Jl. Raya Peternakan No. 45, Bandung', + area: { id: 100, name: 'Jawa Barat' }, + }, + pic: { + id: 3, + id_user: 103, + email: 'kandang1@example.com', + name: 'PIC Kandang 1', + }, + created_user: { + id: 4, + id_user: 104, + email: 'creator@example.com', + name: 'Creator User', + }, + created_at: '2025-10-10T08:00:00Z', + updated_at: '2025-10-20T09:00:00Z', + }, + ], + + vendor: { + id: 301, + name: 'PT. Pakan Makmur', + alias: 'PakanMakmur', + pic: 'Budi Santoso', + type: 'Supplier', + category: 'Pakan', + hatchery: 'Makmur Hatchery', + phone: '08123456789', + email: 'contact@pakanmakmur.com', + address: 'Jl. Industri No. 5, Bekasi', + npwp: '12.345.678.9-012.345', + account_number: '1234567890', + due_date: 30, + balance: 5000000, + created_user: { + id: 5, + id_user: 105, + email: 'finance@example.com', + name: 'Finance User', + }, + created_at: '2025-09-01T09:00:00Z', + updated_at: '2025-09-15T10:00:00Z', + }, + + request_documents: [ + { + name: 'invoice_001.pdf', + url: 'https://example.com/files/invoice_001.pdf', + }, + { + name: 'receipt_001.jpg', + url: 'https://example.com/files/receipt_001.jpg', + }, + ], + + kandang_expenses: [ + { + kandang: { + id: 201, + name: 'Kandang 1', + status: 'ACTIVE', + location: { + id: 10, + name: 'Farm A', + address: 'Jl. Raya Peternakan No. 45, Bandung', + area: { id: 100, name: 'Jawa Barat' }, + }, + pic: { + id: 3, + id_user: 103, + email: 'kandang1@example.com', + name: 'PIC Kandang 1', + }, + created_user: { + id: 4, + id_user: 104, + email: 'creator@example.com', + name: 'Creator User', + }, + created_at: '2025-10-10T08:00:00Z', + updated_at: '2025-10-20T09:00:00Z', + }, + expenses: [ + { + nonstock: { + id: 501, + name: 'Pakan Ayam Broiler', + uom_id: 1, + uom: { + id: 1, + name: 'Kg', + }, + suppliers: [ + { + id: 301, + name: 'PT. Pakan Makmur', + alias: 'PakanMakmur', + pic: 'Budi Santoso', + type: 'Supplier', + category: 'Pakan', + hatchery: 'Makmur Hatchery', + phone: '08123456789', + email: 'contact@pakanmakmur.com', + address: 'Jl. Industri No. 5, Bekasi', + npwp: '12.345.678.9-012.345', + account_number: '1234567890', + due_date: 30, + balance: 5000000, + }, + ], + flags: ['PAKAN', 'IS_ACTIVE'], + created_user: { + id: 6, + id_user: 106, + email: 'staff@example.com', + name: 'Inventory Staff', + }, + created_at: '2025-09-25T08:00:00Z', + updated_at: '2025-09-30T09:00:00Z', + }, + total_quantity: 500, + total_expense: 2500000, + notes: 'Pakan untuk minggu pertama', + }, + { + nonstock: { + id: 502, + name: 'Vitamin C Ayam', + uom_id: 2, + uom: { + id: 2, + name: 'Botol', + }, + suppliers: [], + flags: ['VITAMIN', 'IS_ACTIVE'], + created_user: { + id: 6, + id_user: 106, + email: 'staff@example.com', + name: 'Inventory Staff', + }, + created_at: '2025-09-25T08:00:00Z', + updated_at: '2025-09-30T09:00:00Z', + }, + total_quantity: 20, + total_expense: 400000, + notes: 'Untuk menjaga daya tahan ayam', + }, + ], + }, + ], +}; + +export class ExpenseApiService extends BaseApiService< + Expense, + FormData, + FormData +> { + constructor(basePath: string) { + super(basePath); + } + + // TODO: remove this and integrate to real API + async create( + payload: FormData + ): Promise | undefined> { + await sleep(750); + + const sentPayload = new Map(); + for (const pair of payload.entries()) { + sentPayload.set(pair[0], pair[1]); + } + + console.log({ sentPayload }); + + return { + code: 200, + status: 'success', + message: 'Berhasil membuat pengajuan biaya operasional!', + data: DUMMY_EXPENSE, + }; + } + + convertPayloadToFormData = (payload: CreateExpensePayload) => { + const formData = new FormData(); + + formData.append('locationId', String(payload.locationId)); + formData.append('transaction_date', payload.transaction_date); + formData.append('vendorId', String(payload.vendorId)); + + // kandangIds (array) + payload.kandangIds.forEach((id, index) => { + formData.append(`kandangIds[${index}]`, String(id)); + }); + + // request_documents (array of File) + payload.request_documents.forEach((file, index) => { + formData.append(`request_documents[${index}]`, file); + }); + + // kandang_expenses (nested array) + payload.kandang_expenses.forEach((kandangExpense, kandangIndex) => { + formData.append( + `kandang_expenses[${kandangIndex}][kandangId]`, + String(kandangExpense.kandangId) + ); + + kandangExpense.expenses.forEach((expenseItem, expenseIndex) => { + formData.append( + `kandang_expenses[${kandangIndex}][expenses][${expenseIndex}][nonstockId]`, + String(expenseItem.nonstockId) + ); + formData.append( + `kandang_expenses[${kandangIndex}][expenses][${expenseIndex}][total_quantity]`, + String(expenseItem.total_quantity) + ); + formData.append( + `kandang_expenses[${kandangIndex}][expenses][${expenseIndex}][total_expense]`, + String(expenseItem.total_expense) + ); + formData.append( + `kandang_expenses[${kandangIndex}][expenses][${expenseIndex}][notes]`, + expenseItem.notes ?? '' + ); + }); + }); + + return formData; + }; +} + +export const ExpenseApi = new ExpenseApiService('/expense'); + +// TODO: remove this ASAP // export const ExpenseApi = new BaseApiService< // Expense, // CreateExpensePayload, // UpdateExpensePayload -// >('/expense'); - -// TODO: remove this ASAP -export const ExpenseApi = new BaseApiService< - Expense, - CreateExpensePayload, - UpdateExpensePayload ->('/master-data/uoms'); +// >('/master-data/uoms');