mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 21:41:57 +00:00
139 lines
5.7 KiB
TypeScript
139 lines
5.7 KiB
TypeScript
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<BaseApiResponse<ProductionResult[]>> {
|
|
return await httpClientFetcher<BaseApiResponse<ProductionResult[]>>(
|
|
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<ProductionResult[]>
|
|
>(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<string, string | number | undefined>[]
|
|
> = {};
|
|
|
|
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'
|
|
);
|