Files
lti-web-client/src/services/api/production/transfer-to-laying.ts
T
2026-01-27 18:58:03 +07:00

342 lines
9.0 KiB
TypeScript

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<BaseApiResponse<TransferToLaying> | undefined> {
try {
const approveRes = await httpClient<BaseApiResponse<TransferToLaying>>(
`${this.basePath}/approvals`,
{
method: 'POST',
body: {
action: 'APPROVED',
approvable_ids: [id],
notes: notes,
},
}
);
return approveRes;
} catch (error) {
if (axios.isAxiosError<BaseApiResponse<TransferToLaying>>(error)) {
return error.response?.data;
}
return undefined;
}
}
async bulkApprove(
ids: number[],
notes?: string
): Promise<BaseApiResponse<TransferToLaying> | undefined> {
try {
const approveRes = await httpClient<BaseApiResponse<TransferToLaying>>(
`${this.basePath}/approvals`,
{
method: 'POST',
body: {
action: 'APPROVED',
approvable_ids: ids,
notes: notes,
},
}
);
return approveRes;
} catch (error) {
if (axios.isAxiosError<BaseApiResponse<TransferToLaying>>(error)) {
return error.response?.data;
}
return undefined;
}
}
async reject(
id: number,
notes?: string
): Promise<BaseApiResponse<TransferToLaying> | undefined> {
try {
const rejectRes = await httpClient<BaseApiResponse<TransferToLaying>>(
`${this.basePath}/approvals`,
{
method: 'POST',
body: {
action: 'REJECTED',
approvable_ids: [id],
notes: notes,
},
}
);
return rejectRes;
} catch (error) {
if (axios.isAxiosError<BaseApiResponse<TransferToLaying>>(error)) {
return error.response?.data;
}
return undefined;
}
}
async bulkReject(
ids: number[],
notes?: string
): Promise<BaseApiResponse<TransferToLaying> | undefined> {
try {
const rejectRes = await httpClient<BaseApiResponse<TransferToLaying>>(
`${this.basePath}/approvals`,
{
method: 'POST',
body: {
action: 'REJECTED',
approvable_ids: ids,
notes: notes,
},
}
);
return rejectRes;
} catch (error) {
if (axios.isAxiosError<BaseApiResponse<TransferToLaying>>(error)) {
return error.response?.data;
}
return undefined;
}
}
async getAvailableQty(projectFlockId: number) {
try {
const availableQtyRes = await httpClient<
BaseApiResponse<ProjectFlockAvailableQuantity>
>(`${this.basePath}/project-flocks/${projectFlockId}/available-qty`);
return availableQtyRes;
} catch (error) {
if (
axios.isAxiosError<BaseApiResponse<ProjectFlockAvailableQuantity>>(
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<ProjectFlockMaxQuantity>
>(`${this.basePath}/project-flocks/${projectFlockId}/max-target-qty`);
return availableQtyRes;
} catch (error) {
if (axios.isAxiosError<BaseApiResponse<ProjectFlockMaxQuantity>>(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<TransferToLaying[]>
>(`${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<GroupedApprovals>(
'/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<GroupedApprovals>(error)) {
return error.response?.data;
}
return undefined;
}
}
async getApprovalLineHistory(
transferToLayingId: number,
page: number = 1,
limit: number = 100
) {
try {
const approvalHistoryRes = await httpClient<Approvals>('/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<Approvals>(error)) {
return error.response?.data;
}
return undefined;
}
}
}
export const TransferToLayingApi = new TransferToLayingService(
'/production/transfer_layings'
);