refactor(FE-208,212): enhance PurchaseRequestForm with product and product warehouse fields

This commit is contained in:
rstubryan
2025-10-30 10:39:23 +07:00
parent b0e8a460fd
commit a8fee20133
4 changed files with 73 additions and 32 deletions
@@ -2,6 +2,8 @@ import * as Yup from 'yup';
import { Supplier } from '@/types/api/master-data/supplier';
import { Warehouse } from '@/types/api/master-data/warehouse';
import { CreatePurchaseRequestPayload } from '@/types/api/purchase/purchase';
import { Product } from '@/types/api/master-data/product';
import { ProductWarehouse } from '@/types/api/inventory/product-warehouse';
export const PurchaseRequestFormSchema = Yup.object({
supplier: Yup.object({
@@ -28,10 +30,18 @@ export const PurchaseRequestFormSchema = Yup.object({
.required('Warehouse wajib diisi!')
.min(1, 'Produk wajib diisi!')
.typeError('Warehouse harus berupa angka!'),
product: Yup.object({
value: Yup.number().min(1).required(),
label: Yup.string().required(),
}).nullable(),
product_id: Yup.number()
.required('Produk wajib diisi!')
.min(1, 'Produk wajib diisi!')
.typeError('Produk harus berupa angka!'),
product_warehouse: Yup.object({
value: Yup.number().min(1).required(),
label: Yup.string().required(),
}).nullable(),
product_warehouse_id: Yup.number()
.required('Product warehouse wajib diisi!')
.min(1, 'Product warehouse wajib diisi!')
@@ -57,10 +67,16 @@ export type PurchaseRequestFormValues = Yup.InferType<
typeof PurchaseRequestFormSchema
>;
type PurchaseRequestFormData = Partial<CreatePurchaseRequestPayload> & {
type PurchaseRequestFormData = {
supplier?: Supplier;
warehouse?: Warehouse[];
purchase_items?: CreatePurchaseRequestPayload['purchase_items'];
supplier_id?: number;
credit_term?: number;
notes?: string | null;
purchase_items?: (CreatePurchaseRequestPayload['purchase_items'][0] & {
warehouse?: Warehouse;
product?: Product;
product_warehouse?: ProductWarehouse;
})[];
};
export const getPurchaseRequestFormInitialValues = (
@@ -73,22 +89,30 @@ export const getPurchaseRequestFormInitialValues = (
}
: null,
supplier_id: initialValues?.supplier_id ?? 0,
credit_term: initialValues?.credit_term ?? 0,
credit_term: initialValues?.credit_term ?? 1,
notes: initialValues?.notes ?? '',
purchase_items: initialValues?.purchase_items?.map(
(item: NonNullable<CreatePurchaseRequestPayload['purchase_items']>[0]) => ({
warehouse: initialValues?.warehouse?.find(
(w) => w.id === item.warehouse_ids
)
(item: NonNullable<PurchaseRequestFormData['purchase_items']>[0]) => ({
warehouse: item.warehouse
? {
value: item.warehouse_ids,
label:
initialValues.warehouse.find((w) => w.id === item.warehouse_ids)
?.name || '',
value: item.warehouse.id,
label: item.warehouse.name,
}
: null,
warehouse_ids: item.warehouse_ids,
product: item.product
? {
value: item.product.id,
label: item.product.name,
}
: null,
product_id: item.product_id,
product_warehouse: item.product_warehouse
? {
value: item.product_warehouse.id,
label: item.product_warehouse.product.name,
}
: null,
product_warehouse_id: item.product_warehouse_id,
total_qty: item.total_qty,
price: item.price,
@@ -97,7 +121,9 @@ export const getPurchaseRequestFormInitialValues = (
{
warehouse: null,
warehouse_ids: 0,
product: null,
product_id: 0,
product_warehouse: null,
product_warehouse_id: 0,
total_qty: 0,
price: 0,
@@ -97,21 +97,18 @@ const PurchaseRequestForm = ({
validateOnBlur: true,
onSubmit: async (values) => {
const payload: CreatePurchaseRequestPayload = {
supplier_id: values.supplier_id,
supplier_id: values.supplier_id || 0,
credit_term: values.credit_term || 0,
notes: values.notes || '',
purchase_items: (values.purchase_items || []).map((item) => ({
warehouse_ids: item.warehouse_ids,
product_id: item.product_id,
product_warehouse_id: item.product_warehouse_id,
total_qty:
typeof item.total_qty === 'number'
? item.total_qty
: parseFloat(String(item.total_qty)) || 0,
warehouse_ids: item.warehouse_ids || 0,
product_id: item.product_id || 0,
product_warehouse_id: item.product_warehouse_id || 0,
total_qty: item.total_qty || 0,
price:
typeof item.price === 'number'
? item.price
: parseFloat(String(item.price)) || 0,
: parseFloat(item.price) || 0,
})),
};
@@ -149,8 +146,11 @@ const PurchaseRequestForm = ({
const newPurchaseItems = [
...(formik.values.purchase_items || []),
{
warehouse: null,
warehouse_ids: 0,
product: null,
product_id: 0,
product_warehouse: null,
product_warehouse_id: 0,
total_qty: 0,
price: 0,
@@ -179,12 +179,23 @@ const PurchaseRequestForm = ({
field: string,
value: string | number
) => {
if (field === 'warehouse_ids') {
formik.setFieldValue(`purchase_items.${idx}.${field}`, value);
} else {
const integerFields = [
'warehouse_ids',
'product_id',
'product_warehouse_id',
'total_qty',
];
const floatFields = ['price'];
if (integerFields.includes(field)) {
const numValue = typeof value === 'string' ? parseInt(value) || 0 : value;
formik.setFieldValue(`purchase_items.${idx}.${field}`, numValue);
} else if (floatFields.includes(field)) {
const numValue =
typeof value === 'string' ? parseFloat(value) || 0 : value;
formik.setFieldValue(`purchase_items.${idx}.${field}`, numValue);
} else {
formik.setFieldValue(`purchase_items.${idx}.${field}`, value);
}
};
@@ -388,6 +399,7 @@ const PurchaseRequestForm = ({
</td>
<td>
<TextInput
required
name={`purchase_items.${idx}.product_warehouse_id`}
value={item.product_warehouse_id || ''}
onChange={(e) =>
@@ -6,7 +6,7 @@ import { PurchaseApi } from '@/services/api/purchasing';
import {
CreatePurchaseRequestPayload,
UpdatePurchaseRequestPayload,
} from '@/types/api/purchase/purchasing';
} from '@/types/api/purchase/purchase';
import { isResponseError } from '@/lib/api-helper';
export const usePurchaseRequestFormHandlers = (initialValuesId?: number) => {
@@ -30,7 +30,10 @@ export const usePurchaseRequestFormHandlers = (initialValuesId?: number) => {
);
const updatePurchaseRequestHandler = useCallback(
async (purchaseRequestId: number, payload: UpdatePurchaseRequestPayload) => {
async (
purchaseRequestId: number,
payload: UpdatePurchaseRequestPayload
) => {
const res = await PurchaseApi.update(purchaseRequestId, payload);
if (res?.status === 'error') {
setPurchaseRequestFormErrorMessage(res.message);
@@ -67,4 +70,4 @@ export const usePurchaseRequestFormHandlers = (initialValuesId?: number) => {
deletePurchaseRequestClickHandler,
confirmationModalDeleteClickHandler,
};
};
};
+5 -5
View File
@@ -1,12 +1,12 @@
import { BaseApiService } from './base';
import {
CreatePurchasePayload,
CreatePurchaseRequestPayload,
Purchase,
UpdatePurchasePayload,
} from '@/types/api/purchase/purchasing';
UpdatePurchaseRequestPayload,
} from '@/types/api/purchase/purchase';
export const PurchaseApi = new BaseApiService<
Purchase,
CreatePurchasePayload,
UpdatePurchasePayload
CreatePurchaseRequestPayload,
UpdatePurchaseRequestPayload
>('/purchase-requests');