-- =============================================================================
-- Миграция: логистика, дни продаж и этапы оплаты — на manufacturers
-- manufacturer_counterparty_map — только связь manufacturer_id + contractor_1c_id (из 1С)
--
-- ВАЖНО: Перед запуском выполнить migrate_map_to_contractor_1c.sql
--        (удаление counterparties, переход на contractor_1c_id)
--
-- ИСТОЧНИК: contractor_producer_mapping, contractor_producer_payment_stage
-- (сопоставление по v_contractors, v_producers → counterparties, manufacturers)
--
-- 1. manufacturers: добавить days_of_sales, logistics_days, roic_norm
-- 2. manufacturer_payment_stage: новая таблица, FK на manufacturers
-- 3. Миграция из contractor_producer_* в manufacturers, map, manufacturer_payment_stage
-- 4. manufacturer_counterparty_map: убрать days_of_sales, logistics_days, roic_norm (если есть)
-- 5. Удалить contractor_producer_*, manufacturer_counterparty_payment_stage
-- =============================================================================

USE [mag_pbi]
GO

SET NOCOUNT ON;

-- =============================================================================
-- 1. manufacturers: добавить days_of_sales, logistics_days, roic_norm
-- =============================================================================
IF NOT EXISTS (SELECT 1 FROM sys.columns WHERE object_id = OBJECT_ID(N'[analytics].[manufacturers]') AND name = 'days_of_sales')
    ALTER TABLE [analytics].[manufacturers] ADD [days_of_sales] INT NOT NULL DEFAULT 180;
IF NOT EXISTS (SELECT 1 FROM sys.columns WHERE object_id = OBJECT_ID(N'[analytics].[manufacturers]') AND name = 'logistics_days')
    ALTER TABLE [analytics].[manufacturers] ADD [logistics_days] INT NOT NULL DEFAULT 120;
IF NOT EXISTS (SELECT 1 FROM sys.columns WHERE object_id = OBJECT_ID(N'[analytics].[manufacturers]') AND name = 'roic_norm')
    ALTER TABLE [analytics].[manufacturers] ADD [roic_norm] DECIMAL(12,4) NULL;

-- Миграция из manufacturers.ROI_norm (если ещё не удалена, roic_norm уже добавлена)
IF EXISTS (SELECT 1 FROM sys.columns WHERE object_id = OBJECT_ID(N'[analytics].[manufacturers]') AND name = 'ROI_norm')
   AND EXISTS (SELECT 1 FROM sys.columns WHERE object_id = OBJECT_ID(N'[analytics].[manufacturers]') AND name = 'roic_norm')
BEGIN
    UPDATE [analytics].[manufacturers] SET [roic_norm] = [ROI_norm] WHERE [roic_norm] IS NULL AND [ROI_norm] IS NOT NULL;
END

-- Удалить старые поля manufacturers (n_percent, n_days, m_percent, m_days, ROI_norm)
IF EXISTS (SELECT 1 FROM sys.columns WHERE object_id = OBJECT_ID(N'[analytics].[manufacturers]') AND name = 'ROI_norm')
    ALTER TABLE [analytics].[manufacturers] DROP COLUMN [ROI_norm];
IF EXISTS (SELECT 1 FROM sys.columns WHERE object_id = OBJECT_ID(N'[analytics].[manufacturers]') AND name = 'n_percent')
    ALTER TABLE [analytics].[manufacturers] DROP COLUMN [n_percent];
IF EXISTS (SELECT 1 FROM sys.columns WHERE object_id = OBJECT_ID(N'[analytics].[manufacturers]') AND name = 'n_days')
    ALTER TABLE [analytics].[manufacturers] DROP COLUMN [n_days];
IF EXISTS (SELECT 1 FROM sys.columns WHERE object_id = OBJECT_ID(N'[analytics].[manufacturers]') AND name = 'm_percent')
    ALTER TABLE [analytics].[manufacturers] DROP COLUMN [m_percent];
IF EXISTS (SELECT 1 FROM sys.columns WHERE object_id = OBJECT_ID(N'[analytics].[manufacturers]') AND name = 'm_days')
    ALTER TABLE [analytics].[manufacturers] DROP COLUMN [m_days];

PRINT 'manufacturers: добавлены days_of_sales, logistics_days, roic_norm';
GO

