mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-23 23:05:46 +00:00
Merge branch 'fix/marketing' into 'development'
[FIX/FE] Adding Button Edit and Delete per Product on Marketing Form See merge request mbugroup/lti-web-client!213
This commit is contained in:
@@ -361,6 +361,8 @@ const MarketingForm = ({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const memoSalesOrder = formik.values.sales_order;
|
||||||
|
|
||||||
// ================== FORM REPEATER HANDLER ==================
|
// ================== FORM REPEATER HANDLER ==================
|
||||||
const createMarketingHandler = async (values: CreateSalesOrderPayload) => {
|
const createMarketingHandler = async (values: CreateSalesOrderPayload) => {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
@@ -471,13 +473,25 @@ const MarketingForm = ({
|
|||||||
}, [deleteModal]);
|
}, [deleteModal]);
|
||||||
|
|
||||||
// ================== SALES ORDER HANDLER ==================
|
// ================== SALES ORDER HANDLER ==================
|
||||||
const handleDeleteSO = useCallback((id: number) => {
|
const handleDeleteSO = useCallback(
|
||||||
const currentProducts = formik.values.sales_order;
|
(id: number) => {
|
||||||
formik.setFieldValue(
|
const currentProducts = formik.values.sales_order;
|
||||||
'sales_order',
|
formik.setFieldValue(
|
||||||
currentProducts.filter((p) => p.id != id)
|
'sales_order',
|
||||||
);
|
currentProducts.filter((p) => p.id != id)
|
||||||
}, []);
|
);
|
||||||
|
},
|
||||||
|
[memoSalesOrder]
|
||||||
|
);
|
||||||
|
const handleEditSO = useCallback(
|
||||||
|
(id: number) => {
|
||||||
|
const currentProducts = formik.values.sales_order;
|
||||||
|
const selectedProduct = currentProducts.find((p) => p.id == id);
|
||||||
|
setSelectedMarketingProduct(selectedProduct ?? null);
|
||||||
|
addSOModal.openModal();
|
||||||
|
},
|
||||||
|
[memoSalesOrder]
|
||||||
|
);
|
||||||
const handleBulkDeleteSO = useCallback(() => {
|
const handleBulkDeleteSO = useCallback(() => {
|
||||||
const currentProducts = formik.values.sales_order;
|
const currentProducts = formik.values.sales_order;
|
||||||
formik.setFieldValue(
|
formik.setFieldValue(
|
||||||
@@ -487,7 +501,7 @@ const MarketingForm = ({
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
setRowSOSelection({});
|
setRowSOSelection({});
|
||||||
}, [selectedRowSOIds]);
|
}, [selectedRowSOIds, memoSalesOrder]);
|
||||||
const handleAddSOClick = useCallback(() => {
|
const handleAddSOClick = useCallback(() => {
|
||||||
setSelectedMarketingProduct(null);
|
setSelectedMarketingProduct(null);
|
||||||
addSOModal.openModal();
|
addSOModal.openModal();
|
||||||
@@ -523,7 +537,7 @@ const MarketingForm = ({
|
|||||||
|
|
||||||
addSOModal.closeModal();
|
addSOModal.closeModal();
|
||||||
},
|
},
|
||||||
[addSOModal]
|
[addSOModal, memoSalesOrder]
|
||||||
);
|
);
|
||||||
|
|
||||||
// ================== DELIVERY ORDER HANDLER ==================
|
// ================== DELIVERY ORDER HANDLER ==================
|
||||||
@@ -568,8 +582,30 @@ const MarketingForm = ({
|
|||||||
},
|
},
|
||||||
[addDOModal]
|
[addDOModal]
|
||||||
);
|
);
|
||||||
|
const handleDeleteDO = useCallback(
|
||||||
const memoSalesOrder = formik.values.sales_order;
|
async (id: number) => {
|
||||||
|
setDeliveryOrderValues((prev) =>
|
||||||
|
prev.map((product) =>
|
||||||
|
product.id === id
|
||||||
|
? {
|
||||||
|
...product,
|
||||||
|
...{
|
||||||
|
unit_price: '',
|
||||||
|
total_weight: '',
|
||||||
|
qty: '',
|
||||||
|
avg_weight: '',
|
||||||
|
total_price: '',
|
||||||
|
delivery_date: '',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
: product
|
||||||
|
)
|
||||||
|
);
|
||||||
|
addDOModal.closeModal();
|
||||||
|
setSelectedDeliveryProduct(null);
|
||||||
|
},
|
||||||
|
[addDOModal]
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
formik.setFieldValue('delivery_order', deliveryOrderValues);
|
formik.setFieldValue('delivery_order', deliveryOrderValues);
|
||||||
@@ -654,6 +690,7 @@ const MarketingForm = ({
|
|||||||
setRowSelection={setRowSOSelection}
|
setRowSelection={setRowSOSelection}
|
||||||
selectedRowIds={selectedRowSOIds}
|
selectedRowIds={selectedRowSOIds}
|
||||||
onDelete={handleDeleteSO}
|
onDelete={handleDeleteSO}
|
||||||
|
onEdit={handleEditSO}
|
||||||
onBulkDelete={handleBulkDeleteSO}
|
onBulkDelete={handleBulkDeleteSO}
|
||||||
onAddProductClick={handleAddSOClick}
|
onAddProductClick={handleAddSOClick}
|
||||||
/>
|
/>
|
||||||
@@ -673,6 +710,7 @@ const MarketingForm = ({
|
|||||||
formType={formType}
|
formType={formType}
|
||||||
data={deliveryOrderValues}
|
data={deliveryOrderValues}
|
||||||
onEdit={handleEditDO}
|
onEdit={handleEditDO}
|
||||||
|
onDelete={handleDeleteDO}
|
||||||
onAddProductClick={handleAddDOClick}
|
onAddProductClick={handleAddDOClick}
|
||||||
/>
|
/>
|
||||||
</Card>
|
</Card>
|
||||||
|
|||||||
@@ -106,6 +106,7 @@ const DeliveryOrderProductForm = ({
|
|||||||
await onUpdateForm?.(values.marketing_product_id as number, values);
|
await onUpdateForm?.(values.marketing_product_id as number, values);
|
||||||
}
|
}
|
||||||
handleResetForm();
|
handleResetForm();
|
||||||
|
setSelectedProduct(null);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -124,7 +125,7 @@ const DeliveryOrderProductForm = ({
|
|||||||
marketing_product: undefined,
|
marketing_product: undefined,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
setSelectedProduct(null);
|
// setSelectedProduct(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleBlurField = (field: string) => {
|
const handleBlurField = (field: string) => {
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ type SalesOrderProductSchemaType = {
|
|||||||
avg_weight: string | number | undefined;
|
avg_weight: string | number | undefined;
|
||||||
total_price: string | number | undefined;
|
total_price: string | number | undefined;
|
||||||
vehicle_number?: string | undefined;
|
vehicle_number?: string | undefined;
|
||||||
|
uom?: string | null | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SalesOrderProductSchema: Yup.ObjectSchema<SalesOrderProductSchemaType> =
|
export const SalesOrderProductSchema: Yup.ObjectSchema<SalesOrderProductSchemaType> =
|
||||||
@@ -57,6 +58,7 @@ export const SalesOrderProductSchema: Yup.ObjectSchema<SalesOrderProductSchemaTy
|
|||||||
total_price: Yup.number()
|
total_price: Yup.number()
|
||||||
.min(1, 'Total Penjualan wajib diisi!')
|
.min(1, 'Total Penjualan wajib diisi!')
|
||||||
.required('Total Penjualan wajib diisi!'),
|
.required('Total Penjualan wajib diisi!'),
|
||||||
|
uom: Yup.string().nullable().optional().notRequired(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export type SalesOrderProductFormValues = Yup.InferType<
|
export type SalesOrderProductFormValues = Yup.InferType<
|
||||||
|
|||||||
@@ -61,16 +61,17 @@ const SalesOrderProductForm = ({
|
|||||||
const formik = useFormik<SalesOrderProductFormValues>({
|
const formik = useFormik<SalesOrderProductFormValues>({
|
||||||
enableReinitialize: true,
|
enableReinitialize: true,
|
||||||
initialValues: {
|
initialValues: {
|
||||||
vehicle_number: initialValues?.vehicle_number || undefined,
|
vehicle_number: initialValues?.vehicle_number || '',
|
||||||
kandang_id: initialValues?.kandang_id || undefined,
|
kandang_id: initialValues?.kandang_id || undefined,
|
||||||
kandang: initialValues?.kandang || undefined,
|
kandang: initialValues?.kandang || null,
|
||||||
product_warehouse: initialValues?.product_warehouse || undefined,
|
product_warehouse: initialValues?.product_warehouse || null,
|
||||||
product_warehouse_id: initialValues?.product_warehouse_id || undefined,
|
product_warehouse_id: initialValues?.product_warehouse_id || undefined,
|
||||||
unit_price: initialValues?.unit_price || undefined,
|
unit_price: initialValues?.unit_price || '',
|
||||||
total_weight: initialValues?.total_weight || undefined,
|
total_weight: initialValues?.total_weight || '',
|
||||||
qty: initialValues?.qty || undefined,
|
qty: initialValues?.qty || '',
|
||||||
avg_weight: initialValues?.avg_weight || undefined,
|
avg_weight: initialValues?.avg_weight || '',
|
||||||
total_price: initialValues?.total_price || undefined,
|
total_price: initialValues?.total_price || '',
|
||||||
|
uom: initialValues?.uom || '',
|
||||||
},
|
},
|
||||||
validationSchema: SalesOrderProductSchema,
|
validationSchema: SalesOrderProductSchema,
|
||||||
onSubmit: async (values) => {
|
onSubmit: async (values) => {
|
||||||
@@ -220,7 +221,19 @@ const SalesOrderProductForm = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
// ===== Formik Error List =====
|
// ===== Formik Error List =====
|
||||||
const { formErrorList, close, handleFormSubmit } = useFormikErrorList(formik);
|
const { formErrorList, close, handleFormSubmit } = useFormikErrorList(
|
||||||
|
formik,
|
||||||
|
{
|
||||||
|
onBeforeSubmit(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
handleBlurField(currentInput);
|
||||||
|
formik.setFieldValue(
|
||||||
|
'uom',
|
||||||
|
isResponseSuccess(productData) ? productData?.data?.uom.name : ''
|
||||||
|
);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ type DeliveryOrderProductTableProps = {
|
|||||||
data: DeliveryOrderProductFormValues[];
|
data: DeliveryOrderProductFormValues[];
|
||||||
formType?: 'add' | 'edit' | 'add_deliver' | 'edit_deliver';
|
formType?: 'add' | 'edit' | 'add_deliver' | 'edit_deliver';
|
||||||
onEdit: (id: number) => void;
|
onEdit: (id: number) => void;
|
||||||
|
onDelete: (id: number) => void;
|
||||||
onAddProductClick: () => void;
|
onAddProductClick: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -23,10 +24,13 @@ const DeliveryOrderProductTable = ({
|
|||||||
data,
|
data,
|
||||||
formType,
|
formType,
|
||||||
onEdit,
|
onEdit,
|
||||||
|
onDelete,
|
||||||
onAddProductClick,
|
onAddProductClick,
|
||||||
}: DeliveryOrderProductTableProps) => {
|
}: DeliveryOrderProductTableProps) => {
|
||||||
const onEditRef = useRef(onEdit);
|
const onEditRef = useRef(onEdit);
|
||||||
onEditRef.current = onEdit;
|
onEditRef.current = onEdit;
|
||||||
|
const onDeleteRef = useRef(onDelete);
|
||||||
|
onDeleteRef.current = onDelete;
|
||||||
|
|
||||||
const canAddData = data.filter((item) => !Boolean(item.qty));
|
const canAddData = data.filter((item) => !Boolean(item.qty));
|
||||||
|
|
||||||
@@ -144,16 +148,29 @@ const DeliveryOrderProductTable = ({
|
|||||||
<div className='flex flex-row gap-1 items-center justify-end h-full mt-2'>
|
<div className='flex flex-row gap-1 items-center justify-end h-full mt-2'>
|
||||||
<>
|
<>
|
||||||
{props.row.original.qty && (
|
{props.row.original.qty && (
|
||||||
<Button
|
<>
|
||||||
color='warning'
|
<Button
|
||||||
className='px-2 py-1 text-sm'
|
color='warning'
|
||||||
onClick={() =>
|
className='px-2 py-1 text-sm'
|
||||||
onEditRef.current(props.row.original.id as number)
|
onClick={() =>
|
||||||
}
|
onEditRef.current(props.row.original.id as number)
|
||||||
type='button'
|
}
|
||||||
>
|
type='button'
|
||||||
<Icon icon='mdi:edit' width={16} height={16} /> Edit
|
>
|
||||||
</Button>
|
<Icon icon='mdi:edit' width={16} height={16} /> Edit
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
color='error'
|
||||||
|
className='px-2 py-1 text-sm'
|
||||||
|
onClick={() =>
|
||||||
|
onDeleteRef.current(props.row.original.id as number)
|
||||||
|
}
|
||||||
|
type='button'
|
||||||
|
disabled={!!props.row.original.do_number}
|
||||||
|
>
|
||||||
|
<Icon icon='mdi:delete' width={16} height={16} /> Hapus
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
{!props.row.original.qty && '-'}
|
{!props.row.original.qty && '-'}
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ type SalesOrderProductTableProps = {
|
|||||||
>;
|
>;
|
||||||
selectedRowIds: number[];
|
selectedRowIds: number[];
|
||||||
onDelete: (id: number) => void;
|
onDelete: (id: number) => void;
|
||||||
|
onEdit: (id: number) => void;
|
||||||
onBulkDelete: () => void;
|
onBulkDelete: () => void;
|
||||||
onAddProductClick: () => void;
|
onAddProductClick: () => void;
|
||||||
};
|
};
|
||||||
@@ -34,11 +35,14 @@ const SalesOrderProductTable = ({
|
|||||||
setRowSelection,
|
setRowSelection,
|
||||||
selectedRowIds,
|
selectedRowIds,
|
||||||
onDelete,
|
onDelete,
|
||||||
|
onEdit,
|
||||||
onBulkDelete,
|
onBulkDelete,
|
||||||
onAddProductClick,
|
onAddProductClick,
|
||||||
}: SalesOrderProductTableProps) => {
|
}: SalesOrderProductTableProps) => {
|
||||||
const onDeleteRef = useRef(onDelete);
|
const onDeleteRef = useRef(onDelete);
|
||||||
onDeleteRef.current = onDelete;
|
onDeleteRef.current = onDelete;
|
||||||
|
const onEditRef = useRef(onEdit);
|
||||||
|
onEditRef.current = onEdit;
|
||||||
|
|
||||||
const columns = useMemo(
|
const columns = useMemo(
|
||||||
() => [
|
() => [
|
||||||
@@ -92,17 +96,26 @@ const SalesOrderProductTable = ({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorFn: (row: SalesOrderProductFormValues) =>
|
accessorFn: (row: SalesOrderProductFormValues) =>
|
||||||
formatNumber(parseFloat(row.total_weight as string)),
|
formatNumber(parseFloat(row.total_weight as string), undefined, 0, 5),
|
||||||
header: 'Total Bobot (Kg)',
|
header: 'Total Bobot (Kg)',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorFn: (row: SalesOrderProductFormValues) =>
|
accessorFn: (row: SalesOrderProductFormValues) =>
|
||||||
formatNumber(parseFloat(row.qty as string)),
|
formatNumber(parseFloat(row.qty as string)),
|
||||||
header: 'Kuantitas',
|
header: 'Kuantitas',
|
||||||
|
cell: ({ row }: { row: TanStack.Row<SalesOrderProductFormValues> }) =>
|
||||||
|
formatNumber(
|
||||||
|
parseFloat(row.original.qty as string),
|
||||||
|
undefined,
|
||||||
|
0,
|
||||||
|
5
|
||||||
|
) +
|
||||||
|
' ' +
|
||||||
|
(row.original.uom ?? ''),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorFn: (row: SalesOrderProductFormValues) =>
|
accessorFn: (row: SalesOrderProductFormValues) =>
|
||||||
formatNumber(parseFloat(row.avg_weight as string)),
|
formatNumber(parseFloat(row.avg_weight as string), undefined, 0, 5),
|
||||||
header: 'Avg. Bobot (Kg)',
|
header: 'Avg. Bobot (Kg)',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -116,6 +129,14 @@ const SalesOrderProductTable = ({
|
|||||||
props: TanStack.CellContext<SalesOrderProductFormValues, unknown>
|
props: TanStack.CellContext<SalesOrderProductFormValues, unknown>
|
||||||
) => (
|
) => (
|
||||||
<div className='flex flex-row gap-1 items-center justify-end h-full mt-2'>
|
<div className='flex flex-row gap-1 items-center justify-end h-full mt-2'>
|
||||||
|
<Button
|
||||||
|
color='warning'
|
||||||
|
className='p-1'
|
||||||
|
onClick={() => onEditRef.current(props.row.original.id as number)}
|
||||||
|
type='button'
|
||||||
|
>
|
||||||
|
<Icon icon='mdi:pencil' width={16} height={16} /> Edit
|
||||||
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
color='error'
|
color='error'
|
||||||
className='p-1'
|
className='p-1'
|
||||||
@@ -124,7 +145,7 @@ const SalesOrderProductTable = ({
|
|||||||
}
|
}
|
||||||
type='button'
|
type='button'
|
||||||
>
|
>
|
||||||
<Icon icon='mdi:trash' width={16} height={16} />
|
<Icon icon='mdi:trash' width={16} height={16} /> Hapus
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user