mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 21:41:57 +00:00
fix(FE): skeleton for input skenario sales order
This commit is contained in:
@@ -650,7 +650,7 @@ const SalesOrderFormModal = ({
|
||||
</Button>
|
||||
</RequirePermission>
|
||||
</div>
|
||||
<div className='flex flex-1 flex-col p-4'>
|
||||
<div className='flex flex-1 flex-col'>
|
||||
<MemoizedSalesOrderProductForm
|
||||
onSubmitForm={handleAddSubmitSO}
|
||||
initialValues={selectedMarketingProduct ?? undefined}
|
||||
|
||||
@@ -19,6 +19,23 @@ type SalesOrderProductSchemaType = {
|
||||
total_price: string | number | undefined;
|
||||
vehicle_number?: string | undefined;
|
||||
uom?: string | null | undefined;
|
||||
convertion_unit?: {
|
||||
value: string;
|
||||
label: string;
|
||||
} | null;
|
||||
weight_per_convertion?: number | null | undefined;
|
||||
price_per_convertion?: number | null | undefined;
|
||||
marketing_type?: {
|
||||
value: string;
|
||||
label: string;
|
||||
} | null;
|
||||
total_peti?: number | null | undefined;
|
||||
sisa_berat?: number | null | undefined;
|
||||
price_sisa_berat?: number | null | undefined;
|
||||
weeks?: {
|
||||
value: number;
|
||||
label: string;
|
||||
} | null;
|
||||
};
|
||||
|
||||
export const SalesOrderProductSchema: Yup.ObjectSchema<SalesOrderProductSchemaType> =
|
||||
@@ -59,6 +76,23 @@ export const SalesOrderProductSchema: Yup.ObjectSchema<SalesOrderProductSchemaTy
|
||||
.min(1, 'Total Penjualan wajib diisi!')
|
||||
.required('Total Penjualan wajib diisi!'),
|
||||
uom: Yup.string().nullable().optional().notRequired(),
|
||||
convertion_unit: Yup.object({
|
||||
value: Yup.string().required('Konversi Satuan wajib diisi!'),
|
||||
label: Yup.string().required('Konversi Satuan wajib diisi!'),
|
||||
}).nullable(),
|
||||
weight_per_convertion: Yup.number().nullable().optional().notRequired(),
|
||||
marketing_type: Yup.object({
|
||||
value: Yup.string().required('Kategori Penjualan wajib diisi!'),
|
||||
label: Yup.string().required('Kategori Penjualan wajib diisi!'),
|
||||
}).nullable(),
|
||||
price_per_convertion: Yup.number().nullable().optional().notRequired(),
|
||||
total_peti: Yup.number().nullable().optional().notRequired(),
|
||||
sisa_berat: Yup.number().nullable().optional().notRequired(),
|
||||
price_sisa_berat: Yup.number().nullable().optional().notRequired(),
|
||||
weeks: Yup.object({
|
||||
value: Yup.number().required('Minggu wajib diisi!'),
|
||||
label: Yup.string().required('Minggu wajib diisi!'),
|
||||
}).nullable(),
|
||||
});
|
||||
|
||||
export type SalesOrderProductFormValues = Yup.InferType<
|
||||
|
||||
+465
-162
@@ -14,12 +14,22 @@ import { ProductWarehouseApi } from '@/services/api/inventory';
|
||||
import NumberInput from '@/components/input/NumberInput';
|
||||
import Button from '@/components/Button';
|
||||
import { isResponseSuccess } from '@/lib/api-helper';
|
||||
import { formatNumber, formatVechicleNumber } from '@/lib/helper';
|
||||
import {
|
||||
formatNumber,
|
||||
formatTitleCase,
|
||||
formatVechicleNumber,
|
||||
} from '@/lib/helper';
|
||||
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 SelectInputRadio from '@/components/input/SelectInputRadio';
|
||||
import {
|
||||
MARKETING_CONVERTION_UNIT_OPTIONS,
|
||||
MARKETING_TYPE_OPTIONS,
|
||||
} from '@/config/constant';
|
||||
import { Icon } from '@iconify/react';
|
||||
import Dropdown from '@/components/Dropdown';
|
||||
|
||||
const roundWeight = (value: number) => Number(value.toFixed(2));
|
||||
const roundPrice = (value: number) => Math.round(value);
|
||||
@@ -41,6 +51,7 @@ const SalesOrderProductForm = ({
|
||||
const [currentInput, setCurrentInput] = useState<string>('');
|
||||
const [selectedProductWarehouse, setSelectedProductWarehouse] =
|
||||
useState<ProductWarehouse | null>(null);
|
||||
const [hasSisaBerat, setHasSisaBerat] = useState<boolean>(false);
|
||||
|
||||
// ============ Formik ============
|
||||
const formik = useFormik<SalesOrderProductFormValues>({
|
||||
@@ -57,6 +68,13 @@ const SalesOrderProductForm = ({
|
||||
avg_weight: initialValues?.avg_weight || '',
|
||||
total_price: initialValues?.total_price || '',
|
||||
uom: initialValues?.uom || '',
|
||||
weight_per_convertion:
|
||||
initialValues?.weight_per_convertion != null
|
||||
? Number(initialValues.weight_per_convertion)
|
||||
: null,
|
||||
convertion_unit: initialValues?.convertion_unit || null,
|
||||
marketing_type: initialValues?.marketing_type || null,
|
||||
total_peti: initialValues?.total_peti ?? null,
|
||||
},
|
||||
validationSchema: SalesOrderProductSchema,
|
||||
onSubmit: async (values) => {
|
||||
@@ -76,6 +94,14 @@ const SalesOrderProductForm = ({
|
||||
loadMore: loadMoreKandang,
|
||||
} = useSelect<Kandang>(WarehouseApi.basePath, 'id', 'name');
|
||||
|
||||
// Options Weeks dari minggu 1 - 22
|
||||
const optionsWeeks = useMemo(() => {
|
||||
return Array.from({ length: 22 }, (_, i) => ({
|
||||
value: i + 1,
|
||||
label: `Weeks ${i + 1}`,
|
||||
}));
|
||||
}, []);
|
||||
|
||||
const {
|
||||
options: warehouseSourceOptions,
|
||||
rawData: warehouseSourceRawData,
|
||||
@@ -89,6 +115,7 @@ const SalesOrderProductForm = ({
|
||||
'',
|
||||
{
|
||||
warehouse_id: formik.values.kandang_id?.toString() ?? '',
|
||||
type: formik.values.marketing_type?.value.toLocaleUpperCase() ?? '',
|
||||
}
|
||||
);
|
||||
|
||||
@@ -279,174 +306,450 @@ const SalesOrderProductForm = ({
|
||||
onSubmit={handleFormSubmit}
|
||||
onReset={handleResetForm}
|
||||
>
|
||||
{formErrorMessage && (
|
||||
<div onClick={() => setFormErrorMessage('')} className='my-3 w-full'>
|
||||
<Alert color='error'>
|
||||
{formErrorMessage ? formErrorMessage : ''}
|
||||
</Alert>
|
||||
</div>
|
||||
)}
|
||||
<PatternInput
|
||||
name='vehicle_number'
|
||||
label='No. Polisi'
|
||||
format='AA #### AAA'
|
||||
mask='_'
|
||||
inputVehicleNumber
|
||||
required
|
||||
type='text'
|
||||
placeholder='B 1234 CDE'
|
||||
value={formatVechicleNumber(formik.values.vehicle_number ?? '')}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
isError={
|
||||
formik.touched.vehicle_number &&
|
||||
Boolean(formik.errors.vehicle_number)
|
||||
}
|
||||
errorMessage={formik.errors.vehicle_number}
|
||||
/>
|
||||
<SelectInputRadio
|
||||
required
|
||||
label='Kandang'
|
||||
options={kandangSourceOptions}
|
||||
isLoading={isLoadingKandangSourceOptions}
|
||||
value={formik.values.kandang}
|
||||
onChange={kandangChangeHandler}
|
||||
isClearable
|
||||
onInputChange={setKandangInputValue}
|
||||
onMenuScrollToBottom={loadMoreKandang}
|
||||
isError={
|
||||
formik.touched.kandang_id && Boolean(formik.errors.kandang_id)
|
||||
}
|
||||
errorMessage={formik.errors.kandang_id}
|
||||
placeholder='Pilih Kandang'
|
||||
/>
|
||||
<SelectInputRadio
|
||||
required
|
||||
label='Produk'
|
||||
options={productOptionsFiltered}
|
||||
isLoading={isLoadingWarehouseSourceOptions}
|
||||
value={formik.values.product_warehouse}
|
||||
onChange={warehouseChangeHandler}
|
||||
onInputChange={setWarehouseInputValue}
|
||||
onMenuScrollToBottom={loadMoreWarehouse}
|
||||
isClearable
|
||||
placeholder={
|
||||
formik.values.kandang_id
|
||||
? productOptionsFiltered.length == 0
|
||||
? 'Tidak ada produk yang tersedia'
|
||||
: 'Pilih produk'
|
||||
: 'Pilih Kandang Terlebih Dahulu'
|
||||
}
|
||||
isDisabled={!formik.values.kandang_id}
|
||||
isError={
|
||||
formik.touched.product_warehouse_id &&
|
||||
Boolean(formik.errors.product_warehouse_id)
|
||||
}
|
||||
errorMessage={formik.errors.product_warehouse_id}
|
||||
/>
|
||||
<NumberInput
|
||||
required
|
||||
label='Kuantitas'
|
||||
name='qty'
|
||||
value={formik.values.qty}
|
||||
onChange={(e) => {
|
||||
formik.handleChange(e);
|
||||
setCurrentInput(e.target.name);
|
||||
}}
|
||||
onBlur={() => handleBlurField('qty')}
|
||||
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'>
|
||||
{selectedProductWarehouse?.product?.uom?.name}
|
||||
<div className='flex flex-col gap-1.5 p-4 border-b border-base-content/10'>
|
||||
{formErrorMessage && (
|
||||
<div
|
||||
onClick={() => setFormErrorMessage('')}
|
||||
className='my-3 w-full'
|
||||
>
|
||||
<Alert color='error'>
|
||||
{formErrorMessage ? formErrorMessage : ''}
|
||||
</Alert>
|
||||
</div>
|
||||
)}
|
||||
{/* Nomor Polisi */}
|
||||
<PatternInput
|
||||
name='vehicle_number'
|
||||
label='No. Polisi'
|
||||
format='AA #### AAA'
|
||||
mask='_'
|
||||
inputVehicleNumber
|
||||
required
|
||||
type='text'
|
||||
placeholder='B 1234 CDE'
|
||||
value={formatVechicleNumber(formik.values.vehicle_number ?? '')}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
isError={
|
||||
formik.touched.vehicle_number &&
|
||||
Boolean(formik.errors.vehicle_number)
|
||||
}
|
||||
errorMessage={formik.errors.vehicle_number}
|
||||
/>
|
||||
|
||||
{/* Gudang */}
|
||||
<SelectInputRadio
|
||||
required
|
||||
label='Gudang'
|
||||
options={kandangSourceOptions}
|
||||
isLoading={isLoadingKandangSourceOptions}
|
||||
value={formik.values.kandang}
|
||||
onChange={kandangChangeHandler}
|
||||
isClearable
|
||||
onInputChange={setKandangInputValue}
|
||||
onMenuScrollToBottom={loadMoreKandang}
|
||||
isError={
|
||||
formik.touched.kandang_id && Boolean(formik.errors.kandang_id)
|
||||
}
|
||||
errorMessage={formik.errors.kandang_id}
|
||||
placeholder='Pilih Gudang'
|
||||
/>
|
||||
|
||||
{/* Kategori */}
|
||||
<SelectInputRadio
|
||||
required
|
||||
label='Kategori '
|
||||
options={MARKETING_TYPE_OPTIONS}
|
||||
value={formik.values.marketing_type}
|
||||
onChange={(val) => {
|
||||
formik.setFieldValue('marketing_type', val);
|
||||
warehouseChangeHandler(null);
|
||||
formik.setFieldValue('product_warehouse', null);
|
||||
formik.setFieldValue('product_warehouse_id', null);
|
||||
formik.setFieldValue('convertion_unit', null);
|
||||
formik.setFieldValue('weight_per_convertion', null);
|
||||
formik.setFieldValue('total_peti', null);
|
||||
}}
|
||||
isClearable
|
||||
placeholder='Pilih Kategori'
|
||||
/>
|
||||
|
||||
{/* Produk */}
|
||||
<SelectInputRadio
|
||||
required
|
||||
label='Produk'
|
||||
options={productOptionsFiltered}
|
||||
isLoading={isLoadingWarehouseSourceOptions}
|
||||
value={formik.values.product_warehouse}
|
||||
onChange={warehouseChangeHandler}
|
||||
onInputChange={setWarehouseInputValue}
|
||||
onMenuScrollToBottom={loadMoreWarehouse}
|
||||
isClearable
|
||||
placeholder={
|
||||
formik.values.kandang_id
|
||||
? productOptionsFiltered.length == 0
|
||||
? 'Tidak ada produk yang tersedia'
|
||||
: 'Pilih produk'
|
||||
: 'Pilih Kandang Terlebih Dahulu'
|
||||
}
|
||||
isDisabled={!formik.values.kandang_id}
|
||||
isError={
|
||||
formik.touched.product_warehouse_id &&
|
||||
Boolean(formik.errors.product_warehouse_id)
|
||||
}
|
||||
errorMessage={formik.errors.product_warehouse_id}
|
||||
/>
|
||||
|
||||
{/* Konversi Satuan Telur */}
|
||||
{formik.values.marketing_type &&
|
||||
formik.values.marketing_type.value.toLowerCase() === 'telur' &&
|
||||
(!formik.values.convertion_unit ||
|
||||
formik.values.convertion_unit.value.toLowerCase() !== 'peti') && (
|
||||
<SelectInputRadio
|
||||
required
|
||||
label='Tipe Konversi'
|
||||
options={MARKETING_CONVERTION_UNIT_OPTIONS}
|
||||
value={formik.values.convertion_unit}
|
||||
onChange={(val) => formik.setFieldValue('convertion_unit', val)}
|
||||
isClearable
|
||||
placeholder='Pilih Konversi Satuan'
|
||||
/>
|
||||
)}
|
||||
{formik.values.convertion_unit &&
|
||||
formik.values.convertion_unit.value === 'peti' && (
|
||||
<div className='flex flex-col'>
|
||||
<label className='font-semibold text-xs py-2 leading-5'>
|
||||
Tipe Konversi <span className='text-error'>*</span>
|
||||
</label>
|
||||
<div className='flex items-center gap-2 border border-base-content/10 rounded-lg pe-3 text-sm text-base-content'>
|
||||
<div>
|
||||
<Dropdown
|
||||
align='start'
|
||||
direction='bottom'
|
||||
trigger={
|
||||
<div className='flex flex-row items-stretch gap-2 py-1 ps-3 text-sm'>
|
||||
<div className='py-1.5 flex items-center gap-2'>
|
||||
{formatTitleCase(
|
||||
formik.values.convertion_unit.value
|
||||
)}
|
||||
<Icon
|
||||
icon='heroicons:chevron-down-solid'
|
||||
className='my-auto'
|
||||
/>
|
||||
</div>
|
||||
<div className='w-px border-none bg-base-content/10'></div>
|
||||
</div>
|
||||
}
|
||||
className={{
|
||||
wrapper: 'relative',
|
||||
content:
|
||||
'rounded-xl mt-1 border border-base-content/5 shadow-sm overflow-hidden min-w-68.5 sm:min-w-103.25 w-full',
|
||||
}}
|
||||
>
|
||||
<ul className='rounded-lg w-full'>
|
||||
{MARKETING_CONVERTION_UNIT_OPTIONS.map((option) => (
|
||||
<li className='w-full' key={option.value}>
|
||||
<Button
|
||||
variant='ghost'
|
||||
color='none'
|
||||
className='w-full p-3 gap-3 font-medium justify-start text-sm text-base-content/50'
|
||||
onClick={() =>
|
||||
formik.setFieldValue('convertion_unit', option)
|
||||
}
|
||||
>
|
||||
<input
|
||||
type='radio'
|
||||
checked={
|
||||
formik.values.convertion_unit?.value ===
|
||||
option.value
|
||||
}
|
||||
onChange={() => null}
|
||||
className='radio radio-md radio-primary pointer-events-none'
|
||||
/>{' '}
|
||||
{option.label}
|
||||
</Button>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</Dropdown>
|
||||
</div>
|
||||
<input
|
||||
type='number'
|
||||
className='w-full h-full focus:outline-none appearance-none [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none'
|
||||
placeholder={`Berat ${
|
||||
formik.values.convertion_unit?.value === 'peti'
|
||||
? 'kg'
|
||||
: ''
|
||||
} per ${formik.values.convertion_unit?.value}`}
|
||||
value={formik.values.weight_per_convertion ?? ''}
|
||||
onChange={(e) => {
|
||||
formik.setFieldValue(
|
||||
'weight_per_convertion',
|
||||
Number(e.target.value)
|
||||
);
|
||||
setCurrentInput(e.target.name);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Konversi Satuan Weeks Pullet */}
|
||||
{formik.values.marketing_type?.value.toLowerCase() ===
|
||||
'ayam_pullet' && (
|
||||
<SelectInputRadio
|
||||
required
|
||||
label='Minggu'
|
||||
options={optionsWeeks}
|
||||
value={formik.values.weeks}
|
||||
onChange={(val) => {
|
||||
formik.setFieldValue('weeks', val);
|
||||
}}
|
||||
placeholder='Pilih Weeks'
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Total Peti */}
|
||||
{formik.values.convertion_unit?.value === 'peti' && (
|
||||
<NumberInput
|
||||
required
|
||||
label='Total Peti'
|
||||
name='total_pet'
|
||||
value={formik.values.total_peti ?? undefined}
|
||||
onChange={(e) => {
|
||||
formik.handleChange(e);
|
||||
setCurrentInput(e.target.name);
|
||||
}}
|
||||
onBlur={() => handleBlurField('total_peti')}
|
||||
isError={
|
||||
formik.touched.total_peti && Boolean(formik.errors.total_peti)
|
||||
}
|
||||
errorMessage={formik.errors.total_peti}
|
||||
placeholder='Masukan Total Peti'
|
||||
endAdornment={
|
||||
<div className='flex items-center gap-2'>
|
||||
<span className='text-sm text-base-content/50'>Kg</span>
|
||||
</div>
|
||||
}
|
||||
bottomLabel={`1 ${formik.values.convertion_unit?.value} = ${formik.values.weight_per_convertion ?? 0} Kg`}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Avg. Bobot */}
|
||||
{formik.values.marketing_type?.value.toLowerCase() === 'trading' ||
|
||||
(formik.values.convertion_unit?.value.toLowerCase() !== 'peti' &&
|
||||
formik.values.convertion_unit?.value.toLowerCase() !== 'kg' && (
|
||||
<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'
|
||||
/>
|
||||
))}
|
||||
|
||||
{/* Total Bobot */}
|
||||
{formik.values.marketing_type?.value.toLowerCase() !== 'trading' && (
|
||||
<NumberInput
|
||||
required
|
||||
label='Total Bobot (Kg)'
|
||||
name='total_weight'
|
||||
value={formik.values.total_weight}
|
||||
onChange={(e) => {
|
||||
formik.handleChange(e);
|
||||
setCurrentInput(e.target.name);
|
||||
}}
|
||||
onBlur={() => handleBlurField('total_weight')}
|
||||
isError={
|
||||
formik.touched.total_weight &&
|
||||
Boolean(formik.errors.total_weight)
|
||||
}
|
||||
errorMessage={formik.errors.total_weight}
|
||||
placeholder='Masukan Total Bobot'
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Kuantitas */}
|
||||
<NumberInput
|
||||
required
|
||||
label={
|
||||
formik.values.marketing_type &&
|
||||
formik.values.marketing_type.value.toLowerCase() === 'telur'
|
||||
? `Total Butir Telur`
|
||||
: `Total Kuantitas`
|
||||
}
|
||||
name='qty'
|
||||
value={formik.values.qty}
|
||||
onChange={(e) => {
|
||||
formik.handleChange(e);
|
||||
setCurrentInput(e.target.name);
|
||||
}}
|
||||
onBlur={() => handleBlurField('qty')}
|
||||
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-base-content/50'>
|
||||
{selectedProductWarehouse?.product?.uom?.name}
|
||||
</span>
|
||||
</div>
|
||||
}
|
||||
bottomLabel={
|
||||
isResponseSuccess(warehouseSourceRawData) &&
|
||||
formik.values.product_warehouse_id
|
||||
? `Stok tersedia: ${formatNumber(
|
||||
warehouseSourceRawData?.data?.find(
|
||||
(item) => item.id === formik.values.product_warehouse_id
|
||||
)?.quantity ?? 0
|
||||
)} ${selectedProductWarehouse?.product?.uom?.name}`
|
||||
: ''
|
||||
}
|
||||
/>
|
||||
|
||||
{/* Harga per convertion unit */}
|
||||
{(formik.values.convertion_unit?.value.toLowerCase() === 'peti' ||
|
||||
formik.values.convertion_unit?.value.toLowerCase() === 'kg') && (
|
||||
<NumberInput
|
||||
required
|
||||
label={`Harga / ${formik.values.convertion_unit?.label ?? 'Produk'} (Rp)`}
|
||||
name='price_per_convertion'
|
||||
value={formik.values.price_per_convertion ?? undefined}
|
||||
onChange={(e) => {
|
||||
formik.handleChange(e);
|
||||
setCurrentInput(e.target.name);
|
||||
}}
|
||||
onBlur={() => handleBlurField('price_per_convertion')}
|
||||
isError={
|
||||
formik.touched.price_per_convertion &&
|
||||
Boolean(formik.errors.price_per_convertion)
|
||||
}
|
||||
errorMessage={formik.errors.price_per_convertion}
|
||||
placeholder='Masukan Harga Satuan'
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Harga Satuan per Uom Produk Warehouse */}
|
||||
{formik.values.convertion_unit?.value.toLowerCase() !== 'peti' &&
|
||||
formik.values.convertion_unit?.value.toLowerCase() !== 'kg' && (
|
||||
<NumberInput
|
||||
required
|
||||
label={`Harga / ${selectedProductWarehouse?.product?.uom?.name ?? 'Produk'} (Rp)`}
|
||||
name='unit_price'
|
||||
value={formik.values.unit_price}
|
||||
onChange={(e) => {
|
||||
formik.handleChange(e);
|
||||
setCurrentInput(e.target.name);
|
||||
}}
|
||||
onBlur={() => handleBlurField('unit_price')}
|
||||
isError={
|
||||
formik.touched.unit_price && Boolean(formik.errors.unit_price)
|
||||
}
|
||||
errorMessage={formik.errors.unit_price}
|
||||
placeholder='Masukan Harga Satuan'
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Sisa kg diluar peti */}
|
||||
{formik.values.convertion_unit?.value.toLowerCase() === 'peti' && (
|
||||
<div className='flex flex-col'>
|
||||
<div className='py-2 gap-3 flex items-center'>
|
||||
<input
|
||||
type='checkbox'
|
||||
name='sisa_berat'
|
||||
checked={hasSisaBerat}
|
||||
onChange={() => {
|
||||
setHasSisaBerat(!hasSisaBerat);
|
||||
}}
|
||||
onBlur={() => handleBlurField('sisa_berat')}
|
||||
className='toggle toggle-primary rounded-full before:rounded-full before:bg-base-content/50 border-base-content/50 checked:border-primary checked:bg-primary checked:before:bg-base-100'
|
||||
/>
|
||||
<label className='text-sm text-base-content/50'>
|
||||
Apakah ada sisa berat di luar peti?
|
||||
</label>
|
||||
</div>
|
||||
<span className='text-xs text-base-content/30 leading-4 pt-1.5'>
|
||||
Jika ada, masukan berat di luar peti
|
||||
</span>
|
||||
</div>
|
||||
}
|
||||
bottomLabel={
|
||||
isResponseSuccess(warehouseSourceRawData) &&
|
||||
formik.values.product_warehouse_id
|
||||
? `Stok tersedia: ${formatNumber(
|
||||
warehouseSourceRawData?.data?.find(
|
||||
(item) => item.id === formik.values.product_warehouse_id
|
||||
)?.quantity ?? 0
|
||||
)} ${selectedProductWarehouse?.product?.uom?.name}`
|
||||
: ''
|
||||
}
|
||||
/>
|
||||
<NumberInput
|
||||
required
|
||||
label={`Harga / ${selectedProductWarehouse?.product?.uom?.name ?? 'Produk'} (Rp)`}
|
||||
name='unit_price'
|
||||
value={formik.values.unit_price}
|
||||
onChange={(e) => {
|
||||
formik.handleChange(e);
|
||||
setCurrentInput(e.target.name);
|
||||
}}
|
||||
onBlur={() => handleBlurField('unit_price')}
|
||||
isError={
|
||||
formik.touched.unit_price && Boolean(formik.errors.unit_price)
|
||||
}
|
||||
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)'
|
||||
name='total_weight'
|
||||
value={formik.values.total_weight}
|
||||
onChange={(e) => {
|
||||
formik.handleChange(e);
|
||||
setCurrentInput(e.target.name);
|
||||
}}
|
||||
onBlur={() => handleBlurField('total_weight')}
|
||||
isError={
|
||||
formik.touched.total_weight && Boolean(formik.errors.total_weight)
|
||||
}
|
||||
errorMessage={formik.errors.total_weight}
|
||||
placeholder='Masukan Total Bobot'
|
||||
/>
|
||||
<NumberInput
|
||||
required
|
||||
label='Total Penjualan (Rp)'
|
||||
name='total_price'
|
||||
value={formik.values.total_price}
|
||||
onChange={(e) => {
|
||||
formik.handleChange(e);
|
||||
setCurrentInput(e.target.name);
|
||||
}}
|
||||
onBlur={() => handleBlurField('total_price')}
|
||||
isError={
|
||||
formik.touched.total_price && Boolean(formik.errors.total_price)
|
||||
}
|
||||
errorMessage={formik.errors.total_price}
|
||||
placeholder='Masukan Total Penjualan'
|
||||
/>
|
||||
)}
|
||||
|
||||
<div className='mt-4'>
|
||||
<AlertErrorList formErrorList={formErrorList} onClose={close} />
|
||||
{hasSisaBerat && (
|
||||
<>
|
||||
<NumberInput
|
||||
required
|
||||
label='Sisa Berat (Kg)'
|
||||
name='sisa_berat'
|
||||
value={formik.values.sisa_berat ?? undefined}
|
||||
onChange={(e) => {
|
||||
formik.handleChange(e);
|
||||
setCurrentInput(e.target.name);
|
||||
}}
|
||||
onBlur={() => handleBlurField('sisa_berat')}
|
||||
isError={
|
||||
formik.touched.sisa_berat && Boolean(formik.errors.sisa_berat)
|
||||
}
|
||||
errorMessage={formik.errors.sisa_berat}
|
||||
placeholder='Masukan Sisa Berat'
|
||||
/>
|
||||
<NumberInput
|
||||
required
|
||||
label='Harga Sisa Berat (Rp)'
|
||||
name='price_sisa_berat'
|
||||
value={formik.values.price_sisa_berat ?? undefined}
|
||||
onChange={(e) => {
|
||||
formik.handleChange(e);
|
||||
setCurrentInput(e.target.name);
|
||||
}}
|
||||
onBlur={() => handleBlurField('price_sisa_berat')}
|
||||
isError={
|
||||
formik.touched.price_sisa_berat &&
|
||||
Boolean(formik.errors.price_sisa_berat)
|
||||
}
|
||||
errorMessage={formik.errors.price_sisa_berat}
|
||||
placeholder='Masukan Harga Sisa Berat'
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* Total Penjualan */}
|
||||
<NumberInput
|
||||
required
|
||||
label='Total Penjualan (Rp)'
|
||||
name='total_price'
|
||||
value={formik.values.total_price}
|
||||
onChange={(e) => {
|
||||
formik.handleChange(e);
|
||||
setCurrentInput(e.target.name);
|
||||
}}
|
||||
onBlur={() => handleBlurField('total_price')}
|
||||
isError={
|
||||
formik.touched.total_price && Boolean(formik.errors.total_price)
|
||||
}
|
||||
errorMessage={formik.errors.total_price}
|
||||
placeholder='Masukan Total Penjualan'
|
||||
/>
|
||||
|
||||
{formErrorList.length > 0 && (
|
||||
<div className='mt-4'>
|
||||
<AlertErrorList formErrorList={formErrorList} onClose={close} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className='h-18' />
|
||||
|
||||
<div className='absolute w-full bottom-0 right-0'>
|
||||
<div className='absolute w-full bottom-0 right-0 p-4'>
|
||||
<Button
|
||||
type='submit'
|
||||
isLoading={formik.isSubmitting}
|
||||
|
||||
+24
-5
@@ -495,16 +495,35 @@ export const FILTER_TYPE_OPTIONS = [
|
||||
|
||||
export const MARKETING_TYPE_OPTIONS = [
|
||||
{
|
||||
label: 'Ayam',
|
||||
value: 'ayam',
|
||||
label: 'Ayam Pullet',
|
||||
value: 'AYAM_PULLET',
|
||||
},
|
||||
{
|
||||
label: 'Telur',
|
||||
value: 'telur',
|
||||
label: 'Ayam',
|
||||
value: 'AYAM',
|
||||
},
|
||||
{
|
||||
label: 'Trading',
|
||||
value: 'trading',
|
||||
value: 'TRADING',
|
||||
},
|
||||
{
|
||||
label: 'Telur',
|
||||
value: 'TELUR',
|
||||
},
|
||||
];
|
||||
|
||||
export const MARKETING_CONVERTION_UNIT_OPTIONS = [
|
||||
{
|
||||
label: 'Kg',
|
||||
value: 'kg',
|
||||
},
|
||||
{
|
||||
label: 'Qty',
|
||||
value: 'qty',
|
||||
},
|
||||
{
|
||||
label: 'Peti',
|
||||
value: 'peti',
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
+1
@@ -110,6 +110,7 @@ export type BaseCreateMarketingProductPayload = {
|
||||
qty: string | number | undefined;
|
||||
avg_weight: string | number | undefined;
|
||||
total_price: string | number | undefined;
|
||||
marketing_type: string;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user