mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-25 07:45:47 +00:00
Merge branch 'fix/adjustment-penjualan' into 'development'
[FIX/FE] Adjustment Penjualan UI and Data Fetch (2/2) See merge request mbugroup/lti-web-client!318
This commit is contained in:
@@ -111,6 +111,7 @@ const DeliveryOrderFormModal = ({
|
|||||||
const successModal = useModal();
|
const successModal = useModal();
|
||||||
const rejectModal = useModal();
|
const rejectModal = useModal();
|
||||||
const deleteModal = useModal();
|
const deleteModal = useModal();
|
||||||
|
const approveModal = useModal();
|
||||||
const formRef = useRef<HTMLFormElement>(null);
|
const formRef = useRef<HTMLFormElement>(null);
|
||||||
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
||||||
|
|
||||||
@@ -333,6 +334,33 @@ const DeliveryOrderFormModal = ({
|
|||||||
refreshApproval();
|
refreshApproval();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const approveMarketingHandler = async (notes: string) => {
|
||||||
|
if (!marketingId) {
|
||||||
|
toast.error(`Tidak ada data yang valid untuk di approve.`);
|
||||||
|
approveModal.closeModal();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const approveMarketingRes = await SalesOrderApi.singleApproval(
|
||||||
|
Number(marketingId),
|
||||||
|
'APPROVED',
|
||||||
|
notes
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isResponseSuccess(approveMarketingRes)) {
|
||||||
|
approveModal.closeModal();
|
||||||
|
toast.success(approveMarketingRes?.message as string);
|
||||||
|
closeModalHandler();
|
||||||
|
router.push('/marketing');
|
||||||
|
}
|
||||||
|
if (isResponseError(approveMarketingRes)) {
|
||||||
|
approveModal.closeModal();
|
||||||
|
toast.error(approveMarketingRes?.message as string);
|
||||||
|
}
|
||||||
|
refreshMarketing();
|
||||||
|
refreshApproval();
|
||||||
|
};
|
||||||
|
|
||||||
const deleteClickHandler = () => {
|
const deleteClickHandler = () => {
|
||||||
deleteModal.openModal();
|
deleteModal.openModal();
|
||||||
};
|
};
|
||||||
@@ -380,7 +408,77 @@ const DeliveryOrderFormModal = ({
|
|||||||
},
|
},
|
||||||
[prevButtonHandler]
|
[prevButtonHandler]
|
||||||
);
|
);
|
||||||
const handleUpdateDO = useCallback(
|
|
||||||
|
const isApprovalStep3Approved = useMemo(() => {
|
||||||
|
return (
|
||||||
|
isResponseSuccess(marketing) &&
|
||||||
|
marketing.data.latest_approval?.step_number === 3 &&
|
||||||
|
marketing.data.latest_approval?.action === 'APPROVED'
|
||||||
|
);
|
||||||
|
}, [marketing]);
|
||||||
|
|
||||||
|
const handleUpdateDOWithAPI = useCallback(
|
||||||
|
async (id: number, values: DeliveryOrderProductFormValues) => {
|
||||||
|
if (!marketingId) {
|
||||||
|
toast.error('Marketing ID tidak ditemukan');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setIsLoading(true);
|
||||||
|
|
||||||
|
const updatedDeliveryValues = deliveryOrderValues.map((product) =>
|
||||||
|
product.id === id ? { ...product, ...values } : product
|
||||||
|
);
|
||||||
|
|
||||||
|
const payload = {
|
||||||
|
marketing_id: Number(marketingId),
|
||||||
|
delivery_products: updatedDeliveryValues
|
||||||
|
.map((product) => {
|
||||||
|
if (Boolean(product.delivery_date)) {
|
||||||
|
return {
|
||||||
|
marketing_product_id: product.marketing_product_id as number,
|
||||||
|
unit_price: parseFloat(product.unit_price as string),
|
||||||
|
total_weight: parseFloat(product.total_weight as string),
|
||||||
|
qty: parseFloat(product.qty as string),
|
||||||
|
avg_weight: parseFloat(product.avg_weight as string),
|
||||||
|
total_price: parseFloat(product.total_price as string),
|
||||||
|
delivery_date: formatDate(
|
||||||
|
product.delivery_date as string,
|
||||||
|
'yyyy-MM-DD'
|
||||||
|
),
|
||||||
|
vehicle_number: product.vehicle_number,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.filter((item) => Boolean(item)),
|
||||||
|
} as UpdateDeliveryOrderPayload;
|
||||||
|
|
||||||
|
const updateDeliveryRes = await DeliveryOrderApi.update(
|
||||||
|
Number(marketingId),
|
||||||
|
payload
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isResponseSuccess(updateDeliveryRes)) {
|
||||||
|
toast.success(updateDeliveryRes?.message as string);
|
||||||
|
closeModalHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isResponseError(updateDeliveryRes)) {
|
||||||
|
setFormErrorMessage(updateDeliveryRes?.message as string);
|
||||||
|
}
|
||||||
|
|
||||||
|
setIsLoading(false);
|
||||||
|
},
|
||||||
|
[
|
||||||
|
marketingId,
|
||||||
|
deliveryOrderValues,
|
||||||
|
formik.values.sales_order,
|
||||||
|
prevButtonHandler,
|
||||||
|
refreshMarketing,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleUpdateDOLocal = useCallback(
|
||||||
async (id: number, values: DeliveryOrderProductFormValues) => {
|
async (id: number, values: DeliveryOrderProductFormValues) => {
|
||||||
setDeliveryOrderValues((prev) =>
|
setDeliveryOrderValues((prev) =>
|
||||||
prev.map((product) =>
|
prev.map((product) =>
|
||||||
@@ -463,7 +561,26 @@ const DeliveryOrderFormModal = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
formik.setValues(filledInitialValues);
|
formik.setValues(filledInitialValues);
|
||||||
setStep(1);
|
|
||||||
|
if (modalAction === 'add_delivery') {
|
||||||
|
// add delivery
|
||||||
|
const firstDeliveryItem = filledInitialValues.delivery_order?.[0];
|
||||||
|
if (firstDeliveryItem) {
|
||||||
|
setSelectedDeliveryProduct(firstDeliveryItem);
|
||||||
|
}
|
||||||
|
setStep(2); // Langsung ke form delivery
|
||||||
|
} else if (modalAction === 'edit_delivery') {
|
||||||
|
// edit delivery
|
||||||
|
const firstDeliveryItem = filledInitialValues.delivery_order?.[0];
|
||||||
|
if (firstDeliveryItem) {
|
||||||
|
setSelectedDeliveryProduct(firstDeliveryItem);
|
||||||
|
setStep(2); // Langsung ke form edit
|
||||||
|
} else {
|
||||||
|
setStep(1); // Jika belum ada data, tampilkan detail view
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setStep(1); // Detail view
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isResponseError(marketing)) {
|
if (isResponseError(marketing)) {
|
||||||
@@ -474,7 +591,7 @@ const DeliveryOrderFormModal = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
getFilledInitialValues();
|
getFilledInitialValues();
|
||||||
}, [marketingId, marketing]);
|
}, [marketingId, marketing, modalAction]);
|
||||||
|
|
||||||
// Reset error message when step changes
|
// Reset error message when step changes
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -679,7 +796,12 @@ const DeliveryOrderFormModal = ({
|
|||||||
exisitingValues={deliveryOrderValues}
|
exisitingValues={deliveryOrderValues}
|
||||||
onSubmitForm={handleAddSubmitDO}
|
onSubmitForm={handleAddSubmitDO}
|
||||||
initialValues={selectedDeliveryProduct ?? undefined}
|
initialValues={selectedDeliveryProduct ?? undefined}
|
||||||
onUpdateForm={handleUpdateDO}
|
onUpdateForm={
|
||||||
|
isApprovalStep3Approved
|
||||||
|
? handleUpdateDOWithAPI
|
||||||
|
: handleUpdateDOLocal
|
||||||
|
}
|
||||||
|
isLoading={isLoading}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -723,7 +845,15 @@ const DeliveryOrderFormModal = ({
|
|||||||
type='button'
|
type='button'
|
||||||
color='primary'
|
color='primary'
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
formRef.current?.requestSubmit();
|
// Jika masih di step 1 approval, gunakan single approval API
|
||||||
|
if (
|
||||||
|
marketing?.data?.latest_approval?.step_number === 1
|
||||||
|
) {
|
||||||
|
approveModal.openModal();
|
||||||
|
} else {
|
||||||
|
// Jika sudah di step 2/3, gunakan form submit (delivery products)
|
||||||
|
formRef.current?.requestSubmit();
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
className='p-3 shadow-button-soft text-base-100 rounded-lg text-sm font-semibold'
|
className='p-3 shadow-button-soft text-base-100 rounded-lg text-sm font-semibold'
|
||||||
disabled={deliveryRejected}
|
disabled={deliveryRejected}
|
||||||
@@ -741,8 +871,8 @@ const DeliveryOrderFormModal = ({
|
|||||||
ref={successModal.ref}
|
ref={successModal.ref}
|
||||||
iconPosition='left'
|
iconPosition='left'
|
||||||
type='success'
|
type='success'
|
||||||
text={`${currentModalAction === 'add' ? 'Data Berhasil Disimpan' : 'Data Berhasil Diubah'}`}
|
text={`${currentModalAction === 'add_delivery' ? 'Data Berhasil Disimpan' : 'Data Berhasil Diubah'}`}
|
||||||
subtitleText={`${currentModalAction === 'add' ? 'Data delivery order telah berhasil disimpan.' : 'Data delivery order telah berhasil diubah.'}`}
|
subtitleText={`${currentModalAction === 'add_delivery' ? 'Data delivery order telah berhasil disimpan.' : 'Data delivery order telah berhasil diubah.'}`}
|
||||||
primaryButton={{
|
primaryButton={{
|
||||||
text: 'Oke',
|
text: 'Oke',
|
||||||
color: 'primary',
|
color: 'primary',
|
||||||
@@ -795,6 +925,21 @@ const DeliveryOrderFormModal = ({
|
|||||||
onClick: confirmationModalDeleteClickHandler,
|
onClick: confirmationModalDeleteClickHandler,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<ConfirmationModalWithNotes
|
||||||
|
ref={approveModal.ref}
|
||||||
|
type={'success'}
|
||||||
|
text={`Apakah anda yakin ingin approve data penjualan?`}
|
||||||
|
secondaryButton={{
|
||||||
|
text: 'Tidak',
|
||||||
|
onClick: approveModal.closeModal,
|
||||||
|
}}
|
||||||
|
primaryButton={{
|
||||||
|
text: 'Ya',
|
||||||
|
color: 'success',
|
||||||
|
onClick: approveMarketingHandler,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -394,7 +394,7 @@ const SalesOrderFormModal = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
formik.setFieldValue('sales_order', updatedProducts);
|
formik.setFieldValue('sales_order', updatedProducts);
|
||||||
console.log(formik.values);
|
setSelectedMarketingProduct(null);
|
||||||
nextButtonHandler();
|
nextButtonHandler();
|
||||||
},
|
},
|
||||||
[memoSalesOrder, nextButtonHandler]
|
[memoSalesOrder, nextButtonHandler]
|
||||||
@@ -418,6 +418,15 @@ const SalesOrderFormModal = ({
|
|||||||
if (modalAction === 'add' || modalAction === 'edit') {
|
if (modalAction === 'add' || modalAction === 'edit') {
|
||||||
setCurrentModalAction(modalAction);
|
setCurrentModalAction(modalAction);
|
||||||
formModal.openModal();
|
formModal.openModal();
|
||||||
|
|
||||||
|
if (modalAction === 'add') {
|
||||||
|
formik.resetForm();
|
||||||
|
setStep(1);
|
||||||
|
setSelectedMarketingProduct(null);
|
||||||
|
setSelectedDeliveryProduct(null);
|
||||||
|
setFormErrorMessage('');
|
||||||
|
setFormErrorList([]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, [modalAction]);
|
}, [modalAction]);
|
||||||
|
|
||||||
|
|||||||
+35
-6
@@ -36,6 +36,7 @@ const DeliveryOrderProductForm = ({
|
|||||||
exisitingValues,
|
exisitingValues,
|
||||||
onSubmitForm,
|
onSubmitForm,
|
||||||
onUpdateForm,
|
onUpdateForm,
|
||||||
|
isLoading,
|
||||||
}: {
|
}: {
|
||||||
formState: 'add' | 'edit';
|
formState: 'add' | 'edit';
|
||||||
salesOrders: BaseSalesOrder[];
|
salesOrders: BaseSalesOrder[];
|
||||||
@@ -46,6 +47,7 @@ const DeliveryOrderProductForm = ({
|
|||||||
id: number,
|
id: number,
|
||||||
value: DeliveryOrderProductFormValues
|
value: DeliveryOrderProductFormValues
|
||||||
) => Promise<void>;
|
) => Promise<void>;
|
||||||
|
isLoading?: boolean;
|
||||||
}) => {
|
}) => {
|
||||||
const [formikErrorMessage, setFormErrorMessage] = useState('');
|
const [formikErrorMessage, setFormErrorMessage] = useState('');
|
||||||
const [selectedProduct, setSelectedProduct] = useState<OptionType | null>(
|
const [selectedProduct, setSelectedProduct] = useState<OptionType | null>(
|
||||||
@@ -178,6 +180,25 @@ const DeliveryOrderProductForm = ({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const hasWeekField = useMemo(() => {
|
||||||
|
const marketingType = formik.values.marketing_type?.value?.toLowerCase();
|
||||||
|
if (marketingType === 'ayam_pullet') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (formik.values.marketing_product?.product_warehouse_data) {
|
||||||
|
return Boolean(
|
||||||
|
formik.values.marketing_product?.product_warehouse_data?.week !==
|
||||||
|
undefined &&
|
||||||
|
formik.values.marketing_product?.product_warehouse_data?.week !==
|
||||||
|
null &&
|
||||||
|
formik.values.marketing_product?.product_warehouse_data?.week > 0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}, [formik.values.marketing_product, formik.values.marketing_type]);
|
||||||
|
|
||||||
const handleResetForm = () => {
|
const handleResetForm = () => {
|
||||||
setFormErrorMessage('');
|
setFormErrorMessage('');
|
||||||
formik.resetForm({
|
formik.resetForm({
|
||||||
@@ -362,20 +383,24 @@ const DeliveryOrderProductForm = ({
|
|||||||
avg_weight: '',
|
avg_weight: '',
|
||||||
total_weight: '',
|
total_weight: '',
|
||||||
vehicle_number: '',
|
vehicle_number: '',
|
||||||
|
week: null,
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const soFieldValues = SalesProductToFieldValues(so);
|
||||||
|
|
||||||
formik.setValues({
|
formik.setValues({
|
||||||
...formik.values,
|
...formik.values,
|
||||||
marketing_product_id: selected.value as number,
|
marketing_product_id: selected.value as number,
|
||||||
marketing_product: SalesProductToFieldValues(so),
|
marketing_product: soFieldValues,
|
||||||
qty: so.qty,
|
qty: so.qty,
|
||||||
unit_price: so.unit_price,
|
unit_price: so.unit_price,
|
||||||
total_price: so.total_price,
|
total_price: so.total_price,
|
||||||
avg_weight: so.avg_weight,
|
avg_weight: so.avg_weight,
|
||||||
total_weight: so.total_weight,
|
total_weight: so.total_weight,
|
||||||
vehicle_number: so.vehicle_number,
|
vehicle_number: so.vehicle_number,
|
||||||
|
week: soFieldValues.week ?? null,
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
startAdornment={
|
startAdornment={
|
||||||
@@ -509,10 +534,14 @@ const DeliveryOrderProductForm = ({
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Konversi Satuan Week Pullet */}
|
{/* Konversi Satuan Week Pullet */}
|
||||||
{formik.values.marketing_type?.value.toLowerCase() ===
|
{(formik.values.marketing_type?.value.toLowerCase() ===
|
||||||
'ayam_pullet' && (
|
'ayam_pullet' ||
|
||||||
|
hasWeekField) && (
|
||||||
<NumberInput
|
<NumberInput
|
||||||
required
|
required={
|
||||||
|
formik.values.marketing_type?.value.toLowerCase() ===
|
||||||
|
'ayam_pullet'
|
||||||
|
}
|
||||||
label='Minggu'
|
label='Minggu'
|
||||||
name='week'
|
name='week'
|
||||||
value={formik.values.week ?? undefined}
|
value={formik.values.week ?? undefined}
|
||||||
@@ -793,8 +822,8 @@ const DeliveryOrderProductForm = ({
|
|||||||
<div className='absolute sm:w-full bottom-0 right-0 p-4'>
|
<div className='absolute sm:w-full bottom-0 right-0 p-4'>
|
||||||
<Button
|
<Button
|
||||||
type='submit'
|
type='submit'
|
||||||
isLoading={formik.isSubmitting}
|
isLoading={formik.isSubmitting || isLoading}
|
||||||
disabled={formik.isSubmitting}
|
disabled={formik.isSubmitting || isLoading}
|
||||||
className='w-full p-3 rounded-lg text-base-100 text-sm font-semibold'
|
className='w-full p-3 rounded-lg text-base-100 text-sm font-semibold'
|
||||||
>
|
>
|
||||||
Submit
|
Submit
|
||||||
|
|||||||
@@ -117,6 +117,19 @@ const SalesOrderProductForm = ({
|
|||||||
isInitialValid: false,
|
isInitialValid: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const hasWeekField = useMemo(() => {
|
||||||
|
const marketingType = formik.values.marketing_type?.value?.toLowerCase();
|
||||||
|
if (marketingType === 'ayam_pullet') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Boolean(
|
||||||
|
selectedProductWarehouse?.week !== undefined &&
|
||||||
|
selectedProductWarehouse?.week !== null &&
|
||||||
|
selectedProductWarehouse?.week > 0
|
||||||
|
);
|
||||||
|
}, [selectedProductWarehouse, formik.values.marketing_type]);
|
||||||
|
|
||||||
// ===== Options =====
|
// ===== Options =====
|
||||||
const {
|
const {
|
||||||
options: kandangSourceOptions,
|
options: kandangSourceOptions,
|
||||||
@@ -180,10 +193,20 @@ const SalesOrderProductForm = ({
|
|||||||
setSelectedProductWarehouse(productWarehouse || null);
|
setSelectedProductWarehouse(productWarehouse || null);
|
||||||
formik.setFieldValue('qty', productWarehouse?.quantity);
|
formik.setFieldValue('qty', productWarehouse?.quantity);
|
||||||
formik.setFieldValue('uom', productWarehouse?.product?.uom?.name || '');
|
formik.setFieldValue('uom', productWarehouse?.product?.uom?.name || '');
|
||||||
|
if (
|
||||||
|
productWarehouse?.week !== undefined &&
|
||||||
|
productWarehouse?.week !== null &&
|
||||||
|
productWarehouse?.week > 0
|
||||||
|
) {
|
||||||
|
formik.setFieldValue('week', productWarehouse.week);
|
||||||
|
} else {
|
||||||
|
formik.setFieldValue('week', null);
|
||||||
|
}
|
||||||
handleBlurField('qty');
|
handleBlurField('qty');
|
||||||
} else {
|
} else {
|
||||||
formik.setFieldValue('qty', '');
|
formik.setFieldValue('qty', '');
|
||||||
formik.setFieldValue('uom', '');
|
formik.setFieldValue('uom', '');
|
||||||
|
formik.setFieldValue('week', null);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -465,10 +488,14 @@ const SalesOrderProductForm = ({
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Konversi Satuan Week Pullet */}
|
{/* Konversi Satuan Week Pullet */}
|
||||||
{formik.values.marketing_type?.value.toLowerCase() ===
|
{(formik.values.marketing_type?.value.toLowerCase() ===
|
||||||
'ayam_pullet' && (
|
'ayam_pullet' ||
|
||||||
|
hasWeekField) && (
|
||||||
<NumberInput
|
<NumberInput
|
||||||
required
|
required={
|
||||||
|
formik.values.marketing_type?.value.toLowerCase() ===
|
||||||
|
'ayam_pullet'
|
||||||
|
}
|
||||||
label='Minggu'
|
label='Minggu'
|
||||||
name='week'
|
name='week'
|
||||||
value={formik.values.week ?? undefined}
|
value={formik.values.week ?? undefined}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ type DeliveryOrderProductTableProps = {
|
|||||||
| 'detail'
|
| 'detail'
|
||||||
| 'rejected'
|
| 'rejected'
|
||||||
| 'pending'
|
| 'pending'
|
||||||
|
| 'success'
|
||||||
| string
|
| string
|
||||||
| null;
|
| null;
|
||||||
marketing?: Marketing;
|
marketing?: Marketing;
|
||||||
@@ -32,7 +33,6 @@ const DeliveryOrderProductTable = ({
|
|||||||
formType,
|
formType,
|
||||||
onEdit,
|
onEdit,
|
||||||
onDelete,
|
onDelete,
|
||||||
onAddProductClick,
|
|
||||||
marketing,
|
marketing,
|
||||||
}: DeliveryOrderProductTableProps) => {
|
}: DeliveryOrderProductTableProps) => {
|
||||||
const onEditRef = useRef(onEdit);
|
const onEditRef = useRef(onEdit);
|
||||||
@@ -42,178 +42,193 @@ const DeliveryOrderProductTable = ({
|
|||||||
|
|
||||||
const approvalStepNumber = marketing?.latest_approval?.step_number;
|
const approvalStepNumber = marketing?.latest_approval?.step_number;
|
||||||
|
|
||||||
|
const renderTableContent = (item: DeliveryOrderProductFormValues) => {
|
||||||
|
const doItem = marketing?.delivery_order?.find(
|
||||||
|
(doItem) => doItem.do_number === item.do_number
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<tr className='border-b border-tools-table-outline border-base-content/5'>
|
||||||
|
<th className='w-1/3 text-start not-first:font-medium text-base-content/50 text-sm px-4 py-3'>
|
||||||
|
Label
|
||||||
|
</th>
|
||||||
|
<th className='text-start font-medium text-base-content/50 text-sm px-4 py-3'>
|
||||||
|
<div className='flex w-full flex-row gap-1 items-center justify-between h-full'>
|
||||||
|
<div>Value</div>
|
||||||
|
{formType !== 'success' &&
|
||||||
|
(formType === 'add_delivery' ||
|
||||||
|
formType === 'edit_delivery' ||
|
||||||
|
formType === 'detail') && (
|
||||||
|
<div className='flex flex-row gap-1.5 items-center'>
|
||||||
|
<Button
|
||||||
|
type='button'
|
||||||
|
variant='ghost'
|
||||||
|
color='none'
|
||||||
|
onClick={() => {
|
||||||
|
onEditRef.current(item.id as number, item);
|
||||||
|
}}
|
||||||
|
className='p-0 hover:text-base-content'
|
||||||
|
>
|
||||||
|
<Icon icon='heroicons:pencil' width={20} height={20} />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
<>
|
||||||
|
<tr>
|
||||||
|
<td className='text-sm px-4 py-3'>Gudang</td>
|
||||||
|
<td className='text-sm px-4 py-3'>
|
||||||
|
{doItem?.warehouse?.name ||
|
||||||
|
item.marketing_product?.product_warehouse_data?.warehouse?.name}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td className='text-sm px-4 py-3'>Produk</td>
|
||||||
|
<td className='text-sm px-4 py-3'>
|
||||||
|
{item.marketing_product?.product_warehouse?.label}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td className='text-sm px-4 py-3'>Qty</td>
|
||||||
|
<td className='text-sm px-4 py-3'>
|
||||||
|
{item.qty
|
||||||
|
? `${formatNumber(parseFloat(item.qty as string))} ${item.marketing_product?.uom ?? ''}`
|
||||||
|
: '-'}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{Number(item.avg_weight ?? 0) > 0 && (
|
||||||
|
<tr>
|
||||||
|
<td className='text-sm px-4 py-3'>Avg Bobot</td>
|
||||||
|
<td className='text-sm px-4 py-3'>
|
||||||
|
{formatNumber(Number(item.avg_weight))} Kg
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
)}
|
||||||
|
{Number(item.total_weight ?? 0) > 0 && (
|
||||||
|
<tr>
|
||||||
|
<td className='text-sm px-4 py-3'>Total Bobot</td>
|
||||||
|
<td className='text-sm px-4 py-3'>
|
||||||
|
{formatNumber(Number(item.total_weight))}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
)}
|
||||||
|
<tr>
|
||||||
|
<td className='text-sm px-4 py-3'>Total Harga Satuan</td>
|
||||||
|
<td className='text-sm px-4 py-3'>
|
||||||
|
{formatCurrency(parseFloat(item.unit_price as string))}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td className='text-sm px-4 py-3'>Total Penjualan</td>
|
||||||
|
<td className='text-sm px-4 py-3'>
|
||||||
|
{formatCurrency(parseFloat(item.total_price as string))}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</>
|
||||||
|
<tr className='border-b border-t border-tools-table-outline border-base-content/5'>
|
||||||
|
<th className='w-1/3 text-start not-first:font-medium text-base-content/50 text-sm px-4 py-3'>
|
||||||
|
Label
|
||||||
|
</th>
|
||||||
|
<th className='text-start font-medium text-base-content/50 text-sm px-4 py-3'>
|
||||||
|
<div className='flex w-full flex-row gap-1 items-center justify-between h-full'>
|
||||||
|
<div>Value</div>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
<>
|
||||||
|
{approvalStepNumber !== 1 && (
|
||||||
|
<tr>
|
||||||
|
<td className='text-sm px-4 py-3'>Tanggal Pengiriman</td>
|
||||||
|
<td className='text-sm px-4 py-3'>
|
||||||
|
{item.delivery_date ? (
|
||||||
|
formatDate(item.delivery_date, 'DD MMM YYYY')
|
||||||
|
) : formType === 'add_delivery' ||
|
||||||
|
formType === 'edit_delivery' ||
|
||||||
|
formType === 'detail' ? (
|
||||||
|
<span
|
||||||
|
className='text-error hover:text-error/70 cursor-pointer hover:underline underline-offset-4'
|
||||||
|
onClick={() => {
|
||||||
|
onEditRef.current(item.id as number, item);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Belum diisi
|
||||||
|
</span>
|
||||||
|
) : (
|
||||||
|
<span className='text-error'>Belum diisi</span>
|
||||||
|
)}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
)}
|
||||||
|
{item.do_number && (
|
||||||
|
<tr>
|
||||||
|
<td className='text-sm px-4 py-3'>No. Pengiriman</td>
|
||||||
|
<td className='text-sm px-4 py-3'>{item.do_number}</td>
|
||||||
|
</tr>
|
||||||
|
)}
|
||||||
|
<tr>
|
||||||
|
<td className='text-sm px-4 py-3'>No. Polisi</td>
|
||||||
|
<td className='text-sm px-4 py-3'>{item.vehicle_number}</td>
|
||||||
|
</tr>
|
||||||
|
{doItem && (
|
||||||
|
<tr>
|
||||||
|
<td className='text-sm px-4 py-3'>Dokumen Pengiriman</td>
|
||||||
|
<td className='text-sm px-4 py-3'>
|
||||||
|
<DeliveryOrderExport data={marketing} deliveryOrder={doItem} />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className='size-full flex flex-col relative overflow-x-hidden gap-3'>
|
<div className='size-full flex flex-col relative overflow-x-hidden gap-3'>
|
||||||
{data.map((item) => {
|
{data.map((item) => (
|
||||||
const doItem = marketing?.delivery_order?.find(
|
<div key={`table-${item.id}`}>
|
||||||
(doItem) => doItem.do_number === item.do_number
|
{formType === 'success' ? (
|
||||||
);
|
<div className='rounded-lg border border-tools-table-outline border-base-content/5'>
|
||||||
return (
|
<table
|
||||||
<Card
|
style={{
|
||||||
key={`table-${item.id}`}
|
borderRadius: '0.5rem',
|
||||||
title={
|
}}
|
||||||
item.marketing_product?.product_warehouse?.label || 'Produk'
|
className='border-none w-full'
|
||||||
}
|
>
|
||||||
collapsible={true}
|
<tbody className='w-full'>{renderTableContent(item)}</tbody>
|
||||||
defaultCollapsed={false}
|
</table>
|
||||||
variant='bordered'
|
</div>
|
||||||
className={{
|
) : (
|
||||||
wrapper: 'w-full rounded-lg',
|
<Card
|
||||||
body: 'p-0',
|
key={`table-${item.id}`}
|
||||||
title: 'px-2 py-1.5 font-normal text-sm',
|
title={
|
||||||
collapsible: 'rounded-lg',
|
item.marketing_product?.product_warehouse?.label || 'Produk'
|
||||||
}}
|
}
|
||||||
>
|
collapsible={true}
|
||||||
<table
|
defaultCollapsed={false}
|
||||||
style={{
|
variant='bordered'
|
||||||
borderRadius: '0.5rem',
|
className={{
|
||||||
|
wrapper: 'w-full rounded-lg',
|
||||||
|
body: 'p-0',
|
||||||
|
title: 'px-2 py-1.5 font-normal text-sm',
|
||||||
|
collapsible: 'rounded-lg',
|
||||||
}}
|
}}
|
||||||
className='border-none w-full'
|
|
||||||
>
|
>
|
||||||
<tbody className='w-full'>
|
<table
|
||||||
<tr className='border-b border-t border-tools-table-outline border-base-content/5'>
|
style={{
|
||||||
<th className='w-1/3 text-start not-first:font-medium text-base-content/50 text-sm px-4 py-3'>
|
borderRadius: '0.5rem',
|
||||||
Label
|
}}
|
||||||
</th>
|
className='border-none w-full'
|
||||||
<th className='text-start font-medium text-base-content/50 text-sm px-4 py-3'>
|
>
|
||||||
<div className='flex w-full flex-row gap-1 items-center justify-between h-full'>
|
<tbody className='w-full'>{renderTableContent(item)}</tbody>
|
||||||
<div>Value</div>
|
</table>
|
||||||
{(formType === 'add_delivery' ||
|
</Card>
|
||||||
formType === 'edit_delivery' ||
|
)}
|
||||||
formType === 'detail') && (
|
</div>
|
||||||
<div className='flex flex-row gap-1.5 items-center'>
|
))}
|
||||||
<Button
|
|
||||||
type='button'
|
|
||||||
variant='ghost'
|
|
||||||
color='none'
|
|
||||||
onClick={() => {
|
|
||||||
onEditRef.current(item.id as number, item);
|
|
||||||
}}
|
|
||||||
className='p-0 hover:text-base-content'
|
|
||||||
>
|
|
||||||
<Icon
|
|
||||||
icon='heroicons:pencil'
|
|
||||||
width={20}
|
|
||||||
height={20}
|
|
||||||
/>
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
type='button'
|
|
||||||
variant='ghost'
|
|
||||||
color='none'
|
|
||||||
onClick={() => {
|
|
||||||
onDeleteRef.current(item.id as number);
|
|
||||||
}}
|
|
||||||
className='p-0 text-error hover:text-base-content'
|
|
||||||
>
|
|
||||||
<Icon
|
|
||||||
icon='heroicons:trash'
|
|
||||||
width={20}
|
|
||||||
height={20}
|
|
||||||
/>
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
<>
|
|
||||||
{approvalStepNumber !== 1 && (
|
|
||||||
<tr>
|
|
||||||
<td className='text-sm px-4 py-3'>
|
|
||||||
Tanggal Pengiriman
|
|
||||||
</td>
|
|
||||||
<td className='text-sm px-4 py-3'>
|
|
||||||
{item.delivery_date ? (
|
|
||||||
formatDate(item.delivery_date, 'DD MMM YYYY')
|
|
||||||
) : (
|
|
||||||
<span className='text-error'>Belum diisi</span>
|
|
||||||
)}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
)}
|
|
||||||
{item.do_number && (
|
|
||||||
<tr>
|
|
||||||
<td className='text-sm px-4 py-3'>No. Pengiriman</td>
|
|
||||||
<td className='text-sm px-4 py-3'>{item.do_number}</td>
|
|
||||||
</tr>
|
|
||||||
)}
|
|
||||||
<tr>
|
|
||||||
<td className='text-sm px-4 py-3'>No. Polisi</td>
|
|
||||||
<td className='text-sm px-4 py-3'>
|
|
||||||
{item.vehicle_number}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td className='text-sm px-4 py-3'>Gudang</td>
|
|
||||||
<td className='text-sm px-4 py-3'>
|
|
||||||
{doItem?.warehouse?.name ||
|
|
||||||
item.marketing_product?.product_warehouse_data
|
|
||||||
?.warehouse?.name}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td className='text-sm px-4 py-3'>Produk</td>
|
|
||||||
<td className='text-sm px-4 py-3'>
|
|
||||||
{item.marketing_product?.product_warehouse?.label}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td className='text-sm px-4 py-3'>Qty</td>
|
|
||||||
<td className='text-sm px-4 py-3'>
|
|
||||||
{item.qty
|
|
||||||
? `${formatNumber(parseFloat(item.qty as string))} ${item.marketing_product?.uom ?? ''}`
|
|
||||||
: '-'}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td className='text-sm px-4 py-3'>Avg Bobot</td>
|
|
||||||
<td className='text-sm px-4 py-3'>
|
|
||||||
{item.avg_weight
|
|
||||||
? formatNumber(
|
|
||||||
parseFloat(item.avg_weight as string)
|
|
||||||
) + ' Kg'
|
|
||||||
: '-'}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td className='text-sm px-4 py-3'>Total Bobot</td>
|
|
||||||
<td className='text-sm px-4 py-3'>
|
|
||||||
{formatNumber(parseFloat(item.total_weight as string))}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td className='text-sm px-4 py-3'>Total Harga Satuan</td>
|
|
||||||
<td className='text-sm px-4 py-3'>
|
|
||||||
{formatCurrency(parseFloat(item.unit_price as string))}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td className='text-sm px-4 py-3'>Total Penjualan</td>
|
|
||||||
<td className='text-sm px-4 py-3'>
|
|
||||||
{formatCurrency(parseFloat(item.total_price as string))}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{doItem && (
|
|
||||||
<tr>
|
|
||||||
<td className='text-sm px-4 py-3'>
|
|
||||||
Dokumen Pengiriman
|
|
||||||
</td>
|
|
||||||
<td className='text-sm px-4 py-3'>
|
|
||||||
<DeliveryOrderExport
|
|
||||||
data={marketing}
|
|
||||||
deliveryOrder={doItem}
|
|
||||||
/>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</Card>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -3,15 +3,9 @@
|
|||||||
import Button from '@/components/Button';
|
import Button from '@/components/Button';
|
||||||
import Card from '@/components/Card';
|
import Card from '@/components/Card';
|
||||||
import { SalesOrderProductFormValues } from '@/components/pages/marketing/form/repeater/sales-order/SalesOrderProduct.schema';
|
import { SalesOrderProductFormValues } from '@/components/pages/marketing/form/repeater/sales-order/SalesOrderProduct.schema';
|
||||||
import {
|
import { formatCurrency, formatNumber } from '@/lib/helper';
|
||||||
formatCurrency,
|
|
||||||
formatNumber,
|
|
||||||
formatVechicleNumber,
|
|
||||||
} from '@/lib/helper';
|
|
||||||
import { Icon } from '@iconify/react';
|
import { Icon } from '@iconify/react';
|
||||||
import { useMemo, useRef } from 'react';
|
import { useRef } from 'react';
|
||||||
import * as TanStack from '@tanstack/react-table';
|
|
||||||
import CheckboxInput from '@/components/input/CheckboxInput';
|
|
||||||
|
|
||||||
type SalesOrderProductTableProps = {
|
type SalesOrderProductTableProps = {
|
||||||
data: SalesOrderProductFormValues[];
|
data: SalesOrderProductFormValues[];
|
||||||
@@ -33,278 +27,168 @@ const SalesOrderProductTable = ({
|
|||||||
const onEditRef = useRef(onEdit);
|
const onEditRef = useRef(onEdit);
|
||||||
onEditRef.current = onEdit;
|
onEditRef.current = onEdit;
|
||||||
|
|
||||||
const columns = useMemo(
|
const renderTableContent = (item: SalesOrderProductFormValues) => (
|
||||||
() => [
|
<>
|
||||||
{
|
<tr className='border-b border-tools-table-outline border-base-content/5'>
|
||||||
id: 'select',
|
<th className='w-1/3 text-start not-first:font-medium text-base-content/50 text-sm px-4 py-3'>
|
||||||
header: ({
|
Label
|
||||||
table,
|
</th>
|
||||||
}: {
|
<th className='text-start font-medium text-base-content/50 text-sm px-4 py-3'>
|
||||||
table: TanStack.Table<SalesOrderProductFormValues>;
|
<div className='flex w-full flex-row gap-1 items-center justify-between h-full'>
|
||||||
}) => (
|
<div>Value</div>
|
||||||
<div className='w-full flex flex-row justify-center'>
|
{formType !== 'success' && (
|
||||||
<CheckboxInput
|
<div className='flex flex-row gap-1.5 items-center'>
|
||||||
name='allRow'
|
<Button
|
||||||
checked={table.getIsAllRowsSelected()}
|
type='button'
|
||||||
indeterminate={table.getIsSomeRowsSelected()}
|
variant='ghost'
|
||||||
onChange={table.getToggleAllRowsSelectedHandler()}
|
color='none'
|
||||||
/>
|
onClick={() => {
|
||||||
|
onEditRef.current(item.id as number);
|
||||||
|
}}
|
||||||
|
className='p-0 hover:text-base-content'
|
||||||
|
>
|
||||||
|
<Icon icon='heroicons:pencil' width={20} height={20} />
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
type='button'
|
||||||
|
variant='ghost'
|
||||||
|
color='none'
|
||||||
|
onClick={() => {
|
||||||
|
onDeleteRef.current(item.id as number);
|
||||||
|
}}
|
||||||
|
className='p-0 text-error hover:text-base-content'
|
||||||
|
>
|
||||||
|
<Icon icon='heroicons:trash' width={20} height={20} />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
),
|
</th>
|
||||||
cell: ({ row }: { row: TanStack.Row<SalesOrderProductFormValues> }) => (
|
</tr>
|
||||||
<div>
|
<>
|
||||||
<CheckboxInput
|
<tr>
|
||||||
name='row'
|
<td className='text-sm px-4 py-3'>No. Polisi</td>
|
||||||
checked={row.getIsSelected()}
|
<td className='text-sm px-4 py-3'>{item.vehicle_number}</td>
|
||||||
disabled={!row.getCanSelect()}
|
</tr>
|
||||||
indeterminate={row.getIsSomeSelected()}
|
<tr>
|
||||||
onChange={row.getToggleSelectedHandler()}
|
<td className='text-sm px-4 py-3'>Gudang</td>
|
||||||
value={`${row.original.product_warehouse_id}${row.original.kandang_id}`}
|
<td className='text-sm px-4 py-3'>{item.kandang?.label}</td>
|
||||||
/>
|
</tr>
|
||||||
</div>
|
<tr>
|
||||||
),
|
<td className='text-sm px-4 py-3'>Kategori</td>
|
||||||
},
|
<td className='text-sm px-4 py-3'>{item.marketing_type?.label}</td>
|
||||||
{
|
</tr>
|
||||||
accessorFn: (row: SalesOrderProductFormValues) =>
|
<tr>
|
||||||
formatVechicleNumber(row.vehicle_number as string),
|
<td className='text-sm px-4 py-3'>Produk</td>
|
||||||
header: 'No. Polisi',
|
<td className='text-sm px-4 py-3'>{item.product_warehouse?.label}</td>
|
||||||
},
|
</tr>
|
||||||
{
|
{item.marketing_type?.value.toLowerCase() === 'telur' && (
|
||||||
accessorFn: (row: SalesOrderProductFormValues) => row.kandang?.label,
|
<tr>
|
||||||
header: 'Kandang',
|
<td className='text-sm px-4 py-3'>Tipe Konversi</td>
|
||||||
},
|
<td className='text-sm px-4 py-3'>{item.convertion_unit?.label}</td>
|
||||||
{
|
</tr>
|
||||||
accessorFn: (row: SalesOrderProductFormValues) =>
|
)}
|
||||||
row.product_warehouse?.label,
|
{item.marketing_type?.value.toLowerCase() === 'ayam_pullet' && (
|
||||||
header: 'Produk',
|
<tr>
|
||||||
},
|
<td className='text-sm px-4 py-3'>Tipe Konversi</td>
|
||||||
{
|
<td className='text-sm px-4 py-3'>Week {item.week}</td>
|
||||||
accessorFn: (row: SalesOrderProductFormValues) =>
|
</tr>
|
||||||
formatCurrency(parseFloat(row.unit_price as string)),
|
)}
|
||||||
header: 'Harga Satuan (Rp)',
|
{item.convertion_unit?.value.toLowerCase() === 'peti' && (
|
||||||
},
|
<tr>
|
||||||
{
|
<td className='text-sm px-4 py-3'>Total Peti</td>
|
||||||
accessorFn: (row: SalesOrderProductFormValues) =>
|
<td className='text-sm px-4 py-3'>
|
||||||
formatNumber(parseFloat(row.total_weight as string), undefined, 0, 5),
|
{item.total_peti} {item.convertion_unit?.label}
|
||||||
header: 'Total Bobot (Kg)',
|
</td>
|
||||||
},
|
</tr>
|
||||||
{
|
)}
|
||||||
accessorFn: (row: SalesOrderProductFormValues) =>
|
{item.marketing_type?.value.toLowerCase() !== 'trading' && (
|
||||||
formatNumber(parseFloat(row.qty as string)),
|
<>
|
||||||
header: 'Kuantitas',
|
<tr>
|
||||||
cell: ({ row }: { row: TanStack.Row<SalesOrderProductFormValues> }) =>
|
<td className='text-sm px-4 py-3'>Total Bobot</td>
|
||||||
formatNumber(
|
<td className='text-sm px-4 py-3'>
|
||||||
parseFloat(row.original.qty as string),
|
{item.total_weight
|
||||||
undefined,
|
? formatNumber(parseFloat(item.total_weight as string)) +
|
||||||
0,
|
' Kg'
|
||||||
5
|
: '0 Kg'}
|
||||||
) +
|
</td>
|
||||||
' ' +
|
</tr>
|
||||||
(row.original.uom ?? ''),
|
<tr>
|
||||||
},
|
<td className='text-sm px-4 py-3'>Avg Bobot</td>
|
||||||
{
|
<td className='text-sm px-4 py-3'>
|
||||||
accessorFn: (row: SalesOrderProductFormValues) =>
|
{item.avg_weight
|
||||||
formatNumber(parseFloat(row.avg_weight as string), undefined, 0, 5),
|
? formatNumber(parseFloat(item.avg_weight as string)) + ' Kg'
|
||||||
header: 'Avg. Bobot (Kg)',
|
: '0 Kg'}
|
||||||
},
|
</td>
|
||||||
{
|
</tr>
|
||||||
accessorFn: (row: SalesOrderProductFormValues) =>
|
</>
|
||||||
formatCurrency(parseFloat(row.total_price as string)),
|
)}
|
||||||
header: 'Total Penjualan (Rp)',
|
<tr>
|
||||||
},
|
<td className='text-sm px-4 py-3'>
|
||||||
{
|
{item.marketing_type?.value === 'telur'
|
||||||
header: 'Aksi',
|
? 'Total Butir Telur'
|
||||||
cell: (
|
: 'Qty'}
|
||||||
props: TanStack.CellContext<SalesOrderProductFormValues, unknown>
|
</td>
|
||||||
) => (
|
<td className='text-sm px-4 py-3'>
|
||||||
<div className='flex flex-row gap-1 items-center justify-end h-full mt-2'>
|
{`${formatNumber(parseFloat(item.qty as string))} ${item.uom || ''}`}
|
||||||
<Button
|
</td>
|
||||||
color='warning'
|
</tr>
|
||||||
className='p-1'
|
<tr>
|
||||||
onClick={() => onEditRef.current(props.row.original.id as number)}
|
<td className='text-sm px-4 py-3'>Harga Satuan</td>
|
||||||
type='button'
|
<td className='text-sm px-4 py-3'>
|
||||||
>
|
{formatCurrency(parseFloat(item.unit_price as string))}
|
||||||
<Icon icon='mdi:pencil' width={16} height={16} /> Edit
|
</td>
|
||||||
</Button>
|
</tr>
|
||||||
<Button
|
<tr>
|
||||||
color='error'
|
<td className='text-sm px-4 py-3'>Total Penjualan</td>
|
||||||
className='p-1'
|
<td className='text-sm px-4 py-3'>
|
||||||
onClick={() =>
|
{formatCurrency(parseFloat(item.total_price as string))}
|
||||||
onDeleteRef.current(props.row.original.id as number)
|
</td>
|
||||||
}
|
</tr>
|
||||||
type='button'
|
</>
|
||||||
>
|
</>
|
||||||
<Icon icon='mdi:trash' width={16} height={16} /> Hapus
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
[]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className='size-full flex flex-col relative overflow-x-hidden gap-3'>
|
<div className='size-full flex flex-col relative overflow-x-hidden gap-3'>
|
||||||
{data.map((item) => (
|
{data.map((item) => (
|
||||||
<Card
|
<div key={`table-${item.id}`}>
|
||||||
key={`table-${item.id}`}
|
{formType === 'success' ? (
|
||||||
title={item.product_warehouse?.label || 'Produk'}
|
<div className='rounded-lg border border-tools-table-outline border-base-content/5'>
|
||||||
collapsible={true}
|
<table
|
||||||
defaultCollapsed={false}
|
style={{
|
||||||
variant='bordered'
|
borderRadius: '0.5rem',
|
||||||
className={{
|
}}
|
||||||
wrapper: 'w-full rounded-lg',
|
className='border-none w-full'
|
||||||
body: 'p-0',
|
>
|
||||||
title: 'px-2 py-1.5 font-normal text-sm',
|
<tbody className='w-full'>{renderTableContent(item)}</tbody>
|
||||||
collapsible: 'rounded-lg',
|
</table>
|
||||||
}}
|
</div>
|
||||||
>
|
) : (
|
||||||
<table
|
<Card
|
||||||
style={{
|
title={item.product_warehouse?.label || 'Produk'}
|
||||||
borderRadius: '0.5rem',
|
collapsible={true}
|
||||||
}}
|
defaultCollapsed={false}
|
||||||
className='border-none w-full'
|
variant='bordered'
|
||||||
>
|
className={{
|
||||||
<tbody className='w-full'>
|
wrapper: 'w-full rounded-lg',
|
||||||
<tr className='border-b border-t border-tools-table-outline border-base-content/5'>
|
body: 'p-0',
|
||||||
<th className='w-1/3 text-start not-first:font-medium text-base-content/50 text-sm px-4 py-3'>
|
title: 'px-2 py-1.5 font-normal text-sm',
|
||||||
Label
|
collapsible: 'rounded-lg',
|
||||||
</th>
|
}}
|
||||||
<th className='text-start font-medium text-base-content/50 text-sm px-4 py-3'>
|
>
|
||||||
<div className='flex w-full flex-row gap-1 items-center justify-between h-full'>
|
<table
|
||||||
<div>Value</div>
|
style={{
|
||||||
{formType !== 'success' && (
|
borderRadius: '0.5rem',
|
||||||
<div className='flex flex-row gap-1.5 items-center'>
|
}}
|
||||||
<Button
|
className='border-none w-full'
|
||||||
type='button'
|
>
|
||||||
variant='ghost'
|
<tbody className='w-full'>{renderTableContent(item)}</tbody>
|
||||||
color='none'
|
</table>
|
||||||
onClick={() => {
|
</Card>
|
||||||
onEditRef.current(item.id as number);
|
)}
|
||||||
}}
|
</div>
|
||||||
className='p-0 hover:text-base-content'
|
|
||||||
>
|
|
||||||
<Icon
|
|
||||||
icon='heroicons:pencil'
|
|
||||||
width={20}
|
|
||||||
height={20}
|
|
||||||
/>
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
type='button'
|
|
||||||
variant='ghost'
|
|
||||||
color='none'
|
|
||||||
onClick={() => {
|
|
||||||
onDeleteRef.current(item.id as number);
|
|
||||||
}}
|
|
||||||
className='p-0 text-error hover:text-base-content'
|
|
||||||
>
|
|
||||||
<Icon
|
|
||||||
icon='heroicons:trash'
|
|
||||||
width={20}
|
|
||||||
height={20}
|
|
||||||
/>
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
<>
|
|
||||||
<tr>
|
|
||||||
<td className='text-sm px-4 py-3'>No. Polisi</td>
|
|
||||||
<td className='text-sm px-4 py-3'>{item.vehicle_number}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td className='text-sm px-4 py-3'>Gudang</td>
|
|
||||||
<td className='text-sm px-4 py-3'>{item.kandang?.label}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td className='text-sm px-4 py-3'>Kategori</td>
|
|
||||||
<td className='text-sm px-4 py-3'>
|
|
||||||
{item.marketing_type?.label}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td className='text-sm px-4 py-3'>Produk</td>
|
|
||||||
<td className='text-sm px-4 py-3'>
|
|
||||||
{item.product_warehouse?.label}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{item.marketing_type?.value.toLowerCase() === 'telur' && (
|
|
||||||
<tr>
|
|
||||||
<td className='text-sm px-4 py-3'>Tipe Konversi</td>
|
|
||||||
<td className='text-sm px-4 py-3'>
|
|
||||||
{item.convertion_unit?.label}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
)}
|
|
||||||
{item.marketing_type?.value.toLowerCase() ===
|
|
||||||
'ayam_pullet' && (
|
|
||||||
<tr>
|
|
||||||
<td className='text-sm px-4 py-3'>Tipe Konversi</td>
|
|
||||||
<td className='text-sm px-4 py-3'>Week {item.week}</td>
|
|
||||||
</tr>
|
|
||||||
)}
|
|
||||||
{item.convertion_unit?.value.toLowerCase() === 'peti' && (
|
|
||||||
<tr>
|
|
||||||
<td className='text-sm px-4 py-3'>Total Peti</td>
|
|
||||||
<td className='text-sm px-4 py-3'>
|
|
||||||
{item.total_peti} {item.convertion_unit?.label}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
)}
|
|
||||||
{item.marketing_type?.value.toLowerCase() !== 'trading' && (
|
|
||||||
<>
|
|
||||||
<tr>
|
|
||||||
<td className='text-sm px-4 py-3'>Total Bobot</td>
|
|
||||||
<td className='text-sm px-4 py-3'>
|
|
||||||
{item.total_weight
|
|
||||||
? formatNumber(
|
|
||||||
parseFloat(item.total_weight as string)
|
|
||||||
) + ' Kg'
|
|
||||||
: '0 Kg'}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td className='text-sm px-4 py-3'>Avg Bobot</td>
|
|
||||||
<td className='text-sm px-4 py-3'>
|
|
||||||
{item.avg_weight
|
|
||||||
? formatNumber(
|
|
||||||
parseFloat(item.avg_weight as string)
|
|
||||||
) + ' Kg'
|
|
||||||
: '0 Kg'}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
<tr>
|
|
||||||
<td className='text-sm px-4 py-3'>
|
|
||||||
{item.marketing_type?.value === 'telur'
|
|
||||||
? 'Total Butir Telur'
|
|
||||||
: 'Qty'}
|
|
||||||
</td>
|
|
||||||
<td className='text-sm px-4 py-3'>
|
|
||||||
{`${formatNumber(parseFloat(item.qty as string))} ${item.uom || ''}`}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td className='text-sm px-4 py-3'>Harga Satuan</td>
|
|
||||||
<td className='text-sm px-4 py-3'>
|
|
||||||
{formatCurrency(parseFloat(item.unit_price as string))}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td className='text-sm px-4 py-3'>Total Penjualan</td>
|
|
||||||
<td className='text-sm px-4 py-3'>
|
|
||||||
{formatCurrency(parseFloat(item.total_price as string))}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</Card>
|
|
||||||
))}
|
))}
|
||||||
{formType != 'add_deliver' &&
|
{formType != 'add_deliver' &&
|
||||||
formType != 'edit_deliver' &&
|
formType != 'edit_deliver' &&
|
||||||
|
|||||||
@@ -512,13 +512,9 @@ export const FILTER_TYPE_OPTIONS = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
export const MARKETING_TYPE_OPTIONS = [
|
export const MARKETING_TYPE_OPTIONS = [
|
||||||
{
|
|
||||||
label: 'Ayam Pullet',
|
|
||||||
value: 'AYAM_PULLET',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
label: 'Ayam',
|
label: 'Ayam',
|
||||||
value: 'AYAM',
|
value: 'AYAM,AYAM_PULLET',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Trading',
|
label: 'Trading',
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ export type BaseProductWarehouse = {
|
|||||||
quantity: number;
|
quantity: number;
|
||||||
product: Product;
|
product: Product;
|
||||||
warehouse: Warehouse;
|
warehouse: Warehouse;
|
||||||
|
week?: number | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ProductWarehouse = BaseMetadata & BaseProductWarehouse;
|
export type ProductWarehouse = BaseMetadata & BaseProductWarehouse;
|
||||||
|
|||||||
Reference in New Issue
Block a user