diff --git a/src/services/api/daily-checklist/daily-checklist.ts b/src/services/api/daily-checklist/daily-checklist.ts index 48b789a8..b8f72201 100644 --- a/src/services/api/daily-checklist/daily-checklist.ts +++ b/src/services/api/daily-checklist/daily-checklist.ts @@ -1,13 +1,18 @@ import axios from 'axios'; +import * as XLSX from 'xlsx'; import { BaseApiService } from '@/services/api/base'; -import { httpClient } from '@/services/http/client'; +import { httpClient, httpClientFetcher } from '@/services/http/client'; import { BaseApiResponse } from '@/types/api/api-general'; import { CreateDailyChecklistPayload, DailyChecklist, + DailyChecklistReport, DetailDailyChecklist, } from '@/types/api/daily-checklist/daily-checklist'; +import { isResponseError } from '@/lib/api-helper'; +import { toast } from 'sonner'; +import { formatDate } from '@/lib/helper'; export class DailyChecklistApiService extends BaseApiService< DailyChecklist, @@ -134,15 +139,26 @@ export class DailyChecklistApiService extends BaseApiService< } } - async submit(id: string) { + 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: { - status: 'SUBMITTED', - reject_reason: '', - }, + body: formData, }); return submitRes; @@ -156,13 +172,16 @@ export class DailyChecklistApiService extends BaseApiService< 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: { - status: 'APPROVED', - reject_reason: '', - }, + body: formData, }); return approveRes; @@ -176,13 +195,16 @@ export class DailyChecklistApiService extends BaseApiService< 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: { - status: 'REJECTED', - reject_reason: rejectReason, - }, + body: formData, }); return rejectRes; @@ -193,6 +215,111 @@ export class DailyChecklistApiService extends BaseApiService< 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 (error) { + toast.error('Gagal melakukan export daily checklist! Coba lagi.'); + } + } } export const DailyChecklistApi = new DailyChecklistApiService(