/*Каталог услуг Поддержка композитных услуг Поддержка вариативности услуги Поддержка вариативности параметра Прайс-лист */ -- можно добавить базовые единицы и пересчет if exists (select * from sysobjects where name='measure') drop table measure create table measure ( measure_id int identity PRIMARY KEY NOT NULL ,measure varchar(255) NOT NULL ,measure_short varchar(9) NOT NULL ,measure_short_en varchar(9) NULL ,descr varchar(MAX) NULL ) go insert into measure (measure, measure_short) values ('штука','шт.') insert into measure (measure, measure_short) values ('киловатт','кВт') insert into measure (measure, measure_short) values ('киловатт-час','кВт-ч') insert into measure (measure, measure_short) values ('гигагерц','ГГц') insert into measure (measure, measure_short) values ('гигабайт','ГБайт') insert into measure (measure, measure_short) values ('10000 шт.','10тыс.шт.') go if exists (select * from sysobjects where name='service_type') drop table service_type create table service_type ( service_type_id int PRIMARY KEY NOT NULL ,service_type varchar(255) NOT NULL ) go insert into service_type (service_type_id, service_type) values (1,'инсталляционная') insert into service_type (service_type_id, service_type) values (2,'периодическая') -- период фиксируется в контракте, по умолчанию месяц insert into service_type (service_type_id, service_type) values (3,'тарифицируемая') go -- вариант выбирается из группы. Это, скорее, не семантика предметной области, а искусственная конструкция -- вариант задается определяющей характеристикой, которая может комбинировать несколько условий if exists (select * from sysobjects where name='modifier_class') drop table modifier_class create table modifier_class ( modifier_class_id int identity PRIMARY KEY NOT NULL ,modifier_class varchar(255) NOT NULL ,descr varchar(MAX) NULL ) go -- значение модификатора if exists (select * from sysobjects where name='modifier') drop table modifier create table modifier ( modifier_id int identity PRIMARY KEY NOT NULL ,modifier_class_id int NOT NULL ,modifier varchar(255) NOT NULL ,modifier_en varchar(255) NULL ,descr varchar(MAX) NULL ) go --alter table modifier add modifier_en varchar(255) NULL -- эквивалент номенклатуры в 1С if exists (select * from sysobjects where name='abstract_service') drop table abstract_service create table abstract_service ( abstract_service_id int identity PRIMARY KEY NOT NULL ,abstract_service varchar(255) NOT NULL ,service_type_id INT NOT NULL ,modifier_class_id INT NULL -- migrated from service (no support for multiple modifier classes) ,code varchar(31) NOT NULL ,version int NOT NULL ,descr varchar(MAX) NULL ) go /* -- пришлось выделить эту сущность -- вероятно, для большинства номенклатур она не нужна (придется добавлять тривиальную), -- достаточно миграции атрибута modifier_class_id в abstract_service if exists (select * from sysobjects where name='service_class') drop table service_class create table service_class ( service_class_id int identity PRIMARY KEY NOT NULL ,abstract_service_id int NOT NULL ,modifier_class_id INT NULL --,service_class varchar(255) NOT NULL -- не используется ,descr varchar(MAX) NULL ) go */ -- конкретный вариант сервиса -- в 1С реализуется ЛИБО формой компоновки, ЛИБО модификацией номенклатуры -- модификатор относится к форме компоновки -- форма компоновки есть для любой конкретной комплексной (композитной) номенклатуры, она определяет состав параметров -- при этом она связывается либо с номенклатурой, либо с конкретной реализацией номенклатуры if exists (select * from sysobjects where name='service') drop table service create table service ( service_id int identity PRIMARY KEY NOT NULL ,abstract_service_id int NOT NULL ,modifier_id INT NULL --,service varchar(255) NOT NULL -- не используется ,descr varchar(MAX) NULL ,measure_id int NULL --*** мигрировать в абстрактную услугу? ,precision int NULL ,base_price decimal(15,4) NULL ,CONSTRAINT UK_abstract_service_modifier UNIQUE(abstract_service_id, modifier_id) ) go --alter table service add measure_id int NULL --alter table service add precision int NULL --alter table service add base_price decimal(15,4) NULL --alter table service add CONSTRAINT UK_abstract_service_modifier UNIQUE(abstract_service_id, modifier_id) -- надо проверять, параметры для варианта реализации всегда собственные, либо шарятся -- будет понятно при выгрузке if exists (select * from sysobjects where name='param_class') drop table param_class create table param_class ( param_class_id int identity PRIMARY KEY NOT NULL ,param_class varchar(255) NOT NULL ,measure_id int NULL /*,precision int NULL ,show_in_spec bit NOT NULL*/ ,descr varchar(MAX) NULL ) go if exists (select * from sysobjects where name='param') drop table param create table param ( param_id int identity PRIMARY KEY NOT NULL ,param_class_id int NULL--NOT NULL ,param varchar(255) NOT NULL ,measure_id int NULL -- overrides param_class.measure ,precision int NULL -- *** видимо, поступить, как с единицей измерения, в param_class.precision шаблон --,show_in_spec bit NOT NULL default 1 ,base_price decimal(15,4) NULL -- На самом деле базовые цены отдельно, это обеспечивает версионность прайс-листа ,descr varchar(MAX) NULL ) --alter table param add base_price decimal(15,4) NULL --alter table param add measure_id int NULL go -- состав параметров, эквивалент табличной части формы компоновки -- шаблон -- в сервисе должны быть плейсхолдеры для параметров, определяемых при формировании спецификации и фиксированные параметры -- можно сделать 2 таблицы: шаблон параметров и цены параметров -- при этом записи для простых параметров будут дублироваться 1:1, а для вариативных 1:n if exists (select * from sysobjects where name='service_param') drop table service_param create table service_param ( service_param_id int identity PRIMARY KEY NOT NULL ,service_id int NOT NULL -- FK --,modifier_id int NULL -- FK контекст варианта ,param_class_id int NULL -- конкретный параметр может выбираться при вводе спецификации. В 1С это решается так: если у параметра есть потомки, выбор в спецификации ,param_id int NULL --,base_price decimal(15,4) NULL -- Наследовать от параметра. На самом деле базовые цены отдельно, это обеспечивает версионность прайс-листа ,descr varchar(MAX) NULL ,CONSTRAINT CK_param_xor_class CHECK (((param_class_id IS NULL) AND NOT (param_id IS NULL)) OR ((param_id IS NULL) AND NOT (param_class_id IS NULL))) -- удалить ограничение, в контексте услуги должны быть заданы также цены конкретных параметров -- alter table service_param drop CONSTRAINT CK_param_xor_class ) go -- если в service_param указан конкретный параметр, то отношение 1:1, если класс - то 1:n -- в дальнейшем можно сделать версионность цен -- не только цены, но и варианты выбора для абстрактных параметров if exists (select * from sysobjects where name='service_param_price') drop table service_param_price create table service_param_price ( service_param_price_id int identity PRIMARY KEY NOT NULL ,service_param_id int NOT NULL -- FK, для конкретных параметров 1:1. Как это защитить ограничениями, не придумал --,param_class_id int NOT NULL ,param_id int NOT NULL ,base_price decimal(15,4) NULL -- Наследовать от параметра, для удобства. На самом деле базовые цены должны вестись отдельно, это обеспечивает версионность прайс-листа CONSTRAINT UK_service_param_price UNIQUE (service_param_id, param_id) ) go if exists (select * from sysobjects where name='specification') drop table specification create table specification ( specification_id int identity PRIMARY KEY NOT NULL ,specification varchar(255) NOT NULL ,descr varchar(MAX) NULL ) go if exists (select * from sysobjects where name='specification_item') drop table specification_item create table specification_item ( specification_item_id int identity PRIMARY KEY NOT NULL ,specification_id int NOT NULL ,service_id int NOT NULL --,modifier_id int NULL ,specification_item varchar(1023) NOT NULL -- имя для печати ,quantity decimal(15,4) NULL ,price decimal(15,4) NULL -- для композитных сервисов расчет по параметрам ) go --alter table specification_item alter column specification_item varchar (1023) NOT NULL if exists (select * from sysobjects where name='specification_item_param') drop table specification_item_param create table specification_item_param ( specification_item_param_id int identity PRIMARY KEY NOT NULL ,specification_item_id int NOT NULL ,service_param_id int NOT NULL -- если параметр конкретный, то param_id отсюда ,param_id int NULL -- если в сервисе задан только класс параметра, то здесь надо конкретизировать *** Можно денормализовать, всегда помещая сюда значение ,quantity decimal(15,4) NULL ,price decimal(15,4) NULL ) go ---------------------------------------- --9:00 24.09.2020 -- это не ЦОДы, а площадки if exists (select * from sysobjects where name='site') drop table site create table site ( site_id int identity PRIMARY KEY NOT NULL ,site varchar(255) NOT NULL ,descr varchar(MAX) NULL ) go insert into site(site) values('ЦОД ММТС-9') insert into site(site) values('ЦОД ММТС-10') insert into site(site) values('ЦОД Курчатовский') insert into site(site) values('ЦОД Остаповский') insert into site(site) values('ЦОД Удомля') insert into site(site) values('ЦОД Екатеринбург') insert into site(site) values('ЦОД Адлер') insert into site(site) values('ЦОД NORD') insert into site(site) values('ЦОД OST') go