a lot of
This commit is contained in:
@ -106,6 +106,7 @@ model Organization {
|
|||||||
supplyOrders SupplyOrder[]
|
supplyOrders SupplyOrder[]
|
||||||
partnerSupplyOrders SupplyOrder[] @relation("SupplyOrderPartner")
|
partnerSupplyOrders SupplyOrder[] @relation("SupplyOrderPartner")
|
||||||
fulfillmentSupplyOrders SupplyOrder[] @relation("SupplyOrderFulfillmentCenter")
|
fulfillmentSupplyOrders SupplyOrder[] @relation("SupplyOrderFulfillmentCenter")
|
||||||
|
logisticsSupplyOrders SupplyOrder[] @relation("SupplyOrderLogistics")
|
||||||
wildberriesSupplies WildberriesSupply[]
|
wildberriesSupplies WildberriesSupply[]
|
||||||
supplySuppliers SupplySupplier[] @relation("SupplySuppliers")
|
supplySuppliers SupplySupplier[] @relation("SupplySuppliers")
|
||||||
externalAds ExternalAd[] @relation("ExternalAds")
|
externalAds ExternalAd[] @relation("ExternalAds")
|
||||||
@ -472,6 +473,7 @@ model SupplyOrder {
|
|||||||
totalAmount Decimal @db.Decimal(12, 2)
|
totalAmount Decimal @db.Decimal(12, 2)
|
||||||
totalItems Int
|
totalItems Int
|
||||||
fulfillmentCenterId String?
|
fulfillmentCenterId String?
|
||||||
|
logisticsPartnerId String?
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
organizationId String
|
organizationId String
|
||||||
@ -479,6 +481,7 @@ model SupplyOrder {
|
|||||||
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
||||||
partner Organization @relation("SupplyOrderPartner", fields: [partnerId], references: [id])
|
partner Organization @relation("SupplyOrderPartner", fields: [partnerId], references: [id])
|
||||||
fulfillmentCenter Organization? @relation("SupplyOrderFulfillmentCenter", fields: [fulfillmentCenterId], references: [id])
|
fulfillmentCenter Organization? @relation("SupplyOrderFulfillmentCenter", fields: [fulfillmentCenterId], references: [id])
|
||||||
|
logisticsPartner Organization? @relation("SupplyOrderLogistics", fields: [logisticsPartnerId], references: [id])
|
||||||
|
|
||||||
@@map("supply_orders")
|
@@map("supply_orders")
|
||||||
}
|
}
|
||||||
|
@ -83,6 +83,8 @@ export function CreateFulfillmentConsumablesSupplyPage() {
|
|||||||
const { user } = useAuth();
|
const { user } = useAuth();
|
||||||
const [selectedSupplier, setSelectedSupplier] =
|
const [selectedSupplier, setSelectedSupplier] =
|
||||||
useState<FulfillmentConsumableSupplier | null>(null);
|
useState<FulfillmentConsumableSupplier | null>(null);
|
||||||
|
const [selectedLogistics, setSelectedLogistics] =
|
||||||
|
useState<FulfillmentConsumableSupplier | null>(null);
|
||||||
const [selectedConsumables, setSelectedConsumables] = useState<
|
const [selectedConsumables, setSelectedConsumables] = useState<
|
||||||
SelectedFulfillmentConsumable[]
|
SelectedFulfillmentConsumable[]
|
||||||
>([]);
|
>([]);
|
||||||
@ -113,6 +115,11 @@ export function CreateFulfillmentConsumablesSupplyPage() {
|
|||||||
counterpartiesData?.myCounterparties || []
|
counterpartiesData?.myCounterparties || []
|
||||||
).filter((org: FulfillmentConsumableSupplier) => org.type === "WHOLESALE");
|
).filter((org: FulfillmentConsumableSupplier) => org.type === "WHOLESALE");
|
||||||
|
|
||||||
|
// Фильтруем только логистические компании
|
||||||
|
const logisticsPartners = (
|
||||||
|
counterpartiesData?.myCounterparties || []
|
||||||
|
).filter((org: FulfillmentConsumableSupplier) => org.type === "LOGIST");
|
||||||
|
|
||||||
// Фильтруем поставщиков по поисковому запросу
|
// Фильтруем поставщиков по поисковому запросу
|
||||||
const filteredSuppliers = consumableSuppliers.filter(
|
const filteredSuppliers = consumableSuppliers.filter(
|
||||||
(supplier: FulfillmentConsumableSupplier) =>
|
(supplier: FulfillmentConsumableSupplier) =>
|
||||||
@ -258,6 +265,7 @@ export function CreateFulfillmentConsumablesSupplyPage() {
|
|||||||
deliveryDate: deliveryDate,
|
deliveryDate: deliveryDate,
|
||||||
// Для фулфилмента указываем себя как получателя (поставка на свой склад)
|
// Для фулфилмента указываем себя как получателя (поставка на свой склад)
|
||||||
fulfillmentCenterId: user?.organization?.id,
|
fulfillmentCenterId: user?.organization?.id,
|
||||||
|
logisticsPartnerId: selectedLogistics?.id,
|
||||||
items: selectedConsumables.map((consumable) => ({
|
items: selectedConsumables.map((consumable) => ({
|
||||||
productId: consumable.id,
|
productId: consumable.id,
|
||||||
quantity: consumable.selectedQuantity,
|
quantity: consumable.selectedQuantity,
|
||||||
@ -784,6 +792,42 @@ export function CreateFulfillmentConsumablesSupplyPage() {
|
|||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Выбор логистики */}
|
||||||
|
<div className="mb-3">
|
||||||
|
<label className="text-white/60 text-xs mb-1 block">
|
||||||
|
Логистика (опционально):
|
||||||
|
</label>
|
||||||
|
<div className="relative">
|
||||||
|
<select
|
||||||
|
value={selectedLogistics?.id || ""}
|
||||||
|
onChange={(e) => {
|
||||||
|
const logisticsId = e.target.value;
|
||||||
|
const logistics = logisticsPartners.find(p => p.id === logisticsId);
|
||||||
|
setSelectedLogistics(logistics || null);
|
||||||
|
}}
|
||||||
|
className="w-full bg-white/10 border border-white/20 rounded-md px-3 py-2 text-white text-sm focus:outline-none focus:ring-1 focus:ring-purple-500 focus:border-transparent appearance-none"
|
||||||
|
>
|
||||||
|
<option value="" className="bg-gray-800 text-white">
|
||||||
|
Без логистики
|
||||||
|
</option>
|
||||||
|
{logisticsPartners.map((partner) => (
|
||||||
|
<option
|
||||||
|
key={partner.id}
|
||||||
|
value={partner.id}
|
||||||
|
className="bg-gray-800 text-white"
|
||||||
|
>
|
||||||
|
{partner.name || partner.fullName || partner.inn}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
<div className="absolute inset-y-0 right-0 flex items-center px-2 pointer-events-none">
|
||||||
|
<svg className="w-4 h-4 text-white/60" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div className="flex items-center justify-between mb-3">
|
<div className="flex items-center justify-between mb-3">
|
||||||
<span className="text-white font-semibold text-sm">
|
<span className="text-white font-semibold text-sm">
|
||||||
Итого:
|
Итого:
|
||||||
|
@ -16,8 +16,8 @@ import {
|
|||||||
import { DeliveryDetailsProps } from "./types";
|
import { DeliveryDetailsProps } from "./types";
|
||||||
|
|
||||||
const DELIVERY_STATUS_CONFIG = {
|
const DELIVERY_STATUS_CONFIG = {
|
||||||
delivered: {
|
"in-stock": {
|
||||||
label: "Доставлено",
|
label: "На складе",
|
||||||
color: "bg-green-500/20 text-green-300",
|
color: "bg-green-500/20 text-green-300",
|
||||||
icon: CheckCircle,
|
icon: CheckCircle,
|
||||||
},
|
},
|
||||||
@ -26,6 +26,22 @@ const DELIVERY_STATUS_CONFIG = {
|
|||||||
color: "bg-blue-500/20 text-blue-300",
|
color: "bg-blue-500/20 text-blue-300",
|
||||||
icon: Truck,
|
icon: Truck,
|
||||||
},
|
},
|
||||||
|
confirmed: {
|
||||||
|
label: "Подтверждено",
|
||||||
|
color: "bg-cyan-500/20 text-cyan-300",
|
||||||
|
icon: CheckCircle,
|
||||||
|
},
|
||||||
|
planned: {
|
||||||
|
label: "Запланировано",
|
||||||
|
color: "bg-yellow-500/20 text-yellow-300",
|
||||||
|
icon: Clock,
|
||||||
|
},
|
||||||
|
// Обратная совместимость
|
||||||
|
delivered: {
|
||||||
|
label: "Доставлено",
|
||||||
|
color: "bg-green-500/20 text-green-300",
|
||||||
|
icon: CheckCircle,
|
||||||
|
},
|
||||||
pending: {
|
pending: {
|
||||||
label: "Ожидание",
|
label: "Ожидание",
|
||||||
color: "bg-yellow-500/20 text-yellow-300",
|
color: "bg-yellow-500/20 text-yellow-300",
|
||||||
|
@ -32,6 +32,27 @@ import {
|
|||||||
|
|
||||||
// Статусы расходников с цветами
|
// Статусы расходников с цветами
|
||||||
const STATUS_CONFIG = {
|
const STATUS_CONFIG = {
|
||||||
|
"in-stock": {
|
||||||
|
label: "Доступен",
|
||||||
|
color: "bg-green-500/20 text-green-300",
|
||||||
|
icon: CheckCircle,
|
||||||
|
},
|
||||||
|
"in-transit": {
|
||||||
|
label: "В пути",
|
||||||
|
color: "bg-blue-500/20 text-blue-300",
|
||||||
|
icon: Clock,
|
||||||
|
},
|
||||||
|
confirmed: {
|
||||||
|
label: "Подтверждено",
|
||||||
|
color: "bg-cyan-500/20 text-cyan-300",
|
||||||
|
icon: CheckCircle,
|
||||||
|
},
|
||||||
|
planned: {
|
||||||
|
label: "Запланировано",
|
||||||
|
color: "bg-yellow-500/20 text-yellow-300",
|
||||||
|
icon: Clock,
|
||||||
|
},
|
||||||
|
// Обратная совместимость и специальные статусы
|
||||||
available: {
|
available: {
|
||||||
label: "Доступен",
|
label: "Доступен",
|
||||||
color: "bg-green-500/20 text-green-300",
|
color: "bg-green-500/20 text-green-300",
|
||||||
@ -47,11 +68,6 @@ const STATUS_CONFIG = {
|
|||||||
color: "bg-red-500/20 text-red-300",
|
color: "bg-red-500/20 text-red-300",
|
||||||
icon: AlertTriangle,
|
icon: AlertTriangle,
|
||||||
},
|
},
|
||||||
"in-transit": {
|
|
||||||
label: "В пути",
|
|
||||||
color: "bg-blue-500/20 text-blue-300",
|
|
||||||
icon: Clock,
|
|
||||||
},
|
|
||||||
reserved: {
|
reserved: {
|
||||||
label: "Зарезервирован",
|
label: "Зарезервирован",
|
||||||
color: "bg-purple-500/20 text-purple-300",
|
color: "bg-purple-500/20 text-purple-300",
|
||||||
|
@ -477,6 +477,7 @@ export function FulfillmentWarehouseDashboard() {
|
|||||||
supplyOrders,
|
supplyOrders,
|
||||||
allProducts,
|
allProducts,
|
||||||
mySupplies,
|
mySupplies,
|
||||||
|
myFulfillmentSupplies,
|
||||||
suppliesReceivedToday,
|
suppliesReceivedToday,
|
||||||
suppliesUsedToday,
|
suppliesUsedToday,
|
||||||
productsReceivedToday,
|
productsReceivedToday,
|
||||||
|
@ -15,7 +15,6 @@ export function SuppliesGrid({
|
|||||||
return (
|
return (
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
|
||||||
{supplies.map((supply) => {
|
{supplies.map((supply) => {
|
||||||
const statusConfig = getStatusConfig(supply.status);
|
|
||||||
const isExpanded = expandedSupplies.has(supply.id);
|
const isExpanded = expandedSupplies.has(supply.id);
|
||||||
const deliveries = getSupplyDeliveries(supply);
|
const deliveries = getSupplyDeliveries(supply);
|
||||||
|
|
||||||
@ -26,7 +25,6 @@ export function SuppliesGrid({
|
|||||||
supply={supply}
|
supply={supply}
|
||||||
isExpanded={isExpanded}
|
isExpanded={isExpanded}
|
||||||
onToggleExpansion={onToggleExpansion}
|
onToggleExpansion={onToggleExpansion}
|
||||||
statusConfig={statusConfig}
|
|
||||||
getSupplyDeliveries={getSupplyDeliveries}
|
getSupplyDeliveries={getSupplyDeliveries}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
@ -18,7 +18,6 @@ export function SupplyCard({
|
|||||||
supply,
|
supply,
|
||||||
isExpanded,
|
isExpanded,
|
||||||
onToggleExpansion,
|
onToggleExpansion,
|
||||||
statusConfig,
|
|
||||||
getSupplyDeliveries,
|
getSupplyDeliveries,
|
||||||
}: SupplyCardProps) {
|
}: SupplyCardProps) {
|
||||||
const formatCurrency = (amount: number) => {
|
const formatCurrency = (amount: number) => {
|
||||||
@ -33,7 +32,6 @@ export function SupplyCard({
|
|||||||
return new Intl.NumberFormat("ru-RU").format(num);
|
return new Intl.NumberFormat("ru-RU").format(num);
|
||||||
};
|
};
|
||||||
|
|
||||||
const StatusIcon = statusConfig.icon;
|
|
||||||
const isLowStock =
|
const isLowStock =
|
||||||
supply.currentStock <= supply.minStock && supply.currentStock > 0;
|
supply.currentStock <= supply.minStock && supply.currentStock > 0;
|
||||||
const stockPercentage =
|
const stockPercentage =
|
||||||
@ -58,12 +56,6 @@ export function SupplyCard({
|
|||||||
{supply.description}
|
{supply.description}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center space-x-2 ml-2">
|
|
||||||
<Badge className={`${statusConfig.color} text-xs`}>
|
|
||||||
<StatusIcon className="h-3 w-3 mr-1" />
|
|
||||||
{statusConfig.label}
|
|
||||||
</Badge>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Основная информация */}
|
{/* Основная информация */}
|
||||||
|
@ -54,7 +54,6 @@ export interface SupplyCardProps {
|
|||||||
supply: Supply;
|
supply: Supply;
|
||||||
isExpanded: boolean;
|
isExpanded: boolean;
|
||||||
onToggleExpansion: (id: string) => void;
|
onToggleExpansion: (id: string) => void;
|
||||||
statusConfig: StatusConfig;
|
|
||||||
getSupplyDeliveries: (supply: Supply) => Supply[];
|
getSupplyDeliveries: (supply: Supply) => Supply[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -728,33 +728,57 @@ export const resolvers = {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Получаем расходники селлеров из таблицы supply
|
// Получаем ВСЕ расходники из таблицы supply для фулфилмента
|
||||||
// Это расходники, созданные при доставке заказов от селлеров
|
const allSupplies = await prisma.supply.findMany({
|
||||||
const existingSupplies = await prisma.supply.findMany({
|
|
||||||
where: { organizationId: currentUser.organization.id },
|
where: { organizationId: currentUser.organization.id },
|
||||||
include: { organization: true },
|
include: { organization: true },
|
||||||
orderBy: { createdAt: "desc" },
|
orderBy: { createdAt: "desc" },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Получаем все заказы фулфилмента для себя (чтобы исключить их расходники)
|
||||||
|
const fulfillmentOwnOrders = await prisma.supplyOrder.findMany({
|
||||||
|
where: {
|
||||||
|
organizationId: currentUser.organization.id, // Созданы фулфилментом
|
||||||
|
fulfillmentCenterId: currentUser.organization.id, // Для себя
|
||||||
|
status: "DELIVERED",
|
||||||
|
},
|
||||||
|
include: {
|
||||||
|
items: {
|
||||||
|
include: {
|
||||||
|
product: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Создаем набор названий товаров из заказов фулфилмента для себя
|
||||||
|
const fulfillmentProductNames = new Set(
|
||||||
|
fulfillmentOwnOrders.flatMap((order) =>
|
||||||
|
order.items.map((item) => item.product.name)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Фильтруем расходники: исключаем те, что созданы заказами фулфилмента для себя
|
||||||
|
const sellerSupplies = allSupplies.filter((supply) => {
|
||||||
|
// Если расходник соответствует товару из заказа фулфилмента для себя,
|
||||||
|
// то это расходник фулфилмента, а не селлера
|
||||||
|
return !fulfillmentProductNames.has(supply.name);
|
||||||
|
});
|
||||||
|
|
||||||
// Логирование для отладки
|
// Логирование для отладки
|
||||||
console.log("🔥🔥🔥 SELLER SUPPLIES RESOLVER CALLED 🔥🔥🔥");
|
console.log("🔥🔥🔥 SELLER SUPPLIES RESOLVER CALLED 🔥🔥🔥");
|
||||||
console.log("📊 Расходники селлеров:", {
|
console.log("📊 Расходники селлеров:", {
|
||||||
organizationId: currentUser.organization.id,
|
organizationId: currentUser.organization.id,
|
||||||
organizationType: currentUser.organization.type,
|
organizationType: currentUser.organization.type,
|
||||||
existingSuppliesCount: existingSupplies.length,
|
allSuppliesCount: allSupplies.length,
|
||||||
|
fulfillmentOwnOrdersCount: fulfillmentOwnOrders.length,
|
||||||
|
fulfillmentProductNames: Array.from(fulfillmentProductNames),
|
||||||
|
filteredSellerSuppliesCount: sellerSupplies.length,
|
||||||
sellerOrdersCount: sellerSupplyOrders.length,
|
sellerOrdersCount: sellerSupplyOrders.length,
|
||||||
sellerOrders: sellerSupplyOrders.map((o) => ({
|
|
||||||
id: o.id,
|
|
||||||
sellerName: o.organization.name,
|
|
||||||
supplierName: o.partner.name,
|
|
||||||
status: o.status,
|
|
||||||
itemsCount: o.items.length,
|
|
||||||
})),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Возвращаем только расходники селлеров из таблицы supply
|
// Возвращаем только расходники селлеров (исключая расходники фулфилмента)
|
||||||
// TODO: В будущем можно добавить фильтрацию по источнику заказа
|
return sellerSupplies;
|
||||||
return existingSupplies;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// Расходники фулфилмента (материалы для работы фулфилмента)
|
// Расходники фулфилмента (материалы для работы фулфилмента)
|
||||||
@ -818,12 +842,14 @@ export const resolvers = {
|
|||||||
category: item.product.category?.name || "Расходники фулфилмента",
|
category: item.product.category?.name || "Расходники фулфилмента",
|
||||||
status:
|
status:
|
||||||
order.status === "PENDING"
|
order.status === "PENDING"
|
||||||
? "in-transit"
|
? "planned"
|
||||||
: order.status === "CONFIRMED"
|
: order.status === "CONFIRMED"
|
||||||
? "in-transit"
|
? "confirmed"
|
||||||
: order.status === "IN_TRANSIT"
|
: order.status === "IN_TRANSIT"
|
||||||
? "in-transit"
|
? "in-transit"
|
||||||
: "available",
|
: order.status === "DELIVERED"
|
||||||
|
? "in-stock"
|
||||||
|
: "planned",
|
||||||
date: order.createdAt,
|
date: order.createdAt,
|
||||||
supplier: order.partner.name || order.partner.fullName || "Не указан",
|
supplier: order.partner.name || order.partner.fullName || "Не указан",
|
||||||
minStock: Math.round(item.quantity * 0.1),
|
minStock: Math.round(item.quantity * 0.1),
|
||||||
@ -3751,6 +3777,7 @@ export const resolvers = {
|
|||||||
totalItems: totalItems,
|
totalItems: totalItems,
|
||||||
organizationId: currentUser.organization.id,
|
organizationId: currentUser.organization.id,
|
||||||
fulfillmentCenterId: fulfillmentCenterId,
|
fulfillmentCenterId: fulfillmentCenterId,
|
||||||
|
logisticsPartnerId: args.input.logisticsPartnerId,
|
||||||
status: initialStatus,
|
status: initialStatus,
|
||||||
items: {
|
items: {
|
||||||
create: orderItems,
|
create: orderItems,
|
||||||
@ -3772,6 +3799,11 @@ export const resolvers = {
|
|||||||
users: true,
|
users: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
logisticsPartner: {
|
||||||
|
include: {
|
||||||
|
users: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
items: {
|
items: {
|
||||||
include: {
|
include: {
|
||||||
product: {
|
product: {
|
||||||
@ -3803,7 +3835,7 @@ export const resolvers = {
|
|||||||
quantity: item.quantity,
|
quantity: item.quantity,
|
||||||
unit: "шт",
|
unit: "шт",
|
||||||
category: productWithCategory?.category?.name || "Расходники",
|
category: productWithCategory?.category?.name || "Расходники",
|
||||||
status: "in-transit", // Статус "в пути" так как заказ только создан
|
status: "planned", // Статус "запланировано" (ожидает одобрения поставщиком)
|
||||||
date: new Date(args.input.deliveryDate),
|
date: new Date(args.input.deliveryDate),
|
||||||
supplier: partner.name || partner.fullName || "Не указан",
|
supplier: partner.name || partner.fullName || "Не указан",
|
||||||
minStock: Math.round(item.quantity * 0.1), // 10% от заказанного как минимальный остаток
|
minStock: Math.round(item.quantity * 0.1), // 10% от заказанного как минимальный остаток
|
||||||
@ -5288,10 +5320,53 @@ export const resolvers = {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Если статус изменился на DELIVERED, обновляем склад фулфилмента
|
// Обновляем статусы расходников в зависимости от статуса заказа
|
||||||
if (args.status === "DELIVERED" && existingOrder.fulfillmentCenterId) {
|
const targetOrganizationId = existingOrder.fulfillmentCenterId || existingOrder.organizationId;
|
||||||
console.log("🚚 Обновляем склад фулфилмента:", {
|
|
||||||
|
if (args.status === "CONFIRMED") {
|
||||||
|
// При подтверждении поставщиком - переводим расходники в статус "confirmed"
|
||||||
|
await prisma.supply.updateMany({
|
||||||
|
where: {
|
||||||
|
organizationId: targetOrganizationId,
|
||||||
|
status: "planned",
|
||||||
|
// Находим расходники по названиям товаров из заказа
|
||||||
|
name: {
|
||||||
|
in: existingOrder.items.map(item => item.product.name)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
status: "confirmed"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("✅ Статусы расходников обновлены на 'confirmed'");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.status === "IN_TRANSIT") {
|
||||||
|
// При отгрузке - переводим расходники в статус "in-transit"
|
||||||
|
await prisma.supply.updateMany({
|
||||||
|
where: {
|
||||||
|
organizationId: targetOrganizationId,
|
||||||
|
status: "confirmed",
|
||||||
|
name: {
|
||||||
|
in: existingOrder.items.map(item => item.product.name)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
status: "in-transit"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("✅ Статусы расходников обновлены на 'in-transit'");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Если статус изменился на DELIVERED, обновляем склад
|
||||||
|
if (args.status === "DELIVERED") {
|
||||||
|
|
||||||
|
console.log("🚚 Обновляем склад организации:", {
|
||||||
|
targetOrganizationId,
|
||||||
fulfillmentCenterId: existingOrder.fulfillmentCenterId,
|
fulfillmentCenterId: existingOrder.fulfillmentCenterId,
|
||||||
|
organizationId: existingOrder.organizationId,
|
||||||
itemsCount: existingOrder.items.length,
|
itemsCount: existingOrder.items.length,
|
||||||
items: existingOrder.items.map((item) => ({
|
items: existingOrder.items.map((item) => ({
|
||||||
productName: item.product.name,
|
productName: item.product.name,
|
||||||
@ -5299,19 +5374,19 @@ export const resolvers = {
|
|||||||
})),
|
})),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Обновляем расходники фулфилмента
|
// Обновляем расходники
|
||||||
for (const item of existingOrder.items) {
|
for (const item of existingOrder.items) {
|
||||||
console.log("📦 Обрабатываем товар:", {
|
console.log("📦 Обрабатываем товар:", {
|
||||||
productName: item.product.name,
|
productName: item.product.name,
|
||||||
quantity: item.quantity,
|
quantity: item.quantity,
|
||||||
fulfillmentCenterId: existingOrder.fulfillmentCenterId,
|
targetOrganizationId,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Ищем существующий расходник
|
// Ищем существующий расходник в правильной организации
|
||||||
const existingSupply = await prisma.supply.findFirst({
|
const existingSupply = await prisma.supply.findFirst({
|
||||||
where: {
|
where: {
|
||||||
name: item.product.name,
|
name: item.product.name,
|
||||||
organizationId: existingOrder.fulfillmentCenterId,
|
organizationId: targetOrganizationId,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -5329,14 +5404,14 @@ export const resolvers = {
|
|||||||
where: { id: existingSupply.id },
|
where: { id: existingSupply.id },
|
||||||
data: {
|
data: {
|
||||||
currentStock: existingSupply.currentStock + item.quantity,
|
currentStock: existingSupply.currentStock + item.quantity,
|
||||||
status: "available", // Меняем статус на "доступен"
|
status: "in-stock", // Меняем статус на "на складе"
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
console.log("➕ Создаем новый расходник:", {
|
console.log("➕ Создаем новый расходник:", {
|
||||||
name: item.product.name,
|
name: item.product.name,
|
||||||
quantity: item.quantity,
|
quantity: item.quantity,
|
||||||
organizationId: existingOrder.fulfillmentCenterId,
|
organizationId: targetOrganizationId,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Создаем новый расходник
|
// Создаем новый расходник
|
||||||
@ -5350,7 +5425,7 @@ export const resolvers = {
|
|||||||
quantity: item.quantity,
|
quantity: item.quantity,
|
||||||
unit: "шт",
|
unit: "шт",
|
||||||
category: item.product.category?.name || "Расходники",
|
category: item.product.category?.name || "Расходники",
|
||||||
status: "available",
|
status: "in-stock",
|
||||||
date: new Date(),
|
date: new Date(),
|
||||||
supplier:
|
supplier:
|
||||||
existingOrder.partner.name ||
|
existingOrder.partner.name ||
|
||||||
@ -5358,7 +5433,7 @@ export const resolvers = {
|
|||||||
"Не указан",
|
"Не указан",
|
||||||
minStock: Math.round(item.quantity * 0.1),
|
minStock: Math.round(item.quantity * 0.1),
|
||||||
currentStock: item.quantity,
|
currentStock: item.quantity,
|
||||||
organizationId: existingOrder.fulfillmentCenterId,
|
organizationId: targetOrganizationId,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -5370,7 +5445,7 @@ export const resolvers = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("🎉 Склад фулфилмента успешно обновлен!");
|
console.log("🎉 Склад организации успешно обновлен!");
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
Reference in New Issue
Block a user