From 470cdb8b029d32bfda1cd1fa46ad1bf8b34ffa6b Mon Sep 17 00:00:00 2001 From: ValdiANS Date: Mon, 17 Nov 2025 14:56:25 +0700 Subject: [PATCH] chore(FE-199): create Expense dummy data --- src/services/api/expense.ts | 1213 +++++++++++++++++++++++++++++------ 1 file changed, 1016 insertions(+), 197 deletions(-) diff --git a/src/services/api/expense.ts b/src/services/api/expense.ts index 92e87c43..24931316 100644 --- a/src/services/api/expense.ts +++ b/src/services/api/expense.ts @@ -1,200 +1,738 @@ +import axios from 'axios'; import { sleep } from '@/lib/helper'; import { BaseApiService } from '@/services/api/base'; -import { BaseApiResponse } from '@/types/api/api-general'; +import { BaseApiResponse, CreatedUser } from '@/types/api/api-general'; import { CreateExpensePayload, Expense } from '@/types/api/expense'; +import { httpClient } from '@/services/http/client'; -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', +import { BaseArea } from '@/types/api/master-data/area'; +import { BaseLocation, Location } from '@/types/api/master-data/location'; +import { Kandang } from '@/types/api/master-data/kandang'; +import { BaseSupplier, Supplier } from '@/types/api/master-data/supplier'; +import { Nonstock } from '@/types/api/master-data/nonstock'; +import { resourceUsage } from 'process'; +// Shared base objects +const adminUser: CreatedUser = { 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', - }, - ], - }, - ], + id_user: 1, + email: 'admin@example.com', + name: 'Admin User', }; +const managerAreaUser: CreatedUser = { + id: 200, + id_user: 200, + email: 'manager.area@example.com', + name: 'Manager Area', +}; + +const headFinanceUser: CreatedUser = { + id: 300, + id_user: 300, + email: 'head.finance@example.com', + name: 'Head Finance', +}; + +const financeStaffUser: CreatedUser = { + id: 400, + id_user: 400, + email: 'finance.staff@example.com', + name: 'Finance Staff', +}; + +const auditUser: CreatedUser = { + id: 500, + id_user: 500, + email: 'internal.audit@example.com', + name: 'Internal Audit', +}; + +const areaUtara: BaseArea = { + id: 1, + name: 'Area Utara', +}; + +const areaSelatan: BaseArea = { + id: 2, + name: 'Area Selatan', +}; + +const baseLocationA: BaseLocation = { + id: 1, + name: 'Singaparna', + address: 'Jl. Kebun Raya 12', + area: areaUtara, +}; + +const baseLocationB: BaseLocation = { + id: 2, + name: 'Cikaum', + address: 'Jl. Melati 20', + area: areaSelatan, +}; + +const locationA: Location = { + ...baseLocationA, + created_user: adminUser, + created_at: '2025-01-01T00:00:00Z', + updated_at: '2025-01-01T00:00:00Z', +}; + +const locationB: Location = { + ...baseLocationB, + created_user: adminUser, + created_at: '2025-01-05T00:00:00Z', + updated_at: '2025-01-05T00:00:00Z', +}; + +const kandangA1: Kandang = { + id: 1, + name: 'Singaparna 1', + status: 'ACTIVE', + capacity: 5000, + location: baseLocationA, + pic: { + id: 101, + id_user: 101, + email: 'abkA1@example.com', + name: 'ABK A1', + }, + created_user: adminUser, + created_at: '2024-12-10T00:00:00Z', + updated_at: '2024-12-10T00:00:00Z', +}; + +const kandangA2: Kandang = { + id: 2, + name: 'Singaparna 2', + status: 'ACTIVE', + capacity: 4500, + location: baseLocationA, + pic: { + id: 102, + id_user: 102, + email: 'abkA2@example.com', + name: 'ABK A2', + }, + created_user: adminUser, + created_at: '2024-12-12T00:00:00Z', + updated_at: '2024-12-12T00:00:00Z', +}; + +const kandangB1: Kandang = { + id: 21, + name: 'Kandang B1', + status: 'ACTIVE', + capacity: 3800, + location: baseLocationB, + pic: { + id: 201, + id_user: 201, + email: 'abkB1@example.com', + name: 'ABK B1', + }, + created_user: adminUser, + created_at: '2024-12-15T00:00:00Z', + updated_at: '2024-12-15T00:00:00Z', +}; + +const baseSupplierPakan: BaseSupplier = { + id: 1, + name: 'PT CHAROEN POKPHAND INDONESIA Tbk', + alias: 'PPJ', + pic: 'Budi', + type: 'Pakan', + category: 'PAKAN', + hatchery: '-', + phone: '08121234567', + email: 'pakan@example.com', + address: 'Jl. Raya Pakan 88', + npwp: '1234567890', + account_number: '111-222-333', + due_date: 30, + balance: 5000000, +}; + +const baseSupplierObat: BaseSupplier = { + id: 502, + name: 'CV Obat Sehat', + alias: 'COS', + pic: 'Susi', + type: 'Obat', + category: 'OBAT', + hatchery: '-', + phone: '085612345678', + email: 'cos@example.com', + address: 'Jl. Obat Raya 10', + npwp: '987654321', + account_number: '222-333-444', + due_date: 14, +}; + +const supplierPakan: Supplier = { + ...baseSupplierPakan, + created_user: adminUser, + created_at: '2025-01-01T00:00:00Z', + updated_at: '2025-01-01T00:00:00Z', +}; + +const supplierObat: Supplier = { + ...baseSupplierObat, + created_user: adminUser, + created_at: '2025-01-02T00:00:00Z', + updated_at: '2025-01-02T00:00:00Z', +}; + +const nonstockPakanStarter: Nonstock = { + id: 3001, + name: 'Pakan Ayam Starter', + uom_id: 1, + uom: { id: 1, name: 'KG' }, + suppliers: [baseSupplierPakan], + flags: ['PAKAN', 'STARTER'], + created_user: adminUser, + created_at: '2025-01-10T00:00:00Z', + updated_at: '2025-01-10T00:00:00Z', +}; + +const nonstockPakanFinisher: Nonstock = { + id: 3002, + name: 'Pakan Ayam Finisher', + uom_id: 1, + uom: { id: 1, name: 'KG' }, + suppliers: [baseSupplierPakan], + flags: ['PAKAN', 'FINISHER'], + created_user: adminUser, + created_at: '2025-01-11T00:00:00Z', + updated_at: '2025-01-11T00:00:00Z', +}; + +const nonstockObat: Nonstock = { + id: 3101, + name: 'Obat Antibiotik A', + uom_id: 2, + uom: { id: 2, name: 'BOTOL' }, + suppliers: [baseSupplierObat], + flags: ['OBAT'], + created_user: adminUser, + created_at: '2025-01-12T00:00:00Z', + updated_at: '2025-01-12T00:00:00Z', +}; + +const nonstockVitamin: Nonstock = { + id: 3102, + name: 'Vitamin Ayam B-Complex', + uom_id: 2, + uom: { id: 2, name: 'BOTOL' }, + suppliers: [baseSupplierObat], + flags: ['VITAMIN'], + created_user: adminUser, + created_at: '2025-01-13T00:00:00Z', + updated_at: '2025-01-13T00:00:00Z', +}; + +export const DUMMY_EXPENSE: Expense[] = [ + // STEP 1 - Pengajuan (OK) + { + id: 1, + reference_number: 'REF-EXP-0001', + po_number: 'PO-STEP1-OK', + created_user: adminUser, + created_at: '2025-02-10T08:00:00Z', + updated_at: '2025-02-10T08:00:00Z', + + location: locationA, + transaction_date: '2025-02-10', + + kandangs: [kandangA1, kandangA2], + vendor: supplierPakan, + request_documents: [ + { + name: 'pengajuan_step1_ok.pdf', + url: 'https://example.com/pengajuan_step1_ok.pdf', + }, + ], + kandang_expenses: [ + { + kandang: kandangA1, + expenses: [ + { + nonstock: nonstockPakanStarter, + total_quantity: 100, + total_expense: 1500000, + }, + ], + }, + { + kandang: kandangA2, + expenses: [ + { + nonstock: nonstockPakanFinisher, + total_quantity: 80, + total_expense: 1200000, + }, + ], + }, + ], + nominal: 2700000, + paid: 0, + remaining_cost: 2700000, + + approval: { + step_number: 1, + step_name: 'Pengajuan', + action: 'SUBMITTED', + notes: 'Pengajuan pakan untuk kandang A1 dan A2.', + action_by: adminUser, + action_at: '2025-02-10T08:05:00Z', + }, + }, + + // STEP 1 - Pengajuan (REJECTED) + { + id: 2, + reference_number: 'REF-EXP-0002', + po_number: 'PO-STEP1-REJECT', + created_user: adminUser, + created_at: '2025-02-11T09:00:00Z', + updated_at: '2025-02-11T09:15:00Z', + + location: locationA, + transaction_date: '2025-02-11', + + kandangs: [kandangA1], + vendor: supplierPakan, + request_documents: [], + kandang_expenses: [ + { + kandang: kandangA1, + expenses: [ + { + nonstock: nonstockPakanFinisher, + total_quantity: 300, + total_expense: 4500000, + }, + ], + }, + ], + nominal: 4500000, + paid: 0, + remaining_cost: 4500000, + + approval: { + step_number: 1, + step_name: 'Pengajuan', + action: 'REJECTED', + notes: 'Jumlah terlalu besar untuk pengajuan awal.', + action_by: managerAreaUser, + action_at: '2025-02-11T09:15:00Z', + }, + }, + + // STEP 2 - Approval Manager Area (APPROVED) + { + id: 3, + reference_number: 'REF-EXP-0003', + po_number: 'PO-STEP2-OK', + created_user: adminUser, + created_at: '2025-02-12T07:30:00Z', + updated_at: '2025-02-12T08:30:00Z', + + location: locationA, + transaction_date: '2025-02-12', + + kandangs: [kandangA1, kandangA2], + vendor: supplierPakan, + request_documents: [ + { + name: 'pengajuan_step2_ok.pdf', + url: 'https://example.com/pengajuan_step2_ok.pdf', + }, + ], + kandang_expenses: [ + { + kandang: kandangA1, + expenses: [ + { + nonstock: nonstockPakanStarter, + total_quantity: 120, + total_expense: 1800000, + notes: + 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Non eveniet quos aspernatur magnam mollitia consequatur dolore natus amet libero enim?', + }, + { + nonstock: nonstockPakanFinisher, + total_quantity: 50, + total_expense: 750000, + }, + ], + }, + { + kandang: kandangA2, + expenses: [ + { + nonstock: nonstockPakanStarter, + total_quantity: 60, + total_expense: 900000, + }, + ], + }, + ], + nominal: 3450000, + paid: 0, + remaining_cost: 3450000, + + approval: { + step_number: 2, + step_name: 'Approval Manager Area', + action: 'APPROVED', + notes: 'Disetujui, kebutuhan pakan sesuai rencana.', + action_by: managerAreaUser, + action_at: '2025-02-12T08:30:00Z', + }, + }, + + // STEP 2 - Approval Manager Area (REJECTED) + { + id: 4, + reference_number: 'REF-EXP-0004', + created_user: adminUser, + created_at: '2025-02-13T10:00:00Z', + updated_at: '2025-02-13T10:20:00Z', + + location: locationB, + transaction_date: '2025-02-13', + + kandangs: [kandangB1], + vendor: supplierPakan, + request_documents: [], + kandang_expenses: [ + { + kandang: kandangB1, + expenses: [ + { + nonstock: nonstockPakanFinisher, + total_quantity: 400, + total_expense: 6000000, + }, + ], + }, + ], + nominal: 6000000, + paid: 0, + remaining_cost: 6000000, + + approval: { + step_number: 2, + step_name: 'Approval Manager Area', + action: 'REJECTED', + notes: 'Tidak sesuai rencana kebutuhan area Selatan.', + action_by: managerAreaUser, + action_at: '2025-02-13T10:20:00Z', + }, + }, + + // STEP 3 - Approval Finance (APPROVED) + { + id: 5, + reference_number: 'REF-EXP-0005', + po_number: 'PO-STEP3-OK', + created_user: adminUser, + created_at: '2025-02-14T09:00:00Z', + updated_at: '2025-02-14T09:30:00Z', + + location: locationB, + transaction_date: '2025-02-14', + + kandangs: [kandangB1], + vendor: supplierObat, + request_documents: [ + { + name: 'pengajuan_step3_ok.pdf', + url: 'https://example.com/pengajuan_step3_ok.pdf', + }, + ], + kandang_expenses: [ + { + kandang: kandangB1, + expenses: [ + { + nonstock: nonstockObat, + total_quantity: 10, + total_expense: 700000, + }, + { + nonstock: nonstockVitamin, + total_quantity: 5, + total_expense: 250000, + }, + ], + }, + ], + nominal: 950000, + paid: 0, + remaining_cost: 950000, + + approval: { + step_number: 3, + step_name: 'Approval Finance', + action: 'APPROVED', + notes: 'Budget tersedia untuk obat & vitamin.', + action_by: headFinanceUser, + action_at: '2025-02-14T09:30:00Z', + }, + }, + + // STEP 3 - Approval Finance (REJECTED) + { + id: 6, + reference_number: 'REF-EXP-0006', + created_user: adminUser, + created_at: '2025-02-15T11:00:00Z', + updated_at: '2025-02-15T11:30:00Z', + + location: locationB, + transaction_date: '2025-02-15', + + kandangs: [kandangB1], + vendor: supplierObat, + request_documents: [], + kandang_expenses: [ + { + kandang: kandangB1, + expenses: [ + { + nonstock: nonstockObat, + total_quantity: 60, + total_expense: 4200000, + }, + ], + }, + ], + nominal: 4200000, + paid: 0, + remaining_cost: 4200000, + + approval: { + step_number: 3, + step_name: 'Approval Finance', + action: 'REJECTED', + notes: 'Melebihi plafon budget obat bulan ini.', + action_by: headFinanceUser, + action_at: '2025-02-15T11:30:00Z', + }, + }, + + // STEP 4 - Realisasi (IN_PROGRESS) + { + id: 7, + reference_number: 'REF-EXP-0007', + po_number: 'PO-STEP4-OK', + created_user: adminUser, + created_at: '2025-02-16T08:00:00Z', + updated_at: '2025-02-16T12:00:00Z', + + location: locationA, + transaction_date: '2025-02-16', + realization_date: '2025-02-17', + + kandangs: [kandangA1, kandangA2], + vendor: supplierPakan, + request_documents: [ + { + name: 'do_step4_ok.pdf', + url: 'https://example.com/do_step4_ok.pdf', + }, + ], + kandang_expenses: [ + { + kandang: kandangA1, + expenses: [ + { + nonstock: nonstockPakanStarter, + total_quantity: 70, + total_expense: 1050000, + }, + ], + }, + { + kandang: kandangA2, + expenses: [ + { + nonstock: nonstockPakanFinisher, + total_quantity: 40, + total_expense: 600000, + }, + ], + }, + ], + nominal: 1650000, + paid: 500000, + remaining_cost: 1150000, + + approval: { + step_number: 4, + step_name: 'Realisasi', + action: 'IN_PROGRESS', + notes: 'Barang diterima, pembayaran sebagian.', + action_by: financeStaffUser, + action_at: '2025-02-16T12:00:00Z', + }, + }, + + // STEP 4 - Realisasi (REJECTED) + { + id: 8, + reference_number: 'REF-EXP-0008', + created_user: adminUser, + created_at: '2025-02-17T09:00:00Z', + updated_at: '2025-02-17T09:45:00Z', + + location: locationA, + transaction_date: '2025-02-17', + + kandangs: [kandangA1], + vendor: supplierPakan, + request_documents: [ + { + name: 'invoice_step4_reject.pdf', + url: 'https://example.com/invoice_step4_reject.pdf', + }, + ], + kandang_expenses: [ + { + kandang: kandangA1, + expenses: [ + { + nonstock: nonstockPakanStarter, + total_quantity: 50, + total_expense: 750000, + }, + ], + }, + ], + nominal: 750000, + paid: 0, + remaining_cost: 750000, + + approval: { + step_number: 4, + step_name: 'Realisasi', + action: 'REJECTED', + notes: 'Dokumen realisasi tidak sesuai PO.', + action_by: financeStaffUser, + action_at: '2025-02-17T09:45:00Z', + }, + }, + + // STEP 5 - Selesai (DONE) + { + id: 9, + reference_number: 'REF-EXP-0009', + po_number: 'PO-STEP5-OK', + created_user: adminUser, + created_at: '2025-02-18T08:00:00Z', + updated_at: '2025-02-20T15:00:00Z', + + location: locationB, + transaction_date: '2025-02-18', + realization_date: '2025-02-19', + + kandangs: [kandangB1], + vendor: supplierObat, + request_documents: [ + { + name: 'invoice_step5_ok.pdf', + url: 'https://example.com/invoice_step5_ok.pdf', + }, + { + name: 'bukti_transfer_step5_ok.pdf', + url: 'https://example.com/bukti_transfer_step5_ok.pdf', + }, + ], + kandang_expenses: [ + { + kandang: kandangB1, + expenses: [ + { + nonstock: nonstockObat, + total_quantity: 20, + total_expense: 1400000, + }, + ], + }, + ], + nominal: 1400000, + paid: 1400000, + remaining_cost: 0, + + approval: { + step_number: 5, + step_name: 'Selesai', + action: 'DONE', + notes: 'Proses selesai, sudah lunas.', + action_by: financeStaffUser, + action_at: '2025-02-20T15:00:00Z', + }, + }, + + // STEP 5 - Selesai (REJECTED by audit) + { + id: 10, + reference_number: 'REF-EXP-0010', + created_user: adminUser, + created_at: '2025-02-19T09:00:00Z', + updated_at: '2025-02-21T10:30:00Z', + + location: locationA, + transaction_date: '2025-02-19', + + kandangs: [kandangA1, kandangA2], + vendor: supplierPakan, + request_documents: [ + { + name: 'invoice_step5_recheck.pdf', + url: 'https://example.com/invoice_step5_recheck.pdf', + }, + ], + kandang_expenses: [ + { + kandang: kandangA1, + expenses: [ + { + nonstock: nonstockPakanStarter, + total_quantity: 60, + total_expense: 900000, + }, + ], + }, + { + kandang: kandangA2, + expenses: [ + { + nonstock: nonstockPakanFinisher, + total_quantity: 40, + total_expense: 600000, + }, + ], + }, + ], + nominal: 1500000, + paid: 1500000, + remaining_cost: 0, + + approval: { + step_number: 5, + step_name: 'Selesai', + action: 'REJECTED', + notes: 'Dibatalkan saat audit akhir, terdapat perbedaan kuantitas.', + action_by: auditUser, + action_at: '2025-02-21T10:30:00Z', + }, + }, +]; + export class ExpenseApiService extends BaseApiService< Expense, FormData, @@ -204,6 +742,46 @@ export class ExpenseApiService extends BaseApiService< super(basePath); } + // TODO: remove dummy data and integrate to real API + override async getAllFetcher( + endpoint: string + ): Promise> { + // return await httpClientFetcher>(endpoint); + + await sleep(750); + + return { + code: 200, + status: 'success', + message: 'Successfully get all expense data!', + meta: { + page: 1, + limit: 10, + total_pages: 1, + total_results: 8, + }, + data: DUMMY_EXPENSE, + }; + } + + // TODO: remove this and integrate to real API + async getSingle(id: number): Promise | undefined> { + await sleep(1000); + + return { + code: 200, + status: 'success', + message: 'Successfully get expense data!', + meta: { + page: 1, + limit: 10, + total_pages: 1, + total_results: 8, + }, + data: DUMMY_EXPENSE[id - 1], + }; + } + // TODO: remove this and integrate to real API async create( payload: FormData @@ -221,10 +799,258 @@ export class ExpenseApiService extends BaseApiService< code: 200, status: 'success', message: 'Berhasil membuat pengajuan biaya operasional!', - data: DUMMY_EXPENSE, + data: DUMMY_EXPENSE[0], }; } + // TODO: remove this and integrate to real API + async update( + id: number, + 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 mengubah pengajuan biaya operasional!', + data: DUMMY_EXPENSE[0], + }; + } + + // TODO: remove this and integrate to real API + async delete(id: number): Promise { + await sleep(1000); + + return { + code: 200, + status: 'success', + message: 'Successfully delete expense data!', + data: { + id, + }, + }; + } + + // TODO: remove this and integrate to real API + async uploadRequestDocuments( + id: number, + files: File[] + ): Promise { + try { + // const requestDocumentsFormData = new FormData(); + + // // request_documents (array of File) + // files.forEach((file, index) => { + // requestDocumentsFormData.append(`request_documents[${index}]`, file); + // }); + + // const uploadRequestDocumentsRes = await httpClient( + // this.basePath, + // { + // method: 'POST', + // body: requestDocumentsFormData, + // } + // ); + + // return uploadRequestDocumentsRes; + + await sleep(1000); + + return { + code: 200, + status: 'success', + message: 'Berhasil menambahkan dokumen pengajuan!', + data: null, + }; + } catch (error) { + if (axios.isAxiosError(error)) { + return error.response?.data; + } + + return undefined; + } + } + + // TODO: integrate to real API + async approve( + id: number, + notes?: string + ): Promise | undefined> { + try { + // const approveRes = await httpClient>( + // `${this.basePath}/approvals`, + // { + // method: 'POST', + // body: { + // action: 'APPROVED', + // approvable_ids: [id], + // notes: notes, + // }, + // } + // ); + // + // return approveRes; + + await sleep(1000); + + return { + code: 200, + status: 'success', + message: 'Successfully approve expense data!', + meta: { + page: 1, + limit: 10, + total_pages: 1, + total_results: 1, + }, + data: DUMMY_EXPENSE[id - 1], + }; + } catch (error) { + if (axios.isAxiosError>(error)) { + return error.response?.data; + } + + return undefined; + } + } + + // TODO: integrate to real API + async bulkApprove( + ids: number[], + notes?: string + ): Promise | undefined> { + try { + // const approveRes = await httpClient>( + // `${this.basePath}/approvals`, + // { + // method: 'POST', + // body: { + // action: 'APPROVED', + // approvable_ids: ids, + // notes: notes, + // }, + // } + // ); + // + // return approveRes; + + await sleep(1000); + + return { + code: 200, + status: 'success', + message: 'Successfully bulk approve expense data!', + meta: { + page: 1, + limit: 10, + total_pages: 1, + total_results: 1, + }, + data: DUMMY_EXPENSE[ids[0] - 1], + }; + } catch (error) { + if (axios.isAxiosError>(error)) { + return error.response?.data; + } + + return undefined; + } + } + + // TODO: integrate to real API + async reject( + id: number, + notes?: string + ): Promise | undefined> { + try { + // const rejectRes = await httpClient>( + // `${this.basePath}/approvals`, + // { + // method: 'POST', + // body: { + // action: 'REJECTED', + // approvable_ids: [id], + // notes: notes, + // }, + // } + // ); + // + // return rejectRes; + + await sleep(1000); + + return { + code: 200, + status: 'success', + message: 'Successfully reject expense data!', + meta: { + page: 1, + limit: 10, + total_pages: 1, + total_results: 1, + }, + data: DUMMY_EXPENSE[id - 1], + }; + } catch (error) { + if (axios.isAxiosError>(error)) { + return error.response?.data; + } + + return undefined; + } + } + + // TODO: integrate to real API + async bulkReject( + ids: number[], + notes?: string + ): Promise | undefined> { + try { + // const rejectRes = await httpClient>( + // `${this.basePath}/approvals`, + // { + // method: 'POST', + // body: { + // action: 'REJECTED', + // approvable_ids: ids, + // notes: notes, + // }, + // } + // ); + // + // return rejectRes; + + await sleep(1000); + + return { + code: 200, + status: 'success', + message: 'Successfully bulk reject expense data!', + meta: { + page: 1, + limit: 10, + total_pages: 1, + total_results: 1, + }, + data: DUMMY_EXPENSE[ids[0] - 1], + }; + } catch (error) { + if (axios.isAxiosError>(error)) { + return error.response?.data; + } + + return undefined; + } + } + convertPayloadToFormData = (payload: CreateExpensePayload) => { const formData = new FormData(); @@ -274,10 +1100,3 @@ export class ExpenseApiService extends BaseApiService< } export const ExpenseApi = new ExpenseApiService('/expense'); - -// TODO: remove this ASAP -// export const ExpenseApi = new BaseApiService< -// Expense, -// CreateExpensePayload, -// UpdateExpensePayload -// >('/master-data/uoms');