"use client"; import React, { useState } from "react"; import { Sidebar } from "@/components/dashboard/sidebar"; import { useSidebar } from "@/hooks/useSidebar"; import { useRouter } from "next/navigation"; import { DirectSupplyCreation } from "./direct-supply-creation"; import { Card } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { useQuery } from "@apollo/client"; import { apolloClient } from "@/lib/apollo-client"; import { GET_MY_COUNTERPARTIES, GET_ORGANIZATION_LOGISTICS, } from "@/graphql/queries"; import { ArrowLeft, Package, CalendarIcon, Building } from "lucide-react"; // Компонент создания поставки товаров с новым интерфейсом interface Organization { id: string; name?: string; fullName?: string; type: string; } export function CreateSupplyPage() { const router = useRouter(); const { getSidebarMargin } = useSidebar(); const [canCreateSupply, setCanCreateSupply] = useState(false); const [isCreatingSupply, setIsCreatingSupply] = useState(false); // Состояния для полей формы const [deliveryDate, setDeliveryDate] = useState(""); const [selectedFulfillment, setSelectedFulfillment] = useState(""); const [goodsVolume, setGoodsVolume] = useState(0); const [cargoPlaces, setCargoPlaces] = useState(0); const [goodsPrice, setGoodsPrice] = useState(0); const [fulfillmentServicesPrice, setFulfillmentServicesPrice] = useState(0); const [logisticsPrice, setLogisticsPrice] = useState(0); const [selectedServicesCost, setSelectedServicesCost] = useState(0); const [selectedConsumablesCost, setSelectedConsumablesCost] = useState(0); const [hasItemsInSupply, setHasItemsInSupply] = useState(false); // Загружаем контрагентов-фулфилментов const { data: counterpartiesData } = useQuery(GET_MY_COUNTERPARTIES); // Фильтруем только фулфилмент организации const fulfillmentOrgs = (counterpartiesData?.myCounterparties || []).filter( (org: Organization) => org.type === "FULFILLMENT" ); const formatCurrency = (amount: number) => { return new Intl.NumberFormat("ru-RU", { style: "currency", currency: "RUB", minimumFractionDigits: 0, }).format(amount); }; // Функция для обновления цены товаров из поставки const handleItemsUpdate = (totalItemsPrice: number) => { setGoodsPrice(totalItemsPrice); }; // Функция для обновления статуса наличия товаров const handleItemsCountChange = (hasItems: boolean) => { setHasItemsInSupply(hasItems); }; // Функция для обновления объема товаров из поставки const handleVolumeUpdate = (totalVolume: number) => { setGoodsVolume(totalVolume); // После обновления объема пересчитываем логистику (если есть поставщик) // calculateLogisticsPrice будет вызван из handleSuppliersUpdate }; // Функция для обновления информации о поставщиках (для расчета логистики) const handleSuppliersUpdate = (suppliersData: unknown[]) => { // Находим рынок из выбранного поставщика const selectedSupplier = suppliersData.find( (supplier: unknown) => (supplier as { selected?: boolean }).selected ); const supplierMarket = (selectedSupplier as { market?: string })?.market; console.log("Обновление поставщиков:", { selectedSupplier, supplierMarket, volume: goodsVolume, }); // Пересчитываем логистику с учетом рынка поставщика calculateLogisticsPrice(goodsVolume, supplierMarket); }; // Функция для расчета логистики по рынку поставщика и объему const calculateLogisticsPrice = async ( volume: number, supplierMarket?: string ) => { // Логистика рассчитывается ТОЛЬКО если есть: // 1. Выбранный фулфилмент // 2. Объем товаров > 0 // 3. Рынок поставщика (откуда везти) if (!selectedFulfillment || !volume || volume <= 0 || !supplierMarket) { setLogisticsPrice(0); return; } try { console.log( `Расчет логистики: ${supplierMarket} → ${selectedFulfillment}, объем: ${volume.toFixed( 4 )} м³` ); // Получаем логистику выбранного фулфилмента из БД const { data: logisticsData } = await apolloClient.query({ query: GET_ORGANIZATION_LOGISTICS, variables: { organizationId: selectedFulfillment }, fetchPolicy: "network-only", }); const logistics = logisticsData?.organizationLogistics || []; console.log(`Логистика фулфилмента ${selectedFulfillment}:`, logistics); // Ищем логистику для данного рынка const logisticsRoute = logistics.find( (route: { fromLocation: string; toLocation: string; pricePerCubicMeter: number; }) => route.fromLocation .toLowerCase() .includes(supplierMarket.toLowerCase()) || supplierMarket .toLowerCase() .includes(route.fromLocation.toLowerCase()) ); if (!logisticsRoute) { console.log(`Логистика для рынка "${supplierMarket}" не найдена`); setLogisticsPrice(0); return; } // Выбираем цену в зависимости от объема const pricePerM3 = volume <= 1 ? logisticsRoute.priceUnder1m3 : logisticsRoute.priceOver1m3; const calculatedPrice = volume * pricePerM3; console.log( `Найдена логистика: ${logisticsRoute.fromLocation} → ${logisticsRoute.toLocation}` ); console.log( `Цена: ${pricePerM3}₽/м³ (${ volume <= 1 ? "до 1м³" : "больше 1м³" }) × ${volume.toFixed(4)}м³ = ${calculatedPrice.toFixed(2)}₽` ); setLogisticsPrice(calculatedPrice); } catch (error) { console.error("Error calculating logistics price:", error); setLogisticsPrice(0); } }; const getTotalSum = () => { return ( goodsPrice + selectedServicesCost + selectedConsumablesCost + logisticsPrice ); }; const handleSupplyComplete = () => { router.push("/supplies"); }; const handleCreateSupplyClick = () => { setIsCreatingSupply(true); }; const handleCanCreateSupplyChange = (canCreate: boolean) => { setCanCreateSupply(canCreate); }; // Пересчитываем логистику при изменении фулфилмента (если есть поставщик) React.useEffect(() => { // Логистика пересчитается автоматически через handleSuppliersUpdate // когда будет выбран поставщик с рынком }, [selectedFulfillment, goodsVolume]); const handleSupplyCompleted = () => { setIsCreatingSupply(false); handleSupplyComplete(); }; // Главная страница с табами в новом стиле интерфейса return (
{/* Заголовок */}