-- =============================================================================
-- 2. manufacturer_payment_stage — этапы оплаты, привязаны к manufacturers
-- =============================================================================
IF OBJECT_ID(N'[analytics].[manufacturer_payment_stage]', N'U') IS NULL
BEGIN
    CREATE TABLE [analytics].[manufacturer_payment_stage] (
        [id]             INT IDENTITY(1,1) NOT NULL,
        [manufacturer_id] INT NOT NULL,
        [name]           NVARCHAR(255) NOT NULL,
        [days]           INT NOT NULL,
        [percent]        DECIMAL(9,4) NOT NULL,
        [sort_order]     INT NOT NULL DEFAULT 0,
        CONSTRAINT [PK_manufacturer_payment_stage] PRIMARY KEY CLUSTERED ([id]),
        CONSTRAINT [FK_manufacturer_payment_stage] FOREIGN KEY ([manufacturer_id])
            REFERENCES [analytics].[manufacturers]([id]) ON DELETE CASCADE
    );
    CREATE NONCLUSTERED INDEX [IX_manufacturer_payment_stage_manufacturer_id]
        ON [analytics].[manufacturer_payment_stage]([manufacturer_id]);
    PRINT 'Создана таблица manufacturer_payment_stage';
END
GO

-- =============================================================================
-- Миграция из contractor_producer_mapping и contractor_producer_payment_stage
-- (требует v_contractors, v_producers; manufacturer_counterparty_map с contractor_1c_id)
-- =============================================================================
IF OBJECT_ID(N'[analytics].[contractor_producer_mapping]', N'U') IS NOT NULL
   AND OBJECT_ID(N'[analytics].[contractor_producer_payment_stage]', N'U') IS NOT NULL
   AND OBJECT_ID(N'[analytics].[v_contractors]', N'V') IS NOT NULL
   AND OBJECT_ID(N'[analytics].[v_producers]', N'V') IS NOT NULL
   AND EXISTS (SELECT 1 FROM sys.columns WHERE object_id = OBJECT_ID(N'[analytics].[manufacturer_counterparty_map]') AND name = 'contractor_1c_id')
BEGIN
    -- 3a. Добавить недостающие manufacturers (по именам из 1С)
    INSERT INTO [analytics].[manufacturers] (manufacturer, days_of_sales, logistics_days, roic_norm)
    SELECT t.producer_name, t.days_of_sales, t.logistics_days, t.roic_norm
    FROM (
        SELECT LTRIM(RTRIM(p.producer_name)) AS producer_name, m.days_of_sales, m.logistics_days, m.roic_norm,
               ROW_NUMBER() OVER (PARTITION BY LTRIM(RTRIM(p.producer_name)) ORDER BY m.id) AS rn
        FROM [analytics].[contractor_producer_mapping] m
        JOIN [analytics].[v_producers] p ON p.producer_1c_id = m.producer_1c_id
    ) t
    WHERE t.rn = 1
      AND NOT EXISTS (SELECT 1 FROM [analytics].[manufacturers] man WHERE LTRIM(RTRIM(man.manufacturer)) = t.producer_name);

    -- 3b. Обновить manufacturers (days, logistics, roic) из contractor_producer_mapping
    UPDATE man
    SET man.days_of_sales = src.days_of_sales,
        man.logistics_days = src.logistics_days,
        man.roic_norm = COALESCE(man.roic_norm, src.roic_norm)
    FROM [analytics].[manufacturers] man
    JOIN (
        SELECT p.producer_name, m.days_of_sales, m.logistics_days, m.roic_norm,
               ROW_NUMBER() OVER (PARTITION BY LTRIM(RTRIM(p.producer_name)) ORDER BY m.id) AS rn
        FROM [analytics].[contractor_producer_mapping] m
        JOIN [analytics].[v_producers] p ON p.producer_1c_id = m.producer_1c_id
    ) src ON LTRIM(RTRIM(man.manufacturer)) = LTRIM(RTRIM(src.producer_name)) AND src.rn = 1;

    -- 3c. Вставить связи в manufacturer_counterparty_map (contractor_1c_id из 1С)
    INSERT INTO [analytics].[manufacturer_counterparty_map] (manufacturer_id, contractor_1c_id)
    SELECT man.id, m.contractor_1c_id
    FROM [analytics].[contractor_producer_mapping] m
    JOIN [analytics].[v_producers] p ON p.producer_1c_id = m.producer_1c_id
    JOIN [analytics].[manufacturers] man ON LTRIM(RTRIM(man.manufacturer)) = LTRIM(RTRIM(p.producer_name))
    WHERE NOT EXISTS (
        SELECT 1 FROM [analytics].[manufacturer_counterparty_map] mcm
        WHERE mcm.manufacturer_id = man.id AND mcm.contractor_1c_id = m.contractor_1c_id
    );
    PRINT 'Миграция из contractor_producer_mapping: вставлено связей ' + CAST(@@ROWCOUNT AS NVARCHAR(10));

    -- 3d. Миграция этапов в manufacturer_payment_stage (по одному набору на производителя — из первого mapping)
    INSERT INTO [analytics].[manufacturer_payment_stage] (manufacturer_id, name, [days], [percent], sort_order)
    SELECT man.id, s.name, s.[days], s.[percent], s.sort_order
    FROM [analytics].[contractor_producer_payment_stage] s
    JOIN [analytics].[contractor_producer_mapping] m ON m.id = s.mapping_id
    JOIN [analytics].[v_producers] p ON p.producer_1c_id = m.producer_1c_id
    JOIN [analytics].[manufacturers] man ON LTRIM(RTRIM(man.manufacturer)) = LTRIM(RTRIM(p.producer_name))
    WHERE m.id = (
        SELECT MIN(m2.id) FROM [analytics].[contractor_producer_mapping] m2
        JOIN [analytics].[v_producers] p2 ON p2.producer_1c_id = m2.producer_1c_id
        WHERE LTRIM(RTRIM(p2.producer_name)) = LTRIM(RTRIM(p.producer_name))
    )
      AND man.id NOT IN (SELECT manufacturer_id FROM [analytics].[manufacturer_payment_stage]);
    PRINT 'Миграция из contractor_producer_payment_stage: вставлено этапов ' + CAST(@@ROWCOUNT AS NVARCHAR(10));
