Обновлены категории товаров с "Упаковка" на "Расходники" в различных компонентах и моделях. Добавлены уведомления о непринятых поставках и обновлены соответствующие GraphQL запросы и резолверы для поддержки новых данных. Оптимизирована логика отображения и обработки данных в интерфейсе.
This commit is contained in:
@ -7,7 +7,11 @@ import { Input } from "@/components/ui/input";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { PhoneInput } from "@/components/ui/phone-input";
|
||||
import { formatPhoneInput, isValidPhone, formatNameInput } from "@/lib/input-masks";
|
||||
import {
|
||||
formatPhoneInput,
|
||||
isValidPhone,
|
||||
formatNameInput,
|
||||
} from "@/lib/input-masks";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
@ -51,7 +55,10 @@ import {
|
||||
GET_COUNTERPARTY_SUPPLIES,
|
||||
GET_SUPPLY_SUPPLIERS,
|
||||
} from "@/graphql/queries";
|
||||
import { CREATE_WILDBERRIES_SUPPLY, CREATE_SUPPLY_SUPPLIER } from "@/graphql/mutations";
|
||||
import {
|
||||
CREATE_WILDBERRIES_SUPPLY,
|
||||
CREATE_SUPPLY_SUPPLIER,
|
||||
} from "@/graphql/mutations";
|
||||
import { toast } from "sonner";
|
||||
import { format } from "date-fns";
|
||||
import { ru } from "date-fns/locale";
|
||||
@ -187,7 +194,8 @@ export function DirectSupplyCreation({
|
||||
|
||||
// Загружаем контрагентов-фулфилментов
|
||||
const { data: counterpartiesData } = useQuery(GET_MY_COUNTERPARTIES);
|
||||
const { data: suppliersData, refetch: refetchSuppliers } = useQuery(GET_SUPPLY_SUPPLIERS);
|
||||
const { data: suppliersData, refetch: refetchSuppliers } =
|
||||
useQuery(GET_SUPPLY_SUPPLIERS);
|
||||
|
||||
// Мутации
|
||||
const [createSupply, { loading: creatingSupply }] = useMutation(
|
||||
@ -207,17 +215,17 @@ export function DirectSupplyCreation({
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
const [createSupplierMutation, { loading: creatingSupplier }] = useMutation(
|
||||
CREATE_SUPPLY_SUPPLIER,
|
||||
{
|
||||
onCompleted: (data) => {
|
||||
if (data.createSupplySupplier.success) {
|
||||
toast.success("Поставщик добавлен успешно!");
|
||||
|
||||
|
||||
// Обновляем список поставщиков из БД
|
||||
refetchSuppliers();
|
||||
|
||||
|
||||
// Очищаем форму
|
||||
setNewSupplier({
|
||||
name: "",
|
||||
@ -236,7 +244,10 @@ export function DirectSupplyCreation({
|
||||
});
|
||||
setShowSupplierModal(false);
|
||||
} else {
|
||||
toast.error(data.createSupplySupplier.message || "Ошибка при добавлении поставщика");
|
||||
toast.error(
|
||||
data.createSupplySupplier.message ||
|
||||
"Ошибка при добавлении поставщика"
|
||||
);
|
||||
}
|
||||
},
|
||||
onError: (error) => {
|
||||
@ -260,11 +271,11 @@ export function DirectSupplyCreation({
|
||||
supplierVendorCode: "SUPPLIER-001",
|
||||
mediaFiles: ["/api/placeholder/400/400"],
|
||||
dimensions: {
|
||||
length: 30, // 30 см
|
||||
width: 25, // 25 см
|
||||
height: 5, // 5 см
|
||||
weightBrutto: 0.3, // 300г
|
||||
isValid: true
|
||||
length: 30, // 30 см
|
||||
width: 25, // 25 см
|
||||
height: 5, // 5 см
|
||||
weightBrutto: 0.3, // 300г
|
||||
isValid: true,
|
||||
},
|
||||
sizes: [
|
||||
{
|
||||
@ -289,11 +300,11 @@ export function DirectSupplyCreation({
|
||||
supplierVendorCode: "SUPPLIER-002",
|
||||
mediaFiles: ["/api/placeholder/400/403"],
|
||||
dimensions: {
|
||||
length: 35, // 35 см
|
||||
width: 28, // 28 см
|
||||
height: 6, // 6 см
|
||||
weightBrutto: 0.4, // 400г
|
||||
isValid: true
|
||||
length: 35, // 35 см
|
||||
width: 28, // 28 см
|
||||
height: 6, // 6 см
|
||||
weightBrutto: 0.4, // 400г
|
||||
isValid: true,
|
||||
},
|
||||
sizes: [
|
||||
{
|
||||
@ -404,7 +415,10 @@ export function DirectSupplyCreation({
|
||||
// Загружаем услуги и расходники при выборе фулфилмента
|
||||
useEffect(() => {
|
||||
if (selectedFulfillmentId) {
|
||||
console.log('Загружаем услуги и расходники для фулфилмента:', selectedFulfillmentId);
|
||||
console.log(
|
||||
"Загружаем услуги и расходники для фулфилмента:",
|
||||
selectedFulfillmentId
|
||||
);
|
||||
loadOrganizationServices(selectedFulfillmentId);
|
||||
loadOrganizationSupplies(selectedFulfillmentId);
|
||||
}
|
||||
@ -439,7 +453,12 @@ export function DirectSupplyCreation({
|
||||
const consumablesCost = getConsumablesCost();
|
||||
onConsumablesCostChange(consumablesCost);
|
||||
}
|
||||
}, [selectedConsumables, selectedFulfillmentId, supplyItems.length, onConsumablesCostChange]);
|
||||
}, [
|
||||
selectedConsumables,
|
||||
selectedFulfillmentId,
|
||||
supplyItems.length,
|
||||
onConsumablesCostChange,
|
||||
]);
|
||||
|
||||
const loadCards = async () => {
|
||||
setLoading(true);
|
||||
@ -462,20 +481,34 @@ export function DirectSupplyCreation({
|
||||
if (apiToken) {
|
||||
console.log("Загружаем карточки из WB API...");
|
||||
const cards = await WildberriesService.getAllCards(apiToken, 500);
|
||||
|
||||
|
||||
// Логируем информацию о размерах товаров
|
||||
cards.forEach(card => {
|
||||
cards.forEach((card) => {
|
||||
if (card.dimensions) {
|
||||
const volume = (card.dimensions.length / 100) * (card.dimensions.width / 100) * (card.dimensions.height / 100);
|
||||
console.log(`WB API: Карточка ${card.nmID} - размеры: ${card.dimensions.length}x${card.dimensions.width}x${card.dimensions.height} см, объем: ${volume.toFixed(6)} м³`);
|
||||
const volume =
|
||||
(card.dimensions.length / 100) *
|
||||
(card.dimensions.width / 100) *
|
||||
(card.dimensions.height / 100);
|
||||
console.log(
|
||||
`WB API: Карточка ${card.nmID} - размеры: ${
|
||||
card.dimensions.length
|
||||
}x${card.dimensions.width}x${
|
||||
card.dimensions.height
|
||||
} см, объем: ${volume.toFixed(6)} м³`
|
||||
);
|
||||
} else {
|
||||
console.log(`WB API: Карточка ${card.nmID} - размеры отсутствуют`);
|
||||
console.log(
|
||||
`WB API: Карточка ${card.nmID} - размеры отсутствуют`
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
setWbCards(cards);
|
||||
console.log("Загружено карточек из WB API:", cards.length);
|
||||
console.log("Карточки с размерами:", cards.filter(card => card.dimensions).length);
|
||||
console.log(
|
||||
"Карточки с размерами:",
|
||||
cards.filter((card) => card.dimensions).length
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -522,20 +555,34 @@ export function DirectSupplyCreation({
|
||||
searchTerm,
|
||||
100
|
||||
);
|
||||
|
||||
|
||||
// Логируем информацию о размерах найденных товаров
|
||||
cards.forEach(card => {
|
||||
cards.forEach((card) => {
|
||||
if (card.dimensions) {
|
||||
const volume = (card.dimensions.length / 100) * (card.dimensions.width / 100) * (card.dimensions.height / 100);
|
||||
console.log(`WB API: Найденная карточка ${card.nmID} - размеры: ${card.dimensions.length}x${card.dimensions.width}x${card.dimensions.height} см, объем: ${volume.toFixed(6)} м³`);
|
||||
const volume =
|
||||
(card.dimensions.length / 100) *
|
||||
(card.dimensions.width / 100) *
|
||||
(card.dimensions.height / 100);
|
||||
console.log(
|
||||
`WB API: Найденная карточка ${card.nmID} - размеры: ${
|
||||
card.dimensions.length
|
||||
}x${card.dimensions.width}x${
|
||||
card.dimensions.height
|
||||
} см, объем: ${volume.toFixed(6)} м³`
|
||||
);
|
||||
} else {
|
||||
console.log(`WB API: Найденная карточка ${card.nmID} - размеры отсутствуют`);
|
||||
console.log(
|
||||
`WB API: Найденная карточка ${card.nmID} - размеры отсутствуют`
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
setWbCards(cards);
|
||||
console.log("Найдено карточек в WB API:", cards.length);
|
||||
console.log("Найденные карточки с размерами:", cards.filter(card => card.dimensions).length);
|
||||
console.log(
|
||||
"Найденные карточки с размерами:",
|
||||
cards.filter((card) => card.dimensions).length
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -650,12 +697,17 @@ export function DirectSupplyCreation({
|
||||
const newItems = prev.map((item) => {
|
||||
if (item.card.nmID === nmID) {
|
||||
const updatedItem = { ...item, [field]: value };
|
||||
|
||||
|
||||
// Пересчитываем totalPrice в зависимости от типа цены
|
||||
if (field === "quantity" || field === "pricePerUnit" || field === "priceType") {
|
||||
if (
|
||||
field === "quantity" ||
|
||||
field === "pricePerUnit" ||
|
||||
field === "priceType"
|
||||
) {
|
||||
if (updatedItem.priceType === "perUnit") {
|
||||
// Цена за штуку - умножаем на количество
|
||||
updatedItem.totalPrice = updatedItem.quantity * updatedItem.pricePerUnit;
|
||||
updatedItem.totalPrice =
|
||||
updatedItem.quantity * updatedItem.pricePerUnit;
|
||||
} else {
|
||||
// Цена за общее количество - pricePerUnit становится общей ценой
|
||||
updatedItem.totalPrice = updatedItem.pricePerUnit;
|
||||
@ -669,13 +721,16 @@ export function DirectSupplyCreation({
|
||||
// Если изменился поставщик, уведомляем родительский компонент асинхронно
|
||||
if (field === "supplierId" && onSuppliersChange) {
|
||||
// Создаем список поставщиков с информацией о выборе
|
||||
const suppliersInfo = suppliers.map(supplier => ({
|
||||
const suppliersInfo = suppliers.map((supplier) => ({
|
||||
...supplier,
|
||||
selected: newItems.some(item => item.supplierId === supplier.id)
|
||||
selected: newItems.some((item) => item.supplierId === supplier.id),
|
||||
}));
|
||||
|
||||
console.log("Обновление поставщиков из updateSupplyItem:", suppliersInfo);
|
||||
|
||||
|
||||
console.log(
|
||||
"Обновление поставщиков из updateSupplyItem:",
|
||||
suppliersInfo
|
||||
);
|
||||
|
||||
// Вызываем асинхронно чтобы не обновлять состояние во время рендера
|
||||
setTimeout(() => {
|
||||
onSuppliersChange(suppliersInfo);
|
||||
@ -708,16 +763,22 @@ export function DirectSupplyCreation({
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
setSupplierErrors(prev => ({...prev, [field]: error}));
|
||||
|
||||
setSupplierErrors((prev) => ({ ...prev, [field]: error }));
|
||||
return error === "";
|
||||
};
|
||||
|
||||
const validateAllSupplierFields = () => {
|
||||
const nameValid = validateSupplierField("name", newSupplier.name);
|
||||
const contactNameValid = validateSupplierField("contactName", newSupplier.contactName);
|
||||
const contactNameValid = validateSupplierField(
|
||||
"contactName",
|
||||
newSupplier.contactName
|
||||
);
|
||||
const phoneValid = validateSupplierField("phone", newSupplier.phone);
|
||||
const telegramValid = validateSupplierField("telegram", newSupplier.telegram);
|
||||
const telegramValid = validateSupplierField(
|
||||
"telegram",
|
||||
newSupplier.telegram
|
||||
);
|
||||
return nameValid && contactNameValid && phoneValid && telegramValid;
|
||||
};
|
||||
|
||||
@ -760,17 +821,24 @@ export function DirectSupplyCreation({
|
||||
// Функция для расчета объема одного товара в м³
|
||||
const calculateItemVolume = (card: WildberriesCard): number => {
|
||||
if (!card.dimensions) return 0;
|
||||
|
||||
|
||||
const { length, width, height } = card.dimensions;
|
||||
|
||||
|
||||
// Проверяем что все размеры указаны и больше 0
|
||||
if (!length || !width || !height || length <= 0 || width <= 0 || height <= 0) {
|
||||
if (
|
||||
!length ||
|
||||
!width ||
|
||||
!height ||
|
||||
length <= 0 ||
|
||||
width <= 0 ||
|
||||
height <= 0
|
||||
) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Переводим из сантиметров в метры и рассчитываем объем
|
||||
const volumeInM3 = (length / 100) * (width / 100) * (height / 100);
|
||||
|
||||
|
||||
return volumeInM3;
|
||||
};
|
||||
|
||||
@ -778,7 +846,7 @@ export function DirectSupplyCreation({
|
||||
const getTotalVolume = () => {
|
||||
return supplyItems.reduce((totalVolume, item) => {
|
||||
const itemVolume = calculateItemVolume(item.card);
|
||||
return totalVolume + (itemVolume * item.quantity);
|
||||
return totalVolume + itemVolume * item.quantity;
|
||||
}, 0);
|
||||
};
|
||||
|
||||
@ -883,19 +951,29 @@ export function DirectSupplyCreation({
|
||||
// Загрузка поставщиков из правильного источника
|
||||
React.useEffect(() => {
|
||||
if (suppliersData?.supplySuppliers) {
|
||||
console.log("Загружаем поставщиков из БД:", suppliersData.supplySuppliers);
|
||||
console.log(
|
||||
"Загружаем поставщиков из БД:",
|
||||
suppliersData.supplySuppliers
|
||||
);
|
||||
setSuppliers(suppliersData.supplySuppliers);
|
||||
|
||||
|
||||
// Проверяем есть ли уже выбранные поставщики и уведомляем родителя
|
||||
if (onSuppliersChange && supplyItems.length > 0) {
|
||||
const suppliersInfo = suppliersData.supplySuppliers.map((supplier: { id: string; selected?: boolean }) => ({
|
||||
...supplier,
|
||||
selected: supplyItems.some(item => item.supplierId === supplier.id)
|
||||
}));
|
||||
|
||||
const suppliersInfo = suppliersData.supplySuppliers.map(
|
||||
(supplier: { id: string; selected?: boolean }) => ({
|
||||
...supplier,
|
||||
selected: supplyItems.some(
|
||||
(item) => item.supplierId === supplier.id
|
||||
),
|
||||
})
|
||||
);
|
||||
|
||||
if (suppliersInfo.some((s: { selected?: boolean }) => s.selected)) {
|
||||
console.log("Найдены выбранные поставщики при загрузке:", suppliersInfo);
|
||||
|
||||
console.log(
|
||||
"Найдены выбранные поставщики при загрузке:",
|
||||
suppliersInfo
|
||||
);
|
||||
|
||||
// Вызываем асинхронно чтобы не обновлять состояние во время рендера
|
||||
setTimeout(() => {
|
||||
onSuppliersChange(suppliersInfo);
|
||||
@ -929,8 +1007,6 @@ export function DirectSupplyCreation({
|
||||
<>
|
||||
<style>{lineClampStyles}</style>
|
||||
<div className="flex flex-col h-full space-y-2 w-full min-h-0">
|
||||
|
||||
|
||||
{/* Элегантный блок поиска и товаров */}
|
||||
<div className="relative">
|
||||
{/* Главная карточка с градиентом */}
|
||||
@ -1228,9 +1304,17 @@ export function DirectSupplyCreation({
|
||||
<div className="text-white/60 text-[10px] flex space-x-2">
|
||||
<span>WB: {item.card.nmID}</span>
|
||||
{calculateItemVolume(item.card) > 0 ? (
|
||||
<span className="text-blue-400">| {(calculateItemVolume(item.card) * item.quantity).toFixed(4)} м³</span>
|
||||
<span className="text-blue-400">
|
||||
|{" "}
|
||||
{(
|
||||
calculateItemVolume(item.card) * item.quantity
|
||||
).toFixed(4)}{" "}
|
||||
м³
|
||||
</span>
|
||||
) : (
|
||||
<span className="text-orange-400">| размеры не указаны</span>
|
||||
<span className="text-orange-400">
|
||||
| размеры не указаны
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
@ -1294,56 +1378,78 @@ export function DirectSupplyCreation({
|
||||
{/* Создаем массив валидных параметров */}
|
||||
{(() => {
|
||||
const params = [];
|
||||
|
||||
|
||||
// Бренд
|
||||
if (item.card.brand && item.card.brand.trim() && item.card.brand !== '0') {
|
||||
if (
|
||||
item.card.brand &&
|
||||
item.card.brand.trim() &&
|
||||
item.card.brand !== "0"
|
||||
) {
|
||||
params.push({
|
||||
value: item.card.brand,
|
||||
color: 'bg-blue-500/80',
|
||||
key: 'brand'
|
||||
color: "bg-blue-500/80",
|
||||
key: "brand",
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Категория (объект)
|
||||
if (item.card.object && item.card.object.trim() && item.card.object !== '0') {
|
||||
if (
|
||||
item.card.object &&
|
||||
item.card.object.trim() &&
|
||||
item.card.object !== "0"
|
||||
) {
|
||||
params.push({
|
||||
value: item.card.object,
|
||||
color: 'bg-green-500/80',
|
||||
key: 'object'
|
||||
color: "bg-green-500/80",
|
||||
key: "object",
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Страна (только если не пустая и не 0)
|
||||
if (item.card.countryProduction && item.card.countryProduction.trim() && item.card.countryProduction !== '0') {
|
||||
if (
|
||||
item.card.countryProduction &&
|
||||
item.card.countryProduction.trim() &&
|
||||
item.card.countryProduction !== "0"
|
||||
) {
|
||||
params.push({
|
||||
value: item.card.countryProduction,
|
||||
color: 'bg-purple-500/80',
|
||||
key: 'country'
|
||||
color: "bg-purple-500/80",
|
||||
key: "country",
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Цена WB
|
||||
if (item.card.sizes?.[0]?.price && item.card.sizes[0].price > 0) {
|
||||
if (
|
||||
item.card.sizes?.[0]?.price &&
|
||||
item.card.sizes[0].price > 0
|
||||
) {
|
||||
params.push({
|
||||
value: formatCurrency(item.card.sizes[0].price),
|
||||
color: 'bg-yellow-500/80',
|
||||
key: 'price'
|
||||
color: "bg-yellow-500/80",
|
||||
key: "price",
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Внутренний артикул
|
||||
if (item.card.vendorCode && item.card.vendorCode.trim() && item.card.vendorCode !== '0') {
|
||||
if (
|
||||
item.card.vendorCode &&
|
||||
item.card.vendorCode.trim() &&
|
||||
item.card.vendorCode !== "0"
|
||||
) {
|
||||
params.push({
|
||||
value: item.card.vendorCode,
|
||||
color: 'bg-gray-500/80',
|
||||
key: 'vendor'
|
||||
color: "bg-gray-500/80",
|
||||
key: "vendor",
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// НАМЕРЕННО НЕ ВКЛЮЧАЕМ techSize и wbSize так как они равны '0'
|
||||
|
||||
return params.map(param => (
|
||||
<span key={param.key} className={`${param.color} text-white text-[9px] px-2 py-1 rounded font-medium`}>
|
||||
|
||||
return params.map((param) => (
|
||||
<span
|
||||
key={param.key}
|
||||
className={`${param.color} text-white text-[9px] px-2 py-1 rounded font-medium`}
|
||||
>
|
||||
{param.value}
|
||||
</span>
|
||||
));
|
||||
@ -1377,7 +1483,11 @@ export function DirectSupplyCreation({
|
||||
<div className="flex mb-1">
|
||||
<button
|
||||
onClick={() =>
|
||||
updateSupplyItem(item.card.nmID, "priceType", "perUnit")
|
||||
updateSupplyItem(
|
||||
item.card.nmID,
|
||||
"priceType",
|
||||
"perUnit"
|
||||
)
|
||||
}
|
||||
className={`text-[9px] px-1 py-0.5 rounded-l ${
|
||||
item.priceType === "perUnit"
|
||||
@ -1389,7 +1499,11 @@ export function DirectSupplyCreation({
|
||||
</button>
|
||||
<button
|
||||
onClick={() =>
|
||||
updateSupplyItem(item.card.nmID, "priceType", "total")
|
||||
updateSupplyItem(
|
||||
item.card.nmID,
|
||||
"priceType",
|
||||
"total"
|
||||
)
|
||||
}
|
||||
className={`text-[9px] px-1 py-0.5 rounded-r ${
|
||||
item.priceType === "total"
|
||||
@ -1400,7 +1514,7 @@ export function DirectSupplyCreation({
|
||||
За все
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
<Input
|
||||
type="number"
|
||||
value={item.pricePerUnit || ""}
|
||||
@ -1415,7 +1529,8 @@ export function DirectSupplyCreation({
|
||||
placeholder="₽"
|
||||
/>
|
||||
<div className="text-white/80 text-xs font-medium text-center mt-1">
|
||||
Итого: {formatCurrency(item.totalPrice).replace(" ₽", "₽")}
|
||||
Итого:{" "}
|
||||
{formatCurrency(item.totalPrice).replace(" ₽", "₽")}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1423,11 +1538,15 @@ export function DirectSupplyCreation({
|
||||
<div className="bg-white/10 rounded-lg p-2 flex flex-col justify-center h-20">
|
||||
<div className="space-y-1 max-h-16 overflow-y-auto">
|
||||
{/* DEBUG */}
|
||||
{console.log('DEBUG SERVICES:', {
|
||||
{console.log("DEBUG SERVICES:", {
|
||||
selectedFulfillmentId,
|
||||
hasServices: !!organizationServices[selectedFulfillmentId],
|
||||
servicesCount: organizationServices[selectedFulfillmentId]?.length || 0,
|
||||
allOrganizationServices: Object.keys(organizationServices)
|
||||
hasServices:
|
||||
!!organizationServices[selectedFulfillmentId],
|
||||
servicesCount:
|
||||
organizationServices[selectedFulfillmentId]
|
||||
?.length || 0,
|
||||
allOrganizationServices:
|
||||
Object.keys(organizationServices),
|
||||
})}
|
||||
{selectedFulfillmentId &&
|
||||
organizationServices[selectedFulfillmentId] ? (
|
||||
@ -1463,13 +1582,17 @@ export function DirectSupplyCreation({
|
||||
</span>
|
||||
</div>
|
||||
<span className="text-green-400 text-[10px] font-medium">
|
||||
{service.price ? `${service.price}₽` : 'Бесплатно'}
|
||||
{service.price
|
||||
? `${service.price}₽`
|
||||
: "Бесплатно"}
|
||||
</span>
|
||||
</label>
|
||||
))
|
||||
) : (
|
||||
<span className="text-white/60 text-xs text-center">
|
||||
{selectedFulfillmentId ? 'Нет услуг' : 'Выберите фулфилмент'}
|
||||
{selectedFulfillmentId
|
||||
? "Нет услуг"
|
||||
: "Выберите фулфилмент"}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
@ -1481,7 +1604,11 @@ export function DirectSupplyCreation({
|
||||
<Select
|
||||
value={item.supplierId}
|
||||
onValueChange={(value) =>
|
||||
updateSupplyItem(item.card.nmID, "supplierId", value)
|
||||
updateSupplyItem(
|
||||
item.card.nmID,
|
||||
"supplierId",
|
||||
value
|
||||
)
|
||||
}
|
||||
>
|
||||
<SelectTrigger className="bg-white/20 border-white/20 text-white h-6 text-xs">
|
||||
@ -1497,13 +1624,20 @@ export function DirectSupplyCreation({
|
||||
</Select>
|
||||
|
||||
{/* Компактная информация о выбранном поставщике */}
|
||||
{item.supplierId && suppliers.find((s) => s.id === item.supplierId) ? (
|
||||
{item.supplierId &&
|
||||
suppliers.find((s) => s.id === item.supplierId) ? (
|
||||
<div className="text-center">
|
||||
<div className="text-white/80 text-[10px] font-medium truncate">
|
||||
{suppliers.find((s) => s.id === item.supplierId)?.contactName}
|
||||
{
|
||||
suppliers.find((s) => s.id === item.supplierId)
|
||||
?.contactName
|
||||
}
|
||||
</div>
|
||||
<div className="text-white/60 text-[9px] truncate">
|
||||
{suppliers.find((s) => s.id === item.supplierId)?.phone}
|
||||
{
|
||||
suppliers.find((s) => s.id === item.supplierId)
|
||||
?.phone
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
@ -1524,11 +1658,15 @@ export function DirectSupplyCreation({
|
||||
<div className="bg-white/10 rounded-lg p-2 flex flex-col justify-center h-20">
|
||||
<div className="space-y-1 max-h-16 overflow-y-auto">
|
||||
{/* DEBUG для расходников */}
|
||||
{console.log('DEBUG CONSUMABLES:', {
|
||||
{console.log("DEBUG CONSUMABLES:", {
|
||||
selectedFulfillmentId,
|
||||
hasConsumables: !!organizationSupplies[selectedFulfillmentId],
|
||||
consumablesCount: organizationSupplies[selectedFulfillmentId]?.length || 0,
|
||||
allOrganizationSupplies: Object.keys(organizationSupplies)
|
||||
hasConsumables:
|
||||
!!organizationSupplies[selectedFulfillmentId],
|
||||
consumablesCount:
|
||||
organizationSupplies[selectedFulfillmentId]
|
||||
?.length || 0,
|
||||
allOrganizationSupplies:
|
||||
Object.keys(organizationSupplies),
|
||||
})}
|
||||
{selectedFulfillmentId &&
|
||||
organizationSupplies[selectedFulfillmentId] ? (
|
||||
@ -1564,13 +1702,17 @@ export function DirectSupplyCreation({
|
||||
</span>
|
||||
</div>
|
||||
<span className="text-orange-400 text-[10px] font-medium">
|
||||
{supply.price ? `${supply.price}₽` : 'Бесплатно'}
|
||||
{supply.price
|
||||
? `${supply.price}₽`
|
||||
: "Бесплатно"}
|
||||
</span>
|
||||
</label>
|
||||
))
|
||||
) : (
|
||||
<span className="text-white/60 text-xs text-center">
|
||||
{selectedFulfillmentId ? 'Нет расходников' : 'Выберите фулфилмент'}
|
||||
{selectedFulfillmentId
|
||||
? "Нет расходников"
|
||||
: "Выберите фулфилмент"}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
@ -1581,7 +1723,7 @@ export function DirectSupplyCreation({
|
||||
<div className="space-y-2">
|
||||
<label className="flex items-center space-x-2 cursor-pointer">
|
||||
<input type="checkbox" className="w-3 h-3" />
|
||||
<span className="text-white text-xs">Упаковка</span>
|
||||
<span className="text-white text-xs">Расходники</span>
|
||||
</label>
|
||||
<label className="flex items-center space-x-2 cursor-pointer">
|
||||
<input type="checkbox" className="w-3 h-3" />
|
||||
@ -1626,12 +1768,16 @@ export function DirectSupplyCreation({
|
||||
validateSupplierField("name", value);
|
||||
}}
|
||||
className={`bg-white/10 border-white/20 text-white h-8 text-xs ${
|
||||
supplierErrors.name ? 'border-red-400 focus:border-red-400' : ''
|
||||
supplierErrors.name
|
||||
? "border-red-400 focus:border-red-400"
|
||||
: ""
|
||||
}`}
|
||||
placeholder="Название"
|
||||
/>
|
||||
{supplierErrors.name && (
|
||||
<p className="text-red-400 text-xs mt-1">{supplierErrors.name}</p>
|
||||
<p className="text-red-400 text-xs mt-1">
|
||||
{supplierErrors.name}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
@ -1647,12 +1793,16 @@ export function DirectSupplyCreation({
|
||||
validateSupplierField("contactName", value);
|
||||
}}
|
||||
className={`bg-white/10 border-white/20 text-white h-8 text-xs ${
|
||||
supplierErrors.contactName ? 'border-red-400 focus:border-red-400' : ''
|
||||
supplierErrors.contactName
|
||||
? "border-red-400 focus:border-red-400"
|
||||
: ""
|
||||
}`}
|
||||
placeholder="Имя"
|
||||
/>
|
||||
{supplierErrors.contactName && (
|
||||
<p className="text-red-400 text-xs mt-1">{supplierErrors.contactName}</p>
|
||||
<p className="text-red-400 text-xs mt-1">
|
||||
{supplierErrors.contactName}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
@ -1670,12 +1820,16 @@ export function DirectSupplyCreation({
|
||||
validateSupplierField("phone", value);
|
||||
}}
|
||||
className={`bg-white/10 border-white/20 text-white h-8 text-xs ${
|
||||
supplierErrors.phone ? 'border-red-400 focus:border-red-400' : ''
|
||||
supplierErrors.phone
|
||||
? "border-red-400 focus:border-red-400"
|
||||
: ""
|
||||
}`}
|
||||
placeholder="+7 (999) 123-45-67"
|
||||
/>
|
||||
{supplierErrors.phone && (
|
||||
<p className="text-red-400 text-xs mt-1">{supplierErrors.phone}</p>
|
||||
<p className="text-red-400 text-xs mt-1">
|
||||
{supplierErrors.phone}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
@ -1744,12 +1898,16 @@ export function DirectSupplyCreation({
|
||||
validateSupplierField("telegram", value);
|
||||
}}
|
||||
className={`bg-white/10 border-white/20 text-white h-8 text-xs ${
|
||||
supplierErrors.telegram ? 'border-red-400 focus:border-red-400' : ''
|
||||
supplierErrors.telegram
|
||||
? "border-red-400 focus:border-red-400"
|
||||
: ""
|
||||
}`}
|
||||
placeholder="@username"
|
||||
/>
|
||||
{supplierErrors.telegram && (
|
||||
<p className="text-red-400 text-xs mt-1">{supplierErrors.telegram}</p>
|
||||
<p className="text-red-400 text-xs mt-1">
|
||||
{supplierErrors.telegram}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@ -1763,7 +1921,15 @@ export function DirectSupplyCreation({
|
||||
</Button>
|
||||
<Button
|
||||
onClick={handleCreateSupplier}
|
||||
disabled={!newSupplier.name || !newSupplier.contactName || !newSupplier.phone || Object.values(supplierErrors).some(error => error !== "") || creatingSupplier}
|
||||
disabled={
|
||||
!newSupplier.name ||
|
||||
!newSupplier.contactName ||
|
||||
!newSupplier.phone ||
|
||||
Object.values(supplierErrors).some(
|
||||
(error) => error !== ""
|
||||
) ||
|
||||
creatingSupplier
|
||||
}
|
||||
className="flex-1 bg-gradient-to-r from-purple-500 to-pink-500 hover:from-purple-600 hover:to-pink-600 disabled:opacity-50 disabled:cursor-not-allowed h-8 text-xs"
|
||||
>
|
||||
{creatingSupplier ? (
|
||||
@ -1772,7 +1938,7 @@ export function DirectSupplyCreation({
|
||||
<span>Добавление...</span>
|
||||
</div>
|
||||
) : (
|
||||
'Добавить'
|
||||
"Добавить"
|
||||
)}
|
||||
</Button>
|
||||
</div>
|
||||
|
Reference in New Issue
Block a user