diff --git a/src/components/pages/closing/ClosingIncomingSapronaksTable.tsx b/src/components/pages/closing/ClosingIncomingSapronaksTable.tsx index 53e45710..eda7e756 100644 --- a/src/components/pages/closing/ClosingIncomingSapronaksTable.tsx +++ b/src/components/pages/closing/ClosingIncomingSapronaksTable.tsx @@ -1,6 +1,7 @@ 'use client'; import { ChangeEventHandler, useEffect, useState } from 'react'; +import { useSearchParams } from 'next/navigation'; import useSWR from 'swr'; import { ColumnDef, SortingState } from '@tanstack/react-table'; @@ -23,6 +24,9 @@ interface ClosingIncomingSapronaksTableProps { const ClosingIncomingSapronaksTable = ({ projectFlockId, }: ClosingIncomingSapronaksTableProps) => { + const searchParams = useSearchParams(); + const kandangId = searchParams.get('kandangId'); + const { state: tableFilterState, updateFilter, @@ -43,7 +47,7 @@ const ClosingIncomingSapronaksTable = ({ const { data: incomingSapronaks, isLoading: isLoadingIncomingSapronaks } = useSWR( - `${ClosingApi.basePath}/${projectFlockId}/sapronak${getTableFilterQueryString()}&type=incoming`, + `${ClosingApi.basePath}/${projectFlockId}/sapronak${getTableFilterQueryString()}&type=incoming&kandang_id=${kandangId ? `${kandangId}` : ''}`, ClosingApi.getAllIncomingSapronakFetcher, { keepPreviousData: true, diff --git a/src/components/pages/closing/ClosingOutgoingSapronaksTable.tsx b/src/components/pages/closing/ClosingOutgoingSapronaksTable.tsx index 5662cff1..ac918561 100644 --- a/src/components/pages/closing/ClosingOutgoingSapronaksTable.tsx +++ b/src/components/pages/closing/ClosingOutgoingSapronaksTable.tsx @@ -1,6 +1,7 @@ 'use client'; import { ChangeEventHandler, useEffect, useState } from 'react'; +import { useSearchParams } from 'next/navigation'; import useSWR from 'swr'; import { ColumnDef, SortingState } from '@tanstack/react-table'; @@ -23,6 +24,9 @@ interface ClosingOutgoingSapronaksTableProps { const ClosingOutgoingSapronaksTable = ({ projectFlockId, }: ClosingOutgoingSapronaksTableProps) => { + const searchParams = useSearchParams(); + const kandangId = searchParams.get('kandangId'); + const { state: tableFilterState, updateFilter, @@ -43,7 +47,7 @@ const ClosingOutgoingSapronaksTable = ({ const { data: outgoingSapronaks, isLoading: isLoadingOutgoingSapronaks } = useSWR( - `${ClosingApi.basePath}/${projectFlockId}/sapronak${getTableFilterQueryString()}&type=outgoing`, + `${ClosingApi.basePath}/${projectFlockId}/sapronak${getTableFilterQueryString()}&type=outgoing&kandang_id=${kandangId ? `${kandangId}` : ''}`, ClosingApi.getAllOutgoingSapronakFetcher, { keepPreviousData: true, diff --git a/src/components/pages/closing/ClosingProductionDataTabContent.tsx b/src/components/pages/closing/ClosingProductionDataTabContent.tsx index 0f15d5b9..9295d283 100644 --- a/src/components/pages/closing/ClosingProductionDataTabContent.tsx +++ b/src/components/pages/closing/ClosingProductionDataTabContent.tsx @@ -1,5 +1,6 @@ 'use client'; +import { useSearchParams } from 'next/navigation'; import useSWR from 'swr'; import { ClosingApi } from '@/services/api/closing'; import { isResponseSuccess } from '@/lib/api-helper'; @@ -12,9 +13,12 @@ interface ClosingProductionDataTabContentProps { const ClosingProductionDataTabContent = ({ projectFlockId, }: ClosingProductionDataTabContentProps) => { + const searchParams = useSearchParams(); + const kandangId = searchParams.get('kandangId'); + const { data: productionData, isLoading } = useSWR( - `${ClosingApi.basePath}/${projectFlockId}/production-data`, - () => ClosingApi.getProductionData(projectFlockId) + `${ClosingApi.basePath}/${projectFlockId}/production-data?kandang_id=${kandangId ? `${kandangId}` : ''}`, + () => ClosingApi.getProductionData(projectFlockId, Number(kandangId)) ); if (isLoading) { diff --git a/src/components/pages/marketing/form/MarketingForm.schema.ts b/src/components/pages/marketing/form/MarketingForm.schema.ts index d81cdb9c..b09129c3 100644 --- a/src/components/pages/marketing/form/MarketingForm.schema.ts +++ b/src/components/pages/marketing/form/MarketingForm.schema.ts @@ -11,6 +11,13 @@ import { type MarketingSchemaType = { customer_id: number | undefined; sales_person_id: number | undefined; + sales_person: + | { + value: number; + label: string; + } + | undefined + | null; customer: | { value: number; @@ -33,7 +40,11 @@ type DeliveryOrderSchemaType = { export const SalesOrderSchema: Yup.ObjectSchema = Yup.object({ customer_id: Yup.number().required('Customer wajib diisi!'), - sales_person_id: Yup.number().required('Sales Person wajib diisi!'), + sales_person_id: Yup.number().required('Sales wajib diisi!'), + sales_person: Yup.object({ + value: Yup.number().required(), + label: Yup.string().required(), + }).nullable(), customer: Yup.object({ value: Yup.number().required(), label: Yup.string().required(), diff --git a/src/components/pages/marketing/form/MarketingForm.tsx b/src/components/pages/marketing/form/MarketingForm.tsx index 2fbca835..be4367cb 100644 --- a/src/components/pages/marketing/form/MarketingForm.tsx +++ b/src/components/pages/marketing/form/MarketingForm.tsx @@ -50,6 +50,8 @@ import { DeliveryOrderProductFormValues } from '@/components/pages/marketing/for import RequirePermission from '@/components/helper/RequirePermission'; import AlertErrorList from '@/components/helper/form/FormErrors'; import { useFormikErrorList } from '@/services/hooks/useFormikErrorList'; +import { CreatedUser } from '@/types/api/api-general'; +import { UserApi } from '@/services/api/user'; const MemoizedSalesOrderProductTable = memo(SalesOrderProductTable); const MemoizedSalesOrderProductForm = memo(SalesOrderProductForm); @@ -244,7 +246,15 @@ const MarketingForm = ({ const { options: customerOptions, isLoadingOptions: isLoadingCustomerOptions, + setInputValue: setInputCustomerValue, + loadMore: loadMoreCustomer, } = useSelect(CustomerApi.basePath, 'id', 'name'); + const { + options: salesOptions, + isLoadingOptions: isLoadingSalesOptions, + setInputValue: setInputSalesValue, + loadMore: loadMoreSales, + } = useSelect(UserApi.basePath, 'id', 'name'); // ================== SETUP FORMIK ================== const formikInitialValues = useMemo< @@ -255,6 +265,12 @@ const MarketingForm = ({ notes: initialValues?.notes || undefined, customer_id: initialValues?.customer?.id || undefined, sales_person_id: initialValues?.sales_person?.id || 1, + sales_person: initialValues?.sales_person + ? { + value: initialValues.sales_person.id, + label: initialValues.sales_person.name, + } + : null, customer: initialValues?.customer ? { value: initialValues.customer.id, @@ -443,6 +459,13 @@ const MarketingForm = ({ }, [] ); + const handleChangeSalesPerson = useCallback( + (val: OptionType | OptionType[] | null) => { + formik.setFieldValue('sales_person_id', (val as OptionType)?.value); + formik.setFieldValue('sales_person', val as OptionType); + }, + [] + ); const handleDelete = useCallback(() => { deleteModal.openModal(); }, [deleteModal]); @@ -580,6 +603,7 @@ const MarketingForm = ({ className={{ wrapper: 'bg-white w-full', }} + variant='bordered' >
- -
+
+ + +
+
Total Penjualan {formatCurrency(grandTotal)}{' '} diff --git a/src/components/pages/marketing/form/repeater/delivery-order/DeliverOrderProduct.tsx b/src/components/pages/marketing/form/repeater/delivery-order/DeliverOrderProduct.tsx index 25a20982..da3b2fee 100644 --- a/src/components/pages/marketing/form/repeater/delivery-order/DeliverOrderProduct.tsx +++ b/src/components/pages/marketing/form/repeater/delivery-order/DeliverOrderProduct.tsx @@ -18,6 +18,11 @@ import * as Yup from 'yup'; import { isResponseSuccess } from '@/lib/api-helper'; import AlertErrorList from '@/components/helper/form/FormErrors'; import { useFormikErrorList } from '@/services/hooks/useFormikErrorList'; +import useSWR from 'swr'; +import { ProductApi } from '@/services/api/master-data'; + +const roundWeight = (value: number) => Number(value.toFixed(2)); +const roundPrice = (value: number) => Math.round(value); const DeliveryOrderProductForm = ({ formState, @@ -43,6 +48,17 @@ const DeliveryOrderProductForm = ({ ); const [currentInput, setCurrentInput] = useState(''); + // ============ Fetch Data ============ + const { data: productData } = useSWR( + selectedProduct?.value + ? ProductApi.basePath + '/' + selectedProduct?.value + : null, + () => + selectedProduct?.value + ? ProductApi.getSingle(Number(selectedProduct?.value)) + : undefined + ); + const salesOrder = salesOrders.find( (item) => item.id === initialValues?.marketing_product_id ); @@ -113,22 +129,60 @@ const DeliveryOrderProductForm = ({ const handleBlurField = (field: string) => { setCurrentInput(field); - const { qty, unit_price, total_price, avg_weight, total_weight } = - formik.values; - if (field === 'unit_price' || field === 'total_price' || field === 'qty') { - if (qty && unit_price && (field === 'unit_price' || field === 'qty')) { - formik.setFieldValue('total_price', Number(qty) * Number(unit_price)); - } else if (qty && total_price && field === 'total_price') { - formik.setFieldValue('unit_price', Number(total_price) / Number(qty)); + const qty = Number(formik.values.qty || 0); + const avgWeight = Number(formik.values.avg_weight || 0); + const totalWeight = Number(formik.values.total_weight || 0); + const unitPrice = Number(formik.values.unit_price || 0); + const totalPrice = Number(formik.values.total_price || 0); + + if (qty <= 0) return; + + switch (field) { + // ===== SOURCE FIELDS ===== + case 'qty': { + if (avgWeight > 0) { + formik.setFieldValue('total_weight', roundWeight(qty * avgWeight)); + } + + if (unitPrice > 0) { + formik.setFieldValue('total_price', roundPrice(qty * unitPrice)); + } + break; } - } - if (field === 'avg_weight' || field === 'total_weight' || field === 'qty') { - if (qty && avg_weight && (field === 'avg_weight' || field === 'qty')) { - formik.setFieldValue('total_weight', Number(qty) * Number(avg_weight)); - } else if (qty && total_weight && field === 'total_weight') { - formik.setFieldValue('avg_weight', Number(total_weight) / Number(qty)); + case 'avg_weight': { + if (avgWeight > 0) { + const tw = roundWeight(qty * avgWeight); + formik.setFieldValue('total_weight', tw); + + if (unitPrice > 0) { + formik.setFieldValue('total_price', roundPrice(qty * unitPrice)); + } + } + break; + } + + case 'unit_price': { + if (unitPrice > 0) { + formik.setFieldValue('total_price', roundPrice(qty * unitPrice)); + } + break; + } + + // ===== TOTAL EDITABLE ===== + case 'total_weight': { + if (totalWeight > 0) { + formik.setFieldValue('avg_weight', roundWeight(totalWeight / qty)); + } + break; + } + + case 'total_price': { + if (totalPrice > 0) { + formik.setFieldValue('unit_price', roundPrice(totalPrice / qty)); + } + break; } } }; @@ -183,7 +237,7 @@ const DeliveryOrderProductForm = ({
)} -
+
- +
+
+
+ + {isResponseSuccess(productData) + ? productData?.data?.uom.name + : ''} + +
+ } bottomLabel={ formik.values.marketing_product_id ? 'Stok dijual: ' + salesOrders?.find( (item) => item.id === formik.values.marketing_product_id - )?.qty + )?.qty + + ' ' + + (isResponseSuccess(productData) + ? productData?.data?.uom.name + : '') : '' } /> -
-
-
- { - formik.handleChange(e); - setCurrentInput(e.target.name); - }} - onBlur={() => handleBlurField('avg_weight')} - isError={Boolean(formik.errors.avg_weight)} - errorMessage={formik.errors.avg_weight} - placeholder='Masukan Bobot Rata-rata' - /> - - + { + formik.handleChange(e); + setCurrentInput(e.target.name); + }} + onBlur={() => handleBlurField('avg_weight')} + isError={Boolean(formik.errors.avg_weight)} + errorMessage={formik.errors.avg_weight} + placeholder='Masukan Bobot Rata-rata' + /> Number(value.toFixed(2)); +const roundPrice = (value: number) => Math.round(value); const SalesOrderProductForm = ({ initialValues, @@ -39,6 +43,19 @@ const SalesOrderProductForm = ({ }) => { const [formErrorMessage, setFormErrorMessage] = useState(''); const [currentInput, setCurrentInput] = useState(''); + const [selectedProductWarehouse, setSelectedProductWarehouse] = + useState(null); + + // ============ Fetch Data ============ + const { data: productData } = useSWR( + selectedProductWarehouse?.product_id + ? ProductApi.basePath + '/' + selectedProductWarehouse?.product_id + : null, + () => + selectedProductWarehouse?.product_id + ? ProductApi.getSingle(selectedProductWarehouse?.product_id) + : undefined + ); // ============ Formik ============ const formik = useFormik({ @@ -69,17 +86,21 @@ const SalesOrderProductForm = ({ const { options: kandangSourceOptions, isLoadingOptions: isLoadingKandangSourceOptions, + setInputValue: setKandangInputValue, + loadMore: loadMoreKandang, } = useSelect(WarehouseApi.basePath, 'id', 'name'); const { options: warehouseSourceOptions, rawData: warehouseSourceRawData, isLoadingOptions: isLoadingWarehouseSourceOptions, + setInputValue: setWarehouseInputValue, + loadMore: loadMoreWarehouse, } = useSelect( ProductWarehouseApi.basePath, 'id', 'product.name', - 'search', + '', { warehouse_id: formik.values.kandang_id?.toString() ?? '', } @@ -112,6 +133,7 @@ const SalesOrderProductForm = ({ const productWarehouse = warehouseSourceRawData?.data.find( (item: ProductWarehouse) => item.id === newId ); + setSelectedProductWarehouse(productWarehouse || null); formik.setFieldValue('qty', productWarehouse?.quantity); handleBlurField('qty'); } else { @@ -139,34 +161,60 @@ const SalesOrderProductForm = ({ const handleBlurField = (field: string) => { setCurrentInput(field); - const { qty, unit_price, total_price, avg_weight, total_weight } = - formik.values; - if (field === 'unit_price' || field === 'total_price' || field === 'qty') { - if (qty && unit_price && (field === 'unit_price' || field === 'qty')) { - formik.setFieldValue( - 'total_price', - (qty as number) * (unit_price as number) - ); - } else if (qty && total_price && field === 'total_price') { - formik.setFieldValue( - 'unit_price', - (total_price as number) / (qty as number) - ); + const qty = Number(formik.values.qty || 0); + const avgWeight = Number(formik.values.avg_weight || 0); + const totalWeight = Number(formik.values.total_weight || 0); + const unitPrice = Number(formik.values.unit_price || 0); + const totalPrice = Number(formik.values.total_price || 0); + + if (qty <= 0) return; + + switch (field) { + // ===== SOURCE FIELDS ===== + case 'qty': { + if (avgWeight > 0) { + formik.setFieldValue('total_weight', roundWeight(qty * avgWeight)); + } + + if (unitPrice > 0) { + formik.setFieldValue('total_price', roundPrice(qty * unitPrice)); + } + break; } - } - if (field === 'avg_weight' || field === 'total_weight' || field === 'qty') { - if (qty && avg_weight && (field === 'avg_weight' || field === 'qty')) { - formik.setFieldValue( - 'total_weight', - (qty as number) * (avg_weight as number) - ); - } else if (qty && total_weight && field === 'total_weight') { - formik.setFieldValue( - 'avg_weight', - (total_weight as number) / (qty as number) - ); + case 'avg_weight': { + if (avgWeight > 0) { + const tw = roundWeight(qty * avgWeight); + formik.setFieldValue('total_weight', tw); + + if (unitPrice > 0) { + formik.setFieldValue('total_price', roundPrice(qty * unitPrice)); + } + } + break; + } + + case 'unit_price': { + if (unitPrice > 0) { + formik.setFieldValue('total_price', roundPrice(qty * unitPrice)); + } + break; + } + + // ===== TOTAL EDITABLE ===== + case 'total_weight': { + if (totalWeight > 0) { + formik.setFieldValue('avg_weight', roundWeight(totalWeight / qty)); + } + break; + } + + case 'total_price': { + if (totalPrice > 0) { + formik.setFieldValue('unit_price', roundPrice(totalPrice / qty)); + } + break; } } }; @@ -188,7 +236,7 @@ const SalesOrderProductForm = ({
)} -
+
+
+
+
+ + {isResponseSuccess(productData) + ? productData?.data?.uom.name + : ''} + +
+ } bottomLabel={ isResponseSuccess(warehouseSourceRawData) && formik.values.product_warehouse_id @@ -264,32 +328,13 @@ const SalesOrderProductForm = ({ (item) => item.id === formik.values.product_warehouse_id )?.quantity ?? 0 )} ${ - warehouseSourceRawData?.data?.find( - (item) => item.id === formik.values.product_warehouse_id - )?.product?.uom?.name ?? '' + isResponseSuccess(productData) + ? productData?.data?.uom.name + : '' }` : '' } /> -
-
-
- { - formik.handleChange(e); - setCurrentInput(e.target.name); - }} - onBlur={() => handleBlurField('avg_weight')} - isError={ - formik.touched.avg_weight && Boolean(formik.errors.avg_weight) - } - errorMessage={formik.errors.avg_weight} - placeholder='Masukan Bobot Rata-rata' - /> + { + formik.handleChange(e); + setCurrentInput(e.target.name); + }} + onBlur={() => handleBlurField('avg_weight')} + isError={ + formik.touched.avg_weight && Boolean(formik.errors.avg_weight) + } + errorMessage={formik.errors.avg_weight} + placeholder='Masukan Bobot Rata-rata' + /> { const formikInitialValues = useMemo(() => { return { name: initialValues?.name ?? '', - uomId: initialValues?.uom_id ?? 0, + uomId: initialValues?.uom?.id ?? 0, uom: initialValues?.uom ? { value: initialValues?.uom?.id, diff --git a/src/components/pages/master-data/production-standard/form/ProductionStandardForm.schema.ts b/src/components/pages/master-data/production-standard/form/ProductionStandardForm.schema.ts index 13183e71..eb59a9c0 100644 --- a/src/components/pages/master-data/production-standard/form/ProductionStandardForm.schema.ts +++ b/src/components/pages/master-data/production-standard/form/ProductionStandardForm.schema.ts @@ -2,34 +2,30 @@ import * as Yup from 'yup'; // Schema for LAYING category (production_standard_details is required) const LayingRepeaterFormSchema = Yup.object({ - week: Yup.number().required('Minggu wajib diisi!'), + week: Yup.number().required('Wajib diisi!'), production_standard_uniformity_details: Yup.object({ - target_mean_bw: Yup.number().required('Berat rata-rata wajib diisi!'), - max_depletion: Yup.number().required('Maksimal depletion wajib diisi!'), - min_uniformity: Yup.number().required('Minimal uniformitas wajib diisi!'), - feed_intake: Yup.number().required('Pengambilan makanan wajib diisi!'), + target_mean_bw: Yup.number().required('Wajib diisi!'), + max_depletion: Yup.number().required('Wajib diisi!'), + min_uniformity: Yup.number().required('Wajib diisi!'), + feed_intake: Yup.number().required('Wajib diisi!'), }), production_standard_details: Yup.object({ - target_hen_day_production: Yup.number().required( - 'Produksi telur per hari wajib diisi!' - ), - target_hen_house_production: Yup.number().required( - 'Produksi telur per kandang wajib diisi!' - ), - target_egg_weight: Yup.number().required('Berat telur wajib diisi!'), - target_egg_mass: Yup.number().required('Massa telur wajib diisi!'), - standard_fcr: Yup.number().required('FCR wajib diisi!'), + target_hen_day_production: Yup.number().required('Wajib diisi!'), + target_hen_house_production: Yup.number().required('Wajib diisi!'), + target_egg_weight: Yup.number().required('Wajib diisi!'), + target_egg_mass: Yup.number().required('Wajib diisi!'), + standard_fcr: Yup.number().required('Wajib diisi!'), }).required(), }); // Schema for GROWING category (production_standard_details is optional) const GrowingRepeaterFormSchema = Yup.object({ - week: Yup.number().required('Minggu wajib diisi!'), + week: Yup.number().required('Wajib diisi!'), production_standard_uniformity_details: Yup.object({ - target_mean_bw: Yup.number().required('Berat rata-rata wajib diisi!'), - max_depletion: Yup.number().required('Maksimal depletion wajib diisi!'), - min_uniformity: Yup.number().required('Minimal uniformitas wajib diisi!'), - feed_intake: Yup.number().required('Pengambilan makanan wajib diisi!'), + target_mean_bw: Yup.number().required('Wajib diisi!'), + max_depletion: Yup.number().required('Wajib diisi!'), + min_uniformity: Yup.number().required('Wajib diisi!'), + feed_intake: Yup.number().required('Wajib diisi!'), }), production_standard_details: Yup.object({ target_hen_day_production: Yup.number().optional(), diff --git a/src/components/pages/master-data/production-standard/form/ProductionStandardForm.tsx b/src/components/pages/master-data/production-standard/form/ProductionStandardForm.tsx index 8dfc5f45..4512f474 100644 --- a/src/components/pages/master-data/production-standard/form/ProductionStandardForm.tsx +++ b/src/components/pages/master-data/production-standard/form/ProductionStandardForm.tsx @@ -344,7 +344,7 @@ const ProductionStandardForm = ({ const columns = useMemo[]>(() => { const baseColumns: ColumnDef[] = [ { - header: 'Minggu', + header: 'Week', accessorKey: 'week', enableSorting: false, }, @@ -358,30 +358,40 @@ const ProductionStandardForm = ({ header: 'Hen Day', accessorFn: (row) => row.production_standard_details?.target_hen_day_production, + cell: ({ row }) => + `${row.original.production_standard_details?.target_hen_day_production}%`, enableSorting: false, }, { header: 'Hen House', accessorFn: (row) => row.production_standard_details?.target_hen_house_production, + cell: ({ row }) => + `${row.original.production_standard_details?.target_hen_house_production} pc`, enableSorting: false, }, { header: 'Egg Weight', accessorFn: (row) => row.production_standard_details?.target_egg_weight, + cell: ({ row }) => + `${row.original.production_standard_details?.target_egg_weight} g`, enableSorting: false, }, { header: 'Egg Mass', accessorFn: (row) => row.production_standard_details?.target_egg_mass, + cell: ({ row }) => + `${row.original.production_standard_details?.target_egg_mass} g`, enableSorting: false, }, { header: 'FCR', accessorFn: (row) => row.production_standard_details?.standard_fcr, + cell: ({ row }) => + `${row.original.production_standard_details?.standard_fcr} g`, enableSorting: false, }, ] @@ -393,24 +403,32 @@ const ProductionStandardForm = ({ header: 'Mean BW', accessorFn: (row) => row.production_standard_uniformity_details?.target_mean_bw, + cell: ({ row }) => + `${row.original.production_standard_uniformity_details?.target_mean_bw} g`, enableSorting: false, }, { header: 'Max Depletion', accessorFn: (row) => row.production_standard_uniformity_details?.max_depletion, + cell: ({ row }) => + `${row.original.production_standard_uniformity_details?.max_depletion}%`, enableSorting: false, }, { header: 'Min Uniformity', accessorFn: (row) => row.production_standard_uniformity_details?.min_uniformity, + cell: ({ row }) => + `${row.original.production_standard_uniformity_details?.min_uniformity}%`, enableSorting: false, }, { header: 'Feed Intake', accessorFn: (row) => row.production_standard_uniformity_details?.feed_intake, + cell: ({ row }) => + `${row.original.production_standard_uniformity_details?.feed_intake} g`, enableSorting: false, }, ]; @@ -728,7 +746,52 @@ const ProductionStandardForm = ({ }; // ===== Formik Error List ===== - const { formErrorList, close, handleFormSubmit } = useFormikErrorList(formik); + const { formErrorList, close, handleFormSubmit } = useFormikErrorList( + formik, + { + onBeforeSubmit: (e) => { + e.preventDefault(); + + // For GROWING category, clear production_standard_details errors and set default values + if (formik.values.project_category === 'GROWING') { + // Set default values for production_standard_details + formik.values.details?.forEach((detail) => { + detail.production_standard_details = { + target_hen_day_production: 0, + target_hen_house_production: 0, + target_egg_weight: 0, + target_egg_mass: 0, + standard_fcr: 0, + }; + }); + + // Clear any errors related to production_standard_details + const currentErrors = { ...formik.errors }; + if (currentErrors.details && Array.isArray(currentErrors.details)) { + const cleanedDetails = currentErrors.details + .map((detailError) => { + if (detailError && typeof detailError === 'object') { + const { production_standard_details, ...rest } = detailError; + return Object.keys(rest).length > 0 ? rest : undefined; + } + return detailError; + }) + .filter( + (error): error is Exclude => + error !== undefined + ); + + currentErrors.details = ( + cleanedDetails.length > 0 ? cleanedDetails : undefined + ) as typeof currentErrors.details; + } + formik.setErrors(currentErrors); + } + + return true; + }, + } + ); return ( <> @@ -821,19 +884,20 @@ const ProductionStandardForm = ({ key={`row-${row.index}`} className='sticky bottom-0 bg-base-100 shadow-lg' > - +
} + bottomLabel='Persen (%)' errorMessage={getProductionDetailsError( repeaterFormik.errors .production_standard_details, @@ -894,11 +958,7 @@ const ProductionStandardForm = ({ } onChange={repeaterFormik.handleChange} onBlur={repeaterFormik.handleBlur} - endAdornment={ -
- Butir -
- } + bottomLabel='Butir (pc)' errorMessage={getProductionDetailsError( repeaterFormik.errors .production_standard_details, @@ -930,11 +990,7 @@ const ProductionStandardForm = ({ } onChange={repeaterFormik.handleChange} onBlur={repeaterFormik.handleBlur} - endAdornment={ -
- gr -
- } + bottomLabel='Gram (g)' errorMessage={getProductionDetailsError( repeaterFormik.errors .production_standard_details, @@ -959,17 +1015,13 @@ const ProductionStandardForm = ({ name='production_standard_details.target_egg_mass' label='Egg Mass' placeholder='1' + bottomLabel='Gram (g)' value={ repeaterFormik.values .production_standard_details?.target_egg_mass } onChange={repeaterFormik.handleChange} onBlur={repeaterFormik.handleBlur} - endAdornment={ -
- gr -
- } errorMessage={getProductionDetailsError( repeaterFormik.errors .production_standard_details, @@ -1000,11 +1052,7 @@ const ProductionStandardForm = ({ } onChange={repeaterFormik.handleChange} onBlur={repeaterFormik.handleBlur} - endAdornment={ -
- gr -
- } + bottomLabel='Gram (g)' errorMessage={getProductionDetailsError( repeaterFormik.errors .production_standard_details, @@ -1038,11 +1086,7 @@ const ProductionStandardForm = ({ } onChange={repeaterFormik.handleChange} onBlur={repeaterFormik.handleBlur} - endAdornment={ -
- gr -
- } + bottomLabel='Gram (g)' errorMessage={ repeaterFormik.errors .production_standard_uniformity_details @@ -1072,7 +1116,7 @@ const ProductionStandardForm = ({ } onChange={repeaterFormik.handleChange} onBlur={repeaterFormik.handleBlur} - endAdornment={} + bottomLabel='Persen (%)' errorMessage={ repeaterFormik.errors .production_standard_uniformity_details @@ -1102,7 +1146,7 @@ const ProductionStandardForm = ({ } onChange={repeaterFormik.handleChange} onBlur={repeaterFormik.handleBlur} - endAdornment={} + bottomLabel='Persen (%)' errorMessage={ repeaterFormik.errors .production_standard_uniformity_details @@ -1132,11 +1176,8 @@ const ProductionStandardForm = ({ } onChange={repeaterFormik.handleChange} onBlur={repeaterFormik.handleBlur} - endAdornment={ -
- gr/ekor -
- } + bottomLabel='Gram/Ekor (g)' + endAdornment errorMessage={ repeaterFormik.errors .production_standard_uniformity_details @@ -1162,7 +1203,7 @@ const ProductionStandardForm = ({ type='button' color='error' variant='outline' - className='min-w-24' + className='min-w-xs' onClick={handleCancelEdit} > Batal @@ -1178,7 +1219,7 @@ const ProductionStandardForm = ({