END
GO

-- Fallback: миграция из manufacturer_counterparty_payment_stage (если contractor_producer уже удалён)
IF OBJECT_ID(N'[analytics].[manufacturer_counterparty_payment_stage]', N'U') IS NOT NULL
BEGIN
    INSERT INTO [analytics].[manufacturer_payment_stage] (manufacturer_id, name, [days], [percent], sort_order)
    SELECT mcm.manufacturer_id, s.name, s.[days], s.[percent], s.sort_order
    FROM [analytics].[manufacturer_counterparty_payment_stage] s
    JOIN [analytics].[manufacturer_counterparty_map] mcm ON mcm.id = s.map_id
    WHERE mcm.id = (SELECT MIN(m2.id) FROM [analytics].[manufacturer_counterparty_map] m2 WHERE m2.manufacturer_id = mcm.manufacturer_id)
      AND mcm.manufacturer_id NOT IN (SELECT manufacturer_id FROM [analytics].[manufacturer_payment_stage]);
    PRINT 'Миграция из manufacturer_counterparty_payment_stage: ' + CAST(@@ROWCOUNT AS NVARCHAR(10));
END
GO

-- Дефолтные этапы для manufacturers без этапов (из старых n_/m_ полей, если остались — уже удалены)
-- Берём manufacturers без этапов и добавляем Предоплата+Постоплата
INSERT INTO [analytics].[manufacturer_payment_stage] (manufacturer_id, name, [days], [percent], sort_order)
SELECT man.id, N'Предоплата', 7, 50, 0
FROM [analytics].[manufacturers] man
WHERE NOT EXISTS (SELECT 1 FROM [analytics].[manufacturer_payment_stage] s WHERE s.manufacturer_id = man.id);

INSERT INTO [analytics].[manufacturer_payment_stage] (manufacturer_id, name, [days], [percent], sort_order)
SELECT man.id, N'Постоплата', 120, 50, 1
FROM [analytics].[manufacturers] man
WHERE (SELECT COUNT(*) FROM [analytics].[manufacturer_payment_stage] s WHERE s.manufacturer_id = man.id) = 1;

PRINT 'Созданы дефолтные этапы оплаты';
GO

-- =============================================================================
-- 3. manufacturer_counterparty_map: убрать days_of_sales, logistics_days, roic_norm
-- =============================================================================
IF EXISTS (SELECT 1 FROM sys.columns WHERE object_id = OBJECT_ID(N'[analytics].[manufacturer_counterparty_map]') AND name = 'days_of_sales')
    ALTER TABLE [analytics].[manufacturer_counterparty_map] DROP COLUMN [days_of_sales];
