mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 05:22:02 +00:00
fix: adjust stock, depletion, and egg select input
This commit is contained in:
@@ -5,6 +5,7 @@ import {
|
||||
CreateLayingRecordingPayload,
|
||||
CreateEggPayload,
|
||||
} from '@/types/api/production/recording';
|
||||
import { getProductWarehouseOptionLabel } from '@/lib/product-warehouse';
|
||||
|
||||
type RecordingGrowingFormSchemaType = {
|
||||
record_date: string;
|
||||
@@ -29,11 +30,19 @@ type RecordingGrowingFormSchemaType = {
|
||||
} | null;
|
||||
project_flock_kandang_id: number;
|
||||
stocks: {
|
||||
product_warehouse_id: number;
|
||||
product_warehouse_id:
|
||||
| {
|
||||
value: number;
|
||||
label: string;
|
||||
}
|
||||
| undefined;
|
||||
qty: number | string;
|
||||
}[];
|
||||
depletions: {
|
||||
product_warehouse_id?: number;
|
||||
product_warehouse_id?: {
|
||||
value: number;
|
||||
label: string;
|
||||
};
|
||||
source_product_warehouse_id?: number;
|
||||
qty?: number | string;
|
||||
}[];
|
||||
@@ -41,34 +50,48 @@ type RecordingGrowingFormSchemaType = {
|
||||
|
||||
type RecordingLayingFormSchemaType = RecordingGrowingFormSchemaType & {
|
||||
eggs: {
|
||||
product_warehouse_id?: number;
|
||||
product_warehouse_id?: {
|
||||
value: number;
|
||||
label: string;
|
||||
};
|
||||
qty?: number | string;
|
||||
weight?: number | string;
|
||||
}[];
|
||||
};
|
||||
|
||||
export type StockSchema = {
|
||||
product_warehouse_id: number;
|
||||
product_warehouse_id: {
|
||||
value: number;
|
||||
label: string;
|
||||
};
|
||||
qty: number | string;
|
||||
};
|
||||
|
||||
export type DepletionSchema = {
|
||||
product_warehouse_id?: number;
|
||||
product_warehouse_id?: {
|
||||
value: number;
|
||||
label: string;
|
||||
};
|
||||
source_product_warehouse_id?: number;
|
||||
qty?: number | string;
|
||||
};
|
||||
|
||||
export type EggSchema = {
|
||||
product_warehouse_id?: number;
|
||||
product_warehouse_id?: {
|
||||
value: number;
|
||||
label: string;
|
||||
};
|
||||
qty?: number | string;
|
||||
weight?: number | string;
|
||||
};
|
||||
|
||||
const StockObjectSchema: Yup.ObjectSchema<StockSchema> = Yup.object({
|
||||
product_warehouse_id: Yup.number()
|
||||
product_warehouse_id: Yup.object({
|
||||
value: Yup.number().min(1).required(),
|
||||
label: Yup.string().required(),
|
||||
})
|
||||
.required('Produk wajib diisi!')
|
||||
.min(1, 'Produk wajib diisi!')
|
||||
.typeError('Produk harus berupa angka!'),
|
||||
.typeError('Produk wajib diisi!'),
|
||||
qty: Yup.number()
|
||||
.required('Jumlah penggunaan wajib diisi!')
|
||||
.moreThan(0, 'Jumlah penggunaan harus lebih dari 0!')
|
||||
@@ -76,7 +99,10 @@ const StockObjectSchema: Yup.ObjectSchema<StockSchema> = Yup.object({
|
||||
});
|
||||
|
||||
const DepletionObjectSchema: Yup.ObjectSchema<DepletionSchema> = Yup.object({
|
||||
product_warehouse_id: Yup.number()
|
||||
product_warehouse_id: Yup.object({
|
||||
value: Yup.number().min(1).required(),
|
||||
label: Yup.string().required(),
|
||||
})
|
||||
.optional()
|
||||
.typeError('Depletions harus berupa angka!'),
|
||||
source_product_warehouse_id: Yup.number()
|
||||
@@ -88,7 +114,10 @@ const DepletionObjectSchema: Yup.ObjectSchema<DepletionSchema> = Yup.object({
|
||||
});
|
||||
|
||||
const EggObjectSchema: Yup.ObjectSchema<EggSchema> = Yup.object({
|
||||
product_warehouse_id: Yup.number()
|
||||
product_warehouse_id: Yup.object({
|
||||
value: Yup.number().min(1).required(),
|
||||
label: Yup.string().required(),
|
||||
})
|
||||
.optional()
|
||||
.typeError('Kondisi telur harus berupa angka!'),
|
||||
qty: Yup.number().optional().typeError('Jumlah telur harus berupa angka!'),
|
||||
@@ -248,14 +277,17 @@ export const getRecordingGrowingFormInitialValues = (
|
||||
initialValues?.project_flock?.project_flock_kandang_id ??
|
||||
0,
|
||||
stocks: initialValues?.stocks?.map((stock) => ({
|
||||
product_warehouse_id: stock.product_warehouse_id,
|
||||
product_warehouse_id: {
|
||||
value: stock.product_warehouse_id,
|
||||
label: getProductWarehouseOptionLabel(stock.product_warehouse),
|
||||
},
|
||||
qty:
|
||||
(stock as { qty?: number; usage_amount?: number }).qty ||
|
||||
(stock as { qty?: number; usage_amount?: number }).usage_amount ||
|
||||
'',
|
||||
})) ?? [
|
||||
{
|
||||
product_warehouse_id: 0,
|
||||
product_warehouse_id: undefined,
|
||||
qty: '',
|
||||
},
|
||||
],
|
||||
@@ -263,13 +295,16 @@ export const getRecordingGrowingFormInitialValues = (
|
||||
(
|
||||
depletion: NonNullable<CreateGrowingRecordingPayload['depletions']>[0]
|
||||
) => ({
|
||||
product_warehouse_id: depletion.product_warehouse_id,
|
||||
product_warehouse_id: {
|
||||
value: Number(depletion.product_warehouse_id ?? 0),
|
||||
label: getProductWarehouseOptionLabel(depletion.product_warehouse),
|
||||
},
|
||||
source_product_warehouse_id: depletion.source_product_warehouse_id,
|
||||
qty: depletion.qty,
|
||||
})
|
||||
) ?? [
|
||||
{
|
||||
product_warehouse_id: 0,
|
||||
product_warehouse_id: undefined,
|
||||
qty: '',
|
||||
},
|
||||
],
|
||||
@@ -281,12 +316,15 @@ export const getRecordingLayingFormInitialValues = (
|
||||
...getRecordingGrowingFormInitialValues(initialValues),
|
||||
|
||||
eggs: initialValues?.eggs?.map((egg: CreateEggPayload) => ({
|
||||
product_warehouse_id: egg.product_warehouse_id,
|
||||
product_warehouse_id: {
|
||||
value: Number(egg.product_warehouse_id ?? 0),
|
||||
label: getProductWarehouseOptionLabel(egg.product_warehouse),
|
||||
},
|
||||
qty: egg.qty,
|
||||
weight: egg.weight,
|
||||
})) ?? [
|
||||
{
|
||||
product_warehouse_id: 0,
|
||||
product_warehouse_id: undefined,
|
||||
qty: '',
|
||||
weight: '',
|
||||
},
|
||||
|
||||
@@ -522,7 +522,7 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
||||
? values.depletions
|
||||
?.filter((d) => d.product_warehouse_id && d.qty)
|
||||
.map((depletion) => ({
|
||||
product_warehouse_id: depletion.product_warehouse_id!,
|
||||
product_warehouse_id: depletion.product_warehouse_id?.value ?? 0,
|
||||
...(depletion.source_product_warehouse_id && {
|
||||
source_product_warehouse_id:
|
||||
depletion.source_product_warehouse_id,
|
||||
@@ -533,13 +533,13 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
||||
|
||||
const stocks = recordingRestriction.canEditStock
|
||||
? (values.stocks ?? [])
|
||||
.filter((s) => s.product_warehouse_id && s.qty)
|
||||
.filter((s) => s.product_warehouse_id?.value && s.qty)
|
||||
.map((stock) => ({
|
||||
// In migration mode, product_warehouse_id field holds product.id;
|
||||
// send it as product_id so the backend auto-creates the warehouse entry.
|
||||
...(isMigrationMode
|
||||
? { product_id: stock.product_warehouse_id }
|
||||
: { product_warehouse_id: stock.product_warehouse_id }),
|
||||
? { product_id: stock.product_warehouse_id?.value }
|
||||
: { product_warehouse_id: stock.product_warehouse_id?.value }),
|
||||
qty: Number(stock.qty) || 0,
|
||||
}))
|
||||
: [];
|
||||
@@ -561,9 +561,9 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
||||
const createLayingPayload = useCallback(
|
||||
(values: RecordingLayingFormValues) => {
|
||||
const depletions = values.depletions
|
||||
?.filter((d) => d.product_warehouse_id && d.qty)
|
||||
?.filter((d) => d.product_warehouse_id?.value && d.qty)
|
||||
.map((depletion) => ({
|
||||
product_warehouse_id: depletion.product_warehouse_id!,
|
||||
product_warehouse_id: depletion.product_warehouse_id?.value ?? 0,
|
||||
...(depletion.source_product_warehouse_id && {
|
||||
source_product_warehouse_id: depletion.source_product_warehouse_id,
|
||||
}),
|
||||
@@ -573,7 +573,7 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
||||
const eggs = values.eggs
|
||||
?.filter((e) => e.product_warehouse_id && e.qty && e.weight)
|
||||
.map((egg) => ({
|
||||
product_warehouse_id: egg.product_warehouse_id!,
|
||||
product_warehouse_id: egg.product_warehouse_id?.value ?? 0,
|
||||
qty: Number(egg.qty) || 0,
|
||||
weight:
|
||||
typeof egg.weight === 'number'
|
||||
@@ -583,11 +583,11 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
||||
|
||||
const stocks = recordingRestriction.canEditStock
|
||||
? values.stocks
|
||||
.filter((s) => s.product_warehouse_id && s.qty)
|
||||
.filter((s) => s.product_warehouse_id?.value && s.qty)
|
||||
.map((stock) => ({
|
||||
...(isMigrationMode
|
||||
? { product_id: stock.product_warehouse_id }
|
||||
: { product_warehouse_id: stock.product_warehouse_id }),
|
||||
? { product_id: stock.product_warehouse_id?.value }
|
||||
: { product_warehouse_id: stock.product_warehouse_id?.value }),
|
||||
qty: Number(stock.qty) || 0,
|
||||
}))
|
||||
: [];
|
||||
@@ -1283,8 +1283,12 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
||||
// product_warehouse object returned by the API.
|
||||
if (isMigrationMode && type === 'edit' && initialValues?.stocks?.length) {
|
||||
baseValues.stocks = initialValues.stocks.map((stock) => ({
|
||||
product_warehouse_id:
|
||||
stock.product_warehouse?.product_id ?? stock.product_warehouse_id,
|
||||
product_warehouse_id: {
|
||||
value: Number(
|
||||
stock.product_warehouse?.product_id ?? stock.product_warehouse_id
|
||||
),
|
||||
label: getProductWarehouseOptionLabel(stock.product_warehouse),
|
||||
},
|
||||
qty: stock.usage_amount ?? '',
|
||||
}));
|
||||
}
|
||||
@@ -1438,8 +1442,12 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
||||
formik.setFieldValue(
|
||||
'stocks',
|
||||
initialValues.stocks.map((stock) => ({
|
||||
product_warehouse_id:
|
||||
stock.product_warehouse?.product_id ?? stock.product_warehouse_id,
|
||||
product_warehouse_id: {
|
||||
value: Number(
|
||||
stock.product_warehouse?.product_id ?? stock.product_warehouse_id
|
||||
),
|
||||
label: getProductWarehouseOptionLabel(stock.product_warehouse),
|
||||
},
|
||||
qty: stock.usage_amount ?? '',
|
||||
}))
|
||||
);
|
||||
@@ -1462,7 +1470,7 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
||||
(stockIdx: number) => {
|
||||
if ((type as 'add' | 'edit' | 'detail') === 'detail') return null;
|
||||
const stock = formik.values.stocks?.[stockIdx];
|
||||
if (!stock || !stock.product_warehouse_id) return null;
|
||||
if (!stock || !stock.product_warehouse_id?.value) return null;
|
||||
return null;
|
||||
},
|
||||
[formik.values.stocks, type]
|
||||
@@ -1492,13 +1500,17 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
||||
const getStockUsageAdornment = useCallback(
|
||||
(stockIdx: number) => {
|
||||
const stock = formik.values.stocks?.[stockIdx];
|
||||
if (!stock || !stock.product_warehouse_id) return null;
|
||||
if (!stock || !stock.product_warehouse_id?.value) return null;
|
||||
|
||||
const isDetail = (type as 'add' | 'edit' | 'detail') === 'detail';
|
||||
const availableStock = getAvailableStock(stock.product_warehouse_id);
|
||||
const availableStock = getAvailableStock(
|
||||
stock.product_warehouse_id.value
|
||||
);
|
||||
const requestedUsage = Number(stock.qty) || 0;
|
||||
const remainingStock = availableStock - requestedUsage;
|
||||
const { pendingQty } = getStockPendingInfo(stock.product_warehouse_id);
|
||||
const { pendingQty } = getStockPendingInfo(
|
||||
stock.product_warehouse_id.value
|
||||
);
|
||||
|
||||
if (isDetail) {
|
||||
if (pendingQty > 0) {
|
||||
@@ -1605,10 +1617,10 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
||||
return (
|
||||
idx !== currentIdx &&
|
||||
s.product_warehouse_id &&
|
||||
s.product_warehouse_id !== 0
|
||||
s.product_warehouse_id.value !== 0
|
||||
);
|
||||
})
|
||||
.map((s) => s.product_warehouse_id) || [];
|
||||
.map((s) => s.product_warehouse_id?.value) || [];
|
||||
|
||||
return unifiedStockProducts.filter(
|
||||
(opt) => !selectedProductIds.includes(Number(opt.value))
|
||||
@@ -1625,10 +1637,10 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
||||
return (
|
||||
idx !== currentIdx &&
|
||||
d.product_warehouse_id &&
|
||||
d.product_warehouse_id !== 0
|
||||
d.product_warehouse_id.value !== 0
|
||||
);
|
||||
})
|
||||
.map((d) => d.product_warehouse_id) || [];
|
||||
.map((d) => d.product_warehouse_id?.value) || [];
|
||||
|
||||
return depletionProducts.filter(
|
||||
(opt) => !selectedProductIds.includes(Number(opt.value))
|
||||
@@ -1645,10 +1657,10 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
||||
return (
|
||||
idx !== currentIdx &&
|
||||
e.product_warehouse_id &&
|
||||
e.product_warehouse_id !== 0
|
||||
e.product_warehouse_id.value !== 0
|
||||
);
|
||||
})
|
||||
.map((e) => e.product_warehouse_id) || [];
|
||||
.map((e) => e.product_warehouse_id?.value) || [];
|
||||
|
||||
return eggProducts.filter(
|
||||
(opt) => !selectedProductIds.includes(Number(opt.value))
|
||||
@@ -1694,7 +1706,9 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
||||
isError: touchedField && Boolean(errorField?.[column]),
|
||||
errorMessage:
|
||||
touchedField && errorField?.[column]
|
||||
? (errorField[column] as string)
|
||||
? errorField[column] instanceof Object
|
||||
? (errorField[column] as OptionType)?.label
|
||||
: (errorField[column] as string)
|
||||
: '',
|
||||
};
|
||||
};
|
||||
@@ -2901,20 +2915,15 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
||||
<td>
|
||||
<SelectInput
|
||||
required
|
||||
key={`stock-product-${idx}-${stock.product_warehouse_id}`}
|
||||
value={
|
||||
unifiedStockProducts.find(
|
||||
(product) =>
|
||||
product.value === stock.product_warehouse_id
|
||||
) || null
|
||||
}
|
||||
key={`stock-product-${idx}-${stock.product_warehouse_id?.value}`}
|
||||
value={stock.product_warehouse_id}
|
||||
onInputChange={setStockInputValue}
|
||||
onChange={(selectedOption) => {
|
||||
const option =
|
||||
selectedOption as OptionType | null;
|
||||
formik.setFieldValue(
|
||||
`stocks.${idx}.product_warehouse_id`,
|
||||
option?.value || 0
|
||||
option
|
||||
);
|
||||
}}
|
||||
options={getAvailableStockProductOptions(idx)}
|
||||
@@ -2950,9 +2959,9 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
||||
}
|
||||
isClearable={type !== 'detail'}
|
||||
inputPrefix={
|
||||
stock.product_warehouse_id
|
||||
stock.product_warehouse_id?.value
|
||||
? getProductFlagBadgeAdornment(
|
||||
stock.product_warehouse_id
|
||||
stock.product_warehouse_id.value
|
||||
)
|
||||
: undefined
|
||||
}
|
||||
@@ -2988,7 +2997,7 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
||||
inputSuffix={
|
||||
stock.product_warehouse_id
|
||||
? getProductUomSuffix(
|
||||
stock.product_warehouse_id,
|
||||
stock.product_warehouse_id.value,
|
||||
'stock'
|
||||
)
|
||||
: null
|
||||
@@ -3181,19 +3190,13 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
||||
)}
|
||||
<td>
|
||||
<SelectInput
|
||||
value={
|
||||
depletionProducts.find(
|
||||
(product) =>
|
||||
product.value ===
|
||||
depletion.product_warehouse_id
|
||||
) || null
|
||||
}
|
||||
value={depletion.product_warehouse_id}
|
||||
onChange={(selectedOption) => {
|
||||
const option =
|
||||
selectedOption as OptionType | null;
|
||||
formik.setFieldValue(
|
||||
`depletions.${idx}.product_warehouse_id`,
|
||||
option?.value || 0
|
||||
option
|
||||
);
|
||||
}}
|
||||
options={getAvailableDepletionProductOptions(idx)}
|
||||
@@ -3256,7 +3259,7 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
||||
inputSuffix={
|
||||
depletion.product_warehouse_id
|
||||
? getProductUomSuffix(
|
||||
depletion.product_warehouse_id,
|
||||
depletion.product_warehouse_id.value,
|
||||
'depletion'
|
||||
)
|
||||
: null
|
||||
@@ -3434,18 +3437,13 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
|
||||
)}
|
||||
<td>
|
||||
<SelectInput
|
||||
value={
|
||||
eggProducts.find(
|
||||
(product) =>
|
||||
product.value === egg.product_warehouse_id
|
||||
) || null
|
||||
}
|
||||
value={egg.product_warehouse_id}
|
||||
onChange={(selectedOption) => {
|
||||
const option =
|
||||
selectedOption as OptionType | null;
|
||||
formik.setFieldValue(
|
||||
`eggs.${idx}.product_warehouse_id`,
|
||||
option?.value || 0
|
||||
option
|
||||
);
|
||||
}}
|
||||
options={getAvailableEggProductOptions(idx)}
|
||||
|
||||
+2
@@ -117,6 +117,7 @@ export type CreateGrowingRecordingPayload = {
|
||||
product_warehouse_id?: number;
|
||||
source_product_warehouse_id?: number;
|
||||
qty?: number;
|
||||
product_warehouse?: ProductWarehouse;
|
||||
}[];
|
||||
};
|
||||
|
||||
@@ -124,6 +125,7 @@ export type CreateEggPayload = {
|
||||
product_warehouse_id?: number;
|
||||
qty?: number;
|
||||
weight?: number;
|
||||
product_warehouse?: ProductWarehouse;
|
||||
};
|
||||
|
||||
export type CreateLayingRecordingPayload = CreateGrowingRecordingPayload & {
|
||||
|
||||
Reference in New Issue
Block a user