From 8d09aec66aa961024ba3758037ea8437e24a03dc Mon Sep 17 00:00:00 2001 From: ValdiANS Date: Wed, 12 Nov 2025 13:36:12 +0700 Subject: [PATCH] feat(FE-149): integrate TransferToLayingService to API --- .../api/production/transfer-to-laying.ts | 977 +++--------------- 1 file changed, 155 insertions(+), 822 deletions(-) diff --git a/src/services/api/production/transfer-to-laying.ts b/src/services/api/production/transfer-to-laying.ts index 6f808a8c..85b556e3 100644 --- a/src/services/api/production/transfer-to-laying.ts +++ b/src/services/api/production/transfer-to-laying.ts @@ -1,739 +1,15 @@ -import { sleep } from '@/lib/helper'; +import axios from 'axios'; import { BaseApiService } from '@/services/api/base'; -import { BaseApiResponse } from '@/types/api/api-general'; +import { BaseApiResponse, GroupedApprovals } from '@/types/api/api-general'; import { CreateTransferToLayingPayload, TransferToLaying, UpdateTransferToLayingPayload, } from '@/types/api/production/transfer-to-laying'; -import { FlockWithKandangs } from '@/types/api/master-data/flock'; - -// TODO: delete this dummy data -const GET_ALL_TRANSFER_TO_LAYING_DUMMY_DATA: BaseApiResponse< - TransferToLaying[] -> = { - code: 200, - status: 'success', - message: 'Successfully get all transfer to laying data!', - meta: { - page: 1, - limit: 10, - total_pages: 1, - total_results: 8, - }, - data: [ - { - id: 201, - transfer_date: '2025-10-10', - flock_source: { id: 1, name: 'Flock A' }, - flock_destination: { id: 10, name: 'Laying House 1' }, - quantity: 1200, - kandangs: [ - { - kandang: { - id: 11, - name: 'KDG-11', - status: 'ACTIVE', - location: { - id: 101, - name: 'Farm Alpha', - address: 'Jl. Raya Alpha No. 1', - area: { id: 1001, name: 'Area Utara' }, - }, - pic: { - id: 501, - id_user: 501, - email: 'rina@farm.co', - name: 'Rina Setiawan', - }, - created_user: { - id: 9001, - id_user: 9001, - email: 'admin@farm.co', - name: 'System Admin', - }, - created_at: '2025-09-01T08:00:00Z', - updated_at: '2025-10-01T08:00:00Z', - }, - quantity: 600, - }, - { - kandang: { - id: 12, - name: 'KDG-12', - status: 'ACTIVE', - location: { - id: 101, - name: 'Farm Alpha', - address: 'Jl. Raya Alpha No. 1', - area: { id: 1001, name: 'Area Utara' }, - }, - pic: { - id: 502, - id_user: 502, - email: 'budi@farm.co', - name: 'Budi Hartono', - }, - created_user: { - id: 9002, - id_user: 9002, - email: 'ops@farm.co', - name: 'Ops Bot', - }, - created_at: '2025-08-25T08:00:00Z', - updated_at: '2025-09-20T08:00:00Z', - }, - quantity: 600, - }, - ], - reason: 'Start laying cycle', - created_user: { - id: 9100, - id_user: 9100, - email: 'planner@farm.co', - name: 'Planning', - }, - created_at: '2025-10-10T06:00:00Z', - updated_at: '2025-10-10T06:00:00Z', - }, - { - id: 202, - transfer_date: '2025-10-11', - flock_source: { id: 2, name: 'Flock B' }, - flock_destination: { id: 10, name: 'Laying House 1' }, - quantity: 950, - kandangs: [ - { - kandang: { - id: 13, - name: 'KDG-13', - status: 'ACTIVE', - location: { - id: 102, - name: 'Farm Beta', - address: 'Jl. Melati 2', - area: { id: 1002, name: 'Area Selatan' }, - }, - pic: { - id: 503, - id_user: 503, - email: 'sari@farm.co', - name: 'Sari Wulandari', - }, - created_user: { - id: 9003, - id_user: 9003, - email: 'system@farm.co', - name: 'System', - }, - created_at: '2025-09-05T08:00:00Z', - updated_at: '2025-10-02T08:00:00Z', - }, - quantity: 500, - }, - { - kandang: { - id: 14, - name: 'KDG-14', - status: 'MAINTENANCE', - location: { - id: 102, - name: 'Farm Beta', - address: 'Jl. Melati 2', - area: { id: 1002, name: 'Area Selatan' }, - }, - pic: { - id: 504, - id_user: 504, - email: 'agus@farm.co', - name: 'Agus Pratama', - }, - created_user: { - id: 9003, - id_user: 9003, - email: 'system@farm.co', - name: 'System', - }, - created_at: '2025-07-15T08:00:00Z', - updated_at: '2025-09-15T08:00:00Z', - }, - quantity: 450, - }, - ], - reason: 'Capacity balancing', - created_user: { - id: 9101, - id_user: 9101, - email: 'planner@farm.co', - name: 'Planning', - }, - created_at: '2025-10-11T06:00:00Z', - updated_at: '2025-10-11T06:00:00Z', - }, - { - id: 203, - transfer_date: '2025-10-12', - flock_source: { id: 3, name: 'Flock C' }, - flock_destination: { id: 11, name: 'Laying House 2' }, - quantity: 1100, - kandangs: [ - { - kandang: { - id: 21, - name: 'KDG-21', - status: 'ACTIVE', - location: { - id: 103, - name: 'Farm Gamma', - address: 'Dusun Gamma', - area: { id: 1003, name: 'Area Timur' }, - }, - pic: { - id: 505, - id_user: 505, - email: 'dewi@farm.co', - name: 'Dewi Lestari', - }, - created_user: { - id: 9004, - id_user: 9004, - email: 'ops@farm.co', - name: 'Ops Bot', - }, - created_at: '2025-09-10T08:00:00Z', - updated_at: '2025-10-05T08:00:00Z', - }, - quantity: 700, - }, - { - kandang: { - id: 22, - name: 'KDG-22', - status: 'ACTIVE', - location: { - id: 103, - name: 'Farm Gamma', - address: 'Dusun Gamma', - area: { id: 1003, name: 'Area Timur' }, - }, - pic: { - id: 506, - id_user: 506, - email: 'hadi@farm.co', - name: 'Hadi Santoso', - }, - created_user: { - id: 9004, - id_user: 9004, - email: 'ops@farm.co', - name: 'Ops Bot', - }, - created_at: '2025-09-12T08:00:00Z', - updated_at: '2025-10-06T08:00:00Z', - }, - quantity: 400, - }, - ], - reason: 'Align age group', - created_user: { - id: 9102, - id_user: 9102, - email: 'scheduler@farm.co', - name: 'Scheduler', - }, - created_at: '2025-10-12T06:00:00Z', - updated_at: '2025-10-12T06:00:00Z', - }, - { - id: 204, - transfer_date: '2025-10-13', - flock_source: { id: 1, name: 'Flock A' }, - flock_destination: { id: 12, name: 'Laying House 3' }, - quantity: 800, - kandangs: [ - { - kandang: { - id: 15, - name: 'KDG-15', - status: 'ACTIVE', - location: { - id: 101, - name: 'Farm Alpha', - address: 'Jl. Raya Alpha No. 1', - area: { id: 1001, name: 'Area Utara' }, - }, - pic: { - id: 507, - id_user: 507, - email: 'nadia@farm.co', - name: 'Nadia Putri', - }, - created_user: { - id: 9001, - id_user: 9001, - email: 'admin@farm.co', - name: 'System Admin', - }, - created_at: '2025-08-01T08:00:00Z', - updated_at: '2025-09-28T08:00:00Z', - }, - quantity: 800, - }, - ], - reason: 'Open capacity in LH3', - created_user: { - id: 9103, - id_user: 9103, - email: 'opslead@farm.co', - name: 'Ops Lead', - }, - created_at: '2025-10-13T06:00:00Z', - updated_at: '2025-10-13T06:00:00Z', - }, - { - id: 205, - transfer_date: '2025-10-14', - flock_source: { id: 4, name: 'Flock D' }, - flock_destination: { id: 11, name: 'Laying House 2' }, - quantity: 650, - kandangs: [ - { - kandang: { - id: 23, - name: 'KDG-23', - status: 'ACTIVE', - location: { - id: 104, - name: 'Farm Delta', - address: 'Jl. Delta 4', - area: { id: 1004, name: 'Area Barat' }, - }, - pic: { - id: 508, - id_user: 508, - email: 'yoga@farm.co', - name: 'Yoga Prabowo', - }, - created_user: { - id: 9005, - id_user: 9005, - email: 'ops@farm.co', - name: 'Ops Bot', - }, - created_at: '2025-09-20T08:00:00Z', - updated_at: '2025-10-10T08:00:00Z', - }, - quantity: 350, - }, - { - kandang: { - id: 24, - name: 'KDG-24', - status: 'ACTIVE', - location: { - id: 104, - name: 'Farm Delta', - address: 'Jl. Delta 4', - area: { id: 1004, name: 'Area Barat' }, - }, - pic: { - id: 509, - id_user: 509, - email: 'mega@farm.co', - name: 'Mega Anggraini', - }, - created_user: { - id: 9005, - id_user: 9005, - email: 'ops@farm.co', - name: 'Ops Bot', - }, - created_at: '2025-09-21T08:00:00Z', - updated_at: '2025-10-10T08:00:00Z', - }, - quantity: 300, - }, - ], - reason: 'Fill remaining LH2 slots', - created_user: { - id: 9104, - id_user: 9104, - email: 'scheduler@farm.co', - name: 'Scheduler', - }, - created_at: '2025-10-14T06:00:00Z', - updated_at: '2025-10-14T06:00:00Z', - }, - { - id: 206, - transfer_date: '2025-10-15', - flock_source: { id: 2, name: 'Flock B' }, - flock_destination: { id: 12, name: 'Laying House 3' }, - quantity: 720, - kandangs: [ - { - kandang: { - id: 16, - name: 'KDG-16', - status: 'ACTIVE', - location: { - id: 102, - name: 'Farm Beta', - address: 'Jl. Melati 2', - area: { id: 1002, name: 'Area Selatan' }, - }, - pic: { - id: 510, - id_user: 510, - email: 'rizky@farm.co', - name: 'Rizky Maulana', - }, - created_user: { - id: 9003, - id_user: 9003, - email: 'system@farm.co', - name: 'System', - }, - created_at: '2025-08-12T08:00:00Z', - updated_at: '2025-10-01T08:00:00Z', - }, - quantity: 420, - }, - { - kandang: { - id: 17, - name: 'KDG-17', - status: 'ACTIVE', - location: { - id: 102, - name: 'Farm Beta', - address: 'Jl. Melati 2', - area: { id: 1002, name: 'Area Selatan' }, - }, - pic: { - id: 511, - id_user: 511, - email: 'tia@farm.co', - name: 'Tia Safitri', - }, - created_user: { - id: 9003, - id_user: 9003, - email: 'system@farm.co', - name: 'System', - }, - created_at: '2025-08-18T08:00:00Z', - updated_at: '2025-10-01T08:00:00Z', - }, - quantity: 300, - }, - ], - reason: 'Stage-by-stage transfer', - created_user: { - id: 9105, - id_user: 9105, - email: 'opslead@farm.co', - name: 'Ops Lead', - }, - created_at: '2025-10-15T06:00:00Z', - updated_at: '2025-10-15T06:00:00Z', - }, - { - id: 207, - transfer_date: '2025-10-16', - flock_source: { id: 5, name: 'Flock E' }, - flock_destination: { id: 10, name: 'Laying House 1' }, - quantity: 500, - kandangs: [ - { - kandang: { - id: 18, - name: 'KDG-18', - status: 'ACTIVE', - location: { - id: 105, - name: 'Farm Epsilon', - address: 'Kp. Epsilon', - area: { id: 1005, name: 'Area Tengah' }, - }, - pic: { - id: 512, - id_user: 512, - email: 'lukas@farm.co', - name: 'Lukas Aditya', - }, - created_user: { - id: 9006, - id_user: 9006, - email: 'ops@farm.co', - name: 'Ops Bot', - }, - created_at: '2025-09-01T08:00:00Z', - updated_at: '2025-10-12T08:00:00Z', - }, - quantity: 250, - }, - { - kandang: { - id: 19, - name: 'KDG-19', - status: 'ACTIVE', - location: { - id: 105, - name: 'Farm Epsilon', - address: 'Kp. Epsilon', - area: { id: 1005, name: 'Area Tengah' }, - }, - pic: { - id: 513, - id_user: 513, - email: 'maya@farm.co', - name: 'Maya Kartika', - }, - created_user: { - id: 9006, - id_user: 9006, - email: 'ops@farm.co', - name: 'Ops Bot', - }, - created_at: '2025-09-03T08:00:00Z', - updated_at: '2025-10-12T08:00:00Z', - }, - quantity: 250, - }, - ], - reason: 'Trial batch', - created_user: { - id: 9106, - id_user: 9106, - email: 'planner@farm.co', - name: 'Planning', - }, - created_at: '2025-10-16T06:00:00Z', - updated_at: '2025-10-16T06:00:00Z', - }, - { - id: 208, - transfer_date: '2025-10-17', - flock_source: { id: 6, name: 'Flock F' }, - flock_destination: { id: 13, name: 'Laying House 4' }, - quantity: 1300, - kandangs: [ - { - kandang: { - id: 25, - name: 'KDG-25', - status: 'ACTIVE', - location: { - id: 106, - name: 'Farm Zeta', - address: 'Jl. Zeta 6', - area: { id: 1006, name: 'Area Tenggara' }, - }, - pic: { - id: 514, - id_user: 514, - email: 'rara@farm.co', - name: 'Rara Pertiwi', - }, - created_user: { - id: 9007, - id_user: 9007, - email: 'ops@farm.co', - name: 'Ops Bot', - }, - created_at: '2025-09-07T08:00:00Z', - updated_at: '2025-10-13T08:00:00Z', - }, - quantity: 700, - }, - { - kandang: { - id: 26, - name: 'KDG-26', - status: 'ACTIVE', - location: { - id: 106, - name: 'Farm Zeta', - address: 'Jl. Zeta 6', - area: { id: 1006, name: 'Area Tenggara' }, - }, - pic: { - id: 515, - id_user: 515, - email: 'doni@farm.co', - name: 'Doni Firmansyah', - }, - created_user: { - id: 9007, - id_user: 9007, - email: 'ops@farm.co', - name: 'Ops Bot', - }, - created_at: '2025-09-09T08:00:00Z', - updated_at: '2025-10-13T08:00:00Z', - }, - quantity: 600, - }, - ], - reason: 'Open new house', - created_user: { - id: 9107, - id_user: 9107, - email: 'scheduler@farm.co', - name: 'Scheduler', - }, - created_at: '2025-10-17T06:00:00Z', - updated_at: '2025-10-17T06:00:00Z', - }, - ], -}; - -// TODO: delete this dummy data -const FLOCK_SOURCE_DUMMY_DATA: BaseApiResponse = { - code: 200, - status: 'success', - message: 'Get all projectflocks successfully', - meta: { - page: 1, - limit: 10, - total_pages: 1, - total_results: 2, - }, - data: [ - { - id: 2, - name: 'Flock Banten', - totalQuantity: 300, - kandangs: [ - { - kandang: { - id: 3, - name: 'Cikaum 1', - status: 'ACTIVE', - location: { - id: 1, - name: 'Singaparna', - address: 'Tasik', - area: { - id: 1, - name: 'test area', - }, - }, - pic: { - id: 1, - id_user: 1, - email: 'admin@mbugroup.id', - name: 'Super Admin', - }, - }, - quantity: 100, - }, - { - kandang: { - id: 4, - name: 'Cikaum 2', - status: 'ACTIVE', - location: { - id: 1, - name: 'Singaparna', - address: 'Tasik', - area: { - id: 1, - name: 'test area', - }, - }, - pic: { - id: 1, - id_user: 1, - email: 'admin@mbugroup.id', - name: 'Super Admin', - }, - }, - quantity: 150, - }, - { - kandang: { - id: 5, - name: 'Cikaum 3', - status: 'ACTIVE', - location: { - id: 1, - name: 'Singaparna', - address: 'Tasik', - area: { - id: 1, - name: 'test area', - }, - }, - pic: { - id: 1, - id_user: 1, - email: 'admin@mbugroup.id', - name: 'Super Admin', - }, - }, - quantity: 50, - }, - ], - }, - - { - id: 3, - name: 'Flock Priangan', - totalQuantity: 200, - kandangs: [ - { - kandang: { - id: 3, - name: 'Cikaum 1', - status: 'ACTIVE', - location: { - id: 1, - name: 'Singaparna', - address: 'Tasik', - area: { - id: 1, - name: 'Priangan', - }, - }, - pic: { - id: 1, - id_user: 1, - email: 'admin@mbugroup.id', - name: 'Super Admin', - }, - }, - quantity: 100, - }, - { - kandang: { - id: 4, - name: 'Cikaum 2', - status: 'ACTIVE', - location: { - id: 1, - name: 'Singaparna', - address: 'Tasik', - area: { - id: 1, - name: 'test area', - }, - }, - pic: { - id: 1, - id_user: 1, - email: 'admin@mbugroup.id', - name: 'Super Admin', - }, - }, - quantity: 100, - }, - ], - }, - ], -}; +import { httpClient } from '@/services/http/client'; +import { ProjectFlockAvailableQuantity } from '@/types/api/production/project-flock'; +import { isResponseSuccess } from '@/lib/api-helper'; export class TransferToLayingService extends BaseApiService< TransferToLaying, @@ -744,133 +20,190 @@ export class TransferToLayingService extends BaseApiService< super(basePath); } - // TODO: remove dummy data and integrate to real API - override async getAllFetcher( - endpoint: string - ): Promise> { - // return await httpClientFetcher>(endpoint); - - await sleep(750); - - return GET_ALL_TRANSFER_TO_LAYING_DUMMY_DATA; - } - - // TODO: remove dummy data and integrate to real API - async getFlockSource(): Promise< - BaseApiResponse | undefined - > { - try { - // const getFlockSourcePath = `${this.basePath}/${flockSourcePath}`; - // const getSingleRes = await httpClient(getFlockSourcePath); - // return getSingleRes; - - await sleep(500); - - return FLOCK_SOURCE_DUMMY_DATA; - } catch (error) { - // if (axios.isAxiosError>(error)) { - // return error.response?.data; - // } - - return undefined; - } - } - - // TODO: remove dummy data and integrate to real API async approve( - id: number - ): Promise | undefined> { + id: number, + notes?: string + ): Promise | undefined> { try { - await sleep(750); + const approveRes = await httpClient>( + `${this.basePath}/approvals`, + { + method: 'POST', + body: { + action: 'APPROVED', + approvable_ids: [id], + notes: notes, + }, + } + ); - return { - code: 200, - status: 'success', - message: 'Berhasil approve data transfer ke laying!', - data: { - message: 'Berhasil approve data transfer ke laying!', - }, - }; + return approveRes; } catch (error) { - // if (axios.isAxiosError>(error)) { - // return error.response?.data; - // } + if (axios.isAxiosError>(error)) { + return error.response?.data; + } return undefined; } } - // TODO: remove dummy data and integrate to real API async bulkApprove( - ids: number[] - ): Promise | undefined> { + ids: number[], + notes?: string + ): Promise | undefined> { try { - await sleep(750); + const approveRes = await httpClient>( + `${this.basePath}/approvals`, + { + method: 'POST', + body: { + action: 'APPROVED', + approvable_ids: ids, + notes: notes, + }, + } + ); - return { - code: 200, - status: 'success', - message: 'Berhasil approve data transfer ke laying!', - data: { - message: 'Berhasil approve data transfer ke laying!', - }, - }; + return approveRes; } catch (error) { - // if (axios.isAxiosError>(error)) { - // return error.response?.data; - // } + if (axios.isAxiosError>(error)) { + return error.response?.data; + } return undefined; } } - // TODO: remove dummy data and integrate to real API async reject( - id: number - ): Promise | undefined> { + id: number, + notes?: string + ): Promise | undefined> { try { - await sleep(750); + const rejectRes = await httpClient>( + `${this.basePath}/approvals`, + { + method: 'POST', + body: { + action: 'REJECTED', + approvable_ids: [id], + notes: notes, + }, + } + ); - return { - code: 200, - status: 'success', - message: 'Berhasil reject data transfer ke laying!', - data: { - message: 'Berhasil reject data transfer ke laying!', - }, - }; + return rejectRes; } catch (error) { - // if (axios.isAxiosError>(error)) { - // return error.response?.data; - // } + if (axios.isAxiosError>(error)) { + return error.response?.data; + } return undefined; } } - // TODO: remove dummy data and integrate to real API async bulkReject( - ids: number[] - ): Promise | undefined> { + ids: number[], + notes?: string + ): Promise | undefined> { try { - await sleep(750); + const rejectRes = await httpClient>( + `${this.basePath}/approvals`, + { + method: 'POST', + body: { + action: 'REJECTED', + approvable_ids: ids, + notes: notes, + }, + } + ); - return { - code: 200, - status: 'success', - message: 'Berhasil reject data transfer ke laying!', - data: { - message: 'Berhasil reject data transfer ke laying!', - }, - }; + return rejectRes; } catch (error) { - // if (axios.isAxiosError>(error)) { - // return error.response?.data; - // } + if (axios.isAxiosError>(error)) { + return error.response?.data; + } + + return undefined; + } + } + + async getAvailabelQty(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.getAvailabelQty(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 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; } } } -export const TransferToLayingApi = new TransferToLayingService(''); +export const TransferToLayingApi = new TransferToLayingService( + '/production/transfer_layings' +);