diff --git a/seller_supply_migration.sql b/seller_supply_migration.sql new file mode 100644 index 0000000..60116cc --- /dev/null +++ b/seller_supply_migration.sql @@ -0,0 +1,151 @@ +-- ============================================================================= +-- 📦 МИГРАЦИЯ ДЛЯ СИСТЕМЫ ПОСТАВОК РАСХОДНИКОВ СЕЛЛЕРА +-- ============================================================================= +-- Создание: Новые таблицы для селлерских поставок расходников +-- Автор: Claude Code AI Assistant +-- Дата: $(date) + +-- Создание нового enum для статусов селлера (5-статусная система) +CREATE TYPE "SellerSupplyOrderStatus" AS ENUM ( + 'PENDING', -- Ожидает одобрения поставщика + 'APPROVED', -- Одобрено поставщиком + 'SHIPPED', -- Отгружено + 'DELIVERED', -- Доставлено + 'COMPLETED', -- Завершено + 'CANCELLED' -- Отменено +); + +-- Основная таблица поставок расходников селлера +CREATE TABLE "seller_consumable_supply_orders" ( + -- === БАЗОВЫЕ ПОЛЯ === + "id" TEXT NOT NULL, + "status" "SellerSupplyOrderStatus" NOT NULL DEFAULT 'PENDING', + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + -- === ДАННЫЕ СЕЛЛЕРА (создатель) === + "sellerId" TEXT NOT NULL, -- кто заказывает (FK: Organization SELLER) + "fulfillmentCenterId" TEXT NOT NULL, -- куда доставлять (FK: Organization FULFILLMENT) + "requestedDeliveryDate" TIMESTAMP(3) NOT NULL, -- когда нужно + "notes" TEXT, -- заметки селлера + + -- === ДАННЫЕ ПОСТАВЩИКА === + "supplierId" TEXT, -- кто поставляет (FK: Organization WHOLESALE) + "supplierApprovedAt" TIMESTAMP(3), -- когда одобрил + "packagesCount" INTEGER, -- количество грузомест + "estimatedVolume" DECIMAL(8,3), -- объем груза в м³ + "supplierContractId" TEXT, -- номер договора + "supplierNotes" TEXT, -- заметки поставщика + + -- === ДАННЫЕ ЛОГИСТИКИ === + "logisticsPartnerId" TEXT, -- кто везет (FK: Organization LOGIST) + "estimatedDeliveryDate" TIMESTAMP(3), -- план доставки + "routeId" TEXT, -- маршрут (FK: LogisticsRoute) + "logisticsCost" DECIMAL(10,2), -- стоимость доставки + "logisticsNotes" TEXT, -- заметки логистики + + -- === ДАННЫЕ ОТГРУЗКИ === + "shippedAt" TIMESTAMP(3), -- факт отгрузки + "trackingNumber" TEXT, -- номер отслеживания + + -- === ДАННЫЕ ПРИЕМКИ === + "deliveredAt" TIMESTAMP(3), -- факт доставки в ФФ + "receivedById" TEXT, -- кто принял в ФФ (FK: User) + "actualQuantity" INTEGER, -- принято количество + "defectQuantity" INTEGER, -- брак + "receiptNotes" TEXT, -- заметки приемки + + -- === ЭКОНОМИКА (для будущего раздела экономики) === + "totalCostWithDelivery" DECIMAL(12,2), -- общая стоимость с доставкой + "estimatedStorageCost" DECIMAL(10,2), -- оценочная стоимость хранения + + CONSTRAINT "seller_consumable_supply_orders_pkey" PRIMARY KEY ("id") +); + +-- Позиции в поставке расходников селлера +CREATE TABLE "seller_consumable_supply_items" ( + "id" TEXT NOT NULL, + "supplyOrderId" TEXT NOT NULL, -- связь с поставкой + "productId" TEXT NOT NULL, -- какой расходник (FK: Product) + + -- === КОЛИЧЕСТВА === + "requestedQuantity" INTEGER NOT NULL, -- запросили + "approvedQuantity" INTEGER, -- поставщик одобрил + "shippedQuantity" INTEGER, -- отгрузили + "receivedQuantity" INTEGER, -- приняли в ФФ + "defectQuantity" INTEGER DEFAULT 0, -- брак + + -- === ЦЕНЫ === + "unitPrice" DECIMAL(10,2) NOT NULL, -- цена за единицу от поставщика + "totalPrice" DECIMAL(12,2) NOT NULL, -- общая стоимость + + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "seller_consumable_supply_items_pkey" PRIMARY KEY ("id") +); + +-- === СОЗДАНИЕ ИНДЕКСОВ === +CREATE UNIQUE INDEX "seller_consumable_supply_items_supplyOrderId_productId_key" +ON "seller_consumable_supply_items"("supplyOrderId", "productId"); + +-- === СОЗДАНИЕ ВНЕШНИХ КЛЮЧЕЙ === + +-- Seller Supply Orders связи +ALTER TABLE "seller_consumable_supply_orders" +ADD CONSTRAINT "seller_consumable_supply_orders_sellerId_fkey" +FOREIGN KEY ("sellerId") REFERENCES "organizations"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +ALTER TABLE "seller_consumable_supply_orders" +ADD CONSTRAINT "seller_consumable_supply_orders_fulfillmentCenterId_fkey" +FOREIGN KEY ("fulfillmentCenterId") REFERENCES "organizations"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +ALTER TABLE "seller_consumable_supply_orders" +ADD CONSTRAINT "seller_consumable_supply_orders_supplierId_fkey" +FOREIGN KEY ("supplierId") REFERENCES "organizations"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +ALTER TABLE "seller_consumable_supply_orders" +ADD CONSTRAINT "seller_consumable_supply_orders_logisticsPartnerId_fkey" +FOREIGN KEY ("logisticsPartnerId") REFERENCES "organizations"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +ALTER TABLE "seller_consumable_supply_orders" +ADD CONSTRAINT "seller_consumable_supply_orders_receivedById_fkey" +FOREIGN KEY ("receivedById") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- Seller Supply Items связи +ALTER TABLE "seller_consumable_supply_items" +ADD CONSTRAINT "seller_consumable_supply_items_supplyOrderId_fkey" +FOREIGN KEY ("supplyOrderId") REFERENCES "seller_consumable_supply_orders"("id") ON DELETE CASCADE; + +ALTER TABLE "seller_consumable_supply_items" +ADD CONSTRAINT "seller_consumable_supply_items_productId_fkey" +FOREIGN KEY ("productId") REFERENCES "products"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- === ДОБАВЛЕНИЕ СВЯЗЕЙ В СУЩЕСТВУЮЩИЕ ТАБЛИЦЫ === + +-- Добавление связей в organizations (если они еще не существуют) +DO $$ +BEGIN + -- Проверяем существование колонок перед добавлением + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_name = 'organizations' + AND column_name = 'sellerSupplyOrdersAsSeller' + ) THEN + -- Добавляем связи будут созданы автоматически через Prisma при следующем generate + RAISE NOTICE 'Связи для селлерских поставок будут созданы автоматически при prisma generate'; + END IF; +END +$$; + +-- Комментарии к таблицам +COMMENT ON TABLE "seller_consumable_supply_orders" IS 'Поставки расходников селлера - заказы от селлеров для доставки в фулфилмент-центры'; +COMMENT ON TABLE "seller_consumable_supply_items" IS 'Позиции в поставках расходников селлера'; + +-- Комментарии к ключевым полям +COMMENT ON COLUMN "seller_consumable_supply_orders"."sellerId" IS 'Селлер-заказчик (тип SELLER)'; +COMMENT ON COLUMN "seller_consumable_supply_orders"."fulfillmentCenterId" IS 'Фулфилмент-получатель (тип FULFILLMENT)'; +COMMENT ON COLUMN "seller_consumable_supply_orders"."supplierId" IS 'Поставщик товаров (тип WHOLESALE)'; +COMMENT ON COLUMN "seller_consumable_supply_orders"."totalCostWithDelivery" IS 'Для будущего раздела экономики селлера'; + +RAISE NOTICE 'Система поставок расходников селлера успешно создана!'; \ No newline at end of file