mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 13:32:00 +00:00
fix(FE): add sales person, refactor calculate total weight and price, add uom information and implement lazy load select
This commit is contained in:
@@ -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<SalesOrderSchemaType> =
|
||||
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(),
|
||||
|
||||
@@ -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<Customer>(CustomerApi.basePath, 'id', 'name');
|
||||
const {
|
||||
options: salesOptions,
|
||||
isLoadingOptions: isLoadingSalesOptions,
|
||||
setInputValue: setInputSalesValue,
|
||||
loadMore: loadMoreSales,
|
||||
} = useSelect<CreatedUser>(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'
|
||||
>
|
||||
<div className='grid sm:grid-cols-2 gap-3 mt-3'>
|
||||
<SelectInput
|
||||
@@ -588,6 +612,8 @@ const MarketingForm = ({
|
||||
isLoading={isLoadingCustomerOptions}
|
||||
value={formik.values.customer}
|
||||
onChange={handleChangeCustomer}
|
||||
onInputChange={setInputCustomerValue}
|
||||
onMenuScrollToBottom={loadMoreCustomer}
|
||||
isError={
|
||||
formik.touched.customer_id && Boolean(formik.errors.customer_id)
|
||||
}
|
||||
@@ -617,6 +643,7 @@ const MarketingForm = ({
|
||||
className={{
|
||||
wrapper: 'bg-white w-full',
|
||||
}}
|
||||
variant='bordered'
|
||||
>
|
||||
<MemoizedSalesOrderProductTable
|
||||
formType={formType}
|
||||
@@ -651,19 +678,42 @@ const MarketingForm = ({
|
||||
|
||||
{/* Input Notes */}
|
||||
<div className='grid sm:grid-cols-2 gap-3'>
|
||||
<DebouncedTextArea
|
||||
required
|
||||
name='notes'
|
||||
label='Catatan'
|
||||
rows={3}
|
||||
placeholder='Masukan catatan penjualan'
|
||||
value={formik.values.notes}
|
||||
onChange={formik.handleChange}
|
||||
isError={formik.touched.notes && Boolean(formik.errors.notes)}
|
||||
errorMessage={formik.errors.notes}
|
||||
disabled={formType === 'add_deliver' || formType === 'edit_deliver'}
|
||||
/>
|
||||
<div className='flex flex-col h-full justify-between items-end py-6'>
|
||||
<div className='flex flex-col h-full items-end gap-3'>
|
||||
<SelectInput
|
||||
label='Sales'
|
||||
options={salesOptions}
|
||||
isLoading={isLoadingSalesOptions}
|
||||
value={formik.values.sales_person}
|
||||
onChange={handleChangeSalesPerson}
|
||||
onInputChange={setInputSalesValue}
|
||||
onMenuScrollToBottom={loadMoreSales}
|
||||
isError={
|
||||
formik.touched.sales_person_id &&
|
||||
Boolean(formik.errors.sales_person_id)
|
||||
}
|
||||
errorMessage={formik.errors.sales_person_id}
|
||||
isClearable
|
||||
placeholder='Pilih Sales'
|
||||
isDisabled={
|
||||
formType === 'add_deliver' || formType === 'edit_deliver'
|
||||
}
|
||||
/>
|
||||
<DebouncedTextArea
|
||||
required
|
||||
name='notes'
|
||||
label='Catatan'
|
||||
rows={3}
|
||||
placeholder='Masukan catatan penjualan'
|
||||
value={formik.values.notes}
|
||||
onChange={formik.handleChange}
|
||||
isError={formik.touched.notes && Boolean(formik.errors.notes)}
|
||||
errorMessage={formik.errors.notes}
|
||||
disabled={
|
||||
formType === 'add_deliver' || formType === 'edit_deliver'
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div className='flex flex-col h-full justify-end items-end'>
|
||||
<span>Total Penjualan</span>
|
||||
<span className='text-lg font-semibold'>
|
||||
{formatCurrency(grandTotal)}{' '}
|
||||
|
||||
+99
-35
@@ -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<string>('');
|
||||
|
||||
// ============ 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 = ({
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className='grid sm:grid-cols-2 gap-4'>
|
||||
<div className='grid sm:grid-cols-3 gap-4'>
|
||||
<SelectInput
|
||||
options={options}
|
||||
label='Produk'
|
||||
@@ -287,7 +341,9 @@ const DeliveryOrderProductForm = ({
|
||||
isError={Boolean(formik.errors.vehicle_number)}
|
||||
errorMessage={formik.errors.vehicle_number}
|
||||
/>
|
||||
|
||||
</div>
|
||||
<div className='divider my-6'></div>
|
||||
<div className='grid sm:grid-cols-3 gap-4'>
|
||||
<NumberInput
|
||||
required
|
||||
label='Kuantitas'
|
||||
@@ -301,33 +357,28 @@ const DeliveryOrderProductForm = ({
|
||||
isError={Boolean(formik.errors.qty)}
|
||||
errorMessage={formik.errors.qty}
|
||||
placeholder='Masukan Kuantitas'
|
||||
endAdornment={
|
||||
<div className='flex items-center gap-2'>
|
||||
<span className='text-sm text-gray-500'>
|
||||
{isResponseSuccess(productData)
|
||||
? productData?.data?.uom.name
|
||||
: ''}
|
||||
</span>
|
||||
</div>
|
||||
}
|
||||
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
|
||||
: '')
|
||||
: ''
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div className='divider my-6'></div>
|
||||
<div className='grid sm:grid-cols-2 gap-4'>
|
||||
<NumberInput
|
||||
required
|
||||
label='Avg. Bobot (Kg)'
|
||||
name='avg_weight'
|
||||
value={formik.values.avg_weight}
|
||||
onChange={(e) => {
|
||||
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'
|
||||
/>
|
||||
|
||||
<NumberInput
|
||||
required
|
||||
label='Harga Satuan (Rp)'
|
||||
@@ -342,7 +393,20 @@ const DeliveryOrderProductForm = ({
|
||||
errorMessage={formik.errors.unit_price}
|
||||
placeholder='Masukan Harga Satuan'
|
||||
/>
|
||||
|
||||
<NumberInput
|
||||
required
|
||||
label='Avg. Bobot (Kg)'
|
||||
name='avg_weight'
|
||||
value={formik.values.avg_weight}
|
||||
onChange={(e) => {
|
||||
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'
|
||||
/>
|
||||
<NumberInput
|
||||
required
|
||||
label='Total Bobot (Kg)'
|
||||
|
||||
+111
-50
@@ -11,7 +11,7 @@ import SelectInput, {
|
||||
useSelect,
|
||||
} from '@/components/input/SelectInput';
|
||||
import { Kandang } from '@/types/api/master-data/kandang';
|
||||
import { WarehouseApi } from '@/services/api/master-data';
|
||||
import { ProductApi, UomApi, WarehouseApi } from '@/services/api/master-data';
|
||||
import { ProductWarehouse } from '@/types/api/inventory/product-warehouse';
|
||||
import { ProductWarehouseApi } from '@/services/api/inventory';
|
||||
import NumberInput from '@/components/input/NumberInput';
|
||||
@@ -26,6 +26,10 @@ import PatternInput from '@/components/input/PatternInput';
|
||||
import Alert from '@/components/Alert';
|
||||
import AlertErrorList from '@/components/helper/form/FormErrors';
|
||||
import { useFormikErrorList } from '@/services/hooks/useFormikErrorList';
|
||||
import useSWR from 'swr';
|
||||
|
||||
const roundWeight = (value: number) => 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<string>('');
|
||||
const [selectedProductWarehouse, setSelectedProductWarehouse] =
|
||||
useState<ProductWarehouse | null>(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<SalesOrderProductFormValues>({
|
||||
@@ -69,17 +86,21 @@ const SalesOrderProductForm = ({
|
||||
const {
|
||||
options: kandangSourceOptions,
|
||||
isLoadingOptions: isLoadingKandangSourceOptions,
|
||||
setInputValue: setKandangInputValue,
|
||||
loadMore: loadMoreKandang,
|
||||
} = useSelect<Kandang>(WarehouseApi.basePath, 'id', 'name');
|
||||
|
||||
const {
|
||||
options: warehouseSourceOptions,
|
||||
rawData: warehouseSourceRawData,
|
||||
isLoadingOptions: isLoadingWarehouseSourceOptions,
|
||||
setInputValue: setWarehouseInputValue,
|
||||
loadMore: loadMoreWarehouse,
|
||||
} = useSelect<ProductWarehouse>(
|
||||
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 = ({
|
||||
</Alert>
|
||||
</div>
|
||||
)}
|
||||
<div className='grid sm:grid-cols-2 gap-4 z-200'>
|
||||
<div className='grid sm:grid-cols-3 gap-4 z-200'>
|
||||
<PatternInput
|
||||
name='vehicle_number'
|
||||
label='No. Polisi'
|
||||
@@ -215,6 +263,8 @@ const SalesOrderProductForm = ({
|
||||
value={formik.values.kandang}
|
||||
onChange={kandangChangeHandler}
|
||||
isClearable
|
||||
onInputChange={setKandangInputValue}
|
||||
onMenuScrollToBottom={loadMoreKandang}
|
||||
isError={
|
||||
formik.touched.kandang_id && Boolean(formik.errors.kandang_id)
|
||||
}
|
||||
@@ -228,6 +278,8 @@ const SalesOrderProductForm = ({
|
||||
isLoading={isLoadingWarehouseSourceOptions}
|
||||
value={formik.values.product_warehouse}
|
||||
onChange={warehouseChangeHandler}
|
||||
onInputChange={setWarehouseInputValue}
|
||||
onMenuScrollToBottom={loadMoreWarehouse}
|
||||
isClearable
|
||||
placeholder={
|
||||
formik.values.kandang_id
|
||||
@@ -243,6 +295,9 @@ const SalesOrderProductForm = ({
|
||||
}
|
||||
errorMessage={formik.errors.product_warehouse_id}
|
||||
/>
|
||||
</div>
|
||||
<div className='divider my-6'></div>
|
||||
<div className='grid sm:grid-cols-3 gap-4 z-200'>
|
||||
<NumberInput
|
||||
required
|
||||
label='Kuantitas'
|
||||
@@ -256,6 +311,15 @@ const SalesOrderProductForm = ({
|
||||
isError={formik.touched.qty && Boolean(formik.errors.qty)}
|
||||
errorMessage={formik.errors.qty}
|
||||
placeholder='Masukan Kuantitas'
|
||||
endAdornment={
|
||||
<div className='flex items-center gap-2'>
|
||||
<span className='text-sm text-gray-500'>
|
||||
{isResponseSuccess(productData)
|
||||
? productData?.data?.uom.name
|
||||
: ''}
|
||||
</span>
|
||||
</div>
|
||||
}
|
||||
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
|
||||
: ''
|
||||
}`
|
||||
: ''
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div className='divider my-6'></div>
|
||||
<div className='grid sm:grid-cols-2 gap-4 z-200'>
|
||||
<NumberInput
|
||||
required
|
||||
label='Avg. Bobot (Kg)'
|
||||
name='avg_weight'
|
||||
value={formik.values.avg_weight}
|
||||
onChange={(e) => {
|
||||
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'
|
||||
/>
|
||||
<NumberInput
|
||||
required
|
||||
label='Harga Satuan (Rp)'
|
||||
@@ -306,6 +351,22 @@ const SalesOrderProductForm = ({
|
||||
errorMessage={formik.errors.unit_price}
|
||||
placeholder='Masukan Harga Satuan'
|
||||
/>
|
||||
<NumberInput
|
||||
required
|
||||
label='Avg. Bobot (Kg)'
|
||||
name='avg_weight'
|
||||
value={formik.values.avg_weight}
|
||||
onChange={(e) => {
|
||||
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'
|
||||
/>
|
||||
<NumberInput
|
||||
required
|
||||
label='Total Bobot (Kg)'
|
||||
|
||||
@@ -563,7 +563,7 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
||||
todayRecordings.forEach((recording) => {
|
||||
const recordingDate = recording.record_datetime?.split('T')[0];
|
||||
if (recordingDate === today) {
|
||||
recordedIds.add(recording.project_flock.project_flock_kandang_id);
|
||||
recordedIds.add(recording.project_flock?.project_flock_kandang_id);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user