feat: price by category
This commit is contained in:
@@ -1,99 +1,108 @@
|
||||
import {Button, rem, Textarea, TextInput} from "@mantine/core";
|
||||
import {QuickDeal} from "../../../types/QuickDeal.ts";
|
||||
import {FC} from "react";
|
||||
import {useForm} from "@mantine/form";
|
||||
import styles from './CreateDealForm.module.css';
|
||||
import { Button, rem, Textarea, TextInput } from "@mantine/core";
|
||||
import { QuickDeal } from "../../../types/QuickDeal.ts";
|
||||
import { FC } from "react";
|
||||
import { useForm } from "@mantine/form";
|
||||
import styles from "./CreateDealForm.module.css";
|
||||
import ClientAutocomplete from "../../Selects/ClientAutocomplete/ClientAutocomplete.tsx";
|
||||
import {DateTimePicker} from "@mantine/dates";
|
||||
import { DateTimePicker } from "@mantine/dates";
|
||||
import ShippingWarehouseAutocomplete
|
||||
from "../../Selects/ShippingWarehouseAutocomplete/ShippingWarehouseAutocomplete.tsx";
|
||||
import BaseMarketplaceSelect from "../../Selects/BaseMarketplaceSelect/BaseMarketplaceSelect.tsx";
|
||||
import ServicePriceCategorySelect from "../../Selects/ServicePriceCategorySelect/ServicePriceCategorySelect.tsx";
|
||||
|
||||
type Props = {
|
||||
onSubmit: (quickDeal: QuickDeal) => void
|
||||
onCancel: () => void;
|
||||
}
|
||||
const CreateDealFrom: FC<Props> = ({onSubmit, onCancel}) => {
|
||||
const CreateDealFrom: FC<Props> = ({ onSubmit, onCancel }) => {
|
||||
const form = useForm<QuickDeal>({
|
||||
initialValues: {
|
||||
name: '',
|
||||
clientName: '',
|
||||
clientAddress: '',
|
||||
comment: '',
|
||||
name: "",
|
||||
clientName: "",
|
||||
clientAddress: "",
|
||||
comment: "",
|
||||
acceptanceDate: new Date(),
|
||||
shippingWarehouse: '',
|
||||
shippingWarehouse: "",
|
||||
baseMarketplace: {
|
||||
key: "",
|
||||
iconUrl: "",
|
||||
name: ""
|
||||
}
|
||||
}
|
||||
name: "",
|
||||
},
|
||||
},
|
||||
});
|
||||
return (
|
||||
<form
|
||||
style={{width: '100%'}}
|
||||
style={{ width: "100%" }}
|
||||
onSubmit={form.onSubmit((values) => onSubmit(values))}
|
||||
>
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
width: '100%',
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
width: "100%",
|
||||
gap: rem(10),
|
||||
padding: rem(10)
|
||||
padding: rem(10),
|
||||
}}>
|
||||
<div className={styles['inputs']}>
|
||||
<div className={styles["inputs"]}>
|
||||
<TextInput
|
||||
placeholder={'Название сделки'}
|
||||
{...form.getInputProps('name')}
|
||||
placeholder={"Название сделки"}
|
||||
{...form.getInputProps("name")}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles['inputs']}>
|
||||
<div className={styles["inputs"]}>
|
||||
<ClientAutocomplete
|
||||
nameRestProps={form.getInputProps('clientName')}
|
||||
nameRestProps={form.getInputProps("clientName")}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles['inputs']}>
|
||||
<div className={styles["inputs"]}>
|
||||
<BaseMarketplaceSelect
|
||||
rightSection={<></>}
|
||||
placeholder={"Базовый маркетплейс"}
|
||||
{...form.getInputProps("baseMarketplace")}
|
||||
/>
|
||||
<ShippingWarehouseAutocomplete
|
||||
{...form.getInputProps('shippingWarehouse')}
|
||||
placeholder={'Склад отгрузки'}
|
||||
{...form.getInputProps("shippingWarehouse")}
|
||||
placeholder={"Склад отгрузки"}
|
||||
/>
|
||||
|
||||
</div>
|
||||
<div className={styles["inputs"]}>
|
||||
<ServicePriceCategorySelect
|
||||
rightSection={<></>}
|
||||
placeholder={"Выберите категорию"}
|
||||
{...form.getInputProps("category")}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className={styles['inputs']}>
|
||||
<div className={styles["inputs"]}>
|
||||
<Textarea
|
||||
autosize
|
||||
placeholder={'Комментарий'}
|
||||
placeholder={"Комментарий"}
|
||||
minRows={2}
|
||||
maxRows={4}
|
||||
{...form.getInputProps('comment')}
|
||||
{...form.getInputProps("comment")}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles['inputs']}>
|
||||
<div className={styles["inputs"]}>
|
||||
<DateTimePicker
|
||||
placeholder={'Дата приемки'}
|
||||
{...form.getInputProps('acceptanceDate')}
|
||||
placeholder={"Дата приемки"}
|
||||
{...form.getInputProps("acceptanceDate")}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
<div className={styles['buttons']}>
|
||||
<div className={styles["buttons"]}>
|
||||
<Button
|
||||
type={'submit'}
|
||||
type={"submit"}
|
||||
>Добавить</Button>
|
||||
<Button
|
||||
variant={'outline'}
|
||||
variant={"outline"}
|
||||
onClick={() => onCancel()}
|
||||
>Отменить</Button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
)
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export default CreateDealFrom;
|
||||
@@ -0,0 +1,17 @@
|
||||
import ObjectSelect, { ObjectSelectProps } from "../../ObjectSelect/ObjectSelect.tsx";
|
||||
import { ServicePriceCategorySchema } from "../../../client";
|
||||
import useServicePriceCategoriesList from "../../../pages/ServicesPage/hooks/useServicePriceCategoriesList.tsx";
|
||||
|
||||
type Props = Omit<ObjectSelectProps<ServicePriceCategorySchema>, "data">
|
||||
|
||||
const ServicePriceCategorySelect = (props: Props) => {
|
||||
const { objects } = useServicePriceCategoriesList();
|
||||
return (
|
||||
<ObjectSelect
|
||||
{...props}
|
||||
data={objects}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default ServicePriceCategorySelect;
|
||||
@@ -1,11 +1,11 @@
|
||||
import {ObjectSelectProps} from "../ObjectSelect/ObjectSelect.tsx";
|
||||
import {ServiceSchema} from "../../client";
|
||||
import {Flex, FlexProps, NumberInput, NumberInputProps, rem} from "@mantine/core";
|
||||
import {FC, useEffect, useRef, useState} from "react";
|
||||
import { ObjectSelectProps } from "../ObjectSelect/ObjectSelect.tsx";
|
||||
import { ServicePriceCategorySchema, ServiceSchema } from "../../client";
|
||||
import { Flex, FlexProps, NumberInput, NumberInputProps, rem } from "@mantine/core";
|
||||
import { FC, useEffect, useRef, useState } from "react";
|
||||
import ServiceSelectNew from "../Selects/ServiceSelectNew/ServiceSelectNew.tsx";
|
||||
import {ServiceType} from "../../shared/enums/ServiceType.ts";
|
||||
import { ServiceType } from "../../shared/enums/ServiceType.ts";
|
||||
|
||||
type ServiceProps = Omit<ObjectSelectProps<ServiceSchema>, 'data'>;
|
||||
type ServiceProps = Omit<ObjectSelectProps<ServiceSchema>, "data">;
|
||||
type PriceProps = NumberInputProps;
|
||||
|
||||
type Props = {
|
||||
@@ -15,6 +15,7 @@ type Props = {
|
||||
containerProps: FlexProps,
|
||||
filterType?: ServiceType,
|
||||
lockOnEdit?: boolean
|
||||
category?: ServicePriceCategorySchema
|
||||
}
|
||||
const ServiceWithPriceInput: FC<Props> = ({
|
||||
serviceProps,
|
||||
@@ -22,10 +23,11 @@ const ServiceWithPriceInput: FC<Props> = ({
|
||||
quantity,
|
||||
containerProps,
|
||||
filterType = ServiceType.PRODUCT_SERVICE,
|
||||
lockOnEdit = true
|
||||
lockOnEdit = true,
|
||||
category,
|
||||
}) => {
|
||||
const [price, setPrice] = useState<number | undefined>(
|
||||
typeof priceProps.value === 'number' ? priceProps.value : undefined);
|
||||
typeof priceProps.value === "number" ? priceProps.value : undefined);
|
||||
const [service, setService] = useState<ServiceSchema | undefined>(serviceProps.value);
|
||||
const isFirstRender = useRef(true);
|
||||
const setPriceBasedOnQuantity = (): boolean => {
|
||||
@@ -35,29 +37,40 @@ const ServiceWithPriceInput: FC<Props> = ({
|
||||
|
||||
setPrice(range.price);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
const setPriceBasedOnCategory = () => {
|
||||
if (!category || !service) return false;
|
||||
const categoryPrice = service.categoryPrices.find(categoryPrice => categoryPrice.category.id === category.id);
|
||||
if (!categoryPrice) return false;
|
||||
setPrice(categoryPrice.price);
|
||||
return true;
|
||||
};
|
||||
const setPriceBasedOnService = () => {
|
||||
if (!service) return;
|
||||
// if category is set, we should not set price based on service
|
||||
if (setPriceBasedOnCategory()) return;
|
||||
if (setPriceBasedOnQuantity()) return;
|
||||
setPrice(service.price);
|
||||
}
|
||||
};
|
||||
const onServiceManualChange = (service: ServiceSchema) => {
|
||||
setService(service);
|
||||
}
|
||||
};
|
||||
const onPriceManualChange = (value: number | string) => {
|
||||
if (typeof value !== 'number') return;
|
||||
if (typeof value !== "number") return;
|
||||
setPrice(value);
|
||||
}
|
||||
};
|
||||
useEffect(() => {
|
||||
if (isFirstRender.current && lockOnEdit) return;
|
||||
|
||||
// we need to set price based on quantity only if category is not set, because category has higher priority
|
||||
if (category) return;
|
||||
setPriceBasedOnQuantity();
|
||||
}, [quantity]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isFirstRender.current && lockOnEdit) return;
|
||||
|
||||
if (!priceProps.onChange || typeof price === 'undefined') return;
|
||||
if (!priceProps.onChange || typeof price === "undefined") return;
|
||||
priceProps.onChange(price);
|
||||
}, [price]);
|
||||
|
||||
@@ -97,7 +110,7 @@ const ServiceWithPriceInput: FC<Props> = ({
|
||||
/>
|
||||
|
||||
</Flex>
|
||||
)
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export default ServiceWithPriceInput;
|
||||
Reference in New Issue
Block a user