import * as XLSX from 'xlsx'; import toast from 'react-hot-toast'; import { formatDate, safeRound } from '@/lib/helper'; import { isResponseSuccess } from '@/lib/api-helper'; import { BaseApiService } from '@/services/api/base'; import { httpClient, httpClientFetcher } from '@/services/http/client'; import { BaseApiResponse } from '@/types/api/api-general'; import { ProductionResult } from '@/types/api/report/production-result'; import { BaseProjectFlockKandang } from '@/types/api/production/project-flock-kandang'; export class ProductionResultReportApiService extends BaseApiService< ProductionResult, unknown, unknown > { constructor(basePath: string = '/reports/production-result') { super(basePath); } async getAllProductionResultFetcher( endpoint: string ): Promise> { return await httpClientFetcher>( endpoint ); } async exportProductionResultToExcel( projectFlockKandangs: BaseProjectFlockKandang[] | null ) { try { const mappedProductionResults: { projectFlockKandang: BaseProjectFlockKandang; productionResult: ProductionResult[] | null; }[] = await Promise.all( (projectFlockKandangs || []).map(async (projectFlockKandang) => { const getProductionResultPath = `${this.basePath}/${projectFlockKandang.id}?page=1&limit=99999999`; const getProductionResultRes = await httpClient< BaseApiResponse >(getProductionResultPath); return { projectFlockKandang, productionResult: isResponseSuccess(getProductionResultRes) ? getProductionResultRes.data : null, }; }) ); const rows = mappedProductionResults; if (!rows || rows.length === 0) { toast.error('Tidak ada data untuk diexport.'); return; } // Group by Project Flock Kandang Name const groupedData: Record< string, Record[] > = {}; rows.forEach((row) => { const kandangName = row.projectFlockKandang.kandang.name || 'Unknown'; if (!groupedData[kandangName]) { groupedData[kandangName] = []; } row.productionResult?.forEach((productionResult) => { groupedData[kandangName].push({ woa: safeRound(productionResult.woa, 2), bw: safeRound(productionResult.bw, 2), std_bw: safeRound(productionResult.std_bw, 2), uniformity: safeRound(productionResult.uniformity, 2), std_uniformity: productionResult.std_uniformity, dep_kum: safeRound(productionResult.dep_kum, 2), dep_std: safeRound(productionResult.dep_std, 2), butiran_utuh: safeRound(productionResult.butiran_utuh, 2), butiran_putih: safeRound(productionResult.butiran_putih, 2), butiran_retak: safeRound(productionResult.butiran_retak, 2), butiran_pecah: safeRound(productionResult.butiran_pecah, 2), butiran_jumlah: safeRound(productionResult.butiran_jumlah, 2), total_butir: safeRound(productionResult.total_butir, 2), kg_utuh: safeRound(productionResult.kg_utuh, 2), kg_putih: safeRound(productionResult.kg_putih, 2), kg_retak: safeRound(productionResult.kg_retak, 2), kg_pecah: safeRound(productionResult.kg_pecah, 2), kg_jumlah: safeRound(productionResult.kg_jumlah, 2), total_kg: safeRound(productionResult.total_kg, 2), persen_utuh: safeRound(productionResult.persen_utuh, 2), persen_putih: safeRound(productionResult.persen_putih, 2), persen_retak: safeRound(productionResult.persen_retak, 2), persen_pecah: safeRound(productionResult.persen_pecah, 2), hd: safeRound(productionResult.hd, 2), hd_std: safeRound(productionResult.hd_std, 2), fi: safeRound(productionResult.fi, 2), fi_std: safeRound(productionResult.fi_std, 2), em: safeRound(productionResult.em, 2), em_std: safeRound(productionResult.em_std, 2), ew: safeRound(productionResult.ew, 2), ew_std: safeRound(productionResult.ew_std, 2), fcr: safeRound(productionResult.fcr, 2), fcr_std: safeRound(productionResult.fcr_std, 2), hh: safeRound(productionResult.hh, 2), hh_std: safeRound(productionResult.hh_std, 2), project_flock_name: row.projectFlockKandang.project_flock.flock_name, project_flock_category: row.projectFlockKandang.project_flock.category, kandang_name: row.projectFlockKandang.kandang.name, created_at: formatDate(productionResult.created_at, 'YYYY-MM-DD'), updated_at: formatDate(productionResult.updated_at, 'YYYY-MM-DD'), }); }); }); const wb = XLSX.utils.book_new(); Object.keys(groupedData).forEach((sheetName) => { const ws = XLSX.utils.json_to_sheet(groupedData[sheetName]); // Sheet names cannot exceed 31 chars const safeSheetName = sheetName.substring(0, 31); XLSX.utils.book_append_sheet(wb, ws, safeSheetName); }); const productionResultExcelFileName = `laporan-hasil-produksi-${formatDate(Date.now(), 'YYYY-MM-DD')}-${rows[0].projectFlockKandang.project_flock.flock_name}.xlsx`; XLSX.writeFile(wb, productionResultExcelFileName); } catch (error) { console.error(error); toast.error('Gagal melakukan export laporan hasil produksi! Coba lagi.'); } } } export const ProductionResultReportApi = new ProductionResultReportApiService( '/reports/production-result' );