mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-24 07:15:44 +00:00
refactor(FE-62,63,65): refactor Movement and ProductWarehouse APIs, update MovementForm schema, and enhance MovementTable functionality
This commit is contained in:
@@ -13,7 +13,7 @@ export type ProductSchema = {
|
||||
export type DeliverySchema = {
|
||||
delivery_cost: number;
|
||||
delivery_cost_per_item?: number | undefined;
|
||||
document: string | File;
|
||||
document?: File | string | null;
|
||||
driver_name: string;
|
||||
vehicle_plate: string;
|
||||
supplier: {
|
||||
@@ -64,23 +64,15 @@ const DeliveryObjectSchema: Yup.ObjectSchema<DeliverySchema> = Yup.object({
|
||||
.transform((value) => (isNaN(value) ? undefined : value))
|
||||
.min(0, 'Biaya per item minimal 0!')
|
||||
.typeError('Biaya per item harus berupa angka!'),
|
||||
document: Yup.mixed<string | File>()
|
||||
.required('Dokumen wajib diisi!')
|
||||
.test(
|
||||
'fileType',
|
||||
'Mohon upload file berformat PDF atau JPEG/JPG.',
|
||||
(value) =>
|
||||
typeof value === 'string' ||
|
||||
(value instanceof File &&
|
||||
['application/pdf', 'image/jpeg', 'image/jpg'].includes(value.type))
|
||||
)
|
||||
.test(
|
||||
'fileSize',
|
||||
'Ukuran dokumen maksimal 2 MB!',
|
||||
(value) =>
|
||||
typeof value === 'string' ||
|
||||
(value instanceof File && value.size <= 2 * 1024 * 1024)
|
||||
),
|
||||
document_index: Yup.number().optional(),
|
||||
document: Yup.mixed<File | string>()
|
||||
.nullable()
|
||||
.test('fileSize', 'Ukuran dokumen maksimal 2 MB', (value) => {
|
||||
if (!value) return true;
|
||||
if (typeof value === 'string') return true;
|
||||
if (value instanceof File) return value.size <= 2 * 1024 * 1024;
|
||||
return false;
|
||||
}),
|
||||
driver_name: Yup.string().required('Nama sopir wajib diisi!'),
|
||||
vehicle_plate: Yup.string().required('Plat nomor wajib diisi!'),
|
||||
supplier: Yup.object({
|
||||
@@ -145,24 +137,25 @@ export const getMovementFormInitialValues = (
|
||||
: null,
|
||||
destination_warehouse_id: initialValues?.destination_warehouse?.id ?? 0,
|
||||
products:
|
||||
initialValues?.products?.map((p) => ({
|
||||
product: { value: p.product.id, label: p.product.name },
|
||||
product_id: p.product.id,
|
||||
product_qty: p.product_qty,
|
||||
initialValues?.details?.map((p) => ({
|
||||
product: { value: p.product_id, label: '' },
|
||||
product_id: p.product_id,
|
||||
product_qty: p.quantity,
|
||||
})) ?? [],
|
||||
deliveries:
|
||||
initialValues?.deliveries?.map((d) => ({
|
||||
delivery_cost: d.delivery_cost,
|
||||
delivery_cost_per_item: d.delivery_cost_per_item,
|
||||
document: d.document,
|
||||
delivery_cost: d.shipping_cost_total,
|
||||
delivery_cost_per_item: d.shipping_cost_item,
|
||||
document_index: 0,
|
||||
document: d.document_path || null,
|
||||
driver_name: d.driver_name,
|
||||
vehicle_plate: d.vehicle_plate,
|
||||
supplier: { value: d.supplier.id, label: d.supplier.name },
|
||||
supplier_id: d.supplier.id,
|
||||
products: d.products.map((p) => ({
|
||||
product: { value: p.product.id, label: p.product.name },
|
||||
product_id: p.product.id,
|
||||
product_qty: p.product_qty,
|
||||
supplier_id: d.supplier_id,
|
||||
products: d.items.map((p) => ({
|
||||
product: { value: 0, label: '' },
|
||||
product_id: 0,
|
||||
product_qty: p.quantity,
|
||||
})),
|
||||
})) ?? [],
|
||||
});
|
||||
|
||||
@@ -8,7 +8,6 @@ import {
|
||||
UpdateMovementPayload,
|
||||
} from '@/types/api/inventory/movement';
|
||||
import { isResponseError } from '@/lib/api-helper';
|
||||
import { containsFile, toFormData } from '@/lib/form-data';
|
||||
|
||||
export const useMovementFormHandlers = (initialValuesId?: number) => {
|
||||
const router = useRouter();
|
||||
@@ -17,13 +16,44 @@ export const useMovementFormHandlers = (initialValuesId?: number) => {
|
||||
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
||||
|
||||
const createMovementHandler = useCallback(
|
||||
async (payload: CreateMovementPayload) => {
|
||||
const finalPayload = containsFile(payload)
|
||||
? (toFormData(payload) as unknown as CreateMovementPayload)
|
||||
: payload;
|
||||
async (payload: CreateMovementPayload, documents: File[] = []) => {
|
||||
console.log('=== CREATE HANDLER DEBUG ===');
|
||||
console.log('1. Received payload:', payload);
|
||||
console.log('2. Documents count:', documents.length);
|
||||
|
||||
let finalPayload: CreateMovementPayload | FormData;
|
||||
|
||||
if (documents.length > 0) {
|
||||
// Ada dokumen: kirim sebagai FormData dengan "data" field
|
||||
console.log('3. Creating FormData (has documents)');
|
||||
const formData = new FormData();
|
||||
formData.append('data', JSON.stringify(payload));
|
||||
documents.forEach((file, index) => {
|
||||
formData.append(`documents[${index}]`, file);
|
||||
});
|
||||
|
||||
console.log('4. FormData entries:');
|
||||
for (const [key, value] of formData.entries()) {
|
||||
if (value instanceof File) {
|
||||
console.log(` ${key}: [File] ${value.name} (${value.size} bytes)`);
|
||||
} else {
|
||||
console.log(` ${key}: ${value}`);
|
||||
}
|
||||
}
|
||||
|
||||
finalPayload = formData as unknown as CreateMovementPayload;
|
||||
} else {
|
||||
// Tidak ada dokumen: kirim sebagai JSON biasa
|
||||
console.log('3. Sending as JSON (no documents)');
|
||||
console.log('4. Payload:', JSON.stringify(payload, null, 2));
|
||||
finalPayload = payload;
|
||||
}
|
||||
|
||||
console.log('=== END CREATE HANDLER DEBUG ===');
|
||||
|
||||
const res = await MovementApi.create(finalPayload);
|
||||
if (isResponseError(res)) {
|
||||
console.error('API Error:', res);
|
||||
setMovementFormErrorMessage(res.message);
|
||||
return;
|
||||
}
|
||||
@@ -34,13 +64,45 @@ export const useMovementFormHandlers = (initialValuesId?: number) => {
|
||||
);
|
||||
|
||||
const updateMovementHandler = useCallback(
|
||||
async (movementId: number, payload: UpdateMovementPayload) => {
|
||||
const finalPayload = containsFile(payload)
|
||||
? (toFormData(payload) as unknown as UpdateMovementPayload)
|
||||
: payload;
|
||||
async (movementId: number, payload: UpdateMovementPayload, documents: File[] = []) => {
|
||||
console.log('=== UPDATE HANDLER DEBUG ===');
|
||||
console.log('1. Received payload:', payload);
|
||||
console.log('2. Movement ID:', movementId);
|
||||
console.log('3. Documents count:', documents.length);
|
||||
|
||||
let finalPayload: UpdateMovementPayload | FormData;
|
||||
|
||||
if (documents.length > 0) {
|
||||
// Ada dokumen: kirim sebagai FormData dengan "data" field
|
||||
console.log('4. Creating FormData (has documents)');
|
||||
const formData = new FormData();
|
||||
formData.append('data', JSON.stringify(payload));
|
||||
documents.forEach((file, index) => {
|
||||
formData.append(`documents[${index}]`, file);
|
||||
});
|
||||
|
||||
console.log('5. FormData entries:');
|
||||
for (const [key, value] of formData.entries()) {
|
||||
if (value instanceof File) {
|
||||
console.log(` ${key}: [File] ${value.name} (${value.size} bytes)`);
|
||||
} else {
|
||||
console.log(` ${key}: ${value}`);
|
||||
}
|
||||
}
|
||||
|
||||
finalPayload = formData as unknown as UpdateMovementPayload;
|
||||
} else {
|
||||
// Tidak ada dokumen: kirim sebagai JSON biasa
|
||||
console.log('4. Sending as JSON (no documents)');
|
||||
console.log('5. Payload:', JSON.stringify(payload, null, 2));
|
||||
finalPayload = payload;
|
||||
}
|
||||
|
||||
console.log('=== END UPDATE HANDLER DEBUG ===');
|
||||
|
||||
const res = await MovementApi.update(movementId, finalPayload);
|
||||
if (res?.status === 'error') {
|
||||
console.error('API Error:', res);
|
||||
setMovementFormErrorMessage(res.message);
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user