IF EXISTS (SELECT 1 FROM sys.columns WHERE object_id = OBJECT_ID(N'[analytics].[manufacturer_counterparty_map]') AND name = 'logistics_days')
    ALTER TABLE [analytics].[manufacturer_counterparty_map] DROP COLUMN [logistics_days];
IF EXISTS (SELECT 1 FROM sys.columns WHERE object_id = OBJECT_ID(N'[analytics].[manufacturer_counterparty_map]') AND name = 'roic_norm')
    ALTER TABLE [analytics].[manufacturer_counterparty_map] DROP COLUMN [roic_norm];

PRINT 'manufacturer_counterparty_map: оставлены только manufacturer_id, counterparty_id';
GO

-- =============================================================================
-- 4. Удалить manufacturer_counterparty_payment_stage и contractor_producer_*
-- =============================================================================
IF OBJECT_ID(N'[analytics].[manufacturer_counterparty_payment_stage]', N'U') IS NOT NULL
    DROP TABLE [analytics].[manufacturer_counterparty_payment_stage];
IF OBJECT_ID(N'[analytics].[v_contractor_producer_mapping]', N'V') IS NOT NULL
    DROP VIEW [analytics].[v_contractor_producer_mapping];
IF OBJECT_ID(N'[analytics].[contractor_producer_payment_stage]', N'U') IS NOT NULL
    DROP TABLE [analytics].[contractor_producer_payment_stage];
IF OBJECT_ID(N'[analytics].[contractor_producer_mapping]', N'U') IS NOT NULL
    DROP TABLE [analytics].[contractor_producer_mapping];

PRINT 'Удалены manufacturer_counterparty_payment_stage и contractor_producer_*';
GO

-- =============================================================================
-- 5. Представление для API (map + manufacturer + counterparty, roic из manufacturers)
-- =============================================================================
IF OBJECT_ID(N'[analytics].[v_manufacturer_counterparty_mapping]', N'V') IS NOT NULL
    DROP VIEW [analytics].[v_manufacturer_counterparty_mapping];
GO

CREATE VIEW [analytics].[v_manufacturer_counterparty_mapping] AS
SELECT
    mcm.id,
    mcm.manufacturer_id,
    p.producer_id,
    man.manufacturer AS manufacturer_name,
    mcm.contractor_1c_id,
    c.contractor_id,
    c.contractor_name AS contractor_name,
    man.days_of_sales,
    man.logistics_days,
    man.roic_norm
FROM [analytics].[manufacturer_counterparty_map] mcm
LEFT JOIN [analytics].[manufacturers] man ON man.id = mcm.manufacturer_id
LEFT JOIN [analytics].[v_contractors] c ON c.contractor_1c_id = mcm.contractor_1c_id
LEFT JOIN [analytics].[v_producers] p ON LTRIM(RTRIM(p.producer_name)) = LTRIM(RTRIM(man.manufacturer));
GO

PRINT 'Создано представление v_manufacturer_counterparty_mapping';
GO

-- =============================================================================
-- 6. View для обратной совместимости процедур (manufacturer + roic + n_/m_)
-- =============================================================================
IF OBJECT_ID(N'[analytics].[v_manufacturers_roi_compat]', N'V') IS NOT NULL
    DROP VIEW [analytics].[v_manufacturers_roi_compat];
GO

CREATE VIEW [analytics].[v_manufacturers_roi_compat] AS
SELECT
    man.id,
    man.manufacturer,
    man.roic_norm AS ROI_norm,
    n_stage.[percent] / 100.0 AS n_percent,
    n_stage.[days] AS n_days,
    m_stage.[percent] / 100.0 AS m_percent,
    m_stage.[days] AS m_days
FROM [analytics].[manufacturers] man
LEFT JOIN (
    SELECT manufacturer_id, [percent], [days],
           ROW_NUMBER() OVER (PARTITION BY manufacturer_id ORDER BY sort_order, [days]) AS rn
    FROM [analytics].[manufacturer_payment_stage]
) n_stage ON n_stage.manufacturer_id = man.id AND n_stage.rn = 1
LEFT JOIN (
    SELECT manufacturer_id, [percent], [days],
           ROW_NUMBER() OVER (PARTITION BY manufacturer_id ORDER BY sort_order, [days]) AS rn
    FROM [analytics].[manufacturer_payment_stage]
) m_stage ON m_stage.manufacturer_id = man.id AND m_stage.rn = 2;
GO
