import axios from 'axios'; import * as XLSX from 'xlsx'; import { BaseApiService } from '@/services/api/base'; import { httpClient, httpClientFetcher } from '@/services/http/client'; import { BaseApiResponse } from '@/types/api/api-general'; import { CreateDailyChecklistPayload, DailyChecklist, DailyChecklistReport, DetailDailyChecklist, UpdateDailyChecklistPayload, } from '@/types/api/daily-checklist/daily-checklist'; import { isResponseError } from '@/lib/api-helper'; import { toast } from 'sonner'; export class DailyChecklistApiService extends BaseApiService< DailyChecklist, CreateDailyChecklistPayload, UpdateDailyChecklistPayload > { constructor(basePath: string = '/daily-checklists') { super(basePath); } async update(id: number, payload: UpdateDailyChecklistPayload) { const isFormData = typeof FormData !== 'undefined' && payload instanceof FormData; try { const updatePath = `${this.basePath}/${id}`; const headers = isFormData ? { ...(this.header ?? {}) } : { 'Content-Type': 'application/json', ...(this.header ?? {}) }; const updateRes = await httpClient>( updatePath, { method: 'PUT', body: payload, headers, } ); return updateRes; } catch (error: unknown) { if (axios.isAxiosError>(error)) { return error.response?.data; } return undefined; } } async getOneDailyChecklist(id: string) { try { const getOneDailyChecklistPath = `${this.basePath}/relation/${id}`; const getOneDailyChecklistRes = await httpClient< BaseApiResponse >(getOneDailyChecklistPath); return getOneDailyChecklistRes; } catch (error) { if (axios.isAxiosError>(error)) { return error.response?.data; } return undefined; } } async setDailyChecklistPhase(id: string, phaseIds: string[]) { try { const setDailyChecklistPhasePath = `${this.basePath}/phase/${id}`; const setDailyChecklistPhaseRes = await httpClient( setDailyChecklistPhasePath, { method: 'POST', body: { phase_ids: phaseIds.join(',') }, } ); return setDailyChecklistPhaseRes; } catch (error) { if (axios.isAxiosError(error)) { return error.response?.data; } return undefined; } } async removeEmployeeAssignment(id: string, employeeId: string) { try { const removeEmployeeAssignmentPath = `${this.basePath}/${id}/assignments/${employeeId}`; const removeEmployeeAssignmentRes = await httpClient( removeEmployeeAssignmentPath, { method: 'DELETE', } ); return removeEmployeeAssignmentRes; } catch (error) { if (axios.isAxiosError(error)) { return error.response?.data; } return undefined; } } async setDailyChecklistEmployees(checklistId: string, employeeIds: string[]) { try { const setDailyChecklistPhasePath = `${this.basePath}/assignment/${checklistId}`; const setDailyChecklistPhaseRes = await httpClient( setDailyChecklistPhasePath, { method: 'POST', body: { employee_ids: employeeIds.join(',') }, } ); return setDailyChecklistPhaseRes; } catch (error) { if (axios.isAxiosError(error)) { return error.response?.data; } return undefined; } } async getTasksByChecklistId(id: string) { try { const getTasksByChecklistIdPath = `${this.basePath}/tasks?checklist_id=${id}&page=1&limit=100`; const getTasksByChecklistIdRes = await httpClient( getTasksByChecklistIdPath ); return getTasksByChecklistIdRes; } catch (error) { if (axios.isAxiosError(error)) { return error.response?.data; } return undefined; } } async checkOrUncheckAssignment(payload: { task_id: number; employee_id: number; checked: boolean; note: string | null; }) { try { const checkOrUncheckAssignmentPath = `${this.basePath}/assignment`; const checkOrUncheckAssignmentRes = await httpClient( checkOrUncheckAssignmentPath, { method: 'POST', body: payload, } ); return checkOrUncheckAssignmentRes; } catch (error) { if (axios.isAxiosError(error)) { return error.response?.data; } return undefined; } } async submit( id: string, files: File[] = [], deletedDocumentIds: number[] = [] ) { try { const formData = new FormData(); formData.append('status', 'SUBMITTED'); formData.append('reject_reason', ''); files.forEach((file) => formData.append(`documents`, file)); formData.append('deleted_document_ids', deletedDocumentIds.join(',')); const submitPath = `${this.basePath}/${id}`; const submitRes = await httpClient(submitPath, { method: 'PATCH', body: formData, }); return submitRes; } catch (error) { if (axios.isAxiosError(error)) { return error.response?.data; } return undefined; } } async approve(id: string) { try { const formData = new FormData(); formData.append('status', 'APPROVED'); formData.append('reject_reason', ''); const approvePath = `${this.basePath}/${id}`; const approveRes = await httpClient(approvePath, { method: 'PATCH', body: formData, }); return approveRes; } catch (error) { if (axios.isAxiosError(error)) { return error.response?.data; } return undefined; } } async bulkApprove(ids: string[]) { try { const formData = new FormData(); formData.append('ids', ids.join(',')); formData.append('status', 'APPROVED'); formData.append('reject_reason', ''); const approvePath = `${this.basePath}/bulk-update`; const approveRes = await httpClient(approvePath, { method: 'PATCH', body: formData, }); return approveRes; } catch (error) { if (axios.isAxiosError(error)) { return error.response?.data; } return undefined; } } async reject(id: string, rejectReason: string) { try { const formData = new FormData(); formData.append('status', 'REJECTED'); formData.append('reject_reason', rejectReason); const rejectPath = `${this.basePath}/${id}`; const rejectRes = await httpClient(rejectPath, { method: 'PATCH', body: formData, }); return rejectRes; } catch (error) { if (axios.isAxiosError(error)) { return error.response?.data; } return undefined; } } async bulkReject(ids: string[], rejectReason: string) { try { const formData = new FormData(); formData.append('ids', ids.join(',')); formData.append('status', 'REJECTED'); formData.append('reject_reason', rejectReason); const rejectPath = `${this.basePath}/bulk-update`; const rejectRes = await httpClient(rejectPath, { method: 'PATCH', body: formData, }); return rejectRes; } catch (error) { if (axios.isAxiosError(error)) { return error.response?.data; } return undefined; } } async uploadImage( id: number, status: string, files: File[], deletedDocumentIds: number[] = [] ) { try { const formData = new FormData(); formData.append('status', status); files.forEach((file) => formData.append(`documents`, file)); formData.append('deleted_document_ids', deletedDocumentIds.join(',')); const uploadImagePath = `${this.basePath}/${id}`; const uploadImageRes = await httpClient( uploadImagePath, { method: 'PATCH', body: formData, } ); return uploadImageRes; } catch (error) { if (axios.isAxiosError(error)) { return error.response?.data; } return undefined; } } async exportDailyChecklistReportToExcel(initialQueryString: string) { const params = new URLSearchParams(initialQueryString); params.set('limit', '2000'); const queryString = `?${params.toString()}`; try { const dailyMarketingsReport = await httpClientFetcher< BaseApiResponse >(`${this.basePath}/report${queryString}`); if (isResponseError(dailyMarketingsReport)) { toast.error('Gagal melakukan export daily checklist! Coba lagi.'); return; } const currentMonthMaxDay = new Date( Number(params.get('tahun')), Number(params.get('bulan')), 0 ).getDate(); const rows = dailyMarketingsReport.data; const formattedRows = []; for (let i = 0; i < rows.length; i++) { const formattedData: Record = { Area: rows[i].area.name, Farm: rows[i].farm.name, Kandang: rows[i].kandang.name, ABK: rows[i].abk.name, Phase: rows[i].phase, }; // Add day for (let j = 1; j <= currentMonthMaxDay; j++) { formattedData[`Day ${j}`] = rows[i].daily_activities[`${j}`]; } // add summary formattedData['Total Checklist'] = rows[i].summary.total_checklist; formattedData['Jumlah Hari Efektif'] = rows[i].summary.jumlah_hari_efektif; formattedData['ABK %'] = rows[i].summary.abk_percentage; formattedData['Kandang %'] = rows[i].summary.kandang_percentage; formattedData['Kategori Kurang'] = rows[i].summary.kategori.kurang; formattedData['Kategori Cukup'] = rows[i].summary.kategori.cukup; formattedData['Kategori Baik'] = rows[i].summary.kategori.baik; formattedRows.push(formattedData); } const ws = XLSX.utils.json_to_sheet(formattedRows); const wb = XLSX.utils.book_new(); XLSX.utils.book_append_sheet( wb, ws, `Daily Checklist ${params.get('tahun')}-${params.get('bulan')?.slice(0, 3)}` ); // triggers download in browser XLSX.writeFile( wb, `laporan-daily-checklist-${params.get('tahun')}-${params.get('bulan')}.xlsx` ); } catch { toast.error('Gagal melakukan export daily checklist! Coba lagi.'); } } } export const DailyChecklistApi = new DailyChecklistApiService( '/daily-checklists' );