From 4ec455b3b723cbd548de0938d73a69fbb4977e61 Mon Sep 17 00:00:00 2001 From: rstubryan Date: Wed, 10 Dec 2025 23:54:59 +0700 Subject: [PATCH] feat(FE): Add credit_term to purchase forms and types --- .gitlab-ci.yml | 2 +- .../order/PurchaseOrderStaffApprovalForm.tsx | 8 +- .../request/PurchaseRequestForm.schema.ts | 6 ++ .../form/request/PurchaseRequestForm.tsx | 79 ++++++++++++++++++- .../purchase/order/PurchaseOrderDetail.tsx | 2 - .../purchase/order/PurchaseOrderInvoice.tsx | 3 + src/types/api/purchase/purchase.d.ts | 10 ++- 7 files changed, 99 insertions(+), 11 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f0187471..6028a8cb 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -160,6 +160,6 @@ deploy:dev: # variables: # S3_BUCKET: "lti-erp.mbugroup.id" # CLOUDFRONT_DISTRIBUTION_ID: "ddfd" -# environment: +# environment: # name: production diff --git a/src/components/pages/purchase/form/order/PurchaseOrderStaffApprovalForm.tsx b/src/components/pages/purchase/form/order/PurchaseOrderStaffApprovalForm.tsx index 94998a37..1fcd7a94 100644 --- a/src/components/pages/purchase/form/order/PurchaseOrderStaffApprovalForm.tsx +++ b/src/components/pages/purchase/form/order/PurchaseOrderStaffApprovalForm.tsx @@ -314,7 +314,9 @@ const PurchaseOrderStaffApprovalForm = ({ const isNewItemForm = !formItem.purchase_item_id || formItem.purchase_item_id === 0; - let cleanPayload: UpdateStaffApprovalRequestPayload['items'][0]; + let cleanPayload: NonNullable< + UpdateStaffApprovalRequestPayload['items'] + >[0]; if (isNewItemForm) { cleanPayload = { @@ -362,7 +364,9 @@ const PurchaseOrderStaffApprovalForm = ({ const isNewItemForm = !formItem.purchase_item_id || formItem.purchase_item_id === 0; - let cleanPayload: UpdateStaffApprovalRequestPayload['items'][0]; + let cleanPayload: NonNullable< + UpdateStaffApprovalRequestPayload['items'] + >[0]; if (isNewItemForm) { cleanPayload = { diff --git a/src/components/pages/purchase/form/request/PurchaseRequestForm.schema.ts b/src/components/pages/purchase/form/request/PurchaseRequestForm.schema.ts index 05167715..67a694bc 100644 --- a/src/components/pages/purchase/form/request/PurchaseRequestForm.schema.ts +++ b/src/components/pages/purchase/form/request/PurchaseRequestForm.schema.ts @@ -7,6 +7,7 @@ type PurchaseRequestFormSchemaType = { label: string; } | null; supplier_id: number; + credit_term: number; area?: { value: number; label: string; @@ -81,6 +82,10 @@ export const PurchaseRequestFormSchema: Yup.ObjectSchema ({ warehouse_id: Number(item.warehouse_id) || 0, @@ -338,6 +342,27 @@ const PurchaseRequestForm = ({ }; // ===== UTILITY FUNCTIONS ===== + const updateCreditTermBasedOnSupplier = useCallback( + (supplierId: number) => { + if (supplierId > 0 && isResponseSuccess(supplierRawData)) { + const supplierData = supplierRawData.data.find( + (s: Supplier) => s.id === supplierId + ); + if (supplierData?.due_date) { + formik.setFieldTouched('credit_term', false); + formik.setFieldValue('credit_term', supplierData.due_date.toString()); + } else { + formik.setFieldTouched('credit_term', false); + formik.setFieldValue('credit_term', ''); + } + } else { + formik.setFieldTouched('credit_term', false); + formik.setFieldValue('credit_term', ''); + } + }, + [supplierRawData] + ); + const resetPurchaseItems = useCallback(() => { if (formik.values.items) { formik.values.items.forEach((_, idx) => { @@ -352,6 +377,16 @@ const PurchaseRequestForm = ({ }, []); // ===== SIDE EFFECTS ===== + useEffect(() => { + if (formik.values.supplier_id && Number(formik.values.supplier_id) > 0) { + updateCreditTermBasedOnSupplier(Number(formik.values.supplier_id)); + resetPurchaseItems(); + } else { + formik.setFieldTouched('credit_term', false); + formik.setFieldValue('credit_term', ''); + resetPurchaseItems(); + } + }, [formik.values.supplier_id]); // ===== FORM HANDLERS ===== const handleSupplierChange = useCallback( @@ -367,6 +402,23 @@ const PurchaseRequestForm = ({ [] ); + const handleCreditTermChange = useCallback( + (e: React.ChangeEvent) => { + const value = e.target.value; + + formik.setFieldTouched('credit_term', true); + formik.setFieldValue('credit_term', value); + }, + [] + ); + + const handleCreditTermBlur = useCallback( + (e: React.FocusEvent) => { + formik.handleBlur(e); + }, + [formik] + ); + const handleAreaChange = useCallback( (val: OptionType | OptionType[] | null) => { const area = val as OptionType | null; @@ -447,7 +499,7 @@ const PurchaseRequestForm = ({ body: 'flex flex-col gap-6', }} > -
+
+ + -
+
{ {purchaseData?.supplier?.alias || ''}) {purchaseData?.supplier?.category || '-'} + + Credit Term: {purchaseData?.credit_term || 0} hari + Due Date:{' '} {purchaseData?.due_date diff --git a/src/types/api/purchase/purchase.d.ts b/src/types/api/purchase/purchase.d.ts index 2dcde2d9..e4de565b 100644 --- a/src/types/api/purchase/purchase.d.ts +++ b/src/types/api/purchase/purchase.d.ts @@ -51,6 +51,7 @@ export type BasePurchase = { po_document_path?: string | null; po_date: string; supplier: Supplier; + credit_term?: number; due_date: string; notes?: string | null; deleted_at?: string | null; @@ -66,8 +67,9 @@ export type Purchase = BaseMetadata & BasePurchase; export type CreatePurchaseRequestPayload = { supplier_id: number; + credit_term: number; notes?: string | null; - items: { + items?: { warehouse_id: number; product_id: number; qty: number; @@ -77,7 +79,7 @@ export type CreatePurchaseRequestPayload = { export type CreateStaffApprovalRequestPayload = { action: 'APPROVED' | 'REJECTED'; notes?: string | null; - items: { + items?: { purchase_item_id: number; qty: number; price: number; @@ -88,7 +90,7 @@ export type CreateStaffApprovalRequestPayload = { export type UpdateStaffApprovalRequestPayload = { action: 'APPROVED' | 'REJECTED'; notes?: string | null; - items: Array<{ + items?: Array<{ purchase_item_id?: number; product_id?: number; warehouse_id?: number; @@ -106,7 +108,7 @@ export type CreateManagerApprovalRequestPayload = { export type CreateAcceptApprovalRequestPayload = { action: 'APPROVED' | 'REJECTED'; notes?: string | null; - items: { + items?: { purchase_item_id: number; received_date: string; travel_number: string;