Создание поставки товаров

Выберите карточки товаров Wildberries для создания поставки

{/* Основной контент - карточки Wildberries */}
{/* Левая колонка - карточки товаров */}
{/* Правая колонка - Форма поставки */}

Параметры поставки

{/* Первая строка */}
{/* 1. Модуль выбора даты */}
setDeliveryDate(e.target.value)} className="w-full h-8 rounded-lg border-0 bg-white/20 backdrop-blur px-3 py-1 text-white placeholder:text-white/50 focus:bg-white/30 focus:outline-none focus:ring-1 focus:ring-white/20 text-xs font-medium" min={new Date().toISOString().split("T")[0]} />
{/* 2. Модуль выбора фулфилмента */}
{/* 3. Объём товаров (автоматически) */}
{goodsVolume > 0 ? `${goodsVolume.toFixed(2)} м³` : "Рассчитывается автоматически"}
{/* 4. Грузовые места */}
setCargoPlaces(parseInt(e.target.value) || 0) } placeholder="шт" className="h-8 bg-white/20 border-0 text-white placeholder:text-white/50 focus:bg-white/30 focus:ring-1 focus:ring-white/20 text-xs" />
{/* Вторая группа - цены */}
{/* 5. Цена товаров (автоматически) */}
{goodsPrice > 0 ? formatCurrency(goodsPrice) : "Рассчитывается автоматически"}
{/* 6. Цена услуг фулфилмента (автоматически) */}
{selectedServicesCost > 0 ? formatCurrency(selectedServicesCost) : "Выберите услуги"}
{/* 7. Цена расходников фулфилмента (автоматически) */}
{selectedConsumablesCost > 0 ? formatCurrency(selectedConsumablesCost) : "Выберите расходники"}
{/* 8. Цена логистики (автоматически) */}
{logisticsPrice > 0 ? formatCurrency(logisticsPrice) : "Выберите поставщика"}
{/* 9. Итоговая сумма */}
{formatCurrency(getTotalSum())}
{/* 10. Кнопка создания поставки */}
); }