Files
lti-web-client/src/services/api/daily-checklist/daily-checklist.ts
T

401 lines
11 KiB
TypeScript

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<BaseApiResponse<DailyChecklist>>(
updatePath,
{
method: 'PUT',
body: payload,
headers,
}
);
return updateRes;
} catch (error: unknown) {
if (axios.isAxiosError<BaseApiResponse<DailyChecklist>>(error)) {
return error.response?.data;
}
return undefined;
}
}
async getOneDailyChecklist(id: string) {
try {
const getOneDailyChecklistPath = `${this.basePath}/relation/${id}`;
const getOneDailyChecklistRes = await httpClient<
BaseApiResponse<DetailDailyChecklist>
>(getOneDailyChecklistPath);
return getOneDailyChecklistRes;
} catch (error) {
if (axios.isAxiosError<BaseApiResponse<DetailDailyChecklist>>(error)) {
return error.response?.data;
}
return undefined;
}
}
async setDailyChecklistPhase(id: string, phaseIds: string[]) {
try {
const setDailyChecklistPhasePath = `${this.basePath}/phase/${id}`;
const setDailyChecklistPhaseRes = await httpClient<BaseApiResponse>(
setDailyChecklistPhasePath,
{
method: 'POST',
body: { phase_ids: phaseIds.join(',') },
}
);
return setDailyChecklistPhaseRes;
} catch (error) {
if (axios.isAxiosError<BaseApiResponse>(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<BaseApiResponse>(
removeEmployeeAssignmentPath,
{
method: 'DELETE',
}
);
return removeEmployeeAssignmentRes;
} catch (error) {
if (axios.isAxiosError<BaseApiResponse>(error)) {
return error.response?.data;
}
return undefined;
}
}
async setDailyChecklistEmployees(checklistId: string, employeeIds: string[]) {
try {
const setDailyChecklistPhasePath = `${this.basePath}/assignment/${checklistId}`;
const setDailyChecklistPhaseRes = await httpClient<BaseApiResponse>(
setDailyChecklistPhasePath,
{
method: 'POST',
body: { employee_ids: employeeIds.join(',') },
}
);
return setDailyChecklistPhaseRes;
} catch (error) {
if (axios.isAxiosError<BaseApiResponse>(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<BaseApiResponse>(
getTasksByChecklistIdPath
);
return getTasksByChecklistIdRes;
} catch (error) {
if (axios.isAxiosError<BaseApiResponse>(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<BaseApiResponse>(
checkOrUncheckAssignmentPath,
{
method: 'POST',
body: payload,
}
);
return checkOrUncheckAssignmentRes;
} catch (error) {
if (axios.isAxiosError<BaseApiResponse>(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<BaseApiResponse>(submitPath, {
method: 'PATCH',
body: formData,
});
return submitRes;
} catch (error) {
if (axios.isAxiosError<BaseApiResponse>(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<BaseApiResponse>(approvePath, {
method: 'PATCH',
body: formData,
});
return approveRes;
} catch (error) {
if (axios.isAxiosError<BaseApiResponse>(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<BaseApiResponse>(approvePath, {
method: 'PATCH',
body: formData,
});
return approveRes;
} catch (error) {
if (axios.isAxiosError<BaseApiResponse>(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<BaseApiResponse>(rejectPath, {
method: 'PATCH',
body: formData,
});
return rejectRes;
} catch (error) {
if (axios.isAxiosError<BaseApiResponse>(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<BaseApiResponse>(rejectPath, {
method: 'PATCH',
body: formData,
});
return rejectRes;
} catch (error) {
if (axios.isAxiosError<BaseApiResponse>(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<BaseApiResponse>(
uploadImagePath,
{
method: 'PATCH',
body: formData,
}
);
return uploadImageRes;
} catch (error) {
if (axios.isAxiosError<BaseApiResponse>(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<DailyChecklistReport[]>
>(`${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<string, string | number> = {
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'
);