mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-24 23:35:45 +00:00
feat(FE-338): Slicing UI Halaman Reporting BOP & API integration & refactor debounce input: adding useEffect for sync value
This commit is contained in:
@@ -0,0 +1,627 @@
|
||||
/**
|
||||
* Dummy Data untuk Report Expense API
|
||||
*
|
||||
* File ini berisi dummy data untuk testing Report Expense API sebelum backend siap.
|
||||
*
|
||||
* Struktur data mengikuti tipe yang didefinisikan di @/types/api/report/report-expense.d.ts
|
||||
*
|
||||
* @example
|
||||
* // Menggunakan getAllFetcher dengan SWR:
|
||||
* import useSWR from 'swr';
|
||||
* import { ReportExpenseApi } from '@/services/api/report';
|
||||
*
|
||||
* const { data, error, isLoading } = useSWR(
|
||||
* ReportExpenseApi.basePath,
|
||||
* ReportExpenseApi.getAllFetcher
|
||||
* );
|
||||
*
|
||||
* if (data?.status === 'success') {
|
||||
* console.log(data.data); // Array of ReportExpense objects
|
||||
* }
|
||||
*
|
||||
* @see {@link /home/sweetpotet/Documents/projects/lti-web-client/src/types/api/report/report-expense.d.ts}
|
||||
*/
|
||||
|
||||
import { format } from 'date-fns';
|
||||
import {
|
||||
Pengajuan,
|
||||
Realisasi,
|
||||
ReportExpense,
|
||||
} from '@/types/api/report/report-expense';
|
||||
import { BaseApiResponse, CreatedUser } from '@/types/api/api-general';
|
||||
import { Supplier } from '@/types/api/master-data/supplier';
|
||||
import { Location } from '@/types/api/master-data/location';
|
||||
import { Nonstock } from '@/types/api/master-data/nonstock';
|
||||
import { Kandang } from '@/types/api/master-data/kandang';
|
||||
|
||||
// Waktu saat ini untuk created_at/updated_at
|
||||
const now = format(new Date(), 'yyyy-MM-dd HH:mm:ss');
|
||||
const today = format(new Date(), 'yyyy-MM-dd');
|
||||
const yesterday = format(
|
||||
new Date(new Date().setDate(new Date().getDate() - 1)),
|
||||
'yyyy-MM-dd'
|
||||
);
|
||||
const lastWeek = format(
|
||||
new Date(new Date().setDate(new Date().getDate() - 7)),
|
||||
'yyyy-MM-dd'
|
||||
);
|
||||
const lastMonth = format(
|
||||
new Date(new Date().setMonth(new Date().getMonth() - 1)),
|
||||
'yyyy-MM-dd'
|
||||
);
|
||||
|
||||
// ======================
|
||||
// 👤 Created User
|
||||
// ======================
|
||||
const createdUser: CreatedUser = {
|
||||
id: 1,
|
||||
id_user: 1,
|
||||
email: 'admin@example.com',
|
||||
name: 'Admin Utama',
|
||||
};
|
||||
|
||||
// ======================
|
||||
// 🏢 Supplier Dummy Data
|
||||
// ======================
|
||||
const dummySuppliers: Supplier[] = [
|
||||
{
|
||||
id: 1,
|
||||
name: 'PT. Mitra Pakan Sejahtera',
|
||||
alias: 'MPS',
|
||||
pic: 'Budi Santoso',
|
||||
type: 'Pakan',
|
||||
category: 'Supplier Utama',
|
||||
hatchery: '-',
|
||||
phone: '022-1234567',
|
||||
email: 'info@mitrapakan.com',
|
||||
address: 'Jl. Raya Industri No. 123, Bandung',
|
||||
npwp: '01.234.567.8-901.000',
|
||||
account_number: '1234567890',
|
||||
due_date: 30,
|
||||
created_user: createdUser,
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: 'CV. Sumber Ternak Jaya',
|
||||
alias: 'STJ',
|
||||
pic: 'Siti Rahayu',
|
||||
type: 'DOC',
|
||||
category: 'Supplier Utama',
|
||||
hatchery: 'Hatchery Jaya',
|
||||
phone: '021-9876543',
|
||||
email: 'contact@sumberternak.com',
|
||||
address: 'Jl. Peternakan No. 45, Jakarta',
|
||||
npwp: '02.345.678.9-012.000',
|
||||
account_number: '0987654321',
|
||||
due_date: 45,
|
||||
created_user: createdUser,
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: 'PT. Agro Veteriner Indonesia',
|
||||
alias: 'AVI',
|
||||
pic: 'Dr. Ahmad Fauzi',
|
||||
type: 'OVK',
|
||||
category: 'Supplier Utama',
|
||||
hatchery: '-',
|
||||
phone: '031-5555666',
|
||||
email: 'sales@agroveteriner.co.id',
|
||||
address: 'Jl. Kesehatan Hewan No. 78, Surabaya',
|
||||
npwp: '03.456.789.0-123.000',
|
||||
account_number: '5678901234',
|
||||
due_date: 60,
|
||||
created_user: createdUser,
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
},
|
||||
];
|
||||
|
||||
// ======================
|
||||
// 📍 Location Dummy Data
|
||||
// ======================
|
||||
const dummyLocations: Location[] = [
|
||||
{
|
||||
id: 1,
|
||||
name: 'Farm Sukajadi',
|
||||
address: 'Jl. Sukajadi No. 100, Bandung',
|
||||
area: {
|
||||
id: 1,
|
||||
name: 'Bandung Barat',
|
||||
},
|
||||
created_user: createdUser,
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: 'Farm Cihampelas',
|
||||
address: 'Jl. Cihampelas No. 200, Bandung',
|
||||
area: {
|
||||
id: 1,
|
||||
name: 'Bandung Barat',
|
||||
},
|
||||
created_user: createdUser,
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: 'Farm Pasteur',
|
||||
address: 'Jl. Pasteur No. 300, Bandung',
|
||||
area: {
|
||||
id: 2,
|
||||
name: 'Bandung Timur',
|
||||
},
|
||||
created_user: createdUser,
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
},
|
||||
];
|
||||
|
||||
// ======================
|
||||
// 📦 Nonstock Dummy Data
|
||||
// ======================
|
||||
const dummyNonstocks: Nonstock[] = [
|
||||
{
|
||||
id: 1,
|
||||
name: 'Listrik',
|
||||
uom_id: 1,
|
||||
uom: { id: 1, name: 'kWh' },
|
||||
suppliers: [],
|
||||
flags: [],
|
||||
created_user: createdUser,
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: 'Air',
|
||||
uom_id: 2,
|
||||
uom: { id: 2, name: 'm³' },
|
||||
suppliers: [],
|
||||
flags: [],
|
||||
created_user: createdUser,
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: 'Bahan Bakar',
|
||||
uom_id: 3,
|
||||
uom: { id: 3, name: 'Liter' },
|
||||
suppliers: [],
|
||||
flags: [],
|
||||
created_user: createdUser,
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: 'Pemeliharaan Kandang',
|
||||
uom_id: 4,
|
||||
uom: { id: 4, name: 'Unit' },
|
||||
suppliers: [],
|
||||
flags: [],
|
||||
created_user: createdUser,
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: 'Transportasi',
|
||||
uom_id: 5,
|
||||
uom: { id: 5, name: 'Trip' },
|
||||
suppliers: [],
|
||||
flags: [],
|
||||
created_user: createdUser,
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
},
|
||||
];
|
||||
|
||||
// ======================
|
||||
// 🏠 Kandang Dummy Data
|
||||
// ======================
|
||||
const dummyKandangs: Kandang[] = [
|
||||
{
|
||||
id: 1,
|
||||
name: 'Kandang A1',
|
||||
status: 'Aktif',
|
||||
location: dummyLocations[0],
|
||||
capacity: 5000,
|
||||
pic: {
|
||||
id_user: 1,
|
||||
id: 1,
|
||||
name: 'Budi Kandang',
|
||||
email: 'budi@example.com',
|
||||
},
|
||||
created_user: createdUser,
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: 'Kandang B1',
|
||||
status: 'Aktif',
|
||||
location: dummyLocations[1],
|
||||
capacity: 4000,
|
||||
pic: {
|
||||
id_user: 2,
|
||||
id: 2,
|
||||
name: 'Siti Kandang',
|
||||
email: 'siti@example.com',
|
||||
},
|
||||
created_user: createdUser,
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: 'Kandang C1',
|
||||
status: 'Aktif',
|
||||
location: dummyLocations[2],
|
||||
capacity: 6000,
|
||||
pic: {
|
||||
id_user: 3,
|
||||
id: 3,
|
||||
name: 'Ahmad Kandang',
|
||||
email: 'ahmad@example.com',
|
||||
},
|
||||
created_user: createdUser,
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
},
|
||||
];
|
||||
|
||||
// ======================
|
||||
// 📋 Pengajuan Dummy Data
|
||||
// ======================
|
||||
const dummyPengajuans: Pengajuan[] = [
|
||||
{
|
||||
id: 1,
|
||||
expense_id: 1,
|
||||
project_flock_kandang_id: 1,
|
||||
kandang_id: 1,
|
||||
nonstock_id: 1,
|
||||
qty: 1000,
|
||||
price: 1500,
|
||||
notes: 'Pengajuan biaya listrik bulan ini',
|
||||
nonstock: dummyNonstocks[0],
|
||||
created_at: now,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
expense_id: 2,
|
||||
project_flock_kandang_id: 2,
|
||||
kandang_id: 2,
|
||||
nonstock_id: 2,
|
||||
qty: 500,
|
||||
price: 5000,
|
||||
notes: 'Pengajuan biaya air bulan ini',
|
||||
nonstock: dummyNonstocks[1],
|
||||
created_at: now,
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
expense_id: 3,
|
||||
project_flock_kandang_id: 3,
|
||||
kandang_id: 3,
|
||||
nonstock_id: 3,
|
||||
qty: 200,
|
||||
price: 15000,
|
||||
notes: 'Pengajuan biaya bahan bakar',
|
||||
nonstock: dummyNonstocks[2],
|
||||
created_at: now,
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
expense_id: 4,
|
||||
project_flock_kandang_id: 1,
|
||||
kandang_id: 1,
|
||||
nonstock_id: 4,
|
||||
qty: 1,
|
||||
price: 5000000,
|
||||
notes: 'Pengajuan biaya pemeliharaan kandang',
|
||||
nonstock: dummyNonstocks[3],
|
||||
created_at: now,
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
expense_id: 5,
|
||||
project_flock_kandang_id: 2,
|
||||
kandang_id: 2,
|
||||
nonstock_id: 5,
|
||||
qty: 10,
|
||||
price: 500000,
|
||||
notes: 'Pengajuan biaya transportasi',
|
||||
nonstock: dummyNonstocks[4],
|
||||
created_at: now,
|
||||
},
|
||||
];
|
||||
|
||||
// ======================
|
||||
// 💰 Realisasi Dummy Data
|
||||
// ======================
|
||||
const dummyRealisasis: Realisasi[] = [
|
||||
{
|
||||
id: 1,
|
||||
expense_nonstock_id: 1,
|
||||
qty: 950,
|
||||
price: 1500,
|
||||
notes: 'Realisasi biaya listrik aktual',
|
||||
nonstock: dummyNonstocks[0],
|
||||
created_at: now,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
expense_nonstock_id: 2,
|
||||
qty: 480,
|
||||
price: 5000,
|
||||
notes: 'Realisasi biaya air aktual',
|
||||
nonstock: dummyNonstocks[1],
|
||||
created_at: now,
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
expense_nonstock_id: 3,
|
||||
qty: 195,
|
||||
price: 15000,
|
||||
notes: 'Realisasi biaya bahan bakar aktual',
|
||||
nonstock: dummyNonstocks[2],
|
||||
created_at: now,
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
expense_nonstock_id: 4,
|
||||
qty: 1,
|
||||
price: 4800000,
|
||||
notes: 'Realisasi biaya pemeliharaan kandang',
|
||||
nonstock: dummyNonstocks[3],
|
||||
created_at: now,
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
expense_nonstock_id: 5,
|
||||
qty: 9,
|
||||
price: 500000,
|
||||
notes: 'Realisasi biaya transportasi',
|
||||
nonstock: dummyNonstocks[4],
|
||||
created_at: now,
|
||||
},
|
||||
];
|
||||
|
||||
// ======================
|
||||
// 📊 Report Expense Dummy Data
|
||||
// ======================
|
||||
export const dummyReportExpenses: ReportExpense[] = [
|
||||
{
|
||||
id: 1,
|
||||
reference_number: 'EXP-2025-001',
|
||||
po_number: 'PO-2025-001',
|
||||
category: 'Utilitas',
|
||||
supplier: dummySuppliers[0],
|
||||
realization_date: today,
|
||||
transaction_date: yesterday,
|
||||
location: dummyLocations[0],
|
||||
pengajuan: dummyPengajuans[0],
|
||||
realisasi: dummyRealisasis[0],
|
||||
kandang: dummyKandangs[0],
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
created_user: createdUser,
|
||||
latest_approval: {
|
||||
id: 1,
|
||||
step_number: 1,
|
||||
step_name: 'Manager Approval',
|
||||
action: 'PENDING',
|
||||
notes: '',
|
||||
action_by: createdUser,
|
||||
action_at: now,
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
reference_number: 'EXP-2025-002',
|
||||
po_number: 'PO-2025-002',
|
||||
category: 'Utilitas',
|
||||
supplier: dummySuppliers[0],
|
||||
realization_date: today,
|
||||
transaction_date: yesterday,
|
||||
location: dummyLocations[1],
|
||||
pengajuan: dummyPengajuans[1],
|
||||
realisasi: dummyRealisasis[1],
|
||||
kandang: dummyKandangs[1],
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
created_user: createdUser,
|
||||
latest_approval: {
|
||||
id: 2,
|
||||
step_number: 2,
|
||||
step_name: 'Finance Approval',
|
||||
action: 'APPROVED',
|
||||
notes: 'Disetujui oleh finance',
|
||||
action_by: createdUser,
|
||||
action_at: now,
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
reference_number: 'EXP-2025-003',
|
||||
po_number: 'PO-2025-003',
|
||||
category: 'Operasional',
|
||||
supplier: dummySuppliers[1],
|
||||
realization_date: lastWeek,
|
||||
transaction_date: lastWeek,
|
||||
location: dummyLocations[2],
|
||||
pengajuan: dummyPengajuans[2],
|
||||
realisasi: dummyRealisasis[2],
|
||||
kandang: dummyKandangs[2],
|
||||
created_at: lastWeek,
|
||||
updated_at: lastWeek,
|
||||
created_user: createdUser,
|
||||
latest_approval: {
|
||||
id: 3,
|
||||
step_number: 3,
|
||||
step_name: 'Director Approval',
|
||||
action: 'APPROVED',
|
||||
notes: 'Disetujui oleh direktur',
|
||||
action_by: createdUser,
|
||||
action_at: lastWeek,
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
reference_number: 'EXP-2025-004',
|
||||
po_number: 'PO-2025-004',
|
||||
category: 'Maintenance',
|
||||
supplier: dummySuppliers[2],
|
||||
realization_date: today,
|
||||
transaction_date: yesterday,
|
||||
location: dummyLocations[0],
|
||||
pengajuan: dummyPengajuans[3],
|
||||
realisasi: dummyRealisasis[3],
|
||||
kandang: dummyKandangs[0],
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
created_user: createdUser,
|
||||
latest_approval: {
|
||||
id: 4,
|
||||
step_number: 1,
|
||||
step_name: 'Manager Approval',
|
||||
action: 'REJECTED',
|
||||
notes: 'Biaya terlalu tinggi, perlu revisi',
|
||||
action_by: createdUser,
|
||||
action_at: now,
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
reference_number: 'EXP-2025-005',
|
||||
po_number: 'PO-2025-005',
|
||||
category: 'Operasional',
|
||||
supplier: dummySuppliers[1],
|
||||
realization_date: yesterday,
|
||||
transaction_date: lastWeek,
|
||||
location: dummyLocations[1],
|
||||
pengajuan: dummyPengajuans[4],
|
||||
realisasi: dummyRealisasis[4],
|
||||
kandang: dummyKandangs[1],
|
||||
created_at: lastWeek,
|
||||
updated_at: yesterday,
|
||||
created_user: createdUser,
|
||||
latest_approval: {
|
||||
id: 5,
|
||||
step_number: 2,
|
||||
step_name: 'Finance Approval',
|
||||
action: 'PENDING',
|
||||
notes: '',
|
||||
action_by: createdUser,
|
||||
action_at: yesterday,
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
reference_number: 'EXP-2025-006',
|
||||
po_number: 'PO-2025-006',
|
||||
category: 'Utilitas',
|
||||
supplier: dummySuppliers[0],
|
||||
realization_date: lastMonth,
|
||||
transaction_date: lastMonth,
|
||||
location: dummyLocations[2],
|
||||
pengajuan: {
|
||||
id: 6,
|
||||
expense_id: 6,
|
||||
project_flock_kandang_id: 3,
|
||||
kandang_id: 3,
|
||||
nonstock_id: 1,
|
||||
qty: 1200,
|
||||
price: 1500,
|
||||
notes: 'Pengajuan biaya listrik bulan lalu',
|
||||
nonstock: dummyNonstocks[0],
|
||||
created_at: lastMonth,
|
||||
},
|
||||
realisasi: {
|
||||
id: 6,
|
||||
expense_nonstock_id: 6,
|
||||
qty: 1150,
|
||||
price: 1500,
|
||||
notes: 'Realisasi biaya listrik bulan lalu',
|
||||
nonstock: dummyNonstocks[0],
|
||||
created_at: lastMonth,
|
||||
},
|
||||
kandang: dummyKandangs[2],
|
||||
created_at: lastMonth,
|
||||
updated_at: lastMonth,
|
||||
created_user: createdUser,
|
||||
latest_approval: {
|
||||
id: 6,
|
||||
step_number: 3,
|
||||
step_name: 'Director Approval',
|
||||
action: 'APPROVED',
|
||||
notes: 'Selesai diproses',
|
||||
action_by: createdUser,
|
||||
action_at: lastMonth,
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
// ======================
|
||||
// 🔧 Fetcher Functions
|
||||
// ======================
|
||||
|
||||
/**
|
||||
* Dummy fetcher untuk mendapatkan semua data report expense
|
||||
* @returns Promise dengan BaseApiResponse berisi array ReportExpense
|
||||
*/
|
||||
export async function dummyGetAllFetcher(): Promise<
|
||||
BaseApiResponse<ReportExpense[]>
|
||||
> {
|
||||
// Simulasi delay network
|
||||
await new Promise((resolve) => setTimeout(resolve, 500));
|
||||
|
||||
return {
|
||||
code: 200,
|
||||
status: 'success',
|
||||
message: 'Data report expense berhasil diambil',
|
||||
data: dummyReportExpenses,
|
||||
meta: {
|
||||
page: 1,
|
||||
limit: 10,
|
||||
total_results: dummyReportExpenses.length,
|
||||
total_pages: 1,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Dummy fetcher untuk mendapatkan single data report expense berdasarkan ID
|
||||
* @param id - ID dari report expense yang ingin diambil
|
||||
* @returns Promise dengan BaseApiResponse berisi single ReportExpense
|
||||
*/
|
||||
export async function dummyGetSingle(
|
||||
id: number
|
||||
): Promise<BaseApiResponse<ReportExpense>> {
|
||||
// Simulasi delay network
|
||||
await new Promise((resolve) => setTimeout(resolve, 300));
|
||||
|
||||
const reportExpense = dummyReportExpenses.find((item) => item.id === id);
|
||||
|
||||
if (!reportExpense) {
|
||||
return {
|
||||
code: 404,
|
||||
status: 'error',
|
||||
message: `Report expense dengan ID ${id} tidak ditemukan`,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
code: 200,
|
||||
status: 'success',
|
||||
message: 'Data report expense berhasil diambil',
|
||||
data: reportExpense,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user