import * as XLSX from 'xlsx'; import axios from 'axios'; import { BaseApiService } from '@/services/api/base'; import { Approvals, BaseApiResponse, GroupedApprovals, } from '@/types/api/api-general'; import { CreateTransferToLayingPayload, TransferToLaying, UpdateTransferToLayingPayload, } from '@/types/api/production/transfer-to-laying'; import { httpClient, httpClientFetcher } from '@/services/http/client'; import { ProjectFlockAvailableQuantity, ProjectFlockMaxQuantity, } from '@/types/api/production/project-flock'; import { isResponseError, isResponseSuccess } from '@/lib/api-helper'; import toast from 'react-hot-toast'; import { formatDate } from '@/lib/helper'; export class TransferToLayingService extends BaseApiService< TransferToLaying, CreateTransferToLayingPayload, UpdateTransferToLayingPayload > { constructor(basePath: string = '') { super(basePath); } async approve( id: number, notes?: string ): Promise | undefined> { try { const approveRes = await httpClient>( `${this.basePath}/approvals`, { method: 'POST', body: { action: 'APPROVED', approvable_ids: [id], notes: notes, }, } ); return approveRes; } catch (error) { if (axios.isAxiosError>(error)) { return error.response?.data; } return undefined; } } async bulkApprove( ids: number[], notes?: string ): Promise | undefined> { try { const approveRes = await httpClient>( `${this.basePath}/approvals`, { method: 'POST', body: { action: 'APPROVED', approvable_ids: ids, notes: notes, }, } ); return approveRes; } catch (error) { if (axios.isAxiosError>(error)) { return error.response?.data; } return undefined; } } async reject( id: number, notes?: string ): Promise | undefined> { try { const rejectRes = await httpClient>( `${this.basePath}/approvals`, { method: 'POST', body: { action: 'REJECTED', approvable_ids: [id], notes: notes, }, } ); return rejectRes; } catch (error) { if (axios.isAxiosError>(error)) { return error.response?.data; } return undefined; } } async bulkReject( ids: number[], notes?: string ): Promise | undefined> { try { const rejectRes = await httpClient>( `${this.basePath}/approvals`, { method: 'POST', body: { action: 'REJECTED', approvable_ids: ids, notes: notes, }, } ); return rejectRes; } catch (error) { if (axios.isAxiosError>(error)) { return error.response?.data; } return undefined; } } async getAvailableQty(projectFlockId: number) { try { const availableQtyRes = await httpClient< BaseApiResponse >(`${this.basePath}/project-flocks/${projectFlockId}/available-qty`); return availableQtyRes; } catch (error) { if ( axios.isAxiosError>( error ) ) { return error.response?.data; } return undefined; } } async getMappedFlockKandangsAvailability(projectFlockId: number) { try { const flockAvailableQty = await this.getAvailableQty(projectFlockId); const flockKandangsAvailableQty = isResponseSuccess(flockAvailableQty) ? flockAvailableQty.data.kandangs : []; const mappedFlockKandangsAvailableQty: Record< number, (typeof flockKandangsAvailableQty)[0] > = {}; flockKandangsAvailableQty.forEach((item) => { if (!mappedFlockKandangsAvailableQty[item.project_flock_kandang_id]) { mappedFlockKandangsAvailableQty[item.project_flock_kandang_id] = item; } }); return mappedFlockKandangsAvailableQty; } catch (error) { return undefined; } } async getMaxTargetQty(projectFlockId: number) { try { const availableQtyRes = await httpClient< BaseApiResponse >(`${this.basePath}/project-flocks/${projectFlockId}/max-target-qty`); return availableQtyRes; } catch (error) { if (axios.isAxiosError>(error)) { return error.response?.data; } return undefined; } } async getMappedFlockKandangsMaxTargetQty(projectFlockId: number) { try { const flockMaxTargetQty = await this.getMaxTargetQty(projectFlockId); const flockKandangsMaxTargetQty = isResponseSuccess(flockMaxTargetQty) ? flockMaxTargetQty.data.project_flock_kandangs : []; const mappedFlockKandangsMaxTargetQty: Record< number, (typeof flockKandangsMaxTargetQty)[0] > = {}; flockKandangsMaxTargetQty.forEach((item) => { if (!mappedFlockKandangsMaxTargetQty[item.project_flock_kandang_id]) { mappedFlockKandangsMaxTargetQty[item.project_flock_kandang_id] = item; } }); return mappedFlockKandangsMaxTargetQty; } catch (error) { return undefined; } } async exportToExcel(initialQueryString: string) { const params = new URLSearchParams(initialQueryString); params.set('limit', '9999999'); const queryString = `?${params.toString()}`; try { const transferToLayings = await httpClientFetcher< BaseApiResponse >(`${this.basePath}${queryString}`); if (isResponseError(transferToLayings)) { toast.error('Gagal melakukan export transfer to laying! Coba lagi.'); return; } const rows = transferToLayings.data; const formattedRows = []; for (let i = 0; i < rows.length; i++) { formattedRows.push({ id: rows[i].id, transfer_number: rows[i].transfer_number, transfer_date: formatDate(rows[i].transfer_date, 'DD-MM-YYYY'), project_flock_source: rows[i].from_project_flock.flock_name, project_flock_target: rows[i].to_project_flock.flock_name, pending_usage_qty: rows[i].pending_usage_qty, usage_qty: rows[i].usage_qty, project_flock_source_kandang: rows[i].sources .map((item) => item.source_project_flock_kandang.kandang.name) .join(', '), project_flock_target_kandang: rows[i].targets .map((item) => item.target_project_flock_kandang.kandang.name) .join(', '), created_user: rows[i].created_user.name, created_at: formatDate(rows[i].created_at, 'DD-MM-YYYY'), updated_at: formatDate(rows[i].updated_at, 'DD-MM-YYYY'), notes: rows[i].notes, }); } const ws = XLSX.utils.json_to_sheet(formattedRows); const wb = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(wb, ws, 'transfer-ke-laying'); // triggers download in browser XLSX.writeFile(wb, 'transfer-ke-laying.xlsx'); } catch (error) { toast.error('Gagal melakukan export transfer to laying! Coba lagi.'); } } async getApprovalHistory( transferToLayingId: number, group: boolean = true, page: number = 1, limit: number = 10 ) { try { const approvalHistoryRes = await httpClient( '/approvals', { query: { module_name: 'TRANSFER_TO_LAYINGS', module_id: transferToLayingId, group_step_number: group ? 'true' : 'false', page, limit, }, } ); return approvalHistoryRes; } catch (error) { if (axios.isAxiosError(error)) { return error.response?.data; } return undefined; } } async getApprovalLineHistory( transferToLayingId: number, page: number = 1, limit: number = 100 ) { try { const approvalHistoryRes = await httpClient('/approvals', { query: { module_name: 'TRANSFER_TO_LAYINGS', module_id: transferToLayingId, group_step_number: 'false', page, limit, order_by_date: 'ASC', }, }); return approvalHistoryRes; } catch (error) { if (axios.isAxiosError(error)) { return error.response?.data; } return undefined; } } } export const TransferToLayingApi = new TransferToLayingService( '/production/transfer_layings' );