253 lines
15 KiB
Transact-SQL
253 lines
15 KiB
Transact-SQL
-- =============================================================================
|
||
-- Миграция: логистика, дни продаж и этапы оплаты — на 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
|