feat: residues accounting

This commit is contained in:
2025-01-14 21:35:06 +04:00
parent fec6b13972
commit c45d2ac20a
74 changed files with 2994 additions and 28 deletions

View File

@@ -0,0 +1,129 @@
import { useForm } from "@mantine/form";
import { ContextModalProps } from "@mantine/modals";
import { Button, Divider, Flex, NumberInput, rem, Stack } from "@mantine/core";
import ProductSelect from "../../../../../components/ProductSelect/ProductSelect.tsx";
import useScanning from "../../../hooks/useScanning.tsx";
import ScanBarcode from "../../ScanBarcode/ScanBarcode.tsx";
import { ProductSchema, ResidualBoxSchema, ResidualPalletSchema, ResiduesService } from "../../../../../client";
import { notifications } from "../../../../../shared/lib/notifications.ts";
import { ResidualModalForm } from "../../../../ResiduesPage/types/ResidualProductData.tsx";
type Props = {
clientId: number;
object: ResidualBoxSchema | ResidualPalletSchema;
fetchObject: () => void;
isBox: boolean;
}
const ReceiptModal = ({
context,
id,
innerProps,
}: ContextModalProps<Props>) => {
const {
clientId,
object,
fetchObject,
} = innerProps;
const { isScanning, setIsScanning, scannedValue, setScannedValue } = useScanning();
const initialValues = {
product: null,
quantity: 1,
};
const form = useForm<ResidualModalForm>({
initialValues,
validate: {
product: product => !product && "Необходимо выбрать товар",
quantity: quantity => (!quantity || quantity === 0) && "Слишком мало товара",
},
});
if (!object || !clientId) return;
const postProduct = (product: ProductSchema, quantity: number) => {
ResiduesService.createResidualProduct({
requestBody: {
data: {
productId: product.id,
quantity,
palletId: innerProps.isBox ? null : object.id,
boxId: innerProps.isBox ? object.id : null,
},
},
})
.then(({ ok, message }) => {
notifications.guess(ok, { message });
fetchObject();
if (ok) context.closeContextModal(id);
})
.catch(err => console.log(err));
};
const onProductAfterScanningSelect = (product?: ProductSchema) => {
if (!product) {
setScannedValue("");
return;
}
const productIdx = object.residualProducts.findIndex(p => p.product.id === product.id);
if (productIdx === -1) {
form.setFieldValue("product", product);
} else {
postProduct(product, 1);
}
setScannedValue("");
};
const onSubmit = () => {
postProduct(form.values.product!, form.values.quantity!);
form.reset();
};
return (
<Flex
direction={"column"}
gap={rem(10)}
>
<form onSubmit={form.onSubmit(() => onSubmit())}>
<Stack gap={rem(10)}>
<Divider />
<ProductSelect
label={"Товар"}
placeholder={"Выберите товар"}
{...form.getInputProps("product")}
clientId={clientId}
disabled={isScanning}
/>
<NumberInput
label={"Количество"}
hideControls
{...form.getInputProps("quantity")}
min={1}
defaultValue={1}
disabled={isScanning}
/>
<Button
variant={"default"}
type={"submit"}
disabled={isScanning}
>
Добавить
</Button>
<Divider />
</Stack>
</form>
<ScanBarcode
clientId={clientId}
isScanning={isScanning}
setIsScanning={setIsScanning}
onProductSelect={onProductAfterScanningSelect}
scannedValue={scannedValue}
object={object}
/>
</Flex>
);
};
export default ReceiptModal;