From 7ac5adf5092168b8beda2a0481f3c1ae48fa359f Mon Sep 17 00:00:00 2001 From: Basoff Date: Wed, 18 Feb 2026 14:03:49 +0300 Subject: [PATCH] ini --- analytics/STRUCTURE.md | 178 + analytics/context/00_SYSTEM.md | 20 + analytics/context/01_DATA_RULES.md | 18 + analytics/context/02_GLOSSARY.md | 6 + analytics/context/03_WORKFLOWS.md | 23 + analytics/context/04_KB_POLICY.md | 6 + analytics/context/05_OUTPUT_FORMATS.md | 11 + analytics/context/06_DEFICIT_FORECAST.md | 133 + analytics/mag_pbi/mag_pbi_schema.sql | Bin 0 -> 1484880 bytes .../mag_pbi/procedures/mag_pbi_procedures.sql | Bin 0 -> 838206 bytes .../add_roic_to_contractor_producer.sql | 48 + .../create_contractor_producer_tables.sql | 169 + .../mag_pbi/scripts/import_suppliers_csv.sql | 232 + ..._counterparties_to_contractor_producer.sql | 120 + .../scripts/migrate_map_to_contractor_1c.sql | 156 + .../migrate_to_manufacturers_structure.sql | 252 ++ .../recalc_roic_contractor_producer.sql | 50 + analytics/mag_pbi/scripts/sp_recalc_roic.sql | 62 + analytics/mag_pbi/tables/mag_pbi_tables.sql | Bin 0 -> 162550 bytes analytics/mag_pbi/views/mag_pbi_views.sql | Bin 0 -> 482728 bytes analytics/pbi/model/report/.pbixproj.json | 5 + analytics/pbi/model/report/Connections.json | 10 + analytics/pbi/model/report/DiagramLayout.json | 1274 ++++++ .../model/report/Model/cultures/ru-RU.tmdl | 3734 +++++++++++++++ .../pbi/model/report/Model/database.tmdl | 3 + .../pbi/model/report/Model/expressions.tmdl | 87 + analytics/pbi/model/report/Model/model.tmdl | 78 + .../pbi/model/report/Model/relationships.tmdl | 247 + .../model/report/Model/roles/Алова Елена.tmdl | 7 + .../report/Model/roles/Гладышева Ольга.tmdl | 7 + .../report/Model/roles/Иншакова Ксения.tmdl | 7 + .../report/Model/roles/Кирилюк Юлия.tmdl | 7 + .../report/Model/roles/Ларина Татьяна.tmdl | 7 + .../Model/roles/Менеджер отдела закупок.tmdl | 5 + .../Менеджер отдела интернет-маркетинга.tmdl | 5 + .../Model/roles/Менеджер отдела продаж.tmdl | 5 + .../report/Model/roles/Ханоян Артем.tmdl | 7 + .../report/Model/roles/Шевченко Антонина.tmdl | 7 + .../Model/roles/Эдуард Рахматуллин.tmdl | 5 + .../model/report/Model/tables/.Календарь.tmdl | 36 + ..._716ce6bb-e9bc-46ef-bfd4-865e74deaed5.tmdl | 93 + ..._1c75c57c-6ac4-4a07-ab45-b46636c3847c.tmdl | 98 + ..._2b612047-5dcc-402e-b2ed-154636b18544.tmdl | 98 + ..._2f146245-8120-4ed9-87dc-af8699bb0274.tmdl | 98 + ..._49b06afb-4254-4da6-9109-618106084862.tmdl | 98 + ..._588ed205-7c5f-41f0-9bd7-0d82b2484f09.tmdl | 98 + ..._66d8bbba-35e3-44df-be7f-bb6fc44f271a.tmdl | 98 + ..._67da7b50-915b-480b-9e3a-3a60739fb0c6.tmdl | 98 + ..._704570fc-e0c6-4914-97ab-ebb645a2ab6e.tmdl | 98 + ..._729bf6db-04e4-4a26-9dce-b3837667cb92.tmdl | 98 + ..._93d80160-0984-4e44-91de-316b6ab26727.tmdl | 98 + ..._c661d468-0044-4990-b9e8-723cda59cf51.tmdl | 98 + ..._e0374236-67f4-4331-b4f5-c977a3082bab.tmdl | 98 + .../report/Model/tables/crm_company_uf.tmdl | 60 + .../Model/tables/mp аналитика продаж.tmdl | 105 + .../model/report/Model/tables/mp оборот.tmdl | 147 + .../model/report/Model/tables/mp остатки.tmdl | 103 + .../model/report/Model/tables/mp реклама.tmdl | 209 + .../model/report/Model/tables/mp узел.tmdl | 40 + .../pbi/model/report/Model/tables/Группы.tmdl | 138 + .../model/report/Model/tables/Заказы все.tmdl | 595 +++ .../model/report/Model/tables/Закупки.tmdl | 261 ++ .../report/Model/tables/Заявки на оплату.tmdl | 110 + .../model/report/Model/tables/Менеджеры.tmdl | 49 + .../report/Model/tables/Номенклатура.tmdl | 1174 +++++ .../report/Model/tables/Организация.tmdl | 15 + .../report/Model/tables/Основной отчет.tmdl | 1436 ++++++ .../model/report/Model/tables/Остатки.tmdl | 100 + .../report/Model/tables/Отзывы клиентов.tmdl | 132 + .../model/report/Model/tables/ПРАЙСлист.tmdl | 187 + .../tables/Параметр цена продажи, %.tmdl | 25 + .../model/report/Model/tables/Партнер.tmdl | 275 ++ .../report/Model/tables/План маркеты.tmdl | 159 + .../Model/tables/План продаж менеджеров.tmdl | 168 + .../Model/tables/План продаж по группам.tmdl | 436 ++ .../report/Model/tables/Расходы по годам.tmdl | 220 + .../model/report/Model/tables/Резервы.tmdl | 68 + .../report/Model/tables/Себестоимость.tmdl | 463 ++ .../report/Model/tables/Стоимость МП.tmdl | 114 + .../Model/tables/Упущенные продажи.tmdl | 171 + .../report/Model/tables/Я.Директ заказы.tmdl | 112 + .../report/Model/tables/Я.Директ расходы.tmdl | 133 + analytics/pbi/model/report/Report/config.json | 66 + .../pbi/model/report/Report/filters.json | 1 + analytics/pbi/model/report/Report/report.json | 35 + .../001_Себестоимость для сверки/config.json | 17 + .../001_Себестоимость для сверки/filters.json | 1 + .../001_Себестоимость для сверки/section.json | 8 + .../visualContainers/00000_pivotTable (94244)/config.json | 551 +++ .../visualContainers/00000_pivotTable (94244)/filters.json | 18 + .../visualContainers/00000_pivotTable (94244)/visualContainer.json | 8 + .../visualContainers/00000_pivotTable (a77c8)/config.json | 476 ++ .../visualContainers/00000_pivotTable (a77c8)/filters.json | 18 + .../visualContainers/00000_pivotTable (a77c8)/visualContainer.json | 8 + .../002_Закупка для сверки/config.json | 1 + .../002_Закупка для сверки/filters.json | 1 + .../002_Закупка для сверки/section.json | 8 + .../visualContainers/00000_pivotTable (721f5)/config.json | 333 ++ .../visualContainers/00000_pivotTable (721f5)/filters.json | 1 + .../00000_pivotTable (721f5)/visualContainer.json | 8 + .../visualContainers/00000_pivotTable (ef9b1)/config.json | 446 ++ .../visualContainers/00000_pivotTable (ef9b1)/filters.json | 1 + .../00000_pivotTable (ef9b1)/visualContainer.json | 8 + .../sections/003_Проверка заказа/config.json | 3 + .../sections/003_Проверка заказа/filters.json | 24 + .../sections/003_Проверка заказа/section.json | 8 + .../visualContainers/00000_tableEx (947fa)/config.json | 584 +++ .../visualContainers/00000_tableEx (947fa)/filters.json | 24 + .../00000_tableEx (947fa)/visualContainer.json | 8 + .../004_Расходы по группам/config.json | 1 + .../004_Расходы по группам/filters.json | 95 + .../004_Расходы по группам/section.json | 8 + .../visualContainers/00000_pivotTable (65554)/config.json | 316 ++ .../visualContainers/00000_pivotTable (65554)/filters.json | 1 + .../00000_pivotTable (65554)/visualContainer.json | 8 + .../005_Расходы по партнерам/config.json | 1 + .../005_Расходы по партнерам/filters.json | 95 + .../005_Расходы по партнерам/section.json | 8 + .../visualContainers/00000_tableEx (3c685)/config.json | 263 ++ .../visualContainers/00000_tableEx (3c685)/filters.json | 1 + .../visualContainers/00000_tableEx (3c685)/visualContainer.json | 8 + .../006_Потенциальный рост/config.json | 1 + .../006_Потенциальный рост/filters.json | 95 + .../006_Потенциальный рост/section.json | 8 + .../visualContainers/00000_tableEx (2bf35)/config.json | 180 + .../visualContainers/00000_tableEx (2bf35)/filters.json | 1 + .../00000_tableEx (2bf35)/visualContainer.json | 8 + .../sections/007_Страница 1/config.json | 1 + .../sections/007_Страница 1/filters.json | 57 + .../sections/007_Страница 1/section.json | 8 + .../00000_tableEx (c1173)/config.json | 406 ++ .../00000_tableEx (c1173)/filters.json | 1 + .../00000_tableEx (c1173)/visualContainer.json | 8 + .../008_Учетная цена остатка/config.json | 1 + .../008_Учетная цена остатка/filters.json | 57 + .../008_Учетная цена остатка/section.json | 8 + .../visualContainers/00000_pivotTable (814c2)/config.json | 474 ++ .../visualContainers/00000_pivotTable (814c2)/filters.json | 1 + .../00000_pivotTable (814c2)/visualContainer.json | 8 + .../009_МП оборот и расходы/config.json | 1 + .../009_МП оборот и расходы/filters.json | 1 + .../009_МП оборот и расходы/section.json | 8 + .../visualContainers/00000_pivotTable (19efe)/config.json | 626 +++ .../00000_pivotTable (19efe)/dataTransforms.json | 1090 +++++ .../visualContainers/00000_pivotTable (19efe)/filters.json | 159 + .../visualContainers/00000_pivotTable (19efe)/query.json | 368 ++ .../00000_pivotTable (19efe)/visualContainer.json | 8 + .../sections/999_Обновление/config.json | 1 + .../sections/999_Обновление/filters.json | 1 + .../sections/999_Обновление/section.json | 7 + .../visualContainers/00000_textbox (2067c)/config.json | 4028 +++++++++++++++++ .../visualContainers/00000_textbox (2067c)/filters.json | 1 + .../00000_textbox (2067c)/visualContainer.json | 8 + .../pbi/model/report/ReportMetadata.json | 6 + .../pbi/model/report/ReportSettings.json | 11 + .../SharedResources/BaseThemes/CY20SU09.json | 391 ++ analytics/pbi/model/report/Version.txt | 1 + ...ulationofthecostofproductionreferences.bat | 2 + ...culationofthecostofproductionreferences.py | 950 ++++ .../Calculationofthecostofreproduction.bat | 2 + .../Calculationofthecostofreproduction.py | 950 ++++ .../CostCalculationFrom2022_1_5.bat | 2 + .../CostCalculationFrom2022_1_5.py | 887 ++++ analytics/python skript/main (3).py | 566 +++ analytics/python skript/main3.bat | 2 + .../old/РасчетСебестоимостиБезПроизводства.py | 951 ++++ .../old/РасчетСебестоимостиСПроизводством.py | 951 ++++ 167 files changed, 32273 insertions(+) create mode 100644 analytics/STRUCTURE.md create mode 100644 analytics/context/00_SYSTEM.md create mode 100644 analytics/context/01_DATA_RULES.md create mode 100644 analytics/context/02_GLOSSARY.md create mode 100644 analytics/context/03_WORKFLOWS.md create mode 100644 analytics/context/04_KB_POLICY.md create mode 100644 analytics/context/05_OUTPUT_FORMATS.md create mode 100644 analytics/context/06_DEFICIT_FORECAST.md create mode 100644 analytics/mag_pbi/mag_pbi_schema.sql create mode 100644 analytics/mag_pbi/procedures/mag_pbi_procedures.sql create mode 100644 analytics/mag_pbi/scripts/add_roic_to_contractor_producer.sql create mode 100644 analytics/mag_pbi/scripts/create_contractor_producer_tables.sql create mode 100644 analytics/mag_pbi/scripts/import_suppliers_csv.sql create mode 100644 analytics/mag_pbi/scripts/migrate_manufacturers_counterparties_to_contractor_producer.sql create mode 100644 analytics/mag_pbi/scripts/migrate_map_to_contractor_1c.sql create mode 100644 analytics/mag_pbi/scripts/migrate_to_manufacturers_structure.sql create mode 100644 analytics/mag_pbi/scripts/recalc_roic_contractor_producer.sql create mode 100644 analytics/mag_pbi/scripts/sp_recalc_roic.sql create mode 100644 analytics/mag_pbi/tables/mag_pbi_tables.sql create mode 100644 analytics/mag_pbi/views/mag_pbi_views.sql create mode 100644 analytics/pbi/model/report/.pbixproj.json create mode 100644 analytics/pbi/model/report/Connections.json create mode 100644 analytics/pbi/model/report/DiagramLayout.json create mode 100644 analytics/pbi/model/report/Model/cultures/ru-RU.tmdl create mode 100644 analytics/pbi/model/report/Model/database.tmdl create mode 100644 analytics/pbi/model/report/Model/expressions.tmdl create mode 100644 analytics/pbi/model/report/Model/model.tmdl create mode 100644 analytics/pbi/model/report/Model/relationships.tmdl create mode 100644 analytics/pbi/model/report/Model/roles/Алова Елена.tmdl create mode 100644 analytics/pbi/model/report/Model/roles/Гладышева Ольга.tmdl create mode 100644 analytics/pbi/model/report/Model/roles/Иншакова Ксения.tmdl create mode 100644 analytics/pbi/model/report/Model/roles/Кирилюк Юлия.tmdl create mode 100644 analytics/pbi/model/report/Model/roles/Ларина Татьяна.tmdl create mode 100644 analytics/pbi/model/report/Model/roles/Менеджер отдела закупок.tmdl create mode 100644 analytics/pbi/model/report/Model/roles/Менеджер отдела интернет-маркетинга.tmdl create mode 100644 analytics/pbi/model/report/Model/roles/Менеджер отдела продаж.tmdl create mode 100644 analytics/pbi/model/report/Model/roles/Ханоян Артем.tmdl create mode 100644 analytics/pbi/model/report/Model/roles/Шевченко Антонина.tmdl create mode 100644 analytics/pbi/model/report/Model/roles/Эдуард Рахматуллин.tmdl create mode 100644 analytics/pbi/model/report/Model/tables/.Календарь.tmdl create mode 100644 analytics/pbi/model/report/Model/tables/DateTableTemplate_716ce6bb-e9bc-46ef-bfd4-865e74deaed5.tmdl create mode 100644 analytics/pbi/model/report/Model/tables/LocalDateTable_1c75c57c-6ac4-4a07-ab45-b46636c3847c.tmdl create mode 100644 analytics/pbi/model/report/Model/tables/LocalDateTable_2b612047-5dcc-402e-b2ed-154636b18544.tmdl create mode 100644 analytics/pbi/model/report/Model/tables/LocalDateTable_2f146245-8120-4ed9-87dc-af8699bb0274.tmdl create mode 100644 analytics/pbi/model/report/Model/tables/LocalDateTable_49b06afb-4254-4da6-9109-618106084862.tmdl create mode 100644 analytics/pbi/model/report/Model/tables/LocalDateTable_588ed205-7c5f-41f0-9bd7-0d82b2484f09.tmdl create mode 100644 analytics/pbi/model/report/Model/tables/LocalDateTable_66d8bbba-35e3-44df-be7f-bb6fc44f271a.tmdl create mode 100644 analytics/pbi/model/report/Model/tables/LocalDateTable_67da7b50-915b-480b-9e3a-3a60739fb0c6.tmdl create mode 100644 analytics/pbi/model/report/Model/tables/LocalDateTable_704570fc-e0c6-4914-97ab-ebb645a2ab6e.tmdl create mode 100644 analytics/pbi/model/report/Model/tables/LocalDateTable_729bf6db-04e4-4a26-9dce-b3837667cb92.tmdl create mode 100644 analytics/pbi/model/report/Model/tables/LocalDateTable_93d80160-0984-4e44-91de-316b6ab26727.tmdl create mode 100644 analytics/pbi/model/report/Model/tables/LocalDateTable_c661d468-0044-4990-b9e8-723cda59cf51.tmdl create mode 100644 analytics/pbi/model/report/Model/tables/LocalDateTable_e0374236-67f4-4331-b4f5-c977a3082bab.tmdl create mode 100644 analytics/pbi/model/report/Model/tables/crm_company_uf.tmdl create mode 100644 analytics/pbi/model/report/Model/tables/mp аналитика продаж.tmdl create mode 100644 analytics/pbi/model/report/Model/tables/mp оборот.tmdl create mode 100644 analytics/pbi/model/report/Model/tables/mp остатки.tmdl create mode 100644 analytics/pbi/model/report/Model/tables/mp реклама.tmdl create mode 100644 analytics/pbi/model/report/Model/tables/mp узел.tmdl create mode 100644 analytics/pbi/model/report/Model/tables/Группы.tmdl create mode 100644 analytics/pbi/model/report/Model/tables/Заказы все.tmdl create mode 100644 analytics/pbi/model/report/Model/tables/Закупки.tmdl create mode 100644 analytics/pbi/model/report/Model/tables/Заявки на оплату.tmdl create mode 100644 analytics/pbi/model/report/Model/tables/Менеджеры.tmdl create mode 100644 analytics/pbi/model/report/Model/tables/Номенклатура.tmdl create mode 100644 analytics/pbi/model/report/Model/tables/Организация.tmdl create mode 100644 analytics/pbi/model/report/Model/tables/Основной отчет.tmdl create mode 100644 analytics/pbi/model/report/Model/tables/Остатки.tmdl create mode 100644 analytics/pbi/model/report/Model/tables/Отзывы клиентов.tmdl create mode 100644 analytics/pbi/model/report/Model/tables/ПРАЙСлист.tmdl create mode 100644 analytics/pbi/model/report/Model/tables/Параметр цена продажи, %.tmdl create mode 100644 analytics/pbi/model/report/Model/tables/Партнер.tmdl create mode 100644 analytics/pbi/model/report/Model/tables/План маркеты.tmdl create mode 100644 analytics/pbi/model/report/Model/tables/План продаж менеджеров.tmdl create mode 100644 analytics/pbi/model/report/Model/tables/План продаж по группам.tmdl create mode 100644 analytics/pbi/model/report/Model/tables/Расходы по годам.tmdl create mode 100644 analytics/pbi/model/report/Model/tables/Резервы.tmdl create mode 100644 analytics/pbi/model/report/Model/tables/Себестоимость.tmdl create mode 100644 analytics/pbi/model/report/Model/tables/Стоимость МП.tmdl create mode 100644 analytics/pbi/model/report/Model/tables/Упущенные продажи.tmdl create mode 100644 analytics/pbi/model/report/Model/tables/Я.Директ заказы.tmdl create mode 100644 analytics/pbi/model/report/Model/tables/Я.Директ расходы.tmdl create mode 100644 analytics/pbi/model/report/Report/config.json create mode 100644 analytics/pbi/model/report/Report/filters.json create mode 100644 analytics/pbi/model/report/Report/report.json create mode 100644 analytics/pbi/model/report/Report/sections/001_Себестоимость для сверки/config.json create mode 100644 analytics/pbi/model/report/Report/sections/001_Себестоимость для сверки/filters.json create mode 100644 analytics/pbi/model/report/Report/sections/001_Себестоимость для сверки/section.json create mode 100644 analytics/pbi/model/report/Report/sections/001_Себестоимость для сверки/visualContainers/00000_pivotTable (94244)/config.json create mode 100644 analytics/pbi/model/report/Report/sections/001_Себестоимость для сверки/visualContainers/00000_pivotTable (94244)/filters.json create mode 100644 analytics/pbi/model/report/Report/sections/001_Себестоимость для сверки/visualContainers/00000_pivotTable (94244)/visualContainer.json create mode 100644 analytics/pbi/model/report/Report/sections/001_Себестоимость для сверки/visualContainers/00000_pivotTable (a77c8)/config.json create mode 100644 analytics/pbi/model/report/Report/sections/001_Себестоимость для сверки/visualContainers/00000_pivotTable (a77c8)/filters.json create mode 100644 analytics/pbi/model/report/Report/sections/001_Себестоимость для сверки/visualContainers/00000_pivotTable (a77c8)/visualContainer.json create mode 100644 analytics/pbi/model/report/Report/sections/002_Закупка для сверки/config.json create mode 100644 analytics/pbi/model/report/Report/sections/002_Закупка для сверки/filters.json create mode 100644 analytics/pbi/model/report/Report/sections/002_Закупка для сверки/section.json create mode 100644 analytics/pbi/model/report/Report/sections/002_Закупка для сверки/visualContainers/00000_pivotTable (721f5)/config.json create mode 100644 analytics/pbi/model/report/Report/sections/002_Закупка для сверки/visualContainers/00000_pivotTable (721f5)/filters.json create mode 100644 analytics/pbi/model/report/Report/sections/002_Закупка для сверки/visualContainers/00000_pivotTable (721f5)/visualContainer.json create mode 100644 analytics/pbi/model/report/Report/sections/002_Закупка для сверки/visualContainers/00000_pivotTable (ef9b1)/config.json create mode 100644 analytics/pbi/model/report/Report/sections/002_Закупка для сверки/visualContainers/00000_pivotTable (ef9b1)/filters.json create mode 100644 analytics/pbi/model/report/Report/sections/002_Закупка для сверки/visualContainers/00000_pivotTable (ef9b1)/visualContainer.json create mode 100644 analytics/pbi/model/report/Report/sections/003_Проверка заказа/config.json create mode 100644 analytics/pbi/model/report/Report/sections/003_Проверка заказа/filters.json create mode 100644 analytics/pbi/model/report/Report/sections/003_Проверка заказа/section.json create mode 100644 analytics/pbi/model/report/Report/sections/003_Проверка заказа/visualContainers/00000_tableEx (947fa)/config.json create mode 100644 analytics/pbi/model/report/Report/sections/003_Проверка заказа/visualContainers/00000_tableEx (947fa)/filters.json create mode 100644 analytics/pbi/model/report/Report/sections/003_Проверка заказа/visualContainers/00000_tableEx (947fa)/visualContainer.json create mode 100644 analytics/pbi/model/report/Report/sections/004_Расходы по группам/config.json create mode 100644 analytics/pbi/model/report/Report/sections/004_Расходы по группам/filters.json create mode 100644 analytics/pbi/model/report/Report/sections/004_Расходы по группам/section.json create mode 100644 analytics/pbi/model/report/Report/sections/004_Расходы по группам/visualContainers/00000_pivotTable (65554)/config.json create mode 100644 analytics/pbi/model/report/Report/sections/004_Расходы по группам/visualContainers/00000_pivotTable (65554)/filters.json create mode 100644 analytics/pbi/model/report/Report/sections/004_Расходы по группам/visualContainers/00000_pivotTable (65554)/visualContainer.json create mode 100644 analytics/pbi/model/report/Report/sections/005_Расходы по партнерам/config.json create mode 100644 analytics/pbi/model/report/Report/sections/005_Расходы по партнерам/filters.json create mode 100644 analytics/pbi/model/report/Report/sections/005_Расходы по партнерам/section.json create mode 100644 analytics/pbi/model/report/Report/sections/005_Расходы по партнерам/visualContainers/00000_tableEx (3c685)/config.json create mode 100644 analytics/pbi/model/report/Report/sections/005_Расходы по партнерам/visualContainers/00000_tableEx (3c685)/filters.json create mode 100644 analytics/pbi/model/report/Report/sections/005_Расходы по партнерам/visualContainers/00000_tableEx (3c685)/visualContainer.json create mode 100644 analytics/pbi/model/report/Report/sections/006_Потенциальный рост/config.json create mode 100644 analytics/pbi/model/report/Report/sections/006_Потенциальный рост/filters.json create mode 100644 analytics/pbi/model/report/Report/sections/006_Потенциальный рост/section.json create mode 100644 analytics/pbi/model/report/Report/sections/006_Потенциальный рост/visualContainers/00000_tableEx (2bf35)/config.json create mode 100644 analytics/pbi/model/report/Report/sections/006_Потенциальный рост/visualContainers/00000_tableEx (2bf35)/filters.json create mode 100644 analytics/pbi/model/report/Report/sections/006_Потенциальный рост/visualContainers/00000_tableEx (2bf35)/visualContainer.json create mode 100644 analytics/pbi/model/report/Report/sections/007_Страница 1/config.json create mode 100644 analytics/pbi/model/report/Report/sections/007_Страница 1/filters.json create mode 100644 analytics/pbi/model/report/Report/sections/007_Страница 1/section.json create mode 100644 analytics/pbi/model/report/Report/sections/007_Страница 1/visualContainers/00000_tableEx (c1173)/config.json create mode 100644 analytics/pbi/model/report/Report/sections/007_Страница 1/visualContainers/00000_tableEx (c1173)/filters.json create mode 100644 analytics/pbi/model/report/Report/sections/007_Страница 1/visualContainers/00000_tableEx (c1173)/visualContainer.json create mode 100644 analytics/pbi/model/report/Report/sections/008_Учетная цена остатка/config.json create mode 100644 analytics/pbi/model/report/Report/sections/008_Учетная цена остатка/filters.json create mode 100644 analytics/pbi/model/report/Report/sections/008_Учетная цена остатка/section.json create mode 100644 analytics/pbi/model/report/Report/sections/008_Учетная цена остатка/visualContainers/00000_pivotTable (814c2)/config.json create mode 100644 analytics/pbi/model/report/Report/sections/008_Учетная цена остатка/visualContainers/00000_pivotTable (814c2)/filters.json create mode 100644 analytics/pbi/model/report/Report/sections/008_Учетная цена остатка/visualContainers/00000_pivotTable (814c2)/visualContainer.json create mode 100644 analytics/pbi/model/report/Report/sections/009_МП оборот и расходы/config.json create mode 100644 analytics/pbi/model/report/Report/sections/009_МП оборот и расходы/filters.json create mode 100644 analytics/pbi/model/report/Report/sections/009_МП оборот и расходы/section.json create mode 100644 analytics/pbi/model/report/Report/sections/009_МП оборот и расходы/visualContainers/00000_pivotTable (19efe)/config.json create mode 100644 analytics/pbi/model/report/Report/sections/009_МП оборот и расходы/visualContainers/00000_pivotTable (19efe)/dataTransforms.json create mode 100644 analytics/pbi/model/report/Report/sections/009_МП оборот и расходы/visualContainers/00000_pivotTable (19efe)/filters.json create mode 100644 analytics/pbi/model/report/Report/sections/009_МП оборот и расходы/visualContainers/00000_pivotTable (19efe)/query.json create mode 100644 analytics/pbi/model/report/Report/sections/009_МП оборот и расходы/visualContainers/00000_pivotTable (19efe)/visualContainer.json create mode 100644 analytics/pbi/model/report/Report/sections/999_Обновление/config.json create mode 100644 analytics/pbi/model/report/Report/sections/999_Обновление/filters.json create mode 100644 analytics/pbi/model/report/Report/sections/999_Обновление/section.json create mode 100644 analytics/pbi/model/report/Report/sections/999_Обновление/visualContainers/00000_textbox (2067c)/config.json create mode 100644 analytics/pbi/model/report/Report/sections/999_Обновление/visualContainers/00000_textbox (2067c)/filters.json create mode 100644 analytics/pbi/model/report/Report/sections/999_Обновление/visualContainers/00000_textbox (2067c)/visualContainer.json create mode 100644 analytics/pbi/model/report/ReportMetadata.json create mode 100644 analytics/pbi/model/report/ReportSettings.json create mode 100644 analytics/pbi/model/report/StaticResources/SharedResources/BaseThemes/CY20SU09.json create mode 100644 analytics/pbi/model/report/Version.txt create mode 100644 analytics/python skript/Calculationofthecostofproductionreferences.bat create mode 100644 analytics/python skript/Calculationofthecostofproductionreferences.py create mode 100644 analytics/python skript/Calculationofthecostofreproduction.bat create mode 100644 analytics/python skript/Calculationofthecostofreproduction.py create mode 100644 analytics/python skript/CostCalculationFrom2022_1_5.bat create mode 100644 analytics/python skript/CostCalculationFrom2022_1_5.py create mode 100644 analytics/python skript/main (3).py create mode 100644 analytics/python skript/main3.bat create mode 100644 analytics/python skript/old/РасчетСебестоимостиБезПроизводства.py create mode 100644 analytics/python skript/old/РасчетСебестоимостиСПроизводством.py diff --git a/analytics/STRUCTURE.md b/analytics/STRUCTURE.md new file mode 100644 index 0000000..b26a687 --- /dev/null +++ b/analytics/STRUCTURE.md @@ -0,0 +1,178 @@ +# Структура аналитики: SQL и Power BI + +Справочник, объединяющий правила из `context/*.md` со структурой БД и PBI-модели. + +--- + +## 1. Правила данных (01_DATA_RULES) + +| Правило | Описание | +|---------|----------| +| Stock quantity | Только поле `quantity`. **Никогда** не использовать `sellable_stock` в расчётах остатков | +| MP stock | Остатки маркетплейса считаются отдельно и добавляются при необходимости | +| Входящие заказы | Статусы: `В пути`, `В производстве`, `Выгружен на складе`, `Согласован` | +| Интервалы дат | Формат `[start, end)` (полуоткрытый интервал) при агрегации | + +--- + +## 2. Глоссарий (02_GLOSSARY) + +| Термин | Значение | +|--------|----------| +| Stock (шт) | Физическое количество по полю `quantity` | +| Stock (руб) | Денежная оценка остатков | +| MP | Marketplace (маркетплейс) | +| Data mart | SQL view/table, подготовленная для аналитики | + +--- + +## 3. SQL: Таблицы (analytics schema) + +### 3.1 Дефицит и прогноз + +| Таблица | Назначение | Ключевые поля | +|---------|------------|---------------| +| `analytics.forecast` | Прогноз спроса по месяцам | scenario_id, 1c_id, code, month, value | +| `analytics.deficit_proposal` | Рекомендации к заказу по дефициту | place_month, arrival_month, order_qty | +| `analytics.stock_plan_by_arrival` | План по месяцам прихода | opening, inbound_confirmed, inbound_deficit, forecast_demand, closing | +| `analytics.forecast_scenarios` | Сценарии прогноза | scenario_id, name | +| `analytics.seasonality_groups` | Сезонность по группам (для sp_build_forecast_s4_by_group) | — | +| `stg.forecast_load` | Staging загрузки прогноза из Excel | — | + +### 3.2 Справочники и остатки (pbi schema) + +| Таблица | Назначение | +|---------|------------| +| `pbi.nomenclature` | Номенклатура (minAvailableQty для minAvailable) | +| `pbi.groups` | Группы (path для group_path) | +| `pbi.w_ostatok_da_net` | Остаток на дату (для opening_qty) | + +--- + +## 4. SQL: Представления (Views) + +| View | Назначение | Источники | +|------|------------|-----------| +| `analytics.get_orders_by_group` | Входящие заказы по группе | Заказы со статусами 01_DATA_RULES | +| `analytics.get_quantity_by_group` | Остаток склада по группе | quantity (не sellable_stock) | +| `analytics.get_mp_quantity_by_group` | MP-остатки по группе | — | +| `analytics.get_forecast_by_group` | Прогноз по группе | analytics.forecast | +| `analytics.get_forecast_scenarios` | Сценарии прогноза | analytics.forecast_scenarios | +| `analytics.deficit_orders` | Заказы по дефициту с ценой и суммой | deficit_proposal + nomenclature (status='Дефицит') | + +--- + +## 5. SQL: Хранимые процедуры + +### 5.1 Цепочка дефицита (06_DEFICIT_FORECAST) + +``` +forecast → sp_build_deficit_proposal → deficit_proposal + ↑ ↓ +stock + inbound + │ sp_rebuild_stock_plan_by_arrival +minAvail └──────────────────── stock_plan_by_arrival +``` + +### 5.2 Процедуры + +| Процедура | Назначение | Параметры по умолчанию | +|-----------|------------|------------------------| +| `sp_build_deficit_proposal` | Дефицит и рекомендации к заказу | @scenario_id=4, @group_path='', @lead_time_m=4, @cover_months=6 | +| `sp_rebuild_stock_plan_by_arrival` | План остатков по месяцам прихода | @scenario_id, @from_month, @to_month | +| `sp_run_deficit_all_skus` | Пересчёт дефицита по всем SKU | Вызывает sp_build_deficit_proposal с group_path='' | +| `create_forecast_loop` | Цикл по группам (lvl=2) | — | +| `sp_build_forecast_s4_by_group` | Прогноз по группе (rate×дни×seasonal_koef) | Вставляет в forecast | +| `sp_загрузка_прогноза_закупки` | Загрузка прогноза из Excel | forecast scenario_id=8 | + +### 5.3 Рекомендуемый порядок выполнения + +1. **Прогноз:** `create_forecast_loop` ИЛИ `sp_build_forecast_s4_by_group` ИЛИ `sp_загрузка_прогноза_закупки` +2. **Дефицит:** `sp_build_deficit_proposal` ИЛИ `sp_run_deficit_all_skus` +3. **План:** `sp_rebuild_stock_plan_by_arrival` (читает deficit_proposal; п.2 должен быть выполнен первым) + +### 5.4 Формула closing (stock_plan_by_arrival) + +``` +closing = opening + inbound_confirmed + inbound_deficit - forecast_demand +``` + +--- + +## 6. Power BI: Модель (TMDL) + +### 6.1 Таблицы модели (PBI QueryOrder) + +| Таблица | Источник | +|---------|----------| +| Номенклатура | Sql.Database | +| Партнер | Sql.Database | +| Стоимость МП | Sql.Database | +| Основной отчет | Sql.Database | +| Группы | Sql.Database | +| Остатки | Sql.Database | +| Закупки | Sql.Database | +| Заявки на оплату | Sql.Database | +| План продаж менеджеров | Sql.Database | +| План продаж по группам | Sql.Database | +| Менеджеры | Sql.Database | +| mp остатки | Sql.Database | +| mp аналитика продаж | Sql.Database | +| ПРАЙСлист | Sql.Database | +| Заказы все | Sql.Database | +| ... (см. model.tmdl) | — | + +### 6.2 Связи и меры + +- Связи: `relationships.tmdl` +- Меры: `expressions.tmdl`, таблицы `.tmdl` в `Model/tables/` +- Культура: ru-RU +- Compatibility level: 1600 + +--- + +## 7. Workflow: Trace Measure (03_WORKFLOWS, 05_OUTPUT_FORMATS) + +### Последовательность + +1. Найти меру в TMDL +2. Показать DAX +3. Указать зависимые меры/таблицы +4. Извлечь SQL source из partition (Sql.Database, Schema, Item или Query) +5. Сформировать объяснение + +### Формат вывода + +1. Measure Name +2. DAX Formula +3. Dependencies +4. SQL Source (server, database, schema, object) +5. Business Explanation +6. Usage Recommendations +7. Validation Checks + +--- + +## 8. Workflow: Trace Deficit / Forecast + +1. Прогноз → `sp_build_deficit_proposal` → deficit_proposal +2. deficit_proposal + forecast + inbound → `sp_rebuild_stock_plan_by_arrival` → stock_plan_by_arrival +3. order_qty = прогноз окна [T .. T+cover); дефицит при net_stock < minAvailable + +--- + +## 9. Knowledge Base Policy (04_KB_POLICY) + +- Новая документация — черновик +- Только утверждённое содержание — в общую базу знаний +- Хранить в `/docs/metrics` +- Каждая статья: DAX, SQL lineage, бизнес-объяснение + +--- + +## 10. AI Architect (00_SYSTEM) + +- Трассировка мер от TMDL к SQL +- Структурированные объяснения метрик +- Соблюдение правил данных +- **Не придумывать** объекты схемы — только из файлов проекта +- Трассировка дефицита/прогноза с процедурами diff --git a/analytics/context/00_SYSTEM.md b/analytics/context/00_SYSTEM.md new file mode 100644 index 0000000..b69a854 --- /dev/null +++ b/analytics/context/00_SYSTEM.md @@ -0,0 +1,20 @@ +# AI Architect System Context + +You are an AI architect for Power BI + MS SQL analytics. + +Main responsibilities: +- Trace measures from TMDL to SQL sources. +- Build structured explanations of metrics. +- Respect project data rules. +- Never invent schema objects — always read project files. +- Trace deficit/forecast flow (context/06_DEFICIT_FORECAST.md) with procedures. + +Workflow: +1. Find measure in TMDL. +2. Extract DAX. +3. Resolve dependencies. +4. Extract partition/source (Sql.Database, Schema, Item or Query). +5. Produce structured explanation. + +Language: Russian. +Style: structured, precise, no fluff. diff --git a/analytics/context/01_DATA_RULES.md b/analytics/context/01_DATA_RULES.md new file mode 100644 index 0000000..2af8074 --- /dev/null +++ b/analytics/context/01_DATA_RULES.md @@ -0,0 +1,18 @@ +# Data Rules + +## Идентификаторы 1С (схема analytics) + +- **`*_1c_id`** — бинарный ключ 1С (`BINARY(16)`), ссылка на `_IDRRef` справочника/документа. +- **`*_id`** — строковый id (GUID в формате `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`) для API, поиска, отображения. + +Пример: `contractor_1c_id` (binary) в таблице, `contractor_id` (nvarchar) в представлении для выдачи во внешние системы. + +--- + +- Stock quantity = field 'quantity' only. +- Never use 'sellable_stock' in stock calculations. +- Marketplace (MP) stock is calculated separately and added if needed. +- Orders with statuses: + 'В пути', 'В производстве', 'Выгружен на складе', 'Согласован' + are treated as incoming stock. +- Use date intervals as [start, end) when aggregating. diff --git a/analytics/context/02_GLOSSARY.md b/analytics/context/02_GLOSSARY.md new file mode 100644 index 0000000..f5f332f --- /dev/null +++ b/analytics/context/02_GLOSSARY.md @@ -0,0 +1,6 @@ +# Glossary + +- Stock (шт) — physical quantity, based on 'quantity'. +- Stock (руб) — monetary valuation of stock. +- MP — marketplace. +- Data mart — SQL view/table prepared for analytics. diff --git a/analytics/context/03_WORKFLOWS.md b/analytics/context/03_WORKFLOWS.md new file mode 100644 index 0000000..2551afc --- /dev/null +++ b/analytics/context/03_WORKFLOWS.md @@ -0,0 +1,23 @@ +# Standard Workflows + +## Trace Measure +1. Locate measure in TMDL. +2. Show DAX. +3. List dependent measures/tables. +4. Extract SQL source from partition. +5. Produce explanation. + +## Trace Deficit / Forecast +1. Читай context/06_DEFICIT_FORECAST.md. +2. Прогноз → sp_build_deficit_proposal → deficit_proposal. +3. deficit_proposal + forecast + inbound → sp_rebuild_stock_plan_by_arrival → stock_plan_by_arrival. +4. order_qty = прогноз окна [T .. T+cover); дефицит при net_stock < minAvailable. + +## Documentation Draft +Structure: +- Purpose +- DAX +- Dependencies +- SQL sources +- Business meaning +- Usage notes diff --git a/analytics/context/04_KB_POLICY.md b/analytics/context/04_KB_POLICY.md new file mode 100644 index 0000000..915a76b --- /dev/null +++ b/analytics/context/04_KB_POLICY.md @@ -0,0 +1,6 @@ +# Knowledge Base Policy + +- New documentation starts as draft. +- Only approved content becomes shared knowledge. +- Store documentation under /docs/metrics. +- Each article must include DAX, SQL lineage and business explanation. diff --git a/analytics/context/05_OUTPUT_FORMATS.md b/analytics/context/05_OUTPUT_FORMATS.md new file mode 100644 index 0000000..9b8a801 --- /dev/null +++ b/analytics/context/05_OUTPUT_FORMATS.md @@ -0,0 +1,11 @@ +# Output Formats + +## Measure Trace Format + +1. Measure Name +2. DAX Formula +3. Dependencies +4. SQL Source (server, database, schema, object) +5. Business Explanation +6. Usage Recommendations +7. Validation Checks diff --git a/analytics/context/06_DEFICIT_FORECAST.md b/analytics/context/06_DEFICIT_FORECAST.md new file mode 100644 index 0000000..ff55263 --- /dev/null +++ b/analytics/context/06_DEFICIT_FORECAST.md @@ -0,0 +1,133 @@ +# Механика расчёта дефицита поверх прогноза + +## Общая схема + +``` +forecast (прогноз) → sp_build_deficit_proposal → deficit_proposal + ↑ ↓ +stock + inbound + minAvail │ sp_rebuild_stock_plan_by_arrival + │ ↓ + └──────────────────── stock_plan_by_arrival +``` + +## Таблицы + +| Таблица | Назначение | +|---------|------------| +| `analytics.forecast` | Прогноз спроса по месяцам (scenario_id, 1c_id, code, month, value) | +| `analytics.deficit_proposal` | Рекомендации к заказу по дефициту (place_month, arrival_month, order_qty) | +| `analytics.stock_plan_by_arrival` | План по месяцам: opening, inbound_confirmed, inbound_deficit, forecast_demand, closing | + +## Процедуры + +### 1. sp_build_deficit_proposal + +**Назначение:** Дефицит и рекомендации к заказу с учётом прогноза по сценарию. + +**Параметры (по умолчанию):** +- `@scenario_id` = 4 +- `@group_path` = '' — path группы ('' = все группы) +- `@lead_time_m` = 4 — срок поставки (мес.) +- `@cover_months` = 6 — горизонт покрытия (мес.) +- `@from_month` = текущий месяц +- `@to_month_excl` = '2028-01-01' + +**Шаги логики:** +1. Календарь месяцев [from, to) +2. SKU по group_path (pbi.groups.path LIKE @path + '%') +3. Прогноз из `analytics.forecast` по scenario_id +4. Inbound — подтверждённые заказы (get_orders_by_group): статусы В пути, В производстве, Выгружен на складе (Согласован закомментирован в коде) +5. Stock = остаток склад (get_quantity_by_group) + MP (get_mp_quantity_by_group) +6. Последовательность по месяцам: demand_m, inbound_m, served_m, lost_m, net_stock (рекурсивный flow) +7. Первый месяц дефицита T: net_stock < minAvailable, месяц >= @from + lead_time +8. Якоря: T, T+cover, T+2cover... до to_month_excl +9. order_qty = прогноз окна [T .. T+cover) (demand_window) + +**Результат:** INSERT в `deficit_proposal` (order_qty > 0). + +**Источники данных:** +- forecast ← `analytics.forecast` +- inbound ← `analytics.get_orders_by_group` +- stock ← `analytics.get_quantity_by_group`, `analytics.get_mp_quantity_by_group` +- SKU/minAvail ← `pbi.nomenclature`, `pbi.groups` + +--- + +### 2. sp_rebuild_stock_plan_by_arrival + +**Назначение:** План остатков по месяцам прихода (opening, inbound, forecast, closing). + +**Параметры:** @scenario_id, @from_month, @to_month + +**Источники по CTE:** +1. opening_qty — остаток на дату < from_month (pbi.w_ostatok_da_net) +2. inbound_confirmed — подтверждённые заказы по месяцу прихода (get_orders_by_group: В пути, В производстве, Выгружен на складе, Согласован) +3. inbound_deficit — SUM(order_qty) по deficit_proposal +4. forecast_demand — SUM(value) по forecast + +**Формула closing:** +``` +closing = opening + inbound_confirmed + inbound_deficit - forecast_demand +``` + +Rolling: opening для месяца M = LAG(closing) по SKU и arrival_month. + +**Зависимость:** НЕ вызывает sp_build_deficit_proposal. Только читает deficit_proposal. Перед вызовом должен быть выполнен `sp_build_deficit_proposal` или `sp_run_deficit_all_skus`. + +--- + +### 3. sp_run_deficit_all_skus + +**Назначение:** Пересчёт дефицита по всем SKU (group_path = ''). + +Вызывает `sp_build_deficit_proposal` с @group_path = N''. + +--- + +### 4. sp_загрузка_прогноза_закупки + +**Назначение:** Загрузка прогноза из Excel/внешних источников. + +Записывает в forecast (scenario_id = 8), при отсутствии кода — подтягивает из scenario_id = 5. +В конце может вызывать `sp_build_deficit_proposal` (закомментировано для scenario 8). + +--- + +### 5. create_forecast_loop + +**Назначение:** Цикл по группам (path из pbi.groups, lvl=2). + +Для каждого path вызывает `sp_build_forecast_s4_by_group` — наполняет forecast, **не вызывает** sp_build_deficit_proposal. + +--- + +### 6. sp_build_forecast_s4_by_group + +**Назначение:** Построение прогноза по группе (rate_per_day × дни × seasonal_koef). + +Вставляет в `analytics.forecast`. Источник сезонности — `analytics.seasonality_groups`. + +--- + +## Представления + +| View | Источник | Назначение | +|------|----------|------------| +| `analytics.deficit_orders` | deficit_proposal + nomenclature | Заказы по дефициту с ценой и суммой (status='Дефицит') | + +--- + +## Порядок выполнения (рекомендуемый) + +1. Прогноз: `create_forecast_loop` или `sp_build_forecast_s4_by_group` или `sp_загрузка_прогноза_закупки` +2. Дефицит: `sp_build_deficit_proposal` или `sp_run_deficit_all_skus` +3. План: `sp_rebuild_stock_plan_by_arrival` (читает deficit_proposal; сперва должен быть вызван п.2) + +--- + +## Правила данных (дефицит) + +- Дефицит определяется как net_stock < minAvailable (nomenclature.minAvailableQty). +- order_qty = прогноз спроса на окно [T .. T+cover_months). +- Статусы заказов «входящих»: см. 01_DATA_RULES. Фактически: sp_build_deficit_proposal — 3 статуса (Согласован закомментирован); sp_rebuild_stock_plan_by_arrival — 4 статуса. +- Интервалы дат — [start, end) (полуоткрытые). diff --git a/analytics/mag_pbi/mag_pbi_schema.sql b/analytics/mag_pbi/mag_pbi_schema.sql new file mode 100644 index 0000000000000000000000000000000000000000..df6f2118c023c40b0244ccd62676558f6466a9d9 GIT binary patch literal 1484880 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�%U-C`Pbh@y&h=Zz+%7IOzrj8A6q4jgZgSCQ}uD|eJx-a;}YhuhU9NTKd#jg zMAUxNwECzs#NM)c7gA01`iBCJ(PHM>ouVuYi_Y)jOnv`_j}b~%Td@7Mp@@CpVM)RkqH10!%YuT$Jl@%PqFiqG47D90OV&b+q%nJ2a^mBKe2 ze@!xAMvvjCaylN5*xBdf#lY$xj2ruYW)pv4Sb?_!K4FR=^^EDV;D2TMnIFyn2fKym zxO_e%X9Y_x@@1F_qb~g!_CD(D5g|U=|;D?Dpp z&l?@%c17lN%Wg%CS;Swr-(>AU52>+%?`4GCRQ%@D#S2#LU>%rGdn;cTuPyo)zt!Hh z(We2+XMca}p|Yh&F~uJ(1APbnvgjRc;NUYO~*-C24rAoeWW1SL+SS04?uhRA!yL_d+A zL5?V48?mU)+7HgOGxoEO%2kc_ILDm$TepVt#rQqDU94f%b1&?IvEAstX+E-eKZR2%yYNQ^XKP6J-g6t)6!RE zzjx>RGVgxh_w(=kxH}^yiSpZ2UhCoRZZBw2z9l_;D!PH%azKQ}>Mq#L}VY>Aw$ z{c~{s;+<3K!D=}qV#l)1-`8fVHEpd9&S&mfkMe%pRg&`$&S!Rg_YBGBWTufrmbPW- zL36)9m;KX){mXlPKRbT+)jGk!dSU+FY$)?_{O}*=>>tf&+->u>QgSiRekOgg%idq4ZJ)x6`YPM3K+S<4tIMldy|N&Ui^Mg6UQMf=pU^W>-aSKyZu^#R?d*@w9M zEcz37pN{($*LC_m@$n_exjt&ILAOXUXU!_N)b*~6Ep?yPWAYe>(wB4osGEa`8?ssD z6_W4AixYp;-T4R6Hp;HLoM;>NW#%iVO5VO3sU6QN*Uq80?$cW5x}wR-=t3SntZ3uZ z>E|1zQJ!%+>HHN~?#)Xm#?V63pO>%Gi!qZf-PyYr(X*eKxEA~uJh#iTJ(LVZ>-|;`U4)f z%&xDI+h=MY22a z{ql?oEzSbnk7&B+PS?VF;QJ+;dwrt2|6~0-yu+BSzx1^!OZQt3YtOm^->?5P&qy+~ z_jz%?IJ;lFi`VGUp$PsK-^Gl$#=OQ7_F&Acn&;?b3EIA`*4-q#{56?>2=^OjrS+so-KdI45wNjS$YaA z7ESOXdNaOCr}4|+jrBavQl=`ri`drF~m+nZMs6u$IA(k^{ov+C0 zR$H^~TFKT|-ZF1?qPRUD1GG)qXpW~}i2={gxD~j}I?tWJlpyyXvEs^3l=(Sjs$VwL z)!w`@yyCQ;|aD1G1T=DV_vL*64){Jq~sy>9kvjV?lFaq7kV7QxhV2WyTR*Yc>B z+M9QDEqe28_7!&r)ft*8+FaNp0(TgQ^c}z{EX0VkZ|wgzuQi`YQJB#jKkc$cEbL- zP3em5#%uO^!oG38!zs&Lv~Ax`Sh-F6{i$?SK;N?ki!lOTHOWU6{Z8l(>&p zK^YdI%&qoHN-cOsUQ55|b^knq=B46Lv>~e9<%c4r6))6hg9S>S&6E4eN-C@~ShV*| zqo;0nk9mJ?rCQxwPmx+O24+2+=c&w+P{;YzR_Wzgt2r&4cFqf}w#B-;Kh9E?C*QB=YwkYL&4{{p@C#e7 zuk4Q-DjwQ1?hgffr*j|q%qqDMT5<1pcoJo9iPA&M=ODLsAd9%n+`sqH2;SXYtLb?H zTt}oGIdqb-ims2)U6?w>d@uLQ_Fm#(w`ZIlyAySJQa*P*9_;i|>wrY$(II}C#%#EY z?WVT&b$n;_W!)I!5r<^)ah|8%$9aclnJvZ@kY#B)xA^jKidlO$Kg=Y>WytM?N95io z$CJDQi}8ovPF#iOtwZxM`CiL+8eBJ7kf%sz`40*4bGw!6OUq^dbmg?2JVar@9TE%o zg`ISd?el~5`N#AdCs&kizBg{>YkMNzX2(iDvHE<|ogMHaJ4P3|0SqZgf1g;J+!_7I zeueW_F@6+V%EJ#M4hFkR1Sd&Vz$4n9{uVUb8aG5zq4y?<(vD!1&L zVtAOp!@*1c(aPL0UGh~M1vhV_N4jm_xkc=TeMYlM{7)2?gf@U0-}ZZ%>7)~ZOj^LhP3i26B)%VTA!xbX->*u?(~_NZyU7mqGfCsch`kn zpU$1ao#ZFnwd7A2gE$ZJH|H|chQfL*=5do6(M{^rv*Y`E{04|V1G~2 zF5IyjBtJ9g{Aj;F*{v06+f&OqhlJp(dDm9dTX!wM;^XDUnmmV%S(p zU_`4N&-ne9R_>(L-AEoL{_Ah;*Nc|(lU&&sQXcG6)`LHN-Lz-q9m5-4_o~n`SwQ)P z8$vJGD>gr62KRcmZT>J7lL&2)G+=5`>xWrhXq}_Ygz$8xTKHBTqRW1-9zgxj%I}PJa$`VE|JIF4o=i0Hy1mMS zpBoRZ8>JPsh9dtT`wVT}nEk3ecz&Lj_DtD0HG{}qIEBsdoDaKxNGq~TEN$)O=~&vW zeSoEKMF&`#<-RqeuTc*?AI4{Tn(2z}02MWTkoaDxmiRTOU72OdOH0Q;%y~wdi8R(v z6X8DgV_wd4um_hrH(H)LzkC)lPwuE2yHVJ05roS;W85x0CtT+G%BI~D3=gV&^klIo zpFQ^rLx*ps8)kI>j_wTh_{sWaV%j)nGtga-d4!^d%jR)vuFG$Qe7>Ac7qefKaeXo4 z=Q$COv35+ZdSrX^Tl@T1`~TK{(Y>0_8-gVrc~M7&hT*%pr4ROk>$7StRea`Uq(}J4 z_`b`wR^peXsS$PMR^4_zbf5BST{!}Lnr%Zq;EYy0EeMTaRK+e`U-)EKp9<>iKMRMgo{A3h`O z$LclS6WN}d_mFQ|tbI=Wep4@5zjtpTecdQ7T7~-FSHGv#M<*FzXQfTqhQ~X-*L>S- zhKu*yrU>))T;G`5y1};F_f+}>UbJu{bL{g=Ku-6BCHc10dTpZ)aef>Wf8$tL>p}5Y z?e2DTO}VEbjj?twGEWOS^W93?+C%Rd4f5N3yL%$`S&pFO!JZlocv_6mwdJt|hr3F* zr0skvz=z#1n&Mi5!`4214AlavqDSbAxl6Qf*Y(lB+(&!Q0KuV=_0?*PtX+0|WK(z4 z*jT5x(;EHM+9lS^vzy259!_Dq*vDCV+cf3a#{SK$AAEP*Xkn!C=jGM!?gXv7V^>Sx z-fh=)6nUrT9;BV{894QTeu7`QAHTa>8h_tGkz#fGjkIM-kI$2WIgHwzgU>h5qJ4^j z>rjiVRh0F^>(}q{I?k=O_u^h#ow`T5{j}Efot4ao@jRA6T3lZ_WAYslNo29q4Wqh^ zlW4J%WNyt_*SceL`l*$`miWY0f5-mt z0l@puUTz8 zHzdu$r7&8x@kv@mo?@SeO3~_{(&v8I2r5MW?hi!7p9&5&bQXt$(@K{PyFOpn%)2GS z?b&+=J~B=K9tH~pe(bNlPhg3e^ZNj{ASQaiE4mln^ZBf2S8PA%p6+{A=5nHDaB-z| zySo;u4gO>ww0CFcyiR!Wq|@4Qc~qQQ=|88Q%S)2ERI^y zv+NqELOIGE+t;FD?pG>qGt%#m3>Gmq8g0iH#?L;q{$!Q^*xLBY{_&lH3VvzcsEQ?h zY<)(`jqhCExzv(u`OT~)#U0@3Lk#nVt%uq!Z>#aRzH2k9QSEs~Yc+IY#FAiCdbMT9 z0;yYu2mfK~NoG{>lH#C%-=~Hd&_{7^*ArCX0pQaAnxOF1YVjF~{ek&i@P63rRd|`u z`tbNDu`w&Tk$j%E(zin)RiXFFY)x;hcg*`$f4o%6NN!=2Q!MSyK$riIQgAupRQ1 z?U|2F2G@SyvK*5{*krvsXc>Rt?N?i-mLwdREE-5jPllH{mkC6cK)>6+ig3s z>XN|sRvK})M|3Bm`8(D#w0|dk-(I*LxV^ zvZ(ja{*7;M^4e$kYj&S`kCA_+74*vTae!*wHooMxQS=44#U} z@;w_WCeCsce|_U}4#=Mec$d=#29agcRS!X2MY z=Jo2?$3Ek}>5iS;Pthhg1roIGwrE+Gh<98!Z|tpv373uU+fI1U)sYhmBRkXSWQn4! zJBhwASG?05&iyMFXXmh}VcE}Z<0nw^SeY-4H<`8V9{mz&Yg9hEK3P#R?Y|pN!)Fak zt9Y)LGW(c>`aDO}l31VTcv=$d^Bj-%cq!99-|=KAw>1t$R!C!0pBLIGoEBXib&0Rk z^3*l_E@m%{76*x~y$5UUSEAM?s^{5;RL=4V z{-ev&osh&iy7v@3V@YeBYWe$e;O(vLKis{i{eV9-S5d9ri@&orL{+1yM3z9hW$o}5 zAS1ySCR2)^c3mufNBIBaEelrzO^DCGSU(ihbi|yt&Z9k)}!qR$mS6Ah0+Lm(0Evfnb z_?XL7w<3u{CzD8dnu`Xs=)~6U{x6}W7)c~6>2FGpwmizdY^uV}(qcd^)h&}x!L=Xk zU!!e}s-|9D+8;+7_oA|>bmIh}r^>8H^ftaq=n%1h-%3#_r!1)z$1pDp$39W06{ z{=i3G`@dh>-DT@5@_}#9sK3{E-igjZJE!-Wec;t|#7*DriC$R#bma)Ro-m0V0!IuB zE}PtPXNDET@#BBtnr*M|?^&+&GuAPL?`RFMS#8@%K~9+W>|~xk50{7A@Y~Ox&#q$G z9D|WPFomy8M%p@^}(Z}L|Kr_P#2Xv?rFdb2|7*^}TH5#o63=^Oy_p2tpQ z{&)#qu<>)ctXr-dzTttpW#ij0KS5|`O_`jE`1`W4vtFYqV=ULtN9OPQJwj28mj#~l zjn*L>_eAD{YrP)+4Y6d7U#N9xS>rA~0IeumOYvCe4DZ_9M{K#R*={cV(px^a)Gc+YNHp2kr$d?UX3aGe(`PPD1EeDy+o^*srCotX=DZU zSaM9m^YmT0JjhJ3arj6}yxSWNYh7s(pSWuYKQh&*+jh-YpT#K3gu<74&kJH;L;a-2 z|KSV}7boajwvy}v|23ba-1{b8VRQAZg#Xbtbjf^M$nyB5y^0Ew(OR-fsribu zB<>=|&-R>4%qq)93NT!5Xx}+LF5bczm(iBI{*frco5sPMO;$b8V2$R3Bn@<>u-9yb zGS9<$b$OoQ`3#NaH^x1kN%<*!M(A_E7DepTGU1fbcuQp*U8el?E}8EX$ve<7W6Dl! z^`RSm;cagkRR3W(+`>_5Y*@K^2S#dEKkK&SwsYZt#~LaQ#yM=(_WaDEw~=^sbSRm} z@H540mk<^_%6{H7URl0l%IU{hj!qSgP{u3IlBeI=bii}xIn=w{Oy6$yv(QHkUG|ww z+ojXWmv|>0sC%}vGCJAg8V#Rc^YhBWjn76ofIMc&Gv)cL`f;U1vAYx?x8tW?N!yk) zKc_R`06fn4{9+BDxaj=69cCvQ$?7eirnG2D`@H+i#^D&`I%qh)ni6D4b)Trd?^x{# z-zC1!a(#cY$jL7$3Mt-c3|cqx4BfUr*UqB7B@dFcPRg&jmGpE-*l^GB9zOBc-tU!zW^qQBLuc&_1mxXnDpt7Pt9bA6cXWCyYjH>`Js)ft?=I ze2M61K4l|L=2K{zofZFij}h=)yOC^!aC#bnMynagjxrWEkVlMlAlqf(=U+3f@-?IC zn-+MV z0(XPnIc6v+)FH)B2#(|T4__Qmt&pElW#i2N=%&sv0UTjgV}PhIpVSV%EaG>a2uFy z7-h~HJbo$VcQ6qR5E|N}ri;SHFRG>+C;cRxw#wRBV|_yDGB+c-H3b`{%%^UfI(yqy zi(vb7IAjc8J{)4(z+wMrP6=V1c=OQg{X0eDUJ);odAeokf?Ilh$KkEXjK zLXCVm%6|#AA;0PG<&O^qu8aPck$3awIq8Eg<5^3iLQ3Xa9rf3a6V1N6F^*54@0ul( z=m?#L*6lE#m`|w)G_Y zRy@BkibBMA)%_g{yX47i{(X_Jc?5g$wuUo9m)*^ya3uMryFWG*yyZPE&+2$*i&kxX z)V}`6vGFr@b8>z^G6(<%@_CCQY7BRij-0s5r$#HmX6bUpnS7n(;_i5&u7)zS>Ym^4 znx&6SXP1q}lG*H>QPDdy&u?bKKX4+tlB@-I+r${_yb^I9`ndg1oiC5!JDRj(8v)CKmw*hK*+oHU&(h>R3`(d-h zNrM+x)v>wOP4c_zB}JL1V$?b7`>%<1POCvrSw?xD6j0}6OOhBGm3WzQuG#D8SBaCp zYrNBqbO!x3odM3dy1c{5^@g1oaOQC1tY3y>`2=`*{VZM3LM@Gyt#qIEx1>{#JkN?z z(;2Dk5M`^wCHs4jFVt3|Qu2N~U(LE*f)>{dpNS-d&biOcEjwp@WQURmF0ofw(vMh% zTkPtJzoI_>d&T!mQSv&KI8f7EuR-qz_h4* zwWQxd&y{PCvntn7u0O@^w>2_80_WShS%`0k9K>EadXV}0yJtjOgB~?3aTea9zYF8W zqIK)i9&wYUclQVz>Px!KbH+6RU-e83igcPsOrJ!4AM8VyjL(u^o^+gU4Z?~;#2z>9q2HHEbrUx5m%dr`3BSL>)>~?J@Gx>SsI>|2nPK1A`%XFQ%1# zWc&7^X^|dIEYD3I(1&TQ-(TsA8p0p+l5x0Gai*QsZ2ngI#)CZ}W>K56W7=a{tfiLB zkZrHB4&#@D*F87bPlwyImUTM~_&L30c7;R3r8bU1rDPiynOd7zXdM2q`h zNs~Jr%H1~p!({U5^?$MYOY`GHri(EiQ)l3{FWBt4F?@QzJTvZ*C(_G&gO0rwXTt`IRRIK=I!agGL7peV6v&fM>o4nl0 z-95c$JUBkId`{rQy6GlaEonEw4%SSv$Hf_KnBFq>$wkgR)tl$6qwF+D-?2DOver*4 z{igZJ|8^p_-ZwkyO{3x17Ec&VFIyHZJXVN;x?^|&9$z#Z0nXE5*lH80@4C%`d;G}3 zyKa^+bU?au1L=Eu`R9W%lKFJgKA(sB{>E038^E+fl--PsOQNN48eqI|Z2I`7v^vjz;4~i}CoQg97K)$J zF5QnYHcMgBD`wd8q{KI6FI)Ct?|Q(OFvc|q+YNhr5< zwPa+dE=(d&}x=oA<{td*3v!_L%(>v3=EA+pu$smap2A zEnB5c`-M17@}kk(wNY+xu^uj2kK1WPytg1x#{0GQ9iDyM`HGdqY0uvF1UVLla##;z zy=wb<9k<+=#EARIVir)cd(Yn%d2NO3@W-4gW9N5kM8}F&ZdxnnjpG{U+gfdHhPM8f z@vz)?A<2LKk)1T$%kzu!=OS%ISiQchm2Ty5i938g8g$I|%gI^3VXaF$XM4+|Xs*ZHOhKwO>7EKz%`PSZ4KkkLo!VK{Ky!~qo^`4m8COq$B<9NB%T%(2BK)c3U zP|x$V&^|3%XYb>I5jg$tyQy;T5Le3%RX<-HLM_RrI{ zP4OwyZsqkelV$MO8<+o8XR4f^OHY^Qz0Q1cyVsgWKKDA)<#4CX(wGY7ZHcQTThreV z)sS?oQH{&TUD_4fu1}TE4JRB+_9oH%JyCecc-(G|W-e;~1eG$9c9`m;;pFxfZnoYr zOulY^hwYU7z<536?0i;<0+TaOGQA`u6O-e0hS``qv0yuTj72=J`JO z3`4@(8qcqIBGE1AL#sc<(`hA2=nTyu!)QoqiJ9xP{zok;)7RpgK@4A(9>d|J9n;+j z(m1prlQFdgiHuVvkLLY#v%3xNhS-N_c>E>eTKwI6gO_@DrjKnsC(3)r{4cmi`ho3} zZ;ZY`{qcS9^@v`^eP!D?sTguFOrOMS=(F-A>hrN4jj^73q`S@|pBeAM&T@S58~&&L zBjdJNXoDgE%P9F)%YCK$d-%@I!|!aIt-n?eD&OB8r|eVn$DZ1rm+x=U>EhHDy?lR* zrN4jKZfnjt3qgOI?ps>6rf;n_y?lR*_swegjjcU5xPzUJV}G`9trl}>#Ud#8g4%EG zD?jDAnWa3(>N%)4mEW;b5WcId(Vj)wL;u~RKA*aW{u<-`v1=laSk9?Eqq@#`FK{uD ztDMqHU1z+P%!iik>sxy+vQSNHJ94dM4}ERt8dG|xdED4XyN9yIls-z1IQGzoU9rZL z9wPr-w%^x7uA%l@yAY1G<^YLT>;APNRq{P0SC}~+u$0I`A8E;tdc%$e85bL*kVkKf3Ujg-@ zbt1b@N>wD8TwmP$za*EwC&&azbJuvc^Pwcu`kI$Qhm3uw>Oi_HD?zO=u zM&2-Ik{^^mBdRvXNq%Ub-4};Zzlc$>JI1MS_UZ2+GWJ38AA6c2rN6ZExEn_-h(#>y z^WKV)u0OBn*lB0JW1aiUl@zXhden8CGEFUg5MLTG*P-d}z7qK?nW78yTE2d{_L!H8 z*F1q~97K%@8V6CMSicXVMq9he_xM5V5t+ra?Yy)RJCqisK?hNz%H7_= zvi*)4#eYD({~TkC@Pc@eBa9+Vaw>fgA?oy|esArcg9y zwfYCkSwp@eGS`sr(7YE@en+y?4M*M`#H&6wxE-^6Ld2UnX2oa>e%+Wo^*h{N+<4HF zX%;W;_<-g?ylNR)Fid|q2e9f*%S)9@XFvWiJCD~XJ@cp5ioW(!>rB@G_{kCVtS@%F zYCN|NVphrd_>t}THV5P9deo6~lVq7QFhbO8)bGQQlEXX9+xj`jthV=*L&o1dCZo1K zyc*G}P7|s45#WeKaa3s23d#U%)P?gT{ zio@lc7al7$@O+MUa zzTarL9I;^BYcyP{@Ae@4J%(;G(ufb4x=< z)2H7~q_IqEZTv9($2@c(Q zLz(4O$33p&ojk*%^BNvqH(Yw28-p~WMQ#aFO>l7UHv{Fi&ZN6k{63)Jd5+)MGj!Sl#C{+;WtckcNkD@o_i~`|GLHza)&| zelpA6IC^7`>i8_jZ|Nz^vtOp%%%fWIKAvINw7s2&>*Tv}hRa2`50}g>!q0J68``$9 z+jcb9`EJ1Ix4@c+jG>K{EMg2@o`^dwK-1R$L=dpJGu*Jczs*9)y#JT zj{0h~v$$`u+RW$w@J%-=UEgmrJnwj~%~;8KZ?n;OerY@9WZEf5l1{taJN=o^ReQ>9 zFw?MLN=xGyH?@_ix6@3YCApu6Z=_LMi{3(`+U}X#fA`EVmU#WKJ7q!!vnvb^I=w;TDGPkny@LeORfxDEHl#-JEvJcIHw0=l($S7ay+t!QT0H zHJxq8lTO3!O44v#wVli@Qqpcf**FEy*`1PDoBH({uCpa)2fF3HEIP_Ka=%l?=jmD} ze~;~EeYii(@7}It*Qu>VeR*!nZGDO)8N1P;9AT|b&#n3h>k@5!LfLA`$K*EiNXrsa z+Kl@6*kW!omT0#)HQSBPz0PhUU%-gl*~8=@$IX{T{+gFR#|`Ve|CwmGZTW)HtTXBE zDB0V&)0P{m(Gr|D`ghh|`FzXn0kd1`&5v)x{tl-bE>D{kotv7sR)239c(~izZx?&# zmC0AbO3d>gPa2&8%Y9`m>f@4~4CEVpXuc7rSJv$Bta+K{-`+D@_iZ~}zBj$-`7{UB z+fKd|}C?%O6@6QTgqBZ0%v&c$_?c9;dv!#G;&@wc@wf zaFY$KU$X!873P1(bRvF3I{XVUeH*hoJNce9JxKa~W86Qj{$llgyPsU+s9V2ko+I2K z{?_W-JtekMX4%(_a-6hQ@z=TB=nEPpt>wn*4Wl;Dopz5`(p^q(82!>sh}@saZJy=m z+jTD+MAp*{+80yp(>4}vl=k~Y$sYzsh~8Z{qWjIut@fal+?@NC^$!g_VPoPZUP*q( z?VE1IWX{*DReYQzWkYkB@kQ&Omeo2p3Ol{EPuB8b>p^!C`Dy}hbY}JMK>5ASufVER z8aT)+YHh{Wm;UNj!5xh)&+(kiqgz(6P}z4^KAhD8YxUb&YFoF(U9r#Xf=wGUH^psR zFDGqha95n)7DrZMZj?J>nftd4hqnyU+~M`9?T;&+Hm{_8wQVhNYZkZ5k_bq$I%F!$SrdN%k%K8h11qO`sY8u^8n1<*;r0lZAP)3MtQ=%G51sU^jdlXM2^{WR-8ycpZi8Jd$oFX zwAD@P=Y;)Tw(+XXOV;M4(CY7P#NKK#WxYrhl-JaBns`HFzg(Q#@?+(`mi;FPcAf1c%Zd;XJ_$ zgEK^XhD?Nv!v9%G`rWoXg_mZhj41vmM)hUc&9wjCF6~z<{k5+eu5bsLpVRr&$Tb-m zv+ee$bH%x~*158l=9O!!zgTZ`b`q86(b|j)*)YkNm4qU4=O}i+Gpo0ac5T}??$JJK z-?9H+vNGtu_+9q@yoxp4w$rYI7a@M~CxhpYmMcErK&jhW{%AY?YFO_ZhP5~Bmyc&_ z15``jnR~_w+)a3K)My+K8|w*3+&5eXtGs{7Vzi!d{=WI~klB7G(GN1F3(s_ys6Myu z6NQT9_9C`N4_>VYIpL2PMrX`p4CGvAmLDe^;2X1CH{PP$g?rlv>${W%E^^*J$M&2s z^jLtz{`GP^^x_!k?}u%z#XWG&A5ZsOvi`0czGded8WVnV?c#Ymt-*ht<6FCTW3o2) zSAJ*haJOz*O0C>C?qJJmo6o0};&eZ2Es;e*y5RdO(Q4H$!$@K&@d@lRwV{#vo`e@_ zw{w3b+atxJaH}x#9rhicvwS?hFgpIgb|l;@H`SNkA)5E=RvWDvw-PfJ@i?>tgweEJ zwr9Z2+rB%al0R6hj}61VuyqoovGxKLV0>%_A+=Q7!THtK(lZ_6Vc;!g51Tw@AoLrX z=|$r)*KJl$Qu*~X()#y}-If>=zU1*9dGF=Tw326SwB28RY2!b+`Y)@$GOoG%6yE~w z>ps7F%AO-xA5X8{lD{y18LqZ2m1qCY)_>+0X@M+-@i(BW`Q~|*yqsz|7wDt-mG$fV zI6BckTRXJ=rqO!%R{f^6qerbATGQX!&Eeik34^j6vpQonkFWkNtvZ+jCT;H4?kmsl z7Y%2r?fZxo#s`Y}XLm=JA@vI@dCA5`O<=_8WEYtYX!2or&}R%C59+t$6te z2}T4&PTIdeuOXQEH#jXXB?z^jmFv_l6Gu^(@Yy@3FA0-h%M%kioKHcch#VZCoWEjqSmvqD*I97lYo2!4cvaF~y=3QxvmAkci*lhpEP3(r&?d9(OfyN&G zLaTxtg&v*}U9`1Iy7<}ac501$(WmX7ktr+Vwnc$3GEv_$Vu#rjJ1pJwg;+GkoUD_Sb8Gt{*I86(bT zTP#;n&a#bs(#0AzwJz&KDqB8bwDs8++w~JL{#Mo*ItQoJqP6lgjJ4`BF+LkQ6JxpQ zCu6J?VWu_p^D&mH;od&Ogq!WNGPYK(`%qhPbggo1Zm)G_<@%nzhTCZBk(4#X%daJv z)FqMC`p3-u@8j*q)h?-OdH&_owB!(Ky3Ux&5|IM)H1=4Ykdi3t`UfW~Jo)sKbt+cW zE7v+59q)V%rs3PX=l9eRm-sm}-Wuno?2=fg)i!ura|+<9cJ=?gve+LM+h3SB-P@*3 z`OWIDP3|0PNBf5esqgInL9#<@6i-c;M<$KKW?9L)0BjkupI@?1SL~^KK|*OP;$Wr+ z;2SqJqOs#%$}f^;z-dUSN!1w84pNKwFUI40o8S491{})m*#`P-+UINxrTtUZY^>k& z)|JgKQ+=%Q!brEj`}kP7JjP+Gd*2BCY@rvYk<09-HJfrD)V=xX#E8l>j@*d~nc%JM8x6Nl~v%#%7xAN*-k-cVVt?}NnBIb{^koafo*L8J zmiI<%8_v9|TjX3^H>_l}A{O_rv+t(ZcHT{kcy-i0$K6NF0u~c_=VBwdX|@3LpXl+* zn%awbCyeX*d@md_Di(L)H0|G%+9wUZwLZ}6Y4;Kx-}WHOGa2XE^V+=^`2PHBT+bhj za_rbS{GFXonS<`$FcT2+;X2WY>F1y+dN#^L}U*U#{~b=j`g=VL$k>%zsI890r(MY zt^CPw41O2R=4*S`s^OF3zqKRoiD_4E?H&4E3#-F?9twMSF6z2J zvznhGzgVN5M!{dKF;AoTFWQ*LPly+5#Q8+wJjr{v&kI63xMk~U^Zsy3Q006BNh!zR zS--rv3D@o7e}o?t=M6rWXHta6hDq_n$aVcew1JFaa@^3=Dx>l?chLP-66j#)oa_8{HW!+E+kLHY(b)4j*A(yJnaH&${StEhRY z@o+t`=G_|2-eZ*WXd-0RY@YJ(+Kb=C*_20MdJ8(gYwwLXt~<6OM78GINlR}J;!?jf z&i8@gT9)15d>j`Xn`?Uga%1wmc(cD)yvV*fz~n_S8NMd(5#(Md^ZfirE$4LYsr8vd zUV!?{Dmm2FNt4IAwyPJ-{tIMmi1S&_Ts*T#<}>zhF781EWO8;1(f8%dX3>?Y{WJQZ zj%zq-BJzcaT6PZ?uAb6ef9 zN3X~~C(Xlp5gS_KY&{0}A@~bkJz~`7R6bJ<&~hZLedzhXu!>^S*)|S`bBms3$vS7B z4jKH9B(E6nZGUul^mHoq^Ly)c{8kMt-`E_{H(~Sr$hbiF-^undeFE~@A1Qki9pEskvJ>ENE*vF`9L9g0))-Bj=0 z2Ns2^7;nRfwBK`-_aZ&hei`cqU!?3-nV#S&k^4Pa)VVp!DwWTUNRivoa_zF?(R1y3 z^G4IPTZ!}+sI>g?qSn(rSfDP~E$#(BlX4%k`cTo^ohR%Cpe(85(yY{VYvT`Awx(|X zZgS4Y_Uj+gJ04WfT&P>7Cr*`yXoBO%S7s4L=kDLv?6b0-u$z!5KQK!Fxs`$LU$V7V z-U`XLvXdOQ(LbJ@QtO3;OO!g$!(+{JqY+;&n0oHR-1l0V{WY8W`pUnV=NJAt(2&J4 z!(hiDH;nTHi`kXq=++Dl_$e>elI-qf9-KbEfGj&R{x}BW556)>$@Ko}vJ9%9LG&a&{yXuNTIcBQCHnnMR`*+);*x@+sfw5@K zxD_vs%I7#j+-R7cypabokWpW>1qRY%hDeAL})$DKm9mO3=-8 zpd4=t_ZC}GG6SBRtti$p0LIo7P9OJXw^F zbK^wDf9i9)Nr>FyDormU?+|N zoRF1BJ#RsYe73xOm`kx z64Ywxls|?%2+N!0Uxa87ovhDtwDU)bWZ99($j!tPPmAIZ<`2bi)H|-^ z!qEc}$>sR@rtSKhhKY*gQqJ7k;@QO*!T65h;MeJl{AT4J_WrhVW`(>KCR20 z=`^3zW%oJmQ@Y$9vrp)hD1&_Fba!6g*^_mm_d7a+DLZdJA`4ov0&(}Xp4WS@3jw## z)~9cTKrQ#x5P)BWlljX2p`>KxC3F2e(F1i%K%80qtezEm3%n|owNvXYnrs?fI~jC~ zXkBX_dNiL;bU7ZhWAo9W<@7d<{w$}jX>?~typG&VczU;5J%k%M-+JCIcekB=izBT>jccx)| zxXXcKji`OtYwAQMX7>+8dWp8mp|Z8t`ShCo-sjWXXnUcL)sMCqWug`hm*&DVwRLA* z*5d@vUY9QIlx^e^b!%wB)obbD(O1rWJM>&NS#w5#6!_Tmb;Lko9YJ>#*Ux+E^X|yF z1K&q%rDDQ=>S?F#*O6PPvwGK~aVuT4IS%=J#FkluY?<{;Zslx!zGd0y`JonpV$1}R zbwRFcKAbq$VXct+A2>%Rz4!ilhA{FR;q^SdL&o(`4j;GC3WIfiY97&NdVcSbc}Bpx zcl&R7moPHNQ=dWUVZwUnT`d0xZ<}YzqL^`Yzx*AB`(h6)%fmrE_4zdD=@c&pm7L#i zLG>clV0Nx+&b~jC8>3`UjGq@re!yX&hro`YyOFv+==WE!nnaJqR(?h(7Z?`(e1L-_KF6T-4ywt=t3W67t6EPBzOL46L}^{^)9=rXtZmHoKi zv)aqn??o--?be5^w$t9t^I*%5C_pgT}q_Rvo~$j(uEnhE~V1E)(%vwY7v;*q^=UmZr`_~G;D?uw0KpZgAY z!}6K?P0?OA!=R-Zqm;0)tq&U?iLlVAcURI>>-}1?E{4WC@KifWxizKF^Q(0X(ub)9 zRzGVW$f9$h;spBJ8PZj>TaOVE?Z}Mo>eQppy)yP?Xf5isj5DtF7>*U?@8vFu^~W_G ztr^d&^=P#baYK7N-h@OA-%<10>tigxxUvn~`=T+l>w3}BM}3MXK<&v)9>8O}S!zX5 zA`KGU<#8H+*O}G!taU%)7C-3_S@sO%7cL$vXGJXMQ=Yo5nUy8nv#j((7sT9u|6|kC zf0ewJ&)K?+K}daiz5p-X>NRo$B|lC-U8)>;6?)-cdBW(WRin&%iS$Ct$|y!ovGVS5 z^1t)jHH#L~jpp0-jhMV`d$MUf<~74m?lV`0C;D%DD~oQq99F+$9WeRLq_}@FdG6PC z+v@)smFDQHl;uQ2+R_~Rr?pa7OuBk%uqq`w+FnaFI4us@=<3K^&+AUBDpSg0WeeSv zD_7U4-#ikPAnH6Q-jFy3t8)ICrO5I=BYCLw{G`9t(%_x zSH_?HU+Lzu;qo7*KF9eoMkWpmiV`zgWqC(u8vK=M!R@?5kHJklM^>-d`<>l8NGPW= zIlfH%nYW-4^z^audadY8IAP)XI1i>czmJ1m;I`>@zPI>2Y@E5Jd3ZBoi_v8~wzw;u z0Ck%_zSt_TXz^`jPQZH3JCwjUflJjQGCxG=KYuDum_ZWH0^Scrz@%6G;X@=6|A_N>|bO7E3@|W>7=K(z)6=m zY32RNr+e8>o0~4nOyi~NI`ebVbqf*Z+DB1)%sTn3{PVm#b)7Q@YJNP?Ja2Jv&RXY6 zj3`@X&YS(ubt72ByJv*=zQu?Nz~Io_gYXhIR9Px<~D!@=EOu0=0dC zJTpfs`$FWJ;~eAf!*i(l*v#h)VRr3js=nb^q3!LFclG>Q$MSbzmRozzvLcZ`D&~MY zX?)ZvgG9-d;fJO6GS@F@!uNh|mtW?k0DW^JhYllx1CliCqortbM&r#zP$3E z_UcdPfmCa5PpoB^vpok-p1D8G*^xwLJg?4>%*F^A`{H}Ih84M5j#ro)$10deTM&Qm z$J|)TWybtlh72ta$?CPur2bCE&R?3OjupjhDZs_v-(3A&lHU3LOS7*0vpwN1^0%y9 zdbQjTl+JbEUaecMzcbQO!iPVJb{Ee&BWSH#=7t}vhG5jTxM)9+f93HE@7%5uPfV9L z{n@&41)fo+miRe&@7X^4+%WrL@;i3Py0zwHB&unrxUOM+0KN3vRr)P5!}Z{HYPlW_ zN9Gu8cUT#di|y9h^Trur_c>%V%^^z8!9W7{yQv}OPKzSFEp>62d*mfK8)53M%0Y+SW(qtAIrZq4%pX6WPc zY2(!U2ZP7=*0<(5pDe0YqkLC-YpKm4Pc2HY%E}zYol@L?n8!_|KP!WNK4L{%Dh1Z# zrP|gRM$v9{nw;9MJ1&#fC%aQ1?pCHC1RcAOXrGTkd;4Im`~4JNp0z%Rn0XZ4ua)yrW}c3-B94iZQk(&h ziQ2a4U+U*^yW|ub_w*LvRI^?#N4u0Qy!;xu$U!XTae2geTlp(;0wafWstea^IfXUn zY($@M+qBW-)SNdzbz92GeTrL-_#}y=C0RHQt|ti~OBVGm6CcslsvuQ&C9K@4b1Be; zhl%IQj&pJ0DU`v2QhEIkM zQyb^3^|RJ`_NZeQ`hBpucVw=u;L{y@&e9h7i=*V=Gs4$$!}>lkv)x~|_iJY5ylkUk zL`Z2z>>pg&HZ2t%me=glwIt7+*d49({FjYuBCD3@3lhm@cv^y<{tt$o6Hvgi9?2Fc%`Zz?7>VpF=N1-v(-n_fJ3mG(?nPXiq zygzo5#{t%T&H9k7F!#wGN_TmP0@Np1hNm>a;6J!?G(o~4;_u7V8{zTs>s`GOH;F`z z(eDkNJ_R-at%(HI7C!`+TB%u4P zOQ|WJN?=9bDf#N?%slS?&o#!pMv(MB>pH5%^=!1l?(vr3R1WlPK&7RV8owc{UsnnS%Z5)3w$rgFU%2#f+3d{R^@HA0 z_a5RQd~+3kAI;!pdwR(G$ndtjm0M&e1izv7fG2!O5iUl13`? zsy?&UC-n1i>(mz>+1V-n*=h3^mke3p_%WWCbSRN z`uP1n; z};0M(Xp1hn#9B?7Z`~>-W9bOxz>3YZ)O2)R--Vk#zlM zu|nKQ-q(>0*yC}saMqWNSLc-|9LAHaA?W81Sw!zen;*v+Z`z5U@Q_{3hZ)#1VH_tOb?iNC?38+WcK=9t&5#=2;an~fgZ9=Ut#XEBf6 zz4Qqsh|qM5Y@AF}QUa#=c`R#yB$jQVu?4|Ft_@;n4K@owI}xILKT@ADml{|gc$_z;kKC)%6Bqx}t`n0+FI6R_m%2}#)Y0Y|CpM7WXH2C_6 z+qHT`}$KPexgg=NQ%d#=R)=S^V%DN!Nka;=R#obE*4s&gOj)XKYj(FqBV%mYr|YS+FFdzYqGeN5 zVjOua3y1A`m)N3Xnm9q-0fj95$o7G>Cz*eMLmtjtA6xc#Pa*>pZF$TfOym$6kFuoV z9KW!Af~5Antsqg&x~V#rY@g+BPua1()|$aGyvdImznxDzJR80?{EBg>`mIeJS8`&EKPK*%{2LzNfrpTO)h$X3D{^ZkX}d)&^V0yDO#c>gMXZ$pR9g zqSAd(dBZT_qG7IdkoAr%pJf=_x6_Lq{&c3>yJ71NBy))&DB;0#Wdfco0;gwrqrGct z&^599x-S$4mT8kLx*NT#cKJVYn^<|IrwVyZF_w}|PH`n*|wI4Uv_xH8z zo9p{}s&B4$Y!hw47k%mpL=+HoMb?F*ra1=p;qB&?Amfb_Y6m$B>XvvkJL$81=gkmv zw`Dh#eX#NyJ6|uFUFW88UVc)GDk>s9Qs#2BoCK~(5ub@Y@721szUK0rm-J};#iODf z?yiH5^r?Loy{Z`VD&DI4?C=I_dgfy8+kWomK`l$+C zBhj6f0jAl=(#R#Gmq^woiKFVjmF#hk7N#oQf2D zW?IweC)~Zyw_btvovXARZInZI2G?avteDn*oJG4vKC5*bYSuLDO+PZl`vi?H9%jU? zUA3t4d-jc9pPEek$UYMn&z~?-lJXsUDldEFt8NxI*8|t|D^dXWJ#m{F{;87KktguB zaIUCN58^Gj_e!oYML*&h)I6g|>~V_beR91!VnBkAK1IEf`dTHxuyy(#agOvYkTp!eecBu#Tu}{?- zO@Xz0wH>#;mMw;PW&3n9GtRt6!;>L0-x!V*{J77z)|YtSr5+~tIgbp??!i+6&G}zV zKZ1VcaQciqgnt$9hm#NOJ4w5`ml;9P=aZVB*Z8K%+0Scq(JzqS> zJ);MlC!bj^Sv2;XT1xW7 zLo)hs$xAx$pW9NTAiicJX+4iTV&u}JyqVXeU80mb$4XC;KimC` zNusfqebD#WP%H31?JXzHOmT^4~+kVVBPvTQAmGhur!~Rbz-{O2T9mNxmbL#BMd3&8& zXEW8gxAF&*D{m+H(fhC88L_n1@6X!Du720XMo#p@)&kk+KTcF=%19Y2xih#U28e3R zWt+;-|7o(|vtCo$?Q09^c{_PfT$wyZ(PBpUf&DY$-;ct`Jr1rI4dcN&6~9(2R?sL9ALT#U%eb&lF_(-m5(Pv zgLQ84r(gj(Brx=Ok01XO!Bf1iAgr;u4;b_vtmB#MQ@O|R6Z?*i6#p;RgZA-n(=_do z(^*949_vSr4Nj%h_GO)QT(QMH|BspEMxFzrpU{N)9j$`Wv{hy#%gvL^Xv&e))FsYd zK9qHdwhz*@8A-ohdZ!&vFe-h=8AXoWZH*vvbNCA3YvqyF+3GGl=Jlv?G&!^E|1tbL zV}6L@n|0&ry7^!cTYJGI0?!%Y`5nf&sZGQD^C^1wqH$hNZ71OU3Oz4pGTsum+)in! z1(W^^!x{yz%f%-$`eHAYyrnVSwb|d9&0F5X@%OCJIGJ|Fl(oZS5S~Jk*Oh_QLzd9K z-cD?=E7nln9 za&BX-*L%NjzHavuCszqd}s9mAr(?Rq9&NqanxR&?~QrmgwRRs@|68XRN- zx3Ea2-L##)X}2o3dd*U0mLS_B5l$dCa*Gex2qtj4M0rrU1?4g3bL5frY+P66`o7#3 zb3%Gy25R-T$qatpwsl*A!6C!>OE&*4qjbPQ83P>V{yt^Kr*``zbMa?0&thdElr~L0 z{aMUAN3~DeD;C=0mM|>mJ26 z6&BJQu>SMT+k14pK_k}HSaz{M+}4z`tkuw*9V@}#RymiKw8O3>UBC^?*K)}y8=6t{ z{czpl0ev6B!N%6w{FKjr8ei3oVUZ5JCNyE1mnpUM<4LUf=jn`o{O*QKKsDr!IGYd&P?a6^4V3|3WTL^+Q``< zuJiO!Z`xVewil3RW6S$dABYK6VY zO%V7op;hjBGDXjj7u6TV$KUeA+N%$WVCy@a-9GLeGVFm;TD^QH5m}V^(K1r!W%ep5 zF%%wvdrpZ$&A2)4PvZ1f_!@C?ul^zBYRv2DQPv)|V3%e0Vv8F6Q_JY z6G)b859 z(vKZjchMNQM9u!HVU#Ve2iD!3nJrqBIRT?hxTYpRRP?FT8`tH^z22`q?$b*5*N}!f zo=3wHX_iFYa@^%8Twj2;;8c>8YHRaY9a*SdN{rC(k@`C}mg)B9v3^~y%Qnhs_U0+= za?-TyowZePT3c8jvW;@g-i+-<_GRqm*&?YmWN(l6I;E7>ZEqIma;(`d9Q_8yMw`d6 zn9X@w`_pXB)7mQ6)9p)csV(<^_pGP<9kaOTM#00o-WE4ZLw92)abGsykeWyOEbyuWvQr|Rh_ArO7pUyf;P0Hc}$TGd`7-!+p{YBZfAVv^(F`{>5Z zTBNvh^;c5v2v2E+%jaV`q*VF?qeWQ@Lz`Pg+m;m6X%^Hx_Zrt)KX7|8KJz{gd6A`&Rls+!`ZwYB*K1 z>$0P3cNu-l=G=-obnQibf_R&>1$`ch{A=lVbG>**mb%KQj~k0V%OY#n=;Av7L+=smQczZd;)+3tVYP9)~wAC^CxXanV6B4_p#Ei6N5- zL00*BYK(o3wxSEgB6|H6?4$QYUe9s;afXaq9fG`{1$h3(>>O@M*^9=xoZHkJA&FaG-frTXYugt)|~AbA5royc@MPXlyZ?+L!V)3 z4eGNSwM+Nej;58)afe<$dmq*FCKtHRw;dJezAy0D4wqKspTnPWt>-l#7i|mO=s+KN zyHqPeaJa@;l;Cjfp-912&5|>8pYZXLU}iUBuvM=eHP|XyM-EaZ?}NQY54L)Ye70i+ zl1bK34dDW?o8QjV8b=vP*eX%>l_UGQd3anBDr=a`X&mfuG~qn`(t5NWW#|p{d$Ot} znYPt$X>%IF%OOovZeLdT+I~dOt}W4f*M_7M=#I(po{6TUOu9V)DQGNev98CRh14r; zN!>B|2wQX>5id|`Xd!;QR+m?o**46H3>(aEop?BjYeMOn|l(@!e zqi)-o<{Qmowx;QQOtUvlZ?9ZuaFkzMhg|L?;>@&@rp2#O`%1^7AMUD*by1t_jaGkA z>*PC>_tM@pw8CAitnIDi@FMg5e7IRc_Qi**TcI*fH$C30JiVcxjzQX;`++aO*CX{5 z`Pjl9!9B+9eQ2EhyM}|V_jjDnaeU%wBX`1C>v}2h(f=bp=HG;i^V&=Lc8bT)aYK#! zeQSjIth{G@_~&M+@Ut`SnPuwp6{%K^qTV~P@4omsRx0Yf;A+mz_J1E7>hkpC*~Gxv zAMD&{ogL%4ey1JYM!Oa1(4bx$hIhj;YV)@^Y(tnb&l3CVm_UcH->oU^KWa8$E!kuovF?K6sH9F+H3O+-Z(uF~>MaoC4iJ0kYU6#)<#Bz1gqMeRg z8#%JF4~pES2Q3gBJ%;Qb_RF`07F=}F%Pluf?s!EVG_yW^Y=lLGw$?&cw`}FgkZ@=_ zB!+uwtw7wjrEQGZ2|bN>8OT0)!)V(>yD5Q_@z6a&{VN9H+;>=!x&KuKjND5wXME=HG4i?C$LH9H@~;($%_Y-425&Ml#a1fi;@-h2|nto|zHmn8R$m>vRy~`FV zev9YV?d0a2doc1J-dvxr{7>?LdAf4iW(Hr*E_iIeePKQc+?4$weI`HWm-hU=Mbdq4 zRyWYG`M38>zPN1=Bm>_01PP68JFTrC3ulsHeAYZxSa*Ns@TaBNLi>&q z#&Fi4)w<`VZef35L#x1N+fG<+U1Igt4X^RJ*-k4-jwpV6c6iNrv_J7y;TyE-y5W%U z&N(s1yW453p5I0I2|fM7{uDdOj@4Z^U#4s~+()!-&;D-j+$N3h8*A{RaSA+nV&Cv( zS+{s1cKG*c6y7iQ@3F@o+f!co{deni>{sE3--Sd}on|>Shcl@R<$SLT z8#gSE8}#F%{hu{@!uK;~6TfW#cCsYvIC0ic8vNl;rr$rXKGmzDX>ZwTYh}l*`sCNX zZO~_bU$uAYm-{-8l=VQK z9mDa52}}G0I$_lDn4KSaMuPdUS5AJ~y|MmH^ZNPU=GpTrTaVwF56~~n(+6)Ke14|n z5-%YtzO{y{a7kFwJ(2TMv?qtcxzf$GSKnnXsoP_4%BSlFS$52K2|ooVa5CR%g3aK( z;b1+2_iYr;fxAy<`wq0JHPN<5?Z8?Z)0Fu-UkUV7K98;KlTnT-!$90>=|SPMY~^(J z9_tobR$OoAw868TO}4MK+9K;M)xR?!bHDMp2dV!%wa;>8FJQvY7kI zzp?tp>f1)Q>Xr8A9_vkJf-S?;W1Y+w%tx5v*s-4ONrVGFVs{|1i~CxS`oR7%0KaUj zB>wzD)ne8~N(UniCDMfKLx&CXk#WB>$a7}HZKLbFZzuV~beex>Q6BL*ryC_|4d(ro zay0!sy*PU9ud>b*d#2+d3ob2(YnYvEtkjg@xNJ{);*?~B)�tNc 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%0A3y8(rT%Jv<^4{Q7Hy(5ex`w& zWBWhTNxQ^-iUa zBemqou-~11JY~hZGESZ6+*9zaf@t4)S);KQ@o>0U@0RD+%Z+TR7x4Tl?g~{@CnH=h zBd(LVo-~U!oHY-@e?P*h_ZVlq#e7-~TDV%7S{c!qMop^K6o%?Yvd^9F^uLXpWN!nG zX}=~VrB79xXV)#PjdA>zq4z)W>OE}uy?E*hi^5_Pkt*j$E@+>GqqlM4jrvNkGZnE zU**^`U6^bCp*I2#S-%llXQOb@b96;5aGwrXcVoxW=DT5|Fl}F-&ezJmJEPR*W2m*Z zx7JdMH7A>Mow#JH8?(x#W31mjEXY&$q&y%zZStFk*?ueUYmQ~o-&-6}xu0yD`M%aU zVsB*|h}uD7wKVZM$Nb!h`%+k<5|L8mG>!e_zb~2uwvOGl`+`bfTsvW|X`7Dz)BBk8 zdo}11K8x%3jzbDdcL2w0nzl*fM@fqO@g#)_FP1Nb(RYTP!{ogr+p6d2dr{*+jk}EJ zoYj;@(Kx<`EAw!m$IpF6DIw)ea;}>iaB98@D@7!x5^dkvp7PZvD{E0ok$fI`G_GF$ zdz!fqa>6^{3pb#|IXRcRF1MXHU(}kKHDjuR8yq_?RD) zHu0=yA;S^Y0!nXXBN zM-Q1rMn+tBn|ZWg{U30`jI*J)f;=YZNkYyz?!c5sj&F>H{2o3CwdeH9`9IL{Q|tag z=bds7ZBs{g7nUOVXr+Bwi}q;|864*=)FR)$hX|zgkur&EFs;S-S;iDo+shI<33fV9 zIp#FJ2A=f%j8lCFd@66ekw+cxE@cK_&#y|ag-!6a`*=#oudkf%>c0!B@_rXl7RSKv zgoq%25B7t16C)5e*S;OuE!bmwMbDEx9h0m{_|f&nTJE zc7D3%kvV1<|D0O<`}D2KhQlZsD>YW*n)5dtnUAXepK}r8`~&3WLajbMrRa-Hf0R$a z!9BnnIoI=DezORbXfGayO|F-1ah&OV)Nb7;hkgUGw0%FCx#!+dHuLA5U!hcK*fa4f zwyO3y@hlV1B5zC60=X7u;#rvG;UqMtwmT(Bu64FOo*#@$m8Fj-_&Vh2Gy-Iq((-b> za5>}hgk0-9nm@z*8O8Gzd}qJK=QlW|zsAfNhh)4(Y4Mfstd|(eeHiThRFyVoEgN6X zSLtkKt|IajUm`|^BmEvD{i4f#%E-+6xo%@j=f-hZHaFha`ybFUrC!Bm*`=2%y|%{A zkdWbhooR-xv9)!UYIF{x<#1hVRe#lo8QwoHUcvJ8D>-Sdzx?&m6&<%C(nM_>=$cwE z8*}G#ohx>K)jDPi7l;?~O0Ad5#V8l#EV7(Ilo!w$^Ge$ z@m!V>sm6sHW=|aSc-d7Lcv2knxlTgX7--2iNm@}&i*wU2Hm^-Dqe&xfyS?@~@!Auw zo$}i5nK$v;6R-U|@!IDPPQ~#WV$wwCDkol>r=_?IhswljPrP>Y94T`u2xD5=0G>B( z_2!R|*KS2lMBit~mGG8UMhM-xvDd}=F%#()e61M=$on^TSKsThG%^p-#C_Me?%K17 z6MwNd@n!8O(b|bOKYrfad{ojrty+&YL{!ux?Q+kRG^f{Fu<JRXrcnYtHFA+CF zZbQDB^!<1?%N%PogPsy&bJZ={7h{O*))C7<_u7Ho-DaHX#fgzEZ(EM}VbP*RfUR|> zMC3P9m_@G#eV6}82_tXO#>iFKhn{p79!1P7d@YQEdG*#ipV+^2PtU>=_9Ap^w$579 zwDu-ET+CCd-N)9bQWr;++8I@fcWsOr**SRsjw#0+;AOe?jQ2YnHlO!#P)h5JgIQW< z90b!k#ZQ#dTX$2zZaBR?+qUQzMNYQ3olE`<1ok}-3O7hY(IR`vi;CX%l5-AEjt9symUWY z)6#V)J0|7$_Za7ras??5D`QZ3QycFGVebB$-Dg}W&)#YphSsT|^T6u*xsaX;^aD)K zH=PY*&(n`FO4%Zx9-M3(5wo}RrcP#c*F9S{lKL6u78Krc`yuulqg+e)*sO1MJCgau zna}bDydAkeeU@cSp7!#B%}+01ALanK)%g%|uU|uZ-1qF|6RgPtoPQ6nK8z0L-e9bX zjmNnee?~Yw1~0<4ay;Rl(LKP#8U7GXU%+RT{=*KdG5fCG`s--XY1CTB3w<71{sJ~n z=B{77U-=Mnmi%%0;55?crN+WiJ~Q$i8jnA#LrYXc(AruMT26U#Xz9(epymCxpyeg5 zA)<(QaX4s+ZVFnw-ER@xa@w0iOK+A1E$_DlEiZ8mT;}1SrISO@;vLM3K+8{`99nv_ zENFSZEoga(Ylu-hJhbfW6ukJ~Vi2=-NJVp)*}G*y&Ds|QciIyvSS)i5R8(BNMzkmu zGnv6)=XV6oNB6CrI_$))EDv_h4YhDC9iRPoIM^9qCD_@CxyYHRm8`+e`dAk1to=T` zi)DCrj>S7-vHj{a&ht|oHP=_$HxE1M=ws|@!IykMEJt6yhusHP6VXCIbxzbTX*BD8&!uG69=SPo* z>s{;kY-W4$UZ|5-kYt=IVIQ4c0D54dP$$!t!94+x1#Z$-Miq3 z{~H|YBgjb912fB^-wUN%taxtdd9Kc_?5+y-W{){+uCd8}6IZ_WeX`p;&vqO7 zKJDNht4(}v!E%XP6Y;HOyE*#(MU0v>fn+_Exa%=+>kZ3eKPCE#VM3 z8?}+%bClma^G@J6>@;vL;VAh5YPcw0@vbYugqk?US^v;!UY(=(OJ@mS`9I;?*Io9x zFFKx3r}vAI3uHQHpO16)DDd`lor)R_<%YgYy8U!3?#$ZGrDPUqk>~MUOKt}BoS%|24$_WZQ6M(r>6fO+lr^jnCSak z7&ULsy$7qoIauA<>qStk*k*)AImT_&RW!ZHv>V7IOg-p6JTa)-+k~b25q5R!}@K#*BGcxTC885xVppHPgdhPYVYcEzTaidJ-gr-@>OQUSIoNG&a7J>A^lwH zeno8eUgy0;yREYG#ua7HTIbI?io*;Z)Lq0q;rlIK?)AExY*K?eOvjV7ZCi>?a;?BV?w> z8^Ek>l-j{}Kb?eC={Q>_o#vb3QXJ29w9j*Rf7TO6wh0Pz6TceIMZDYTPGq*lcbj;- ziKlj2*07RZ=DaE6O_WSWN*bkIt$5gc#bfC_N+G^$(vJwCG3%t1cw+`5J9Tm{?vsvF7B_2I2=ZAHzE*#cm3j*@JLh4iq~T@yH02l;>!*c{ z)?=#2u+w3&zG@h4{nXwauD29c>#(h?ci8b+f*o&x|8-2V(Zpvq3gZP9oBJZ88PBaP zHl{kv*KsPPGNEI9q>#0}rZdq`!jzATyD#n#+bMa!Z-t#Et|c$wBTM&!wP+bg7K2aZ zES>T`%Os~yDjcZwZ=Z|x-`<;JdAP;;t>K03jM}@nmcI7+TE$W|ZSEpt6}}mi?Nc{| zZwW&CD{cmQf{fbxrfL*f=9yns03Vw2LF;Z*67HcCwS} z04ZgZyc6-jT5*{q&*Mtz&LmQ!D=DABHmv>|-FYNWU1gO27QI+rBIekq-i3h zVBMiBZ2AI{7iaq)-I#vpAgw4adVo{!^6${X=w4H|jY)%e2{JJ$V7qN<8FyxFe+%fD zO^n~`xk!KLo~QZ2;@WDy98cf)9%dSB$y^Ym=?K z0{i_2e)nO?XK$BRsEIwZ@+-(P9;5s&<%~-<+APM!fUDR-R*^Bu?7*1b$Ut zpg*=NeEml!X-CeA6!cGlD`h*%6e}7O-_>V*6ts%Hmb3XYFpW`gX9u`Mov`#)=MEJl z4AP5Hy_|#As+bq1wQV<2?Lr%H9iz1IQbMG}FKrwD%gKGq%ld2YTROkoJ6h+k&cX|;=Wy=Pr;R>t zm+_b1Z?Cq-VmC*Uf2(=}#_wDS(yV~!8=mowcS*ZOUozVCLoE85dn@szz^?DDqS z(|=oiY4y$3R}OTGgbUl-fCnD$X0&p@TK#D#^$O<18yjPZ-_G)l*j?njg`D5xJwKci zVaea9%`mGDBlkFei)}D|Saj!u4ugBoAyc#gNb z(O$#%x6y{(GD#lg_UhRcg9@oPSBdSi#`+5XUY_MzA*H{KXS&svSyuR#<*%V{ayIIV zcUBU{%*XOJemOGvHSVv{%8awIgUsDodz*kaN6Iq%%bPJTb|u)x4LsY%T*WQz;v1j5 z)%^%7dB)W6#NX0u{ugMq#21#aQ;MG~nPX3_OpZ&nGLBibwhewt0>(wU)Z$vf(44Om*jO0jnjS918+bBBpNDdAvmZ0`1dI$!P#N>%N7 z**H_liaFVo7sz&w?^A=aOIW$o>aZEYIMepF#>erS_J1sHdYd_p#@6z8HY>yPH$ZuK zlP=dUU#Hkk{;sbbU)R`zKkchqVnA%8eB0NS;Y@77p7qr$am&^wePioSSQ?hF-8KC0 z?{cikdmh3aw{l0D_RFB#TcCYcK?`XU+gQDcCp(>lNlEa`>^^cylpByJ*CBhz%B?Yy zoAI@;W1S=vo>TdLr|+=g%}`y7mL9@!!OSp|pAkEAOpdFXzsq49+sQFGwv)f>Ysc|9 zw%||u>XvvM+bG}mwPhF`Td-$+^-^4pwbM6h!&)*tC#_BSyi(`V<~%vWl;1QPd(;us zc7{%VoYSzF$Or`cLo% zPr>_9_f5VZpP~lgy@B`i{rC*<=G--Z{yj-;#V#mkT^gCR7gwN9JlqdgSCYyuY@F1h z)BECW?20wuVSM%m==>ev2{VjcJ;3U9c;4_H3G?+eFJHz%UC!QJpOs=uv4!iX{}fnC z@6hit2KtD8+l}Ee^l-Izc?*YwL0@gcXCJyxYCsk5`62#e{O1jfjd^S6*+##WJm!L@ zo#d`7IPoQi&4Od+Nnrw$_>0VVgk$I>fUGfCTb4>Stx z6UMEq4_AJNb91}k`qT>f_Z{GcXcsjelC0Sm^%f6daZskzYt1smw^(W$b*a_hr|CXk z#`kwt?{sr$_w~OznH{G*N>e-FIa|FY`DlIKVa^Y;{DRM5*E2c3AujyPa5gYu2Jkh*waaJoEW(lzTJy{IdIx-h9+J zs4X8u>QUy;%X8m!Qu}CQ7jypsyG1q{=^oPO)Qww>npQ&ZUg_5JGRADB{mD--+U-^2 z`SSAXsQDhCb9MC+bXIQza$DWsvYnT(TGZg=rF^cWJgF`%m-^Ye=IisyxoVBDk+i4qAI36n7Juf@G(t)pNao^NTL2^wr4QH)xXj z3KEQ=V|K5Pa1OYyG2{1XJ>)*FulxFnR(>6OHtHjNhniMnw`irWOxZ5|-TpAMS4~<= zuG-ORE%S3iI6|yS&kBFuJ}~53@;VWge~l}{B)_8OivFla?-&lP`Po-Y0_o-O{gJX!qRFR-K2)2026R4u-( zoihGDQXG>=g^5Oq((|TXrhV$vda9p1UNS#-T5q^B{q*rt`3a;qqQDPVQk{*ge4Ozw zJI>;5oUYs@SHLasRPk2J6U^VGr&#Qdry1uX4rC8jjbE<*1}(=j4V*UqW(?5v+ywYq*Pwnt-SYOUG{%G$13lAmvB5u*mvY+@eiWGnJ;#y7GpYnPuK zcj{4JD^b$fyp4W}o0smVy?N>i+jB#qKZLPr38a`WV_YJg-xu=KW<# zx}KNM&qF)&hRTUD=A~-qMP4SSx<=>fEw)PcQAPGxqq-%<9@l4CZ%pr6E$RSddw&~z z$NMV3u?z1>NRrah=(UHt^jAstV={9Sp@<|UZf>~W`?x{Xijt^A44!B3yV*fm}U zzuwX*D{q?Yaq5>4vERCOf70xyI>n>Vh6*d?4@8~Fi|CnXSasM>X^8u@*oS+^@tGES zvJsT9Bz%s?Mo`-o?0pRxg+B+)T*qHoVrWI7rDhY)QB6F9}277MyS9ZR-#(xdE zq~C)oTU3HY=2KJq0CtZrU~PDNCJ!;5Twd1vi(Gg3UGLk$npIq#V z))}6*^c%c|@ljt=Z|^$b#vZ9}rsjDAx>{;Q($UxJ?g1j}oiE$9u6Fe1qt>3@d5V@k z*S+6E4}{j;>R7mn*U_HyJ}hk-L`J#mel_zop;n)73E9h?J&Ia*j#Q(K7zM2{T0V;& z($yrq$=l`63FSA6r-W6lG~r;LDkjUbzr0oAj>hJ5yaH&HWd#eBrRG!Lh_(90_@DVR z`_PY*Q8CPOpmmq#IdAhi{1k?A73{(C&X@$~wG3Bhl#`>dITBvXK|zSp7i%BcNN#mA;B6Y*A!neih;d78e)40Klc+ueWVIyx!Nf?|L`c z4r^X3wkG7XD239O&i&^tj<@7wRV`s7P2&3LGGVJu9dlq z&VjpSmNUW0v)So?Qk9=!1e9AXZq7<7%cw;})JyTyn&2McM~Jv(da*S~+ZeMRwHiDb zQu$ZfXi*dAU(~+Y$dB3<&XLtQp0wX_c5v2l4ZiHhd`90{<|F2vC){70P0TZ5S_AS_ z7MH(^Z;bV~+_)TR8tb2C(j>*O-B8+@*)k!k3<1hJq8aLqWqW6)%Jl)A*cC|Fss2RT zFwvTReOg}Ev^^FRq>L2wBD35RHa^14Dd&8>n7%IdVi|6UXLxI9+VMHtpV}eT}^@qKO^fpY*}8Kk0_Yw;(-V+CsmscYNE@|Hih- zN49jq^o1YWw(Y0bw(qA!^ul@1asM$Bj_$ir^gbiKFLgR_`X;6|EsL)0gkc%P_QDy^ zG45@v87m0ior7Qc+g_+Ij>HuC3`ztw))#qVr?HD%f(d2FB zQOnF{REwAL$Y=6%WA0gyeNVAL%G%D`9h57K(h0elukfjLQWTV))$@jF_QG`D*ubo2 z7Y{IfJ;Y$P<4An%xMvreyV($kBf77GnsntzV{B|K0~>edg;|y~#!!(oGi6D zE6oVvH-LAntFu8-;>S4(uKydr*OMFr?S>~mhLauvae)!a+!?RoM_j@XK9`iDb;`SR z>i%W(Pzq8uT6h0?KqKA;ub0Og)F=gOwCRLpz7*xW09=eY7bBhM(@`3iRKjC4z zpO)twq90i5>*chPGd5W%eYys^L`p}kR!N)FJBIR_p0}CO*(LBV;<(9mU&MdA;Ow^W zm%di?Y1+egO0e`9;(are59ncab9SbZ<7Te8=+j4h1_YSTZWkr_ zOkBCmPx|G2F7$*l{kqnle_cMTmuFk0-cfe{qmW;toXlH;l+EFrPDk;mJF%Dn!t!O1 zdysrZ{Tuzb(iJ)C5m}}=gV)h&pp|ccSvT${at$$pS`NyfZGC9}KFzi4rT#mgn_~if zImCsv1yFcPc zSkS85jyke>bxUObI=%?>HbP#oSe)Xn&2o1$kNfjLb4#pGDHh@3JFmp`vVLuE#y0A^ zmo&!goTV+Dqu^e9(fI+(5=$@rS8Gw(=dg&lnd5h@{&@U$3ZD9Y5R=`*!N)^?$5N+ik=*pJG46u5?oz7fUW)pXF?=889b#QU#!M!mi;~H$-oA{p*4UC4k1kV|Z9({k+tuQ`=$ahH}osO7% zr|A-;Z6J+2ye~UP9&^*g5vBSL(|!|v_0h=IGyWFhGFHJy6UVWJdCDW`F#Z#|A7Ok8 zI=$mfK$O1XxXN1SHi^a~_kKb1lCNGM~ z&i*{ZJK+ZjM&qw{UC-j<`mV^5d5eqKkfvfus*a@4)ff?HZFQGMGU-@s0hI!uC3y-L{W;M9@t%-unov{8#GfVRctXrQs z=R1YJK%8YA4-7Y-00!S<_Vi_XiWN?MpdRAwx6l%N)4ijAb8LC7^9YjHv)S<3-j^5? z$0e!HWL;snTZ&>!wK3+H8dpNSM4vRuzvjJ}Qb`-7dv->=X^nInyVme#Xr$x(=&l3G zwB0Zl$G3nsZ5J0n9sUIRL^}=717fl8XxPdVM`d#yuBDyR8cT!>$HG;7h;?*-IC>{M z>16RI2k^<^%{|R5SXZLHU*#>~`CTS3?9Ksw$U?k%>WTR20uXDdqU6fKv&qS203 zTf6wazDm~q(XP@E#Uu`tW7GO*mfHuIz}ec|#EnP&#dv*DDlzk1XXKnR+pvB9egwLA zYes>1*597>%y+e1lrfG-8EV+BjduLlEU%8Z4e}eh(Psx|GjI4|i{wT9hklB@pVzqk z7>9ycLH^jqy=bhh%r_d7>XX}1{K>Cz^3%R;HwRg3t>~1zl`|a&tyN)fwY>BO5AXXK z;;MM#G|xVI`Ko?9Z)Dkm`|VTaBd>C~)8y`9Cf1&psb#1y+w9AFUu#qT4)XZty>_(B zQk$$Xn8(C=$Rp$s@N=W(D`-8sE}AprYUZ=e*TiK=y&=aCqXKl!xp$gu{qj!xv^({U zPM(H{f#V~S*`xv&of?fYUFj1MGl$j~VnG*8_ z3CX9~PojY1@(Jbg2ak4O%bxFtPp-1!i>!#zGpAH>OZ{z6C(eyQr?i^KL z!}R88dU84=J-u*Baa;5%eFUr`Zsqv+S7-yiMugXQ2PZ2vl)2wyUMsyNC)IHGmCZdB z$JcCoERJuZ?zuQrKlQnB9!wI6Wos#Coz~;da$g>HTX{kDL)Z;JI?(tj*Z(JY zrfmPDRH99G9vCHIOd$2%zUExDGZ=MB38^Pn#QFvJTa|~9eG|7=(i=zZ)3)Jl zQTlG@(yCiByf$;)nbq!mXAxzt8?(duoccAZ*AmYO)4O^v(h!(ulV;%-2*M%P+Y2MS zOijDrYQN7`;dKZ#%T;BN&22BXg0mb-)md_dVyh*t$YQ|k@syiO*tWF8fRx?G!KZ zzqUrH-o;us{JaAEeW%;y`<=be=fX97V@8=j1c&uQ;0R@>$YPVT{%~mTXZ`!w$`&+!33}{xp-~9?tcOzCP}}|Tg^zF%2_n``av*=YyDgFc6p6x_w3)!x#;Fj1ALX-vrhPx7n^qHS>Em=6+Ai zDs#Te=jFH@v0uA_d9UcrMhPl%U3EX4KK{iZa?~@B7n#m<&#@!iw{fS`zBaS8gxQi) zuQfr;y#4NVFd^)&jDV2(wD`07xXM!~gVF>0N@WM_(z^7ZU2m`-k|5aj8sK6aa~TC<**;aK>qO2xJ};r@+*8h5Yn*lNd0d+l?@W&^#sOc% z-)q?!Mhq?SE7ApGXo@XuK3TleFsGZ!T4{t+nXAM0Q9QT3)Q^$VtevX1hjLysU5#b) zk?G2om__c-WS}wpBXJ|0!7yhiZ0*+~6PHwOn9ozm+CC{yL$x`~=aF_1uaA<)J8JIe zKX6i$M@ji1o_!qs(Q!p$WnO5;4hd^H2LASO zAb)@zqyLAuT&_ct`BQKt{{y@TEff7e>~okCVJYzx+*L6rfOGhq34f>+qppt`N0@P3 zzR!0Laxq((cvthr?5(w-GVJRfc)?oy0&zq5KFoQ@6P^*2rhC29#dLgzwizd3EzQG` zctpk1nLamfv({>hTS>F31qxNgge|IrHC4r_67wYf3dAonPL)C!@~(mmE& zP?nlLtt0Er!{gQZxrBA_Gb`#XhxLo~_F{BdY_DJAn9qe=2BoX?mMPKLbk=D}wo}tL z`ppQ2IZlaE%%tTY<>znVv|;q)M_u$!%x7^1Q8j+YmR5QU$H;TZDOZ30HeSoUV7bGF z`Z3CDGBqt}8eyuzR0ci05r@eeooV~I0xN~}9!pX48hsfeHFG|(&QIDpt3R&YUS~UC zW`t5_$lkS!)Ca%M%K_#Q(4;(D-Tt)J7v}>-17mzB^JO1Z1oQGEmj#QMY1-j@)KF0l z0@1U1PFi80U@=cUozVTdQ#*;Gen`19iD`>NAlLsgYIq~l|3(fk&M`jkpF_@b`I+2@ z*}3PP`X)a`I#eHdsfX1%rq2m8Z|x1lxHCI(%=xg5GoSa3ryK-*4%D7=sN#HW?|Zw8 zP=MB)7!l18@wArgW}{~>?}5X)3!48SzVEI4IhosdNY&={6fK)nXc5&ub9-CQ&Ci|} zTlYm{jhPQ1m2Bf!1u@CC@p&6_V=0qw{Fy_BE%!;5E#0;~Ux!ECPas!P%T3=H{NVGI z)!%ipCjb8lwBJ9&o1fwNt0>p~UHMg4+Ux#y)mm(Qa-^v|8g=3p11w0bBaZG{loouh z1MiNuIK1Zen8$)h+*}#5Ccecx$ z{gNwtSwv&rU#}*Cy7v$D=&%cclVCP(^P${_bZ%LY1)={8aF_0nHox?~2jh^&NNw)} zip;OT>=VwxQ5Ixw@6>iIZl^7im1En)8tmZLZ!GdPXh~WfjuX#2n|!U!9gHjYbh0`3 zNmxEV!i>5jKWmJ3e+zhggT6J_`J^Vb8YPj`heK`l`ERfUv52>9d-p6k%P7<+V26i$AArC zmVW2`B#!`3`ZzNmyu(I1n3#Ei_Y?Cr0C4Hhrt!W$mcD{t<~n*0&-UN7JdUoF8}h*EZ#Qr1Z&Cr)&7aKPN}@@ z-66>`?u?l2A(tz)Z?t#&B+FQ?PqtJ!8>Q2F;!qqDp`%_~@+C_X+Hoh0@fgWDN#-T7 zOe~~fXrPQTzT~M?1dgb|2f5_Ln%XmEt{!%t~VUm%SCfx0bkXbDcF? zJG1fE9!kJ=kjdeVE>d0av3m(jXg?uj*)k;8jueo4!3MhuBPJJ-ORO7R4=8PTI- z6MbLA>e61ahtHd!VS5-2M?`L81HZ(TeUzXd$4z{@*`3Q551?W8Fy1L*x!10Nn(iG~ zqZgM=>pF|5ZFJ5?t3Yj)IDCJjvo&3L!i$hFJaQ^q<7U`4f3GENsb;?F>?0k8 zW6r$0yMzqocBj1SiN);`&`|Qx^!pJG^7feXz&V%sa*FHl)Q%(mv+lVL5(W|bJX-08 zR<@rXNI%Sf8ReeWfoG-Uvq(gN@g2N@kw32;(B@&;$JUOg*qJ0EDwlTBQ%`S+L;7L; zocao5TNFISA)`u@w8OnmXy!X#wD850b|gdGZ^#h2-Ad=zki5fEgrn0$?v0(9^~Lb5 zPr_mCAE$I#ZV&a7?Au^X6dE!;jcZyzP!KhL@e zpU9&tx8c(cYf^d_&m`{8)+zbo$bJ@0_A#LGJji}|d~I9$qSyEqWchKF(6Kalm%j#R$-~OLLG<~L>HOYhYEWrEToo&dtMYbVBmj3rp8tt_-jR172-p6;JjIWg&xQ$2ViEUK zN_)xw353I8Io)NWMfT?H8Kk5ww&xx53)+KXs93u)tTtm{XYBuCJH-4-{#CPs`zd!S zUT3~K&b|d}ElTBesz5ro(c!@OxED55ElmhfuFnX-L!Hg&$!rbZADTk#Z+xt z%KBEBUtej(yZKt>($Nw-GXG)H7#ok_=wTyrX>GY;+z2lMMLCqq=L|9qe)*ikiuZO= z?nAqE3_|P<1m2KB<6neCdV7Og?VQ|q)^_}V8Tp^tDwI+_e0KZfdW<5qXwb7$!&9bv zQTw5OJNsNG!+2b}2RB>y?lUaNfAuZtf;k;8HvOL8(IRw^sT^tqZKP2o;mAk&RABpS$)SM`oE!f;`9XL4z5GS)j9rPv za8|g*A`(H6ddE~qBCq{WA7yWD^?sfR~v^} z;ts+2x-Yd^59_maXAE0k8*%*<4|&G?Rz2+RH-Rcr%czHPe(aQL zi!rsoxZaog;;>cDjO^$2$Stjyor?byuAYaLYL#rmQ#z;9 zhg7K9*DW{4659G>?ZmU`i?oxEz0OmNKZlsQ(RKe!?5JwK&Kha^7ie(w`z7UZjUsR8I+F6PwvSl@-U(+*9;GK+ntgp4@6ppCF9qE z120G|_`PT*N6!D*@a&8{;}h28XQjPe`Nh-Wp_G|P3(C2iOKSJk!-uj`wG35x3#(ZhT4j9> zgnqm(Yr)QK3moHBMr4g^vY)(xmRThnGX{$wvo9-*Rf$Gf*cPY;6X>qshxA-VvMsa_ zyXd8``nPjPo$@3iYhtgoFU_Cmy9uUY-)GV$xcXE$FZf=*FK1-u@ULPFyqjqS%h{U( z*OuoNT8LEwZ;>Me9rjcCq`nHA{1eSn{$;{>5$8xP$pLN~#Ltt8Qg6-Jq@B9`gsN-0U zAH?T8r*ieCPVb=p+Z*nE9B$4v(@sf{!yb((u}aQ{I2ZpcaWYRF(HbsAG_U%7!Q@)U zTIniNwrgBtY5fyxU@WGI^ON~%>Mq&c{f{y#!)-+E<;`La5fTXT9=03pt!+P728tLlV%HpkKQT=yBqB;w5lKJ&n zAIsQ~;e0M~Vr>Vl590`@S0Kr4qD}}EU_RFukQ1yMCOAA{JK0re!3@rHO@U6SR_J7laV`L5Q*6Zsde^n)PImQ zyB4h>)Qo9^uN_L)_NBx%S=}E++QDwKQ}2g0q;I~ZabS_Et1nRwz42}lq3LsJS0$_( z2`X*J<37;h`|_JwqtNr2BYDi0j7@#I;uCKxtYzcVVCT6!tF1b|Z#As2NUc`iE`6|8 z(|97M2g>KDtu4fwR%^5C0%Uj^XVUBt<9gkz2?U{OG4DaI zIpGMEZcjLZC;>xpL<&!wfLB%825z|-Zir8W`?)1l2X?h^ok-L#1&QzL!V4LG;=fYB zCA~h@6YnF|pG`V7TVK{^J$%tn2xmmcU&F?2iB4W;!#BJamZ#ow%FSB6Ce$C4AsGeE z3k3(|HxoMRhWsi`cuur{=j0pTiClLkd?GF$(UXZ~RgU#~pf9^xC41GL^o51?dFh=9 zJqPl6Pg*??%K68vRn6UfO~$e(bZ_q*Qq7zJf^-&X;Nz`eM(7>^JZ--=VouLrg3!k9RDOvdc78J^^NlMY+2IJs6X_MNL%y}r}dUC&Nnt5oe&w#v3n zYO8#DPP^7MFR8w=C1lsmuS*fqRycDpUTBRnZ?kKhd08+7?K=05#^aq}pJSFLb~Dc- zn=uP7kB014(fRqd_L=V~k-wqoBJOBTvt2K^lGz|>W4HB78#lDZm2yVu7}{7PZY`G@ z-j`dZX5BWwyzp~rC$)b^lIK?9*nWL0>m1vP=(D;l?gOzba<2cpP+6W~U_0_dZr}a! zyyM;NTE#A`7`JyVj4qA_;?lN092vKh=Ke65UO%o(+aMUZ1`@59YbOYFIZjMIjG;>-F4B{q|)0Q_nOAWqn7BY)!5W=#0%>w zzAf(w_wZ-IsP_fxABuz=T>3(8PqkqGUfyww+IQ@2%Lv@hq>Q&6OU+X*MCIJ=6Xk8V zL|B` zY3=KziF;X^xaH}^820)g#-;KxT>>Yc)4Va{s88{m1v@GQTSi(19xzE*DzSo}A5WM2 zszMN46R@f9`Hf(8B6AqD+Kqse6Y4wmK+8QGHEyioxNC3y3>ND)^Vog-8LYG%yjb}2?TARK3t^nUQavz~aUSY*js+)P-4tHcs+3Q&S zp0}~m$!b22SL9q~*l7KQB*_-XoXh z#@Le|_8+OY>dA~NOJ%6N=bKaSA3mQ)240$O|X zM4HJbry5cT3@iAm>R>f*0kLt(RX^FDnvSsVKYOb1Iq6tyYsLDkN5@)&V8vOsKdZMi z-P*V!vNXKo9vt!?V|Xm;EL5k;U96T7Gtq9T=kZLQfa~HF058r0{yQUhk$k~7L_XB^ zV5Yq5`>Zc=78(`gIZlW&c1~oZYPHU2$hbnb6YZ0jXnQiE55yai=u+6W>)7A|_kvX* znpUrVOYuvGHaoh4l^mlIuYJ&Vz__iVMzPFJ_E-wF`W+7v2UbdZaEG<{hE=HMnEzZjdTC6%9g>u*GU#V|3OAT+C&oEgg zu_H6isTKs;9C-#)zCvl+)~a}<-4qJpbsRgbV=XMURjT{J z>fCidvCgM9%b%isCqf{+so8+X^D8lJIz!LxQO4V{xVy0|5ROX6c3bwu;;gD)!jAAC zSo7T7_+6mfYp|5+e_WH<#q;GnB^-}tb%t_CAwxNjn1fTOP+SD}7)KV4SIpO?dya6M ztDhqg>xkR1{`p-MXj=XJ;AeMV%KU)%b<7XXikGo}NCwt1KjIU;jQOc=%Bpe9p6Eo8 zr>+0|sh#Dj=Z6dlecfv2r*a#o*x8nF(C}E%9^G*k~qgWv0N3 z=0ZqknV+66p4V50lk=oP6Prf9W=*0T&+6<+%JDGDRa%mC^|%TflCJ(%VLj5_-`I8| zUA@h3F{03>8Mm?ZP@3E{B1BI^HI>#a?*>^I(kraSh_0uaU*uyNvrAZ z=s}$evm$>C^J16Olj4$;g7(G_C$(EJ{eOw$$-H9nA3c{y4r2>yMjgk@kJrYuG0H9Q zH-1a}%-aGppUd9;U$M~TJ9sDG{UK6Pa>;2X4J|%+WuXX{()z;kcnr9Hm5$Pet67h6w6+p%bjR* z%DMVFzgogzOCqcLs6FIs5YKJwlZMPyH3)jv{;~6{rJ9NqHp@L??QDM>PE~_bJ7qET zu_JanI}yyzZEW!l`dV+pt4AZNe_2`#(eKRHR~lBIDb&ycOAwuvgcLwdWt@$=2U+k9Ul zv*|eV*0G)37CGR_&0jT2TnJMBRDv7ZL26$}@63*f$i|lh!_<3JDP$>mbjwOwtk=C7 z=sctzEg3MBI?EVCm*M8s>cLUd*KWCN6O_!Ett>9zx=d6QSrr7?{UtSK_(Xsg) zFAE%%WpypItW)kltv*{#%niniUG|s}H>}Mu<89F9_|Z1J)n&XFO3ww~zb#o=IC-*q zkk7%b35>3_*zEQn>!DUolJ=V+crv!va9Yiv3o4ap3ZKhJw*xnbC!5>*+xYDN>c%;i z&7aNe-bUMty5C+ewR6jP2#t;a-~7*ljo|c&p`dsO-pSwhd;c<)ZmT#jk@@gF5ZPos z+KA7)9Y3OG^GMsD31@-bl6pLREOfWo>w)v(|G>q&0Z(7;u$1&M#5$e#j&NBm&ydcp z^sd6Es`R?@SR{2Bytd|YaGQrei6!IZ+m?j8ELoFOQ_9x>+JXC6BMI_Ovl00-MjOXw zU@y`e!}|T1?1SC&$eZ9DXzxVO(_INNC@rf{8OMZ0o=s!`YwK5sk}A7#)u+?jY`yom zMR;qu{~P1T>oC?dvyzRtzhtW)Xm;J-gTop9L9mvOgIkjovG|xaUw=|Ym(lk8l-io? z7p-)aDcen>);OJ-My_E-?m4Uy4E0t8ij+tBG_0g(9E84NbZU*Qv=aJT^t8JF%;oIn z?}MZbx)k|qNv~;kn|DOR4CRF^OQ}lQrG{m|Qu(FXrmL1187^hmTjZJag7q|i4?=6V zLJ8F@Lm{KVR(*%IcSq`yWeZz(MoJm}YSwe518)UwJ6IH|61YDTo}3n$)9J(WRkzaB z6QSI-X7JI|$n!ocTgtR=3~vXC?{8(ywL8H}#rMMSlIacNtvT$q;_Z0Z?z_ax4T%TA znzU{cZz;E<_cyhB#ovO#%e%$j|1#V+NZ#QPu+aB+@%`dYTQLEcM|s0|z5JbHH?3K- z!S~vZU%+v-=jokOFVntxYAx1pA1|5TJ*_wC4dkWrTgcy(H<7+{^l{ zE8*@#q_g7_2PI={Z2m>>KuP6V%pX4URmnp<3XRjW5*N=)=Ip7IM8RA zV?fK_s=1Td+cyCtf{Pt1y53pk3#xUFKeuHczwVHj#B!0hgyK}|5N>s|lSt1DyTr)4 zb&>J7;?GZn8`0>WUyI&Rt#Fe)WkK*6Xcn=!uC=QpIR2S{6)KF2HqNGYo5SP8*(uHPN-2rst*uk8vef#F^#nN6 zJ|<84+M2RHi)q)EhhO@}B1kps_*iIkE%$Cma{}(TEWZ{DqKdY7j*jBWf4 zE`}Dqd&n_u3GT_c79GbsMvq7E%>R>&S`CCVe?I6t;M*zdwk!E zU8T3N73AYJ>#4LwlgMa}(eK66G;V|JG1y%396bIrk!~Qds7n-d1sKQaL$3kN!K%5! z(V|&9eG-SbrBrU+rrX`Kg3KN9EUedGNcJgdIp9mAH>$Z)dpG8kV^Wne0$rMIxTI&* zZVe1#8l?l##tpFoC4-P^{LtU+%MVt~Hfp3$_Bn^Nlnb5@>bl#SpfHUoJwag%g}Ibv zUdYSqPtZ0&TN~$@#R4}k7(p(b755J{xOp6?4@EZxKl}P*w>RkO=a_&OVg-FAzj#BbENS>^DGal#$`cLcjxGpP zLO)u4q(j#{mlXUY|}`qI&1No2fS zIfuU;&f#xi{2t+*nC)jfM)bApCh|4v{V2cpB}(>lnb$M<`LoP1Z%-qIGt$;*)$@%O z@P8{;iFh?c9Pb)c+Q$7O8;-?V`>WJ{F3`}`j_%!d=kDe0l%pBe%2SbI0x^H7tWG}+ zk!h6^SoS_-WszBaC;R=A?E0fY`%~X%;yc|BmQt)N@zn83{DYjSFNFWb`{_pbueEcz zf}Lh~QJ~vOsb?>|cuf;SX)wXP!1dxggGU(n7%K*XAhoZ?!8W6u&qlJM1*lQabWjwb5 zKFgNZ;I#NN-w$}crbnS2AEU|76mDYgq|1lvT9YZ&H6N_A$3Y%KZ~8clI@E067sN^> z&u6Dp7;6fzrEy2hABYHm*sB2z{WR%;cvWKEe^zP@s{s{@Ju+D{$}zVoTBUuw24nP@ zLXDL44gT6rhnM@p{yh!!4_a*2BDH}?acQa_O!)|xtllpqi{zw;=gQ84>3uF+(syeH z_{Rca!IU6a3iS#R+!m`2=qw_l0B402(9h(m|P0MS|+FaW``~2&wajN!;gcuo6%emTF7R0UsmU?oP@g}GlO$1 zwg%3vaF%S{6)HcLc4*INePm1}*29As`YSKj$Ct-AP%Ktu#4*>Tm>g^+EoU4u+7)C7 z_@M6#4&9O8TK%Hf)~1VTk(yU;t<_+gHp$f`Tc08GF`V= zCNunQ%-dk~OW0Y@jj6F|4G)zVxlZJ*N2DPXn4lJqz9E*H*BkGFuQHLsrU# zYFk4gD_w7u>rOC*WDQ#nJS^^q(-&KT#2857vkzxE6}Bi$DPH5R>dJw<+P-67%3TeH zGyey*vL`MJHul6`LL2*meAY+Ai>Y{}A*ufcERNs4E~J+Ofk%tuwWRv$^s0nXEt$0zVP^QrzkrSaPP8%u?_ zJ@OIh&NBa8iWJYT9E0t~{Fo*m(PB7<6Xd>6)19_zE-=2wQ^^zA_Ubp9!!fuejl`eB zp+iLscf;ZOO~GKkPNqjn@wvZW6svg)=}!1=`q^*qVps1aHqo~0&vQ&SJ}eo<+FD8I zb0EAMM=BSSLwR={opHMe8Vqe)( zXE4tS*KBBx2PNFM&gsk+TkRNwq;{T*@ttvdwu89^-IsDcYLre~*EB6DACuA)^;TNg zk-D*^i`IU9Zzab^N>SVQF1(-8(pDqg7dxLR6>Vj^TCd+8L+NMTzZB*Tl3w3kEODRi zX8ycu-P2voYYy4nyiQkd%k6SJnplE`miDsT@M??TrJyzJj^=YNbxh@WDoM85E)_k# z@?JYVN}=e?ur9e1`4T4a%a8e<&T=^jNs@(Gq| zu++VV>xQn@-52Al6i03y>8QL+xDgX=8F603QtBu|kY@eVI1FbaTm^2=vF?1BHRhSo zi8*#{#dg2~*vC$t^oHRHGy1LQ_pXQ(|5nIYij5Dk35iI3wK+H9)*wCap1)w3U=QS@ z*ebMlaV!V0kwy1X&!;#8Lfp!HINa=J%wJk9JRb(TJ+*x$Z{g!;we)_86s4#_e4WOoF!_ZtMT}p=$RF^(O;95=&Hat z<<82Ttfy8q!}5)2Oxqh+ACfzOXr#m(yCSt>n0qJExx~-oObxki`o2&ak7cDaZhoA# zA=XJRZZQ_)wOV#bgG^2q)WN(yf|@C!ZN13ukvEIAZ(A^`q>vb|~KzGY)*gl|5 z)L31+vi`(^BQiI%0sAUBY!COy_Kyq#?A~p8=R5h%Vf*<_Jtp>h(PA<)!EKcy6r$)IfK?Y}~Q ze5b{DA(rSF#YIi84fT)J-p@9FE^*f1lN<9N2qX8r4^&~>{6}#Nf}jDOZY8Qld1HVDcg- z89y)U$9;Oqa^K3D-g7sU#AE3$S@sc+uB&eMc;j}5-(0zWYu9;?dx$aXd~#g#-I(9{ zH^((f&&@B-EoBg7#e=ui{1EDA12;II#5P_Zyh@*n)Z>}7@|Ad+#_xzslwwHUdI{t% z;Aek=*WmHT*{Pgg@mU=M7_RfPoDbhXKg!}U! z{M^3U_`y@Zr+x0d=jLHSi%sUh4_njcw#B@ z?_vLL%bq@wa*t(C(Zs1|{DUB8MZfevXoo~ntMXbTo@e9F z^OCIJCt+uZpp*7!7EOPWc4&|P*h3v`+>&uy>Dysuaaq>kru5t{&Dfa#r}F!sp`^wb z!Ke26#_weXu#ut!?cSIEt_NwFkB|G^_Wm;&9c>W@=syH1bZ_+U>R@vxz@Nof7!H9Z z@lz@JX_-Z)(b6(vk*WW$)+~n-^;;_D}B#U@Sc!JZYZ?-o8rr2b7-T=EYW{oO?dIbiM3e zUG=?qZuEK0x2LsPGiSF?UoXD~Ekp#d3zEzD;I-k`SW$ladEUDsYy3+1p*DZprj~~A zwr9lZ;*4-kr;qrmZQ-Uag=j;U0#AjO)_;Ce;V7Ri$cvYI3qQ%abaRtL*tse^0Ceqe z8r!Kx^>WeJLincK5w3#&8c_zG6q;Fijl04<5c`vumhcxTU$K42g>=!A_e4UG=ZW}I z+SE)D)@$5Cikp~Y8mE)m7WuOrf80|0?9bb(+Rc0;Gxj8=6xKm?XIkL)Zlj%j7OrXM0)StMj|iN->93>cs4m@1mLZfVg%3r{N8Y&S$> zu8*KDrO=kpj9G+coe43THO{ZMR^qNR3FdMQ5BreEeU9VqF4AV2w{QIRu@bx)AnT&o zTU`=LX)pX;#a!xnQ^%T9&MB{^UEsqb=Zw`yEgJ2ZFq*fo7$b$%#ZN#kff#F5ELO#M zu-NjJS$z+AmfGdk$Rxg=x9d#sG&wJ~!zHoJxh484=9JTpj)7t<9p9MR031Rg|K%*gj0*}?qli0uw~Zch?3yJ*hV}`bcz?_)?>XRzCPyphz@x#g#y3L8Dw2e)5#) zqtNYL6Z-4VArk}9`q@1)AMXTyNawx);-}BuM5YAz7wq>I?t=Zp`ViE+u%58}mx2j3(4{zOKFe%)6D6_S~)!T9R; zwsj`!vu#1b{E&=%eI2lSb}rametrtA+z9KL-?=rRqw=9fYb~?+g{goIAP?SA8DIwKmTTTkA2;iCo9NwJ=8= z&nz=5#hmLnZSzqp%g+fMIh?lM556CdM6Ukuh?|U|qU4!!jwI&f>fC8R?{-JHJ$OfS z3-!{9q3#C0QcJuqS!i06#3wSFZ-S=rvb0y?yL=AXdOQ=?of{`uKX3IqI>M8}!Im7I z-=4&OcMkgckwgFuDdVp97}t;2qqP=s`E*^-PW1P2Ro484{HXU5<09(CklsEId-|87 zeVBzjM_oPE_a&YI5QZG(v8?TnBAMX-xAH_+Y$h`*cRQ}HD+YukCHd|M-deS~MilR! z!;9_xlQr%=J2GT1$Jzgx?EaA6YWv@!jdhQ@R$EIPpZ))Kjr%_n`mqJUG4zkK|8V+4 zdMo$8O}8Ac{mkn-$qH=dBgwzV{Tzh*T6;hqZ4%skcI60T%=;(7<>Wp7%Mt!=Q|@s+?PW(eLm;t! zpX>{MXJj_xiybhV<8DULK2LY#-gqH55Px+f=YveQH4gG6KMYb_A9wrw+?KNcz41pG zxk~Y^PS=ROklTz1C3odUq%W&OZo$_2SRE)YG!Vq5(7Sz4X5XrHQ_88Y{#EJAYIOB; zLv{h1uegV<@{DIlyW^G1;oQIbCwxoM{a=x}JPfq*V_75gG_1GkXYlj-ooGw&8^XFR zEsM>J>vGWAu){w}8{~Wb{z!l0?eApm|50oUuZz!A-u6yt%iI1|M)V@+nesmFhxiJb z$6I$%qi&m3?m9JAoaY~8pf`*jU%-C1*mx<_Zht6q#^90nc~~J zfAtLG*6*;o^ra=MY44Ht5^F}0e41QdWoVOzP0E*s`gfQbJ7s5W;Z7dAyzL& z+qY!l!!eOUt6`$m>(g3Nkosv{UM9Ty8MWj=^%=FW(eNF^s%Fv&ZE`R>m zO|w5(hmN-`XIRw?6~jy#LWkJJDAX3_sPEhIm~+w)9$yV%ONy0B!OK!E_i<=Vb#*Q= zG#aGNImIyUb&L;sDiq8Mk$Sw4?5K|_64_SoZ-S-}OkjB3$uy9QzT+bx#)I-4ue_JCY zwC>e-Pg6)hQZvK~poD~rVh7N*pW0^*2YUi{-Tl2zIN_P#0qicGt`P=yWJg<)g*F`Q z2}Wpf0CBAn4uGH*g%;P$A>o|V>hAINf`sQmNAz&5kU*To{xh0lgo{#V2!<~qVMj1R z_kCZ-3Gi`kZdL2NPO$K?=xT}4xIPMjvpwXDrjRgnKTAm1mEMNX7dcMY6$t8vz2gE0 z`8f0MF;6ksmc*-p^w6yOYPKaUj2723P1qu~C1YC&XudG?{i)@_qLu+r6B-Q&OMr*M zaoiUw6OF2RqQZx~Jd1!?)e->DSMwQ-X@Z=ao@{nn*l)7gc`UGwefx4YJ8#x$1Shub zbMP3rdYLPIKgRxW0+$ z&!I5glC{-gx>b5OOi#8rCBHo0Znh+5_1)~^LF$%`rY*8~B9pg1CvUv{Ye^gG``40% z3^|RHx4vQ1@piAJNvQAM@~3a|*4I58ZwDt^9HSe|mS7niWAQU4Z~a9mGknVGT8}zD zS!Sp7Hh5FK^;>*gsy8T0_2U_r1lsw@cQ9`w{~kliBvFr71FEJ=qTU7nR&N=J`Xu?) z+jjESY*CJWmi^PKu7@EmAuO^YW=8fH2%6avatwS2DJ;gI{39{+h z?@J7?ujPjbp`S~vq1_Pi6yG=EtrOwvrr6Hn?SQ5GX|c-xN@OLqsJrn!5cl~e_;9{1 zUOGAM&%ej}I_VGM)!>dYJwVMOzw2(ZdXxSj#v$911?s6_+$q{)O*hmZ6*51&{@p*l z4*G+Ck*sn1qCc2PR=zWn4nfXK9IJC^EX^T0gjZ#yCq2TXN9f}TTla09^K40``+A9G zK~sdsb=lCjc5798JLwT7JwnM#57l~2dW1NFWeYD4!L*ZAx$#F%!P^u5$NcC}=$x#| z)jQ8DDq9lkA@FGy$y0#`bX1BP@bVCOyKNsz=ZWk0qVhx}Vms z6(E;aixx{qIaU_9z23NSbsQOw=J>>Rd?M1?@75TviCdwiU5i&R)wB)E9#=+d!X|J? zZ+Wz)ndsBH>%C4e@QujpAIi`A@BsVLqS?lW0-$F|ZzUA;MUZ@*px_6Iw?qt@^+Ca6 zSs{mJcdTK9#qvUOBXmdqd!69m#ai!!A$R*YcL9F9ExtL%IVBc&lVUw{6RbC~@B9$3 zC;Qm)gN=8x!~hrMBPLjVz;yZbvX=RY53{ypX%CrgodHIO8k#YfFjq(xuE z^;T~wGPY$vngL+ENRM}t%mSZEtgYvQb;t|(h5RRH_Jdb4(qmVa(>r2~H|1TO@~$ou zXYkEDZ{WzbAMe<)9N)|}o~&;s>zh7pSW5#_*VnY{Ir@5;tZ%*)J)1_!Tc6KzYqwUl zx0CfvDM!n>E#)?2E@PLMepSaai(nZvMs@jZ9nZ8V+97yG?G~r}s#AW|l1_7vT*DA` zsElFU>zEhs_agE9N`Ajzqt3MzKg7@F_C~62+w0MN+Uk_{H|Kk7D70p-ZJCL7r*&?% zM*XIXXK;M%ZyW}`5UKa$R~{PhG#{cxEp=~Qvh#TFa(Fl^J+`p^@q&jOZu9RkwwSbU z@oI2icWK{R_#&>idhHt!-qL0tFYQok7UtWHAM*pjRnJ9|byZBHxz-BCuYNs}~blKS}P)_q*((p%JBUoVp;Y0@OUTa9YvcW}&E#1y4T z`1)Y1W%pNy(gi&o*kgS>i;ja`^DOp}JGkFTCIOwhP> zDcacjw8>X#mA*WahG|?4j6y3>q*1pyqn6ROt$$@vUNQQP(RcHfw)z5dEja>%;c-&I~PlkhVNU8 z4y*55YnS^dVaJ^7(C5xatt>yMnb`N#^48VQ*Q8-8@yw)Q@^fsfGijLWH%g4>9Bzz4 zn|zgWNSZWElZFYHh|kTWVZs||(lE8;0^|80DK_eFFQ=9KyMKE9HB2XuJe_9ZyL4yr zU0OKj2+4WCAMf zFa0+APoZlJmhol!PHaQakZWrtJ>0?p>(5QOXjVd^Shl2t@$7Q#!c5{zb;s|k?@`?5 zs}UJ5A7}nO#_f~;O1v7!N4rpB5QW3z6$!01i*EmwR;}?Op|yJG*9O=wcGeKcci3-Yc|Ps9Bm z7P;4_oI1p>uiL{9*(tpZChfuMwFfz_%D>0ZKS_<_)c}rc| DyWnN5 literal 0 HcmV?d00001 diff --git a/analytics/mag_pbi/procedures/mag_pbi_procedures.sql b/analytics/mag_pbi/procedures/mag_pbi_procedures.sql new file mode 100644 index 0000000000000000000000000000000000000000..497fda253bf3717b93f76429ee6328c188be1b65 GIT binary patch literal 838206 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 Rz81OPgfG+VLtP!m{|9-JU+@3` literal 0 HcmV?d00001 diff --git a/analytics/mag_pbi/scripts/add_roic_to_contractor_producer.sql b/analytics/mag_pbi/scripts/add_roic_to_contractor_producer.sql new file mode 100644 index 0000000..15d6a1e --- /dev/null +++ b/analytics/mag_pbi/scripts/add_roic_to_contractor_producer.sql @@ -0,0 +1,48 @@ +-- ============================================================================= +-- Добавить колонку roic_norm в contractor_producer_mapping +-- ============================================================================= + +USE [mag_pbi] +GO + +IF NOT EXISTS ( + SELECT 1 FROM sys.columns + WHERE object_id = OBJECT_ID(N'[analytics].[contractor_producer_mapping]') + AND name = 'roic_norm' +) +BEGIN + ALTER TABLE [analytics].[contractor_producer_mapping] + ADD [roic_norm] DECIMAL(12,4) NULL; + + EXEC sys.sp_addextendedproperty + @name = N'MS_Description', + @value = N'Нормированный ROIC (при торговой надбавке 100%). Рассчитывается по этапам оплаты.', + @level0type = N'SCHEMA', @level0name = N'analytics', + @level1type = N'TABLE', @level1name = N'contractor_producer_mapping', + @level2type = N'COLUMN', @level2name = N'roic_norm'; +END +GO + +-- Обновить представление v_contractor_producer_mapping +IF OBJECT_ID(N'[analytics].[v_contractor_producer_mapping]', N'V') IS NOT NULL + DROP VIEW [analytics].[v_contractor_producer_mapping]; +GO + +CREATE VIEW [analytics].[v_contractor_producer_mapping] AS +SELECT + m.id, + m.contractor_1c_id, + c.contractor_id, + c.contractor_name, + m.producer_1c_id, + p.producer_id, + p.producer_name, + m.days_of_sales, + m.logistics_days, + m.roic_norm, + m.created_at, + m.updated_at +FROM [analytics].[contractor_producer_mapping] m +LEFT JOIN [analytics].[v_contractors] c ON c.contractor_1c_id = m.contractor_1c_id +LEFT JOIN [analytics].[v_producers] p ON p.producer_1c_id = m.producer_1c_id; +GO diff --git a/analytics/mag_pbi/scripts/create_contractor_producer_tables.sql b/analytics/mag_pbi/scripts/create_contractor_producer_tables.sql new file mode 100644 index 0000000..99d1599 --- /dev/null +++ b/analytics/mag_pbi/scripts/create_contractor_producer_tables.sql @@ -0,0 +1,169 @@ +-- ============================================================================= +-- Скрипт: сопоставление Контрагент + Производитель с этапами оплаты +-- Схема: analytics +-- Источники: Контрагенты из _Reference168, Производители из _Reference260 (1С MAG_2019) +-- ============================================================================= + +USE [mag_pbi] +GO + +SET ANSI_NULLS ON +GO +SET QUOTED_IDENTIFIER ON +GO + +-- ----------------------------------------------------------------------------- +-- 0. DROP всех сущностей (пересоздание с нуля) +-- ----------------------------------------------------------------------------- + +IF OBJECT_ID(N'[analytics].[v_contractor_producer_mapping]', N'V') IS NOT NULL + DROP VIEW [analytics].[v_contractor_producer_mapping]; +GO + +IF OBJECT_ID(N'[analytics].[tr_contractor_producer_mapping_updated]', N'TR') IS NOT NULL + DROP TRIGGER [analytics].[tr_contractor_producer_mapping_updated]; +GO + +IF OBJECT_ID(N'[analytics].[contractor_producer_payment_stage]', N'U') IS NOT NULL + DROP TABLE [analytics].[contractor_producer_payment_stage]; +GO + +IF OBJECT_ID(N'[analytics].[contractor_producer_mapping]', N'U') IS NOT NULL + DROP TABLE [analytics].[contractor_producer_mapping]; +GO + +IF OBJECT_ID(N'[analytics].[v_contractors]', N'V') IS NOT NULL + DROP VIEW [analytics].[v_contractors]; +GO + +IF OBJECT_ID(N'[analytics].[v_producers]', N'V') IS NOT NULL + DROP VIEW [analytics].[v_producers]; +GO + +-- ----------------------------------------------------------------------------- +-- 1. Представления для списков из 1С +-- ----------------------------------------------------------------------------- + +-- Контрагенты: [pbi].[ПартнерыКонтрагенты] уже существует (из _Reference168) +-- Для удобства создаём представление analytics.v_contractors с search-friendly полями + +CREATE VIEW [analytics].[v_contractors] AS + +SELECT + c._IDRRef AS contractor_1c_id, -- бинарный ключ 1С + LOWER(CONCAT( + SUBSTRING(CONVERT(nvarchar(36), c._IDRRef, 2), 25, 8), '-', + SUBSTRING(CONVERT(nvarchar(36), c._IDRRef, 2), 21, 4), '-', + SUBSTRING(CONVERT(nvarchar(36), c._IDRRef, 2), 17, 4), '-', + SUBSTRING(CONVERT(nvarchar(36), c._IDRRef, 2), 1, 4), '-', + SUBSTRING(CONVERT(nvarchar(36), c._IDRRef, 2), 5, 12) + )) AS contractor_id, -- строковый id для API/поиска + c._Description AS contractor_name +FROM [MAG_2019].[dbo].[_Reference168] c +WHERE c._Marked = 0; +GO + +-- Производители из справочника 1С _Reference260 +CREATE VIEW [analytics].[v_producers] AS +SELECT + pr._IDRRef AS producer_1c_id, -- бинарный ключ 1С + LOWER(CONCAT( + SUBSTRING(CONVERT(nvarchar(36), pr._IDRRef, 2), 25, 8), '-', + SUBSTRING(CONVERT(nvarchar(36), pr._IDRRef, 2), 21, 4), '-', + SUBSTRING(CONVERT(nvarchar(36), pr._IDRRef, 2), 17, 4), '-', + SUBSTRING(CONVERT(nvarchar(36), pr._IDRRef, 2), 1, 4), '-', + SUBSTRING(CONVERT(nvarchar(36), pr._IDRRef, 2), 5, 12) + )) AS producer_id, -- строковый id для API/поиска + pr._Description AS producer_name +FROM [MAG_2019].[dbo].[_Reference260] pr +WHERE pr._Marked = 0; +GO + +-- ----------------------------------------------------------------------------- +-- 2. Основная таблица: сопоставление Контрагент + Производитель +-- ----------------------------------------------------------------------------- + +CREATE TABLE [analytics].[contractor_producer_mapping] ( + [id] INT IDENTITY(1,1) NOT NULL, + [contractor_1c_id] BINARY(16) NOT NULL, -- бинарный ключ 1С (_Reference168) + [producer_1c_id] BINARY(16) NOT NULL, -- бинарный ключ 1С (_Reference260) + [days_of_sales] INT NOT NULL DEFAULT 180, -- На сколько дней продажи привезли остатков + [logistics_days] INT NOT NULL DEFAULT 120, -- Срок логистики (дней от дня заказа) + [roic_norm] DECIMAL(12,4) NULL, -- Нормированный ROIC (при TN 100%) + [created_at] DATETIME2(0) NOT NULL DEFAULT GETDATE(), + [updated_at] DATETIME2(0) NOT NULL DEFAULT GETDATE(), + + CONSTRAINT [PK_contractor_producer_mapping] PRIMARY KEY CLUSTERED ([id] ASC), + CONSTRAINT [UQ_contractor_producer] UNIQUE NONCLUSTERED ([contractor_1c_id], [producer_1c_id]) + ); + + EXEC sys.sp_addextendedproperty + @name = N'MS_Description', + @value = N'Сопоставление Контрагент (1С) + Производитель (1С). Параметры для расчёта нормированного ROIC.', + @level0type = N'SCHEMA', @level0name = N'analytics', + @level1type = N'TABLE', @level1name = N'contractor_producer_mapping'; +GO + +-- ----------------------------------------------------------------------------- +-- 3. Таблица этапов оплаты (неограниченное количество) +-- ----------------------------------------------------------------------------- + +CREATE TABLE [analytics].[contractor_producer_payment_stage] ( + [id] INT IDENTITY(1,1) NOT NULL, + [mapping_id] INT NOT NULL, + [name] NVARCHAR(255) NOT NULL, -- Название этапа (Предоплата, Постоплата и т.д.) + [days] INT NOT NULL, -- Дней от дня заказа до оплаты + [percent] DECIMAL(9,4) NOT NULL, -- Процент от суммы (0..100) + [sort_order] INT NOT NULL DEFAULT 0, + + CONSTRAINT [PK_contractor_producer_payment_stage] PRIMARY KEY CLUSTERED ([id] ASC), + CONSTRAINT [FK_payment_stage_mapping] FOREIGN KEY ([mapping_id]) + REFERENCES [analytics].[contractor_producer_mapping]([id]) ON DELETE CASCADE + ); + + CREATE NONCLUSTERED INDEX [IX_payment_stage_mapping_id] + ON [analytics].[contractor_producer_payment_stage]([mapping_id] ASC); + + EXEC sys.sp_addextendedproperty + @name = N'MS_Description', + @value = N'Этапы оплаты для пары Контрагент-Производитель. [{days, percent}, ...]. Сумма percent по паре должна = 100.', + @level0type = N'SCHEMA', @level0name = N'analytics', + @level1type = N'TABLE', @level1name = N'contractor_producer_payment_stage'; +GO + +-- ----------------------------------------------------------------------------- +-- 4. Представление для выборки с именами (для UI и API) +-- ----------------------------------------------------------------------------- + +CREATE VIEW [analytics].[v_contractor_producer_mapping] AS +SELECT + m.id, + m.contractor_1c_id, + c.contractor_id, -- строковый id для API/поиска + c.contractor_name, + m.producer_1c_id, + p.producer_id, -- строковый id для API/поиска + p.producer_name, + m.days_of_sales, + m.logistics_days, + m.roic_norm, + m.created_at, + m.updated_at +FROM [analytics].[contractor_producer_mapping] m +LEFT JOIN [analytics].[v_contractors] c ON c.contractor_1c_id = m.contractor_1c_id +LEFT JOIN [analytics].[v_producers] p ON p.producer_1c_id = m.producer_1c_id; +GO + +-- ----------------------------------------------------------------------------- +-- 5. Триггер обновления updated_at +-- ----------------------------------------------------------------------------- + +CREATE TRIGGER [analytics].[tr_contractor_producer_mapping_updated] +ON [analytics].[contractor_producer_mapping] +AFTER UPDATE +AS + UPDATE [analytics].[contractor_producer_mapping] + SET updated_at = GETDATE() + FROM [analytics].[contractor_producer_mapping] t + INNER JOIN inserted i ON t.id = i.id; +GO diff --git a/analytics/mag_pbi/scripts/import_suppliers_csv.sql b/analytics/mag_pbi/scripts/import_suppliers_csv.sql new file mode 100644 index 0000000..4baaf00 --- /dev/null +++ b/analytics/mag_pbi/scripts/import_suppliers_csv.sql @@ -0,0 +1,232 @@ +-- ============================================================================= +-- Импорт поставщиков из CSV +-- Пропускает: пустые строки, пустой производитель, "не работаем", двойной (партнёр=производитель) +-- ============================================================================= + +USE [mag_pbi] +GO + +SET NOCOUNT ON; + +DECLARE @t TABLE ( + partner NVARCHAR(500), + producer NVARCHAR(500), + contractor NVARCHAR(500), + log_val NVARCHAR(50), + sales_val NVARCHAR(50), + n_pct NVARCHAR(50), + n_days NVARCHAR(50), + m_pct NVARCHAR(50), + m_days NVARCHAR(50) +); + +INSERT INTO @t (partner, producer, contractor, log_val, sales_val, n_pct, n_days, m_pct, m_days) VALUES +(N'TWIST (Коврига)', N'TWIST', N'ИП Коврига Богдан Владиславович', N'14-21', N'', N'', N'', N'100', N'14-21'), +(N'АО "ПНК "Красная нить"', N'АО "ПНК "Красная нить"', N'ПНК КРАСНАЯ НИТЬ АО', N'7', N'', N'', N'', N'100', N'30'), +(N'АОРА ООО', N'Оллтекс', N'АОРА ООО', N'10', N'', N'', N'', N'100', N'14'), +(N'АПИА', N'АПИА', N'АКВИЛОН ТЕКС ООО', N'5', N'', N'0', N'', N'100', N''), +(N'Астра ООО', N'Астра ООО', N'АСТРА ООО(ИНН5027282471)', N'10', N'30', N'100', N'1', N'0', N'0'), +(N'БАЛТИЙСКИЙ ТЕКСТИЛЬ', N'БАЛТИЙСКИЙ ТЕКСТИЛЬ', N'НЕВА-ТЕКСТИЛЬ ООО', N'10', N'30', N'100', N'1', N'0', N'0'), +(N'ДЕНВИС ООО', N'Денвис ООО', N'ДЕНВИС ООО', N'14', N'', N'', N'', N'100', N'14'), +(N'Дилан-Текс ООО', N'Дилан-Текс', N'ДИЛАН-ТЕКСТИЛЬ ООО', N'3', N'30', N'100', N'', N'0', N'0'), +(N'Зарина Садовод', N'Зарина', N'ИП Ашурова Зарина Мирзоевна', N'7', N'30', N'0', N'', N'100', N'10'), +(N'Зарина Садовод', N'Зарина', N'ИП Забиров Умед Махмадиевич', N'7', N'30', N'0', N'', N'100', N'10'), +(N'Интай (ТЕКСТИЛЬ-ПРИНТ ООО)', N'Интай', N'ТЕКСТИЛЬ-ПРИНТ ООО', N'7', N'', N'0', N'', N'100', N''), +(N'ИП Маркович Олег Вячеславович', N'М-тех', N'ИП Маркович Олег Вячеславович', N'20', N'', N'100', N'', N'', N''), +(N'КАПРИЧЧО ООО', N'КАПРИЧЧО', N'КАПРИЗ ООО', N'7', N'30', N'0', N'', N'100', N'30'), +(N'КВИКЕР ООО (АРИМА)', N'Арима', N'КВИКЕР ООО', N'7', N'30', N'100', N'', N'0', N'0'), +(N'КВИНТА', N'КВИНТА ООО', N'КВИНТА ООО', N'14', N'30', N'50', N'', N'50', N'50'), +(N'КВИНТА', N'КВИНТА ООО', N'ТЕКСИНТЕХ ООО', N'14', N'30', N'50', N'', N'50', N'50'), +(N'КИТАЙ', N'ANHUI PHAETON CO.,LTD.', N'ANHUI PHAETON CO., LTD', N'120', N'180', N'30', N'1', N'70', N'50'), +(N'КИТАЙ', N'ANHUI PHAETON CO.,LTD.', N'ANHUI XINGTAI INTERNATIONAL TRADE CO., LTD', N'120', N'180', N'30', N'1', N'70', N'50'), +(N'КИТАЙ', N'Crafoam', N'CHANGSHA HEAPLAKE ENTERPRISES CO., LTD.', N'120', N'180', N'30', N'1', N'70', N'50'), +(N'КИТАЙ', N'DAVID', N'David YIWU SUPPLY AND MARKETING IMPORT AND EXPORT CO.,LTD', N'120', N'180', N'', N'', N'100', N'90'), +(N'КИТАЙ', N'WENDY', N'FUJIAN FOR BOTH TEXTILE CO.,LTD', N'120', N'180', N'', N'', N'100', N'60'), +(N'КИТАЙ', N'WENDY', N'Fujian Original Textile Co., Ltd', N'120', N'180', N'', N'', N'100', N'60'), +(N'КИТАЙ', N'GREAT ART INDUSTRIAL LTD.', N'GREAT ART INDUSTRIAL LTD.', N'120', N'180', N'30', N'1', N'70', N'60'), +(N'КИТАЙ', N'FEELO', N'AURORA SEWING SOLUTIONS - FZCO / MH / Yisun', N'120', N'180', N'30', N'1', N'70', N'21'), +(N'КИТАЙ', N'FEELO', N'GUANGDONG YILE TOYS CO., LTD.', N'120', N'180', N'30', N'1', N'70', N'21'), +(N'КИТАЙ', N'Evernice', N'GUANGZHOU ARK IMPORT EXPORT CO. LTD', N'120', N'180', N'', N'', N'100', N'60'), +(N'КИТАЙ', N'Evernice', N'Guangzhou Evernice Technology Development Co., Ltd', N'120', N'180', N'', N'', N'100', N'60'), +(N'КИТАЙ', N'ZHEJIANG BEYOND INDUSTRIAL AND TRADING', N'Jessy YIWU SUPPLY AND MARKETING IMPORT AND EXPORT CO.,LTD', N'120', N'180', N'', N'', N'', N''), +(N'КИТАЙ', N'JIANGSU GOLDEN AUTUMN ELASTIC FABRICS CO.,LTD', N'JIANGSU GOLDEN AUTUMN ELASTIC FABRICS CO.,LTD', N'120', N'180', N'30', N'1', N'70', N'60'), +(N'КИТАЙ', N'MH', N'NINGBO MH INDUSTRY CO., LTD.', N'120', N'180', N'50', N'100', N'50', N'160'), +(N'КИТАЙ', N'ZHEJIANG BEYOND INDUSTRIAL AND TRADING', N'NINGBO QUANAO IMP. AND EXP.CO.,LTD', N'120', N'180', N'', N'', N'100', N'120'), +(N'КИТАЙ', N'NINGBO YISUN IMPORT AND EXPORT COMPANY LIMITED', N'NINGBO UNISUN TRADE CO., LTD', N'120', N'180', N'50', N'90', N'50', N'120'), +(N'КИТАЙ', N'XINDEW', N'NINGBO YINZHOU XINDEW TEXTILE CO.,LTD', N'120', N'180', N'30', N'1', N'70', N'60'), +(N'КИТАЙ', N'NINGBO YISUN IMPORT AND EXPORT COMPANY LIMITED', N'SHAAN XI SUCCEED TRADING CO.,LTD', N'120', N'180', N'50', N'90', N'50', N'120'), +(N'КИТАЙ', N'Hebei', N'SHAOXING CITY YEHUA TEXTILE CO.,LTD', N'120', N'180', N'', N'', N'', N''), +(N'КИТАЙ', N'Houwen', N'SHAOXING KEQIAO DISTRICT HOUWEN IMPORT & EXPORT CO., LTD', N'120', N'180', N'30', N'1', N'70', N'60'), +(N'КИТАЙ', N'Mingge', N'SHAOXING KEQIAO MINGGE TEXTILE CO.,LTD', N'120', N'180', N'', N'', N'100', N'60'), +(N'КИТАЙ', N'QX', N'SHAOXING LIUYI TEXTILE IMPORT AND EXPORT CO.,LTD', N'120', N'180', N'', N'', N'', N''), +(N'КИТАЙ', N'Mingge', N'SHAOXING MENGYUE TEXTILE CO., LTD', N'120', N'180', N'', N'', N'100', N'60'), +(N'КИТАЙ', N'Varo', N'SHAOXING VARO TEXTILE CO., LTD', N'120', N'180', N'', N'', N'100', N'80'), +(N'КИТАЙ', N'ZHONGZHE', N'SHAOXING ZHONGZHE TEXTILE IMPORT AND EXPORT CO.,LTD', N'120', N'180', N'50', N'60', N'50', N'80'), +(N'КИТАЙ', N'Joanna', N'SHAOXING ZUHAO TEXTILE CO.,LTD', N'120', N'180', N'', N'', N'100', N'80'), +(N'КИТАЙ', N'SINEM BRODE', N'SINEMBRODE TEKSTIL SANAYI VE TICARET LTD. STI.', N'120', N'180', N'50', N'60', N'50', N'100'), +(N'КИТАЙ', N'RECHSEA', N'TOWARD OCEAN TECHNOLOGY CO., LIMITED', N'120', N'180', N'30', N'1', N'70', N''), +(N'КИТАЙ', N'XINDEW', N'XINDEW GROUP CO LIMITED', N'120', N'180', N'30', N'1', N'70', N'60'), +(N'КИТАЙ', N'Yingfeng Textile', N'Yingfeng Textile (Nanjing) Co., Ltd', N'120', N'180', N'30', N'1', N'70', N'50'), +(N'КИТАЙ', N'Sunshine', N'YIWU JYAO IMPORT AND EXPORT CO.,LTD', N'120', N'180', N'30', N'1', N'70', N'60'), +(N'КИТАЙ', N'ZHEGAO', N'AURORA SEWING SOLUTIONS - FZCO / MH / Yisun', N'120', N'180', N'30', N'1', N'70', N'21'), +(N'КИТАЙ', N'CADA', N'AURORA SEWING SOLUTIONS - FZCO / MH / Yisun', N'120', N'180', N'30', N'1', N'70', N'21'), +(N'КИТАЙ', N'KAVO', N'Shenzhen Sfun Toys Co., Ltd.', N'120', N'180', N'30', N'1', N'70', N'21'), +(N'КИТАЙ', N'Im.master', N'AURORA SEWING SOLUTIONS - FZCO / MH / Yisun', N'120', N'180', N'30', N'1', N'70', N'21'), +(N'КИТАЙ', N'LX', N'AURORA SEWING SOLUTIONS - FZCO / MH / Yisun', N'120', N'180', N'30', N'1', N'70', N'21'), +(N'КИТАЙ', N'LB+', N'AURORA SEWING SOLUTIONS - FZCO / MH / Yisun', N'120', N'180', N'30', N'1', N'70', N'21'), +(N'КИТАЙ', N'CAYI', N'AURORA SEWING SOLUTIONS - FZCO / MH / Yisun', N'120', N'180', N'30', N'1', N'70', N'21'), +(N'КИТАЙ', N'JINGXIN', N'YONGJIA JINGXIN GARMENT ACCESSORIES CO.,LTD', N'120', N'180', N'', N'', N'100', N'21'), +(N'КИТАЙ', N'HP', N'SHISHI HONGPENG METAL WEAR ACCESSORIES CO., LTD.', N'120', N'180', N'30', N'1', N'70', N'21'), +(N'КИТАЙ', N'YANG', N'ZHEJIANG KENKING INDUSTRIAL CO., LTD.', N'120', N'180', N'', N'', N'', N''), +(N'КИТАЙ', N'YANG', N'ZHEJIANG KENKING TEXTILE CO., LTD.', N'120', N'180', N'', N'', N'', N''), +(N'КИТАЙ', N'Larbene', N'ZHEJIANG LARBENE TEXTILE TECHNOLOG Y CO.,LTD', N'120', N'180', N'', N'', N'', N''), +(N'КИТАЙ', N'SHUAINING', N'ZHEJIANG SHUAINING INTERLINING TECHNOLOGY CO., LTD', N'120', N'180', N'', N'', N'100', N'160'), +(N'ЛАВИСТА ТЕКСТИЛЬ ООО', N'ЛАВИСТА ТЕКСТИЛЬ ООО', N'ЛАВИСТА ТЕКСТИЛЬ ООО', N'10', N'30', N'100', N'1', N'0', N'0'), +(N'ЛЕНТА АО (Чебоксары)', N'АО "Лента" (Ч)', N'ЛЕНТА АО (Чебоксары)', N'', N'', N'', N'', N'', N''), +(N'ЛЕРТЕКС ГРУПП ООО', N'ЛЕРТЕКС ГРУПП ООО', N'ЛЕРТЕКС ГРУПП ООО', N'10', N'30', N'100', N'1', N'0', N'0'), +(N'МЕБЕЛЬНАЯ ЛИНИЯ ООО', N'МЕБЕЛЬНАЯ ЛИНИЯ ООО', N'МЕБЕЛЬНАЯ ЛИНИЯ ООО', N'7', N'30', N'100', N'1', N'0', N'0'), +(N'МИР МАНУФАКТУРЫ', N'МИР МАНУФАКТУРЫ', N'РАДУГА ООО/МИР МАНУФАКТУРЫ', N'7', N'30', N'100', N'', N'', N''), +(N'Морозкин Иван Васильевич', N'Морозкин Иван Васильевич', N'ИП Морозкин Иван Васильевич', N'7', N'30', N'0', N'', N'100', N'20'), +(N'Морозкин Иван Васильевич', N'Морозкин Иван Васильевич', N'ИП Морозкина Нина Ивановна', N'7', N'30', N'0', N'', N'100', N'20'), +(N'Московское ПО Металлпластизделие ООО', N'ООО "Московское ПО Металлпластизделие"', N'Московское ПО Металлпластизделие ООО', N'5', N'60', N'', N'', N'100', N'20'), +(N'НЬЮСТАР ООО', N'НЬЮСТАР ООО', N'НЬЮСТАР ООО', N'10', N'60', N'', N'', N'100', N'40'), +(N'ОАО "Лента" Беларусь', N'ОАО "Лента"', N'ОАО "Лента"', N'10', N'', N'', N'', N'100', N'90'), +(N'ОАО ХБК "Шуйские ситцы"', N'ОАО ХБК "Шуйские ситцы"', N'ШУЙСКИЕ СИТЦЫ АО ХБК', N'10', N'30', N'100', N'1', N'', N''), +(N'ОЛДОС', N'АнТекс', N'АНТЕКС ООО', N'3', N'', N'0', N'', N'30', N'30'), +(N'ООО "АРГО ДС"', N'Арго ДС', N'АРГО ДС ООО', N'5', N'', N'', N'', N'', N''), +(N'ООО "ЕВРОПЛАСТИК"', N'ЕВРОПЛАСТИК ПЛЮС ООО', N'ЕВРОПЛАСТИК ПЛЮС ООО', N'14', N'', N'', N'', N'100', N'14'), +(N'ООО "ЕвроСнаб" (Казинников ДВ)', N'ЕВРОСНАБ ООО', N'ЕВРОСНАБ ООО', N'14-21', N'', N'', N'', N'100', N'20'), +(N'ООО "ТриЯна" ДАВА Пласт', N'ДАВА Пласт', N'ДАВА Пласт', N'10', N'30', N'0', N'', N'100', N'10'), +(N'ООО "Ф-ЛЕЙБЛ"', N'ООО "Фуртекс"', N'ООО "ФУРТЕКС" ПРОИЗВОДСТВО ЭТИКЕТОК (Ф-ЛЕЙБЛ)', N'14', N'30', N'', N'', N'100', N'10'), +(N'ООО "ЭЛАСТТЕКС2020"', N'ООО "ЭЛАСТТЕКС2020"', N'ЭЛАСТТЕКС2020', N'14-20', N'', N'30', N'1', N'70', N'14'), +(N'ПИН (Булавки)', N'дистр. ПАО "Мосточлегмаш"', N'БУЛАВКИ ООО', N'5', N'', N'', N'', N'100', N'14'), +(N'ПИН (Булавки)', N'дистр. ПАО "Мосточлегмаш"', N'ПИН ООО 9715499112', N'5', N'', N'', N'', N'100', N'14'), +(N'ПНК ИМ. КИРОВА АО', N'ООО "ПНК им. Кирова"', N'ПНК ИМ. КИРОВА АО', N'7', N'', N'', N'', N'100', N'30'), +(N'ПНК ИМ. КИРОВА АО', N'ООО "ПНК им. Кирова"', N'ПНК ИМ. КИРОВА ООО', N'7', N'', N'', N'', N'100', N'30'), +(N'ПНК ИМ. КИРОВА АО', N'ООО "ПНК им. Кирова"', N'Филиал АО "ПНК ИМ. КИРОВА"', N'7', N'', N'', N'', N'100', N'30'), +(N'ПОЛИМЕРНАЯ ИМПЕРИЯ ООО', N'Мегафторполимер', N'ПОЛИМЕРНАЯ ИМПЕРИЯ ООО', N'20', N'', N'', N'', N'100', N'14'), +(N'ПремиумФорм', N'Антинея', N'ПРЕМИУМФОРМ ООО', N'14-20', N'30', N'100', N'1', N'', N''), +(N'Результат-МСК', N'Следопыт', N'РЕЗУЛЬТАТ-МСК ООО', N'7', N'', N'', N'', N'100', N'30'), +(N'РЭДТЕКС ООО', N'Рэдтекс', N'РЭДТЕКС ООО', N'14-20', N'', N'', N'', N'100', N'30'), +(N'СИДЖЕЙ МОДА ООО', N'СИДЖЕЙ МОДА ООО', N'ЕВРОПА ТЕКС ООО', N'7', N'30', N'0', N'', N'100', N'14'), +(N'СПЕКТР ПРО-АКТИВ ООО', N'СПЕКТР ПРО-АКТИВ ООО', N'СПЕКТР ПРО-АКТИВ ООО', N'7', N'30', N'0', N'', N'100', N'21'), +(N'ТДЛ Текстиль', N'ТДЛ Текстиль', N'ТДЛ ТЕКСТИЛЬ ООО', N'7', N'30', N'0', N'', N'100', N'5'), +(N'ТЕКСТРА ТРЭЙД ООО', N'ООО "Текстра трэйд"', N'ТЕКСТРА РУ ООО', N'3', N'14', N'0', N'', N'14', N'14'), +(N'ТК МегаМаркет', N'ООО "ТК МегаМаркет"', N'МАРКЕТ ПЛЮС ООО', N'3', N'30', N'100', N'', N'0', N'0'), +(N'ТОП ПРИНТ (Азхар Аймаль)', N'Топ принт', N'Азхар Аймаль', N'5', N'20', N'0', N'', N'100', N'14'), +(N'ТОП ПРИНТ (Азхар Аймаль)', N'Топ принт', N'ТОП ПРИНТ ООО', N'5', N'20', N'0', N'', N'100', N'14'), +(N'ТРЕНД ООО ( Колибри)', N'Colibri', N'ТРЕНД ООО', N'30', N'90', N'', N'', N'100', N'120'), +(N'ФЕЛИтеКС Беларусь', N'Фелитекс', N'ФЕЛИтеКС Беларусь', N'14', N'30', N'0', N'', N'30', N'30'), +(N'Фи-текс', N'ООО "Фи-текс"', N'Фи-текс ООО', N'14', N'30', N'0', N'', N'30', N'30'), +(N'ЧУП "Максипресс"', N'ЧУП "Максипресс"', N'НЕЙЛОН ООО', N'25', N'', N'100', N'1', N'', N''), +(N'Экстра Текстиль ООО', N'Экстра Текстиль ООО', N'ЭКСТРА ТЕКСТИЛЬ ООО', N'3', N'15', N'100', N'', N'', N''), +(N'Эскар ООО', N'ЭСКАР ООО', N'ЭСКАР ООО', N'10', N'', N'', N'', N'100', N'14'); + +-- Фильтрация: пустой производитель, не работаем, партнёр=производитель +;WITH Filtered AS ( + SELECT producer, contractor, log_val, sales_val, n_pct, n_days, m_pct, m_days, + ROW_NUMBER() OVER (PARTITION BY LTRIM(RTRIM(producer)), LTRIM(RTRIM(contractor)) ORDER BY (SELECT 1)) AS rn + FROM @t + WHERE LTRIM(RTRIM(producer)) <> N'' + AND LOWER(LTRIM(RTRIM(producer))) NOT LIKE N'%не работаем%' + AND LOWER(LTRIM(RTRIM(producer))) NOT LIKE N'%под клиентов%' + AND (LTRIM(RTRIM(partner)) <> LTRIM(RTRIM(producer)) OR LTRIM(RTRIM(partner)) = N'') +) +SELECT producer, contractor, log_val, sales_val, n_pct, n_days, m_pct, m_days +INTO #staging +FROM Filtered +WHERE rn = 1; + +DECLARE @log_days INT, @sales_days INT, @n_pct DECIMAL(9,4), @n_days INT, @m_pct DECIMAL(9,4), @m_days INT; +DECLARE @producer NVARCHAR(500), @contractor NVARCHAR(500); +DECLARE @manufacturer_id INT, @contractor_1c_id BINARY(16); +DECLARE @log_val NVARCHAR(50), @sales_val NVARCHAR(50), @n_pct_val NVARCHAR(50), @n_days_val NVARCHAR(50), @m_pct_val NVARCHAR(50), @m_days_val NVARCHAR(50); + +DECLARE cur CURSOR LOCAL FAST_FORWARD FOR + SELECT producer, contractor, log_val, sales_val, n_pct, n_days, m_pct, m_days FROM #staging; + +OPEN cur; + +WHILE 1=1 +BEGIN + FETCH cur INTO @producer, @contractor, @log_val, @sales_val, @n_pct_val, @n_days_val, @m_pct_val, @m_days_val; + IF @@FETCH_STATUS <> 0 BREAK; + + SET @manufacturer_id = NULL; + SET @contractor_1c_id = NULL; + + -- Парсинг чисел: диапазон 14-21 -> среднее, пустое -> NULL + SET @log_days = CASE + WHEN @log_val = N'' OR @log_val IS NULL THEN NULL + WHEN @log_val LIKE N'%-%' AND CHARINDEX(N'-', @log_val) > 1 + THEN (TRY_CAST(LEFT(@log_val, CHARINDEX(N'-', @log_val)-1) AS INT) + TRY_CAST(LTRIM(SUBSTRING(@log_val, CHARINDEX(N'-', @log_val)+1, 10)) AS INT))/2 + ELSE TRY_CAST(@log_val AS INT) END; + SET @sales_days = CASE + WHEN @sales_val = N'' OR @sales_val IS NULL THEN NULL + WHEN @sales_val LIKE N'%-%' AND CHARINDEX(N'-', @sales_val) > 1 + THEN (TRY_CAST(LEFT(@sales_val, CHARINDEX(N'-', @sales_val)-1) AS INT) + TRY_CAST(LTRIM(SUBSTRING(@sales_val, CHARINDEX(N'-', @sales_val)+1, 10)) AS INT))/2 + ELSE TRY_CAST(@sales_val AS INT) END; + SET @n_pct = TRY_CAST(@n_pct_val AS DECIMAL(9,4)); + SET @n_days = TRY_CAST(@n_days_val AS INT); + SET @m_pct = TRY_CAST(@m_pct_val AS DECIMAL(9,4)); + SET @m_days = TRY_CAST(@m_days_val AS INT); + + IF @log_days IS NULL SET @log_days = 120; + IF @sales_days IS NULL SET @sales_days = 180; + + -- Найти contractor_1c_id в v_contractors (по точному совпадению имени) + SELECT @contractor_1c_id = (SELECT TOP 1 contractor_1c_id + FROM [analytics].[v_contractors] + WHERE LTRIM(RTRIM(contractor_name)) = LTRIM(RTRIM(@contractor))); + + IF @contractor_1c_id IS NULL + CONTINUE; -- контрагент не найден в 1С, пропускаем + + -- Найти или создать manufacturer (подзапрос — при отсутствии строк переменная станет NULL) + SELECT @manufacturer_id = (SELECT id FROM [analytics].[manufacturers] + WHERE LTRIM(RTRIM(manufacturer)) = LTRIM(RTRIM(@producer))); + + IF @manufacturer_id IS NULL + BEGIN + INSERT INTO [analytics].[manufacturers] (manufacturer, days_of_sales, logistics_days, roic_norm) + VALUES (LTRIM(RTRIM(@producer)), @sales_days, @log_days, NULL); + SET @manufacturer_id = SCOPE_IDENTITY(); + END + ELSE + BEGIN + UPDATE [analytics].[manufacturers] + SET days_of_sales = @sales_days, logistics_days = @log_days + WHERE id = @manufacturer_id; + END + + -- Проверить, нет ли уже связи + IF EXISTS (SELECT 1 FROM [analytics].[manufacturer_counterparty_map] + WHERE manufacturer_id = @manufacturer_id AND contractor_1c_id = @contractor_1c_id) + CONTINUE; + + INSERT INTO [analytics].[manufacturer_counterparty_map] (manufacturer_id, contractor_1c_id) + VALUES (@manufacturer_id, @contractor_1c_id); + + -- Этапы оплаты + DELETE FROM [analytics].[manufacturer_payment_stage] WHERE manufacturer_id = @manufacturer_id; + + IF @n_pct IS NOT NULL AND @n_pct > 0 + INSERT INTO [analytics].[manufacturer_payment_stage] (manufacturer_id, name, days, [percent], sort_order) + VALUES (@manufacturer_id, N'Первая оплата', ISNULL(@n_days, 1), @n_pct, 0); + + IF @m_pct IS NOT NULL AND @m_pct > 0 + INSERT INTO [analytics].[manufacturer_payment_stage] (manufacturer_id, name, days, [percent], sort_order) + VALUES (@manufacturer_id, N'Вторая оплата', ISNULL(@m_days, 60), @m_pct, 1); + + IF NOT EXISTS (SELECT 1 FROM [analytics].[manufacturer_payment_stage] WHERE manufacturer_id = @manufacturer_id) + INSERT INTO [analytics].[manufacturer_payment_stage] (manufacturer_id, name, days, [percent], sort_order) + VALUES (@manufacturer_id, N'Предоплата', 14, 100, 0); +END + +CLOSE cur; +DEALLOCATE cur; + +DROP TABLE #staging; + +PRINT 'Импорт завершён.'; +GO diff --git a/analytics/mag_pbi/scripts/migrate_manufacturers_counterparties_to_contractor_producer.sql b/analytics/mag_pbi/scripts/migrate_manufacturers_counterparties_to_contractor_producer.sql new file mode 100644 index 0000000..7ad41d2 --- /dev/null +++ b/analytics/mag_pbi/scripts/migrate_manufacturers_counterparties_to_contractor_producer.sql @@ -0,0 +1,120 @@ +-- ============================================================================= +-- Миграция: manufacturers + manufacturer_counterparty_map + counterparties +-- → contractor_producer_mapping + contractor_producer_payment_stage +-- +-- Источник: analytics.manufacturers, analytics.manufacturer_counterparty_map, +-- analytics.counterparties +-- Назначение: analytics.contractor_producer_mapping, +-- analytics.contractor_producer_payment_stage +-- +-- Сопоставление по именам: counterparty → v_contractors (_Reference168), +-- manufacturer → v_producers (_Reference260) +-- ============================================================================= + +USE [mag_pbi] +GO + +SET NOCOUNT ON; + +-- 1. Проверка: какие строки будут мигрировать, какие найдутся в 1С +PRINT '=== Сопоставление с v_contractors и v_producers ==='; +SELECT + mcm.id AS map_id, + cp.counterparty, + c.contractor_id AS contractor_1c_match, + man.manufacturer, + p.producer_id AS producer_1c_match, + CASE WHEN c.contractor_1c_id IS NULL THEN 'НЕТ' ELSE 'OK' END AS contractor_ok, + CASE WHEN p.producer_1c_id IS NULL THEN 'НЕТ' ELSE 'OK' END AS producer_ok +FROM [analytics].[manufacturer_counterparty_map] mcm +JOIN [analytics].[manufacturers] man ON man.id = mcm.manufacturer_id +JOIN [analytics].[counterparties] cp ON cp.id = mcm.counterparty_id +LEFT JOIN [analytics].[v_contractors] c + ON LTRIM(RTRIM(c.contractor_name)) = LTRIM(RTRIM(cp.counterparty)) +LEFT JOIN [analytics].[v_producers] p + ON LTRIM(RTRIM(p.producer_name)) = LTRIM(RTRIM(man.manufacturer)) +ORDER BY mcm.id; + +-- 2. Вставка в contractor_producer_mapping (только пары, найденные в 1С) +PRINT ''; +PRINT '=== Вставка в contractor_producer_mapping ==='; + +INSERT INTO [analytics].[contractor_producer_mapping] + (contractor_1c_id, producer_1c_id, days_of_sales, logistics_days, roic_norm) +SELECT + c.contractor_1c_id, + p.producer_1c_id, + 180, + 120, + man.ROI_norm +FROM [analytics].[manufacturer_counterparty_map] mcm +JOIN [analytics].[manufacturers] man ON man.id = mcm.manufacturer_id +JOIN [analytics].[counterparties] cp ON cp.id = mcm.counterparty_id +JOIN [analytics].[v_contractors] c + ON LTRIM(RTRIM(c.contractor_name)) = LTRIM(RTRIM(cp.counterparty)) +JOIN [analytics].[v_producers] p + ON LTRIM(RTRIM(p.producer_name)) = LTRIM(RTRIM(man.manufacturer)) +WHERE NOT EXISTS ( + SELECT 1 FROM [analytics].[contractor_producer_mapping] m2 + WHERE m2.contractor_1c_id = c.contractor_1c_id AND m2.producer_1c_id = p.producer_1c_id +); + +PRINT 'Вставлено сопоставлений: ' + CAST(@@ROWCOUNT AS NVARCHAR(10)); + +-- 3. Вставка этапов оплаты для маппингов без этапов +PRINT ''; +PRINT '=== Вставка этапов оплаты ==='; + +DECLARE @mapping_id INT; +DECLARE @n_pct DECIMAL(10,3), @n_d INT, @m_pct DECIMAL(10,3), @m_d INT; + +DECLARE cur CURSOR LOCAL FAST_FORWARD FOR +SELECT + m.id, + man.n_percent, + ISNULL(man.n_days, 1), + man.m_percent, + ISNULL(man.m_days, 120) +FROM [analytics].[contractor_producer_mapping] m +JOIN [analytics].[v_contractors] c ON c.contractor_1c_id = m.contractor_1c_id +JOIN [analytics].[v_producers] p ON p.producer_1c_id = m.producer_1c_id +JOIN [analytics].[counterparties] cp ON LTRIM(RTRIM(cp.counterparty)) = LTRIM(RTRIM(c.contractor_name)) +JOIN [analytics].[manufacturer_counterparty_map] mcm ON mcm.counterparty_id = cp.id +JOIN [analytics].[manufacturers] man ON man.id = mcm.manufacturer_id + AND LTRIM(RTRIM(man.manufacturer)) = LTRIM(RTRIM(p.producer_name)) +WHERE NOT EXISTS (SELECT 1 FROM [analytics].[contractor_producer_payment_stage] s WHERE s.mapping_id = m.id); + +OPEN cur; +FETCH NEXT FROM cur INTO @mapping_id, @n_pct, @n_d, @m_pct, @m_d; + +WHILE @@FETCH_STATUS = 0 +BEGIN + -- Этап 1: Предоплата (n_percent, n_days) + IF @n_pct IS NOT NULL AND @n_pct <> 0 + BEGIN + INSERT INTO [analytics].[contractor_producer_payment_stage] (mapping_id, name, days, [percent], sort_order) + VALUES (@mapping_id, N'Предоплата', @n_d, + CASE WHEN @n_pct > 1 THEN @n_pct ELSE @n_pct * 100 END, 0); + END + -- Этап 2: Постоплата (m_percent, m_days) + IF @m_pct IS NOT NULL AND @m_pct <> 0 + BEGIN + INSERT INTO [analytics].[contractor_producer_payment_stage] (mapping_id, name, days, [percent], sort_order) + VALUES (@mapping_id, N'Постоплата', @m_d, + CASE WHEN @m_pct > 1 THEN @m_pct ELSE @m_pct * 100 END, 1); + END + -- Если оба NULL — дефолт Предоплата 7-50, Постоплата 120-50 + IF (@n_pct IS NULL OR @n_pct = 0) AND (@m_pct IS NULL OR @m_pct = 0) + BEGIN + INSERT INTO [analytics].[contractor_producer_payment_stage] (mapping_id, name, days, [percent], sort_order) + VALUES (@mapping_id, N'Предоплата', 7, 50, 0), + (@mapping_id, N'Постоплата', 120, 50, 1); + END + FETCH NEXT FROM cur INTO @mapping_id, @n_pct, @n_d, @m_pct, @m_d; +END; + +CLOSE cur; +DEALLOCATE cur; + +PRINT 'Миграция завершена.'; +GO diff --git a/analytics/mag_pbi/scripts/migrate_map_to_contractor_1c.sql b/analytics/mag_pbi/scripts/migrate_map_to_contractor_1c.sql new file mode 100644 index 0000000..2111a7a --- /dev/null +++ b/analytics/mag_pbi/scripts/migrate_map_to_contractor_1c.sql @@ -0,0 +1,156 @@ +-- ============================================================================= +-- Переход: counterparties → v_contractors (1С) +-- manufacturer_counterparty_map: counterparty_id → contractor_1c_id +-- Контрагенты и производители из 1С (v_contractors, v_producers) +-- ============================================================================= + +USE [mag_pbi] +GO + +SET NOCOUNT ON; + +-- Удаляем представления, ссылающиеся на map/counterparties +IF OBJECT_ID(N'[analytics].[v_manufacturer_counterparty_mapping]', N'V') IS NOT NULL + DROP VIEW [analytics].[v_manufacturer_counterparty_mapping]; +GO + +-- Удалить FK manufacturer_counterparty_map → counterparties (если есть) +DECLARE @fk NVARCHAR(256); +SELECT @fk = name FROM sys.foreign_keys +WHERE parent_object_id = OBJECT_ID(N'[analytics].[manufacturer_counterparty_map]') + AND referenced_object_id = OBJECT_ID(N'[analytics].[counterparties]'); +IF @fk IS NOT NULL + EXEC('ALTER TABLE [analytics].[manufacturer_counterparty_map] DROP CONSTRAINT ' + @fk); +GO + +-- Очистить таблицу привязки +TRUNCATE TABLE [analytics].[manufacturer_counterparty_map]; +PRINT 'manufacturer_counterparty_map: очищена'; +GO + +-- Заменить counterparty_id на contractor_1c_id +IF EXISTS (SELECT 1 FROM sys.columns WHERE object_id = OBJECT_ID(N'[analytics].[manufacturer_counterparty_map]') AND name = 'counterparty_id') +BEGIN + ALTER TABLE [analytics].[manufacturer_counterparty_map] DROP COLUMN [counterparty_id]; + PRINT 'Удалена колонка counterparty_id'; +END +IF NOT EXISTS (SELECT 1 FROM sys.columns WHERE object_id = OBJECT_ID(N'[analytics].[manufacturer_counterparty_map]') AND name = 'contractor_1c_id') +BEGIN + ALTER TABLE [analytics].[manufacturer_counterparty_map] ADD [contractor_1c_id] BINARY(16) NOT NULL; + PRINT 'Добавлена колонка contractor_1c_id'; +END +GO + +-- Удалить старые уникальные ограничения (на counterparty_id), создать новое +DECLARE @uq NVARCHAR(256); +SELECT @uq = name FROM sys.key_constraints +WHERE parent_object_id = OBJECT_ID(N'[analytics].[manufacturer_counterparty_map]') + AND type = 'UQ' AND name = 'UQ_mcm_counterparty'; +IF @uq IS NOT NULL + EXEC('ALTER TABLE [analytics].[manufacturer_counterparty_map] DROP CONSTRAINT ' + @uq); + +SELECT @uq = name FROM sys.key_constraints +WHERE parent_object_id = OBJECT_ID(N'[analytics].[manufacturer_counterparty_map]') + AND type = 'UQ' AND name = 'UQ_mcm_pair'; +IF @uq IS NOT NULL + EXEC('ALTER TABLE [analytics].[manufacturer_counterparty_map] DROP CONSTRAINT ' + @uq); + +-- Один контрагент — один производитель +IF NOT EXISTS (SELECT 1 FROM sys.key_constraints + WHERE parent_object_id = OBJECT_ID(N'[analytics].[manufacturer_counterparty_map]') AND name = 'UQ_mcm_contractor') + ALTER TABLE [analytics].[manufacturer_counterparty_map] ADD CONSTRAINT [UQ_mcm_contractor] UNIQUE ([contractor_1c_id]); +-- Уникальная пара +IF NOT EXISTS (SELECT 1 FROM sys.key_constraints + WHERE parent_object_id = OBJECT_ID(N'[analytics].[manufacturer_counterparty_map]') AND name = 'UQ_mcm_pair') + ALTER TABLE [analytics].[manufacturer_counterparty_map] ADD CONSTRAINT [UQ_mcm_pair] UNIQUE ([manufacturer_id], [contractor_1c_id]); +GO + +-- Удалить таблицу counterparties +IF OBJECT_ID(N'[analytics].[counterparties]', N'U') IS NOT NULL +BEGIN + DROP TABLE [analytics].[counterparties]; + PRINT 'Удалена таблица analytics.counterparties'; +END +GO + +-- Создать v_contractors, v_producers если не существуют +IF OBJECT_ID(N'[analytics].[v_contractors]', N'V') IS NULL +BEGIN + EXEC(' + CREATE VIEW [analytics].[v_contractors] AS + SELECT + c._IDRRef AS contractor_1c_id, + LOWER(CONCAT( + SUBSTRING(CONVERT(nvarchar(36), c._IDRRef, 2), 25, 8), ''-'', + SUBSTRING(CONVERT(nvarchar(36), c._IDRRef, 2), 21, 4), ''-'', + SUBSTRING(CONVERT(nvarchar(36), c._IDRRef, 2), 17, 4), ''-'', + SUBSTRING(CONVERT(nvarchar(36), c._IDRRef, 2), 1, 4), ''-'', + SUBSTRING(CONVERT(nvarchar(36), c._IDRRef, 2), 5, 12) + )) AS contractor_id, + c._Description AS contractor_name + FROM [MAG_2019].[dbo].[_Reference168] c + WHERE c._Marked = 0'); + PRINT 'Создано представление v_contractors'; +END + +IF OBJECT_ID(N'[analytics].[v_producers]', N'V') IS NULL +BEGIN + EXEC(' + CREATE VIEW [analytics].[v_producers] AS + SELECT + pr._IDRRef AS producer_1c_id, + LOWER(CONCAT( + SUBSTRING(CONVERT(nvarchar(36), pr._IDRRef, 2), 25, 8), ''-'', + SUBSTRING(CONVERT(nvarchar(36), pr._IDRRef, 2), 21, 4), ''-'', + SUBSTRING(CONVERT(nvarchar(36), pr._IDRRef, 2), 17, 4), ''-'', + SUBSTRING(CONVERT(nvarchar(36), pr._IDRRef, 2), 1, 4), ''-'', + SUBSTRING(CONVERT(nvarchar(36), pr._IDRRef, 2), 5, 12) + )) AS producer_id, + pr._Description AS producer_name + FROM [MAG_2019].[dbo].[_Reference260] pr + WHERE pr._Marked = 0'); + PRINT 'Создано представление v_producers'; +END +GO + +-- Представление для API: map + manufacturer + contractor/producer (из 1С) +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 + +-- Исправить [analytics].[get_orders_list]: counterparties удалена, map по contractor_1c_id, +-- manufacturers без ROI_norm/n_percent/n_days/m_percent/m_days — использовать v_manufacturers_roi_compat +IF OBJECT_ID(N'[analytics].[get_orders_list]', N'V') IS NOT NULL +BEGIN + DECLARE @def NVARCHAR(MAX); + SELECT @def = OBJECT_DEFINITION(OBJECT_ID(N'[analytics].[get_orders_list]')); + IF @def LIKE N'%counterparties%' + BEGIN + SET @def = REPLACE(@def, N'LEFT JOIN [analytics].[counterparties] cp ON cp.[counterparty] = r._Description', N''); + SET @def = REPLACE(@def, N'map.[counterparty_id] = cp.id', N'map.[contractor_1c_id] = r._IDRRef'); + -- manufacturers без старых полей — join на v_manufacturers_roi_compat (ROI_norm, n_percent, n_days, m_percent, m_days) + IF @def LIKE N'%ROI_norm%' AND OBJECT_ID(N'[analytics].[v_manufacturers_roi_compat]', N'V') IS NOT NULL + SET @def = REPLACE(@def, N'[analytics].[manufacturers] man', N'[analytics].[v_manufacturers_roi_compat] man'); + DROP VIEW [analytics].[get_orders_list]; + EXEC sp_executesql @def; + PRINT 'Обновлено представление analytics.get_orders_list'; + END +END +GO + +PRINT 'Готово: manufacturer_counterparty_map с contractor_1c_id, counterparties удалена'; +GO diff --git a/analytics/mag_pbi/scripts/migrate_to_manufacturers_structure.sql b/analytics/mag_pbi/scripts/migrate_to_manufacturers_structure.sql new file mode 100644 index 0000000..eb19249 --- /dev/null +++ b/analytics/mag_pbi/scripts/migrate_to_manufacturers_structure.sql @@ -0,0 +1,252 @@ +-- ============================================================================= +-- Миграция: логистика, дни продаж и этапы оплаты — на 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 diff --git a/analytics/mag_pbi/scripts/recalc_roic_contractor_producer.sql b/analytics/mag_pbi/scripts/recalc_roic_contractor_producer.sql new file mode 100644 index 0000000..c67d390 --- /dev/null +++ b/analytics/mag_pbi/scripts/recalc_roic_contractor_producer.sql @@ -0,0 +1,50 @@ +-- ============================================================================= +-- Пересчёт roic_norm по методике (возврат денег по ходу продаж) +-- Таблицы: manufacturers, manufacturer_payment_stage +-- Алгоритм: avgReturnDay = logistics_days + days_of_sales/2 +-- frozenDays = avgReturnDay - effectiveDeferralDays +-- roic_norm = 12 / (frozenDays/30) * 100 +-- ============================================================================= + +USE [mag_pbi] +GO + +;WITH stage_agg AS ( + SELECT + manufacturer_id, + SUM([percent] / 100.0 * [days]) AS effective_deferral_days, + SUM([percent] / 100.0) AS total_percent + FROM [analytics].[manufacturer_payment_stage] + GROUP BY manufacturer_id +), +calc AS ( + SELECT + man.id, + man.days_of_sales, + man.logistics_days, + COALESCE(s.effective_deferral_days, 0) AS effective_deferral_days, + COALESCE(s.total_percent, 0) AS total_percent, + (man.logistics_days + man.days_of_sales / 2.0) AS avg_return_day + FROM [analytics].[manufacturers] man + LEFT JOIN stage_agg s ON s.manufacturer_id = man.id +), +roic_calc AS ( + SELECT + id, + CASE + WHEN total_percent <= 0 THEN NULL + WHEN (avg_return_day - effective_deferral_days) <= 0 THEN NULL + ELSE ROUND(12.0 / ((avg_return_day - effective_deferral_days) / 30.0) * 100.0, 2) + END AS new_roic + FROM calc +) +UPDATE man +SET man.roic_norm = r.new_roic +FROM [analytics].[manufacturers] man +JOIN roic_calc r ON r.id = man.id; + +SELECT + COUNT(*) AS total, + COUNT(roic_norm) AS with_roic, + COUNT(*) - COUNT(roic_norm) AS without_roic +FROM [analytics].[manufacturers]; diff --git a/analytics/mag_pbi/scripts/sp_recalc_roic.sql b/analytics/mag_pbi/scripts/sp_recalc_roic.sql new file mode 100644 index 0000000..f2d9832 --- /dev/null +++ b/analytics/mag_pbi/scripts/sp_recalc_roic.sql @@ -0,0 +1,62 @@ +-- ============================================================================= +-- Процедура пересчёта roic_norm для manufacturers +-- Параметры: @manufacturer_id INT = NULL — id строки в manufacturers; если NULL, пересчёт для всех +-- Формула: avgReturnDay = logistics_days + days_of_sales/2 +-- frozenDays = avgReturnDay - effectiveDeferralDays (из этапов оплаты) +-- roic_norm = 12 / (frozenDays/30) * 100 +-- ============================================================================= + +USE [mag_pbi] +GO + +IF OBJECT_ID(N'[analytics].[sp_recalc_roic]', N'P') IS NOT NULL + DROP PROCEDURE [analytics].[sp_recalc_roic]; +GO + +CREATE PROCEDURE [analytics].[sp_recalc_roic] + @manufacturer_id INT = NULL +AS +SET NOCOUNT ON; + +;WITH stage_agg AS ( + SELECT + manufacturer_id, + SUM([percent] / 100.0 * [days]) AS effective_deferral_days, + SUM([percent] / 100.0) AS total_percent + FROM [analytics].[manufacturer_payment_stage] + WHERE @manufacturer_id IS NULL OR manufacturer_id = @manufacturer_id + GROUP BY manufacturer_id +), +calc AS ( + SELECT + man.id, + man.days_of_sales, + man.logistics_days, + COALESCE(s.effective_deferral_days, 0) AS effective_deferral_days, + COALESCE(s.total_percent, 0) AS total_percent, + (ISNULL(man.logistics_days, 120) + ISNULL(man.days_of_sales, 180) / 2.0) AS avg_return_day + FROM [analytics].[manufacturers] man + LEFT JOIN stage_agg s ON s.manufacturer_id = man.id + WHERE @manufacturer_id IS NULL OR man.id = @manufacturer_id +), +roic_calc AS ( + SELECT + id, + CASE + WHEN total_percent <= 0 THEN NULL + WHEN (avg_return_day - effective_deferral_days) <= 0 THEN NULL + ELSE ROUND(12.0 / ((avg_return_day - effective_deferral_days) / 30.0) * 100.0, 2) + END AS new_roic + FROM calc +) +UPDATE man +SET man.roic_norm = r.new_roic +FROM [analytics].[manufacturers] man +JOIN roic_calc r ON r.id = man.id; + +SELECT @@ROWCOUNT AS updated_count; +GO + +-- Примеры вызова: +-- EXEC [analytics].[sp_recalc_roic]; -- пересчёт для всех +-- EXEC [analytics].[sp_recalc_roic] @manufacturer_id = 5; -- только для id=5 diff --git a/analytics/mag_pbi/tables/mag_pbi_tables.sql b/analytics/mag_pbi/tables/mag_pbi_tables.sql new file mode 100644 index 0000000000000000000000000000000000000000..aa98e8d7a5bbaee0aafad20ff7fd3728bfca1dcd GIT binary patch literal 162550 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 Ry=w@j#HvjHaH^N_`+xBJFJ%A# literal 0 HcmV?d00001 diff --git a/analytics/mag_pbi/views/mag_pbi_views.sql b/analytics/mag_pbi/views/mag_pbi_views.sql new file mode 100644 index 0000000000000000000000000000000000000000..1df1827bc5df5b52f97e48747ec33978b8503655 GIT binary patch literal 482728 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 z%0A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 literal 0 HcmV?d00001 diff --git a/analytics/pbi/model/report/.pbixproj.json b/analytics/pbi/model/report/.pbixproj.json new file mode 100644 index 0000000..7e28290 --- /dev/null +++ b/analytics/pbi/model/report/.pbixproj.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "created": "2026-02-04T18:19:36.8541938+03:00", + "lastModified": "2026-02-04T18:19:37.3198069+03:00" +} \ No newline at end of file diff --git a/analytics/pbi/model/report/Connections.json b/analytics/pbi/model/report/Connections.json new file mode 100644 index 0000000..2740b2f --- /dev/null +++ b/analytics/pbi/model/report/Connections.json @@ -0,0 +1,10 @@ +{ + "Version": 6, + "RemoteArtifacts": [ + { + "DatasetId": "f4e65e8a-12c8-4f22-864c-59603e40b45e", + "ReportId": "25e09a6e-0b0f-4a8a-a640-4331f9329c40" + } + ], + "OriginalWorkspaceObjectId": "dc155dfb-5cd1-4587-adfd-bde5c5298968" +} \ No newline at end of file diff --git a/analytics/pbi/model/report/DiagramLayout.json b/analytics/pbi/model/report/DiagramLayout.json new file mode 100644 index 0000000..cbf0197 --- /dev/null +++ b/analytics/pbi/model/report/DiagramLayout.json @@ -0,0 +1,1274 @@ +{ + "version": "1.1.0", + "diagrams": [ + { + "ordinal": 0, + "scrollPosition": { + "x": 0, + "y": 0 + }, + "nodes": [ + { + "location": { + "x": 856.22444097511425, + "y": 389.55821729990259 + }, + "nodeIndex": "Номенклатура", + "nodeLineageTag": "f50f43b8-653f-4068-88a3-0ada40f333a9", + "size": { + "height": 128, + "width": 234 + }, + "zIndex": 12, + "expandedHeight": 300 + }, + { + "location": { + "x": 333.84477886671806, + "y": 261.69057158549634 + }, + "nodeIndex": "Партнер", + "nodeLineageTag": "97e02e8a-24d7-460f-a5d4-380f0994e0c4", + "size": { + "height": 200, + "width": 234 + }, + "zIndex": 13, + "expandedHeight": 300 + }, + { + "location": { + "x": 288.1722637728721, + "y": 943.01405790699573 + }, + "nodeIndex": "Стоимость МП", + "nodeLineageTag": "7582b25e-0a47-4bd4-998d-ad7beb18db6d", + "size": { + "height": 176, + "width": 234 + }, + "zIndex": 14, + "expandedHeight": 300 + }, + { + "location": { + "x": 1715.1829989146879, + "y": 226.27094844324148 + }, + "nodeIndex": "crm_company_uf", + "nodeLineageTag": "fd78159b-18fa-40a9-970a-1470a125bad3", + "size": { + "height": 104, + "width": 234 + }, + "zIndex": 15, + "expandedHeight": 128 + }, + { + "location": { + "x": 1130.3166562159849, + "y": 0 + }, + "nodeIndex": "Основной отчет", + "nodeLineageTag": "2d43f3dd-0ea9-4290-8d89-3174dc2dc1da", + "size": { + "height": 72, + "width": 234 + }, + "zIndex": 3, + "expandedHeight": 300 + }, + { + "location": { + "x": 1008.4916974160167, + "y": 203.17770862374468 + }, + "nodeIndex": "Группы", + "nodeLineageTag": "085eeae7-b80c-4f6e-b69a-6cb3c636ab1e", + "size": { + "height": 104, + "width": 234 + }, + "zIndex": 25, + "expandedHeight": 300 + }, + { + "location": { + "x": 454.31072127633752, + "y": 624.985893116132 + }, + "nodeIndex": "Себестоимость", + "nodeLineageTag": "14d56775-0ee6-4ae1-af81-db38504b0997", + "size": { + "height": 224, + "width": 234 + }, + "zIndex": 19, + "expandedHeight": 300 + }, + { + "location": { + "x": 1289.0151811161079, + "y": 260.4741026736952 + }, + "nodeIndex": "Остатки", + "nodeLineageTag": "8d7e8c56-9dcb-4c28-b191-4737cd281542", + "size": { + "height": 128, + "width": 234 + }, + "zIndex": 4, + "expandedHeight": 272 + }, + { + "location": { + "x": 56.340787032174546, + "y": 674.10197715650111 + }, + "nodeIndex": "Заявки на оплату", + "nodeLineageTag": "cf134e75-cc78-416f-a1c4-a3752a52eff1", + "size": { + "height": 152, + "width": 234 + }, + "zIndex": 5, + "expandedHeight": 300 + }, + { + "location": { + "x": 1700.2647080298225, + "y": 380.26815647414179 + }, + "nodeIndex": "Параметр цена продажи, %", + "nodeLineageTag": "567240c7-beb9-460f-adb6-dc71a6b3306f", + "size": { + "height": 72, + "width": 234 + }, + "zIndex": 6, + "expandedHeight": 224 + }, + { + "location": { + "x": 406.1462596814074, + "y": 18.695727397596468 + }, + "nodeIndex": "План продаж менеджеров", + "nodeLineageTag": "730b70a2-916d-410b-8ccd-6a28377b1d5f", + "size": { + "height": 128, + "width": 234 + }, + "zIndex": 21, + "expandedHeight": 300 + }, + { + "location": { + "x": 1406.1557649795775, + "y": 0 + }, + "nodeIndex": "План продаж по группам", + "nodeLineageTag": "e5099f33-fe37-44c8-8fc3-d31668a2913f", + "size": { + "height": 104, + "width": 234 + }, + "zIndex": 7, + "expandedHeight": 300 + }, + { + "location": { + "x": 1264.1750442241512, + "y": 754.45840881409413 + }, + "nodeIndex": "Закупки", + "nodeLineageTag": "3b808b20-2111-4e80-9c03-a234a8b34733", + "size": { + "height": 176, + "width": 234 + }, + "zIndex": 26, + "expandedHeight": 300 + }, + { + "location": { + "x": 1393.9196486731632, + "y": 984.37919495128688 + }, + "nodeIndex": "Организация", + "nodeLineageTag": "445da135-b7ce-41de-a01b-f652726fbeda", + "size": { + "height": 104, + "width": 234 + }, + "zIndex": 8, + "expandedHeight": 200 + }, + { + "location": { + "x": 861.4335883379548, + "y": 52.230858939218265 + }, + "nodeIndex": "ПРАЙСлист", + "nodeLineageTag": "1c432e4c-6774-47b9-a4e5-46ccccc3084a", + "size": { + "height": 128, + "width": 234 + }, + "zIndex": 20, + "expandedHeight": 296 + }, + { + "location": { + "x": 645.2235789234087, + "y": 255.0265573547602 + }, + "nodeIndex": ".Календарь", + "nodeLineageTag": "fa15f6a2-9f96-4009-a5f4-ba8eaed6c41f", + "size": { + "height": 104, + "width": 234 + }, + "zIndex": 24, + "expandedHeight": 224 + }, + { + "location": { + "x": 1698.5032190149034, + "y": 0 + }, + "nodeIndex": "Отзывы клиентов", + "nodeLineageTag": "e203fedd-13d1-4354-93b1-a4029329da19", + "size": { + "height": 72, + "width": 234 + }, + "zIndex": 10, + "expandedHeight": 300 + }, + { + "location": { + "x": 1397.2946535990513, + "y": 422.51108795463841 + }, + "nodeIndex": "mp остатки", + "nodeLineageTag": "0d2dd773-f3b9-4998-a61e-4c0ee3b786f7", + "size": { + "height": 152, + "width": 234 + }, + "zIndex": 17, + "expandedHeight": 272 + }, + { + "location": { + "x": 879.52645993747183, + "y": 646.08722694057167 + }, + "nodeIndex": "mp аналитика продаж", + "nodeLineageTag": "58250bbb-338e-4a45-893e-194a83401242", + "size": { + "height": 152, + "width": 234 + }, + "zIndex": 11, + "expandedHeight": 300 + }, + { + "location": { + "x": 0, + "y": 66.03828416218451 + }, + "nodeIndex": "Менеджеры", + "nodeLineageTag": "def64f4b-cbb7-4474-ac96-3666666a1096", + "size": { + "height": 104, + "width": 234 + }, + "zIndex": 23, + "expandedHeight": 152 + }, + { + "location": { + "x": 861.46790242389773, + "y": 875.62787424427336 + }, + "nodeIndex": "Упущенные продажи", + "nodeLineageTag": "3971542f-0c46-485b-9c48-73006d99f2be", + "size": { + "height": 152, + "width": 234 + }, + "zIndex": 22, + "expandedHeight": 300 + }, + { + "location": { + "x": 1715.3846898844733, + "y": 118.27935590649554 + }, + "nodeIndex": "Расходы по годам", + "nodeLineageTag": "fd14666a-afa4-4e1e-b839-07b6214ab536", + "size": { + "height": 72, + "width": 234 + }, + "zIndex": 1, + "expandedHeight": 272 + }, + { + "location": { + "x": 1557.5020243171532, + "y": 773.66967180124664 + }, + "nodeIndex": "Заказы все", + "nodeLineageTag": "27466267-3e13-47a0-9e7b-4f6283bee193", + "size": { + "height": 128, + "width": 234 + }, + "zIndex": 2, + "expandedHeight": 300 + }, + { + "location": { + "x": 1708.9772899451859, + "y": 485.93002622980629 + }, + "nodeIndex": "mp реклама", + "nodeLineageTag": "6204a654-5807-4a4b-b334-e584c554211f", + "size": { + "height": 176, + "width": 234 + }, + "zIndex": 0, + "expandedHeight": 300 + }, + { + "location": { + "x": 1399.6889244439476, + "y": 127.60354121010988 + }, + "nodeIndex": "План маркеты", + "nodeLineageTag": "0f193589-de81-448a-9dec-947bcb7e02e9", + "size": { + "height": 104, + "width": 234 + }, + "zIndex": 0, + "expandedHeight": 176 + }, + { + "location": { + "x": 1125.8010546698013, + "y": 529.186820587779 + }, + "nodeIndex": "Резервы", + "nodeLineageTag": "66ec7641-9058-4f7a-9c9c-83c8bc3e1b61", + "size": { + "height": 104, + "width": 234 + }, + "zIndex": 0, + "expandedHeight": 200 + }, + { + "location": { + "x": 1999.3846898844733, + "y": 409.50702895349787 + }, + "nodeIndex": "Я.Директ расходы", + "size": { + "height": 300, + "width": 234 + }, + "zIndex": 0 + }, + { + "location": { + "x": 2283.3846898844731, + "y": 447.50702895349787 + }, + "nodeIndex": "Я.Директ заказы", + "size": { + "height": 224, + "width": 234 + }, + "zIndex": 0 + }, + { + "location": {}, + "nodeIndex": "mp узел", + "size": { + "height": 152, + "width": 234 + }, + "zIndex": 0 + }, + { + "location": {}, + "nodeIndex": "mp оборот", + "size": { + "height": 200, + "width": 234 + }, + "zIndex": 0 + } + ], + "name": "Все таблицы", + "zoomValue": 44.489226033719291, + "pinKeyFieldsToTop": false, + "showExtraHeaderInfo": false, + "hideKeyFieldsWhenCollapsed": false, + "tablesLocked": false + }, + { + "ordinal": 1, + "scrollPosition": { + "x": 0, + "y": 0 + }, + "nodes": [ + { + "location": { + "x": 278.82072939327463, + "y": 0 + }, + "nodeIndex": "Себестоимость", + "nodeLineageTag": "14d56775-0ee6-4ae1-af81-db38504b0997", + "size": { + "height": 224, + "width": 234 + }, + "zIndex": 6, + "expandedHeight": 300 + }, + { + "location": { + "x": 576.85444350025887, + "y": 0 + }, + "nodeIndex": "Номенклатура", + "nodeLineageTag": "f50f43b8-653f-4068-88a3-0ada40f333a9", + "size": { + "height": 128, + "width": 234 + }, + "zIndex": 1, + "expandedHeight": 300 + }, + { + "location": { + "x": 579.30497128726233, + "y": 150.23186583948245 + }, + "nodeIndex": "Партнер", + "nodeLineageTag": "97e02e8a-24d7-460f-a5d4-380f0994e0c4", + "size": { + "height": 200, + "width": 234 + }, + "zIndex": 4, + "expandedHeight": 300 + }, + { + "location": { + "x": 0, + "y": 0 + }, + "nodeIndex": "Организация", + "nodeLineageTag": "445da135-b7ce-41de-a01b-f652726fbeda", + "size": { + "height": 104, + "width": 234 + }, + "zIndex": 2, + "expandedHeight": 200 + }, + { + "location": { + "x": 273, + "y": 313.79564757385549 + }, + "nodeIndex": ".Календарь", + "nodeLineageTag": "fa15f6a2-9f96-4009-a5f4-ba8eaed6c41f", + "size": { + "height": 104, + "width": 234 + }, + "zIndex": 3, + "expandedHeight": 224 + } + ], + "name": "Себестоимость", + "zoomValue": 100, + "pinKeyFieldsToTop": false, + "showExtraHeaderInfo": false, + "hideKeyFieldsWhenCollapsed": false, + "tablesLocked": false + }, + { + "ordinal": 2, + "scrollPosition": { + "x": 0, + "y": 0 + }, + "nodes": [ + { + "location": { + "x": 334.17858572069377, + "y": 162.93565687764863 + }, + "nodeIndex": "Закупки", + "nodeLineageTag": "3b808b20-2111-4e80-9c03-a234a8b34733", + "size": { + "height": 176, + "width": 234 + }, + "zIndex": 0, + "expandedHeight": 300 + }, + { + "location": { + "x": 911.45841204098838, + "y": 137.92652400598126 + }, + "nodeIndex": "Заказы все", + "nodeLineageTag": "27466267-3e13-47a0-9e7b-4f6283bee193", + "size": { + "height": 128, + "width": 234 + }, + "zIndex": 0, + "expandedHeight": 300 + }, + { + "location": { + "x": 50.006187814825424, + "y": 429.90011254954914 + }, + "nodeIndex": ".Календарь", + "nodeLineageTag": "fa15f6a2-9f96-4009-a5f4-ba8eaed6c41f", + "size": { + "height": 104, + "width": 234 + }, + "zIndex": 0, + "expandedHeight": 224 + }, + { + "location": { + "x": 618.39447550116085, + "y": 6.9547428984280941 + }, + "nodeIndex": "Номенклатура", + "nodeLineageTag": "f50f43b8-653f-4068-88a3-0ada40f333a9", + "size": { + "height": 128, + "width": 234 + }, + "zIndex": 0, + "expandedHeight": 300 + }, + { + "location": { + "x": 50, + "y": -50 + }, + "nodeIndex": "Организация", + "nodeLineageTag": "445da135-b7ce-41de-a01b-f652726fbeda", + "size": { + "height": 104, + "width": 234 + }, + "zIndex": 0, + "expandedHeight": 200 + }, + { + "location": { + "x": 598.17799730451543, + "y": 389.07734323365776 + }, + "nodeIndex": "Партнер", + "nodeLineageTag": "97e02e8a-24d7-460f-a5d4-380f0994e0c4", + "size": { + "height": 200, + "width": 234 + }, + "zIndex": 0, + "expandedHeight": 300 + } + ], + "name": "Закупки", + "zoomValue": 72.098030420636007, + "pinKeyFieldsToTop": false, + "showExtraHeaderInfo": false, + "hideKeyFieldsWhenCollapsed": false, + "tablesLocked": false + }, + { + "ordinal": 3, + "scrollPosition": { + "x": 0, + "y": 0 + }, + "nodes": [ + { + "location": { + "x": 319.85173587601759, + "y": 185.55473625676396 + }, + "nodeIndex": "Номенклатура", + "nodeLineageTag": "f50f43b8-653f-4068-88a3-0ada40f333a9", + "size": { + "height": 128, + "width": 234 + }, + "zIndex": 1, + "expandedHeight": 300 + }, + { + "location": { + "x": 0, + "y": 416.14285714285728 + }, + "nodeIndex": "Стоимость МП", + "nodeLineageTag": "7582b25e-0a47-4bd4-998d-ad7beb18db6d", + "size": { + "height": 176, + "width": 234 + }, + "zIndex": 2, + "expandedHeight": 300 + }, + { + "location": { + "x": 0, + "y": 0 + }, + "nodeIndex": "Себестоимость", + "nodeLineageTag": "14d56775-0ee6-4ae1-af81-db38504b0997", + "size": { + "height": 224, + "width": 234 + }, + "zIndex": 3, + "expandedHeight": 300 + }, + { + "location": { + "x": 264.49934796494404, + "y": 0 + }, + "nodeIndex": "Группы", + "nodeLineageTag": "085eeae7-b80c-4f6e-b69a-6cb3c636ab1e", + "size": { + "height": 104, + "width": 234 + }, + "zIndex": 4, + "expandedHeight": 300 + }, + { + "location": { + "x": 577.89370914977928, + "y": 399.66399436463456 + }, + "nodeIndex": "Остатки", + "nodeLineageTag": "8d7e8c56-9dcb-4c28-b191-4737cd281542", + "size": { + "height": 128, + "width": 234 + }, + "zIndex": 5, + "expandedHeight": 272 + }, + { + "location": { + "x": 836.30168327901436, + "y": 370.14285714285711 + }, + "nodeIndex": "mp остатки", + "nodeLineageTag": "0d2dd773-f3b9-4998-a61e-4c0ee3b786f7", + "size": { + "height": 152, + "width": 234 + }, + "zIndex": 11, + "expandedHeight": 272 + }, + { + "location": { + "x": 0, + "y": 611.60209175832654 + }, + "nodeIndex": "mp аналитика продаж", + "nodeLineageTag": "58250bbb-338e-4a45-893e-194a83401242", + "size": { + "height": 152, + "width": 234 + }, + "zIndex": 6, + "expandedHeight": 300 + }, + { + "location": { + "x": 522, + "y": 0 + }, + "nodeIndex": "ПРАЙСлист", + "nodeLineageTag": "1c432e4c-6774-47b9-a4e5-46ccccc3084a", + "size": { + "height": 128, + "width": 234 + }, + "zIndex": 7, + "expandedHeight": 296 + }, + { + "location": { + "x": 0, + "y": 235.91428922895591 + }, + "nodeIndex": "Упущенные продажи", + "nodeLineageTag": "3971542f-0c46-485b-9c48-73006d99f2be", + "size": { + "height": 152, + "width": 234 + }, + "zIndex": 8, + "expandedHeight": 300 + }, + { + "location": { + "x": 849.87963136149119, + "y": 1.4285714285714306 + }, + "nodeIndex": "Закупки", + "nodeLineageTag": "3b808b20-2111-4e80-9c03-a234a8b34733", + "size": { + "height": 176, + "width": 234 + }, + "zIndex": 10, + "expandedHeight": 300 + }, + { + "location": { + "x": 845.717208859902, + "y": 201.42857142857144 + }, + "nodeIndex": "Заказы все", + "nodeLineageTag": "27466267-3e13-47a0-9e7b-4f6283bee193", + "size": { + "height": 128, + "width": 234 + }, + "zIndex": 9, + "expandedHeight": 300 + }, + { + "location": { + "x": 578.28571537562789, + "y": 560.71428571428578 + }, + "nodeIndex": "Резервы", + "nodeLineageTag": "66ec7641-9058-4f7a-9c9c-83c8bc3e1b61", + "size": { + "height": 104, + "width": 234 + }, + "zIndex": 0, + "expandedHeight": 248 + } + ], + "name": "Номенклатура", + "zoomValue": 70, + "pinKeyFieldsToTop": false, + "showExtraHeaderInfo": false, + "hideKeyFieldsWhenCollapsed": false, + "tablesLocked": false + }, + { + "ordinal": 4, + "scrollPosition": { + "x": 0, + "y": 0 + }, + "nodes": [ + { + "location": { + "x": 463.20931009254724, + "y": 312.10342270120651 + }, + "nodeIndex": "Партнер", + "nodeLineageTag": "97e02e8a-24d7-460f-a5d4-380f0994e0c4", + "size": { + "height": 200, + "width": 234 + }, + "zIndex": 0, + "expandedHeight": 300 + }, + { + "location": { + "x": 0, + "y": 322.867331076958 + }, + "nodeIndex": "Стоимость МП", + "nodeLineageTag": "7582b25e-0a47-4bd4-998d-ad7beb18db6d", + "size": { + "height": 176, + "width": 234 + }, + "zIndex": 0, + "expandedHeight": 300 + }, + { + "location": { + "x": 0, + "y": 17.698512508729767 + }, + "nodeIndex": "Себестоимость", + "nodeLineageTag": "14d56775-0ee6-4ae1-af81-db38504b0997", + "size": { + "height": 224, + "width": 234 + }, + "zIndex": 0, + "expandedHeight": 300 + }, + { + "location": { + "x": 801.27195927338471, + "y": 574.07636918212324 + }, + "nodeIndex": "Заявки на оплату", + "nodeLineageTag": "cf134e75-cc78-416f-a1c4-a3752a52eff1", + "size": { + "height": 152, + "width": 234 + }, + "zIndex": 0, + "expandedHeight": 300 + }, + { + "location": { + "x": 322.6838489227473, + "y": 0 + }, + "nodeIndex": "Менеджеры", + "nodeLineageTag": "def64f4b-cbb7-4474-ac96-3666666a1096", + "size": { + "height": 104, + "width": 234 + }, + "zIndex": 0, + "expandedHeight": 152 + }, + { + "location": { + "x": 734.28440040802957, + "y": 0 + }, + "nodeIndex": "Закупки", + "nodeLineageTag": "3b808b20-2111-4e80-9c03-a234a8b34733", + "size": { + "height": 176, + "width": 234 + }, + "zIndex": 0, + "expandedHeight": 300 + }, + { + "location": { + "x": 67.4617591125649, + "y": 587.47302931263562 + }, + "nodeIndex": "Заказы все", + "nodeLineageTag": "27466267-3e13-47a0-9e7b-4f6283bee193", + "size": { + "height": 128, + "width": 234 + }, + "zIndex": 0, + "expandedHeight": 300 + } + ], + "name": "Партнер", + "zoomValue": 67.802308211387924, + "pinKeyFieldsToTop": false, + "showExtraHeaderInfo": false, + "hideKeyFieldsWhenCollapsed": false, + "tablesLocked": false + }, + { + "ordinal": 5, + "scrollPosition": { + "x": 0, + "y": 0 + }, + "nodes": [ + { + "location": { + "x": 731.79923497418508, + "y": 380.348965964979 + }, + "nodeIndex": ".Календарь", + "nodeLineageTag": "fa15f6a2-9f96-4009-a5f4-ba8eaed6c41f", + "size": { + "height": 104, + "width": 234 + }, + "zIndex": 0, + "expandedHeight": 224 + }, + { + "location": { + "x": 624.024563493825, + "y": -50 + }, + "nodeIndex": "Стоимость МП", + "nodeLineageTag": "7582b25e-0a47-4bd4-998d-ad7beb18db6d", + "size": { + "height": 176, + "width": 234 + }, + "zIndex": 0, + "expandedHeight": 300 + }, + { + "location": { + "x": 339.86216137017868, + "y": 46.498922391333508 + }, + "nodeIndex": "Себестоимость", + "nodeLineageTag": "14d56775-0ee6-4ae1-af81-db38504b0997", + "size": { + "height": 224, + "width": 234 + }, + "zIndex": 0, + "expandedHeight": 300 + }, + { + "location": { + "x": 124.75191273584787, + "y": 413.09132409722645 + }, + "nodeIndex": "Заявки на оплату", + "nodeLineageTag": "cf134e75-cc78-416f-a1c4-a3752a52eff1", + "size": { + "height": 152, + "width": 234 + }, + "zIndex": 0, + "expandedHeight": 300 + }, + { + "location": { + "x": 56.122105275656139, + "y": 209.7559982310361 + }, + "nodeIndex": "План продаж менеджеров", + "nodeLineageTag": "730b70a2-916d-410b-8ccd-6a28377b1d5f", + "size": { + "height": 128, + "width": 234 + }, + "zIndex": 0, + "expandedHeight": 300 + }, + { + "location": { + "x": 304.62949194707193, + "y": 667.136404296038 + }, + "nodeIndex": "mp остатки", + "nodeLineageTag": "0d2dd773-f3b9-4998-a61e-4c0ee3b786f7", + "size": { + "height": 152, + "width": 234 + }, + "zIndex": 0, + "expandedHeight": 272 + }, + { + "location": { + "x": 658.93291216068769, + "y": 692.63638039081729 + }, + "nodeIndex": "mp аналитика продаж", + "nodeLineageTag": "58250bbb-338e-4a45-893e-194a83401242", + "size": { + "height": 152, + "width": 234 + }, + "zIndex": 0, + "expandedHeight": 300 + }, + { + "location": { + "x": 1239.5219403790009, + "y": 134.64269632352392 + }, + "nodeIndex": "ПРАЙСлист", + "nodeLineageTag": "1c432e4c-6774-47b9-a4e5-46ccccc3084a", + "size": { + "height": 128, + "width": 234 + }, + "zIndex": 0, + "expandedHeight": 296 + }, + { + "location": { + "x": 1023.1824883911881, + "y": 624.56680923889 + }, + "nodeIndex": "Упущенные продажи", + "nodeLineageTag": "3971542f-0c46-485b-9c48-73006d99f2be", + "size": { + "height": 152, + "width": 234 + }, + "zIndex": 0, + "expandedHeight": 300 + }, + { + "location": { + "x": 1267.2520811466998, + "y": 374.04138366473012 + }, + "nodeIndex": "Закупки", + "nodeLineageTag": "3b808b20-2111-4e80-9c03-a234a8b34733", + "size": { + "height": 176, + "width": 234 + }, + "zIndex": 0, + "expandedHeight": 300 + } + ], + "name": "Календарь", + "zoomValue": 56.563138400491255, + "pinKeyFieldsToTop": false, + "showExtraHeaderInfo": false, + "hideKeyFieldsWhenCollapsed": false, + "tablesLocked": false + }, + { + "ordinal": 6, + "scrollPosition": { + "x": 0, + "y": 0 + }, + "nodes": [ + { + "location": { + "x": 901.0635684672518, + "y": 667.77185407253342 + }, + "nodeIndex": "mp аналитика продаж", + "nodeLineageTag": "58250bbb-338e-4a45-893e-194a83401242", + "size": { + "height": 152, + "width": 234 + }, + "zIndex": 1, + "expandedHeight": 300 + }, + { + "location": { + "x": 461.11882653339137, + "y": -50 + }, + "nodeIndex": "Номенклатура", + "nodeLineageTag": "f50f43b8-653f-4068-88a3-0ada40f333a9", + "size": { + "height": 128, + "width": 234 + }, + "zIndex": 2, + "expandedHeight": 300 + }, + { + "location": { + "x": 176.98728238226806, + "y": 6.2160781495917945 + }, + "nodeIndex": ".Календарь", + "nodeLineageTag": "fa15f6a2-9f96-4009-a5f4-ba8eaed6c41f", + "size": { + "height": 104, + "width": 234 + }, + "zIndex": 3, + "expandedHeight": 224 + }, + { + "location": { + "x": 50, + "y": 252.14321515749793 + }, + "nodeIndex": "mp остатки", + "nodeLineageTag": "0d2dd773-f3b9-4998-a61e-4c0ee3b786f7", + "size": { + "height": 152, + "width": 234 + }, + "zIndex": 5, + "expandedHeight": 272 + }, + { + "location": { + "x": 1116.6486804111864, + "y": 7.953611690738569 + }, + "nodeIndex": "Партнер", + "nodeLineageTag": "97e02e8a-24d7-460f-a5d4-380f0994e0c4", + "size": { + "height": 200, + "width": 234 + }, + "zIndex": 6, + "expandedHeight": 300 + }, + { + "location": { + "x": 784.078397523599, + "y": 0 + }, + "nodeIndex": "Организация", + "nodeLineageTag": "445da135-b7ce-41de-a01b-f652726fbeda", + "size": { + "height": 200, + "width": 234 + }, + "zIndex": 8 + }, + { + "location": { + "x": 270.74894072150448, + "y": 541.4919981410452 + }, + "nodeIndex": "mp реклама", + "nodeLineageTag": "6204a654-5807-4a4b-b334-e584c554211f", + "size": { + "height": 176, + "width": 234 + }, + "zIndex": 7, + "expandedHeight": 300 + } + ], + "name": "МП", + "zoomValue": 57.987299814218673, + "pinKeyFieldsToTop": false, + "showExtraHeaderInfo": false, + "hideKeyFieldsWhenCollapsed": false, + "tablesLocked": false + }, + { + "ordinal": 7, + "scrollPosition": { + "x": 0, + "y": 0 + }, + "nodes": [ + { + "location": { + "x": 336.62869602952946, + "y": 302.97185681962878 + }, + "nodeIndex": "mp узел", + "nodeLineageTag": "5fc1bba4-c923-4dff-9116-09c8bfccfff6", + "size": { + "height": 152, + "width": 234 + }, + "zIndex": 0, + "expandedHeight": 152 + }, + { + "location": { + "x": 716.53585436394167, + "y": 183.77251858355436 + }, + "nodeIndex": "Партнер", + "nodeLineageTag": "97e02e8a-24d7-460f-a5d4-380f0994e0c4", + "size": { + "height": 224, + "width": 234 + }, + "zIndex": 0, + "expandedHeight": 300 + }, + { + "location": { + "x": 534.23407008970389, + "y": -50 + }, + "nodeIndex": "mp остатки", + "nodeLineageTag": "0d2dd773-f3b9-4998-a61e-4c0ee3b786f7", + "size": { + "height": 152, + "width": 234 + }, + "zIndex": 0, + "expandedHeight": 300 + }, + { + "location": { + "x": 208.23895162812818, + "y": -49.775485418642916 + }, + "nodeIndex": "mp аналитика продаж", + "nodeLineageTag": "58250bbb-338e-4a45-893e-194a83401242", + "size": { + "height": 152, + "width": 234 + }, + "zIndex": 0, + "expandedHeight": 300 + }, + { + "location": { + "x": 0, + "y": 215.08167563814186 + }, + "nodeIndex": "mp реклама", + "nodeLineageTag": "6204a654-5807-4a4b-b334-e584c554211f", + "size": { + "height": 176, + "width": 234 + }, + "zIndex": 0, + "expandedHeight": 300 + }, + { + "location": { + "x": 563.20782384973438, + "y": 508.16068530776022 + }, + "nodeIndex": "Организация", + "nodeLineageTag": "445da135-b7ce-41de-a01b-f652726fbeda", + "size": { + "height": 104, + "width": 234 + }, + "zIndex": 0, + "expandedHeight": 200 + } + ], + "name": "Макет 1", + "zoomValue": 80, + "pinKeyFieldsToTop": false, + "showExtraHeaderInfo": false, + "hideKeyFieldsWhenCollapsed": false, + "tablesLocked": false + } + ], + "selectedDiagram": "Макет 1", + "defaultDiagram": "Все таблицы" +} \ No newline at end of file diff --git a/analytics/pbi/model/report/Model/cultures/ru-RU.tmdl b/analytics/pbi/model/report/Model/cultures/ru-RU.tmdl new file mode 100644 index 0000000..9bd6e7d --- /dev/null +++ b/analytics/pbi/model/report/Model/cultures/ru-RU.tmdl @@ -0,0 +1,3734 @@ +cultureInfo ru-RU + + linguisticMetadata = + { + "Version": "1.2.0", + "Language": "en-US", + "Entities": { + "номенклатура": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Terms": [ + { + "номенклатура": { + "State": "Generated" + } + } + ] + }, + "номенклатура.artic_id": { + "Binding": { + "ConceptualEntity": "Номенклатура", + "ConceptualProperty": "_artic_id" + }, + "State": "Generated", + "Hidden": true, + "Terms": [ + { + "artic id": { + "State": "Generated" + } + }, + { + "_artic_id": { + "Type": "Noun", + "State": "Generated", + "Weight": 0.99 + } + }, + { + "artic identification": { + "Type": "Noun", + "State": "Suggested", + "Weight": 0.75 + } + }, + { + "artic identity": { + "Type": "Noun", + "State": "Suggested", + "Weight": 0.75 + } + }, + { + "artic identifier": { + "Type": "Noun", + "State": "Suggested", + "Weight": 0.75 + } + }, + { + "artic credential": { + "Type": "Noun", + "State": "Suggested", + "Weight": 0.727 + } + } + ] + }, + "номенклатура.код_УТ": { + "Binding": { + "ConceptualEntity": "Номенклатура", + "ConceptualProperty": "Код УТ" + }, + "State": "Generated", + "Terms": [ + { + "код УТ": { + "State": "Generated" + } + } + ] + }, + "номенклатура.наименование": { + "Binding": { + "ConceptualEntity": "Номенклатура", + "ConceptualProperty": "Наименование" + }, + "State": "Generated", + "Terms": [ + { + "наименование": { + "State": "Generated" + } + } + ] + }, + "номенклатура.артикул": { + "Binding": { + "ConceptualEntity": "Номенклатура", + "ConceptualProperty": "Артикул" + }, + "State": "Generated", + "Terms": [ + { + "артикул": { + "State": "Generated" + } + } + ] + }, + "номенклатура.group_id": { + "Binding": { + "ConceptualEntity": "Номенклатура", + "ConceptualProperty": "_group_id" + }, + "State": "Generated", + "Hidden": true, + "Terms": [ + { + "group id": { + "State": "Generated" + } + }, + { + "_group_id": { + "Type": "Noun", + "State": "Generated", + "Weight": 0.99 + } + }, + { + "group identification": { + "Type": "Noun", + "State": "Suggested", + "Weight": 0.75 + } + }, + { + "group identity": { + "Type": "Noun", + "State": "Suggested", + "Weight": 0.75 + } + }, + { + "group identifier": { + "Type": "Noun", + "State": "Suggested", + "Weight": 0.75 + } + }, + { + "group credential": { + "Type": "Noun", + "State": "Suggested", + "Weight": 0.727 + } + }, + { + "category id": { + "Type": "Noun", + "State": "Suggested", + "Weight": 0.6 + } + }, + { + "organization id": { + "Type": "Noun", + "State": "Suggested", + "Weight": 0.6 + } + }, + { + "bracket id": { + "Type": "Noun", + "State": "Suggested", + "Weight": 0.582 + } + }, + { + "class id": { + "Type": "Noun", + "State": "Suggested", + "Weight": 0.582 + } + }, + { + "crew id": { + "Type": "Noun", + "State": "Suggested", + "Weight": 0.582 + } + }, + { + "team id": { + "Type": "Noun", + "State": "Suggested", + "Weight": 0.582 + } + } + ] + }, + "номенклатура.ценовая_группа": { + "Binding": { + "ConceptualEntity": "Номенклатура", + "ConceptualProperty": "Ценовая группа" + }, + "State": "Generated", + "Terms": [ + { + "ценовая группа": { + "State": "Generated" + } + } + ] + }, + "номенклатура.производитель": { + "Binding": { + "ConceptualEntity": "Номенклатура", + "ConceptualProperty": "Производитель" + }, + "State": "Generated", + "Terms": [ + { + "производитель": { + "State": "Generated" + } + } + ] + }, + "номенклатура.фото": { + "Binding": { + "ConceptualEntity": "Номенклатура", + "ConceptualProperty": "Фото" + }, + "State": "Generated", + "Terms": [ + { + "фото": { + "State": "Generated" + } + } + ] + }, + "номенклатура.менеджер_по_закупкам_2": { + "Binding": { + "ConceptualEntity": "Номенклатура", + "ConceptualProperty": "Менеджер по закупкам" + }, + "State": "Generated", + "Terms": [ + { + "менеджер по закупкам 2": { + "State": "Generated" + } + }, + { + "МенеджерПоЗакупкам2": { + "Type": "Noun", + "State": "Generated", + "Weight": 0.99 + } + } + ] + }, + "номенклатура.руководитель_направления": { + "Binding": { + "ConceptualEntity": "Номенклатура", + "ConceptualProperty": "РуководительНаправления" + }, + "State": "Generated", + "Terms": [ + { + "руководитель направления": { + "State": "Generated" + } + }, + { + "РуководительНаправления": { + "Type": "Noun", + "State": "Generated", + "Weight": 0.99 + } + } + ] + }, + "номенклатура.базовая_упаковка": { + "Binding": { + "ConceptualEntity": "Номенклатура", + "ConceptualProperty": "Базовая упаковка" + }, + "State": "Generated", + "Terms": [ + { + "базовая упаковка": { + "State": "Generated" + } + } + ] + }, + "номенклатура.начало_продаж.изменение.иерархия_дат": { + "Binding": { + "ConceptualEntity": "Номенклатура", + "VariationSource": "начало продаж", + "VariationSet": "Изменение", + "Hierarchy": "Иерархия дат" + }, + "State": "Generated", + "Terms": [ + { + "иерархия дат": { + "State": "Generated" + } + } + ] + }, + "номенклатура.начало_продаж.изменение.иерархия_дат.год": { + "Binding": { + "ConceptualEntity": "Номенклатура", + "VariationSource": "начало продаж", + "VariationSet": "Изменение", + "Hierarchy": "Иерархия дат", + "HierarchyLevel": "Год" + }, + "State": "Generated", + "Terms": [ + { + "год": { + "State": "Generated" + } + }, + { + "начало продаж год": { + "State": "Generated" + } + } + ] + }, + "номенклатура.начало_продаж.изменение.иерархия_дат.квартал": { + "Binding": { + "ConceptualEntity": "Номенклатура", + "VariationSource": "начало продаж", + "VariationSet": "Изменение", + "Hierarchy": "Иерархия дат", + "HierarchyLevel": "Квартал" + }, + "State": "Generated", + "Terms": [ + { + "квартал": { + "State": "Generated" + } + }, + { + "начало продаж квартал": { + "State": "Generated" + } + } + ] + }, + "номенклатура.начало_продаж.изменение.иерархия_дат.месяц": { + "Binding": { + "ConceptualEntity": "Номенклатура", + "VariationSource": "начало продаж", + "VariationSet": "Изменение", + "Hierarchy": "Иерархия дат", + "HierarchyLevel": "Месяц" + }, + "State": "Generated", + "Terms": [ + { + "месяц": { + "State": "Generated" + } + }, + { + "начало продаж месяц": { + "State": "Generated" + } + } + ] + }, + "номенклатура.начало_продаж.изменение.иерархия_дат.день": { + "Binding": { + "ConceptualEntity": "Номенклатура", + "VariationSource": "начало продаж", + "VariationSet": "Изменение", + "Hierarchy": "Иерархия дат", + "HierarchyLevel": "День" + }, + "State": "Generated", + "Terms": [ + { + "день": { + "State": "Generated" + } + }, + { + "начало продаж день": { + "State": "Generated" + } + } + ] + }, + "номенклатура.АБС_статус": { + "Binding": { + "ConceptualEntity": "Номенклатура", + "ConceptualProperty": "ABC статус 12м" + }, + "State": "Generated", + "Terms": [ + { + "АБС статус": { + "State": "Generated" + } + } + ] + }, + "партнер": { + "Binding": { + "ConceptualEntity": "Партнер" + }, + "State": "Generated", + "Terms": [ + { + "партнер": { + "State": "Generated" + } + } + ] + }, + "партнер.partner_id": { + "Binding": { + "ConceptualEntity": "Партнер", + "ConceptualProperty": "partner_id" + }, + "State": "Generated", + "Hidden": true, + "Terms": [ + { + "partner id": { + "State": "Generated" + } + }, + { + "partner_id": { + "Type": "Noun", + "State": "Generated", + "Weight": 0.99 + } + }, + { + "partner": { + "State": "Generated", + "Weight": 0.97 + } + }, + { + "partner identification": { + "Type": "Noun", + "State": "Suggested", + "Weight": 0.75 + } + }, + { + "partner identity": { + "Type": "Noun", + "State": "Suggested", + "Weight": 0.75 + } + }, + { + "partner identifier": { + "Type": "Noun", + "State": "Suggested", + "Weight": 0.75 + } + }, + { + "partner credential": { + "Type": "Noun", + "State": "Suggested", + "Weight": 0.727 + } + }, + { + "wife": { + "Type": "Noun", + "State": "Suggested", + "Weight": 0.491 + } + }, + { + "lover": { + "Type": "Noun", + "State": "Suggested", + "Weight": 0.491 + } + }, + { + "spouse": { + "Type": "Noun", + "State": "Suggested", + "Weight": 0.476 + } + }, + { + "companion": { + "Type": "Noun", + "State": "Suggested", + "Weight": 0.476 + } + }, + { + "husband": { + "Type": "Noun", + "State": "Suggested", + "Weight": 0.476 + } + }, + { + "mate": { + "Type": "Noun", + "State": "Suggested", + "Weight": 0.476 + } + } + ] + }, + "партнер.партнер": { + "Binding": { + "ConceptualEntity": "Партнер", + "ConceptualProperty": "Партнер" + }, + "State": "Generated", + "Terms": [ + { + "партнер": { + "State": "Generated" + } + }, + { + "партнер name": { + "State": "Generated" + } + } + ] + }, + "партнер.регион": { + "Binding": { + "ConceptualEntity": "Партнер", + "ConceptualProperty": "Регион" + }, + "State": "Generated", + "Terms": [ + { + "регион": { + "State": "Generated" + } + } + ] + }, + "партнер.manager_id": { + "Binding": { + "ConceptualEntity": "Партнер", + "ConceptualProperty": "manager_id" + }, + "State": "Generated", + "Hidden": true, + "Terms": [ + { + "manager id": { + "State": "Generated" + } + }, + { + "manager_id": { + "Type": "Noun", + "State": "Generated", + "Weight": 0.99 + } + }, + { + "manager": { + "State": "Generated", + "Weight": 0.97 + } + }, + { + "manager identification": { + "Type": "Noun", + "State": "Suggested", + "Weight": 0.75 + } + }, + { + "manager identity": { + "Type": "Noun", + "State": "Suggested", + "Weight": 0.75 + } + }, + { + "manager identifier": { + "Type": "Noun", + "State": "Suggested", + "Weight": 0.75 + } + }, + { + "manager credential": { + "Type": "Noun", + "State": "Suggested", + "Weight": 0.727 + } + }, + { + "director": { + "Type": "Noun", + "State": "Suggested", + "Weight": 0.491 + } + }, + { + "administrator": { + "Type": "Noun", + "State": "Suggested", + "Weight": 0.491 + } + }, + { + "supervisor": { + "Type": "Noun", + "State": "Suggested", + "Weight": 0.491 + } + }, + { + "leader": { + "Type": "Noun", + "State": "Suggested", + "Weight": 0.491 + } + }, + { + "boss": { + "Type": "Noun", + "State": "Suggested", + "Weight": 0.476 + } + }, + { + "executive": { + "Type": "Noun", + "State": "Suggested", + "Weight": 0.476 + } + } + ] + }, + "партнер.да_нет_клиент": { + "Binding": { + "ConceptualEntity": "Партнер", + "ConceptualProperty": "Да/Нет Клиент" + }, + "State": "Generated", + "Terms": [ + { + "да/нет клиент": { + "State": "Generated" + } + }, + { + "да": { + "State": "Generated", + "Weight": 0.97 + } + }, + { + "да нет клиент": { + "State": "Generated", + "Weight": 0.97 + } + }, + { + "нет клиент": { + "State": "Generated", + "Weight": 0.97 + } + } + ] + }, + "партнер.да_нет_поставщик": { + "Binding": { + "ConceptualEntity": "Партнер", + "ConceptualProperty": "Да/Нет Поставщик" + }, + "State": "Generated", + "Terms": [ + { + "да/нет поставщик": { + "State": "Generated" + } + }, + { + "да": { + "State": "Generated", + "Weight": 0.97 + } + }, + { + "да нет поставщик": { + "State": "Generated", + "Weight": 0.97 + } + }, + { + "нет поставщик": { + "State": "Generated", + "Weight": 0.97 + } + } + ] + }, + "партнер.да_нет_конкурент": { + "Binding": { + "ConceptualEntity": "Партнер", + "ConceptualProperty": "Да/Нет Конкурент" + }, + "State": "Generated", + "Terms": [ + { + "да/нет конкурент": { + "State": "Generated" + } + }, + { + "да": { + "State": "Generated", + "Weight": 0.97 + } + }, + { + "да нет конкурент": { + "State": "Generated", + "Weight": 0.97 + } + }, + { + "нет конкурент": { + "State": "Generated", + "Weight": 0.97 + } + } + ] + }, + "номенклатура.статус": { + "Binding": { + "ConceptualEntity": "Номенклатура", + "ConceptualProperty": "Статус" + }, + "State": "Generated", + "Terms": [ + { + "статус": { + "State": "Generated" + } + } + ] + }, + "номенклатура.коллекция": { + "Binding": { + "ConceptualEntity": "Номенклатура", + "ConceptualProperty": "Коллекция" + }, + "State": "Generated", + "Terms": [ + { + "коллекция": { + "State": "Generated" + } + } + ] + }, + "номенклатура.бренд": { + "Binding": { + "ConceptualEntity": "Номенклатура", + "ConceptualProperty": "Бренд" + }, + "State": "Generated", + "Terms": [ + { + "бренд": { + "State": "Generated" + } + } + ] + }, + "партнер.дата_первого_заказа.изменение.иерархия_дат": { + "Binding": { + "ConceptualEntity": "Партнер", + "VariationSource": "Дата первого заказа", + "VariationSet": "Изменение", + "Hierarchy": "Иерархия дат" + }, + "State": "Generated", + "Terms": [ + { + "иерархия дат": { + "State": "Generated" + } + } + ] + }, + "партнер.дата_первого_заказа.изменение.иерархия_дат.год": { + "Binding": { + "ConceptualEntity": "Партнер", + "VariationSource": "Дата первого заказа", + "VariationSet": "Изменение", + "Hierarchy": "Иерархия дат", + "HierarchyLevel": "Год" + }, + "State": "Generated", + "Terms": [ + { + "год": { + "State": "Generated" + } + }, + { + "дата первого заказа год": { + "State": "Generated" + } + } + ] + }, + "партнер.дата_первого_заказа.изменение.иерархия_дат.квартал": { + "Binding": { + "ConceptualEntity": "Партнер", + "VariationSource": "Дата первого заказа", + "VariationSet": "Изменение", + "Hierarchy": "Иерархия дат", + "HierarchyLevel": "Квартал" + }, + "State": "Generated", + "Terms": [ + { + "квартал": { + "State": "Generated" + } + }, + { + "дата первого заказа квартал": { + "State": "Generated" + } + } + ] + }, + "партнер.дата_первого_заказа.изменение.иерархия_дат.месяц": { + "Binding": { + "ConceptualEntity": "Партнер", + "VariationSource": "Дата первого заказа", + "VariationSet": "Изменение", + "Hierarchy": "Иерархия дат", + "HierarchyLevel": "Месяц" + }, + "State": "Generated", + "Terms": [ + { + "месяц": { + "State": "Generated" + } + }, + { + "дата первого заказа месяц": { + "State": "Generated" + } + } + ] + }, + "партнер.дата_первого_заказа.изменение.иерархия_дат.день": { + "Binding": { + "ConceptualEntity": "Партнер", + "VariationSource": "Дата первого заказа", + "VariationSet": "Изменение", + "Hierarchy": "Иерархия дат", + "HierarchyLevel": "День" + }, + "State": "Generated", + "Terms": [ + { + "день": { + "State": "Generated" + } + }, + { + "дата первого заказа день": { + "State": "Generated" + } + } + ] + }, + "номенклатура.знаменатель_веса": { + "Binding": { + "ConceptualEntity": "Номенклатура", + "ConceptualProperty": "Знаменатель веса" + }, + "State": "Generated", + "Terms": [ + { + "знаменатель веса": { + "State": "Generated" + } + } + ] + }, + "номенклатура.числитель_веса": { + "Binding": { + "ConceptualEntity": "Номенклатура", + "ConceptualProperty": "Числитель веса" + }, + "State": "Generated", + "Terms": [ + { + "числитель веса": { + "State": "Generated" + } + } + ] + }, + "номенклатура.знаменатель_объема": { + "Binding": { + "ConceptualEntity": "Номенклатура", + "ConceptualProperty": "Знаменатель объема" + }, + "State": "Generated", + "Terms": [ + { + "знаменатель объема": { + "State": "Generated" + } + } + ] + }, + "номенклатура.числитель_объема": { + "Binding": { + "ConceptualEntity": "Номенклатура", + "ConceptualProperty": "Числитель объема" + }, + "State": "Generated", + "Terms": [ + { + "числитель объема": { + "State": "Generated" + } + } + ] + }, + "номенклатура.вид_номенклатуры": { + "Binding": { + "ConceptualEntity": "Номенклатура", + "ConceptualProperty": "Вид номенклатуры" + }, + "State": "Generated", + "Terms": [ + { + "вид номенклатуры": { + "State": "Generated" + } + } + ] + }, + "номенклатура.сквозной_цвет": { + "Binding": { + "ConceptualEntity": "Номенклатура", + "ConceptualProperty": "Сквозной цвет" + }, + "State": "Generated", + "Terms": [ + { + "сквозной цвет": { + "State": "Generated" + } + } + ] + }, + "номенклатура.объем": { + "Binding": { + "ConceptualEntity": "Номенклатура", + "ConceptualProperty": "Объем" + }, + "State": "Generated", + "Terms": [ + { + "объем": { + "State": "Generated" + } + } + ] + }, + "номенклатура.начало_продаж_иерархия": { + "Binding": { + "ConceptualEntity": "Номенклатура", + "Hierarchy": "начало продаж Иерархия" + }, + "State": "Generated", + "Terms": [ + { + "начало продаж иерархия": { + "State": "Generated" + } + } + ], + "SemanticType": "Time" + }, + "номенклатура.начало_продаж_иерархия.начало_продаж": { + "Binding": { + "ConceptualEntity": "Номенклатура", + "Hierarchy": "начало продаж Иерархия", + "HierarchyLevel": "начало продаж" + }, + "State": "Generated", + "Terms": [ + { + "начало продаж": { + "State": "Generated" + } + } + ], + "SemanticType": "Time" + }, + "номенклатура.начало_продаж_иерархия.знаменатель_объема": { + "Binding": { + "ConceptualEntity": "Номенклатура", + "Hierarchy": "начало продаж Иерархия", + "HierarchyLevel": "Знаменатель объема" + }, + "State": "Generated", + "Terms": [ + { + "знаменатель объема": { + "State": "Generated" + } + } + ], + "SemanticType": "Time" + } + }, + "Relationships": { + "партнер_is_named_партнер": { + "Binding": { + "ConceptualEntity": "Партнер" + }, + "State": "Generated", + "Roles": { + "партнер": { + "Target": { + "Entity": "партнер" + } + }, + "партнер.партнер": { + "Target": { + "Entity": "партнер.партнер" + } + } + }, + "Phrasings": [ + { + "Name": { + "Subject": { + "Role": "партнер" + }, + "Name": { + "Role": "партнер.партнер" + } + }, + "State": "Generated", + "Weight": 0.99 + }, + { + "Attribute": { + "Subject": { + "Role": "партнер" + }, + "Object": { + "Role": "партнер.партнер" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_код_УТ": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.код_УТ": { + "Target": { + "Entity": "номенклатура.код_УТ" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.код_УТ" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_наименование": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.наименование": { + "Target": { + "Entity": "номенклатура.наименование" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.наименование" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_артикул": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.артикул": { + "Target": { + "Entity": "номенклатура.артикул" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.артикул" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_ценовая_группа": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.ценовая_группа": { + "Target": { + "Entity": "номенклатура.ценовая_группа" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.ценовая_группа" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_производитель": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.производитель": { + "Target": { + "Entity": "номенклатура.производитель" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.производитель" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_ссылка_на_карточку_товара": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.ссылка_на_карточку_товара": { + "Target": { + "Entity": "номенклатура.ссылка_на_карточку_товара" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.ссылка_на_карточку_товара" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_фото": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.фото": { + "Target": { + "Entity": "номенклатура.фото" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.фото" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_товарный_менеджера": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.товарный_менеджера": { + "Target": { + "Entity": "номенклатура.товарный_менеджера" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.товарный_менеджера" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_менеджер_по_закупкам_2": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.менеджер_по_закупкам_2": { + "Target": { + "Entity": "номенклатура.менеджер_по_закупкам_2" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.менеджер_по_закупкам_2" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_руководитель_направления": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.руководитель_направления": { + "Target": { + "Entity": "номенклатура.руководитель_направления" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.руководитель_направления" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_базовая_упаковка": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.базовая_упаковка": { + "Target": { + "Entity": "номенклатура.базовая_упаковка" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.базовая_упаковка" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_недель_в_продаже": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.недель_в_продаже": { + "Target": { + "Entity": "номенклатура.недель_в_продаже" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.недель_в_продаже" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_норма_продаж_шт_в_день": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.норма_продаж_шт_в_день": { + "Target": { + "Entity": "номенклатура.норма_продаж_шт_в_день" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.норма_продаж_шт_в_день" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_норма_продаж_упак_в_день": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.норма_продаж_упак_в_день": { + "Target": { + "Entity": "номенклатура.норма_продаж_упак_в_день" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.норма_продаж_упак_в_день" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_всего_продано_шт": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.всего_продано_шт": { + "Target": { + "Entity": "номенклатура.всего_продано_шт" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.всего_продано_шт" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_всего_продано_упаковок": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.всего_продано_упаковок": { + "Target": { + "Entity": "номенклатура.всего_продано_упаковок" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.всего_продано_упаковок" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_дней_в_продаже": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.дней_в_продаже": { + "Target": { + "Entity": "номенклатура.дней_в_продаже" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.дней_в_продаже" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_начало_продаж": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.начало_продаж": { + "Target": { + "Entity": "номенклатура.начало_продаж" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.начало_продаж" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_остаток_продаж_дн": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.остаток_продаж_дн": { + "Target": { + "Entity": "номенклатура.остаток_продаж_дн" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.остаток_продаж_дн" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_АБС_статус": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.АБС_статус": { + "Target": { + "Entity": "номенклатура.АБС_статус" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.АБС_статус" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_последняя_цена": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.последняя_цена": { + "Target": { + "Entity": "номенклатура.последняя_цена" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.последняя_цена" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_плана_маржи": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.плана_маржи": { + "Target": { + "Entity": "номенклатура.плана_маржи" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.плана_маржи" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_коэф_плана_по_марже": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.коэф_плана_по_марже": { + "Target": { + "Entity": "номенклатура.коэф_плана_по_марже" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.коэф_плана_по_марже" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_зп": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.зп": { + "Target": { + "Entity": "номенклатура.зп" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.зп" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_маржа__коэф": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.маржа__коэф": { + "Target": { + "Entity": "номенклатура.маржа__коэф" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.маржа__коэф" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "партнер_has_регион": { + "Binding": { + "ConceptualEntity": "Партнер" + }, + "State": "Generated", + "Roles": { + "партнер": { + "Target": { + "Entity": "партнер" + } + }, + "партнер.регион": { + "Target": { + "Entity": "партнер.регион" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "партнер" + }, + "Object": { + "Role": "партнер.регион" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "партнер_has_направление": { + "Binding": { + "ConceptualEntity": "Партнер" + }, + "State": "Generated", + "Roles": { + "партнер": { + "Target": { + "Entity": "партнер" + } + }, + "партнер.направление": { + "Target": { + "Entity": "партнер.направление" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "партнер" + }, + "Object": { + "Role": "партнер.направление" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "партнер_has_да_нет_клиент": { + "Binding": { + "ConceptualEntity": "Партнер" + }, + "State": "Generated", + "Roles": { + "партнер": { + "Target": { + "Entity": "партнер" + } + }, + "партнер.да_нет_клиент": { + "Target": { + "Entity": "партнер.да_нет_клиент" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "партнер" + }, + "Object": { + "Role": "партнер.да_нет_клиент" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "партнер_has_да_нет_поставщик": { + "Binding": { + "ConceptualEntity": "Партнер" + }, + "State": "Generated", + "Roles": { + "партнер": { + "Target": { + "Entity": "партнер" + } + }, + "партнер.да_нет_поставщик": { + "Target": { + "Entity": "партнер.да_нет_поставщик" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "партнер" + }, + "Object": { + "Role": "партнер.да_нет_поставщик" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "партнер_has_да_нет_конкурент": { + "Binding": { + "ConceptualEntity": "Партнер" + }, + "State": "Generated", + "Roles": { + "партнер": { + "Target": { + "Entity": "партнер" + } + }, + "партнер.да_нет_конкурент": { + "Target": { + "Entity": "партнер.да_нет_конкурент" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "партнер" + }, + "Object": { + "Role": "партнер.да_нет_конкурент" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_таблица_продаж_остаток_продаж_дн_": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "таблица_продаж.остаток_продаж_дн_": { + "Target": { + "Entity": "таблица_продаж.остаток_продаж_дн_" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "таблица_продаж.остаток_продаж_дн_" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_статус": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.статус": { + "Target": { + "Entity": "номенклатура.статус" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.статус" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_коллекция": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.коллекция": { + "Target": { + "Entity": "номенклатура.коллекция" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.коллекция" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_KPI_продажи_предыдущий_год_единиц_мес": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.KPI_продажи_предыдущий_год_единиц_мес": { + "Target": { + "Entity": "номенклатура.KPI_продажи_предыдущий_год_единиц_мес" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.KPI_продажи_предыдущий_год_единиц_мес" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_KPI_излишек_китай": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.KPI_излишек_китай": { + "Target": { + "Entity": "номенклатура.KPI_излишек_китай" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.KPI_излишек_китай" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_KPI_дней_с_первого_появления": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.KPI_дней_с_первого_появления": { + "Target": { + "Entity": "номенклатура.KPI_дней_с_первого_появления" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.KPI_дней_с_первого_появления" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_KPI_маржа_предыдущий_год": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.KPI_маржа_предыдущий_год": { + "Target": { + "Entity": "номенклатура.KPI_маржа_предыдущий_год" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.KPI_маржа_предыдущий_год" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_KPI_план_торг__надбавка": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.KPI_план_торг__надбавка": { + "Target": { + "Entity": "номенклатура.KPI_план_торг__надбавка" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.KPI_план_торг__надбавка" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_KPI_маржа_текущий_год": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.KPI_маржа_текущий_год": { + "Target": { + "Entity": "номенклатура.KPI_маржа_текущий_год" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.KPI_маржа_текущий_год" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_KPI_продажи_текущий_год": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.KPI_продажи_текущий_год": { + "Target": { + "Entity": "номенклатура.KPI_продажи_текущий_год" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.KPI_продажи_текущий_год" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "партнер_has_наименование": { + "Binding": { + "ConceptualEntity": "Партнер" + }, + "State": "Generated", + "Roles": { + "партнер": { + "Target": { + "Entity": "партнер" + } + }, + "партнер.наименование": { + "Target": { + "Entity": "партнер.наименование" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "партнер" + }, + "Object": { + "Role": "партнер.наименование" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_бренд": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.бренд": { + "Target": { + "Entity": "номенклатура.бренд" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.бренд" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_KPI_продажи_предыдущий_год": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.KPI_продажи_предыдущий_год": { + "Target": { + "Entity": "номенклатура.KPI_продажи_предыдущий_год" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.KPI_продажи_предыдущий_год" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_KPI__маржи_прошлый_год": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.KPI__маржи_прошлый_год": { + "Target": { + "Entity": "номенклатура.KPI__маржи_прошлый_год" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.KPI__маржи_прошлый_год" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_KPI__маржи_текущий_год": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.KPI__маржи_текущий_год": { + "Target": { + "Entity": "номенклатура.KPI__маржи_текущий_год" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.KPI__маржи_текущий_год" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_KPI_план_продаж": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.KPI_план_продаж": { + "Target": { + "Entity": "номенклатура.KPI_план_продаж" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.KPI_план_продаж" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "партнер_has_дата_первого_заказа": { + "Binding": { + "ConceptualEntity": "Партнер" + }, + "State": "Generated", + "Roles": { + "партнер": { + "Target": { + "Entity": "партнер" + } + }, + "партнер.дата_первого_заказа": { + "Target": { + "Entity": "партнер.дата_первого_заказа" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "партнер" + }, + "Object": { + "Role": "партнер.дата_первого_заказа" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_знаменатель_веса": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.знаменатель_веса": { + "Target": { + "Entity": "номенклатура.знаменатель_веса" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.знаменатель_веса" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_числитель_веса": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.числитель_веса": { + "Target": { + "Entity": "номенклатура.числитель_веса" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.числитель_веса" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_знаменатель_объема": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.знаменатель_объема": { + "Target": { + "Entity": "номенклатура.знаменатель_объема" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.знаменатель_объема" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_числитель_объема": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.числитель_объема": { + "Target": { + "Entity": "номенклатура.числитель_объема" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.числитель_объема" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_вид_номенклатуры": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.вид_номенклатуры": { + "Target": { + "Entity": "номенклатура.вид_номенклатуры" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.вид_номенклатуры" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_сквозной_цвет": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.сквозной_цвет": { + "Target": { + "Entity": "номенклатура.сквозной_цвет" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.сквозной_цвет" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_объем": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.объем": { + "Target": { + "Entity": "номенклатура.объем" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.объем" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_начало_продаж_иерархия": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "номенклатура.начало_продаж_иерархия": { + "Target": { + "Entity": "номенклатура.начало_продаж_иерархия" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "номенклатура.начало_продаж_иерархия" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "партнер_has_когорта": { + "Binding": { + "ConceptualEntity": "Партнер" + }, + "State": "Generated", + "Roles": { + "партнер": { + "Target": { + "Entity": "партнер" + } + }, + "партнер.когорта": { + "Target": { + "Entity": "партнер.когорта" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "партнер" + }, + "Object": { + "Role": "партнер.когорта" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_has_группы": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура": { + "Target": { + "Entity": "номенклатура" + } + }, + "группы": { + "Target": { + "Entity": "группы" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура" + }, + "Object": { + "Role": "группы" + } + }, + "State": "Generated", + "Weight": 0.99 + }, + { + "Attribute": { + "Subject": { + "Role": "группы" + }, + "Object": { + "Role": "номенклатура" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "партнер_has_менеджеры_1С": { + "Binding": { + "ConceptualEntity": "Партнер" + }, + "State": "Generated", + "Roles": { + "партнер": { + "Target": { + "Entity": "партнер" + } + }, + "менеджеры_1С": { + "Target": { + "Entity": "менеджеры_1С" + }, + "Nouns": [ + { + "manager": {} + } + ] + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "партнер" + }, + "Object": { + "Role": "менеджеры_1С" + } + }, + "State": "Generated", + "Weight": 0.99 + }, + { + "Attribute": { + "Subject": { + "Role": "менеджеры_1С" + }, + "Object": { + "Role": "партнер" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_начало_продаж_has_изменение_иерархия_дат": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура.начало_продаж": { + "Target": { + "Entity": "номенклатура.начало_продаж" + } + }, + "номенклатура.начало_продаж.изменение.иерархия_дат": { + "Target": { + "Entity": "номенклатура.начало_продаж.изменение.иерархия_дат" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура.начало_продаж" + }, + "Object": { + "Role": "номенклатура.начало_продаж.изменение.иерархия_дат" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_начало_продаж_изменение_иерархия_дат_has_год": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура.начало_продаж.изменение.иерархия_дат": { + "Target": { + "Entity": "номенклатура.начало_продаж.изменение.иерархия_дат" + } + }, + "номенклатура.начало_продаж.изменение.иерархия_дат.год": { + "Target": { + "Entity": "номенклатура.начало_продаж.изменение.иерархия_дат.год" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура.начало_продаж.изменение.иерархия_дат" + }, + "Object": { + "Role": "номенклатура.начало_продаж.изменение.иерархия_дат.год" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_начало_продаж_изменение_иерархия_дат_has_квартал": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура.начало_продаж.изменение.иерархия_дат": { + "Target": { + "Entity": "номенклатура.начало_продаж.изменение.иерархия_дат" + } + }, + "номенклатура.начало_продаж.изменение.иерархия_дат.квартал": { + "Target": { + "Entity": "номенклатура.начало_продаж.изменение.иерархия_дат.квартал" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура.начало_продаж.изменение.иерархия_дат" + }, + "Object": { + "Role": "номенклатура.начало_продаж.изменение.иерархия_дат.квартал" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_начало_продаж_изменение_иерархия_дат_has_месяц": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура.начало_продаж.изменение.иерархия_дат": { + "Target": { + "Entity": "номенклатура.начало_продаж.изменение.иерархия_дат" + } + }, + "номенклатура.начало_продаж.изменение.иерархия_дат.месяц": { + "Target": { + "Entity": "номенклатура.начало_продаж.изменение.иерархия_дат.месяц" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура.начало_продаж.изменение.иерархия_дат" + }, + "Object": { + "Role": "номенклатура.начало_продаж.изменение.иерархия_дат.месяц" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_начало_продаж_изменение_иерархия_дат_has_день": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура.начало_продаж.изменение.иерархия_дат": { + "Target": { + "Entity": "номенклатура.начало_продаж.изменение.иерархия_дат" + } + }, + "номенклатура.начало_продаж.изменение.иерархия_дат.день": { + "Target": { + "Entity": "номенклатура.начало_продаж.изменение.иерархия_дат.день" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура.начало_продаж.изменение.иерархия_дат" + }, + "Object": { + "Role": "номенклатура.начало_продаж.изменение.иерархия_дат.день" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_начало_продаж_изменение_иерархия_дат_год_has_номенклатура_начало_продаж_изменение_иерархия_дат_квартал": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура.начало_продаж.изменение.иерархия_дат.год": { + "Target": { + "Entity": "номенклатура.начало_продаж.изменение.иерархия_дат.год" + } + }, + "номенклатура.начало_продаж.изменение.иерархия_дат.квартал": { + "Target": { + "Entity": "номенклатура.начало_продаж.изменение.иерархия_дат.квартал" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура.начало_продаж.изменение.иерархия_дат.год" + }, + "Object": { + "Role": "номенклатура.начало_продаж.изменение.иерархия_дат.квартал" + } + }, + "State": "Generated", + "Weight": 0.99 + }, + { + "Attribute": { + "Subject": { + "Role": "номенклатура.начало_продаж.изменение.иерархия_дат.квартал" + }, + "Object": { + "Role": "номенклатура.начало_продаж.изменение.иерархия_дат.год" + } + }, + "State": "Generated", + "Weight": 0.99 + }, + { + "Preposition": { + "Subject": { + "Role": "номенклатура.начало_продаж.изменение.иерархия_дат.квартал" + }, + "Prepositions": [ + { + "in": {} + } + ], + "Object": { + "Role": "номенклатура.начало_продаж.изменение.иерархия_дат.год" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_начало_продаж_изменение_иерархия_дат_квартал_has_номенклатура_начало_продаж_изменение_иерархия_дат_месяц": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура.начало_продаж.изменение.иерархия_дат.квартал": { + "Target": { + "Entity": "номенклатура.начало_продаж.изменение.иерархия_дат.квартал" + } + }, + "номенклатура.начало_продаж.изменение.иерархия_дат.месяц": { + "Target": { + "Entity": "номенклатура.начало_продаж.изменение.иерархия_дат.месяц" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура.начало_продаж.изменение.иерархия_дат.квартал" + }, + "Object": { + "Role": "номенклатура.начало_продаж.изменение.иерархия_дат.месяц" + } + }, + "State": "Generated", + "Weight": 0.99 + }, + { + "Attribute": { + "Subject": { + "Role": "номенклатура.начало_продаж.изменение.иерархия_дат.месяц" + }, + "Object": { + "Role": "номенклатура.начало_продаж.изменение.иерархия_дат.квартал" + } + }, + "State": "Generated", + "Weight": 0.99 + }, + { + "Preposition": { + "Subject": { + "Role": "номенклатура.начало_продаж.изменение.иерархия_дат.месяц" + }, + "Prepositions": [ + { + "in": {} + } + ], + "Object": { + "Role": "номенклатура.начало_продаж.изменение.иерархия_дат.квартал" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_начало_продаж_изменение_иерархия_дат_месяц_has_номенклатура_начало_продаж_изменение_иерархия_дат_день": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура.начало_продаж.изменение.иерархия_дат.месяц": { + "Target": { + "Entity": "номенклатура.начало_продаж.изменение.иерархия_дат.месяц" + } + }, + "номенклатура.начало_продаж.изменение.иерархия_дат.день": { + "Target": { + "Entity": "номенклатура.начало_продаж.изменение.иерархия_дат.день" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура.начало_продаж.изменение.иерархия_дат.месяц" + }, + "Object": { + "Role": "номенклатура.начало_продаж.изменение.иерархия_дат.день" + } + }, + "State": "Generated", + "Weight": 0.99 + }, + { + "Attribute": { + "Subject": { + "Role": "номенклатура.начало_продаж.изменение.иерархия_дат.день" + }, + "Object": { + "Role": "номенклатура.начало_продаж.изменение.иерархия_дат.месяц" + } + }, + "State": "Generated", + "Weight": 0.99 + }, + { + "Preposition": { + "Subject": { + "Role": "номенклатура.начало_продаж.изменение.иерархия_дат.день" + }, + "Prepositions": [ + { + "in": {} + } + ], + "Object": { + "Role": "номенклатура.начало_продаж.изменение.иерархия_дат.месяц" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "партнер_дата_первого_заказа_has_изменение_иерархия_дат": { + "Binding": { + "ConceptualEntity": "Партнер" + }, + "State": "Generated", + "Roles": { + "партнер.дата_первого_заказа": { + "Target": { + "Entity": "партнер.дата_первого_заказа" + } + }, + "партнер.дата_первого_заказа.изменение.иерархия_дат": { + "Target": { + "Entity": "партнер.дата_первого_заказа.изменение.иерархия_дат" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "партнер.дата_первого_заказа" + }, + "Object": { + "Role": "партнер.дата_первого_заказа.изменение.иерархия_дат" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "партнер_дата_первого_заказа_изменение_иерархия_дат_has_год": { + "Binding": { + "ConceptualEntity": "Партнер" + }, + "State": "Generated", + "Roles": { + "партнер.дата_первого_заказа.изменение.иерархия_дат": { + "Target": { + "Entity": "партнер.дата_первого_заказа.изменение.иерархия_дат" + } + }, + "партнер.дата_первого_заказа.изменение.иерархия_дат.год": { + "Target": { + "Entity": "партнер.дата_первого_заказа.изменение.иерархия_дат.год" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "партнер.дата_первого_заказа.изменение.иерархия_дат" + }, + "Object": { + "Role": "партнер.дата_первого_заказа.изменение.иерархия_дат.год" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "партнер_дата_первого_заказа_изменение_иерархия_дат_has_квартал": { + "Binding": { + "ConceptualEntity": "Партнер" + }, + "State": "Generated", + "Roles": { + "партнер.дата_первого_заказа.изменение.иерархия_дат": { + "Target": { + "Entity": "партнер.дата_первого_заказа.изменение.иерархия_дат" + } + }, + "партнер.дата_первого_заказа.изменение.иерархия_дат.квартал": { + "Target": { + "Entity": "партнер.дата_первого_заказа.изменение.иерархия_дат.квартал" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "партнер.дата_первого_заказа.изменение.иерархия_дат" + }, + "Object": { + "Role": "партнер.дата_первого_заказа.изменение.иерархия_дат.квартал" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "партнер_дата_первого_заказа_изменение_иерархия_дат_has_месяц": { + "Binding": { + "ConceptualEntity": "Партнер" + }, + "State": "Generated", + "Roles": { + "партнер.дата_первого_заказа.изменение.иерархия_дат": { + "Target": { + "Entity": "партнер.дата_первого_заказа.изменение.иерархия_дат" + } + }, + "партнер.дата_первого_заказа.изменение.иерархия_дат.месяц": { + "Target": { + "Entity": "партнер.дата_первого_заказа.изменение.иерархия_дат.месяц" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "партнер.дата_первого_заказа.изменение.иерархия_дат" + }, + "Object": { + "Role": "партнер.дата_первого_заказа.изменение.иерархия_дат.месяц" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "партнер_дата_первого_заказа_изменение_иерархия_дат_has_день": { + "Binding": { + "ConceptualEntity": "Партнер" + }, + "State": "Generated", + "Roles": { + "партнер.дата_первого_заказа.изменение.иерархия_дат": { + "Target": { + "Entity": "партнер.дата_первого_заказа.изменение.иерархия_дат" + } + }, + "партнер.дата_первого_заказа.изменение.иерархия_дат.день": { + "Target": { + "Entity": "партнер.дата_первого_заказа.изменение.иерархия_дат.день" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "партнер.дата_первого_заказа.изменение.иерархия_дат" + }, + "Object": { + "Role": "партнер.дата_первого_заказа.изменение.иерархия_дат.день" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "партнер_дата_первого_заказа_изменение_иерархия_дат_год_has_партнер_дата_первого_заказа_изменение_иерархия_дат_квартал": { + "Binding": { + "ConceptualEntity": "Партнер" + }, + "State": "Generated", + "Roles": { + "партнер.дата_первого_заказа.изменение.иерархия_дат.год": { + "Target": { + "Entity": "партнер.дата_первого_заказа.изменение.иерархия_дат.год" + } + }, + "партнер.дата_первого_заказа.изменение.иерархия_дат.квартал": { + "Target": { + "Entity": "партнер.дата_первого_заказа.изменение.иерархия_дат.квартал" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "партнер.дата_первого_заказа.изменение.иерархия_дат.год" + }, + "Object": { + "Role": "партнер.дата_первого_заказа.изменение.иерархия_дат.квартал" + } + }, + "State": "Generated", + "Weight": 0.99 + }, + { + "Attribute": { + "Subject": { + "Role": "партнер.дата_первого_заказа.изменение.иерархия_дат.квартал" + }, + "Object": { + "Role": "партнер.дата_первого_заказа.изменение.иерархия_дат.год" + } + }, + "State": "Generated", + "Weight": 0.99 + }, + { + "Preposition": { + "Subject": { + "Role": "партнер.дата_первого_заказа.изменение.иерархия_дат.квартал" + }, + "Prepositions": [ + { + "in": {} + } + ], + "Object": { + "Role": "партнер.дата_первого_заказа.изменение.иерархия_дат.год" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "партнер_дата_первого_заказа_изменение_иерархия_дат_квартал_has_партнер_дата_первого_заказа_изменение_иерархия_дат_месяц": { + "Binding": { + "ConceptualEntity": "Партнер" + }, + "State": "Generated", + "Roles": { + "партнер.дата_первого_заказа.изменение.иерархия_дат.квартал": { + "Target": { + "Entity": "партнер.дата_первого_заказа.изменение.иерархия_дат.квартал" + } + }, + "партнер.дата_первого_заказа.изменение.иерархия_дат.месяц": { + "Target": { + "Entity": "партнер.дата_первого_заказа.изменение.иерархия_дат.месяц" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "партнер.дата_первого_заказа.изменение.иерархия_дат.квартал" + }, + "Object": { + "Role": "партнер.дата_первого_заказа.изменение.иерархия_дат.месяц" + } + }, + "State": "Generated", + "Weight": 0.99 + }, + { + "Attribute": { + "Subject": { + "Role": "партнер.дата_первого_заказа.изменение.иерархия_дат.месяц" + }, + "Object": { + "Role": "партнер.дата_первого_заказа.изменение.иерархия_дат.квартал" + } + }, + "State": "Generated", + "Weight": 0.99 + }, + { + "Preposition": { + "Subject": { + "Role": "партнер.дата_первого_заказа.изменение.иерархия_дат.месяц" + }, + "Prepositions": [ + { + "in": {} + } + ], + "Object": { + "Role": "партнер.дата_первого_заказа.изменение.иерархия_дат.квартал" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "партнер_дата_первого_заказа_изменение_иерархия_дат_месяц_has_партнер_дата_первого_заказа_изменение_иерархия_дат_день": { + "Binding": { + "ConceptualEntity": "Партнер" + }, + "State": "Generated", + "Roles": { + "партнер.дата_первого_заказа.изменение.иерархия_дат.месяц": { + "Target": { + "Entity": "партнер.дата_первого_заказа.изменение.иерархия_дат.месяц" + } + }, + "партнер.дата_первого_заказа.изменение.иерархия_дат.день": { + "Target": { + "Entity": "партнер.дата_первого_заказа.изменение.иерархия_дат.день" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "партнер.дата_первого_заказа.изменение.иерархия_дат.месяц" + }, + "Object": { + "Role": "партнер.дата_первого_заказа.изменение.иерархия_дат.день" + } + }, + "State": "Generated", + "Weight": 0.99 + }, + { + "Attribute": { + "Subject": { + "Role": "партнер.дата_первого_заказа.изменение.иерархия_дат.день" + }, + "Object": { + "Role": "партнер.дата_первого_заказа.изменение.иерархия_дат.месяц" + } + }, + "State": "Generated", + "Weight": 0.99 + }, + { + "Preposition": { + "Subject": { + "Role": "партнер.дата_первого_заказа.изменение.иерархия_дат.день" + }, + "Prepositions": [ + { + "in": {} + } + ], + "Object": { + "Role": "партнер.дата_первого_заказа.изменение.иерархия_дат.месяц" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_начало_продаж_иерархия_has_начало_продаж": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура.начало_продаж_иерархия": { + "Target": { + "Entity": "номенклатура.начало_продаж_иерархия" + } + }, + "номенклатура.начало_продаж_иерархия.начало_продаж": { + "Target": { + "Entity": "номенклатура.начало_продаж_иерархия.начало_продаж" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура.начало_продаж_иерархия" + }, + "Object": { + "Role": "номенклатура.начало_продаж_иерархия.начало_продаж" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + }, + "номенклатура_начало_продаж_иерархия_has_знаменатель_объема": { + "Binding": { + "ConceptualEntity": "Номенклатура" + }, + "State": "Generated", + "Roles": { + "номенклатура.начало_продаж_иерархия": { + "Target": { + "Entity": "номенклатура.начало_продаж_иерархия" + } + }, + "номенклатура.начало_продаж_иерархия.знаменатель_объема": { + "Target": { + "Entity": "номенклатура.начало_продаж_иерархия.знаменатель_объема" + } + } + }, + "Phrasings": [ + { + "Attribute": { + "Subject": { + "Role": "номенклатура.начало_продаж_иерархия" + }, + "Object": { + "Role": "номенклатура.начало_продаж_иерархия.знаменатель_объема" + } + }, + "State": "Generated", + "Weight": 0.99 + } + ] + } + } + } + contentType: json + diff --git a/analytics/pbi/model/report/Model/database.tmdl b/analytics/pbi/model/report/Model/database.tmdl new file mode 100644 index 0000000..d3ecc5f --- /dev/null +++ b/analytics/pbi/model/report/Model/database.tmdl @@ -0,0 +1,3 @@ +database report + compatibilityLevel: 1600 + diff --git a/analytics/pbi/model/report/Model/expressions.tmdl b/analytics/pbi/model/report/Model/expressions.tmdl new file mode 100644 index 0000000..86503f7 --- /dev/null +++ b/analytics/pbi/model/report/Model/expressions.tmdl @@ -0,0 +1,87 @@ +/// DNS-name of the server with BI-data, e.g. "myhost.bitrix24.com" +expression 'Server address' = "magok.bitrix24.ru" meta [IsParameterQuery=true, Type="Text", IsParameterQueryRequired=true] + + annotation PBI_ResultType = Text + +/// Secret token +expression 'Secret key' = "OLK0Ik9i34J1r3afMOHb5Q16DO821hjMru" meta [IsParameterQuery=true, Type="Text", IsParameterQueryRequired=true] + + annotation PBI_ResultType = Text + +expression bx24_load_entity = + let + //https://helpdesk.bitrix24.com/open/16457718/ + //bx24_entity_name: "crm_company_uf" + //https://docs.microsoft.com/en-us/powerquery-m/web-contents + func = (bx24_entity_name as text) as table => + let + response = Web.Contents( + "https://" & #"Server address", + [ + RelativePath = "bitrix/tools/biconnector/pbi.php", + Query = [ + table = bx24_entity_name + ], + Content = Json.FromValue([dateRange = [ + startDate = Date.AddYears(Date.From(DateTime.LocalNow()),-5), + endDate = Date.From(DateTime.LocalNow())], + key = #"Secret key" + ] + ) + ] + ), + jd = Json.Document(response) + in + Table.FromRows( + List.Skip(jd),//data: >=1 row (index 0 based) + List.First(jd)//header: 0 row (index 0 based) + ) + in + func + + annotation PBI_ResultType = Function + +expression 'Ошибки в Я Директ расходы' = + let + Источник = #"Я.Директ расходы стар", + #"Обнаруженные несоответствия типов" = let + tableWithOnlyPrimitiveTypes = Table.SelectColumns(Источник, Table.ColumnsOfType(Источник, {type nullable number, type nullable text, type nullable logical, type nullable date, type nullable datetime, type nullable datetimezone, type nullable time, type nullable duration})), + recordTypeFields = Type.RecordFields(Type.TableRow(Value.Type(tableWithOnlyPrimitiveTypes))), + fieldNames = Record.FieldNames(recordTypeFields), + fieldTypes = List.Transform(Record.ToList(recordTypeFields), each [Type]), + pairs = List.Transform(List.Positions(fieldNames), (i) => {fieldNames{i}, (v) => if v = null or Value.Is(v, fieldTypes{i}) then v else error [Message = "Тип значения не соответствует типу столбца.", Detail = v], fieldTypes{i}}) + in + Table.TransformColumns(Источник, pairs), + #"Добавлен индекс" = Table.AddIndexColumn(#"Обнаруженные несоответствия типов", "Номер строки" ,1), + #"Сохраненные ошибки" = Table.SelectRowsWithErrors(#"Добавлен индекс", {"Дата", "Кампания", "Группа", "Условие показа", "№ Условия показа", "Показы", "Клики", "CTR (%)", "key_dir", "Ср. цена клика, руб", "Расход, руб"}), + #"Переупорядоченные столбцы" = Table.ReorderColumns(#"Сохраненные ошибки", {"Номер строки", "Дата", "Кампания", "Группа", "Условие показа", "№ Условия показа", "Показы", "Клики", "CTR (%)", "key_dir", "Ср. цена клика, руб", "Расход, руб"}) + in + #"Переупорядоченные столбцы" + queryGroup: 'Ошибки в запросах — 05 01 2025 15:59:08' + + annotation PBI_NavigationStepName = Навигация + + annotation PBI_ResultType = Exception + +expression 'Я.Директ расходы стар' = + let + Источник = GoogleSheets.Contents("https://docs.google.com/spreadsheets/d/12gd2O6tTGPGc2BsRbX_QPKn4VF23jhXoFcrj8ErblAo/edit?usp=sharing"), + #"Мастер отчётов_Table" = Источник{[name="Мастер отчётов",ItemKind="Table"]}[Data], + #"Повышенные заголовки" = Table.PromoteHeaders(#"Мастер отчётов_Table", [PromoteAllScalars=true]), + #"Измененный тип" = Table.TransformColumnTypes(#"Повышенные заголовки",{{"Дата", type date}, {"Кампания", type text}, {"№ Кампании", type text}, {"Группа", type text}, {"№ Группы", type text}, {"Условие показа", type text}, {"№ Условия показа", type text}, {"Показы", Int64.Type}, {"Клики", Int64.Type}, {"CTR (%)", type number}, {"Расход (руб.)", type number}, {"Ср. цена клика (руб.)", type number}}), + #"Вставлено: объединенный столбец" = Table.AddColumn(#"Измененный тип", "key_dir", each Text.Combine({[#"№ Кампании"], [#"№ Группы"]}, "-"), type text), + #"Удаленные столбцы" = Table.RemoveColumns(#"Вставлено: объединенный столбец",{"№ Кампании", "№ Группы"}), + #"Добавлен пользовательский объект" = Table.AddColumn(#"Удаленные столбцы", "Ср. цена клика, руб", each [#"Ср. цена клика (руб.)"]/1000), + #"Удаленные столбцы1" = Table.RemoveColumns(#"Добавлен пользовательский объект",{"Ср. цена клика (руб.)"}), + #"Измененный тип1" = Table.TransformColumnTypes(#"Удаленные столбцы1",{{"Ср. цена клика, руб", type number}}), + #"Добавлен пользовательский объект1" = Table.AddColumn(#"Измененный тип1", "Расход, руб", each [#"Расход (руб.)"]/1000), + #"Измененный тип2" = Table.TransformColumnTypes(#"Добавлен пользовательский объект1",{{"Расход, руб", type number}}), + #"Удаленные столбцы2" = Table.RemoveColumns(#"Измененный тип2",{"Расход (руб.)"}), + #"Строки с примененным фильтром" = Table.SelectRows(#"Удаленные столбцы2", each [Дата] < #date(2024, 6, 1)) + in + #"Строки с примененным фильтром" + + annotation PBI_NavigationStepName = Навигация + + annotation PBI_ResultType = Table + diff --git a/analytics/pbi/model/report/Model/model.tmdl b/analytics/pbi/model/report/Model/model.tmdl new file mode 100644 index 0000000..4c70987 --- /dev/null +++ b/analytics/pbi/model/report/Model/model.tmdl @@ -0,0 +1,78 @@ +model Model + culture: ru-RU + defaultPowerBIDataSourceVersion: powerBI_V3 + sourceQueryCulture: ru-RU + dataAccessOptions + fastCombine + legacyRedirects + returnErrorValuesAsNull + +/// Ошибки в запросах, загруженных 05.01.2025 15:59:08. +queryGroup 'Ошибки в запросах — 05 01 2025 15:59:08' + + annotation PBI_QueryGroupOrder = 0 + +annotation __PBI_TimeIntelligenceEnabled = 1 + +annotation PBI_QueryOrder = ["Номенклатура","Партнер","Стоимость МП","Server address","Secret key","crm_company_uf","Себестоимость","Основной отчет","Группы","bx24_load_entity","Остатки","Заявки на оплату","План продаж менеджеров","План продаж по группам","Менеджеры","mp остатки","mp аналитика продаж","Я.Директ расходы стар","Ошибки в Я Директ расходы","ПРАЙСлист","Отзывы клиентов","Упущенные продажи","Расходы по годам","Заказы все","mp реклама","План маркеты","Резервы","Я.Директ расходы","Я.Директ заказы","mp узел","mp оборот"] + +annotation PBI_ProTooling = ["DaxQueryView_Desktop"] + +ref table Номенклатура +ref table Партнер +ref table 'Стоимость МП' +ref table DateTableTemplate_716ce6bb-e9bc-46ef-bfd4-865e74deaed5 +ref table LocalDateTable_67da7b50-915b-480b-9e3a-3a60739fb0c6 +ref table crm_company_uf +ref table LocalDateTable_49b06afb-4254-4da6-9109-618106084862 +ref table LocalDateTable_c661d468-0044-4990-b9e8-723cda59cf51 +ref table '.Календарь' +ref table Себестоимость +ref table LocalDateTable_93d80160-0984-4e44-91de-316b6ab26727 +ref table 'Основной отчет' +ref table Группы +ref table Закупки +ref table Остатки +ref table 'Заявки на оплату' +ref table LocalDateTable_729bf6db-04e4-4a26-9dce-b3837667cb92 +ref table 'Параметр цена продажи, %' +ref table 'План продаж менеджеров' +ref table 'План продаж по группам' +ref table LocalDateTable_704570fc-e0c6-4914-97ab-ebb645a2ab6e +ref table LocalDateTable_2b612047-5dcc-402e-b2ed-154636b18544 +ref table Организация +ref table Менеджеры +ref table 'mp остатки' +ref table 'mp аналитика продаж' +ref table ПРАЙСлист +ref table LocalDateTable_e0374236-67f4-4331-b4f5-c977a3082bab +ref table 'Отзывы клиентов' +ref table 'Упущенные продажи' +ref table LocalDateTable_2f146245-8120-4ed9-87dc-af8699bb0274 +ref table 'Расходы по годам' +ref table 'Заказы все' +ref table 'mp реклама' +ref table LocalDateTable_1c75c57c-6ac4-4a07-ab45-b46636c3847c +ref table 'План маркеты' +ref table LocalDateTable_66d8bbba-35e3-44df-be7f-bb6fc44f271a +ref table Резервы +ref table LocalDateTable_588ed205-7c5f-41f0-9bd7-0d82b2484f09 +ref table 'Я.Директ расходы' +ref table 'Я.Директ заказы' +ref table 'mp узел' +ref table 'mp оборот' + +ref role 'Алова Елена' +ref role 'Гладышева Ольга' +ref role 'Кирилюк Юлия' +ref role 'Ларина Татьяна' +ref role 'Шевченко Антонина' +ref role 'Иншакова Ксения' +ref role 'Менеджер отдела закупок' +ref role 'Ханоян Артем' +ref role 'Менеджер отдела интернет-маркетинга' +ref role 'Менеджер отдела продаж' +ref role 'Эдуард Рахматуллин' + +ref cultureInfo ru-RU + diff --git a/analytics/pbi/model/report/Model/relationships.tmdl b/analytics/pbi/model/report/Model/relationships.tmdl new file mode 100644 index 0000000..e4e5ee1 --- /dev/null +++ b/analytics/pbi/model/report/Model/relationships.tmdl @@ -0,0 +1,247 @@ +relationship 0c9c501a-fa6a-4c94-99ae-b825ee836e89 + fromColumn: 'Стоимость МП'.artic_id + toColumn: Номенклатура._artic_id + +relationship 70d8fb19-ce6e-4331-bdd5-c48b97661c3a + joinOnDateBehavior: datePartOnly + fromColumn: Партнер.ДатаРегистрации + toColumn: LocalDateTable_67da7b50-915b-480b-9e3a-3a60739fb0c6.Date + +relationship 34a39f02-5cb4-4c1b-b8e8-ea3ef9aafb4e + joinOnDateBehavior: datePartOnly + fromColumn: crm_company_uf.'Дата последнего звонка' + toColumn: LocalDateTable_49b06afb-4254-4da6-9109-618106084862.Date + +relationship b7780e24-ae05-4812-ad3f-b6d9dc7f50cc + joinOnDateBehavior: datePartOnly + fromColumn: Партнер.'Дата последнего звонка' + toColumn: LocalDateTable_c661d468-0044-4990-b9e8-723cda59cf51.Date + +relationship 8e2d6fc2-aec0-1ef2-5916-f2e35c465192 + fromColumn: 'Стоимость МП'.ПартнерКод + toColumn: Партнер.'Код УТ' + +relationship d56f34dd-d18a-4511-b10b-85895b67822c + joinOnDateBehavior: datePartOnly + fromColumn: Себестоимость.'Заказ закрыт' + toColumn: LocalDateTable_93d80160-0984-4e44-91de-316b6ab26727.Date + +relationship 355102b6-e291-2095-8fd4-32447366f728 + fromColumn: Себестоимость.artic_id + toColumn: Номенклатура._artic_id + +relationship 7505878b-5508-458a-653e-9360556cef53 + fromColumn: Себестоимость.PartnerId + toColumn: Партнер.partner_id + +relationship 5534460f-9c82-363b-9fe4-45f95118ac89 + crossFilteringBehavior: bothDirections + fromColumn: Номенклатура._group_id + toColumn: Группы.group_id + +relationship AutoDetected_e288bde8-030d-4a1f-8a03-91f31dd9f651 + fromColumn: Остатки.artic_id + toColumn: Номенклатура._artic_id + +relationship 8208f512-c8a9-47d1-b47c-2bce30b6b8f8 + joinOnDateBehavior: datePartOnly + fromColumn: 'Заявки на оплату'.date + toColumn: LocalDateTable_729bf6db-04e4-4a26-9dce-b3837667cb92.Date + +relationship 55297e27-cac1-ef2a-4ee1-6cc80b8a1167 + fromColumn: 'Заявки на оплату'.partner_id + toColumn: Партнер.partner_id + +relationship 6bdd8855-c6d2-4c21-b90f-cb9f0b0bd52e + joinOnDateBehavior: datePartOnly + fromColumn: 'План продаж по группам'.Месяц + toColumn: LocalDateTable_704570fc-e0c6-4914-97ab-ebb645a2ab6e.Date + +relationship 8afa5bd2-9707-4363-96f2-670a305dc4f3 + joinOnDateBehavior: datePartOnly + fromColumn: Остатки.Дата + toColumn: LocalDateTable_2b612047-5dcc-402e-b2ed-154636b18544.Date + +relationship 7fecb2f9-fc49-b4a1-2fd5-41f2e1888950 + fromColumn: Себестоимость.Организация + toColumn: Организация.Организация + +relationship 32985c97-823f-ffbc-00fe-9f92ac1bae11 + fromColumn: 'Стоимость МП'.Организация + toColumn: Организация.Организация + +relationship AutoDetected_e9e769be-3122-4b9c-a4eb-06f97eba8eae + fromColumn: 'План продаж менеджеров'.user_id + toColumn: Менеджеры.user_id + +relationship 02f6fe40-78b9-93d1-f010-564c9b543bfe + fromColumn: Партнер.manager_id + toColumn: Менеджеры.user_id + +relationship f2e0ac1f-b839-4157-6c3e-57b88efa417c + fromColumn: 'mp остатки'.artic_id + toColumn: Номенклатура._artic_id + +relationship 31cf1118-b7c5-7d77-48dd-1b589c984d03 + fromColumn: 'mp аналитика продаж'.artic_id + toColumn: Номенклатура._artic_id + +relationship AutoDetected_34ee49f1-fee2-4e8c-ae63-add84ec273df + fromColumn: ПРАЙСлист.artic_id + toColumn: Номенклатура._artic_id + +relationship 306cff38-7ed9-4281-b26b-fdf3eb9b0316 + joinOnDateBehavior: datePartOnly + fromColumn: '.Календарь'.Дата + toColumn: LocalDateTable_e0374236-67f4-4331-b4f5-c977a3082bab.Date + +relationship aeabbc3f-c05e-16a8-0814-e1504239b9c6 + fromColumn: 'Стоимость МП'.Период + toColumn: '.Календарь'.Дата + +relationship 8be1b23d-e487-097c-bcee-1a32b231c1dc + fromColumn: Себестоимость.Период + toColumn: '.Календарь'.Дата + +relationship f67b410c-fe68-57c7-552d-861cd0a89a3e + fromColumn: 'Заявки на оплату'.'Дата оплаты план' + toColumn: '.Календарь'.Дата + +relationship 5e52a163-909c-6b8d-25bc-b035e9ac2da8 + fromColumn: 'План продаж менеджеров'.Период + toColumn: '.Календарь'.Дата + +relationship dd599fe4-4d7d-02f0-ff23-c15949d273d6 + fromColumn: 'mp остатки'.'Дата обновления' + toColumn: '.Календарь'.Дата + +relationship a9aa002f-ecc1-626a-3629-1649907a88ac + fromColumn: 'mp аналитика продаж'.Дата + toColumn: '.Календарь'.Дата + +relationship 60f5c804-9c9a-709a-3a69-c4fdd8d95032 + fromColumn: ПРАЙСлист.Дата + toColumn: '.Календарь'.Дата + +relationship AutoDetected_3779c3ac-c497-4083-8eb0-ad86aaa8a771 + fromColumn: 'Упущенные продажи'.artic_id + toColumn: Номенклатура._artic_id + +relationship 4f365827-f1a2-9c34-5415-efb3452f5951 + fromColumn: 'Упущенные продажи'.Дата + toColumn: '.Календарь'.Дата + +relationship 28a764af-4e8a-4c89-8ceb-304403c0d71a + joinOnDateBehavior: datePartOnly + fromColumn: 'Упущенные продажи'.'Дата первого поступления' + toColumn: LocalDateTable_2f146245-8120-4ed9-87dc-af8699bb0274.Date + +relationship 4d693140-48df-ebb1-5b1f-775c66de2412 + fromColumn: 'Заказы все'.artic_id + toColumn: Номенклатура._artic_id + +relationship 9178e59f-fd80-fe45-d854-b1b441024ce8 + isActive: false + fromColumn: 'Заказы все'.partner_id + toColumn: Партнер.partner_id + +relationship 8229a93a-e14d-491e-ac57-cbab91627fdd + joinOnDateBehavior: datePartOnly + fromColumn: 'mp реклама'.'Дата начала' + toColumn: LocalDateTable_1c75c57c-6ac4-4a07-ab45-b46636c3847c.Date + +relationship c3cb1aca-d642-4ed3-d7a7-c54fe18f71d3 + fromColumn: 'mp реклама'.Дата + toColumn: '.Календарь'.Дата + +relationship fae31430-95d8-f385-acf1-a2826f31846c + fromColumn: 'mp реклама'.artic_id + toColumn: Номенклатура._artic_id + +relationship 381b6bd4-06f4-496e-9264-13deb45adbf2 + joinOnDateBehavior: datePartOnly + fromColumn: 'План маркеты'.Месяц + toColumn: LocalDateTable_66d8bbba-35e3-44df-be7f-bb6fc44f271a.Date + +relationship f9bb46c5-d73a-2219-3f8a-07559a96a567 + fromColumn: Закупки.Период + toColumn: '.Календарь'.Дата + +relationship e4537ee3-4045-38dc-b214-cb1c5de0b9e2 + fromColumn: Закупки.artic_id + toColumn: Номенклатура._artic_id + +relationship cf649bbe-1ad9-14ce-b264-dacef01746a7 + fromColumn: Закупки.Организация + toColumn: Организация.Организация + +relationship b3ea723a-e172-b759-0f23-bb851737fb34 + fromColumn: Закупки.partner_id + toColumn: Партнер.partner_id + +relationship AutoDetected_78bdb83b-79d3-4f5e-b7af-54227f9db024 + fromColumn: Резервы.artic_id + toColumn: Номенклатура._artic_id + +relationship e27252e4-5020-94c9-42db-b3a63806f34f + fromColumn: Резервы.'Дата обновления' + toColumn: '.Календарь'.Дата + +relationship 8171e79f-bfe6-4798-bb1a-98146553bada + joinOnDateBehavior: datePartOnly + fromColumn: Партнер.'Дата первого заказа' + toColumn: LocalDateTable_588ed205-7c5f-41f0-9bd7-0d82b2484f09.Date + +relationship 43da0466-6cb4-29cb-0624-f73171c1d064 + toCardinality: many + fromColumn: 'Я.Директ расходы'.key_dir + toColumn: 'Я.Директ заказы'.key_dir + +relationship 634101f5-71e4-2d48-7d90-832b057647a3 + fromColumn: 'Я.Директ расходы'.Дата + toColumn: '.Календарь'.Дата + +relationship e1b1daf7-34c4-f072-2ead-53e97f931563 + fromColumn: Себестоимость.'Номер заказа' + toColumn: 'Я.Директ заказы'.'ID покупки' + +relationship AutoDetected_817d2b4f-98f1-49e0-870f-fdecc60d7626 + fromColumn: 'mp узел'.partner_id + toColumn: Партнер.partner_id + +relationship AutoDetected_42494399-5383-444c-8db6-3ff0012aa9c5 + fromColumn: 'mp остатки'.Узел + toColumn: 'mp узел'.Узел + +relationship AutoDetected_77d661d6-36fd-48d2-b282-4961d4b5d737 + fromColumn: 'mp аналитика продаж'.Узел + toColumn: 'mp узел'.Узел + +relationship AutoDetected_372b4703-5804-44e3-9c83-e56aea6514b2 + fromColumn: 'mp реклама'.Узел + toColumn: 'mp узел'.Узел + +relationship 706a676c-ec4a-005d-17ab-0073194ef5f8 + fromColumn: 'План продаж по группам'.group_id + toColumn: Группы.group_id + +relationship 13260857-b641-cb5b-b3cb-f14771c5cec6 + fromColumn: 'mp узел'.Организация + toColumn: Организация.Организация + +relationship AutoDetected_3bd74343-497b-4516-b07f-1d3c2d6b07b6 + fromColumn: 'mp оборот'.artic_id + toColumn: Номенклатура._artic_id + +relationship AutoDetected_db8d1849-dfff-4593-996d-4891727f496d + fromColumn: 'mp оборот'.partner_id + toColumn: Партнер.partner_id + +relationship a388dedc-5e84-5967-96df-b8bae5c33891 + fromColumn: 'mp оборот'.Организация + toColumn: Организация.Организация + +relationship d0083c1d-7d13-e893-6081-a9eeae7c53f0 + fromColumn: 'mp оборот'.Дата + toColumn: '.Календарь'.Дата + diff --git a/analytics/pbi/model/report/Model/roles/Алова Елена.tmdl b/analytics/pbi/model/report/Model/roles/Алова Елена.tmdl new file mode 100644 index 0000000..52fbdee --- /dev/null +++ b/analytics/pbi/model/report/Model/roles/Алова Елена.tmdl @@ -0,0 +1,7 @@ +role 'Алова Елена' + modelPermission: read + + tablePermission Номенклатура = [Менеджер по закупкам] == "Алова Елена" || [РуководительНаправления] == "Алова Елена" || [Товарный менеджер] == "Алова Елена" + + annotation PBI_Id = 232ba4e958694f06a7d05f870c7a2e09 + diff --git a/analytics/pbi/model/report/Model/roles/Гладышева Ольга.tmdl b/analytics/pbi/model/report/Model/roles/Гладышева Ольга.tmdl new file mode 100644 index 0000000..b4951da --- /dev/null +++ b/analytics/pbi/model/report/Model/roles/Гладышева Ольга.tmdl @@ -0,0 +1,7 @@ +role 'Гладышева Ольга' + modelPermission: read + + tablePermission Номенклатура = [Менеджер по закупкам] == "Гладышева Ольга" || [РуководительНаправления] == "Гладышева Ольга" || [Товарный менеджер] == "Гладышева Ольга" + + annotation PBI_Id = 7c1c9d1f38744bf4a1bd941e24707af1 + diff --git a/analytics/pbi/model/report/Model/roles/Иншакова Ксения.tmdl b/analytics/pbi/model/report/Model/roles/Иншакова Ксения.tmdl new file mode 100644 index 0000000..24dd224 --- /dev/null +++ b/analytics/pbi/model/report/Model/roles/Иншакова Ксения.tmdl @@ -0,0 +1,7 @@ +role 'Иншакова Ксения' + modelPermission: read + + tablePermission Номенклатура = [Менеджер по закупкам] == "Иншакова Ксения" || [РуководительНаправления] == "Иншакова Ксения" || [Товарный менеджер] == "Иншакова Ксения" || [Товарный менеджер] == "Дивеева Ирина" + + annotation PBI_Id = 2b33c12aca5843adae941a60b22de032 + diff --git a/analytics/pbi/model/report/Model/roles/Кирилюк Юлия.tmdl b/analytics/pbi/model/report/Model/roles/Кирилюк Юлия.tmdl new file mode 100644 index 0000000..4132136 --- /dev/null +++ b/analytics/pbi/model/report/Model/roles/Кирилюк Юлия.tmdl @@ -0,0 +1,7 @@ +role 'Кирилюк Юлия' + modelPermission: read + + tablePermission Номенклатура = [Менеджер по закупкам] == "Кирилюк Юлия" || [РуководительНаправления] == "Кирилюк Юлия" || [Товарный менеджер] == "Кирилюк Юлия" + + annotation PBI_Id = 229e8df5eeb84976a4877b1f158b9061 + diff --git a/analytics/pbi/model/report/Model/roles/Ларина Татьяна.tmdl b/analytics/pbi/model/report/Model/roles/Ларина Татьяна.tmdl new file mode 100644 index 0000000..d568507 --- /dev/null +++ b/analytics/pbi/model/report/Model/roles/Ларина Татьяна.tmdl @@ -0,0 +1,7 @@ +role 'Ларина Татьяна' + modelPermission: read + + tablePermission Номенклатура = [Менеджер по закупкам] == "Ларина Татьяна" || [РуководительНаправления] == "Ларина Татьяна" || [Товарный менеджер] == "Ларина Татьяна" + + annotation PBI_Id = 8e3b251c563a42249202718154a471e4 + diff --git a/analytics/pbi/model/report/Model/roles/Менеджер отдела закупок.tmdl b/analytics/pbi/model/report/Model/roles/Менеджер отдела закупок.tmdl new file mode 100644 index 0000000..cf77a96 --- /dev/null +++ b/analytics/pbi/model/report/Model/roles/Менеджер отдела закупок.tmdl @@ -0,0 +1,5 @@ +role 'Менеджер отдела закупок' + modelPermission: read + + annotation PBI_Id = 5c63de3d119c4466a367623e23f8c9e3 + diff --git a/analytics/pbi/model/report/Model/roles/Менеджер отдела интернет-маркетинга.tmdl b/analytics/pbi/model/report/Model/roles/Менеджер отдела интернет-маркетинга.tmdl new file mode 100644 index 0000000..90958b1 --- /dev/null +++ b/analytics/pbi/model/report/Model/roles/Менеджер отдела интернет-маркетинга.tmdl @@ -0,0 +1,5 @@ +role 'Менеджер отдела интернет-маркетинга' + modelPermission: read + + annotation PBI_Id = 09735f8d6e7f4139929ac3460ed5829b + diff --git a/analytics/pbi/model/report/Model/roles/Менеджер отдела продаж.tmdl b/analytics/pbi/model/report/Model/roles/Менеджер отдела продаж.tmdl new file mode 100644 index 0000000..cd6b4e1 --- /dev/null +++ b/analytics/pbi/model/report/Model/roles/Менеджер отдела продаж.tmdl @@ -0,0 +1,5 @@ +role 'Менеджер отдела продаж' + modelPermission: read + + annotation PBI_Id = 3e05b61dc5134a3f9ef8d14b2a0b742a + diff --git a/analytics/pbi/model/report/Model/roles/Ханоян Артем.tmdl b/analytics/pbi/model/report/Model/roles/Ханоян Артем.tmdl new file mode 100644 index 0000000..e2cc69a --- /dev/null +++ b/analytics/pbi/model/report/Model/roles/Ханоян Артем.tmdl @@ -0,0 +1,7 @@ +role 'Ханоян Артем' + modelPermission: read + + tablePermission Номенклатура = [Менеджер по закупкам] == "Ханоян Артем" || [РуководительНаправления] == "Ханоян Артем" || [Товарный менеджер] == "Ханоян Артем" + + annotation PBI_Id = 2ae5566020ac4b96a50a5f1937670aee + diff --git a/analytics/pbi/model/report/Model/roles/Шевченко Антонина.tmdl b/analytics/pbi/model/report/Model/roles/Шевченко Антонина.tmdl new file mode 100644 index 0000000..e8b519a --- /dev/null +++ b/analytics/pbi/model/report/Model/roles/Шевченко Антонина.tmdl @@ -0,0 +1,7 @@ +role 'Шевченко Антонина' + modelPermission: read + + tablePermission Номенклатура = [Менеджер по закупкам] == "Шевченко Антонина" || [РуководительНаправления] == "Шевченко Антонина" || [Товарный менеджер] == "Шевченко Антонина" + + annotation PBI_Id = 00514f80ab984abd9f6957c4a3df98ea + diff --git a/analytics/pbi/model/report/Model/roles/Эдуард Рахматуллин.tmdl b/analytics/pbi/model/report/Model/roles/Эдуард Рахматуллин.tmdl new file mode 100644 index 0000000..e8f91d0 --- /dev/null +++ b/analytics/pbi/model/report/Model/roles/Эдуард Рахматуллин.tmdl @@ -0,0 +1,5 @@ +role 'Эдуард Рахматуллин' + modelPermission: read + + annotation PBI_Id = ffed27e83fa442788546be7bc067a933 + diff --git a/analytics/pbi/model/report/Model/tables/.Календарь.tmdl b/analytics/pbi/model/report/Model/tables/.Календарь.tmdl new file mode 100644 index 0000000..a77fedd --- /dev/null +++ b/analytics/pbi/model/report/Model/tables/.Календарь.tmdl @@ -0,0 +1,36 @@ +table '.Календарь' + + measure 'Курс TODAY-1, usd2' = CALCULATE(MAX('Себестоимость'[Курс usd2]), '.Календарь'[Дата] = TODAY() - 1) + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column Дата + formatString: m/d/yyyy + summarizeBy: none + sourceColumn: [Date] + + variation Изменение + isDefault + relationship: 306cff38-7ed9-4281-b26b-fdf3eb9b0316 + defaultHierarchy: LocalDateTable_e0374236-67f4-4331-b4f5-c977a3082bab.'Иерархия дат' + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isDateTimeCustom":true} + + annotation UnderlyingDateTimeDataType = Date + + column 'Год неделя' = YEAR('.Календарь'[Дата]) & "-" & FORMAT(WEEKNUM('.Календарь'[Дата], 2), "00") + summarizeBy: none + + annotation SummarizationSetBy = Automatic + + partition '.Календарь' = calculated + mode: import + source = ``` + CALENDAR(DATE(2018,01,01), TODAY()) + + ``` + + annotation PBI_Id = 96f54ceb7af44a4682e4399eeac84d37 + diff --git a/analytics/pbi/model/report/Model/tables/DateTableTemplate_716ce6bb-e9bc-46ef-bfd4-865e74deaed5.tmdl b/analytics/pbi/model/report/Model/tables/DateTableTemplate_716ce6bb-e9bc-46ef-bfd4-865e74deaed5.tmdl new file mode 100644 index 0000000..0070a2f --- /dev/null +++ b/analytics/pbi/model/report/Model/tables/DateTableTemplate_716ce6bb-e9bc-46ef-bfd4-865e74deaed5.tmdl @@ -0,0 +1,93 @@ +table DateTableTemplate_716ce6bb-e9bc-46ef-bfd4-865e74deaed5 + isHidden + isPrivate + + column Date + isHidden + dataCategory: PaddedDateTableDates + summarizeBy: none + isNameInferred + sourceColumn: [Date] + + annotation SummarizationSetBy = User + + column Год = YEAR([Date]) + isHidden + dataCategory: Years + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = Year + + column №Месяца = MONTH([Date]) + isHidden + dataCategory: MonthOfYear + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = MonthNumber + + column Месяц = FORMAT([Date], "MMMM") + isHidden + dataCategory: Months + summarizeBy: none + sortByColumn: №Месяца + + annotation SummarizationSetBy = User + + annotation TemplateId = Month + + column №Квартала = INT(([№Месяца] + 2) / 3) + isHidden + dataCategory: QuarterOfYear + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = QuarterNumber + + column Квартал = "Кв. " & [№Квартала] + isHidden + dataCategory: Quarters + summarizeBy: none + sortByColumn: №Квартала + + annotation SummarizationSetBy = User + + annotation TemplateId = Quarter + + column День = DAY([Date]) + isHidden + dataCategory: DayOfMonth + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = Day + + hierarchy 'Иерархия дат' + + level Год + column: Год + + level Квартал + column: Квартал + + level Месяц + column: Месяц + + level День + column: День + + annotation TemplateId = DateHierarchy + + partition DateTableTemplate_716ce6bb-e9bc-46ef-bfd4-865e74deaed5-a50c2945-fdf8-4e06-908a-c3e9748445a8 = calculated + mode: import + source = Calendar(Date(2015,1,1), Date(2015,1,1)) + + annotation __PBI_TemplateDateTable = true + + annotation DefaultItem = DateHierarchy + diff --git a/analytics/pbi/model/report/Model/tables/LocalDateTable_1c75c57c-6ac4-4a07-ab45-b46636c3847c.tmdl b/analytics/pbi/model/report/Model/tables/LocalDateTable_1c75c57c-6ac4-4a07-ab45-b46636c3847c.tmdl new file mode 100644 index 0000000..1ba9769 --- /dev/null +++ b/analytics/pbi/model/report/Model/tables/LocalDateTable_1c75c57c-6ac4-4a07-ab45-b46636c3847c.tmdl @@ -0,0 +1,98 @@ +table LocalDateTable_1c75c57c-6ac4-4a07-ab45-b46636c3847c + isHidden + showAsVariationsOnly + + column Date + dataType: dateTime + isHidden + dataCategory: PaddedDateTableDates + summarizeBy: none + isNameInferred + sourceColumn: [Date] + + annotation SummarizationSetBy = User + + column Год = YEAR([Date]) + dataType: int64 + isHidden + dataCategory: Years + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = Year + + column №Месяца = MONTH([Date]) + dataType: int64 + isHidden + dataCategory: MonthOfYear + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = MonthNumber + + column Месяц = FORMAT([Date], "MMMM") + dataType: string + isHidden + dataCategory: Months + summarizeBy: none + sortByColumn: №Месяца + + annotation SummarizationSetBy = User + + annotation TemplateId = Month + + column №Квартала = INT(([№Месяца] + 2) / 3) + dataType: int64 + isHidden + dataCategory: QuarterOfYear + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = QuarterNumber + + column Квартал = "Кв. " & [№Квартала] + dataType: string + isHidden + dataCategory: Quarters + summarizeBy: none + sortByColumn: №Квартала + + annotation SummarizationSetBy = User + + annotation TemplateId = Quarter + + column День = DAY([Date]) + dataType: int64 + isHidden + dataCategory: DayOfMonth + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = Day + + hierarchy 'Иерархия дат' + + level Год + column: Год + + level Квартал + column: Квартал + + level Месяц + column: Месяц + + level День + column: День + + annotation TemplateId = DateHierarchy + + partition LocalDateTable_1c75c57c-6ac4-4a07-ab45-b46636c3847c = calculated + mode: import + source = Calendar(Date(Year(MIN('mp реклама'[Дата начала])), 1, 1), Date(Year(MAX('mp реклама'[Дата начала])), 12, 31)) + + annotation __PBI_LocalDateTable = true + diff --git a/analytics/pbi/model/report/Model/tables/LocalDateTable_2b612047-5dcc-402e-b2ed-154636b18544.tmdl b/analytics/pbi/model/report/Model/tables/LocalDateTable_2b612047-5dcc-402e-b2ed-154636b18544.tmdl new file mode 100644 index 0000000..ba66587 --- /dev/null +++ b/analytics/pbi/model/report/Model/tables/LocalDateTable_2b612047-5dcc-402e-b2ed-154636b18544.tmdl @@ -0,0 +1,98 @@ +table LocalDateTable_2b612047-5dcc-402e-b2ed-154636b18544 + isHidden + showAsVariationsOnly + + column Date + dataType: dateTime + isHidden + dataCategory: PaddedDateTableDates + summarizeBy: none + isNameInferred + sourceColumn: [Date] + + annotation SummarizationSetBy = User + + column Год = YEAR([Date]) + dataType: int64 + isHidden + dataCategory: Years + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = Year + + column №Месяца = MONTH([Date]) + dataType: int64 + isHidden + dataCategory: MonthOfYear + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = MonthNumber + + column Месяц = FORMAT([Date], "MMMM") + dataType: string + isHidden + dataCategory: Months + summarizeBy: none + sortByColumn: №Месяца + + annotation SummarizationSetBy = User + + annotation TemplateId = Month + + column №Квартала = INT(([№Месяца] + 2) / 3) + dataType: int64 + isHidden + dataCategory: QuarterOfYear + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = QuarterNumber + + column Квартал = "Кв. " & [№Квартала] + dataType: string + isHidden + dataCategory: Quarters + summarizeBy: none + sortByColumn: №Квартала + + annotation SummarizationSetBy = User + + annotation TemplateId = Quarter + + column День = DAY([Date]) + dataType: int64 + isHidden + dataCategory: DayOfMonth + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = Day + + hierarchy 'Иерархия дат' + + level Год + column: Год + + level Квартал + column: Квартал + + level Месяц + column: Месяц + + level День + column: День + + annotation TemplateId = DateHierarchy + + partition LocalDateTable_2b612047-5dcc-402e-b2ed-154636b18544 = calculated + mode: import + source = Calendar(Date(Year(MIN('Остатки'[Дата])), 1, 1), Date(Year(MAX('Остатки'[Дата])), 12, 31)) + + annotation __PBI_LocalDateTable = true + diff --git a/analytics/pbi/model/report/Model/tables/LocalDateTable_2f146245-8120-4ed9-87dc-af8699bb0274.tmdl b/analytics/pbi/model/report/Model/tables/LocalDateTable_2f146245-8120-4ed9-87dc-af8699bb0274.tmdl new file mode 100644 index 0000000..6966646 --- /dev/null +++ b/analytics/pbi/model/report/Model/tables/LocalDateTable_2f146245-8120-4ed9-87dc-af8699bb0274.tmdl @@ -0,0 +1,98 @@ +table LocalDateTable_2f146245-8120-4ed9-87dc-af8699bb0274 + isHidden + showAsVariationsOnly + + column Date + dataType: dateTime + isHidden + dataCategory: PaddedDateTableDates + summarizeBy: none + isNameInferred + sourceColumn: [Date] + + annotation SummarizationSetBy = User + + column Год = YEAR([Date]) + dataType: int64 + isHidden + dataCategory: Years + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = Year + + column №Месяца = MONTH([Date]) + dataType: int64 + isHidden + dataCategory: MonthOfYear + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = MonthNumber + + column Месяц = FORMAT([Date], "MMMM") + dataType: string + isHidden + dataCategory: Months + summarizeBy: none + sortByColumn: №Месяца + + annotation SummarizationSetBy = User + + annotation TemplateId = Month + + column №Квартала = INT(([№Месяца] + 2) / 3) + dataType: int64 + isHidden + dataCategory: QuarterOfYear + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = QuarterNumber + + column Квартал = "Кв. " & [№Квартала] + dataType: string + isHidden + dataCategory: Quarters + summarizeBy: none + sortByColumn: №Квартала + + annotation SummarizationSetBy = User + + annotation TemplateId = Quarter + + column День = DAY([Date]) + dataType: int64 + isHidden + dataCategory: DayOfMonth + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = Day + + hierarchy 'Иерархия дат' + + level Год + column: Год + + level Квартал + column: Квартал + + level Месяц + column: Месяц + + level День + column: День + + annotation TemplateId = DateHierarchy + + partition LocalDateTable_2f146245-8120-4ed9-87dc-af8699bb0274 = calculated + mode: import + source = Calendar(Date(Year(MIN('Упущенные продажи'[Дата первого поступления])), 1, 1), Date(Year(MAX('Упущенные продажи'[Дата первого поступления])), 12, 31)) + + annotation __PBI_LocalDateTable = true + diff --git a/analytics/pbi/model/report/Model/tables/LocalDateTable_49b06afb-4254-4da6-9109-618106084862.tmdl b/analytics/pbi/model/report/Model/tables/LocalDateTable_49b06afb-4254-4da6-9109-618106084862.tmdl new file mode 100644 index 0000000..7ab0a8e --- /dev/null +++ b/analytics/pbi/model/report/Model/tables/LocalDateTable_49b06afb-4254-4da6-9109-618106084862.tmdl @@ -0,0 +1,98 @@ +table LocalDateTable_49b06afb-4254-4da6-9109-618106084862 + isHidden + showAsVariationsOnly + + column Date + dataType: dateTime + isHidden + dataCategory: PaddedDateTableDates + summarizeBy: none + isNameInferred + sourceColumn: [Date] + + annotation SummarizationSetBy = User + + column Год = YEAR([Date]) + dataType: int64 + isHidden + dataCategory: Years + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = Year + + column №Месяца = MONTH([Date]) + dataType: int64 + isHidden + dataCategory: MonthOfYear + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = MonthNumber + + column Месяц = FORMAT([Date], "MMMM") + dataType: string + isHidden + dataCategory: Months + summarizeBy: none + sortByColumn: №Месяца + + annotation SummarizationSetBy = User + + annotation TemplateId = Month + + column №Квартала = INT(([№Месяца] + 2) / 3) + dataType: int64 + isHidden + dataCategory: QuarterOfYear + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = QuarterNumber + + column Квартал = "Кв. " & [№Квартала] + dataType: string + isHidden + dataCategory: Quarters + summarizeBy: none + sortByColumn: №Квартала + + annotation SummarizationSetBy = User + + annotation TemplateId = Quarter + + column День = DAY([Date]) + dataType: int64 + isHidden + dataCategory: DayOfMonth + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = Day + + hierarchy 'Иерархия дат' + + level Год + column: Год + + level Квартал + column: Квартал + + level Месяц + column: Месяц + + level День + column: День + + annotation TemplateId = DateHierarchy + + partition LocalDateTable_49b06afb-4254-4da6-9109-618106084862 = calculated + mode: import + source = Calendar(Date(Year(MIN('crm_company_uf'[Дата последнего звонка])), 1, 1), Date(Year(MAX('crm_company_uf'[Дата последнего звонка])), 12, 31)) + + annotation __PBI_LocalDateTable = true + diff --git a/analytics/pbi/model/report/Model/tables/LocalDateTable_588ed205-7c5f-41f0-9bd7-0d82b2484f09.tmdl b/analytics/pbi/model/report/Model/tables/LocalDateTable_588ed205-7c5f-41f0-9bd7-0d82b2484f09.tmdl new file mode 100644 index 0000000..47b16a2 --- /dev/null +++ b/analytics/pbi/model/report/Model/tables/LocalDateTable_588ed205-7c5f-41f0-9bd7-0d82b2484f09.tmdl @@ -0,0 +1,98 @@ +table LocalDateTable_588ed205-7c5f-41f0-9bd7-0d82b2484f09 + isHidden + showAsVariationsOnly + + column Date + dataType: dateTime + isHidden + dataCategory: PaddedDateTableDates + summarizeBy: none + isNameInferred + sourceColumn: [Date] + + annotation SummarizationSetBy = User + + column Год = YEAR([Date]) + dataType: int64 + isHidden + dataCategory: Years + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = Year + + column №Месяца = MONTH([Date]) + dataType: int64 + isHidden + dataCategory: MonthOfYear + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = MonthNumber + + column Месяц = FORMAT([Date], "MMMM") + dataType: string + isHidden + dataCategory: Months + summarizeBy: none + sortByColumn: №Месяца + + annotation SummarizationSetBy = User + + annotation TemplateId = Month + + column №Квартала = INT(([№Месяца] + 2) / 3) + dataType: int64 + isHidden + dataCategory: QuarterOfYear + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = QuarterNumber + + column Квартал = "Кв. " & [№Квартала] + dataType: string + isHidden + dataCategory: Quarters + summarizeBy: none + sortByColumn: №Квартала + + annotation SummarizationSetBy = User + + annotation TemplateId = Quarter + + column День = DAY([Date]) + dataType: int64 + isHidden + dataCategory: DayOfMonth + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = Day + + hierarchy 'Иерархия дат' + + level Год + column: Год + + level Квартал + column: Квартал + + level Месяц + column: Месяц + + level День + column: День + + annotation TemplateId = DateHierarchy + + partition LocalDateTable_588ed205-7c5f-41f0-9bd7-0d82b2484f09 = calculated + mode: import + source = Calendar(Date(Year(MIN('Партнер'[Дата первого заказа])), 1, 1), Date(Year(MAX('Партнер'[Дата первого заказа])), 12, 31)) + + annotation __PBI_LocalDateTable = true + diff --git a/analytics/pbi/model/report/Model/tables/LocalDateTable_66d8bbba-35e3-44df-be7f-bb6fc44f271a.tmdl b/analytics/pbi/model/report/Model/tables/LocalDateTable_66d8bbba-35e3-44df-be7f-bb6fc44f271a.tmdl new file mode 100644 index 0000000..75f03fe --- /dev/null +++ b/analytics/pbi/model/report/Model/tables/LocalDateTable_66d8bbba-35e3-44df-be7f-bb6fc44f271a.tmdl @@ -0,0 +1,98 @@ +table LocalDateTable_66d8bbba-35e3-44df-be7f-bb6fc44f271a + isHidden + showAsVariationsOnly + + column Date + dataType: dateTime + isHidden + dataCategory: PaddedDateTableDates + summarizeBy: none + isNameInferred + sourceColumn: [Date] + + annotation SummarizationSetBy = User + + column Год = YEAR([Date]) + dataType: int64 + isHidden + dataCategory: Years + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = Year + + column №Месяца = MONTH([Date]) + dataType: int64 + isHidden + dataCategory: MonthOfYear + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = MonthNumber + + column Месяц = FORMAT([Date], "MMMM") + dataType: string + isHidden + dataCategory: Months + summarizeBy: none + sortByColumn: №Месяца + + annotation SummarizationSetBy = User + + annotation TemplateId = Month + + column №Квартала = INT(([№Месяца] + 2) / 3) + dataType: int64 + isHidden + dataCategory: QuarterOfYear + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = QuarterNumber + + column Квартал = "Кв. " & [№Квартала] + dataType: string + isHidden + dataCategory: Quarters + summarizeBy: none + sortByColumn: №Квартала + + annotation SummarizationSetBy = User + + annotation TemplateId = Quarter + + column День = DAY([Date]) + dataType: int64 + isHidden + dataCategory: DayOfMonth + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = Day + + hierarchy 'Иерархия дат' + + level Год + column: Год + + level Квартал + column: Квартал + + level Месяц + column: Месяц + + level День + column: День + + annotation TemplateId = DateHierarchy + + partition LocalDateTable_66d8bbba-35e3-44df-be7f-bb6fc44f271a = calculated + mode: import + source = Calendar(Date(Year(MIN('План маркеты'[Месяц])), 1, 1), Date(Year(MAX('План маркеты'[Месяц])), 12, 31)) + + annotation __PBI_LocalDateTable = true + diff --git a/analytics/pbi/model/report/Model/tables/LocalDateTable_67da7b50-915b-480b-9e3a-3a60739fb0c6.tmdl b/analytics/pbi/model/report/Model/tables/LocalDateTable_67da7b50-915b-480b-9e3a-3a60739fb0c6.tmdl new file mode 100644 index 0000000..6690024 --- /dev/null +++ b/analytics/pbi/model/report/Model/tables/LocalDateTable_67da7b50-915b-480b-9e3a-3a60739fb0c6.tmdl @@ -0,0 +1,98 @@ +table LocalDateTable_67da7b50-915b-480b-9e3a-3a60739fb0c6 + isHidden + showAsVariationsOnly + + column Date + dataType: dateTime + isHidden + dataCategory: PaddedDateTableDates + summarizeBy: none + isNameInferred + sourceColumn: [Date] + + annotation SummarizationSetBy = User + + column Год = YEAR([Date]) + dataType: int64 + isHidden + dataCategory: Years + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = Year + + column №Месяца = MONTH([Date]) + dataType: int64 + isHidden + dataCategory: MonthOfYear + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = MonthNumber + + column Месяц = FORMAT([Date], "MMMM") + dataType: string + isHidden + dataCategory: Months + summarizeBy: none + sortByColumn: №Месяца + + annotation SummarizationSetBy = User + + annotation TemplateId = Month + + column №Квартала = INT(([№Месяца] + 2) / 3) + dataType: int64 + isHidden + dataCategory: QuarterOfYear + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = QuarterNumber + + column Квартал = "Кв. " & [№Квартала] + dataType: string + isHidden + dataCategory: Quarters + summarizeBy: none + sortByColumn: №Квартала + + annotation SummarizationSetBy = User + + annotation TemplateId = Quarter + + column День = DAY([Date]) + dataType: int64 + isHidden + dataCategory: DayOfMonth + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = Day + + hierarchy 'Иерархия дат' + + level Год + column: Год + + level Квартал + column: Квартал + + level Месяц + column: Месяц + + level День + column: День + + annotation TemplateId = DateHierarchy + + partition LocalDateTable_67da7b50-915b-480b-9e3a-3a60739fb0c6 = calculated + mode: import + source = Calendar(Date(Year(MIN('Партнер'[ДатаРегистрации])), 1, 1), Date(Year(MAX('Партнер'[ДатаРегистрации])), 12, 31)) + + annotation __PBI_LocalDateTable = true + diff --git a/analytics/pbi/model/report/Model/tables/LocalDateTable_704570fc-e0c6-4914-97ab-ebb645a2ab6e.tmdl b/analytics/pbi/model/report/Model/tables/LocalDateTable_704570fc-e0c6-4914-97ab-ebb645a2ab6e.tmdl new file mode 100644 index 0000000..7cff9ef --- /dev/null +++ b/analytics/pbi/model/report/Model/tables/LocalDateTable_704570fc-e0c6-4914-97ab-ebb645a2ab6e.tmdl @@ -0,0 +1,98 @@ +table LocalDateTable_704570fc-e0c6-4914-97ab-ebb645a2ab6e + isHidden + showAsVariationsOnly + + column Date + dataType: dateTime + isHidden + dataCategory: PaddedDateTableDates + summarizeBy: none + isNameInferred + sourceColumn: [Date] + + annotation SummarizationSetBy = User + + column Год = YEAR([Date]) + dataType: int64 + isHidden + dataCategory: Years + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = Year + + column №Месяца = MONTH([Date]) + dataType: int64 + isHidden + dataCategory: MonthOfYear + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = MonthNumber + + column Месяц = FORMAT([Date], "MMMM") + dataType: string + isHidden + dataCategory: Months + summarizeBy: none + sortByColumn: №Месяца + + annotation SummarizationSetBy = User + + annotation TemplateId = Month + + column №Квартала = INT(([№Месяца] + 2) / 3) + dataType: int64 + isHidden + dataCategory: QuarterOfYear + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = QuarterNumber + + column Квартал = "Кв. " & [№Квартала] + dataType: string + isHidden + dataCategory: Quarters + summarizeBy: none + sortByColumn: №Квартала + + annotation SummarizationSetBy = User + + annotation TemplateId = Quarter + + column День = DAY([Date]) + dataType: int64 + isHidden + dataCategory: DayOfMonth + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = Day + + hierarchy 'Иерархия дат' + + level Год + column: Год + + level Квартал + column: Квартал + + level Месяц + column: Месяц + + level День + column: День + + annotation TemplateId = DateHierarchy + + partition LocalDateTable_704570fc-e0c6-4914-97ab-ebb645a2ab6e = calculated + mode: import + source = Calendar(Date(Year(MIN('План продаж по группам'[Месяц])), 1, 1), Date(Year(MAX('План продаж по группам'[Месяц])), 12, 31)) + + annotation __PBI_LocalDateTable = true + diff --git a/analytics/pbi/model/report/Model/tables/LocalDateTable_729bf6db-04e4-4a26-9dce-b3837667cb92.tmdl b/analytics/pbi/model/report/Model/tables/LocalDateTable_729bf6db-04e4-4a26-9dce-b3837667cb92.tmdl new file mode 100644 index 0000000..dc5966d --- /dev/null +++ b/analytics/pbi/model/report/Model/tables/LocalDateTable_729bf6db-04e4-4a26-9dce-b3837667cb92.tmdl @@ -0,0 +1,98 @@ +table LocalDateTable_729bf6db-04e4-4a26-9dce-b3837667cb92 + isHidden + showAsVariationsOnly + + column Date + dataType: dateTime + isHidden + dataCategory: PaddedDateTableDates + summarizeBy: none + isNameInferred + sourceColumn: [Date] + + annotation SummarizationSetBy = User + + column Год = YEAR([Date]) + dataType: int64 + isHidden + dataCategory: Years + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = Year + + column №Месяца = MONTH([Date]) + dataType: int64 + isHidden + dataCategory: MonthOfYear + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = MonthNumber + + column Месяц = FORMAT([Date], "MMMM") + dataType: string + isHidden + dataCategory: Months + summarizeBy: none + sortByColumn: №Месяца + + annotation SummarizationSetBy = User + + annotation TemplateId = Month + + column №Квартала = INT(([№Месяца] + 2) / 3) + dataType: int64 + isHidden + dataCategory: QuarterOfYear + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = QuarterNumber + + column Квартал = "Кв. " & [№Квартала] + dataType: string + isHidden + dataCategory: Quarters + summarizeBy: none + sortByColumn: №Квартала + + annotation SummarizationSetBy = User + + annotation TemplateId = Quarter + + column День = DAY([Date]) + dataType: int64 + isHidden + dataCategory: DayOfMonth + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = Day + + hierarchy 'Иерархия дат' + + level Год + column: Год + + level Квартал + column: Квартал + + level Месяц + column: Месяц + + level День + column: День + + annotation TemplateId = DateHierarchy + + partition LocalDateTable_729bf6db-04e4-4a26-9dce-b3837667cb92 = calculated + mode: import + source = Calendar(Date(Year(MIN('Заявки на оплату'[date])), 1, 1), Date(Year(MAX('Заявки на оплату'[date])), 12, 31)) + + annotation __PBI_LocalDateTable = true + diff --git a/analytics/pbi/model/report/Model/tables/LocalDateTable_93d80160-0984-4e44-91de-316b6ab26727.tmdl b/analytics/pbi/model/report/Model/tables/LocalDateTable_93d80160-0984-4e44-91de-316b6ab26727.tmdl new file mode 100644 index 0000000..cfb224a --- /dev/null +++ b/analytics/pbi/model/report/Model/tables/LocalDateTable_93d80160-0984-4e44-91de-316b6ab26727.tmdl @@ -0,0 +1,98 @@ +table LocalDateTable_93d80160-0984-4e44-91de-316b6ab26727 + isHidden + showAsVariationsOnly + + column Date + dataType: dateTime + isHidden + dataCategory: PaddedDateTableDates + summarizeBy: none + isNameInferred + sourceColumn: [Date] + + annotation SummarizationSetBy = User + + column Год = YEAR([Date]) + dataType: int64 + isHidden + dataCategory: Years + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = Year + + column №Месяца = MONTH([Date]) + dataType: int64 + isHidden + dataCategory: MonthOfYear + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = MonthNumber + + column Месяц = FORMAT([Date], "MMMM") + dataType: string + isHidden + dataCategory: Months + summarizeBy: none + sortByColumn: №Месяца + + annotation SummarizationSetBy = User + + annotation TemplateId = Month + + column №Квартала = INT(([№Месяца] + 2) / 3) + dataType: int64 + isHidden + dataCategory: QuarterOfYear + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = QuarterNumber + + column Квартал = "Кв. " & [№Квартала] + dataType: string + isHidden + dataCategory: Quarters + summarizeBy: none + sortByColumn: №Квартала + + annotation SummarizationSetBy = User + + annotation TemplateId = Quarter + + column День = DAY([Date]) + dataType: int64 + isHidden + dataCategory: DayOfMonth + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = Day + + hierarchy 'Иерархия дат' + + level Год + column: Год + + level Квартал + column: Квартал + + level Месяц + column: Месяц + + level День + column: День + + annotation TemplateId = DateHierarchy + + partition LocalDateTable_93d80160-0984-4e44-91de-316b6ab26727 = calculated + mode: import + source = Calendar(Date(Year(MIN('Себестоимость'[Заказ закрыт])), 1, 1), Date(Year(MAX('Себестоимость'[Заказ закрыт])), 12, 31)) + + annotation __PBI_LocalDateTable = true + diff --git a/analytics/pbi/model/report/Model/tables/LocalDateTable_c661d468-0044-4990-b9e8-723cda59cf51.tmdl b/analytics/pbi/model/report/Model/tables/LocalDateTable_c661d468-0044-4990-b9e8-723cda59cf51.tmdl new file mode 100644 index 0000000..acbf486 --- /dev/null +++ b/analytics/pbi/model/report/Model/tables/LocalDateTable_c661d468-0044-4990-b9e8-723cda59cf51.tmdl @@ -0,0 +1,98 @@ +table LocalDateTable_c661d468-0044-4990-b9e8-723cda59cf51 + isHidden + showAsVariationsOnly + + column Date + dataType: dateTime + isHidden + dataCategory: PaddedDateTableDates + summarizeBy: none + isNameInferred + sourceColumn: [Date] + + annotation SummarizationSetBy = User + + column Год = YEAR([Date]) + dataType: int64 + isHidden + dataCategory: Years + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = Year + + column №Месяца = MONTH([Date]) + dataType: int64 + isHidden + dataCategory: MonthOfYear + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = MonthNumber + + column Месяц = FORMAT([Date], "MMMM") + dataType: string + isHidden + dataCategory: Months + summarizeBy: none + sortByColumn: №Месяца + + annotation SummarizationSetBy = User + + annotation TemplateId = Month + + column №Квартала = INT(([№Месяца] + 2) / 3) + dataType: int64 + isHidden + dataCategory: QuarterOfYear + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = QuarterNumber + + column Квартал = "Кв. " & [№Квартала] + dataType: string + isHidden + dataCategory: Quarters + summarizeBy: none + sortByColumn: №Квартала + + annotation SummarizationSetBy = User + + annotation TemplateId = Quarter + + column День = DAY([Date]) + dataType: int64 + isHidden + dataCategory: DayOfMonth + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = Day + + hierarchy 'Иерархия дат' + + level Год + column: Год + + level Квартал + column: Квартал + + level Месяц + column: Месяц + + level День + column: День + + annotation TemplateId = DateHierarchy + + partition LocalDateTable_c661d468-0044-4990-b9e8-723cda59cf51 = calculated + mode: import + source = Calendar(Date(Year(MIN('Партнер'[Дата последнего звонка])), 1, 1), Date(Year(MAX('Партнер'[Дата последнего звонка])), 12, 31)) + + annotation __PBI_LocalDateTable = true + diff --git a/analytics/pbi/model/report/Model/tables/LocalDateTable_e0374236-67f4-4331-b4f5-c977a3082bab.tmdl b/analytics/pbi/model/report/Model/tables/LocalDateTable_e0374236-67f4-4331-b4f5-c977a3082bab.tmdl new file mode 100644 index 0000000..17ddd5b --- /dev/null +++ b/analytics/pbi/model/report/Model/tables/LocalDateTable_e0374236-67f4-4331-b4f5-c977a3082bab.tmdl @@ -0,0 +1,98 @@ +table LocalDateTable_e0374236-67f4-4331-b4f5-c977a3082bab + isHidden + showAsVariationsOnly + + column Date + dataType: dateTime + isHidden + dataCategory: PaddedDateTableDates + summarizeBy: none + isNameInferred + sourceColumn: [Date] + + annotation SummarizationSetBy = User + + column Год = YEAR([Date]) + dataType: int64 + isHidden + dataCategory: Years + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = Year + + column №Месяца = MONTH([Date]) + dataType: int64 + isHidden + dataCategory: MonthOfYear + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = MonthNumber + + column Месяц = FORMAT([Date], "MMMM") + dataType: string + isHidden + dataCategory: Months + summarizeBy: none + sortByColumn: №Месяца + + annotation SummarizationSetBy = User + + annotation TemplateId = Month + + column №Квартала = INT(([№Месяца] + 2) / 3) + dataType: int64 + isHidden + dataCategory: QuarterOfYear + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = QuarterNumber + + column Квартал = "Кв. " & [№Квартала] + dataType: string + isHidden + dataCategory: Quarters + summarizeBy: none + sortByColumn: №Квартала + + annotation SummarizationSetBy = User + + annotation TemplateId = Quarter + + column День = DAY([Date]) + dataType: int64 + isHidden + dataCategory: DayOfMonth + summarizeBy: none + + annotation SummarizationSetBy = User + + annotation TemplateId = Day + + hierarchy 'Иерархия дат' + + level Год + column: Год + + level Квартал + column: Квартал + + level Месяц + column: Месяц + + level День + column: День + + annotation TemplateId = DateHierarchy + + partition LocalDateTable_e0374236-67f4-4331-b4f5-c977a3082bab = calculated + mode: import + source = Calendar(Date(Year(MIN('.Календарь'[Дата])), 1, 1), Date(Year(MAX('.Календарь'[Дата])), 12, 31)) + + annotation __PBI_LocalDateTable = true + diff --git a/analytics/pbi/model/report/Model/tables/crm_company_uf.tmdl b/analytics/pbi/model/report/Model/tables/crm_company_uf.tmdl new file mode 100644 index 0000000..b300d53 --- /dev/null +++ b/analytics/pbi/model/report/Model/tables/crm_company_uf.tmdl @@ -0,0 +1,60 @@ +table crm_company_uf + isHidden + + column bitrix_id + dataType: string + isHidden + summarizeBy: none + sourceColumn: bitrix_id + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column 'Дата последнего звонка' + dataType: dateTime + isHidden + formatString: Long Date + summarizeBy: none + sourceColumn: Дата последнего звонка + + variation Изменение + isDefault + relationship: 34a39f02-5cb4-4c1b-b8e8-ea3ef9aafb4e + defaultHierarchy: LocalDateTable_49b06afb-4254-4da6-9109-618106084862.'Иерархия дат' + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + annotation UnderlyingDateTimeDataType = Date + + partition crm_company_uf = m + mode: import + source = + let + raw_t = bx24_load_entity("crm_company_uf"), + fixed_t = Table.TransformColumnTypes(raw_t, + { + {"COMPANY_ID", Int64.Type}, + + {"DATE_CREATE", type datetime} + + //{"UF_CRM_12345", type text} + + }, + "en-US" + ), + #"Другие удаленные столбцы" = Table.SelectColumns(fixed_t,{"COMPANY_ID", "UF_CRM_LAST_CALL_DATE"}), + #"Разделить столбец по разделителю" = Table.SplitColumn(#"Другие удаленные столбцы", "UF_CRM_LAST_CALL_DATE", Splitter.SplitTextByDelimiter(" ", QuoteStyle.Csv), {"UF_CRM_LAST_CALL_DATE.1", "UF_CRM_LAST_CALL_DATE.2"}), + #"Измененный тип" = Table.TransformColumnTypes(#"Разделить столбец по разделителю",{{"UF_CRM_LAST_CALL_DATE.1", type date}, {"UF_CRM_LAST_CALL_DATE.2", type time}}), + #"Удаленные столбцы" = Table.RemoveColumns(#"Измененный тип",{"UF_CRM_LAST_CALL_DATE.2"}), + #"Переименованные столбцы" = Table.RenameColumns(#"Удаленные столбцы",{{"COMPANY_ID", "bitrix_id"}, {"UF_CRM_LAST_CALL_DATE.1", "Дата последнего звонка"}}), + #"Измененный тип1" = Table.TransformColumnTypes(#"Переименованные столбцы",{{"bitrix_id", type text}}) + in + #"Измененный тип1" + + changedProperty = IsHidden + + annotation PBI_ResultType = Table + diff --git a/analytics/pbi/model/report/Model/tables/mp аналитика продаж.tmdl b/analytics/pbi/model/report/Model/tables/mp аналитика продаж.tmdl new file mode 100644 index 0000000..d8dab6d --- /dev/null +++ b/analytics/pbi/model/report/Model/tables/mp аналитика продаж.tmdl @@ -0,0 +1,105 @@ +table 'mp аналитика продаж' + + column Узел + dataType: string + isHidden + summarizeBy: none + sourceColumn: Узел + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column 'Вид загрузки' + dataType: string + summarizeBy: none + sourceColumn: Вид загрузки + + annotation SummarizationSetBy = Automatic + + column Склад + dataType: string + summarizeBy: none + sourceColumn: Склад + + annotation SummarizationSetBy = Automatic + + column Дата + dataType: dateTime + isHidden + formatString: Long Date + summarizeBy: none + sourceColumn: Дата + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + annotation UnderlyingDateTimeDataType = Date + + column artic_id + dataType: string + isHidden + summarizeBy: none + sourceColumn: artic_id + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column Область + dataType: string + summarizeBy: none + sourceColumn: Область + + annotation SummarizationSetBy = Automatic + + column Страна + dataType: string + summarizeBy: none + sourceColumn: Страна + + annotation SummarizationSetBy = Automatic + + column Регион + dataType: string + summarizeBy: none + sourceColumn: Регион + + annotation SummarizationSetBy = Automatic + + column 'Продано, упак' + dataType: int64 + formatString: #,0 + summarizeBy: sum + sourceColumn: Продано, упак + + annotation SummarizationSetBy = Automatic + + column 'Продано, руб' + dataType: double + formatString: #,0 + summarizeBy: sum + sourceColumn: Продано, руб + + annotation SummarizationSetBy = Automatic + + partition 'mp аналитика продаж' = m + mode: import + source = + let + Источник = Sql.Database("prdsql", "mag_pbi"), + #"pbi_Внешние продажи" = Источник{[Schema="pbi",Item="Внешние продажи"]}[Data], + #"Измененный тип" = Table.TransformColumnTypes(#"pbi_Внешние продажи",{{"Дата", type date}, {"Количество", Int64.Type}}), + #"Переименованные столбцы" = Table.RenameColumns(#"Измененный тип",{{"Количество", "Продано, шт"}, {"Сумма", "Продано, руб"}}), + #"Обрезанный текст" = Table.TransformColumns(#"Переименованные столбцы",{{"id_внешний", Text.Trim, type text}}), + #"Удаленные столбцы" = Table.RemoveColumns(#"Обрезанный текст",{"id_внешний"}), + #"Строки с примененным фильтром" = Table.SelectRows(#"Удаленные столбцы", each [Дата] >= #date(2024, 1, 1)), + #"Переименованные столбцы1" = Table.RenameColumns(#"Строки с примененным фильтром",{{"Продано, шт", "Продано, упак"}}) + in + #"Переименованные столбцы1" + + annotation PBI_ResultType = Table + + annotation PBI_NavigationStepName = Навигация + diff --git a/analytics/pbi/model/report/Model/tables/mp оборот.tmdl b/analytics/pbi/model/report/Model/tables/mp оборот.tmdl new file mode 100644 index 0000000..a4c1a13 --- /dev/null +++ b/analytics/pbi/model/report/Model/tables/mp оборот.tmdl @@ -0,0 +1,147 @@ +table 'mp оборот' + + measure 'Расходы к обороту, %' = ``` + + VAR _MinDate = DATE(2025, 1, 1) + RETURN + CALCULATE( + VAR _Turnover = + SUM('mp оборот'[Сумма оборот МП, руб]) + VAR _Sales = + [Сумма продаж, руб] + RETURN + DIVIDE( + _Turnover - _Sales, + _Turnover, + 0 + ), + KEEPFILTERS( + FILTER( + '.Календарь', + '.Календарь'[Дата] >= _MinDate + ) + ) + ) + + ``` + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + measure 'Расходы МП + РК + СПП, руб' = ``` + + VAR _MinDate = DATE(2025, 1, 1) + RETURN + CALCULATE( + VAR _Turnover = + SUM('mp оборот'[Сумма оборот МП, руб]) + VAR _Sales = + [Сумма продаж, руб] + RETURN + + _Turnover - _Sales, + + KEEPFILTERS( + FILTER( + '.Календарь', + '.Календарь'[Дата] >= _MinDate + ) + ) + ) + ``` + formatString: #,0 + + measure 'НДС_20 по расходам, руб' = [Расходы МП + РК + СПП, руб] - [Расходы МП + РК + СПП, руб] / 1.2 + formatString: #,0 + + measure 'Расходы к учетной сумме, %' = + + VAR _MinDate = DATE(2025, 1, 1) + RETURN + CALCULATE( + VAR _Turnover = + SUM('mp оборот'[Сумма оборот МП, руб]) + VAR _Sales = + [Сумма учетная, руб] + RETURN + DIVIDE( + _Turnover - _Sales, + _Turnover, + 0 + ), + KEEPFILTERS( + FILTER( + '.Календарь', + '.Календарь'[Дата] >= _MinDate + ) + ) + ) + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column Дата + dataType: dateTime + isHidden + formatString: Long Date + summarizeBy: none + sourceColumn: Дата + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + annotation UnderlyingDateTimeDataType = Date + + column artic_id + dataType: string + isHidden + summarizeBy: none + sourceColumn: artic_id + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column Организация + dataType: string + isHidden + summarizeBy: none + sourceColumn: Организация + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column partner_id + dataType: string + isHidden + summarizeBy: none + sourceColumn: partner_id + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column 'Сумма оборот МП, руб' + dataType: double + formatString: #,0 + summarizeBy: sum + sourceColumn: Сумма оборот МП, руб + + annotation SummarizationSetBy = Automatic + + partition 'mp оборот' = m + mode: import + source = + let + Источник = Sql.Database("prdsql", "mag_pbi"), + #"pbi_Внешний оборот" = Источник{[Schema="pbi",Item="Внешний оборот"]}[Data], + #"Измененный тип" = Table.TransformColumnTypes(#"pbi_Внешний оборот",{{"Дата", type date}}) + in + #"Измененный тип" + + changedProperty = Name + + annotation PBI_NavigationStepName = Навигация + + annotation PBI_ResultType = Table + diff --git a/analytics/pbi/model/report/Model/tables/mp остатки.tmdl b/analytics/pbi/model/report/Model/tables/mp остатки.tmdl new file mode 100644 index 0000000..7b51770 --- /dev/null +++ b/analytics/pbi/model/report/Model/tables/mp остатки.tmdl @@ -0,0 +1,103 @@ +table 'mp остатки' + + column Узел + dataType: string + isHidden + summarizeBy: none + sourceColumn: Узел + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column Тип + dataType: string + summarizeBy: none + sourceColumn: Тип + + annotation SummarizationSetBy = Automatic + + column Склад + dataType: string + summarizeBy: none + sourceColumn: Склад + + annotation SummarizationSetBy = Automatic + + column 'Дата обновления' + dataType: dateTime + isHidden + formatString: Long Date + summarizeBy: none + sourceColumn: Дата обновления + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + annotation UnderlyingDateTimeDataType = Date + + column artic_id + dataType: string + isHidden + summarizeBy: none + sourceColumn: artic_id + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column id_внешний + dataType: string + summarizeBy: none + sourceColumn: id_внешний + + annotation SummarizationSetBy = Automatic + + column 'Остаток МП, упак' + dataType: int64 + formatString: #,0 + summarizeBy: sum + sourceColumn: Остаток МП, упак + + annotation SummarizationSetBy = Automatic + + column 'Доступно, упак' + dataType: int64 + formatString: #,0 + summarizeBy: sum + sourceColumn: Доступно, упак + + annotation SummarizationSetBy = Automatic + + column 'Остаток МП, шт' + dataType: double + formatString: #,0 + summarizeBy: sum + sourceColumn: Остаток МП, шт + + annotation SummarizationSetBy = Automatic + + column 'Остаток МП, руб' = 'mp остатки'[Остаток МП, шт] * RELATED('Номенклатура'[Цена учетная, руб]) + formatString: #,0 + summarizeBy: sum + + annotation SummarizationSetBy = Automatic + + partition 'mp остатки' = m + mode: import + source = + let + Источник = Sql.Database("prdsql", "mag_pbi"), + #"pbi_Внешние остатки" = Источник{[Schema="pbi",Item="Внешние остатки"]}[Data], + #"Измененный тип" = Table.TransformColumnTypes(#"pbi_Внешние остатки",{{"Дата обновления", type date}, {"Количество", Int64.Type}, {"Доступное кол-во", Int64.Type}}), + #"Переименованные столбцы" = Table.RenameColumns(#"Измененный тип",{{"Количество", "Остаток, упак"}, {"Доступное кол-во", "Доступно, упак"}}), + #"Обрезанный текст" = Table.TransformColumns(#"Переименованные столбцы",{{"id_внешний", Text.Trim, type text}}), + #"Переименованные столбцы1" = Table.RenameColumns(#"Обрезанный текст",{{"Остаток, упак", "Остаток МП, упак"}}) + in + #"Переименованные столбцы1" + + annotation PBI_ResultType = Table + + annotation PBI_NavigationStepName = Навигация + diff --git a/analytics/pbi/model/report/Model/tables/mp реклама.tmdl b/analytics/pbi/model/report/Model/tables/mp реклама.tmdl new file mode 100644 index 0000000..787dd0f --- /dev/null +++ b/analytics/pbi/model/report/Model/tables/mp реклама.tmdl @@ -0,0 +1,209 @@ +table 'mp реклама' + + measure 'ДРР заказы по рекламе, %' = ``` + DIVIDE( + SUM('mp реклама'[Затраты РК, руб]), + SUM('mp реклама'[Сумма заказов]), 1) + ``` + formatString: #,0%;-#,0%;#,0% + + measure 'ДРР заказы все, %' = + + DIVIDE( + SUM('mp реклама'[Затраты РК, руб]), + CALCULATE( + SUM('mp аналитика продаж'[Продано, руб]), + 'mp аналитика продаж'[Вид загрузки] = "ЗаказыВС" + ), + 1 + ) + formatString: #,0%;-#,0%;#,0% + + column Дата + dataType: dateTime + isHidden + formatString: Long Date + summarizeBy: none + sourceColumn: Дата + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + annotation UnderlyingDateTimeDataType = Date + + column Узел + dataType: string + isHidden + summarizeBy: none + sourceColumn: Узел + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column artic_id + dataType: string + isHidden + summarizeBy: none + sourceColumn: artic_id + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column 'Номер кампании' + dataType: string + summarizeBy: none + sourceColumn: Номер кампании + + annotation SummarizationSetBy = Automatic + + column 'Тип кампании' + dataType: string + summarizeBy: none + sourceColumn: Тип кампании + + annotation SummarizationSetBy = Automatic + + column Просмотры + dataType: int64 + formatString: #,0 + summarizeBy: sum + sourceColumn: Просмотры + + annotation SummarizationSetBy = Automatic + + column Клики + dataType: int64 + formatString: #,0 + summarizeBy: sum + sourceColumn: Клики + + annotation SummarizationSetBy = Automatic + + column 'atbs кол-во добавлений в корзину' + dataType: int64 + formatString: #,0 + summarizeBy: sum + sourceColumn: atbs кол-во добавлений в корзину + + annotation SummarizationSetBy = Automatic + + column 'Затраты РК, руб' + dataType: double + formatString: #,0 + summarizeBy: sum + sourceColumn: Затраты РК, руб + + annotation SummarizationSetBy = Automatic + + column 'Стоимость клика, руб' + dataType: double + formatString: #,0 + summarizeBy: sum + sourceColumn: Стоимость клика, руб + + annotation SummarizationSetBy = Automatic + + column 'Количество заказов' + dataType: int64 + formatString: #,0 + summarizeBy: sum + sourceColumn: Количество заказов + + annotation SummarizationSetBy = Automatic + + column 'Сумма заказов' + dataType: double + formatString: #,0 + summarizeBy: sum + sourceColumn: Сумма заказов + + annotation SummarizationSetBy = Automatic + + column 'Ставка поиск, %' + dataType: double + formatString: #,0 + summarizeBy: sum + sourceColumn: Ставка поиск, % + + annotation SummarizationSetBy = Automatic + + column 'Ставка поиск, руб' + dataType: double + formatString: #,0 + summarizeBy: sum + sourceColumn: Ставка поиск, руб + + annotation SummarizationSetBy = Automatic + + column 'Охват, %' + dataType: double + formatString: #,0 + summarizeBy: sum + sourceColumn: Охват, % + + annotation SummarizationSetBy = Automatic + + column 'cr кол-во заказов / кол-во посещений' + dataType: double + formatString: #,0 + summarizeBy: sum + sourceColumn: cr кол-во заказов / кол-во посещений + + annotation SummarizationSetBy = Automatic + + column 'Дата начала' + dataType: dateTime + formatString: Long Date + summarizeBy: none + sourceColumn: Дата начала + + variation Изменение + isDefault + relationship: 8229a93a-e14d-491e-ac57-cbab91627fdd + defaultHierarchy: LocalDateTable_1c75c57c-6ac4-4a07-ab45-b46636c3847c.'Иерархия дат' + + annotation SummarizationSetBy = Automatic + + annotation UnderlyingDateTimeDataType = Date + + column id_product + dataType: string + summarizeBy: none + sourceColumn: id_product + + annotation SummarizationSetBy = Automatic + + column 'Заказано товаров, упак' + dataType: double + formatString: #,0 + summarizeBy: sum + sourceColumn: Заказано товаров, упак + + annotation SummarizationSetBy = Automatic + + column 'Затраты РК, usd' + dataType: double + formatString: #,0 + summarizeBy: sum + sourceColumn: Затраты РК, usd + + annotation SummarizationSetBy = Automatic + + partition 'mp реклама' = m + mode: import + source = + let + Источник = Sql.Database("prdsql", "mag_pbi"), + pbi_РекламаМаркетплейсы = Источник{[Schema="pbi",Item="РекламаМаркетплейсы"]}[Data], + #"Измененный тип" = Table.TransformColumnTypes(pbi_РекламаМаркетплейсы,{{"Дата", type date}, {"Просмотры", Int64.Type}, {"Клики", Int64.Type}, {"atbs кол-во добавлений в корзину", Int64.Type}, {"Количество заказов", Int64.Type}, {"Дата начала", type date}}), + #"Переименованные столбцы" = Table.RenameColumns(#"Измененный тип",{{"Затраты, руб", "Затраты РК, руб"}, {"Затраты, usd", "Затраты РК, usd"}}) + in + #"Переименованные столбцы" + + annotation PBI_NavigationStepName = Навигация + + annotation PBI_ResultType = Table + diff --git a/analytics/pbi/model/report/Model/tables/mp узел.tmdl b/analytics/pbi/model/report/Model/tables/mp узел.tmdl new file mode 100644 index 0000000..d057ced --- /dev/null +++ b/analytics/pbi/model/report/Model/tables/mp узел.tmdl @@ -0,0 +1,40 @@ +table 'mp узел' + + column Узел + dataType: string + summarizeBy: none + sourceColumn: Узел + + annotation SummarizationSetBy = Automatic + + column Организация + dataType: string + isHidden + summarizeBy: none + sourceColumn: Организация + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column partner_id + dataType: string + isHidden + summarizeBy: none + sourceColumn: partner_id + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + partition 'mp узел' = m + mode: import + source = + let + Источник = Sql.Database("prdsql", "mag_pbi"), + pbi_node_mp = Источник{[Schema="pbi",Item="node_mp"]}[Data] + in + pbi_node_mp + + changedProperty = Name + diff --git a/analytics/pbi/model/report/Model/tables/Группы.tmdl b/analytics/pbi/model/report/Model/tables/Группы.tmdl new file mode 100644 index 0000000..5c633d7 --- /dev/null +++ b/analytics/pbi/model/report/Model/tables/Группы.tmdl @@ -0,0 +1,138 @@ +table Группы + + column _Description + dataType: string + isHidden + summarizeBy: none + sourceColumn: _Description + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column Группа + dataType: string + summarizeBy: none + sourceColumn: Группа + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column 'Подгруппа 1' + dataType: string + summarizeBy: none + sourceColumn: Подгруппа 1 + + annotation SummarizationSetBy = Automatic + + column 'Подгруппа 2' + dataType: string + summarizeBy: none + sourceColumn: Подгруппа 2 + + annotation SummarizationSetBy = Automatic + + column 'Подгруппа 3' + dataType: string + summarizeBy: none + sourceColumn: Подгруппа 3 + + annotation SummarizationSetBy = Automatic + + column group_id + dataType: string + isHidden + summarizeBy: none + sourceColumn: group_id + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column _ParentIDRRef + dataType: string + isHidden + summarizeBy: none + sourceColumn: _ParentIDRRef + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column 'Уровень вложенности' + dataType: int64 + formatString: 0 + summarizeBy: sum + sourceColumn: Уровень вложенности + + annotation SummarizationSetBy = Automatic + + column 'Полный путь' + dataType: string + summarizeBy: none + sourceColumn: Полный путь + + annotation SummarizationSetBy = Automatic + + column code + dataType: string + isHidden + summarizeBy: none + sourceColumn: code + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column план + dataType: double + isHidden + summarizeBy: sum + sourceColumn: план + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column 'first group' + dataType: string + isHidden + summarizeBy: none + sourceColumn: first group + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + hierarchy 'Группа Иерархия' + + level Группа + column: Группа + + level 'Подгруппа 1' + column: 'Подгруппа 1' + + level 'Подгруппа 2' + column: 'Подгруппа 2' + + level 'Подгруппа 3' + column: 'Подгруппа 3' + + partition Группы = m + mode: import + source = + let + Источник = Sql.Databases("prdsql"), + mag_pbi = Источник{[Name="mag_pbi"]}[Data], + pbi_groups = mag_pbi{[Schema="pbi",Item="groups"]}[Data], + #"Переименованные столбцы" = Table.RenameColumns(pbi_groups,{{"g", "Группа"}, {"g1", "Подгруппа 1"}, {"g2", "Подгруппа 2"}, {"g3", "Подгруппа 3"}, {"path", "Полный путь"}, {"lvl", "Уровень вложенности"}}) + in + #"Переименованные столбцы" + + annotation PBI_NavigationStepName = Навигация + + annotation PBI_ResultType = Table + diff --git a/analytics/pbi/model/report/Model/tables/Заказы все.tmdl b/analytics/pbi/model/report/Model/tables/Заказы все.tmdl new file mode 100644 index 0000000..642a1ed --- /dev/null +++ b/analytics/pbi/model/report/Model/tables/Заказы все.tmdl @@ -0,0 +1,595 @@ +table 'Заказы все' + + measure 'В производстве кол.' = + + CALCULATE( + SUM('Заказы все'[Количество]), + 'Заказы все'[Статус] = "В производстве" + ) + formatString: #,0 + displayFolder: Заказы в производстве + + measure 'В производстве объем, м3' = + + CALCULATE( + SUM('Заказы все'[Объем, м3]), + 'Заказы все'[Статус] = "В производстве" + ) + formatString: #,0 + displayFolder: Заказы в производстве + + measure 'В производстве сумма всего в usd2' = + + CALCULATE( + SUM('Заказы все'[Сумма всего в usd2]), + 'Заказы все'[Статус] = "В производстве" + ) + formatString: #,0 + displayFolder: Заказы в производстве + + measure 'В производстве сумма всего в руб' = + + CALCULATE( + SUM('Заказы все'[Сумма всего в руб]), + 'Заказы все'[Статус] = "В производстве" + ) + formatString: #,0 + displayFolder: Заказы в производстве + + measure 'В производстве упак.' = + + CALCULATE( + SUM('Заказы все'[Кол. упаковок]), + 'Заказы все'[Статус] = "В производстве" + ) + formatString: #,0 + displayFolder: Заказы в производстве + + measure 'Сумма в производстве, руб' = ``` + + CALCULATE( + [В производстве сумма всего в usd2], + 'Заказы все'[Валюта] = "руб." + ) + ``` + formatString: #,0 + displayFolder: Заказы в производстве + + measure 'Сумма в производстве, cny' = ``` + + CALCULATE( + [В производстве сумма всего в usd2], + 'Заказы все'[Валюта] = "CNY" + ) + ``` + formatString: #,0 + displayFolder: Заказы в производстве + + measure 'Сумма в производстве, try' = ``` + + CALCULATE( + [В производстве сумма всего в usd2], + 'Заказы все'[Валюта] = "TRY" + ) + ``` + formatString: #,0 + displayFolder: Заказы в производстве + + measure 'Сумма в производстве, usd2' = ``` + + CALCULATE( + [В производстве сумма всего в usd2], + 'Заказы все'[Валюта] = "USD2" + ) + ``` + formatString: #,0 + displayFolder: Заказы в производстве + + measure 'В пути кол.' = + + CALCULATE( + SUM('Заказы все'[Количество]), + 'Заказы все'[Статус] = "В пути" + ) + formatString: #,0 + displayFolder: Заказы в пути + + measure 'В пути объем, м3' = + + CALCULATE( + SUM('Заказы все'[Объем, м3]), + 'Заказы все'[Статус] = "В пути" + ) + formatString: #,0 + displayFolder: Заказы в пути + + measure 'В пути сумма всего в usd2' = + + CALCULATE( + SUM('Заказы все'[Сумма всего в usd2]), + 'Заказы все'[Статус] = "В пути" + ) + formatString: #,0 + displayFolder: Заказы в пути + + measure 'В пути сумма всего в руб' = + + CALCULATE( + SUM('Заказы все'[Сумма всего в руб]), + 'Заказы все'[Статус] = "В пути" + ) + formatString: #,0 + displayFolder: Заказы в пути + + measure 'В пути упак.' = + + CALCULATE( + SUM('Заказы все'[Кол. упаковок]), + 'Заказы все'[Статус] = "В пути" + ) + formatString: #,0 + displayFolder: Заказы в пути + + measure 'Сумма в пути, руб' = ``` + + CALCULATE( + [В пути сумма всего в usd2], + 'Заказы все'[Валюта] = "руб." + ) + ``` + formatString: #,0 + displayFolder: Заказы в пути + + measure 'Сумма в пути, cny' = ``` + + CALCULATE( + [В пути сумма всего в usd2], + 'Заказы все'[Валюта] = "CNY" + ) + ``` + formatString: #,0 + displayFolder: Заказы в пути + + measure 'Сумма в пути, try' = ``` + + CALCULATE( + [В пути сумма всего в usd2], + 'Заказы все'[Валюта] = "TRY" + ) + ``` + formatString: #,0 + displayFolder: Заказы в пути + + measure 'Сумма в пути, usd2' = ``` + + CALCULATE( + [В пути сумма всего в usd2], + 'Заказы все'[Валюта] = "USD2" + ) + ``` + formatString: #,0 + displayFolder: Заказы в пути + + measure 'Тех заказ кол.' = + + CALCULATE( + SUM('Заказы все'[Количество]), + 'Заказы все'[Статус] = "Тех. заказ" + ) + formatString: #,0 + displayFolder: Заказы тех + + measure 'Тех заказ объем, м3' = + + CALCULATE( + SUM('Заказы все'[Объем, м3]), + 'Заказы все'[Статус] = "Тех. заказ" + ) + formatString: #,0 + displayFolder: Заказы тех + + measure 'Тех заказ сумма всего в usd2' = + + CALCULATE( + SUM('Заказы все'[Сумма всего в usd2]), + 'Заказы все'[Статус] = "Тех. заказ" + ) + formatString: #,0 + displayFolder: Заказы тех + + measure 'Тех заказ сумма всего в руб' = + + CALCULATE( + SUM('Заказы все'[Сумма всего в руб]), + 'Заказы все'[Статус] = "Тех. заказ" + ) + formatString: #,0 + displayFolder: Заказы тех + + measure 'Тех заказ упак.' = + + CALCULATE( + SUM('Заказы все'[Кол. упаковок]), + 'Заказы все'[Статус] = "Тех. заказ" + ) + formatString: #,0 + displayFolder: Заказы тех + + measure 'Сумма тех заказ, руб' = ``` + + CALCULATE( + [Тех заказ сумма всего в usd2], + 'Заказы все'[Валюта] = "руб." + ) + ``` + formatString: #,0 + displayFolder: Заказы тех + + measure 'Сумма тех заказ, cny' = ``` + + CALCULATE( + [Тех заказ сумма всего в usd2], + 'Заказы все'[Валюта] = "CNY" + ) + ``` + formatString: #,0 + displayFolder: Заказы тех + + measure 'Сумма тех заказ, try' = ``` + + CALCULATE( + [Тех заказ сумма всего в usd2], + 'Заказы все'[Валюта] = "TRY" + ) + ``` + formatString: #,0 + displayFolder: Заказы тех + + measure 'Сумма тех заказ, usd2' = ``` + + CALCULATE( + [Тех заказ сумма всего в usd2], + 'Заказы все'[Валюта] = "USD2" + ) + ``` + formatString: #,0 + displayFolder: Заказы тех + + measure 'Согласование упак.' = + + CALCULATE( + SUM('Заказы все'[Кол. упаковок]), + FILTER('Заказы все', [Статус] IN {"На согласовании", "Согласован" }) + ) + formatString: #,0 + displayFolder: Заказы согласование + + measure 'Согласование кол.' = + + CALCULATE( + SUM('Заказы все'[Количество]), + FILTER('Заказы все', [Статус] IN {"На согласовании", "Согласован" }) + ) + formatString: #,0 + displayFolder: Заказы согласование + + measure 'Согласование объем, м3' = + + CALCULATE( + SUM('Заказы все'[Объем, м3]), + FILTER('Заказы все', [Статус] IN {"На согласовании", "Согласован" }) + ) + formatString: #,0 + displayFolder: Заказы согласование + + measure 'Согласование сумма всего в руб' = + + CALCULATE( + SUM('Заказы все'[Сумма всего в руб]), + FILTER('Заказы все', [Статус] IN {"На согласовании", "Согласован" }) + ) + formatString: #,0 + displayFolder: Заказы согласование + + measure 'Согласование сумма всего в usd2' = + + CALCULATE( + SUM('Заказы все'[Сумма всего в usd2]), + FILTER('Заказы все', [Статус] IN {"На согласовании", "Согласован" }) + ) + formatString: #,0 + displayFolder: Заказы согласование + + measure 'Сумма согласование, руб' = ``` + + CALCULATE( + [Согласование сумма всего в usd2], + 'Заказы все'[Валюта] = "руб." + ) + ``` + formatString: #,0 + displayFolder: Заказы согласование + + measure 'Сумма согласование, cny' = ``` + + CALCULATE( + [Согласование сумма всего в usd2], + 'Заказы все'[Валюта] = "CNY" + ) + ``` + formatString: #,0 + displayFolder: Заказы согласование + + measure 'Сумма согласование, try' = ``` + + CALCULATE( + [Согласование сумма всего в usd2], + 'Заказы все'[Валюта] = "TRY" + ) + ``` + formatString: #,0 + displayFolder: Заказы согласование + + measure 'Сумма согласование, usd2' = ``` + + CALCULATE( + [Согласование сумма всего в usd2], + 'Заказы все'[Валюта] = "USD2" + ) + ``` + formatString: #,0 + displayFolder: Заказы согласование + + measure 'Выгружен на складе кол.' = + + CALCULATE( + SUM('Заказы все'[Количество]), + FILTER('Заказы все', [Статус] = "Выгружен на складе") + ) + formatString: #,0 + displayFolder: Заказы выгружены на складе + + measure 'Выгружен на складе упак.' = + + CALCULATE( + SUM('Заказы все'[Кол. упаковок]), + FILTER('Заказы все', [Статус] = "Выгружен на складе") + ) + formatString: #,0 + displayFolder: Заказы выгружены на складе + + measure 'Выгружен на складе объем, м3' = + + CALCULATE( + SUM('Заказы все'[Объем, м3]), + FILTER('Заказы все', [Статус] = "Выгружен на складе") + ) + formatString: #,0 + displayFolder: Заказы выгружены на складе + + measure 'Выгружен на складе сумма всего в руб' = + + CALCULATE( + SUM('Заказы все'[Сумма всего в руб]), + FILTER('Заказы все', [Статус] = "Выгружен на складе") + ) + formatString: #,0 + displayFolder: Заказы выгружены на складе + + measure 'Выгружен на складе сумма всего в usd2' = + + CALCULATE( + SUM('Заказы все'[Сумма всего в usd2]), + FILTER('Заказы все', [Статус] = "Выгружен на складе") + ) + formatString: #,0 + displayFolder: Заказы выгружены на складе + + measure 'Сумма выгружен на складе, руб' = ``` + + CALCULATE( + [Выгружен на складе сумма всего в usd2], + 'Заказы все'[Валюта] = "руб." + ) + ``` + formatString: #,0 + displayFolder: Заказы выгружены на складе + + measure 'Сумма выгружен на складе, cny' = ``` + + CALCULATE( + [Выгружен на складе сумма всего в usd2], + 'Заказы все'[Валюта] = "CNY" + ) + ``` + formatString: #,0 + displayFolder: Заказы выгружены на складе + + measure 'Сумма выгружен на складе, try' = ``` + + CALCULATE( + [Выгружен на складе сумма всего в usd2], + 'Заказы все'[Валюта] = "TRY" + ) + ``` + formatString: #,0 + displayFolder: Заказы выгружены на складе + + measure 'Сумма выгружен на складе, usd2' = ``` + + CALCULATE( + [Выгружен на складе сумма всего в usd2], + 'Заказы все'[Валюта] = "USD2" + ) + ``` + formatString: #,0 + displayFolder: Заказы выгружены на складе + + column 'Дата заказа поставщику' + dataType: dateTime + formatString: Long Date + sourceProviderType: date + summarizeBy: none + sourceColumn: Дата заказа поставщику + + annotation SummarizationSetBy = Automatic + + annotation UnderlyingDateTimeDataType = Date + + column 'Номер заказа поставщику' + dataType: string + isNullable: false + sourceProviderType: nchar + summarizeBy: none + sourceColumn: Номер заказа поставщику + + annotation SummarizationSetBy = Automatic + + column partner_id + dataType: string + isHidden + sourceProviderType: nvarchar(36) + summarizeBy: none + sourceColumn: partner_id + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column Контрагент + dataType: string + sourceProviderType: nvarchar(100) + summarizeBy: none + sourceColumn: Контрагент + + annotation SummarizationSetBy = Automatic + + column Статус + dataType: string + isNullable: false + sourceProviderType: varchar(15) + summarizeBy: none + sourceColumn: Статус + + annotation SummarizationSetBy = Automatic + + column artic_id + dataType: string + isHidden + sourceProviderType: nvarchar(36) + summarizeBy: none + sourceColumn: artic_id + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column Количество + dataType: double + isNullable: false + sourceProviderType: decimal(15, 3) + summarizeBy: sum + sourceColumn: Количество + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column 'Кол. упаковок' + dataType: double + formatString: #,0 + sourceProviderType: decimal(10, 2) + summarizeBy: sum + sourceColumn: Кол. упаковок + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isDecimal":true} + + column 'Объем, м3' + dataType: double + sourceProviderType: decimal(38, 13) + summarizeBy: sum + sourceColumn: Объем, м3 + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column Цена + dataType: double + sourceProviderType: decimal(20, 12) + summarizeBy: sum + sourceColumn: Цена + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column Сумма + dataType: double + isHidden + sourceProviderType: decimal(20, 7) + summarizeBy: sum + sourceColumn: Сумма + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column Валюта + dataType: string + sourceProviderType: nvarchar(10) + summarizeBy: none + sourceColumn: Валюта + + annotation SummarizationSetBy = Automatic + + column 'Сумма всего в руб' + dataType: double + formatString: #,0 + sourceProviderType: decimal(31, 11) + summarizeBy: sum + sourceColumn: Сумма всего в руб + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isDecimal":true} + + column Партнер + dataType: string + sourceProviderType: nvarchar(100) + summarizeBy: none + sourceColumn: Партнер + + annotation SummarizationSetBy = Automatic + + column 'Сумма всего в usd2' + dataType: double + formatString: #,0.00 + sourceProviderType: decimal(38, 14) + summarizeBy: sum + sourceColumn: Сумма всего в usd2 + + annotation SummarizationSetBy = Automatic + + partition 'Заказы все' = m + mode: directQuery + source = + let + Источник = Sql.Database("prdsql", "mag_pbi"), + pbi_Заказы = Источник{[Schema="pbi",Item="Заказы"]}[Data], + #"Измененный тип" = Table.TransformColumnTypes(pbi_Заказы,{{"Дата заказа поставщику", type date}}), + #"Строки с примененным фильтром" = Table.SelectRows(#"Измененный тип", each ([Статус] <> "Закрыт" and [Статус] <> "Неизвестно" and [Статус] <> "Подтвержден")), + #"Строки с примененным фильтром1" = Table.SelectRows(#"Строки с примененным фильтром", each [Дата заказа поставщику] >= #date(2024, 1, 1)), + Округлено = Table.TransformColumns(#"Строки с примененным фильтром1",{{"Сумма всего, usd2", each Number.Round(_, 7), type number}}), + #"Переименованные столбцы" = Table.RenameColumns(Округлено,{{"Сумма в руб.", "Сумма всего в руб"}, {"Сумма всего, usd2", "Сумма всего в usd2"}}) + in + #"Переименованные столбцы" + + annotation PBI_NavigationStepName = Навигация + + annotation PBI_ResultType = Table + diff --git a/analytics/pbi/model/report/Model/tables/Закупки.tmdl b/analytics/pbi/model/report/Model/tables/Закупки.tmdl new file mode 100644 index 0000000..f6507bf --- /dev/null +++ b/analytics/pbi/model/report/Model/tables/Закупки.tmdl @@ -0,0 +1,261 @@ +table Закупки + + measure 'Сумма закупки, руб' = ``` + + SUM('Закупки'[Закуп.Закупка, руб]) + + SUM('Закупки'[Закуп.Таможня, руб]) + + SUM('Закупки'[Закуп.Доставка, руб]) + + SUM('Закупки'[Закуп.НДС, руб]) + + SUM('Закупки'[Закуп.Производство, руб]) - + SUM('Закупки'[Закуп.Доп расходы, руб]) + ``` + formatString: #,0 + + measure 'Сумма закупки, usd' = ``` + + SUM('Закупки'[Закуп.Закупка, usd]) + + SUM('Закупки'[Закуп.Таможня, usd]) + + SUM('Закупки'[Закуп.Доставка, usd]) + + SUM('Закупки'[Закуп.НДС, usd]) + + SUM('Закупки'[Закуп.Производство, usd]) - + SUM('Закупки'[Закуп.Доп расходы, usd]) + ``` + formatString: #,0 + + measure 'Цена учетная по закупкам, руб' = ``` + + + SUMX('Номенклатура', + DIVIDE( + [Сумма закупки, руб], + SUM('Закупки'[Кол-во закупка, шт]), 0 + + ) + ) + + ``` + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column Период + isHidden + formatString: General Date + summarizeBy: none + isNameInferred + sourceColumn: [Период] + + annotation SummarizationSetBy = Automatic + + column artic_id + isHidden + summarizeBy: none + isNameInferred + sourceColumn: [artic_id] + + annotation SummarizationSetBy = Automatic + + column Организация + isHidden + summarizeBy: none + isNameInferred + sourceColumn: [Организация] + + annotation SummarizationSetBy = Automatic + + column Контрагент + summarizeBy: none + isNameInferred + sourceColumn: [Контрагент] + + annotation SummarizationSetBy = Automatic + + column Менеджер + summarizeBy: none + isNameInferred + sourceColumn: [Менеджер] + + annotation SummarizationSetBy = Automatic + + column 'Закуп.Закупка, руб' + formatString: #,0 + displayFolder: Учет закупка + summarizeBy: sum + isNameInferred + sourceColumn: [Закуп.Закупка, руб] + + annotation SummarizationSetBy = Automatic + + column 'Закуп.Закупка, usd' + formatString: #,0 + displayFolder: Учет закупка + summarizeBy: sum + isNameInferred + sourceColumn: [Закуп.Закупка, usd] + + annotation SummarizationSetBy = Automatic + + column 'Валюта документа' + summarizeBy: none + isNameInferred + sourceColumn: [Валюта документа] + + annotation SummarizationSetBy = Automatic + + column 'Закуп.Доставка, руб' + formatString: #,0 + displayFolder: Учет закупка + summarizeBy: sum + isNameInferred + sourceColumn: [Закуп.Доставка, руб] + + annotation SummarizationSetBy = Automatic + + column 'Закуп.Доставка, usd' + formatString: #,0 + displayFolder: Учет закупка + summarizeBy: sum + isNameInferred + sourceColumn: [Закуп.Доставка, usd] + + annotation SummarizationSetBy = Automatic + + column 'Закуп.Таможня, руб' + formatString: #,0 + displayFolder: Учет закупка + summarizeBy: sum + isNameInferred + sourceColumn: [Закуп.Таможня, руб] + + annotation SummarizationSetBy = Automatic + + column 'Закуп.Таможня, usd' + formatString: #,0 + displayFolder: Учет закупка + summarizeBy: sum + isNameInferred + sourceColumn: [Закуп.Таможня, usd] + + annotation SummarizationSetBy = Automatic + + column 'Закуп.НДС, руб' + formatString: #,0 + displayFolder: Учет закупка + summarizeBy: sum + isNameInferred + sourceColumn: [Закуп.НДС, руб] + + annotation SummarizationSetBy = Automatic + + column 'Закуп.НДС, usd' + formatString: #,0 + displayFolder: Учет закупка + summarizeBy: sum + isNameInferred + sourceColumn: [Закуп.НДС, usd] + + annotation SummarizationSetBy = Automatic + + column 'Закуп.Производство, руб' + formatString: #,0 + displayFolder: Учет закупка + summarizeBy: sum + isNameInferred + sourceColumn: [Закуп.Производство, руб] + + annotation SummarizationSetBy = Automatic + + column 'Закуп.Производство, usd' + formatString: #,0 + displayFolder: Учет закупка + summarizeBy: sum + isNameInferred + sourceColumn: [Закуп.Производство, usd] + + annotation SummarizationSetBy = Automatic + + column Статья + summarizeBy: none + isNameInferred + sourceColumn: [Статья] + + annotation SummarizationSetBy = Automatic + + column partner_id + summarizeBy: none + isNameInferred + sourceColumn: [partner_id] + + annotation SummarizationSetBy = Automatic + + column 'Закуп.Доп расходы, руб' + formatString: #,0 + displayFolder: Учет закупка + summarizeBy: sum + isNameInferred + sourceColumn: [Закуп.Доп расходы, руб] + + annotation SummarizationSetBy = Automatic + + column 'Закуп.Доп расходы, usd' + formatString: #,0 + displayFolder: Учет закупка + summarizeBy: sum + isNameInferred + sourceColumn: [Закуп.Доп расходы, usd] + + annotation SummarizationSetBy = Automatic + + column 'Кол-во закупка, шт' + formatString: #,0 + summarizeBy: sum + isNameInferred + sourceColumn: [Кол-во закупка, шт] + + annotation SummarizationSetBy = Automatic + + column 'Кол-во закупка, упак' + formatString: #,0 + summarizeBy: sum + isNameInferred + sourceColumn: [Кол-во закупка, упак] + + annotation SummarizationSetBy = Automatic + + partition Закупки = calculated + mode: import + source = ``` + + var tbl = FILTER( + 'Себестоимость', + 'Себестоимость'[Вид операции]="Приход" && ('Себестоимость'[Статья] = "Закупка" + || 'Себестоимость'[Статья] = "Ввод начальных остатков" || 'Себестоимость'[Статья] = "Производство товара" + || 'Себестоимость'[Статья] = "Доставка контейнера ВЭД" || 'Себестоимость'[Статья] = "НДС" || 'Себестоимость'[Статья] = "Доп расходы" || 'Себестоимость'[Статья] = "Оприходование излишков товара" + )) + return SELECTCOLUMNS(tbl + , "Период", 'Себестоимость'[Период] + , "artic_id", 'Себестоимость'[artic_id] + , "Кол-во закупка, шт", 'Себестоимость'[Количество] + , "Кол-во закупка, упак", 'Себестоимость'[КоличествоУпаковок] + , "Организация", 'Себестоимость'[Организация] + , "Контрагент", 'Себестоимость'[Контрагент] + , "Менеджер", 'Себестоимость'[Менеджер] + , "partner_id", 'Себестоимость'[PartnerId] + , "Валюта документа", 'Себестоимость'[Валюта документа] + , "Статья", 'Себестоимость'[Статья] + , "Закуп.Закупка, руб", 'Себестоимость'[Закупка] + , "Закуп.Закупка, usd", 'Себестоимость'[Закупка, usd2] + , "Закуп.Доставка, руб", 'Себестоимость'[Доставка] + , "Закуп.Доставка, usd", 'Себестоимость'[Доставка, usd] + , "Закуп.Таможня, руб", 'Себестоимость'[Таможня] + , "Закуп.Таможня, usd", 'Себестоимость'[Таможня, usd] + , "Закуп.НДС, руб", 'Себестоимость'[НДС] + , "Закуп.НДС, usd", 'Себестоимость'[НДС, usd] + , "Закуп.Производство, руб", 'Себестоимость'[Производство] + , "Закуп.Производство, usd", 'Себестоимость'[Производство, usd] + , "Закуп.Доп расходы, руб", 'Себестоимость'[Доп расходы] + , "Закуп.Доп расходы, usd", 'Себестоимость'[Доп расходы USD2+2] + ) + ``` + + annotation PBI_Id = ebfb73925d604adf81607d1026029df9 + diff --git a/analytics/pbi/model/report/Model/tables/Заявки на оплату.tmdl b/analytics/pbi/model/report/Model/tables/Заявки на оплату.tmdl new file mode 100644 index 0000000..906d7f5 --- /dev/null +++ b/analytics/pbi/model/report/Model/tables/Заявки на оплату.tmdl @@ -0,0 +1,110 @@ +table 'Заявки на оплату' + + column date + dataType: dateTime + isHidden + formatString: Long Date + summarizeBy: none + sourceColumn: date + + variation Изменение + isDefault + relationship: 8208f512-c8a9-47d1-b47c-2bce30b6b8f8 + defaultHierarchy: LocalDateTable_729bf6db-04e4-4a26-9dce-b3837667cb92.'Иерархия дат' + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + annotation UnderlyingDateTimeDataType = Date + + column 'Номер заявки' + dataType: string + summarizeBy: none + sourceColumn: Номер заявки + + annotation SummarizationSetBy = Automatic + + column Статус + dataType: string + summarizeBy: none + sourceColumn: Статус + + annotation SummarizationSetBy = Automatic + + column Сумма + dataType: double + summarizeBy: sum + sourceColumn: Сумма + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column 'Валюта документа' + dataType: string + summarizeBy: none + sourceColumn: Валюта документа + + annotation SummarizationSetBy = Automatic + + column partner_id + dataType: string + isHidden + summarizeBy: none + sourceColumn: partner_id + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column Партнер + dataType: string + summarizeBy: none + sourceColumn: Партнер + + annotation SummarizationSetBy = Automatic + + column Получатель + dataType: string + summarizeBy: none + sourceColumn: Получатель + + annotation SummarizationSetBy = Automatic + + column Комментарий + dataType: string + summarizeBy: none + sourceColumn: Комментарий + + annotation SummarizationSetBy = Automatic + + column 'Дата оплаты план' + dataType: dateTime + formatString: Long Date + summarizeBy: none + sourceColumn: Дата оплаты план + + annotation SummarizationSetBy = Automatic + + annotation UnderlyingDateTimeDataType = Date + + column 'Статья ДДС' + dataType: string + summarizeBy: none + sourceColumn: Статья ДДС + + annotation SummarizationSetBy = Automatic + + partition 'Заявки на оплату' = m + mode: import + source = + let + Источник = Sql.Database("prdsql", "mag_pbi"), + pbi_Заявки_на_оплату = Источник{[Schema="pbi",Item="Заявки_на_оплату"]}[Data], + #"Измененный тип" = Table.TransformColumnTypes(pbi_Заявки_на_оплату,{{"date", type date}, {"Дата оплаты план", type date}}) + in + #"Измененный тип" + + annotation PBI_ResultType = Table + diff --git a/analytics/pbi/model/report/Model/tables/Менеджеры.tmdl b/analytics/pbi/model/report/Model/tables/Менеджеры.tmdl new file mode 100644 index 0000000..e329d7d --- /dev/null +++ b/analytics/pbi/model/report/Model/tables/Менеджеры.tmdl @@ -0,0 +1,49 @@ +table Менеджеры + + column user_id + dataType: string + isHidden + summarizeBy: none + sourceColumn: user_id + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column Менеджер + dataType: string + summarizeBy: none + sourceColumn: Менеджер + + annotation SummarizationSetBy = Automatic + + column Подразделение + dataType: string + summarizeBy: none + sourceColumn: Подразделение + + annotation SummarizationSetBy = Automatic + + column 'Вышестоящее подразделение' + dataType: string + summarizeBy: none + sourceColumn: Вышестоящее подразделение + + annotation SummarizationSetBy = Automatic + + partition Менеджеры = m + mode: import + source = + let + Источник = Sql.Database("prdsql", "mag_pbi"), + pbi_users_1C = Источник{[Schema="pbi",Item="users_1C"]}[Data], + #"Переименованные столбцы" = Table.RenameColumns(pbi_users_1C,{{"podr", "Подразделение"}, {"user", "Менеджер"}}), + #"Строки с примененным фильтром" = Table.SelectRows(#"Переименованные столбцы", each ([Подразделение] = "<Подразделение по умолчанию>" or [Подразделение] = "Cash&Carry" or [Подразделение] = "Бухгалтерия" or [Подразделение] = "Дедовск2" or [Подразделение] = "Маркетплейс" or [Подразделение] = "МРК" or [Подразделение] = "Операторы" or [Подразделение] = "Оптовый отдел" or [Подразделение] = "Отдел закупок" or [Подразделение] = "Отдел продаж" or [Подразделение] = "Региональный отдел" or [Подразделение] = "Сельскохозяйственная")), + #"Переименованные столбцы1" = Table.RenameColumns(#"Строки с примененным фильтром",{{"higher_podr", "Вышестоящее подразделение"}}) + in + #"Переименованные столбцы1" + + annotation PBI_ResultType = Table + + annotation PBI_NavigationStepName = Навигация + diff --git a/analytics/pbi/model/report/Model/tables/Номенклатура.tmdl b/analytics/pbi/model/report/Model/tables/Номенклатура.tmdl new file mode 100644 index 0000000..84b0d65 --- /dev/null +++ b/analytics/pbi/model/report/Model/tables/Номенклатура.tmdl @@ -0,0 +1,1174 @@ +table Номенклатура + + measure Объем = ``` + sumx('Номенклатура', DIVIDE( 'Основной отчет'[Остаток - МП конец, шт],'Номенклатура'[Знаменатель объема],0)*'Номенклатура'[Числитель объема]) + ``` + displayFolder: Измерения + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + measure 'Ср. цена учетная, руб' = + + CALCULATE( + DIVIDE( + 'Основной отчет'[Сумма учетная, руб], + 'Основной отчет'[Количество продаж, шт] + ), + FILTER('.Календарь', '.Календарь'[Дата] > TODAY()-365) + ) + displayFolder: Аналитика + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + measure 'Дней с первой продажи' = ``` + + DATEDIFF( + CALCULATE( + MIN('Себестоимость'[Период]), + FILTER( + 'Себестоимость', + 'Себестоимость'[Вид операции] = "Расход" && + 'Себестоимость'[Статья] = "Реализация" + ) + ), + TODAY(), + DAY + ) + + ``` + formatString: 0 + displayFolder: Аналитика + + measure 'Упущ. сумма продаж, руб' = + + CALCULATE( + SUMX('Номенклатура', [_Упущ. продажи, руб]) + ) + formatString: #,0 + displayFolder: Аналитика + + annotation PBI_FormatHint = {"isDecimal":true} + + measure 'Упущ. сумма продаж, USD' = SUMX('Номенклатура', [_Упущ. продажи, USD]) + displayFolder: Аналитика + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + measure 'Отчет продажи упак/день' = ``` + CALCULATE( + DIVIDE( + 'Основной отчет'[Количество продаж, упак], + SUM('Упущенные продажи'[Дней в продаже]), 0 + ), + FILTER('.Календарь', '.Календарь'[Дата] > TODAY() - 365 + )) + ``` + displayFolder: Аналитика + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + measure 'Отчет ТН руб/день за 365 дней' = ``` + + CALCULATE( + DIVIDE('Основной отчет'[Торг. надбавка, руб], SUM('Упущенные продажи'[Дней в продаже]), 0), + FILTER('.Календарь', '.Календарь'[Дата] > /* DATE(2023,01,01)*/ TODAY() - 365 ) + ) + ``` + displayFolder: Аналитика + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + measure 'Дней в продаже' = + + CALCULATE( + SUM('Упущенные продажи'[Дней в продаже]) + ) + formatString: #,0 + displayFolder: Аналитика + + annotation PBI_FormatHint = {"isDecimal":true} + + measure 'Дней отсутствия в продаже' = SUM('Упущенные продажи'[Дней отсутствия в продаже]) + formatString: #,0 + displayFolder: Аналитика + + measure 'Рентабельность -70р за упак за год' = ``` + + CALCULATE( + DIVIDE( + 'Основной отчет'[Торг. надбавка - 70р за упак, руб], + SUM([Остаток МАКС год, руб]) + ) + , + FILTER( + ALL('.Календарь'), + '.Календарь'[Дата]>TODAY() - 365 + ) + ) + ``` + isHidden + displayFolder: Аналитика + + changedProperty = IsHidden + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + measure Рекомендация = + + VAR logistic = 120 + VAR ostatokP = SUM('Номенклатура'[Остаток дней продаж потенциальный + согласование]) + RETURN + SWITCH( + TRUE(), + ostatokP < logistic, "1. Меньше 120 дней", + ostatokP < 2 * logistic, "2. Продаем", + ostatokP < 3 * logistic, "3. Больше 240 дней", + "4. Больше 360 дней" + ) + displayFolder: Аналитика + + measure 'Вес заказов' = ``` + + SUMX( + FILTER( + 'Себестоимость', + 'Себестоимость'[Вид операции] = "Расход" && + 'Себестоимость'[Статья] = "Реализация" + ), + 'Себестоимость'[Количество] * + DIVIDE( + COALESCE(RELATED('Номенклатура'[Числитель веса]), 0), + COALESCE(RELATED('Номенклатура'[Знаменатель веса]), 1) + ) + ) + + ``` + displayFolder: Аналитика + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + measure 'Объем заказов' = ``` + + SUMX( + FILTER( + 'Себестоимость', + 'Себестоимость'[Вид операции] = "Расход" && + 'Себестоимость'[Статья] = "Реализация" + ), + 'Себестоимость'[Количество] * + DIVIDE( + COALESCE(RELATED('Номенклатура'[Числитель объема]), 0), + COALESCE(RELATED('Номенклатура'[Знаменатель объема]), 1) + ) + ) + + ``` + displayFolder: Аналитика + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + measure 'Остаток дней продаж потенциальный' = ``` + + CALCULATE( + DIVIDE( + 'Основной отчет'[Остаток потенциальный, упак], + 'Номенклатура'[Отчет продажи упак/день] + ), ALL('.Календарь'[Дата]) + ) + ``` + formatString: #,0 + isHidden + displayFolder: Аналитика + + changedProperty = IsHidden + + measure 'ТН за квартал' = + + CALCULATE( + 'Основной отчет'[Торг. надбавка, руб] + , + FILTER( + ALL('.Календарь'), + '.Календарь'[Дата]>TODAY() - 90 + ) + ) + formatString: #,0 + displayFolder: Аналитика + + annotation PBI_FormatHint = {"isDecimal":true} + + measure 'ТН за год' = + + CALCULATE( + 'Основной отчет'[Торг. надбавка, руб] + , + FILTER( + ALL('.Календарь'), + '.Календарь'[Дата]>TODAY() - 365 + ) + ) + formatString: #,0 + displayFolder: Аналитика + + annotation PBI_FormatHint = {"isDecimal":true} + + measure 'Коэффициент вариации' = DIVIDE(SUM('Номенклатура'[СКО месячных продаж, упак]), SUM('Номенклатура'[Средние месячные продажи, упак])) + displayFolder: Статистика + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + measure 'Ср. цена продажи упак, руб x 1000' = + + CALCULATE( + DIVIDE( + 'Основной отчет'[Сумма продаж + МП + РК, руб] * 1000, + 'Основной отчет'[Количество продаж, упак] + ), + FILTER('.Календарь', '.Календарь'[Дата] > TODAY()-365) + ) + formatString: #,0 + displayFolder: Аналитика + + measure 'Ср. цена учетная упак, руб x 1000' = + + CALCULATE( + DIVIDE( + 'Основной отчет'[Сумма учетная, руб] * 1000, + 'Основной отчет'[Количество продаж, упак] + ), + FILTER('.Календарь', '.Календарь'[Дата] > TODAY()-365) + ) + formatString: #,0 + displayFolder: Аналитика + + column _artic_id + dataType: string + isHidden + summarizeBy: none + sourceColumn: _artic_id + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column 'Код УТ' + dataType: string + displayFolder: Описание + summarizeBy: none + sourceColumn: Код УТ + + annotation SummarizationSetBy = Automatic + + column Наименование + dataType: string + displayFolder: Описание + summarizeBy: none + sourceColumn: Наименование + + annotation SummarizationSetBy = Automatic + + column Артикул + dataType: string + displayFolder: Описание + summarizeBy: none + sourceColumn: Артикул + + annotation SummarizationSetBy = Automatic + + column _group_id + dataType: string + isHidden + summarizeBy: none + sourceColumn: _group_id + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column 'Ценовая группа' + dataType: string + displayFolder: Свойства + summarizeBy: none + sourceColumn: Ценовая группа + + annotation SummarizationSetBy = Automatic + + column Производитель + dataType: string + displayFolder: Свойства + summarizeBy: none + sourceColumn: Производитель + + annotation SummarizationSetBy = Automatic + + column Фото + dataType: string + displayFolder: Описание + dataCategory: ImageUrl + summarizeBy: none + sourceColumn: Фото + + annotation SummarizationSetBy = Automatic + + column 'Менеджер по закупкам' + dataType: string + displayFolder: Менеджеры + summarizeBy: none + sourceColumn: Менеджер по закупкам + + annotation SummarizationSetBy = Automatic + + column РуководительНаправления + dataType: string + displayFolder: Менеджеры + summarizeBy: none + sourceColumn: РуководительНаправления + + annotation SummarizationSetBy = Automatic + + column 'Базовая упаковка' + dataType: double + formatString: #,0 + displayFolder: Описание + summarizeBy: sum + sourceColumn: Базовая упаковка + + annotation SummarizationSetBy = Automatic + + column 'ABC статус 12м' + dataType: string + displayFolder: Статусы + summarizeBy: none + sourceColumn: ABC статус 12м + + annotation SummarizationSetBy = Automatic + + column Статус + dataType: string + displayFolder: Статусы + summarizeBy: none + sourceColumn: Статус + + annotation SummarizationSetBy = Automatic + + column Коллекция + dataType: string + displayFolder: Свойства + summarizeBy: none + sourceColumn: Коллекция + + annotation SummarizationSetBy = Automatic + + column Бренд + dataType: string + displayFolder: Свойства + summarizeBy: none + sourceColumn: Бренд + + annotation SummarizationSetBy = Automatic + + column 'Знаменатель веса' + dataType: double + displayFolder: Измерения + summarizeBy: sum + sourceColumn: Знаменатель веса + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column 'Числитель веса' + dataType: double + displayFolder: Измерения + summarizeBy: sum + sourceColumn: Числитель веса + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column 'Знаменатель объема' + dataType: double + displayFolder: Измерения + summarizeBy: sum + sourceColumn: Знаменатель объема + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column 'Числитель объема' + dataType: double + displayFolder: Измерения + summarizeBy: sum + sourceColumn: Числитель объема + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column 'Вид номенклатуры' + dataType: string + displayFolder: Описание + summarizeBy: none + sourceColumn: Вид номенклатуры + + annotation SummarizationSetBy = Automatic + + column 'Сквозной цвет' + dataType: string + displayFolder: Свойства + summarizeBy: none + sourceColumn: Сквозной цвет + + annotation SummarizationSetBy = Automatic + + column Метка + dataType: string + displayFolder: Свойства + summarizeBy: none + sourceColumn: Метка + + annotation SummarizationSetBy = Automatic + + column 'Ширина, мм' + dataType: string + displayFolder: Свойства + summarizeBy: none + sourceColumn: Ширина, мм + + annotation SummarizationSetBy = Automatic + + column Цвет + dataType: string + displayFolder: Свойства + summarizeBy: none + sourceColumn: Цвет + + annotation SummarizationSetBy = Automatic + + column Ширина + dataType: string + displayFolder: Свойства + summarizeBy: none + sourceColumn: Ширина + + annotation SummarizationSetBy = Automatic + + column 'Формат упаковки' + dataType: string + displayFolder: Свойства + summarizeBy: none + sourceColumn: Формат упаковки + + annotation SummarizationSetBy = Automatic + + column 'маркеты.WB' + dataType: string + displayFolder: Маркеты + summarizeBy: none + sourceColumn: маркеты.WB + + annotation SummarizationSetBy = Automatic + + column 'маркеты.СТМ' + dataType: string + displayFolder: Маркеты + summarizeBy: none + sourceColumn: маркеты.СТМ + + annotation SummarizationSetBy = Automatic + + column 'маркеты.Выгружать на я.маркет' + dataType: string + displayFolder: Маркеты + summarizeBy: none + sourceColumn: маркеты.Выгружать на я.маркет + + annotation SummarizationSetBy = Automatic + + column 'маркеты.Выгружать в Google Merchant' + dataType: string + displayFolder: Маркеты + summarizeBy: none + sourceColumn: маркеты.Выгружать в Google Merchant + + annotation SummarizationSetBy = Automatic + + column 'Товарный менеджер' + dataType: string + displayFolder: Менеджеры + summarizeBy: none + sourceColumn: Товарный менеджер + + annotation SummarizationSetBy = Automatic + + column 'Номер цвета' + dataType: string + displayFolder: Свойства + summarizeBy: none + sourceColumn: Номер цвета + + annotation SummarizationSetBy = Automatic + + column 'Да/Нет Собственное пр-во' + dataType: string + displayFolder: Свойства + summarizeBy: none + sourceColumn: Да/Нет Собственное пр-во + + annotation SummarizationSetBy = Automatic + + column 'Менеджер OZON' + dataType: string + displayFolder: Менеджеры + summarizeBy: none + sourceColumn: Менеджер OZON + + annotation SummarizationSetBy = Automatic + + column 'Менеджер WB' + dataType: string + displayFolder: Менеджеры + summarizeBy: none + sourceColumn: Менеджер WB + + annotation SummarizationSetBy = Automatic + + column 'Макс. запас' + dataType: int64 + formatString: #,0 + displayFolder: Измерения + summarizeBy: sum + sourceColumn: Макс. запас + + annotation SummarizationSetBy = Automatic + + column 'Мин. запас' + dataType: int64 + formatString: #,0 + displayFolder: Измерения + summarizeBy: sum + sourceColumn: Мин. запас + + annotation SummarizationSetBy = Automatic + + column 'Товар МП' + dataType: string + displayFolder: Свойства + summarizeBy: none + sourceColumn: Товар МП + + annotation SummarizationSetBy = Automatic + + column 'Цена учетная последняя известная, руб' = ``` + + + VAR LastKnowDate = MAX('.Календарь'[Дата]) + + RETURN + CALCULATE( + [Цена учетная по закупкам, руб], + TOPN( + 1, + FILTER( + ALL('Закупки'), + 'Закупки'[Период] <= LastKnowDate && + 'Закупки'[artic_id] = 'Номенклатура'[_artic_id] + ), + 'Закупки'[Период], + DESC + ) + ) + ``` + isHidden + displayFolder: Свойства + summarizeBy: sum + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column 'ABC статус 3м' + dataType: string + displayFolder: Статусы + summarizeBy: none + sourceColumn: ABC статус 3м + + annotation SummarizationSetBy = Automatic + + column 'Ценовой сегмент Магок' + dataType: string + displayFolder: Свойства + summarizeBy: none + sourceColumn: Ценовой сегмент Магок + + annotation SummarizationSetBy = Automatic + + column 'Ценовой сегмент МП' + dataType: string + displayFolder: Свойства + summarizeBy: none + sourceColumn: Ценовой сегмент МП + + annotation SummarizationSetBy = Automatic + + column 'Кол-во упак в заказе Магок' + dataType: string + displayFolder: Свойства + summarizeBy: none + sourceColumn: Кол-во упак в заказе Магок + + annotation SummarizationSetBy = Automatic + + column 'Цена учетная последняя, руб' = ``` + + + VAR LastKnowDate = MAX('.Календарь'[Дата]) + + RETURN + CALCULATE( + DIVIDE([Сумма закупки, руб], + SUM('Закупки'[Кол-во закупка, шт]), 0 + ), + TOPN( + 1, + FILTER( + ALL('Закупки'), + 'Закупки'[Период] <= LastKnowDate && + 'Закупки'[artic_id] = 'Номенклатура'[_artic_id] + ), + 'Закупки'[Период], + DESC + ) + ) + ``` + isHidden + displayFolder: Свойства + summarizeBy: sum + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column 'Цена учетная последняя, usd' = ``` + + + VAR LastKnowDate = MAX('.Календарь'[Дата]) + + RETURN + CALCULATE( + DIVIDE([Сумма закупки, usd], + SUM('Закупки'[Кол-во закупка, шт]), 0 + ), + TOPN( + 1, + FILTER( + ALL('Закупки'), + 'Закупки'[Период] <= LastKnowDate && + 'Закупки'[artic_id] = 'Номенклатура'[_artic_id] + ), + 'Закупки'[Период], + DESC + ) + ) + ``` + isHidden + displayFolder: Свойства + summarizeBy: sum + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column 'Цена учетная, руб' + dataType: double + formatString: #,0.0000 + displayFolder: Свойства + summarizeBy: sum + sourceColumn: Цена учетная, руб + + annotation SummarizationSetBy = Automatic + + column 'Цена учетная, usd' + dataType: double + displayFolder: Свойства + summarizeBy: sum + sourceColumn: Цена учетная, usd + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column max_year_quantity + dataType: double + formatString: #,0 + displayFolder: Статистика + summarizeBy: sum + sourceColumn: max_year_quantity + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isDecimal":true} + + column max_quarter_quantity + dataType: double + formatString: #,0 + displayFolder: Статистика + summarizeBy: sum + sourceColumn: max_quarter_quantity + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isDecimal":true} + + column 'Остаток дней продаж потенциальный, дн' = ``` + + CALCULATE( + DIVIDE( + 'Основной отчет'[Остаток потенциальный, упак], + 'Номенклатура'[Отчет продажи упак/день] + ), ALL('.Календарь'[Дата]) + ) + ``` + formatString: #,0 + displayFolder: Аналитика + summarizeBy: sum + + annotation SummarizationSetBy = Automatic + + column 'Остаток дней продаж потенциальный + согласование' = ``` + + CALCULATE( + DIVIDE( + 'Основной отчет'[Остаток потенциальный + согласование, упак], + 'Номенклатура'[Отчет продажи упак/день] + ), ALL('.Календарь'[Дата]) + ) + ``` + formatString: #,0 + displayFolder: Аналитика + summarizeBy: sum + + annotation SummarizationSetBy = Automatic + + column 'Остаток дней продаж без остатка МП' = ``` + + CALCULATE( + DIVIDE( + 'Основной отчет'[Остаток потенциальный - МП, шт], + SUM('Номенклатура'[Продажи шт / день]) + ), + ALL('.Календарь'[Дата]) + ) + ``` + displayFolder: Аналитика + summarizeBy: sum + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column 'ID OZON' + dataType: string + displayFolder: Описание + summarizeBy: none + sourceColumn: ID OZON + + annotation SummarizationSetBy = Automatic + + column 'ID WB' + dataType: string + displayFolder: Описание + summarizeBy: none + sourceColumn: ID WB + + annotation SummarizationSetBy = Automatic + + column 'Средние месячные продажи, упак' + dataType: double + formatString: #,0 + displayFolder: Статистика + summarizeBy: sum + sourceColumn: Средние месячные продажи, упак + + annotation SummarizationSetBy = Automatic + + column 'СКО месячных продаж, упак' + dataType: double + formatString: #,0 + displayFolder: Статистика + summarizeBy: sum + sourceColumn: СКО месячных продаж, упак + + annotation SummarizationSetBy = Automatic + + column minAvailableQty + dataType: int64 + displayFolder: Статистика + summarizeBy: sum + sourceColumn: minAvailableQty + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column 'XYZ статус 12м' + dataType: string + displayFolder: Статусы + summarizeBy: none + sourceColumn: XYZ статус 12м + + annotation SummarizationSetBy = Automatic + + column 'Качество контента Ozon' + dataType: int64 + formatString: 0 + displayFolder: Описание + summarizeBy: sum + sourceColumn: Качество контента Ozon + + annotation SummarizationSetBy = Automatic + + column 'Качество контента WB' + dataType: int64 + formatString: 0 + displayFolder: Описание + summarizeBy: sum + sourceColumn: Качество контента WB + + annotation SummarizationSetBy = Automatic + + column 'Качество контента WB by Ozon' + dataType: int64 + formatString: 0 + displayFolder: Описание + summarizeBy: sum + sourceColumn: Качество контента WB by Ozon + + annotation SummarizationSetBy = Automatic + + column 'Качество контента Magok' + dataType: int64 + formatString: 0 + displayFolder: Описание + summarizeBy: sum + sourceColumn: Качество контента Magok + + annotation SummarizationSetBy = Automatic + + column Неликвид + dataType: string + displayFolder: Статусы + summarizeBy: none + sourceColumn: Неликвид + + annotation SummarizationSetBy = Automatic + + column 'маркеты.Ozon' + dataType: string + displayFolder: Маркеты + summarizeBy: none + sourceColumn: маркеты.Ozon + + annotation SummarizationSetBy = Automatic + + column Размер + dataType: string + displayFolder: Свойства + summarizeBy: none + sourceColumn: Размер + + annotation SummarizationSetBy = Automatic + + column Особенность + dataType: string + displayFolder: Свойства + summarizeBy: none + sourceColumn: Особенность + + annotation SummarizationSetBy = Automatic + + column Форма + dataType: string + displayFolder: Свойства + summarizeBy: none + sourceColumn: Форма + + annotation SummarizationSetBy = Automatic + + column 'ABC Парето' + dataType: string + displayFolder: Статусы + summarizeBy: none + sourceColumn: ABC Парето + + annotation SummarizationSetBy = Automatic + + column 'Тип товара' + dataType: string + displayFolder: Описание + summarizeBy: none + sourceColumn: Тип товара + + annotation SummarizationSetBy = Automatic + + column 'QTY PACKS' + dataType: string + displayFolder: Измерения + summarizeBy: none + sourceColumn: QTY PACKS + + annotation SummarizationSetBy = Automatic + + column 'Количество упак в коробе' + dataType: double + displayFolder: Измерения + summarizeBy: sum + sourceColumn: Количество упак в коробе + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column 'Количество упак в кванте' + dataType: double + displayFolder: Измерения + summarizeBy: sum + sourceColumn: Количество упак в кванте + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column 'Продано шт' + dataType: double + displayFolder: Аналитика + summarizeBy: sum + sourceColumn: Продано шт + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column 'Продажи шт / день' + dataType: double + displayFolder: Аналитика + summarizeBy: sum + sourceColumn: Продажи шт / день + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column 'Остаток дней продаж' + dataType: double + displayFolder: Аналитика + summarizeBy: sum + sourceColumn: Остаток дней продаж + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column 'Продажи / год, руб.' + dataType: double + displayFolder: Аналитика + summarizeBy: sum + sourceColumn: Продажи / год, руб. + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column 'учетная сумма / год, руб.' + dataType: double + displayFolder: Аналитика + summarizeBy: sum + sourceColumn: учетная сумма / год, руб. + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column 'ТН / год, руб.' + dataType: double + displayFolder: Аналитика + summarizeBy: sum + sourceColumn: ТН / год, руб. + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column 'Стоимость МП год, руб.' + dataType: double + displayFolder: Аналитика + summarizeBy: sum + sourceColumn: Стоимость МП год, руб. + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column '%ТН год, руб.' + dataType: double + displayFolder: Аналитика + summarizeBy: sum + sourceColumn: %ТН год, руб. + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column 'Дней в продаже / год' + dataType: int64 + formatString: 0 + displayFolder: Аналитика + summarizeBy: sum + sourceColumn: Дней в продаже / год + + annotation SummarizationSetBy = Automatic + + column 'Дней в продаже / квартал' + dataType: int64 + formatString: 0 + displayFolder: Аналитика + summarizeBy: sum + sourceColumn: Дней в продаже / квартал + + annotation SummarizationSetBy = Automatic + + column 'Продажи / квартал, руб.' + dataType: double + displayFolder: Аналитика + summarizeBy: sum + sourceColumn: Продажи / квартал, руб. + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column 'учетная сумма / квартал, руб.' + dataType: double + displayFolder: Аналитика + summarizeBy: sum + sourceColumn: учетная сумма / квартал, руб. + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column 'ТН / квартал, руб.' + dataType: double + displayFolder: Аналитика + summarizeBy: sum + sourceColumn: ТН / квартал, руб. + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column 'ТН / месяц, руб.' + dataType: double + displayFolder: Аналитика + summarizeBy: sum + sourceColumn: ТН / месяц, руб. + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column 'Оплаченный остаток' + dataType: double + displayFolder: Аналитика + summarizeBy: sum + sourceColumn: Оплаченный остаток + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column 'Рентабельность / год' + dataType: double + displayFolder: Аналитика + summarizeBy: sum + sourceColumn: Рентабельность / год + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column 'Рентабельность / квартал' + dataType: double + displayFolder: Аналитика + summarizeBy: sum + sourceColumn: Рентабельность / квартал + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column 'Рентабельность / будущий год' + dataType: double + displayFolder: Аналитика + summarizeBy: sum + sourceColumn: Рентабельность / будущий год + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + partition Номенклатура-6a1affcd-7af8-46ea-9676-cf8ac08c58c1 = m + mode: import + source = ``` + let + Источник = Sql.Databases("prdsql"), + mag_pbi = Источник{[Name="mag_pbi"]}[Data], + pbi_nomenclature = mag_pbi{[Schema="pbi",Item="nomeclature_for_pbi"]}[Data], + + + //sales_w_nomenclature = Источник{[Schema="sales",Item="w_nomenclature"]}[Data], + #"Переименованные столбцы" = Table.RenameColumns(pbi_nomenclature,{{"description", "Наименование"}, {"artic", "Артикул"}, {"artic_id", "_artic_id"}, {"group_id", "_group_id"}, {"cenovaya_gruppa", "Ценовая группа"}, {"photo", "Фото"}, {"card", "Ссылка на карточку товара"}/*, {"продажи упаковки в день", "скорость упак в день"}, {"продажи штуки в день", "норма продаж шт в день"}*/}), + //#"Измененный тип" = Table.TransformColumnTypes(#"Переименованные столбцы",{{"норма продаж шт в день", type number}}), + #"Переименованные столбцы1" = Table.RenameColumns(#"Переименованные столбцы",{{"Ozon", "маркеты.Ozon"}, {"WB", "маркеты.WB"}, {"Выгружать на я.маркет", "маркеты.Выгружать на я.маркет"}, {"СТМ", "маркеты.СТМ"}, {"Выгружать в Google Merchant", "маркеты.Выгружать в Google Merchant"}}), + #"Удаленные столбцы" = Table.RemoveColumns(#"Переименованные столбцы1",{"base"}), + #"Замененное значение" = Table.ReplaceValue(#"Удаленные столбцы","1","Да",Replacer.ReplaceText,{"Да/Нет Собственное пр-во"}), + #"Замененное значение1" = Table.ReplaceValue(#"Замененное значение","0","Нет",Replacer.ReplaceText,{"Да/Нет Собственное пр-во"}), + #"Замененное значение2" = Table.ReplaceValue(#"Замененное значение1",null,"Нет",Replacer.ReplaceValue,{"Да/Нет Собственное пр-во"}), + //*#"Переименованные столбцы2" = Table.RenameColumns(#"Замененное значение2",{{"Наполнитель", "XYZ статус"}}), + #"Замененное значение3" = Table.ReplaceValue(#"Замененное значение2","",null,Replacer.ReplaceValue,{"Менеджер OZON"}), + #"Замененное значение4" = Table.ReplaceValue(#"Замененное значение3","",null,Replacer.ReplaceValue,{"Менеджер WB"}), + #"Замененное значение5" = Table.ReplaceValue(#"Замененное значение4",".",",",Replacer.ReplaceText,{"Мин. запас"}), + #"Измененный тип" = Table.TransformColumnTypes(#"Замененное значение5",{{"Мин. запас", Int64.Type}}), + #"Замененное значение6" = Table.ReplaceValue(#"Измененный тип",".",",",Replacer.ReplaceText,{"Макс. запас"}), + #"Измененный тип1" = Table.TransformColumnTypes(#"Замененное значение6",{{"Макс. запас", Int64.Type}}), + #"Замененное значение7" = Table.ReplaceValue(#"Измененный тип1","0",null,Replacer.ReplaceValue,{"Товар МП"}), + #"Замененное значение8" = Table.ReplaceValue(#"Замененное значение7","1","Да",Replacer.ReplaceText,{"Товар МП"}), + #"Переименованные столбцы3" = Table.RenameColumns(#"Замененное значение8",{{"МенеджерПоЗакупкам2", "Менеджер по закупкам"}, {"Товарныйменеджера", "Товарный менеджер"}}), + #"Удаленные столбцы1" = Table.RemoveColumns(#"Переименованные столбцы3",{"Тип плетения", "Тип шнура"}), + #"Переименованные столбцы4" = Table.RenameColumns(#"Удаленные столбцы1",{{"АБС статус", "ABC статус 12м"}, {"АБС план", "ABC статус 3м"}}), + #"Удаленные столбцы2" = Table.RemoveColumns(#"Переименованные столбцы4",{"Ссылка на карточку товара", "id magok"}), + #"Переименованные столбцы5" = Table.RenameColumns(#"Удаленные столбцы2",{{"СКО_МесячныхПродаж", "СКО месячных продаж, упак"}, {"СредниеМесячныеПродажи", "Средние месячные продажи, упак"}}), + #"Измененный тип2" = Table.TransformColumnTypes(#"Переименованные столбцы5",{{"minAvailableQty", Int64.Type}}), + #"Замененное значение9" = Table.ReplaceValue(#"Измененный тип2","0",null,Replacer.ReplaceValue,{"Неликвид"}), + #"Переименованные столбцы2" = Table.RenameColumns(#"Замененное значение9",{{"code", "Код УТ"}}), + #"Удаленные столбцы3" = Table.RemoveColumns(#"Переименованные столбцы2",{"Комментарий для матрицы"}) + + + in + #"Удаленные столбцы3" + ``` + + annotation PBI_QueryRelationships = {"columnCount":29,"keyColumnNames":[],"queryRelationships":[],"columnIdentities":["Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{artic_id,0}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{1c_id,1}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{code,2}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{cenovaya_gruppa,3}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{description,4}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{artic,5}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{vid_nomen,6}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{Производитель,7}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{group_id,8}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{1c_group,9}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{manager,10}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{ТоварныйМенеджера,11}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{МенеджерПоЗакупкам2,12}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{РуководительНаправления,13}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{АБС статус,14}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{Базовая упаковка,15}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{card,16}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{photo,17}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{base,18}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{недель в продаже,19}","Section1/Номенклатура/Измененный тип.{норма продаж шт в день,20}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{продажи упаковки в день,21}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{всего продано шт,22}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{всего продано упаковок,23}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{начало продаж,24}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{ср. кв. откл.,25}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{остаток продаж дн,26}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{норм. кв. откл.75,27}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{норм. кв. откл.90,28}"],"ColumnCount":29,"KeyColumnNames":[],"ColumnIdentities":["Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{artic_id,0}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{1c_id,1}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{code,2}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{cenovaya_gruppa,3}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{description,4}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{artic,5}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{vid_nomen,6}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{Производитель,7}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{group_id,8}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{1c_group,9}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{manager,10}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{ТоварныйМенеджера,11}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{МенеджерПоЗакупкам2,12}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{РуководительНаправления,13}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{АБС статус,14}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{Базовая упаковка,15}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{card,16}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{photo,17}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{base,18}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{недель в продаже,19}","Section1/Номенклатура/Измененный тип.{норма продаж шт в день,20}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{продажи упаковки в день,21}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{всего продано шт,22}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{всего продано упаковок,23}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{начало продаж,24}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{ср. кв. откл.,25}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{остаток продаж дн,26}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{норм. кв. откл.75,27}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_nomenclature.{норм. кв. откл.90,28}"],"RelationshipInfo":[]} + + annotation PBI_ResultType = Exception + + annotation PBI_NavigationStepName = Навигация + diff --git a/analytics/pbi/model/report/Model/tables/Организация.tmdl b/analytics/pbi/model/report/Model/tables/Организация.tmdl new file mode 100644 index 0000000..b9d8760 --- /dev/null +++ b/analytics/pbi/model/report/Model/tables/Организация.tmdl @@ -0,0 +1,15 @@ +table Организация + + column Организация + summarizeBy: none + isNameInferred + sourceColumn: Себестоимость[Организация] + + annotation SummarizationSetBy = Automatic + + partition Организация = calculated + mode: import + source = VALUES('Себестоимость'[Организация]) + + annotation PBI_Id = edae5abbb56b4e8dba63758043b0a407 + diff --git a/analytics/pbi/model/report/Model/tables/Основной отчет.tmdl b/analytics/pbi/model/report/Model/tables/Основной отчет.tmdl new file mode 100644 index 0000000..fe6556c --- /dev/null +++ b/analytics/pbi/model/report/Model/tables/Основной отчет.tmdl @@ -0,0 +1,1436 @@ +table 'Основной отчет' + + measure 'Сумма продаж + РК, руб' = ``` + + CALCULATE( + SUMX( + FILTER('Себестоимость','Себестоимость'[Вид операции]="Расход" && 'Себестоимость'[Статья]="Реализация"), + 'Себестоимость'[Сумма plus МП, руб]) - SUM('Стоимость МП'[Расходы МП, руб] + ) * (1 + 'Параметр цена продажи, %'[Значение Параметр цена продажи, %] / 100) + ) + ``` + formatString: #,0 + + annotation PBI_FormatHint = {"isDecimal":true} + + measure 'Сумма учетная, руб' = + CALCULATE( + SUM('Себестоимость'[Учетная сумма, руб]) - SUM('Себестоимость'[Доп расходы]) + , FILTER('Себестоимость','Себестоимость'[Вид операции]="Расход" && 'Себестоимость'[Статья]="Реализация") + ) + [Учет.Списание товара, руб] + formatString: #,0 + + measure 'Учет.Закупка, руб' = ``` + + CALCULATE( + -1 * ( + SUM('Себестоимость'[Закупка] ) + ) + , FILTER('Себестоимость','Себестоимость'[Вид операции]="Расход" && 'Себестоимость'[Статья]="Реализация") + ) + ``` + formatString: #,0 + displayFolder: Учет + + annotation PBI_FormatHint = {"isDecimal":true} + + measure 'Учет.НДС, руб' = ``` + + CALCULATE( + -1 * ( + SUM('Себестоимость'[НДС]) + ) + , FILTER('Себестоимость','Себестоимость'[Вид операции]="Расход" && 'Себестоимость'[Статья]="Реализация") + ) + ``` + formatString: #,0 + displayFolder: Учет + + annotation PBI_FormatHint = {"isDecimal":true} + + measure 'Учет.Таможня, руб' = ``` + + CALCULATE( + -1 * ( + SUM('Себестоимость'[Таможня]) + ) + , FILTER('Себестоимость','Себестоимость'[Вид операции]="Расход" && 'Себестоимость'[Статья]="Реализация") + ) + ``` + formatString: #,0 + displayFolder: Учет + + annotation PBI_FormatHint = {"isDecimal":true} + + measure 'Учет.Доставка, руб' = ``` + + CALCULATE( + -1 * ( + SUM('Себестоимость'[Доставка]) + ) + , FILTER('Себестоимость','Себестоимость'[Вид операции]="Расход" && 'Себестоимость'[Статья]="Реализация") + ) + ``` + formatString: #,0 + displayFolder: Учет + + annotation PBI_FormatHint = {"isDecimal":true} + + measure 'Сборка в другие товары, руб' = ``` + + CALCULATE( + -1 * ( + SUM('Себестоимость'[Закупка]) + ) + , FILTER('Себестоимость','Себестоимость'[Вид операции]="Расход" && 'Себестоимость'[Статья]="Производство товара" ) + ) + ``` + formatString: #,0 + + annotation PBI_FormatHint = {"isDecimal":true} + + measure 'Сумма продаж + РК, usd' = ``` + + CALCULATE( + SUMX( + FILTER('Себестоимость','Себестоимость'[Вид операции]="Расход" && 'Себестоимость'[Статья]="Реализация"), + 'Себестоимость'[Сумма plus МП, usd]) - SUM('Стоимость МП'[Расходы МП, usd] + ) * (1 + 'Параметр цена продажи, %'[Значение Параметр цена продажи, %] / 100) + ) + ``` + formatString: #,0 + + measure 'Сумма учетная, usd' = + CALCULATE( + SUM('Себестоимость'[Учетная сумма, usd]) - SUM('Себестоимость'[Доп расходы USD2+2]) + , FILTER('Себестоимость','Себестоимость'[Вид операции]="Расход" && 'Себестоимость'[Статья]="Реализация") + ) + [Учет.Списание товара, usd] + formatString: #,0 + + measure 'Учет.Закупка, usd' = ``` + + CALCULATE( + -1 * ( + SUM('Себестоимость'[Закупка, usd2] ) + ) + , FILTER('Себестоимость','Себестоимость'[Вид операции]="Расход" && 'Себестоимость'[Статья]="Реализация") + ) + ``` + formatString: #,0 + displayFolder: Учет + + annotation PBI_FormatHint = {"isDecimal":true} + + measure 'Учет.Доставка, usd' = ``` + + CALCULATE( + -1 * ( + SUM('Себестоимость'[Доставка, usd] ) + ) + , FILTER('Себестоимость','Себестоимость'[Вид операции]="Расход" && 'Себестоимость'[Статья]="Реализация") + ) + ``` + formatString: #,0 + displayFolder: Учет + + annotation PBI_FormatHint = {"isDecimal":true} + + measure 'Учет.НДС, usd' = ``` + + CALCULATE( + -1 * ( + SUM('Себестоимость'[НДС, usd] ) + ) + , FILTER('Себестоимость','Себестоимость'[Вид операции]="Расход" && 'Себестоимость'[Статья]="Реализация") + ) + ``` + formatString: #,0 + displayFolder: Учет + + annotation PBI_FormatHint = {"isDecimal":true} + + measure 'Учет.Таможня, usd' = ``` + + CALCULATE( + -1 * ( + SUM('Себестоимость'[Таможня, usd] ) + ) + , FILTER('Себестоимость','Себестоимость'[Вид операции]="Расход" && 'Себестоимость'[Статья]="Реализация") + ) + ``` + formatString: #,0 + displayFolder: Учет + + annotation PBI_FormatHint = {"isDecimal":true} + + measure 'Сборка в другие товары, usd' = ``` + + CALCULATE( + -1 * ( + SUM('Себестоимость'[Закупка, usd2] ) + ) + , FILTER('Себестоимость','Себестоимость'[Вид операции]="Расход" && 'Себестоимость'[Статья]="Производство товара" ) + ) + ``` + formatString: #,0 + + annotation PBI_FormatHint = {"isDecimal":true} + + measure 'Сборка из других товаров, руб' = ``` + + CALCULATE( + -1 * ( + SUM('Себестоимость'[Закупка]) + ) + , FILTER('Себестоимость','Себестоимость'[Вид операции]="Приход" && 'Себестоимость'[Статья]="Производство товара" ) + ) + ``` + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + measure 'Сборка из других товаров, usd' = ``` + + CALCULATE( + -1 * ( + SUM('Себестоимость'[Закупка, usd2]) + ) + , FILTER('Себестоимость','Себестоимость'[Вид операции]="Приход" && 'Себестоимость'[Статья]="Производство товара" ) + ) + ``` + formatString: #,0 + + annotation PBI_FormatHint = {"isDecimal":true} + + measure 'Сумма продаж + МП + РК, руб' = + CALCULATE( + SUM('Себестоимость'[Сумма plus МП, руб]), + FILTER('Себестоимость','Себестоимость'[Вид операции]="Расход" && 'Себестоимость'[Статья]="Реализация") + ) + formatString: #,0 + + measure 'Сумма продаж + МП + РК, usd' = + CALCULATE( + SUM('Себестоимость'[Сумма plus МП, usd]), + FILTER('Себестоимость','Себестоимость'[Вид операции]="Расход" && 'Себестоимость'[Статья]="Реализация") + ) + formatString: #,0 + + measure 'MAT скользящая годовая, руб' = ``` + + CALCULATE( + [Сумма продаж + РК, руб], + DATESINPERIOD( + '.Календарь'[Дата], + MAX('.Календарь'[Дата]), -1, YEAR + ) + ) + + ``` + formatString: #,0 + displayFolder: MAA, MAT, MTD, PY, YTD + + measure 'Торг. надбавка, руб' = ``` + + [Сумма продаж, руб] - [Сумма учетная, руб] + + ``` + formatString: #,0 + + measure 'Торг. надбавка, usd' = [Сумма продаж, usd] - [Сумма учетная, usd] + formatString: #,0 + + measure 'Торг. надбавка, руб, %' = + + DIVIDE( + [Торг. надбавка, руб], + [Сумма учетная, руб] + ) * 100 + formatString: #,0 + + annotation PBI_FormatHint = {"isDecimal":true} + + measure 'Торг. надбавка, usd, %' = + + DIVIDE( + [Торг. надбавка, usd], + [Сумма учетная, usd] + ) * 100 + formatString: #,0 + + annotation PBI_FormatHint = {"isDecimal":true} + + measure 'MAT скользящая годовая сегодня, руб' = ``` + + CALCULATE( + [Сумма продаж + РК, руб], + DATESINPERIOD( + '.Календарь'[Дата], + TODAY() - 1, -1, YEAR + ) + ) + + ``` + formatString: #,0 + displayFolder: MAA, MAT, MTD, PY, YTD + + measure 'MTD Сумма продаж с начала месяца, руб' = ``` + + IF ( + NOT ISBLANK([Сумма продаж + РК, руб]), + CALCULATE( + [Сумма продаж + РК, руб], + DATESMTD('.Календарь'[Дата]) + ) + ) + ``` + formatString: #,0 + displayFolder: MAA, MAT, MTD, PY, YTD + + measure 'MTD Сумма продаж с начала месяца, usd' = ``` + + IF ( + NOT ISBLANK([Сумма продаж + РК, usd]), + CALCULATE( + [Сумма продаж + РК, usd], + DATESMTD('.Календарь'[Дата]) + ) + ) + ``` + formatString: #,0 + displayFolder: MAA, MAT, MTD, PY, YTD + + measure 'MAA скользящая среднегодовая' = ``` + + CALCULATE ( + DIVIDE ( + [Сумма продаж + РК, руб], + DISTINCTCOUNT ( '.Календарь'[Дата].[Месяц] ) + ), + DATESINPERIOD ( + '.Календарь'[Дата], + MAX ('.Календарь'[Дата]), -1, YEAR) + ) + ``` + formatString: #,0 + displayFolder: MAA, MAT, MTD, PY, YTD + + measure 'PY Сумма продаж прошлый год, руб' = ``` + + CALCULATE( + [Сумма продаж + РК, руб], + SAMEPERIODLASTYEAR('.Календарь'[Дата]) + ) + ``` + formatString: #,0 + displayFolder: MAA, MAT, MTD, PY, YTD + + measure 'YTD Сумма продаж с начала года, руб' = ``` + + IF ( + NOT ISBLANK([Сумма продаж + РК, руб]), + CALCULATE( + [Сумма продаж + РК, руб], + DATESYTD('.Календарь'[Дата]) + ) + ) + ``` + formatString: #,0 + displayFolder: MAA, MAT, MTD, PY, YTD + + measure 'YTD Сумма продаж с начала года, usd' = ``` + + IF ( + NOT ISBLANK ([Сумма продаж + РК, usd]), + CALCULATE( + [Сумма продаж + РК, usd], + DATESYTD('.Календарь'[Дата]) + ) + ) + ``` + formatString: #,0 + displayFolder: MAA, MAT, MTD, PY, YTD + + measure 'Средний чек' = DIVIDE('Основной отчет'[Сумма продаж + РК, руб], DISTINCTCOUNTNOBLANK('Себестоимость'[Номер заказа]), 0) + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + measure 'Средний чек, usd' = DIVIDE('Основной отчет'[Сумма продаж + РК, usd], DISTINCTCOUNTNOBLANK('Себестоимость'[Номер заказа]), 0) + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + measure 'Остаток - МП начало, упак' = ``` + + CALCULATE( + SUM('Остатки'[upakovok]) + , REMOVEFILTERS('Остатки'[Дата]) + , REMOVEFILTERS('.Календарь'[Дата]) + , FILTER( + 'Остатки' + ,'Остатки'[Дата] "Виртуальный" + )) + + + /*CALCULATE( + SUM('Остатки'[upakovok]), + + FILTER(ALL('Остатки'[Дата]),'Остатки'[Дата] "Виртуальный" + ))*/ + ``` + formatString: #,0 + displayFolder: Остаток склад + + measure 'Остаток - МП конец, упак' = ``` + + CALCULATE( + SUM('Остатки'[upakovok]) + , REMOVEFILTERS('Остатки'[Дата]) + , REMOVEFILTERS('.Календарь'[Дата]) + , FILTER( + 'Остатки' + ,'Остатки'[Дата]<=SELECTEDVALUE('.Календарь'[Дата],MAX('.Календарь'[Дата])) + ) + , FILTER('Остатки', [Категория склада] <> "Виртуальный" + )) + + + + /*CALCULATE( + SUM('Остатки'[upakovok]), + FILTER('Остатки','Остатки'[Дата]<=SELECTEDVALUE('.Календарь'[Дата],MAX('.Календарь'[Дата]))) + , FILTER('Остатки', [Категория склада] <> "Виртуальный" + ))*/ + ``` + formatString: #,0 + displayFolder: Остаток склад + + measure 'Остаток - МП начало, шт' = ``` + + CALCULATE( + SUM('Остатки'[quantity]) + , REMOVEFILTERS('Остатки'[Дата]) + , REMOVEFILTERS('.Календарь'[Дата]) + , FILTER( + 'Остатки' + ,'Остатки'[Дата] "Виртуальный" + )) + + /*CALCULATE( + SUM('Остатки'[Quantity]), + + FILTER(ALL('Остатки'[Дата]),'Остатки'[Дата] "Виртуальный" + ))*/ + ``` + formatString: #,0 + displayFolder: Остаток склад + + measure 'Остаток - МП конец, шт' = ``` + + CALCULATE( + SUM('Остатки'[quantity]) + , REMOVEFILTERS('Остатки'[Дата]) + , REMOVEFILTERS('.Календарь'[Дата]) + , FILTER( + 'Остатки' + ,'Остатки'[Дата]<=SELECTEDVALUE('.Календарь'[Дата],MAX('.Календарь'[Дата])) + ) + , FILTER('Остатки', [Категория склада] <> "Виртуальный" + )) + + + + /*CALCULATE( + SUM('Остатки'[Quantity]), + FILTER('Остатки','Остатки'[Дата]<=SELECTEDVALUE('.Календарь'[Дата],MAX('.Календарь'[Дата]))) + , FILTER('Остатки', [Категория склада] <> "Виртуальный" + ))*/ + ``` + formatString: #,0 + displayFolder: Остаток склад + + measure 'Продажи за все время, руб' = + CALCULATE( + [Сумма продаж + РК, руб], + ALL('.Календарь'[Дата]) + ) + formatString: #,0 + + measure 'Продажи за все время, шт' = + CALCULATE( + [Количество продаж, шт], + ALL('.Календарь'[Дата]) + ) + formatString: #,0 + displayFolder: Количество + + measure 'Количество продаж, шт' = + CALCULATE( + SUM('Себестоимость'[Количество]), + FILTER('Себестоимость','Себестоимость'[Вид операции]="Расход" && 'Себестоимость'[Статья]="Реализация") + ) + formatString: #,0 + displayFolder: Количество + + measure 'Остаток - МП начало, руб' = ``` + + CALCULATE( + SUM('Остатки'[quantity в руб]) + , REMOVEFILTERS('Остатки'[Дата]) + , REMOVEFILTERS('.Календарь'[Дата]) + , FILTER( + 'Остатки' + ,'Остатки'[Дата] "Виртуальный" + )) + + + + /*CALCULATE( + SUM('Остатки'[quantity в руб]), + FILTER(ALL('Остатки'[Дата]),'Остатки'[Дата] "Виртуальный" + ))*/ + ``` + formatString: #,0 + displayFolder: Остаток склад + + measure 'Остаток - МП начало, usd' = ``` + + + CALCULATE( + SUM('Остатки'[quantity в usd]) + , REMOVEFILTERS('Остатки'[Дата]) + , REMOVEFILTERS('.Календарь'[Дата]) + , FILTER( + 'Остатки' + ,'Остатки'[Дата] "Виртуальный" + )) + + + /*CALCULATE( + SUM('Остатки'[quantity в usd]), + FILTER(ALL('Остатки'[Дата]),'Остатки'[Дата] "Виртуальный" + ))*/ + ``` + formatString: #,0 + displayFolder: Остаток склад + + measure 'Остаток - МП конец, руб' = ``` + + CALCULATE( + SUM('Остатки'[quantity в руб]) + , REMOVEFILTERS('Остатки'[Дата]) + , REMOVEFILTERS('.Календарь'[Дата]) + , FILTER( + 'Остатки' + ,'Остатки'[Дата]<=SELECTEDVALUE('.Календарь'[Дата],MAX('.Календарь'[Дата])) + ) + , FILTER('Остатки', [Категория склада] <> "Виртуальный" + )) + + + + /*CALCULATE( + SUM('Остатки'[quantity в руб]), + FILTER('Остатки','Остатки'[Дата]<=SELECTEDVALUE('.Календарь'[Дата],MAX('.Календарь'[Дата]))) + , FILTER('Остатки', [Категория склада] <> "Виртуальный" + ))*/ + ``` + formatString: #,0 + displayFolder: Остаток склад + + measure 'Остаток - МП конец, usd' = ``` + + CALCULATE( + SUM('Остатки'[quantity в usd]) + , REMOVEFILTERS('Остатки'[Дата]) + , REMOVEFILTERS('.Календарь'[Дата]) + , FILTER( + 'Остатки' + ,'Остатки'[Дата]<=SELECTEDVALUE('.Календарь'[Дата],MAX('.Календарь'[Дата])) + ) + , FILTER('Остатки', [Категория склада] <> "Виртуальный" + )) + + + + + /*CALCULATE( + SUM('Остатки'[quantity в usd]), + FILTER('Остатки','Остатки'[Дата]<=SELECTEDVALUE('.Календарь'[Дата],MAX('.Календарь'[Дата]))) + , FILTER('Остатки', [Категория склада] <> "Виртуальный" + ))*/ + ``` + formatString: #,0 + displayFolder: Остаток склад + + measure Оборачиваемость = ``` + DIVIDE( + [Сумма учетная, руб], + (('Основной отчет'[Остаток - МП конец, руб] + 'Основной отчет'[Остаток - МП начало, руб])/2 ) + ) + ``` + displayFolder: Показатели эффективности + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + measure 'Оборачиваемость, usd' = ``` + DIVIDE( + [Сумма учетная, usd], + (('Основной отчет'[Остаток - МП конец, usd] + 'Основной отчет'[Остаток - МП начало, usd])/2 ) + ) + ``` + displayFolder: Показатели эффективности + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + measure 'Рентаб. активов' = 'Основной отчет'[Оборачиваемость] * 'Основной отчет'[Торг. надбавка, руб, %] + formatString: #,0 + displayFolder: Показатели эффективности + + measure 'Рентаб. активов, usd' = 'Основной отчет'[Оборачиваемость, usd] * 'Основной отчет'[Торг. надбавка, usd, %] + formatString: #,0 + displayFolder: Показатели эффективности + + measure КоэфВозвратаUsd = DIVIDE([Сумма продаж + РК, usd], [Сумма закупки, usd], 0) + displayFolder: Показатели эффективности + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + measure КоэфВозвратаРуб = DIVIDE([Сумма продаж + РК, руб], [Сумма закупки, руб], 0) + displayFolder: Показатели эффективности + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + measure 'Сальдо, руб' = [Сумма продаж + РК, руб] - [Сумма закупки, руб] + formatString: #,0 + displayFolder: Показатели эффективности + + measure 'Сальдо, usd' = [Сумма продаж + РК, usd] - [Сумма закупки, usd] + formatString: #,0 + displayFolder: Показатели эффективности + + measure 'Сальдо накопит. руб' = + + CALCULATE( + [Сальдо, руб], + FILTER( + ALLSELECTED('.Календарь'[Дата]), + ISONORAFTER('.Календарь'[Дата], MAX('.Календарь'[Дата]), DESC) + ) + ) + formatString: #,0 + displayFolder: Показатели эффективности + + measure 'Сальдо накопит. usd' = + + CALCULATE( + [Сальдо, usd], + FILTER( + ALLSELECTED('.Календарь'[Дата]), + ISONORAFTER('.Календарь'[Дата], MAX('.Календарь'[Дата]), DESC) + ) + ) + formatString: #,0 + displayFolder: Показатели эффективности + + measure 'Хранение.Продажа, руб' = ``` + + CALCULATE( + -1 * ( + SUM('Себестоимость'[ЗатратыСкладХранение] ) + ) + , FILTER('Себестоимость','Себестоимость'[Вид операции]="Расход" && 'Себестоимость'[Статья]="Реализация") + ) + ``` + displayFolder: Учет + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + measure 'Хранение.Закупка, руб' = ``` + + CALCULATE( + ( + SUM('Себестоимость'[ЗатратыСкладХранение] ) + ) + , FILTER('Себестоимость','Себестоимость'[Вид операции]="Приход" && 'Себестоимость'[Статья]="Склад хранение") + ) + ``` + displayFolder: Учет + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + measure 'Количество заказов' = + CALCULATE( + DISTINCTCOUNTNOBLANK('Себестоимость'[Номер заказа]), + FILTER('Себестоимость','Себестоимость'[Вид операции]="Расход" && 'Себестоимость'[Статья]="Реализация") + ) + formatString: #,0 + displayFolder: Количество + + measure 'Артикулы продающие' = + CALCULATE( + DISTINCTCOUNTNOBLANK('Себестоимость'[artic_id]), + FILTER('Себестоимость','Себестоимость'[Вид операции]="Расход" && 'Себестоимость'[Статья]="Реализация") + ) + formatString: #,0 + displayFolder: Количество + + measure 'PY Прирост к прошлому году, руб' = ``` + + VAR CySales = [Сумма продаж + РК, руб] + VAR PySales = [PY Сумма продаж прошлый год, руб] + VAR YoySales = + IF ( + NOT ISBLANK ( CySales ) && NOT ISBLANK ( PySales ), + CySales - PySales + ) + RETURN + YoySales + ``` + formatString: #,0 + displayFolder: MAA, MAT, MTD, PY, YTD + + measure 'PY Прирост к прошлому году, %' = ``` + + DIVIDE( + [PY Прирост к прошлому году, руб], + [PY Сумма продаж прошлый год, руб] + ) + ``` + formatString: #,0%;-#,0%;#,0% + displayFolder: MAA, MAT, MTD, PY, YTD + + measure 'Сборка в другие товары, шт' = ``` + + CALCULATE( + SUM('Себестоимость'[Количество]) + , FILTER('Себестоимость','Себестоимость'[Вид операции]="Расход" && 'Себестоимость'[Статья]="Производство товара" ) + ) + ``` + formatString: #,0 + displayFolder: Количество + + measure 'Сборка из других товаров, шт' = ``` + + CALCULATE( + SUM('Себестоимость'[Количество]) + , FILTER('Себестоимость','Себестоимость'[Вид операции]="Приход" && 'Себестоимость'[Статья]="Производство товара" ) + ) + ``` + formatString: #,0 + displayFolder: Количество + + measure 'Количество продаж, упак' = + CALCULATE( + SUM('Себестоимость'[КоличествоУпаковок]), + FILTER('Себестоимость','Себестоимость'[Вид операции]="Расход" && 'Себестоимость'[Статья]="Реализация") + ) + formatString: #,0 + displayFolder: Количество + + measure 'PP Продажи прошлый период, руб' = ``` + + VAR StartDate = MIN( '.Календарь'[Дата] ) + VAR EndDate = MAX( '.Календарь'[Дата] ) + VAR PeriodLength = DATEDIFF( StartDate, EndDate, DAY ) + + RETURN + CALCULATE( + [Сумма продаж + РК, руб], + DATESBETWEEN( + '.Календарь'[Дата], + StartDate - PeriodLength - 1, + StartDate - 1 + ) + ) + ``` + formatString: #,0 + displayFolder: MAA, MAT, MTD, PY, YTD + + measure 'PP Прирост к прошлому периоду, руб' = ``` + + VAR CySales = [Сумма продаж + РК, руб] + VAR PySales = [PP Продажи прошлый период, руб] + VAR YoySales = + IF ( + NOT ISBLANK ( CySales ) && NOT ISBLANK ( PySales ), + CySales - PySales + ) + RETURN + YoySales + ``` + formatString: #,0 + displayFolder: MAA, MAT, MTD, PY, YTD + + measure 'PP Прирост к прошлому периоду, руб, %' = ``` + + DIVIDE( + [PP Прирост к прошлому периоду, руб], + [PP Продажи прошлый период, руб] + ) + ``` + formatString: 0%;-0%;0% + displayFolder: MAA, MAT, MTD, PY, YTD + + measure 'PP Продажи прошлый период, шт' = ``` + + VAR StartDate = MIN( '.Календарь'[Дата] ) + VAR EndDate = MAX( '.Календарь'[Дата] ) + VAR PeriodLength = DATEDIFF( StartDate, EndDate, DAY ) + + RETURN + CALCULATE( + [Количество продаж, шт], + DATESBETWEEN( + '.Календарь'[Дата], + StartDate - PeriodLength - 1, + StartDate - 1 + ) + ) + ``` + formatString: #,0 + displayFolder: MAA, MAT, MTD, PY, YTD + + measure 'PP Прирост к прошлому периоду, шт' = ``` + + VAR CySales = [Количество продаж, шт] + VAR PySales = [PP Продажи прошлый период, шт] + VAR YoySales = + IF ( + NOT ISBLANK ( CySales ) && NOT ISBLANK ( PySales ), + CySales - PySales + ) + RETURN + YoySales + ``` + formatString: #,0 + displayFolder: MAA, MAT, MTD, PY, YTD + + measure 'PP Прирост к прошлому периоду, шт, %' = ``` + + DIVIDE( + [PP Прирост к прошлому периоду, шт], + [PP Продажи прошлый период, шт] + ) + ``` + formatString: 0%;-0%;0% + displayFolder: MAA, MAT, MTD, PY, YTD + + measure 'PP Продажи прошлый период, упак' = ``` + + VAR StartDate = MIN( '.Календарь'[Дата] ) + VAR EndDate = MAX( '.Календарь'[Дата] ) + VAR PeriodLength = DATEDIFF( StartDate, EndDate, DAY ) + + RETURN + CALCULATE( + [Количество продаж, упак], + DATESBETWEEN( + '.Календарь'[Дата], + StartDate - PeriodLength - 1, + StartDate - 1 + ) + ) + ``` + formatString: #,0 + displayFolder: MAA, MAT, MTD, PY, YTD + + measure 'PP Прирост к прошлому периоду, упак' = ``` + + VAR CySales = [Количество продаж, упак] + VAR PySales = [PP Продажи прошлый период, упак] + VAR YoySales = + IF ( + NOT ISBLANK ( CySales ) && NOT ISBLANK ( PySales ), + CySales - PySales + ) + RETURN + YoySales + ``` + formatString: #,0 + displayFolder: MAA, MAT, MTD, PY, YTD + + measure 'PP Прирост к прошлому периоду, упак, %' = ``` + + DIVIDE( + [PP Прирост к прошлому периоду, упак], + [PP Продажи прошлый период, упак] + ) + ``` + formatString: 0%;-0%;0% + displayFolder: MAA, MAT, MTD, PY, YTD + + measure 'YTD Сумма продаж с начала года, шт' = ``` + + IF ( + NOT ISBLANK([Количество продаж, шт]), + CALCULATE( + [Количество продаж, шт], + DATESYTD('.Календарь'[Дата]) + ) + ) + ``` + formatString: #,0 + displayFolder: MAA, MAT, MTD, PY, YTD + + measure 'Оборачиваемость, шт' = ``` + DIVIDE( + [Количество продаж, шт], + (('Основной отчет'[Остаток - МП конец, шт] + 'Основной отчет'[Остаток - МП начало, шт])/2 ) + ) + ``` + displayFolder: Показатели эффективности + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + measure 'Остаток - МП средний, шт' = DIVIDE(([Остаток - МП начало, шт] + [Остаток - МП конец, шт]), 2, 0) + formatString: #,0 + displayFolder: Остаток склад + + measure 'Остаток конец по последней закупке, руб' = + + SUMX('Номенклатура', 'Номенклатура'[Цена учетная последняя известная, руб] * [Остаток - МП конец, шт]) + formatString: #,0 + isHidden + displayFolder: Остаток склад + + changedProperty = IsHidden + + measure 'Остаток конец по средней закупке, руб' = + + VAR EndDate = MAX('.Календарь'[Дата].[Date]) + + RETURN + CALCULATE( + SUMX('Номенклатура', [Остаток - МП конец, шт] * [Цена учетная по закупкам, руб]), + FILTER( + ALL('.Календарь'), -- Убираем фильтр по дате + '.Календарь'[Дата] <= EndDate + ) + ) + formatString: #,0 + isHidden + displayFolder: Остаток склад + + changedProperty = IsHidden + + measure 'Остаток, упак' = [Остаток - МП конец, упак] + sum('mp остатки'[Остаток МП, упак]) + displayFolder: Остаток склад + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + measure 'Остаток потенциальный + согласование, упак' = ``` + + + [Остаток - МП конец, упак] + + sum('mp остатки'[Остаток МП, упак]) + + [В производстве упак.] + + [В пути упак.] + + [Согласование упак.] + ``` + formatString: #,0 + displayFolder: Остаток склад + + annotation PBI_FormatHint = {"isDecimal":true} + + measure 'Торг. надбавка - 70р за упак, руб' = [Торг. надбавка, руб] - 70 /1000 * [Количество продаж, упак] + formatString: #,0 + + annotation PBI_FormatHint = {"isDecimal":true} + + measure 'Количество строк' = + + COUNTROWS( + FILTER( + 'Себестоимость', + 'Себестоимость'[Статья] = "Реализация" + ) + ) + formatString: 0 + displayFolder: Количество + + measure 'Потенциальный остаток, руб' = [Остаток - МП конец, руб] + 'Заказы все'[В производстве сумма всего в руб] + 'Заказы все'[В пути сумма всего в руб] + 'Заказы все'[Тех заказ сумма всего в руб] + formatString: #,0 + displayFolder: Аналитика + + annotation PBI_FormatHint = {"isDecimal":true} + + measure 'Потенциальная ТН' = [Потенциальный остаток, руб] * [Торг. надбавка, руб, %] / 100 + displayFolder: Аналитика + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + measure 'Оборачиваемость + 20%' = [Оборачиваемость] * 1.2 + displayFolder: Аналитика + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + measure 'Сумма скидки, руб' = SUM('Себестоимость'[Сумма скидки]) + formatString: #,0 + + annotation PBI_FormatHint = {"isDecimal":true} + + measure 'Остаток - МП конец, кг' = ``` + + SUMX('Номенклатура', + DIVIDE( + [Остаток - МП конец, шт] * COALESCE('Номенклатура'[Числитель веса], 0), + COALESCE('Номенклатура'[Знаменатель веса], 1))) + ``` + formatString: #,0 + displayFolder: Остаток склад + + measure 'Остаток - МП конец, м3' = ``` + + SUMX('Номенклатура', + DIVIDE( + [Остаток - МП конец, шт] * COALESCE('Номенклатура'[Числитель объема], 0), + COALESCE('Номенклатура'[Знаменатель объема], 1))) + ``` + formatString: #,0 + displayFolder: Остаток склад + + measure 'Учет.Доп расходы, руб' = ``` + + CALCULATE( + -1 * ( + SUM('Себестоимость'[Доп расходы]) + ) + , FILTER('Себестоимость','Себестоимость'[Вид операции]="Расход" && 'Себестоимость'[Статья]="Реализация") + ) + ``` + formatString: #,0 + displayFolder: Учет + + measure 'Учет.Доп расходы, usd' = ``` + + CALCULATE( + -1 * ( + SUM('Себестоимость'[Доп расходы USD2+2]) + ) + , FILTER('Себестоимость','Себестоимость'[Вид операции]="Расход" && 'Себестоимость'[Статья]="Реализация") + ) + ``` + formatString: #,0 + displayFolder: Учет + + measure 'Остаток потенциальный - МП, шт' = ``` + + + [Остаток - МП конец, шт] + + [В производстве кол.] + + [В пути кол.] + ``` + formatString: #,0 + displayFolder: Остаток склад + + measure 'Количество партнеров' = + CALCULATE( + DISTINCTCOUNTNOBLANK('Себестоимость'[PartnerId]), + FILTER('Себестоимость','Себестоимость'[Вид операции]="Расход" && 'Себестоимость'[Статья]="Реализация") + ) + formatString: #,0 + displayFolder: Количество + + measure 'Остаток потенциальный, упак' = ``` + + + [Остаток - МП конец, упак] + + sum('mp остатки'[Остаток МП, упак]) + + [В производстве упак.] + + [В пути упак.] + ``` + formatString: #,0 + displayFolder: Остаток склад + + measure 'Остаток потенциальный - МП, руб' = ``` + + [Остаток - МП конец, руб] + + [В пути сумма всего в руб] + + [В производстве сумма всего в руб] + ``` + formatString: #,0 + displayFolder: Остаток склад + + measure 'Остаток, шт' = [Остаток - МП конец, шт] + sum('mp остатки'[Остаток МП, шт]) + formatString: #,0 + displayFolder: Остаток склад + + measure 'Остаток, руб' = [Остаток - МП конец, руб] + sum('mp остатки'[Остаток МП, руб]) + formatString: #,0 + displayFolder: Остаток склад + + measure 'Остаток потенциальный, шт' = ``` + + + [Остаток - МП конец, шт] + + sum('mp остатки'[Остаток МП, шт]) + + [В производстве кол.] + + [В пути кол.] + ``` + formatString: #,0 + displayFolder: Остаток склад + + measure 'Остаток потенциальный, руб' = ``` + + + [Остаток - МП конец, руб] + + sum('mp остатки'[Остаток МП, руб]) + + [В производстве сумма всего в руб] + + [В пути сумма всего в руб] + ``` + formatString: #,0 + displayFolder: Остаток склад + + measure 'Остаток - МП средний, руб' = ``` + + ('Основной отчет'[Остаток - МП конец, руб] + 'Основной отчет'[Остаток - МП начало, руб])/2 + + ``` + formatString: #,0 + displayFolder: Остаток склад + + measure 'Остаток - МП средний, usd' = ``` + + ('Основной отчет'[Остаток - МП конец, usd] + 'Основной отчет'[Остаток - МП начало, usd])/2 + + ``` + formatString: #,0 + displayFolder: Остаток склад + + measure 'Остаток - МП средний, упак' = ``` + + ('Основной отчет'[Остаток - МП конец, упак] + 'Основной отчет'[Остаток - МП начало, упак])/2 + + ``` + formatString: #,0 + displayFolder: Остаток склад + + measure 'Сумма продаж, руб' = + + [Сумма продаж + РК, руб] - SUM('mp реклама'[Затраты РК, руб]) + formatString: #,0 + + measure 'Торг. надбавка + РК, руб' = ``` + + [Сумма продаж + РК, руб] - [Сумма учетная, руб] + ``` + formatString: #,0 + + measure 'Учет.Списание товара, руб' = ``` + + CALCULATE( + 1 * ( + SUM('Себестоимость'[Сумма учетная]) + ) + , FILTER('Себестоимость','Себестоимость'[Вид операции]="Расход" && 'Себестоимость'[Статья]="Списание товара") + ) + ``` + formatString: #,0 + displayFolder: Учет + + measure 'Учет.Списание товара, usd' = ``` + + CALCULATE( + 1 * ( + SUM('Себестоимость'[Сумма учетная, usd]) + ) + , FILTER('Себестоимость','Себестоимость'[Вид операции]="Расход" && 'Себестоимость'[Статья]="Списание товара") + ) + ``` + formatString: #,0 + displayFolder: Учет + + measure 'Сумма продаж Маркеты, руб' = ``` + + CALCULATE( + [Сумма продаж, руб], + FILTER('Партнер', 'Партнер'[Партнер] IN {"ВАЙЛДБЕРРИЗ ООО", "ИНТЕРНЕТ РЕШЕНИЯ ООО", + "ИНТЕРНЕТ РЕШЕНИЯ ООО юр. лица", "ЯНДЕКС.МАРКЕТ ООО", "ЯНДЕКС.МАРКЕТ ООО юр.лица"}) + ) + ``` + formatString: #,0 + displayFolder: Магок и маркеты + + measure 'Сумма продаж Маркеты, usd' = ``` + + CALCULATE( + [Сумма продаж, usd], + FILTER('Партнер', 'Партнер'[Партнер] IN {"ВАЙЛДБЕРРИЗ ООО", "ИНТЕРНЕТ РЕШЕНИЯ ООО", + "ИНТЕРНЕТ РЕШЕНИЯ ООО юр. лица", "ЯНДЕКС.МАРКЕТ ООО", "ЯНДЕКС.МАРКЕТ ООО юр.лица"}) + ) + ``` + formatString: #,0 + displayFolder: Магок и маркеты + + measure 'Сумма продаж Магок, руб' = ``` + + CALCULATE( + [Сумма продаж, руб], + FILTER('Партнер', NOT 'Партнер'[Партнер] IN {"ВАЙЛДБЕРРИЗ ООО", "ИНТЕРНЕТ РЕШЕНИЯ ООО", + "ИНТЕРНЕТ РЕШЕНИЯ ООО юр. лица", "ЯНДЕКС.МАРКЕТ ООО", "ЯНДЕКС.МАРКЕТ ООО юр.лица"}) + ) + ``` + formatString: #,0 + displayFolder: Магок и маркеты + + measure 'Сумма продаж Магок, usd' = ``` + + CALCULATE( + [Сумма продаж, usd], + FILTER('Партнер', NOT 'Партнер'[Партнер] IN {"ВАЙЛДБЕРРИЗ ООО", "ИНТЕРНЕТ РЕШЕНИЯ ООО", + "ИНТЕРНЕТ РЕШЕНИЯ ООО юр. лица", "ЯНДЕКС.МАРКЕТ ООО", "ЯНДЕКС.МАРКЕТ ООО юр.лица"}) + ) + ``` + formatString: #,0 + displayFolder: Магок и маркеты + + measure 'Торг. надбавка Маркеты, руб' = ``` + + CALCULATE( + [Торг. надбавка, руб], + FILTER('Партнер', 'Партнер'[Партнер] IN {"ВАЙЛДБЕРРИЗ ООО", "ИНТЕРНЕТ РЕШЕНИЯ ООО", + "ИНТЕРНЕТ РЕШЕНИЯ ООО юр. лица", "ЯНДЕКС.МАРКЕТ ООО", "ЯНДЕКС.МАРКЕТ ООО юр.лица"}) + ) + ``` + formatString: #,0 + displayFolder: Магок и маркеты + + measure 'Торг. надбавка Маркеты, usd' = ``` + + CALCULATE( + [Торг. надбавка, usd], + FILTER('Партнер', 'Партнер'[Партнер] IN {"ВАЙЛДБЕРРИЗ ООО", "ИНТЕРНЕТ РЕШЕНИЯ ООО", + "ИНТЕРНЕТ РЕШЕНИЯ ООО юр. лица", "ЯНДЕКС.МАРКЕТ ООО", "ЯНДЕКС.МАРКЕТ ООО юр.лица"}) + ) + ``` + formatString: #,0 + displayFolder: Магок и маркеты + + measure 'Торг. надбавка Магок, руб' = ``` + + CALCULATE( + [Торг. надбавка, руб], + FILTER('Партнер', NOT 'Партнер'[Партнер] IN {"ВАЙЛДБЕРРИЗ ООО", "ИНТЕРНЕТ РЕШЕНИЯ ООО", + "ИНТЕРНЕТ РЕШЕНИЯ ООО юр. лица", "ЯНДЕКС.МАРКЕТ ООО", "ЯНДЕКС.МАРКЕТ ООО юр.лица"}) + ) + ``` + formatString: #,0 + displayFolder: Магок и маркеты + + measure 'Торг. надбавка Магок, usd' = ``` + + CALCULATE( + [Торг. надбавка, usd], + FILTER('Партнер', NOT 'Партнер'[Партнер] IN {"ВАЙЛДБЕРРИЗ ООО", "ИНТЕРНЕТ РЕШЕНИЯ ООО", + "ИНТЕРНЕТ РЕШЕНИЯ ООО юр. лица", "ЯНДЕКС.МАРКЕТ ООО", "ЯНДЕКС.МАРКЕТ ООО юр.лица"}) + ) + ``` + formatString: #,0 + displayFolder: Магок и маркеты + + measure 'Торг. надбавка Маркеты, руб, %' = ``` + + CALCULATE( + [Торг. надбавка, руб, %], + FILTER('Партнер', 'Партнер'[Партнер] IN {"ВАЙЛДБЕРРИЗ ООО", "ИНТЕРНЕТ РЕШЕНИЯ ООО", + "ИНТЕРНЕТ РЕШЕНИЯ ООО юр. лица", "ЯНДЕКС.МАРКЕТ ООО", "ЯНДЕКС.МАРКЕТ ООО юр.лица"}) + ) + ``` + formatString: #,0 + displayFolder: Магок и маркеты + + annotation PBI_FormatHint = {"isDecimal":true} + + measure 'Торг. надбавка Маркеты, usd, %' = ``` + + CALCULATE( + [Торг. надбавка, usd, %], + FILTER('Партнер', 'Партнер'[Партнер] IN {"ВАЙЛДБЕРРИЗ ООО", "ИНТЕРНЕТ РЕШЕНИЯ ООО", + "ИНТЕРНЕТ РЕШЕНИЯ ООО юр. лица", "ЯНДЕКС.МАРКЕТ ООО", "ЯНДЕКС.МАРКЕТ ООО юр.лица"}) + ) + ``` + formatString: #,0 + displayFolder: Магок и маркеты + + annotation PBI_FormatHint = {"isDecimal":true} + + measure 'Торг. надбавка Магок, руб, %' = ``` + + CALCULATE( + [Торг. надбавка, руб, %], + FILTER('Партнер', NOT 'Партнер'[Партнер] IN {"ВАЙЛДБЕРРИЗ ООО", "ИНТЕРНЕТ РЕШЕНИЯ ООО", + "ИНТЕРНЕТ РЕШЕНИЯ ООО юр. лица", "ЯНДЕКС.МАРКЕТ ООО", "ЯНДЕКС.МАРКЕТ ООО юр.лица"}) + ) + ``` + formatString: #,0 + displayFolder: Магок и маркеты + + annotation PBI_FormatHint = {"isDecimal":true} + + measure 'Торг. надбавка Магок, usd, %' = ``` + + CALCULATE( + [Торг. надбавка, usd, %], + FILTER('Партнер', NOT 'Партнер'[Партнер] IN {"ВАЙЛДБЕРРИЗ ООО", "ИНТЕРНЕТ РЕШЕНИЯ ООО", + "ИНТЕРНЕТ РЕШЕНИЯ ООО юр. лица", "ЯНДЕКС.МАРКЕТ ООО", "ЯНДЕКС.МАРКЕТ ООО юр.лица"}) + ) + ``` + formatString: #,0 + displayFolder: Магок и маркеты + + annotation PBI_FormatHint = {"isDecimal":true} + + measure 'Продажи Маркеты, шт' = ``` + + CALCULATE( + [Количество продаж, шт], + FILTER('Партнер', 'Партнер'[Партнер] IN {"ВАЙЛДБЕРРИЗ ООО", "ИНТЕРНЕТ РЕШЕНИЯ ООО", + "ИНТЕРНЕТ РЕШЕНИЯ ООО юр. лица", "ЯНДЕКС.МАРКЕТ ООО", "ЯНДЕКС.МАРКЕТ ООО юр.лица"}) + ) + ``` + formatString: #,0 + displayFolder: Магок и маркеты + + measure 'Продажи Маркеты, упак' = ``` + + CALCULATE( + [Количество продаж, упак], + FILTER('Партнер', 'Партнер'[Партнер] IN {"ВАЙЛДБЕРРИЗ ООО", "ИНТЕРНЕТ РЕШЕНИЯ ООО", + "ИНТЕРНЕТ РЕШЕНИЯ ООО юр. лица", "ЯНДЕКС.МАРКЕТ ООО", "ЯНДЕКС.МАРКЕТ ООО юр.лица"}) + ) + ``` + formatString: #,0 + displayFolder: Магок и маркеты + + measure 'Продажи Магок, шт' = ``` + + CALCULATE( + [Количество продаж, шт], + FILTER('Партнер', NOT 'Партнер'[Партнер] IN {"ВАЙЛДБЕРРИЗ ООО", "ИНТЕРНЕТ РЕШЕНИЯ ООО", + "ИНТЕРНЕТ РЕШЕНИЯ ООО юр. лица", "ЯНДЕКС.МАРКЕТ ООО", "ЯНДЕКС.МАРКЕТ ООО юр.лица"}) + ) + ``` + formatString: #,0 + displayFolder: Магок и маркеты + + measure 'Продажи Магок, упак' = ``` + + CALCULATE( + [Количество продаж, упак], + FILTER('Партнер', NOT 'Партнер'[Партнер] IN {"ВАЙЛДБЕРРИЗ ООО", "ИНТЕРНЕТ РЕШЕНИЯ ООО", + "ИНТЕРНЕТ РЕШЕНИЯ ООО юр. лица", "ЯНДЕКС.МАРКЕТ ООО", "ЯНДЕКС.МАРКЕТ ООО юр.лица"}) + ) + ``` + formatString: #,0 + displayFolder: Магок и маркеты + + measure 'Остаток - МП - резерв, руб' = ``` + + [Остаток - МП конец, руб] - SUM('Резервы'[В резерве всего, руб]) + ``` + formatString: #,0 + displayFolder: Остаток склад + + measure 'Остаток - МП - резерв, шт' = [Остаток - МП конец, шт] - SUM('Резервы'[В резерве всего, шт]) + formatString: #,0 + displayFolder: Остаток склад + + measure 'Остаток - МП - резерв, упак' = [Остаток - МП конец, упак] - SUM('Резервы'[В резерве всего, упак]) + formatString: #,0 + displayFolder: Остаток склад + + measure 'Торг. надбавка + РК, руб, %' = + + DIVIDE( + [Торг. надбавка + РК, руб], + [Сумма учетная, руб] + ) * 100 + formatString: #,0 + + measure 'ДРР реальный от продаж, %' = ``` + DIVIDE( + SUM('mp реклама'[Затраты РК, руб]), + 'Основной отчет'[Сумма продаж + МП + РК, руб], 1) + ``` + formatString: #,0%;-#,0%;#,0% + displayFolder: Показатели эффективности + + measure 'Сумма продаж, usd' = + + [Сумма продаж + РК, usd] - SUM('mp реклама'[Затраты РК, usd]) + formatString: #,0 + + measure 'Торг. надбавка + РК, usd' = ``` + + [Сумма продаж + РК, usd] - [Сумма учетная, usd] + ``` + formatString: #,0 + + measure 'Торг. надбавка + РК, usd, %' = + + DIVIDE( + [Торг. надбавка + РК, usd], + [Сумма учетная, usd] + ) * 100 + formatString: #,0 + + measure 'Сумма продаж + РК Маркеты, usd' = ``` + + CALCULATE( + [Сумма продаж + РК, usd], + FILTER('Партнер', 'Партнер'[Партнер] IN {"ВАЙЛДБЕРРИЗ ООО", "ИНТЕРНЕТ РЕШЕНИЯ ООО", + "ИНТЕРНЕТ РЕШЕНИЯ ООО юр. лица", "ЯНДЕКС.МАРКЕТ ООО", "ЯНДЕКС.МАРКЕТ ООО юр.лица"}) + ) + ``` + formatString: #,0 + displayFolder: Магок и маркеты + + measure 'Сумма продаж + РК Маркеты, руб' = ``` + + CALCULATE( + [Сумма продаж + РК, руб], + FILTER('Партнер', 'Партнер'[Партнер] IN {"ВАЙЛДБЕРРИЗ ООО", "ИНТЕРНЕТ РЕШЕНИЯ ООО", + "ИНТЕРНЕТ РЕШЕНИЯ ООО юр. лица", "ЯНДЕКС.МАРКЕТ ООО", "ЯНДЕКС.МАРКЕТ ООО юр.лица"}) + ) + ``` + formatString: #,0 + displayFolder: Магок и маркеты + + measure 'Продажи за год, руб' = ``` + + CALCULATE( + [Сумма продаж + РК, руб], + ALLEXCEPT('.Календарь', '.Календарь'[Дата].[Год]) + ) + ``` + formatString: #,0 + + measure 'Торг. надбавка + МП + РК, руб' = ``` + + [Сумма продаж + МП + РК, руб] - [Сумма учетная, руб] + ``` + formatString: #,0 + + partition 'Основной отчет' = m + mode: import + source = + let + Источник = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WMlSKjQUA", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Столбец1 = _t]), + #"Измененный тип" = Table.TransformColumnTypes(Источник,{{"Столбец1", Int64.Type}}), + #"Удаленные столбцы" = Table.RemoveColumns(#"Измененный тип",{"Столбец1"}) + in + #"Удаленные столбцы" + + annotation PBI_ResultType = Table + diff --git a/analytics/pbi/model/report/Model/tables/Остатки.tmdl b/analytics/pbi/model/report/Model/tables/Остатки.tmdl new file mode 100644 index 0000000..79eb7b0 --- /dev/null +++ b/analytics/pbi/model/report/Model/tables/Остатки.tmdl @@ -0,0 +1,100 @@ +table Остатки + + column artic_id + dataType: string + summarizeBy: none + sourceColumn: artic_id + + annotation SummarizationSetBy = Automatic + + column Code + dataType: string + summarizeBy: none + sourceColumn: Code + + annotation SummarizationSetBy = Automatic + + column sklad + dataType: string + summarizeBy: none + sourceColumn: sklad + + annotation SummarizationSetBy = Automatic + + column 'Категория склада' + dataType: string + summarizeBy: none + sourceColumn: Категория склада + + annotation SummarizationSetBy = Automatic + + column upakovok + dataType: double + summarizeBy: sum + sourceColumn: upakovok + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column quantity + dataType: double + summarizeBy: sum + sourceColumn: quantity + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column upakovka + dataType: double + summarizeBy: sum + sourceColumn: upakovka + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column Дата + dataType: dateTime + formatString: Long Date + summarizeBy: none + sourceColumn: Дата + + variation Изменение + isDefault + relationship: 8afa5bd2-9707-4363-96f2-670a305dc4f3 + defaultHierarchy: LocalDateTable_2b612047-5dcc-402e-b2ed-154636b18544.'Иерархия дат' + + annotation SummarizationSetBy = Automatic + + annotation UnderlyingDateTimeDataType = Date + + column 'quantity в руб' = [quantity] * RELATED('Номенклатура'[Цена учетная, руб]) + formatString: #,0.00000 + summarizeBy: sum + + annotation SummarizationSetBy = Automatic + + column 'quantity в usd' = [quantity] * RELATED('Номенклатура'[Цена учетная, usd]) + formatString: #,0.0000000 + summarizeBy: sum + + annotation SummarizationSetBy = Automatic + + partition Остатки = m + mode: import + source = + let + Источник = Sql.Database("prdsql", "mag_pbi"), + pbi_ostatki_short = Источник{[Schema="pbi",Item="ostatki_short"]}[Data], + #"Переименованные столбцы" = Table.RenameColumns(pbi_ostatki_short,{{"date", "Дата"}}), + #"Измененный тип" = Table.TransformColumnTypes(#"Переименованные столбцы",{{"Дата", type date}}), + #"Удаленные столбцы" = Table.RemoveColumns(#"Измененный тип",{"Учетная цена, старое"}) + in + #"Удаленные столбцы" + + annotation PBI_ResultType = Table + + annotation PBI_NavigationStepName = Навигация + diff --git a/analytics/pbi/model/report/Model/tables/Отзывы клиентов.tmdl b/analytics/pbi/model/report/Model/tables/Отзывы клиентов.tmdl new file mode 100644 index 0000000..464b7bd --- /dev/null +++ b/analytics/pbi/model/report/Model/tables/Отзывы клиентов.tmdl @@ -0,0 +1,132 @@ +table 'Отзывы клиентов' + + column feedback_id + dataType: string + summarizeBy: none + sourceColumn: feedback_id + + annotation SummarizationSetBy = Automatic + + column order_id + dataType: string + summarizeBy: none + sourceColumn: order_id + + annotation SummarizationSetBy = Automatic + + column 'Номер заказа' + dataType: string + summarizeBy: none + sourceColumn: Номер заказа + + annotation SummarizationSetBy = Automatic + + column user_id + dataType: string + summarizeBy: none + sourceColumn: user_id + + annotation SummarizationSetBy = Automatic + + column 'Имя пользователя' + dataType: string + summarizeBy: none + sourceColumn: Имя пользователя + + annotation SummarizationSetBy = Automatic + + column Телефон + dataType: string + summarizeBy: none + sourceColumn: Телефон + + annotation SummarizationSetBy = Automatic + + column email + dataType: string + summarizeBy: none + sourceColumn: email + + annotation SummarizationSetBy = Automatic + + column 'Работа менеджера' + dataType: int64 + formatString: 0 + summarizeBy: sum + sourceColumn: Работа менеджера + + annotation SummarizationSetBy = Automatic + + column 'Скорость сборки' + dataType: int64 + formatString: 0 + summarizeBy: sum + sourceColumn: Скорость сборки + + annotation SummarizationSetBy = Automatic + + column 'Качество сборки' + dataType: int64 + formatString: 0 + summarizeBy: sum + sourceColumn: Качество сборки + + annotation SummarizationSetBy = Automatic + + column 'Качество упаковки' + dataType: int64 + formatString: 0 + summarizeBy: sum + sourceColumn: Качество упаковки + + annotation SummarizationSetBy = Automatic + + column 'Скорость доставки' + dataType: int64 + formatString: 0 + summarizeBy: sum + sourceColumn: Скорость доставки + + annotation SummarizationSetBy = Automatic + + column 'Готов рекомендовать' + dataType: int64 + formatString: 0 + summarizeBy: sum + sourceColumn: Готов рекомендовать + + annotation SummarizationSetBy = Automatic + + column 'Другие замечания' + dataType: string + summarizeBy: none + sourceColumn: Другие замечания + + annotation SummarizationSetBy = Automatic + + partition 'Отзывы клиентов' = m + mode: import + source = + let + Источник = Json.Document(Web.Contents("https://magok.ru/api/v2/ApiControllerSurveys/get_order_reports/")), + #"Преобразовано в таблицу" = Table.FromRecords({Источник}), + #"Развернутый элемент data" = Table.ExpandListColumn(#"Преобразовано в таблицу", "data"), + #"Развернутый элемент data1" = Table.ExpandRecordColumn(#"Развернутый элемент data", "data", {"ID", "UF_ORDER_ID", "UF_ORDER_CODE", "UF_USER_ID", "UF_TIME", "UF_ORDER_DATE", "UF_USER_NAME", "UF_USER_PHONE", "UF_USER_EMAIL", "UF_Q1_MNG", "UF_Q2_SKSB", "UF_Q3_QTSB", "UF_Q4_QTUP", "UF_Q5_SKDS", "UF_Q6_RECM", "UF_Q7_OTHER", "UF_DATE_SEND"}, {"data.ID", "data.UF_ORDER_ID", "data.UF_ORDER_CODE", "data.UF_USER_ID", "data.UF_TIME", "data.UF_ORDER_DATE", "data.UF_USER_NAME", "data.UF_USER_PHONE", "data.UF_USER_EMAIL", "data.UF_Q1_MNG", "data.UF_Q2_SKSB", "data.UF_Q3_QTSB", "data.UF_Q4_QTUP", "data.UF_Q5_SKDS", "data.UF_Q6_RECM", "data.UF_Q7_OTHER", "data.UF_DATE_SEND"}), + #"Измененный тип" = Table.TransformColumnTypes(#"Развернутый элемент data1",{{"status", type text}, {"message", type any}, {"data.ID", Int64.Type}, {"data.UF_ORDER_ID", Int64.Type}, {"data.UF_ORDER_CODE", type text}, {"data.UF_USER_ID", Int64.Type}, {"data.UF_TIME", type any}, {"data.UF_ORDER_DATE", type any}, {"data.UF_USER_NAME", type text}, {"data.UF_USER_PHONE", type text}, {"data.UF_USER_EMAIL", type text}, {"data.UF_Q1_MNG", Int64.Type}, {"data.UF_Q2_SKSB", Int64.Type}, {"data.UF_Q3_QTSB", Int64.Type}, {"data.UF_Q4_QTUP", Int64.Type}, {"data.UF_Q5_SKDS", Int64.Type}, {"data.UF_Q6_RECM", Int64.Type}, {"data.UF_Q7_OTHER", type text}, {"data.UF_DATE_SEND", type any}}), + #"Удаленные столбцы" = Table.RemoveColumns(#"Измененный тип",{"status", "message"}), + #"Измененный тип1" = Table.TransformColumnTypes(#"Удаленные столбцы",{{"data.ID", type text}}), + #"Переименованные столбцы" = Table.RenameColumns(#"Измененный тип1",{{"data.ID", "feedback_id"}, {"data.UF_ORDER_ID", "order_id"}}), + #"Измененный тип2" = Table.TransformColumnTypes(#"Переименованные столбцы",{{"order_id", type text}}), + #"Переименованные столбцы1" = Table.RenameColumns(#"Измененный тип2",{{"data.UF_ORDER_CODE", "Номер заказа"}, {"data.UF_USER_ID", "user_id"}}), + #"Измененный тип3" = Table.TransformColumnTypes(#"Переименованные столбцы1",{{"user_id", type text}}), + #"Удаленные столбцы1" = Table.RemoveColumns(#"Измененный тип3",{"data.UF_TIME", "data.UF_ORDER_DATE"}), + #"Переименованные столбцы2" = Table.RenameColumns(#"Удаленные столбцы1",{{"data.UF_USER_NAME", "Имя пользователя"}, {"data.UF_USER_PHONE", "Телефон"}, {"data.UF_USER_EMAIL", "email"}}), + #"Удаленные столбцы2" = Table.RemoveColumns(#"Переименованные столбцы2",{"data.UF_DATE_SEND"}), + #"Переименованные столбцы3" = Table.RenameColumns(#"Удаленные столбцы2",{{"data.UF_Q1_MNG", "Работа менеджера"}, {"data.UF_Q2_SKSB", "Скорость сборки"}, {"data.UF_Q3_QTSB", "Качество сборки"}, {"data.UF_Q4_QTUP", "Качество упаковки"}, {"data.UF_Q5_SKDS", "Скорость доставки"}, {"data.UF_Q6_RECM", "Готов рекомендовать"}, {"data.UF_Q7_OTHER", "Другие замечания"}}) + in + #"Переименованные столбцы3" + + annotation PBI_NavigationStepName = Навигация + + annotation PBI_ResultType = Table + diff --git a/analytics/pbi/model/report/Model/tables/ПРАЙСлист.tmdl b/analytics/pbi/model/report/Model/tables/ПРАЙСлист.tmdl new file mode 100644 index 0000000..36b1abd --- /dev/null +++ b/analytics/pbi/model/report/Model/tables/ПРАЙСлист.tmdl @@ -0,0 +1,187 @@ +table ПРАЙСлист + + measure 'Цена инвойс (вал)' = ``` + + VAR MaxDate = MAX('.Календарь'[Дата]) // Находим последнюю дату, где есть цена + + VAR LastKnowDate = + CALCULATE( + MAX('Прайслист'[Дата]), // Находим последнюю дату, где есть цена + 'Прайслист'[Дата] <= MaxDate, + 'Прайслист'[Вид цены] = "Цена Инвойс (вал)", + REMOVEFILTERS('.Календарь') // Убираем влияние фильтра на даты + ) + + RETURN + CALCULATE( + SELECTEDVALUE('Прайслист'[Цена]), // Берем цену для найденной последней даты + 'Прайслист'[Дата] = LastKnowDate, + 'Прайслист'[Вид цены] = "Цена Инвойс (вал)", + REMOVEFILTERS('.Календарь') + ) + + ``` + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + measure 'Цена отпускная (руб)' = ``` + + VAR MaxDate = MAX('.Календарь'[Дата]) // Находим последнюю дату, где есть цена + + VAR LastKnowDate = + CALCULATE( + MAX('Прайслист'[Дата]), // Находим последнюю дату, где есть цена + 'Прайслист'[Дата] <= MaxDate, + 'Прайслист'[Вид цены] = "Цена отпускная (руб)", + REMOVEFILTERS('.Календарь') // Убираем влияние фильтра на даты + ) + + RETURN + CALCULATE( + SELECTEDVALUE('Прайслист'[Цена]), // Берем цену для найденной последней даты + 'Прайслист'[Дата] = LastKnowDate, + 'Прайслист'[Вид цены] = "Цена отпускная (руб)", + REMOVEFILTERS('.Календарь') + ) + + ``` + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + measure 'Цена отпускная вал в руб' = ``` + + VAR MaxDate = MAX('.Календарь'[Дата]) // Находим последнюю дату, где есть цена + + VAR LastKnowDate = + CALCULATE( + MAX('Прайслист'[Дата]), // Находим последнюю дату, где есть цена + 'Прайслист'[Дата] <= MaxDate, + 'Прайслист'[Вид цены] = "Цена отпускная вал в руб", + REMOVEFILTERS('.Календарь') // Убираем влияние фильтра на даты + ) + + RETURN + CALCULATE( + SELECTEDVALUE('Прайслист'[Цена]), // Берем цену для найденной последней даты + 'Прайслист'[Дата] = LastKnowDate, + 'Прайслист'[Вид цены] = "Цена отпускная вал в руб", + REMOVEFILTERS('.Календарь') + ) + + ``` + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + measure 'Учетная цена (руб)' = ``` + + VAR nowdate = MAX('.Календарь'[Дата]) + VAR MaxDate = MAX('.Календарь'[Дата]) // Находим последнюю дату, где есть цена + + VAR LastKnowDate = + CALCULATE( + MAX('Прайслист'[Дата]), // Находим последнюю дату, где есть цена + 'Прайслист'[Дата] <= MaxDate, + 'Прайслист'[Вид цены] = "Учетная цена (руб)", + REMOVEFILTERS('.Календарь') // Убираем влияние фильтра на даты + ) + + RETURN + CALCULATE( + SELECTEDVALUE('Прайслист'[Цена]), // Берем цену для найденной последней даты + 'Прайслист'[Дата] = LastKnowDate, + 'Прайслист'[Вид цены] = "Учетная цена (руб)", + REMOVEFILTERS('.Календарь') + ) + + ``` + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + measure 'Учетная цена (вал)' = ``` + + VAR MaxDate = MAX('.Календарь'[Дата]) // Находим последнюю дату, где есть цена + + VAR LastKnowDate = + CALCULATE( + MAX('Прайслист'[Дата]), // Находим последнюю дату, где есть цена + 'Прайслист'[Дата] <= MaxDate, + 'Прайслист'[Вид цены] = "Учетная цена (вал)", + REMOVEFILTERS('.Календарь') // Убираем влияние фильтра на даты + ) + + RETURN + CALCULATE( + SELECTEDVALUE('Прайслист'[Цена]), // Берем цену для найденной последней даты + 'Прайслист'[Дата] = LastKnowDate, + 'Прайслист'[Вид цены] = "Учетная цена (вал)", + REMOVEFILTERS('.Календарь') + ) + + ``` + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + measure 'Цена отпускная упак все в руб' = IF(MAX('Номенклатура'[Ценовая группа]) = "Валютная", [Цена отпускная вал в руб], [Цена отпускная (руб)]) * MAX('Номенклатура'[Базовая упаковка]) + formatString: #,0 + + column Цена + dataType: double + isHidden + summarizeBy: sum + sourceColumn: Цена + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column 'Вид цены' + dataType: string + isHidden + summarizeBy: none + sourceColumn: Вид цены + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column artic_id + dataType: string + isHidden + summarizeBy: none + sourceColumn: artic_id + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column Дата + dataType: dateTime + isHidden + formatString: Long Date + summarizeBy: none + sourceColumn: Дата + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + annotation UnderlyingDateTimeDataType = Date + + partition ПРАЙСлист = m + mode: import + source = + let + Источник = Sql.Database("prdsql", "mag_pbi"), + pbi_pricelist = Источник{[Schema="pbi",Item="pricelist"]}[Data], + #"Измененный тип" = Table.TransformColumnTypes(pbi_pricelist,{{"Дата", type date}}), + #"Удаленные столбцы" = Table.RemoveColumns(#"Измененный тип",{"1c_id", "_Period"}), + #"Строки с примененным фильтром" = Table.SelectRows(#"Удаленные столбцы", each [Вид цены] = "Учетная цена (руб)" or [Вид цены] = "Цена отпускная (руб)" or [Вид цены] = "Учетная цена (вал)" or [Вид цены] = "Цена отпускная вал в руб" or [Вид цены] = "Цена Инвойс (вал)") + in + #"Строки с примененным фильтром" + + annotation PBI_ResultType = Table + + annotation PBI_NavigationStepName = Навигация + diff --git a/analytics/pbi/model/report/Model/tables/Параметр цена продажи, %.tmdl b/analytics/pbi/model/report/Model/tables/Параметр цена продажи, %.tmdl new file mode 100644 index 0000000..d73f3de --- /dev/null +++ b/analytics/pbi/model/report/Model/tables/Параметр цена продажи, %.tmdl @@ -0,0 +1,25 @@ +table 'Параметр цена продажи, %' + + measure 'Значение Параметр цена продажи, %' = SELECTEDVALUE('Параметр цена продажи, %'[Параметр цена продажи, %], 0) + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column 'Параметр цена продажи, %' + summarizeBy: none + sourceColumn: [Value] + + extendedProperty ParameterMetadata = + { + "version": 0 + } + + annotation SummarizationSetBy = User + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + partition 'Параметр цена продажи, %' = calculated + mode: import + source = GENERATESERIES(-20, 20, 0.5) + + annotation PBI_Id = b90d31cda7104f04bc1706ba6701fc53 + diff --git a/analytics/pbi/model/report/Model/tables/Партнер.tmdl b/analytics/pbi/model/report/Model/tables/Партнер.tmdl new file mode 100644 index 0000000..b0174e4 --- /dev/null +++ b/analytics/pbi/model/report/Model/tables/Партнер.tmdl @@ -0,0 +1,275 @@ +table Партнер + + measure 'ABC Class dynamic' = + + IF ( + HASONEVALUE ( 'Партнер'[partner_id] ), + VAR SalesByPartner = + CALCULATETABLE ( + ADDCOLUMNS ( + SUMMARIZE ( 'Партнер', 'Партнер'[partner_id] ), + "@PartnerSales", [Сумма продаж + РК, руб] + ), + ALLSELECTED ( 'Партнер' ) + ) + VAR AllSales = + CALCULATE ( + [Сумма продаж + РК, руб], + ALLSELECTED ( 'Партнер' ) + ) + VAR CurrentSalesAmt = [Сумма продаж + РК, руб] + VAR CumulatedSales = + FILTER ( + SalesByPartner, + [@PartnerSales] >= CurrentSalesAmt + ) + VAR CumulatedSalesAmount = + SUMX ( + CumulatedSales, + [@PartnerSales] + ) + VAR CurrentCumulatedPct = + DIVIDE ( + CumulatedSalesAmount, + AllSales + ) + VAR Result = + SWITCH ( + TRUE, + ISBLANK ( CurrentCumulatedPct ), BLANK (), + CurrentCumulatedPct <= 0.8, "A", + CurrentCumulatedPct <= 0.95, "B", + "C" + ) + RETURN + Result + ) + + column partner_id + dataType: string + isHidden + summarizeBy: none + sourceColumn: partner_id + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column Партнер + dataType: string + summarizeBy: none + sourceColumn: Партнер + + changedProperty = SortByColumn + + annotation SummarizationSetBy = Automatic + + column Регион + dataType: string + summarizeBy: none + sourceColumn: Регион + + annotation SummarizationSetBy = Automatic + + column manager_id + dataType: string + isHidden + summarizeBy: none + sourceColumn: manager_id + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column 'Да/Нет Клиент' + dataType: int64 + formatString: 0 + summarizeBy: sum + sourceColumn: Да/Нет Клиент + + annotation SummarizationSetBy = Automatic + + column 'Да/Нет Поставщик' + dataType: int64 + formatString: 0 + summarizeBy: sum + sourceColumn: Да/Нет Поставщик + + annotation SummarizationSetBy = Automatic + + column 'Да/Нет Конкурент' + dataType: int64 + formatString: 0 + summarizeBy: sum + sourceColumn: Да/Нет Конкурент + + annotation SummarizationSetBy = Automatic + + column 'Код УТ' + dataType: string + summarizeBy: none + sourceColumn: Код УТ + + annotation SummarizationSetBy = Automatic + + column 'Основной менеджер' + dataType: string + isHidden + summarizeBy: none + sourceColumn: Основной менеджер + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column 'Направление деятельности' + dataType: string + summarizeBy: none + sourceColumn: Направление деятельности + + annotation SummarizationSetBy = Automatic + + column bitrix_id + dataType: string + isHidden + summarizeBy: none + sourceColumn: bitrix_id + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column ДатаРегистрации + dataType: dateTime + formatString: General Date + summarizeBy: none + sourceColumn: ДатаРегистрации + + variation Изменение + isDefault + relationship: 70d8fb19-ce6e-4331-bdd5-c48b97661c3a + defaultHierarchy: LocalDateTable_67da7b50-915b-480b-9e3a-3a60739fb0c6.'Иерархия дат' + + annotation SummarizationSetBy = Automatic + + column Сегмент + dataType: string + summarizeBy: none + sourceColumn: Сегмент + + annotation SummarizationSetBy = Automatic + + column 'Дата последнего звонка' + dataType: dateTime + formatString: Long Date + summarizeBy: none + sourceColumn: Дата последнего звонка + + variation Изменение + isDefault + relationship: b7780e24-ae05-4812-ad3f-b6d9dc7f50cc + defaultHierarchy: LocalDateTable_c661d468-0044-4990-b9e8-723cda59cf51.'Иерархия дат' + + annotation SummarizationSetBy = Automatic + + annotation UnderlyingDateTimeDataType = Date + + column partner_link + dataType: string + dataCategory: WebUrl + summarizeBy: none + sourceColumn: partner_link + + annotation SummarizationSetBy = Automatic + + column Область + dataType: string + summarizeBy: none + sourceColumn: Область + + annotation SummarizationSetBy = Automatic + + column Округ + dataType: string + summarizeBy: none + sourceColumn: Округ + + annotation SummarizationSetBy = Automatic + + column 'Что шьют?' + dataType: string + summarizeBy: none + sourceColumn: Что шьют? + + annotation SummarizationSetBy = Automatic + + column Категория + dataType: string + summarizeBy: none + sourceColumn: Категория + + annotation SummarizationSetBy = Automatic + + column 'Статус партнера' + dataType: string + summarizeBy: none + sourceColumn: Статус партнера + + annotation SummarizationSetBy = Automatic + + column 'Дата первого заказа' + dataType: dateTime + formatString: Long Date + summarizeBy: none + sourceColumn: Дата первого заказа + + variation Изменение + isDefault + relationship: 8171e79f-bfe6-4798-bb1a-98146553bada + defaultHierarchy: LocalDateTable_588ed205-7c5f-41f0-9bd7-0d82b2484f09.'Иерархия дат' + + changedProperty = DataType + + annotation SummarizationSetBy = Automatic + + annotation UnderlyingDateTimeDataType = Date + + column Когорта = FORMAT('Партнер'[Дата первого заказа], "YYYY-MM") + summarizeBy: none + + annotation SummarizationSetBy = Automatic + + column 'Статус по динамике 2025/2024' + dataType: string + summarizeBy: none + sourceColumn: Статус по динамике 2025/2024 + + annotation SummarizationSetBy = Automatic + + column 'Статус по обороту 2025' + dataType: string + summarizeBy: none + sourceColumn: Статус по обороту 2025 + + annotation SummarizationSetBy = Automatic + + partition Партнер-974763bd-dd7f-47ca-b4b6-800173f04370 = m + mode: import + source = + let + Источник = Sql.Database("prdsql", "mag_pbi"), + sales_w_partners = Источник{[Schema="pbi",Item="Партнеры"]}[Data], + #"Переименованные столбцы" = Table.RenameColumns(sales_w_partners,{{"partner", "Партнер"}, {"region", "Регион"}, {"konkurent", "Да/Нет Конкурент"}, {"client", "Да/Нет Клиент"}, {"supplier", "Да/Нет Поставщик"}, {"_Code", "Код УТ"}}), + #"Объединенные запросы" = Table.NestedJoin(#"Переименованные столбцы", {"bitrix_id"}, crm_company_uf, {"bitrix_id"}, "crm_company_uf", JoinKind.LeftOuter), + #"Развернутый элемент crm_company_uf" = Table.ExpandTableColumn(#"Объединенные запросы", "crm_company_uf", {"Дата последнего звонка"}, {"Дата последнего звонка"}), + #"Вставлено: объединенный столбец" = Table.AddColumn(#"Развернутый элемент crm_company_uf", "Сведено", each Text.Combine({"https://magok.bitrix24.ru/crm/company/details/", [bitrix_id], "/"}), type text), + #"Переименованные столбцы1" = Table.RenameColumns(#"Вставлено: объединенный столбец",{{"Сведено", "partner_link"}, {"oblast", "Область"}, {"okrug", "Округ"}, {"Category", "Категория"}}) + in + #"Переименованные столбцы1" + + annotation PBI_QueryRelationships = {"columnCount":10,"keyColumnNames":[],"queryRelationships":[],"columnIdentities":["Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_partners.{1c_id,0}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_partners.{partner_id,1}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_partners.{partner,2}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_partners.{region,3}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_partners.{1c_manager_id,4}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_partners.{manager_id,5}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_partners.{napravlenie,6}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_partners.{client,7}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_partners.{supplier,8}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_partners.{konkurent,9}"],"ColumnCount":10,"KeyColumnNames":[],"ColumnIdentities":["Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_partners.{1c_id,0}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_partners.{partner_id,1}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_partners.{partner,2}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_partners.{region,3}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_partners.{1c_manager_id,4}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_partners.{manager_id,5}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_partners.{napravlenie,6}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_partners.{client,7}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_partners.{supplier,8}","Server.Database\\/2/SQL/1cnew;mag_reports/sales/sales.w_partners.{konkurent,9}"],"RelationshipInfo":[]} + + annotation PBI_ResultType = Table + + annotation PBI_NavigationStepName = Навигация + diff --git a/analytics/pbi/model/report/Model/tables/План маркеты.tmdl b/analytics/pbi/model/report/Model/tables/План маркеты.tmdl new file mode 100644 index 0000000..df99a44 --- /dev/null +++ b/analytics/pbi/model/report/Model/tables/План маркеты.tmdl @@ -0,0 +1,159 @@ +table 'План маркеты' + + measure 'План Ozon, руб' = ``` + + + VAR PlanGroups = + SUMMARIZE( + 'Номенклатура', + 'Номенклатура'[Менеджер OZON] + ) + + VAR FilterPlanGroups = + TREATAS( + PlanGroups, + 'План маркеты'[Менеджер] + ) + + VAR Result = + CALCULATE( + SUM('План маркеты'[План]), KEEPFILTERS(FilterPlanGroups), + FILTER('План маркеты',MONTH('План маркеты'[Месяц]) = MONTH(MAX('.Календарь'[Дата]))), + FILTER('План маркеты',YEAR('План маркеты'[Месяц]) = YEAR(MAX('.Календарь'[Дата]))), + FILTER('План маркеты', 'План маркеты'[Маркетплейс] = "OZON") + + ) + + RETURN Result + ``` + formatString: #,0 + + measure 'План WB, руб' = ``` + + + VAR PlanGroups = + SUMMARIZE( + 'Номенклатура', + 'Номенклатура'[Менеджер WB] + ) + + VAR FilterPlanGroups = + TREATAS( + PlanGroups, + 'План маркеты'[Менеджер] + ) + + VAR Result = + CALCULATE( + SUM('План маркеты'[План]), KEEPFILTERS(FilterPlanGroups), + FILTER('План маркеты',MONTH('План маркеты'[Месяц]) = MONTH(MAX('.Календарь'[Дата]))), + FILTER('План маркеты',YEAR('План маркеты'[Месяц]) = YEAR(MAX('.Календарь'[Дата]))), + FILTER('План маркеты', 'План маркеты'[Маркетплейс] = "WB") + ) + + RETURN Result + ``` + formatString: #,0 + + measure 'Осталось до плана Ozon' = + IF( + [План Ozon, руб] > [Сумма продаж + РК, руб], + [План Ozon, руб] - [Сумма продаж + РК, руб], 0 + ) + formatString: #,0 + + measure 'Осталось до плана WB' = + IF( + [План WB, руб] > [Сумма продаж + РК, руб], + [План WB, руб] - [Сумма продаж + РК, руб], 0 + ) + formatString: #,0 + + measure '% плана Ozon' = ``` + DIVIDE( + [Сумма продаж + РК, руб], [План Ozon, руб]) + ``` + formatString: 0%;-0%;0% + + measure '% плана WB' = ``` + DIVIDE( + [Сумма продаж + РК, руб], [План WB, руб]) + ``` + formatString: 0%;-0%;0% + + measure 'Аппроксим. Ozon, %' = ``` + + DIVIDE( + [Аппроксимация месяц, руб], [План Ozon, руб] + ) + ``` + formatString: 0%;-0%;0% + + measure 'Аппроксим. WB, %' = ``` + + DIVIDE( + [Аппроксимация месяц, руб], [План WB, руб] + ) + ``` + formatString: 0%;-0%;0% + + column Маркетплейс + dataType: string + summarizeBy: none + sourceColumn: Маркетплейс + + annotation SummarizationSetBy = Automatic + + column Менеджер + dataType: string + isHidden + summarizeBy: none + sourceColumn: Менеджер + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column Месяц + dataType: dateTime + isHidden + formatString: Long Date + summarizeBy: none + sourceColumn: Месяц + + variation Изменение + isDefault + relationship: 381b6bd4-06f4-496e-9264-13deb45adbf2 + defaultHierarchy: LocalDateTable_66d8bbba-35e3-44df-be7f-bb6fc44f271a.'Иерархия дат' + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + annotation UnderlyingDateTimeDataType = Date + + column План + dataType: int64 + formatString: #,0 + summarizeBy: sum + sourceColumn: План + + annotation SummarizationSetBy = Automatic + + partition 'План маркеты' = m + mode: import + source = + let + Источник = GoogleSheets.Contents("https://docs.google.com/spreadsheets/d/1bf0nQKoZaTlIlj86tRrAarHdg5dSsXH4xwgOdJc2lqQ/edit?usp=sharing"), + Маркеты_Table = Источник{[name="Маркеты",ItemKind="Table"]}[Data], + #"Повышенные заголовки" = Table.PromoteHeaders(Маркеты_Table, [PromoteAllScalars=true]), + #"Измененный тип" = Table.TransformColumnTypes(#"Повышенные заголовки",{{"Маркетплейс", type text}, {"Менеджер", type text}, {"Месяц", type date}, {"План", Int64.Type}}) + in + #"Измененный тип" + + changedProperty = Name + + annotation PBI_NavigationStepName = Навигация + + annotation PBI_ResultType = Table + diff --git a/analytics/pbi/model/report/Model/tables/План продаж менеджеров.tmdl b/analytics/pbi/model/report/Model/tables/План продаж менеджеров.tmdl new file mode 100644 index 0000000..5eb9348 --- /dev/null +++ b/analytics/pbi/model/report/Model/tables/План продаж менеджеров.tmdl @@ -0,0 +1,168 @@ +table 'План продаж менеджеров' + + measure 'Актуальный план, руб' = + CALCULATE( + SUM('План продаж менеджеров'[план продаж]), + STARTOFMONTH('.Календарь'[Дата]) + ) + formatString: #,0 + + measure '% плана' = + DIVIDE( + [Сумма продаж + РК, руб], + 'План продаж менеджеров'[Актуальный план, руб] + ) + formatString: 0%;-0%;0% + + measure '% премии' = + IF( + [% плана]< 0.8, + 1.8, + IF( + [% плана]<0.9, + 2.2, + IF ( + [% плана]<=1.01, + 2.6, + 3 + ) + ) + ) + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + measure 'Аппроксимация месяц, руб' = ``` + + VAR CySales = [Сумма продаж + РК, руб] + VAR LastSalesDay = DAY(LASTNONBLANK('.Календарь'[Дата], [Сумма продаж + РК, руб] > 0)) + VAR MonthDays = DAY(EOMONTH(MAX('.Календарь'[Дата]), 0)) + VAR Approx = + IF( + NOT ISBLANK ( CySales ), + DIVIDE( + 'Основной отчет'[MTD Сумма продаж с начала месяца, руб] * MonthDays , + LastSalesDay + ) + ) + RETURN Approx + ``` + formatString: #,0 + + measure 'Аппроксимация год, руб' = ``` + + VAR CySales = [Сумма продаж + РК, руб] + + VAR LastSalesDay = + INT( + LASTNONBLANK('.Календарь'[Дата], [Сумма продаж + РК, руб] > 0) - + STARTOFYEAR('.Календарь'[Дата].[Date]) + ) + 1 + + + VAR YearDays = + INT( + ENDOFYEAR('.Календарь'[Дата].[Date]) - STARTOFYEAR('.Календарь'[Дата].[Date]) + ) + 1 + + VAR Approx = + IF( + NOT ISBLANK ( CySales ), + DIVIDE( + 'Основной отчет'[YTD Сумма продаж с начала года, руб] * YearDays , + LastSalesDay + ) + ) + RETURN Approx + ``` + formatString: #,0 + + annotation PBI_FormatHint = {"isDecimal":true} + + measure 'Аппроксим. месяц руб, %' = ``` + + DIVIDE( + [Аппроксимация месяц, руб], SUM('План продаж менеджеров'[план продаж]) + ) + ``` + formatString: 0%;-0%;0% + + measure 'Осталось до плана, руб' = [Актуальный план, руб] - [Сумма продаж + РК, руб] + formatString: #,0 + + measure 'План продаж в день, руб' = DIVIDE('План продаж менеджеров'[Актуальный план, руб],21.5) + formatString: #,0 + + measure 'План продаж менеджеров год, руб' = ``` + + CALCULATE( + SUM('План продаж менеджеров'[план продаж]), + ALLEXCEPT('.Календарь', '.Календарь'[Дата].[Год]) + ) + ``` + formatString: #,0 + + measure '% годового плана' = + DIVIDE( + [Сумма продаж + РК, руб], + 'План продаж менеджеров'[План продаж менеджеров год, руб] + ) + formatString: 0%;-0%;0% + + column Период + dataType: dateTime + isHidden + formatString: Long Date + summarizeBy: none + sourceColumn: Период + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + annotation UnderlyingDateTimeDataType = Date + + column user_id + dataType: string + isHidden + summarizeBy: none + sourceColumn: user_id + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column 'план продаж' + dataType: double + isHidden + summarizeBy: sum + sourceColumn: план продаж + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column Менеджер + dataType: string + isHidden + summarizeBy: none + sourceColumn: Менеджер + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + partition 'План продаж менеджеров' = m + mode: import + source = + let + Источник = Sql.Database("prdsql", "mag_pbi"), + pbi_ПланПродажМенеджеров = Источник{[Schema="pbi",Item="ПланПродажМенеджеров"]}[Data], + #"Измененный тип" = Table.TransformColumnTypes(pbi_ПланПродажМенеджеров,{{"_Fld27878", type date}}), + #"Переименованные столбцы" = Table.RenameColumns(#"Измененный тип",{{"_Fld27878", "Период"}}) + in + #"Переименованные столбцы" + + annotation PBI_ResultType = Table + diff --git a/analytics/pbi/model/report/Model/tables/План продаж по группам.tmdl b/analytics/pbi/model/report/Model/tables/План продаж по группам.tmdl new file mode 100644 index 0000000..4849e07 --- /dev/null +++ b/analytics/pbi/model/report/Model/tables/План продаж по группам.tmdl @@ -0,0 +1,436 @@ +table 'План продаж по группам' + + measure 'План продаж месяц, usd' = ``` + + + VAR PlanGroups = + SUMMARIZE( + 'Номенклатура', + 'Группы'[first group], + 'Номенклатура'[Менеджер по закупкам], + 'Номенклатура'[Товарный менеджер] + ) + + VAR FilterPlanGroups = + TREATAS( + PlanGroups, + 'План продаж по группам'[group_id], + 'План продаж по группам'[Менеджер по закупкам], + 'План продаж по группам'[Товарный менеджер] + ) + + VAR Result = + CALCULATE( + SUM('План продаж по группам'[План продаж, usd]), KEEPFILTERS(FilterPlanGroups), + FILTER('План продаж по группам',MONTH('План продаж по группам'[Месяц]) = MONTH(MAX('.Календарь'[Дата]))), + FILTER('План продаж по группам',YEAR('План продаж по группам'[Месяц]) = YEAR(MAX('.Календарь'[Дата]))) + ) + + RETURN Result + ``` + formatString: #,0 + displayFolder: План по группам usd + + annotation PBI_FormatHint = {"isDecimal":true} + + measure 'План год, usd' = ``` + + + VAR PlanGroups = + SUMMARIZE( + 'Номенклатура', + 'Группы'[first group], + 'Номенклатура'[Менеджер по закупкам], + 'Номенклатура'[Товарный менеджер] + ) + + VAR FilterPlanGroups = + TREATAS( + PlanGroups, + 'План продаж по группам'[group_id], + 'План продаж по группам'[Менеджер по закупкам], + 'План продаж по группам'[Товарный менеджер] + ) + + VAR Result = + CALCULATE( + SUM('План продаж по группам'[План продаж, usd]), KEEPFILTERS(FilterPlanGroups), + FILTER('План продаж по группам',YEAR('План продаж по группам'[Месяц]) = YEAR(MAX('.Календарь'[Дата]))) + ) + + RETURN Result + ``` + formatString: #,0 + displayFolder: План по группам usd + + annotation PBI_FormatHint = {"isDecimal":true} + + measure '% план год' = ``` + + DIVIDE ( + [Сумма продаж + РК, usd], [План год, usd], BLANK() + ) + ``` + formatString: 0.00%;-0.00%;0.00% + displayFolder: План по группам usd + + measure '% план месяц' = ``` + + DIVIDE ( + [Сумма продаж + РК, usd], [План продаж месяц, usd], BLANK() + ) + ``` + formatString: 0.00%;-0.00%;0.00% + displayFolder: План по группам usd + + measure 'Аппроксимация год, usd' = ``` + + VAR CySales = [Сумма продаж + РК, usd] + + VAR LastSalesDay = + INT( + LASTNONBLANK('.Календарь'[Дата], [Сумма продаж + РК, usd] > 0) - + STARTOFYEAR('.Календарь'[Дата].[Date]) + ) + 1 + + + VAR YearDays = + INT( + ENDOFYEAR('.Календарь'[Дата].[Date]) - STARTOFYEAR('.Календарь'[Дата].[Date]) + ) + 1 + + VAR Approx = + IF( + NOT ISBLANK ( CySales ), + DIVIDE( + 'Основной отчет'[YTD Сумма продаж с начала года, usd] * YearDays , + LastSalesDay + ) + ) + RETURN Approx + ``` + formatString: #,0 + displayFolder: План по группам usd + + measure 'Аппроксимация месяц, usd' = ``` + + VAR CySales = [Сумма продаж + РК, usd] + VAR LastSalesDay = DAY(LASTNONBLANK('.Календарь'[Дата], [Сумма продаж + РК, usd] > 0)) + VAR MonthDays = DAY(EOMONTH(MAX('.Календарь'[Дата]), 0)) + VAR Approx = + IF( + NOT ISBLANK ( CySales ), + DIVIDE( + 'Основной отчет'[MTD Сумма продаж с начала месяца, usd] * MonthDays , + LastSalesDay + ) + ) + RETURN Approx + ``` + formatString: #,0 + displayFolder: План по группам usd + + measure 'Аппроксим. год usd, %' = ``` + + DIVIDE( + [Аппроксимация год, usd], [План год, usd] + ) + ``` + formatString: 0.00%;-0.00%;0.00% + displayFolder: План по группам usd + + measure 'Аппроксим. месяц usd, %' = ``` + + DIVIDE( + [Аппроксимация месяц, usd], [План продаж месяц, usd] + ) + ``` + formatString: 0.00%;-0.00%;0.00% + displayFolder: План по группам usd + + measure 'Аппроксимация год, шт' = ``` + + VAR CySales = [Количество продаж, шт] + + VAR LastSalesDay = + INT( + LASTNONBLANK('.Календарь'[Дата], [Количество продаж, шт] > 0) - + STARTOFYEAR('.Календарь'[Дата].[Date]) + ) + 1 + + + VAR YearDays = + INT( + ENDOFYEAR('.Календарь'[Дата].[Date]) - STARTOFYEAR('.Календарь'[Дата].[Date]) + ) + 1 + + VAR Approx = + IF( + NOT ISBLANK ( CySales ), + DIVIDE( + 'Основной отчет'[YTD Сумма продаж с начала года, шт] * YearDays , + LastSalesDay + ) + ) + RETURN Approx + ``` + formatString: #,0 + + measure 'План закупки ост. период, шт' = ``` + + [Аппроксимация год, шт] + - [YTD Сумма продаж с начала года, шт] + - 'Заказы все'[В производстве кол.] + - 'Заказы все'[В пути кол.] + - [Остаток - МП конец, шт] + + [Остаток - МП средний, шт] + ``` + formatString: #,0 + displayFolder: План закупки + + measure 'План закупки ост. период, руб' = + + SUMX('Номенклатура', + [Учетная цена (руб)] * [План закупки ост. период, шт] / 1000) + formatString: #,0 + displayFolder: План закупки + + measure 'План закупки ост. период, usd' = + + DIVIDE([План закупки ост. период, руб], [Курс TODAY-1, usd2], 0) + formatString: #,0 + displayFolder: План закупки + + measure 'План год, руб' = ``` + + + VAR PlanGroups = + SUMMARIZE( + 'Номенклатура', + 'Группы'[first group], + 'Номенклатура'[Менеджер по закупкам], + 'Номенклатура'[Товарный менеджер] + ) + + VAR FilterPlanGroups = + TREATAS( + PlanGroups, + 'План продаж по группам'[group_id], + 'План продаж по группам'[Менеджер по закупкам], + 'План продаж по группам'[Товарный менеджер] + ) + + VAR Result = + CALCULATE( + SUM('План продаж по группам'[План продаж, руб]), KEEPFILTERS(FilterPlanGroups), + FILTER('План продаж по группам',YEAR('План продаж по группам'[Месяц]) = YEAR(MAX('.Календарь'[Дата]))) + ) + + RETURN Result + ``` + formatString: #,0 + displayFolder: План по группам руб + + annotation PBI_FormatHint = {"isDecimal":true} + + measure 'План продаж месяц, руб' = ``` + + + VAR PlanGroups = + SUMMARIZE( + 'Номенклатура', + 'Группы'[first group], + 'Номенклатура'[Менеджер по закупкам], + 'Номенклатура'[Товарный менеджер] + ) + + VAR FilterPlanGroups = + TREATAS( + PlanGroups, + 'План продаж по группам'[group_id], + 'План продаж по группам'[Менеджер по закупкам], + 'План продаж по группам'[Товарный менеджер] + ) + + VAR Result = + CALCULATE( + SUM('План продаж по группам'[План продаж, руб]), KEEPFILTERS(FilterPlanGroups), + FILTER('План продаж по группам',MONTH('План продаж по группам'[Месяц]) = MONTH(MAX('.Календарь'[Дата]))), + FILTER('План продаж по группам',YEAR('План продаж по группам'[Месяц]) = YEAR(MAX('.Календарь'[Дата]))) + ) + + RETURN Result + ``` + formatString: #,0 + displayFolder: План по группам руб + + annotation PBI_FormatHint = {"isDecimal":true} + + measure '% план год (р)' = ``` + + DIVIDE ( + [Сумма продаж + РК, руб], [План год, руб], BLANK() + ) + ``` + formatString: 0.00%;-0.00%;0.00% + displayFolder: План по группам руб + + measure '% план месяц (р)' = ``` + + DIVIDE ( + [Сумма продаж + РК, руб], [План продаж месяц, руб], BLANK() + ) + ``` + formatString: 0.00%;-0.00%;0.00% + displayFolder: План по группам руб + + measure 'Аппроксимация год по группам, руб' = ``` + + VAR CySales = [Сумма продаж + РК, руб] + + VAR LastSalesDay = + INT( + LASTNONBLANK('.Календарь'[Дата], [Сумма продаж + РК, руб] > 0) - + STARTOFYEAR('.Календарь'[Дата].[Date]) + ) + 1 + + + VAR YearDays = + INT( + ENDOFYEAR('.Календарь'[Дата].[Date]) - STARTOFYEAR('.Календарь'[Дата].[Date]) + ) + 1 + + VAR Approx = + IF( + NOT ISBLANK ( CySales ), + DIVIDE( + 'Основной отчет'[YTD Сумма продаж с начала года, руб] * YearDays , + LastSalesDay + ) + ) + RETURN Approx + ``` + formatString: #,0 + displayFolder: План по группам руб + + measure 'Аппроксимация месяц по группам, руб' = ``` + + VAR CySales = [Сумма продаж + РК, руб] + VAR LastSalesDay = DAY(LASTNONBLANK('.Календарь'[Дата], [Сумма продаж + РК, руб] > 0)) + VAR MonthDays = DAY(EOMONTH(MAX('.Календарь'[Дата]), 0)) + VAR Approx = + IF( + NOT ISBLANK ( CySales ), + DIVIDE( + 'Основной отчет'[MTD Сумма продаж с начала месяца, руб] * MonthDays , + LastSalesDay + ) + ) + RETURN Approx + ``` + formatString: #,0 + displayFolder: План по группам руб + + measure 'Аппроксим. год по группам руб, %' = ``` + + DIVIDE( + [Аппроксимация год по группам, руб], [План год, руб] + ) + ``` + formatString: 0.00%;-0.00%;0.00% + displayFolder: План по группам руб + + measure 'Аппроксим. месяц по группам руб, %' = ``` + + DIVIDE( + [Аппроксимация месяц по группам, руб], [План продаж месяц, руб] + ) + ``` + formatString: 0.00%;-0.00%;0.00% + displayFolder: План по группам руб + + column Месяц + dataType: dateTime + isHidden + formatString: Long Date + summarizeBy: none + sourceColumn: Месяц + + variation Изменение + isDefault + relationship: 6bdd8855-c6d2-4c21-b90f-cb9f0b0bd52e + defaultHierarchy: LocalDateTable_704570fc-e0c6-4914-97ab-ebb645a2ab6e.'Иерархия дат' + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + annotation UnderlyingDateTimeDataType = Date + + column 'План продаж, usd' + dataType: double + isHidden + formatString: #,0 + summarizeBy: sum + sourceColumn: План продаж, usd + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isDecimal":true} + + column group_id + dataType: string + isHidden + summarizeBy: none + sourceColumn: group_id + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column 'Товарный менеджер' + dataType: string + isHidden + summarizeBy: none + sourceColumn: Товарный менеджер + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column 'Менеджер по закупкам' + dataType: string + isHidden + summarizeBy: none + sourceColumn: Менеджер по закупкам + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column 'План продаж, руб' = 'План продаж по группам'[План продаж, usd] * 102 + isHidden + formatString: #,0 + summarizeBy: sum + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isDecimal":true} + + partition 'План продаж по группам' = m + mode: import + source = + let + Источник = Sql.Database("prdsql", "mag_pbi"), + pbi_ПланыПродажПоГруппам = Источник{[Schema="pbi",Item="ПланыПродажПоГруппам"]}[Data], + #"Измененный тип" = Table.TransformColumnTypes(pbi_ПланыПродажПоГруппам,{{"Месяц", type date}}), + #"Переименованные столбцы" = Table.RenameColumns(#"Измененный тип",{{"План продаж", "План продаж, usd"}}) + in + #"Переименованные столбцы" + + annotation PBI_ResultType = Table + diff --git a/analytics/pbi/model/report/Model/tables/Расходы по годам.tmdl b/analytics/pbi/model/report/Model/tables/Расходы по годам.tmdl new file mode 100644 index 0000000..0825a46 --- /dev/null +++ b/analytics/pbi/model/report/Model/tables/Расходы по годам.tmdl @@ -0,0 +1,220 @@ +table 'Расходы по годам' + isHidden + + measure '% от выручки 2024' = ``` + + VAR summa = + CALCULATE( + SUM('Расходы по годам'[Сумма]), + 'Расходы по годам'[Категория] IN { "Реклама", "Платежи в бюджет", "Расходы", "Ведение р/счета", "Прочие выплаты", "Канцелярия", "Питание", "Хозяйственные расходы", "Оргтехника и IT" + } && 'Расходы по годам'[Год] = 2024 + ) + RETURN + DIVIDE( + //[Платежи в бюджет 2024] + [Аренда 2024] + [Прочие расходы 2024], + summa, + CALCULATE( + 'Основной отчет'[Сумма продаж + РК, руб], + FILTER( ALL('.Календарь'), '.Календарь'[Дата].[Год] = 2024 ), + ALL('Себестоимость') + ) + ) * + CALCULATE( + 'Основной отчет'[Сумма продаж + РК, руб], + FILTER('.Календарь', '.Календарь'[Дата].[Год]=2024) + ) + + ``` + formatString: #,0 + isHidden + displayFolder: расчеты 2024 + + changedProperty = IsHidden + + annotation PBI_FormatHint = {"isDecimal":true} + + measure 'Расходы на строку 2024' = ``` + + VAR summa = + 5/8 * CALCULATE( + SUM('Расходы по годам'[Сумма]), + 'Расходы по годам'[Категория] = "Зарплата" + && 'Расходы по годам'[Год] = 2024 + ) + + 1/2 * CALCULATE( + SUM('Расходы по годам'[Сумма]), + 'Расходы по годам'[Категория] IN { "Транспортные расходы", "Аренда"} + && 'Расходы по годам'[Год] = 2024 + ) + + RETURN + DIVIDE( + summa, + CALCULATE( + 'Основной отчет'[Количество строк], + FILTER( ALL('.Календарь'), '.Календарь'[Дата].[Год] = 2024 ), + ALL('Себестоимость') + ) + ) * + CALCULATE( + 'Основной отчет'[Количество строк], + FILTER('.Календарь', '.Календарь'[Дата].[Год]=2024) + ) + ``` + formatString: #,0 + isHidden + displayFolder: расчеты 2024 + + changedProperty = IsHidden + + annotation PBI_FormatHint = {"isDecimal":true} + + measure 'Расходы на упаковку 2024' = ``` + + VAR summa = + 3/8 * CALCULATE( + SUM('Расходы по годам'[Сумма]), + 'Расходы по годам'[Категория] = "Зарплата" + && 'Расходы по годам'[Год] = 2024 + ) + + CALCULATE( + SUM('Расходы по годам'[Сумма]), + 'Расходы по годам'[Категория] = "Содержание офиса и складов" + && 'Расходы по годам'[Год] = 2024 + ) + + 1/2 * CALCULATE( + SUM('Расходы по годам'[Сумма]), + 'Расходы по годам'[Категория] IN { "Транспортные расходы", "Аренда"} + && 'Расходы по годам'[Год] = 2024 + ) + + RETURN + DIVIDE( + summa, + CALCULATE( + 'Основной отчет'[Количество продаж, упак], + FILTER( ALL('.Календарь'), '.Календарь'[Дата].[Год] = 2024 ), + ALL('Себестоимость') + ) + ) * + CALCULATE( + 'Основной отчет'[Количество продаж, упак], + FILTER('.Календарь', '.Календарь'[Дата].[Год]=2024) + ) + ``` + formatString: #,0 + isHidden + displayFolder: расчеты 2024 + + changedProperty = IsHidden + + annotation PBI_FormatHint = {"isDecimal":true} + + measure 'Чистая прибыль 2024' = ``` + + CALCULATE( + 'Основной отчет'[Сумма продаж + РК, руб] - 'Основной отчет'[Сумма учетная, руб] + - ( [% от выручки 2024] + [Расходы на строку 2024] + [Расходы на упаковку 2024] ), + FILTER('.Календарь', '.Календарь'[Дата].[Год] = 2024) + ) + /*CALCULATE( + 'Основной отчет'[Сумма продаж, руб] - 'Основной отчет'[Сумма учетная, руб] - + ([Расходы на упаковку 2024] * 'Основной отчет'[Количество продаж, упак]) - + ([Расходы на строку 2024] * 'Основной отчет'[Количество строк]) - + [Расходы через выручку 2024], + FILTER('.Календарь', '.Календарь'[Дата].[Год] = 2024) + ) + */ + + + ``` + formatString: #,0 + isHidden + + changedProperty = IsHidden + + annotation PBI_FormatHint = {"isDecimal":true} + + measure 'Расходы на заказы 2024' = ``` + + VAR summa = + 5/12 * CALCULATE( + SUM('Расходы по годам'[Сумма]), + 'Расходы по годам'[Категория] = "Зарплата" + && 'Расходы по годам'[Год] = 2024 + ) + + CALCULATE( + SUM('Расходы по годам'[Сумма]), + 'Расходы по годам'[Категория] IN { "Транспортные расходы", "Аренда" } + && 'Расходы по годам'[Год] = 2024 + ) + + RETURN + DIVIDE( + summa, + CALCULATE( + 'Основной отчет'[Количество заказов], + FILTER( ALL('.Календарь'), '.Календарь'[Дата].[Год] = 2024 ), + ALL('Себестоимость') + ) + ) * + CALCULATE( + 'Основной отчет'[Количество заказов], + FILTER('.Календарь', '.Календарь'[Дата].[Год]=2024) + ) + ``` + formatString: #,0 + isHidden + displayFolder: расчеты 2024 + + changedProperty = IsHidden + + annotation PBI_FormatHint = {"isDecimal":true} + + column Категория + dataType: string + isHidden + summarizeBy: none + sourceColumn: Категория + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column Сумма + dataType: double + isHidden + summarizeBy: sum + sourceColumn: Сумма + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column Год + dataType: int64 + isHidden + formatString: 0 + summarizeBy: sum + sourceColumn: Год + + changedProperty = DataType + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + partition 'Расходы по годам' = m + mode: import + source = + let + Источник = Sql.Databases("prdsql"), + mag_pbi = Источник{[Name="mag_pbi"]}[Data], + #"pbi_Расходы по годам" = mag_pbi{[Schema="pbi",Item="Расходы по годам"]}[Data] + in + #"pbi_Расходы по годам" + + changedProperty = IsHidden + diff --git a/analytics/pbi/model/report/Model/tables/Резервы.tmdl b/analytics/pbi/model/report/Model/tables/Резервы.tmdl new file mode 100644 index 0000000..0ed007c --- /dev/null +++ b/analytics/pbi/model/report/Model/tables/Резервы.tmdl @@ -0,0 +1,68 @@ +table Резервы + + column artic_id + dataType: string + isHidden + summarizeBy: none + sourceColumn: artic_id + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column 'В резерве всего, шт' + dataType: double + formatString: #,0 + summarizeBy: sum + sourceColumn: В резерве всего, шт + + annotation SummarizationSetBy = Automatic + + column 'В резерве всего, упак' + dataType: double + formatString: #,0 + summarizeBy: sum + sourceColumn: В резерве всего, упак + + annotation SummarizationSetBy = Automatic + + column Склад + dataType: string + summarizeBy: none + sourceColumn: Склад + + annotation SummarizationSetBy = Automatic + + column 'В резерве всего, руб' = 'Резервы'[В резерве всего, шт] * RELATED('Номенклатура'[Цена учетная, руб]) + formatString: #,0 + summarizeBy: sum + + annotation SummarizationSetBy = Automatic + + column 'Дата обновления' + dataType: dateTime + isHidden + formatString: Long Date + summarizeBy: none + sourceColumn: Дата обновления + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + annotation UnderlyingDateTimeDataType = Date + + partition Резервы = m + mode: import + source = + let + Источник = Sql.Database("prdsql", "mag_pbi"), + pbi_Резервы = Источник{[Schema="pbi",Item="Резервы"]}[Data], + #"Измененный тип" = Table.TransformColumnTypes(pbi_Резервы,{{"Склад", type text}}) + in + #"Измененный тип" + + annotation PBI_NavigationStepName = Навигация + + annotation PBI_ResultType = Table + diff --git a/analytics/pbi/model/report/Model/tables/Себестоимость.tmdl b/analytics/pbi/model/report/Model/tables/Себестоимость.tmdl new file mode 100644 index 0000000..89b1b74 --- /dev/null +++ b/analytics/pbi/model/report/Model/tables/Себестоимость.tmdl @@ -0,0 +1,463 @@ +table Себестоимость + + column Период + dataType: dateTime + formatString: General Date + summarizeBy: none + sourceColumn: Период + + changedProperty = DataType + + annotation SummarizationSetBy = Automatic + + column Статья + dataType: string + summarizeBy: none + sourceColumn: Статья + + annotation SummarizationSetBy = Automatic + + column 'Вид операции' + dataType: string + summarizeBy: none + sourceColumn: Вид операции + + annotation SummarizationSetBy = Automatic + + column Организация + dataType: string + isHidden + summarizeBy: none + sourceColumn: Организация + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column Контрагент + dataType: string + summarizeBy: none + sourceColumn: Контрагент + + annotation SummarizationSetBy = Automatic + + column Менеджер + dataType: string + summarizeBy: none + sourceColumn: Менеджер + + annotation SummarizationSetBy = Automatic + + column 'Номер документа' + dataType: string + summarizeBy: none + sourceColumn: Номер документа + + annotation SummarizationSetBy = Automatic + + column 'Валюта документа' + dataType: string + summarizeBy: none + sourceColumn: Валюта документа + + annotation SummarizationSetBy = Automatic + + column artic_id + dataType: string + summarizeBy: none + sourceColumn: artic_id + + annotation SummarizationSetBy = Automatic + + column Количество + dataType: double + summarizeBy: sum + sourceColumn: Количество + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column 'Сумма plus МП, руб' + dataType: double + formatString: #,0.00 + summarizeBy: sum + sourceColumn: Сумма plus МП, руб + + annotation SummarizationSetBy = Automatic + + column Закупка + dataType: double + formatString: #,0.00000 + summarizeBy: sum + sourceColumn: Закупка + + annotation SummarizationSetBy = Automatic + + column 'Закупка, usd2' + dataType: double + formatString: 0.0000000 + summarizeBy: sum + sourceColumn: Закупка, usd2 + + annotation SummarizationSetBy = Automatic + + column 'Курс usd2' + dataType: double + summarizeBy: sum + sourceColumn: Курс usd2 + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column 'Курс usd' + dataType: double + summarizeBy: sum + sourceColumn: Курс usd + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column Таможня + dataType: double + formatString: 0.00000 + summarizeBy: sum + sourceColumn: Таможня + + annotation SummarizationSetBy = Automatic + + column ЕАЭС + dataType: double + formatString: 0.00000 + summarizeBy: sum + sourceColumn: ЕАЭС + + annotation SummarizationSetBy = Automatic + + column 'Учетная цена' + dataType: double + formatString: 0.00000 + summarizeBy: sum + sourceColumn: Учетная цена + + annotation SummarizationSetBy = Automatic + + column 'Учетная цена USD2+2' + dataType: double + formatString: 0.0000000 + summarizeBy: sum + sourceColumn: Учетная цена USD2+2 + + annotation SummarizationSetBy = Automatic + + column 'Заказ закрыт' + dataType: dateTime + formatString: Long Date + summarizeBy: none + sourceColumn: Заказ закрыт + + variation Variation + isDefault + relationship: d56f34dd-d18a-4511-b10b-85895b67822c + defaultHierarchy: LocalDateTable_93d80160-0984-4e44-91de-316b6ab26727.'Иерархия дат' + + annotation SummarizationSetBy = Automatic + + annotation UnderlyingDateTimeDataType = Date + + column Маркетинг + dataType: double + formatString: 0.00000 + summarizeBy: sum + sourceColumn: Маркетинг + + annotation SummarizationSetBy = Automatic + + column Доставка + dataType: double + formatString: 0.00000 + summarizeBy: sum + sourceColumn: Доставка + + annotation SummarizationSetBy = Automatic + + column НДС + dataType: double + formatString: 0.00000 + summarizeBy: sum + sourceColumn: НДС + + annotation SummarizationSetBy = Automatic + + column ЗатратыМП + dataType: double + formatString: 0.00000 + summarizeBy: sum + sourceColumn: ЗатратыМП + + annotation SummarizationSetBy = Automatic + + column PartnerId + dataType: string + summarizeBy: none + sourceColumn: PartnerId + + annotation SummarizationSetBy = Automatic + + column 'Доставка, usd' = ``` + + DIVIDE('Себестоимость'[Доставка], 'Себестоимость'[Курс usd2], 0) + + ``` + formatString: 0.0000000 + summarizeBy: sum + + annotation SummarizationSetBy = Automatic + + column 'НДС, usd' = ``` + + DIVIDE('Себестоимость'[НДС], 'Себестоимость'[Курс usd2], 0) + + ``` + formatString: 0.0000000 + summarizeBy: sum + + annotation SummarizationSetBy = Automatic + + column 'Таможня, usd' = ``` + + DIVIDE('Себестоимость'[Таможня], 'Себестоимость'[Курс usd2], 0) + + ``` + formatString: 0.0000000 + summarizeBy: sum + + annotation SummarizationSetBy = Automatic + + column 'Производство, usd' = ``` + + DIVIDE('Себестоимость'[Производство], 'Себестоимость'[Курс usd2], 0) + + ``` + formatString: 0.0000000 + summarizeBy: sum + + annotation SummarizationSetBy = Automatic + + column ЗатратыСкладХранение + dataType: double + summarizeBy: sum + sourceColumn: ЗатратыСкладХранение + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column 'ЗатратыСкладХранение, usd' = ``` + + DIVIDE('Себестоимость'[ЗатратыСкладХранение], 'Себестоимость'[Курс usd2], 0) + + ``` + summarizeBy: sum + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column 'Сумма учетная' = ``` + -1 * ( + 'Себестоимость'[Закупка] + 'Себестоимость'[Доставка] + + 'Себестоимость'[НДС] + 'Себестоимость'[Таможня] + + 'Себестоимость'[Производство] - 'Себестоимость'[Доп расходы]) + ``` + isHidden + formatString: #,0.00000 + summarizeBy: sum + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column 'Сумма учетная, usd' = ``` + -1 * ( + 'Себестоимость'[Закупка, usd2] + 'Себестоимость'[Доставка, usd] + + 'Себестоимость'[НДС, usd] + 'Себестоимость'[Таможня, usd] + + 'Себестоимость'[Производство, usd] - 'Себестоимость'[Доп расходы USD2+2]) + ``` + isHidden + summarizeBy: sum + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column 'Номер заказа' + dataType: string + summarizeBy: none + sourceColumn: Номер заказа + + annotation SummarizationSetBy = Automatic + + column 'Хоз операция' + dataType: string + summarizeBy: none + sourceColumn: Хоз операция + + annotation SummarizationSetBy = Automatic + + column Приемка + dataType: double + summarizeBy: sum + sourceColumn: Приемка + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column АтсМаркировка + dataType: double + summarizeBy: sum + sourceColumn: АтсМаркировка + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column ВремяВыполненияМинут + dataType: double + summarizeBy: sum + sourceColumn: ВремяВыполненияМинут + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column СборкаЗаказа + dataType: double + summarizeBy: sum + sourceColumn: СборкаЗаказа + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column Производство + dataType: double + summarizeBy: sum + sourceColumn: Производство + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column КоличествоУпаковок + dataType: double + summarizeBy: sum + sourceColumn: КоличествоУпаковок + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column 'Учетная сумма, руб' + dataType: double + formatString: 0.00000 + summarizeBy: sum + sourceColumn: Учетная сумма, руб + + annotation SummarizationSetBy = Automatic + + column 'Учетная сумма, usd' + dataType: double + formatString: 0.0000000 + summarizeBy: sum + sourceColumn: Учетная сумма, usd + + annotation SummarizationSetBy = Automatic + + column 'Сумма скидки' + dataType: double + formatString: #,0 + summarizeBy: sum + sourceColumn: Сумма скидки + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isDecimal":true} + + column 'Доп расходы' + dataType: double + summarizeBy: sum + sourceColumn: Доп расходы + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column 'Доп расходы USD2+2' + dataType: double + summarizeBy: sum + sourceColumn: Доп расходы USD2+2 + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column 'Сумма plus МП, usd' + dataType: double + formatString: #,0.00 + summarizeBy: sum + sourceColumn: Сумма plus МП, usd + + annotation SummarizationSetBy = Automatic + + partition Себестоимость = m + mode: import + source = + let + Источник = Sql.Database("prdsql", "mag_pbi"), + pbiProd_СебестоимостьСводныйОт2022 = Источник{[Schema="pbiProd",Item="СводныйСебестоимость Для PBI"]}[Data], + #"Changed Type" = Table.TransformColumnTypes(pbiProd_СебестоимостьСводныйОт2022,{{"Период", type date}}), + #"Переименованные столбцы" = Table.RenameColumns(#"Changed Type",{{"Сумма", "Сумма, руб"}}), + Округлено = Table.TransformColumns(#"Переименованные столбцы",{{"Сумма, руб", each Number.Round(_, 5), type number}}), + Округлено1 = Table.TransformColumns(Округлено,{{"СуммаБезНДС", each Number.Round(_, 5), type number}}), + Округлено2 = Table.TransformColumns(Округлено1,{{"Закупка", each Number.Round(_, 5), type number}}), + Округлено3 = Table.TransformColumns(Округлено2,{{"СуммаРучнойСкидки", each Number.Round(_, 5), type number}}), + Округлено4 = Table.TransformColumns(Округлено3,{{"СуммаАвтоСкидки", each Number.Round(_, 5), type number}}), + Округлено5 = Table.TransformColumns(Округлено4,{{"Закупка, usd2", each Number.Round(_, 7), type number}}), + Округлено6 = Table.TransformColumns(Округлено5,{{"Таможня", each Number.Round(_, 5), type number}}), + Округлено7 = Table.TransformColumns(Округлено6,{{"ЕАЭС", each Number.Round(_, 5), type number}}), + Округлено8 = Table.TransformColumns(Округлено7,{{"Учетная цена", each Number.Round(_, 5), type number}}), + Округлено9 = Table.TransformColumns(Округлено8,{{"Учетная цена USD2+2", each Number.Round(_, 7), type number}}), + Округлено10 = Table.TransformColumns(Округлено9,{{"Маркетинг", each Number.Round(_, 5), type number}}), + Округлено11 = Table.TransformColumns(Округлено10,{{"Доставка", each Number.Round(_, 5), type number}}), + Округлено12 = Table.TransformColumns(Округлено11,{{"НДС", each Number.Round(_, 5), type number}}), + Округлено13 = Table.TransformColumns(Округлено12,{{"Производство", each Number.Round(_, 5), type number}}), + Округлено14 = Table.TransformColumns(Округлено13,{{"ЗатратыМП", each Number.Round(_, 5), type number}}), + Округлено15 = Table.TransformColumns(Округлено14,{{"Учетная стоимость", each Number.Round(_, 5), type number}}), + Округлено16 = Table.TransformColumns(Округлено15,{{"Учетная стоимость USD2+2", each Number.Round(_, 7), type number}}), + #"Переименованные столбцы1" = Table.RenameColumns(Округлено16,{{"Сумма, руб", "Сумма plus МП, руб"}}), + #"Удаленные столбцы" = Table.RemoveColumns(#"Переименованные столбцы1",{"id", "Code", "Ценовая группа", "Учетная стоимость", "Учетная стоимость USD2+2", "СуммаАвтоСкидки", "СуммаБезНДС", "СуммаРучнойСкидки", "Тип документа", "Номер регистратора"}), + #"Замененное значение" = Table.ReplaceValue(#"Удаленные столбцы","-","",Replacer.ReplaceText,{"Номер заказа"}), + #"Замененное значение1" = Table.ReplaceValue(#"Замененное значение"," ","",Replacer.ReplaceText,{"Номер заказа"}), + #"Замененное значение2" = Table.ReplaceValue(#"Замененное значение1",null,"-",Replacer.ReplaceValue,{"Организация"}), + #"Удаленные столбцы1" = Table.RemoveColumns(#"Замененное значение2",{"Партнер", "Сумма скидки USD2+2"}), + Округлено17 = Table.TransformColumns(#"Удаленные столбцы1",{{"АтсМаркировка", each Number.Round(_, 5), type number}}), + Округлено18 = Table.TransformColumns(Округлено17,{{"Приемка", each Number.Round(_, 5), type number}}), + Округлено19 = Table.TransformColumns(Округлено18,{{"СборкаЗаказа", each Number.Round(_, 5), type number}}), + #"Измененный тип" = Table.TransformColumnTypes(Округлено19,{{"Заказ закрыт", type date}}), + #"Замененное значение3" = Table.ReplaceValue(#"Измененный тип","Супер пупер","АНТУРАЖ ЛТД ООО",Replacer.ReplaceText,{"Организация"}), + #"Добавлен пользовательский объект" = Table.AddColumn(#"Замененное значение3", "Пользовательский", each [#"Сумма plus МП, руб"]/[Курс usd2]), + #"Измененный тип1" = Table.TransformColumnTypes(#"Добавлен пользовательский объект",{{"Пользовательский", type number}}), + #"Переименованные столбцы2" = Table.RenameColumns(#"Измененный тип1",{{"Пользовательский", "Сумма plus МП, usd"}}) + in + #"Переименованные столбцы2" + + annotation PBI_ResultType = Table + + annotation PBI_NavigationStepName = Навигация + diff --git a/analytics/pbi/model/report/Model/tables/Стоимость МП.tmdl b/analytics/pbi/model/report/Model/tables/Стоимость МП.tmdl new file mode 100644 index 0000000..ff035cb --- /dev/null +++ b/analytics/pbi/model/report/Model/tables/Стоимость МП.tmdl @@ -0,0 +1,114 @@ +table 'Стоимость МП' + + column Период + dataType: dateTime + formatString: m/d/yyyy + summarizeBy: none + sourceColumn: Период + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + annotation UnderlyingDateTimeDataType = Date + + annotation PBI_FormatHint = {"isDateTimeCustom":true} + + column 'Номер отчета комиссионера' + dataType: string + summarizeBy: none + sourceColumn: Номер отчета комиссионера + + annotation SummarizationSetBy = Automatic + + column artic_id + dataType: string + summarizeBy: none + sourceColumn: artic_id + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column 'Статья себестоимости' + dataType: string + summarizeBy: none + sourceColumn: Статья себестоимости + + annotation SummarizationSetBy = Automatic + + column 'Расходы МП, руб' + dataType: double + summarizeBy: sum + sourceColumn: Расходы МП, руб + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column Организация + dataType: string + isHidden + summarizeBy: none + sourceColumn: Организация + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column Партнер + dataType: string + isHidden + summarizeBy: none + sourceColumn: Партнер + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column Курс + dataType: double + isHidden + summarizeBy: sum + sourceColumn: Курс + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column ПартнерКод + dataType: string + summarizeBy: none + sourceColumn: ПартнерКод + + annotation SummarizationSetBy = Automatic + + column 'Расходы МП, usd' + dataType: double + summarizeBy: sum + sourceColumn: Расходы МП, usd + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + partition 'Стоимость МП-9505004b-b265-4a48-bb15-0e21468f67fc' = m + mode: import + source = + let + Источник = Sql.Database("prdsql", "mag_pbi"), + #"sales_Стоимость обработки заказа" = Источник{[Schema="pbi",Item="Стоимость обработки заказа"]}[Data], + #"Переименованные столбцы" = Table.RenameColumns(#"sales_Стоимость обработки заказа",{{"date", "Период"}}), + #"Измененный тип" = Table.TransformColumnTypes(#"Переименованные столбцы",{{"Период", type date}}), + #"Переименованные столбцы1" = Table.RenameColumns(#"Измененный тип",{{"Сумма", "Расходы МП, руб"}}), + Округлено = Table.TransformColumns(#"Переименованные столбцы1",{{"Расходы МП, руб", each Number.Round(_, 5), type number}}), + Округлено1 = Table.TransformColumns(Округлено,{{"Расходы МП, usd", each Number.Round(_, 7), type number}}) + in + Округлено1 + + annotation PBI_ResultType = Table + + annotation PBI_NavigationStepName = Навигация + diff --git a/analytics/pbi/model/report/Model/tables/Упущенные продажи.tmdl b/analytics/pbi/model/report/Model/tables/Упущенные продажи.tmdl new file mode 100644 index 0000000..813a37f --- /dev/null +++ b/analytics/pbi/model/report/Model/tables/Упущенные продажи.tmdl @@ -0,0 +1,171 @@ +table 'Упущенные продажи' + + measure '_Упущ. продажи, руб' = ``` + DIVIDE( + CALCULATE( + 'Основной отчет'[Сумма продаж + РК, руб], FILTER('.Календарь', '.Календарь'[Дата] > DATE(2023,01,01)) + ), + SUM('Упущенные продажи'[Дней в продаже]), 0) * SUM('Упущенные продажи'[Дней отсутствия в продаже] + ) + ``` + isHidden + + changedProperty = IsHidden + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + measure '_Упущ. продажи, usd' = ``` + DIVIDE( + CALCULATE( + 'Основной отчет'[Сумма продаж + РК, usd], FILTER('.Календарь', '.Календарь'[Дата] > DATE(2023,01,01)) + ), + SUM('Упущенные продажи'[Дней в продаже]), 0) * SUM('Упущенные продажи'[Дней отсутствия в продаже] + ) + ``` + isHidden + + changedProperty = IsHidden + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + measure '_Упущ. учетная, руб' = ``` + DIVIDE( + CALCULATE( + 'Основной отчет'[Сумма учетная, руб], FILTER('.Календарь', '.Календарь'[Дата] > DATE(2023,01,01)) + ), + SUM('Упущенные продажи'[Дней в продаже]), 0) * SUM('Упущенные продажи'[Дней отсутствия в продаже] + ) + ``` + isHidden + + changedProperty = IsHidden + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + measure '_Упущ. учетная, usd' = ``` + DIVIDE( + CALCULATE( + 'Основной отчет'[Сумма учетная, usd], FILTER('.Календарь', '.Календарь'[Дата] > DATE(2023,01,01)) + ), + SUM('Упущенные продажи'[Дней в продаже]), 0) * SUM('Упущенные продажи'[Дней отсутствия в продаже] + ) + ``` + isHidden + + changedProperty = IsHidden + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + measure 'Упущ. сумма учетная, руб' = SUMX('Номенклатура', [_Упущ. учетная, руб]) + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + measure 'Упущ. сумма учетная, USD' = SUMX('Номенклатура', [_Упущ. учетная, USD]) + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + measure 'Упущ. торг. надбавка, руб' = ``` + [Упущ. сумма продаж, руб] - [Упущ. сумма учетная, руб] + ``` + formatString: #,0 + + annotation PBI_FormatHint = {"isDecimal":true} + + measure 'Упущ. торг. надбавка, USD' = ``` + [Упущ. сумма продаж, USD] - [Упущ. сумма учетная, USD] + ``` + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column Дата + dataType: dateTime + isHidden + formatString: Long Date + summarizeBy: none + sourceColumn: Дата + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + annotation UnderlyingDateTimeDataType = Date + + column artic_id + dataType: string + isHidden + summarizeBy: none + sourceColumn: artic_id + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column 'Дней в продаже' + dataType: int64 + formatString: #,0 + summarizeBy: sum + sourceColumn: Дней в продаже + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isDecimal":true} + + column 'Дата первого поступления' = FIRSTDATE('Остатки'[Дата]) + formatString: Long Date + summarizeBy: none + + variation Изменение + isDefault + relationship: 28a764af-4e8a-4c89-8ceb-304403c0d71a + defaultHierarchy: LocalDateTable_2f146245-8120-4ed9-87dc-af8699bb0274.'Иерархия дат' + + changedProperty = DataType + + annotation SummarizationSetBy = Automatic + + annotation UnderlyingDateTimeDataType = Date + + column 'Дней отсутствия в продаже' = IF( AND ([Дней в продаже] = 0, 'Упущенные продажи'[Дата] > [Дата первого поступления]), 1, 0) + isHidden + formatString: 0 + summarizeBy: sum + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column minAvailableQty + dataType: double + summarizeBy: sum + sourceColumn: minAvailableQty + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column sellable_stock + dataType: double + summarizeBy: sum + sourceColumn: sellable_stock + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + partition 'Упущенные продажи' = m + mode: import + source = + let + Источник = Sql.Databases("prdsql"), + mag_pbi = Источник{[Name="mag_pbi"]}[Data], + sales_w_ostatok_da_net = mag_pbi{[Schema="pbi",Item="w_ostatok_da_net"]}[Data], + #"Переименованные столбцы" = Table.RenameColumns(sales_w_ostatok_da_net,{{"dt", "Дата"}, {"ostatok", "Дней в продаже"}}) + in + #"Переименованные столбцы" + + annotation PBI_ResultType = Table + + annotation PBI_NavigationStepName = Навигация + diff --git a/analytics/pbi/model/report/Model/tables/Я.Директ заказы.tmdl b/analytics/pbi/model/report/Model/tables/Я.Директ заказы.tmdl new file mode 100644 index 0000000..54cc9d3 --- /dev/null +++ b/analytics/pbi/model/report/Model/tables/Я.Директ заказы.tmdl @@ -0,0 +1,112 @@ +table 'Я.Директ заказы' + + measure 'Торг. надбавка - расходы директ, руб' = CALCULATE([Торг. надбавка, руб] - SUM('Я.Директ расходы'[Расходы, руб])) + formatString: #,0 + + measure 'Торг. надбавка директ - расходы директ, руб' = + CALCULATE( + [Сумма продаж + МП + РК, руб] - [Сумма учетная, руб] - SUM('Я.Директ расходы'[Расходы, руб]), + FILTER( + ALL('Я.Директ заказы'), + NOT ISBLANK('Я.Директ заказы'[ID покупки]) + ) + ) + formatString: #,0 + + measure 'Торг. надбавка директ, руб' = + CALCULATE( + [Сумма продаж + МП + РК, руб] - [Сумма учетная, руб], + FILTER( + ALL('Я.Директ заказы'), + NOT ISBLANK('Я.Директ заказы'[ID покупки]) + ) + ) + formatString: #,0 + + measure 'Сумма продаж директ, руб' = + CALCULATE( + [Сумма продаж + МП + РК, руб], + FILTER( + ALL('Я.Директ заказы'), + NOT ISBLANK('Я.Директ заказы'[ID покупки]) + ) + ) + formatString: #,0 + + column 'Условия показа' + dataType: string + summarizeBy: none + sourceColumn: Условия показа + + annotation SummarizationSetBy = Automatic + + column 'ID покупки' + dataType: string + summarizeBy: none + sourceColumn: ID покупки + + annotation SummarizationSetBy = Automatic + + column 'Количество покупок' + dataType: int64 + isHidden + formatString: 0 + summarizeBy: sum + sourceColumn: Количество покупок + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column key_dir + dataType: string + summarizeBy: none + sourceColumn: key_dir + + annotation SummarizationSetBy = Automatic + + column 'Сумма заказов директ, руб' + dataType: double + isHidden + summarizeBy: sum + sourceColumn: Сумма заказов директ, руб + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column 'Группа директ' = FIRSTNONBLANK('Я.Директ расходы'[Группа], 'Я.Директ расходы'[Группа]) + summarizeBy: none + + annotation SummarizationSetBy = Automatic + + partition 'Я.Директ заказы' = m + mode: import + source = + let + Источник = Sql.Database("prdsql", "mag_pbi"), + pbi_direct_orders = Источник{[Schema="pbi",Item="direct_orders"]}[Data], + #"Разделить столбец по разделителю" = Table.SplitColumn(pbi_direct_orders, "Кампания", Splitter.SplitTextByDelimiter("N-", QuoteStyle.Csv), {"Кампания.1", "Кампания.2"}), + #"Измененный тип" = Table.TransformColumnTypes(#"Разделить столбец по разделителю",{{"Кампания.1", type text}, {"Кампания.2", type text}}), + #"Удаленные столбцы" = Table.RemoveColumns(#"Измененный тип",{"Кампания.1"}), + #"Замененное значение" = Table.ReplaceValue(#"Удаленные столбцы",")","",Replacer.ReplaceText,{"Кампания.2"}), + #"Разделить столбец по разделителю1" = Table.SplitColumn(#"Замененное значение", "Группа", Splitter.SplitTextByEachDelimiter({"("}, QuoteStyle.Csv, true), {"Группа.1", "Группа.2"}), + #"Измененный тип1" = Table.TransformColumnTypes(#"Разделить столбец по разделителю1",{{"Группа.1", type text}, {"Группа.2", type text}}), + #"Удаленные столбцы1" = Table.RemoveColumns(#"Измененный тип1",{"Группа.1"}), + #"Замененное значение1" = Table.ReplaceValue(#"Удаленные столбцы1",")","",Replacer.ReplaceText,{"Группа.2"}), + #"Вставлено: объединенный столбец" = Table.AddColumn(#"Замененное значение1", "key_dir", each Text.Combine({Text.Trim([Кампания.2]), "-", Text.Trim([Группа.2])}), type text), + #"Добавлен пользовательский объект" = Table.AddColumn(#"Вставлено: объединенный столбец", "Доход директ, руб", each [#"Доход, руб"]/1000), + #"Удаленные столбцы2" = Table.RemoveColumns(#"Добавлен пользовательский объект",{"Доход, руб"}), + #"Измененный тип2" = Table.TransformColumnTypes(#"Удаленные столбцы2",{{"Доход директ, руб", type number}}), + #"Удаленные столбцы3" = Table.RemoveColumns(#"Измененный тип2",{"Группа.2", "Кампания.2"}), + #"Замененное значение2" = Table.ReplaceValue(#"Удаленные столбцы3","-","",Replacer.ReplaceText,{"ID покупки"}), + #"Переименованные столбцы" = Table.RenameColumns(#"Замененное значение2",{{"Доход директ, руб", "Сумма заказов директ, руб"}}) + in + #"Переименованные столбцы" + + annotation PBI_NavigationStepName = Навигация + + annotation PBI_ResultType = Table + diff --git a/analytics/pbi/model/report/Model/tables/Я.Директ расходы.tmdl b/analytics/pbi/model/report/Model/tables/Я.Директ расходы.tmdl new file mode 100644 index 0000000..feac4fe --- /dev/null +++ b/analytics/pbi/model/report/Model/tables/Я.Директ расходы.tmdl @@ -0,0 +1,133 @@ +table 'Я.Директ расходы' + + measure 'Клики директ' = CALCULATE(SUM('Я.Директ расходы'[Клики]), ALL('Я.Директ заказы'[ID покупки])) + formatString: #,0 + + measure 'Показы директ' = CALCULATE(SUM('Я.Директ расходы'[Показы]), ALL('Я.Директ заказы'[ID покупки])) + formatString: #,0 + + measure 'Расходы директ, руб' = CALCULATE(SUM('Я.Директ расходы'[Расходы, руб]), ALL('Я.Директ заказы'[ID покупки])) + formatString: #,0 + + column Дата + dataType: dateTime + isHidden + formatString: Long Date + summarizeBy: none + sourceColumn: Дата + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + annotation UnderlyingDateTimeDataType = Date + + column Кампания + dataType: string + summarizeBy: none + sourceColumn: Кампания + + annotation SummarizationSetBy = Automatic + + column Группа + dataType: string + summarizeBy: none + sourceColumn: Группа + + annotation SummarizationSetBy = Automatic + + column 'Условия показа' + dataType: string + summarizeBy: none + sourceColumn: Условия показа + + annotation SummarizationSetBy = Automatic + + column 'N условия показа' + dataType: string + summarizeBy: none + sourceColumn: N условия показа + + annotation SummarizationSetBy = Automatic + + column Показы + dataType: int64 + isHidden + formatString: 0 + summarizeBy: sum + sourceColumn: Показы + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column Клики + dataType: int64 + isHidden + formatString: 0 + summarizeBy: sum + sourceColumn: Клики + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column 'CTR, %' + dataType: double + summarizeBy: sum + sourceColumn: CTR, % + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + column 'Расходы, руб' + dataType: double + isHidden + formatString: #,0 + summarizeBy: sum + sourceColumn: Расходы, руб + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column key_dir + dataType: string + isHidden + summarizeBy: none + sourceColumn: key_dir + + changedProperty = IsHidden + + annotation SummarizationSetBy = Automatic + + column 'Ср. цена клика, руб' + dataType: double + summarizeBy: sum + sourceColumn: Ср. цена клика, руб + + annotation SummarizationSetBy = Automatic + + annotation PBI_FormatHint = {"isGeneralNumber":true} + + partition 'Я.Директ расходы' = m + mode: import + source = + let + Источник = Sql.Database("prdsql", "mag_pbi"), + pbi_direct_adv_costs = Источник{[Schema="pbi",Item="direct_adv_costs"]}[Data], + #"Измененный тип" = Table.TransformColumnTypes(pbi_direct_adv_costs,{{"Дата", type date}}), + #"Добавлен пользовательский объект" = Table.AddColumn(#"Измененный тип", "Пользовательский", each [#"Расход, руб"]/1000), + #"Переименованные столбцы" = Table.RenameColumns(#"Добавлен пользовательский объект",{{"Пользовательский", "Расходы, руб"}}), + #"Удаленные столбцы" = Table.RemoveColumns(#"Переименованные столбцы",{"Расход, руб"}), + #"Вставлено: объединенный столбец" = Table.AddColumn(#"Удаленные столбцы", "key_dir", each Text.Combine({[N кампании], "-", [N группы]}), type text), + #"Удаленные столбцы2" = Table.RemoveColumns(#"Вставлено: объединенный столбец",{"N кампании", "N группы"}), + #"Измененный тип1" = Table.TransformColumnTypes(#"Удаленные столбцы2",{{"Расходы, руб", type number}}) + in + #"Измененный тип1" + + annotation PBI_NavigationStepName = Навигация + + annotation PBI_ResultType = Table + diff --git a/analytics/pbi/model/report/Report/config.json b/analytics/pbi/model/report/Report/config.json new file mode 100644 index 0000000..177bbdd --- /dev/null +++ b/analytics/pbi/model/report/Report/config.json @@ -0,0 +1,66 @@ +{ + "version": "5.66", + "themeCollection": { + "baseTheme": { + "name": "CY20SU09", + "type": 2, + "version": { + "visual": "1.8.53", + "report": "2.0.53", + "page": "1.3.53" + } + } + }, + "activeSectionIndex": 9, + "defaultDrillFilterOtherVisuals": true, + "slowDataSourceSettings": { + "isCrossHighlightingDisabled": false, + "isSlicerSelectionsButtonEnabled": false, + "isFilterSelectionsButtonEnabled": false, + "isFieldWellButtonEnabled": false, + "isApplyAllButtonEnabled": false + }, + "linguisticSchemaSyncVersion": 2, + "settings": { + "useNewFilterPaneExperience": true, + "allowChangeFilterTypes": true, + "useStylableVisualContainerHeader": true, + "exportDataMode": 1, + "useEnhancedTooltips": true + }, + "objects": { + "section": [ + { + "properties": { + "verticalAlignment": { + "expr": { + "Literal": { + "Value": "'Top'" + } + } + } + } + } + ], + "outspacePane": [ + { + "properties": { + "expanded": { + "expr": { + "Literal": { + "Value": "false" + } + } + }, + "visible": { + "expr": { + "Literal": { + "Value": "true" + } + } + } + } + } + ] + } +} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/filters.json b/analytics/pbi/model/report/Report/filters.json new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/analytics/pbi/model/report/Report/filters.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/report.json b/analytics/pbi/model/report/Report/report.json new file mode 100644 index 0000000..56e4231 --- /dev/null +++ b/analytics/pbi/model/report/Report/report.json @@ -0,0 +1,35 @@ +{ + "id": 22443069, + "layoutOptimization": 0, + "pods": [ + { + "boundSection": "ReportSection1ae8f92a5273f14462dd", + "config": "{}", + "id": 112399774, + "name": "Pod", + "objectId": "1cd74b08-f926-4a57-b91a-4be5e0bb83ac" + } + ], + "publicCustomVisuals": [], + "reportId": 2058200, + "resourcePackages": [ + { + "resourcePackage": { + "disabled": false, + "id": 23531593, + "items": [ + { + "id": 139019140, + "name": "CY20SU09", + "path": "BaseThemes/CY20SU09.json", + "resourcePackageId": 23531593, + "type": 202 + } + ], + "name": "SharedResources", + "reportId": 2058200, + "type": 2 + } + } + ] +} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/001_Себестоимость для сверки/config.json b/analytics/pbi/model/report/Report/sections/001_Себестоимость для сверки/config.json new file mode 100644 index 0000000..f5ec59f --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/001_Себестоимость для сверки/config.json @@ -0,0 +1,17 @@ +{ + "objects": { + "outspacePane": [ + { + "properties": { + "width": { + "expr": { + "Literal": { + "Value": "191L" + } + } + } + } + } + ] + } +} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/001_Себестоимость для сверки/filters.json b/analytics/pbi/model/report/Report/sections/001_Себестоимость для сверки/filters.json new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/001_Себестоимость для сверки/filters.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/001_Себестоимость для сверки/section.json b/analytics/pbi/model/report/Report/sections/001_Себестоимость для сверки/section.json new file mode 100644 index 0000000..e635ee1 --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/001_Себестоимость для сверки/section.json @@ -0,0 +1,8 @@ +{ + "displayName": "Себестоимость для сверки", + "displayOption": 1, + "height": 720, + "name": "ReportSection1ae8f92a5273f14462dd", + "ordinal": 1, + "width": 1280 +} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/001_Себестоимость для сверки/visualContainers/00000_pivotTable (94244)/config.json b/analytics/pbi/model/report/Report/sections/001_Себестоимость для сверки/visualContainers/00000_pivotTable (94244)/config.json new file mode 100644 index 0000000..aeaa3a7 --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/001_Себестоимость для сверки/visualContainers/00000_pivotTable (94244)/config.json @@ -0,0 +1,551 @@ +{ + "name": "942443c8a4be384462a8", + "layouts": [ + { + "id": 0, + "position": { + "x": 0, + "y": 292.24327018943171, + "z": 1000, + "width": 1280, + "height": 292.24327018943171, + "tabOrder": 1000 + } + } + ], + "singleVisual": { + "visualType": "pivotTable", + "projections": { + "Rows": [ + { + "queryRef": ".Календарь.Дата.Изменение.Иерархия дат.Год", + "active": true + }, + { + "queryRef": ".Календарь.Дата.Изменение.Иерархия дат.Квартал" + }, + { + "queryRef": ".Календарь.Дата.Изменение.Иерархия дат.Месяц" + }, + { + "queryRef": ".Календарь.Дата.Изменение.Иерархия дат.День" + } + ], + "Values": [ + { + "queryRef": "Основной отчет.Сумма плюс МП, usd" + }, + { + "queryRef": "Основной отчет.Сумма minus Расходы МП, usd" + }, + { + "queryRef": "Основной отчет.Торг. надбавка, usd" + }, + { + "queryRef": "Основной отчет.Сумма учетная, usd" + }, + { + "queryRef": "Основной отчет.Закупка, usd" + }, + { + "queryRef": "Основной отчет.Доставка, usd" + }, + { + "queryRef": "Основной отчет.НДС, usd" + }, + { + "queryRef": "Основной отчет.Таможня, usd" + }, + { + "queryRef": "Основной отчет.Учет.Доп расходы, usd" + }, + { + "queryRef": "Основной отчет.Сборка, usd" + }, + { + "queryRef": "Основной отчет.Сборка из других товаров, usd" + } + ] + }, + "prototypeQuery": { + "Version": 2, + "From": [ + { + "Name": "о", + "Entity": "Основной отчет", + "Type": 0 + }, + { + "Name": "к", + "Entity": ".Календарь", + "Type": 0 + } + ], + "Select": [ + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Сумма продаж + РК, usd" + }, + "Name": "Основной отчет.Сумма minus Расходы МП, usd", + "NativeReferenceName": "Сумма, usd" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Сумма учетная, usd" + }, + "Name": "Основной отчет.Сумма учетная, usd", + "NativeReferenceName": "Сумма учетная, usd" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Учет.Закупка, usd" + }, + "Name": "Основной отчет.Закупка, usd", + "NativeReferenceName": "Закупка, usd" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Учет.Доставка, usd" + }, + "Name": "Основной отчет.Доставка, usd", + "NativeReferenceName": "Доставка, usd" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Учет.НДС, usd" + }, + "Name": "Основной отчет.НДС, usd", + "NativeReferenceName": "НДС, usd" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Учет.Таможня, usd" + }, + "Name": "Основной отчет.Таможня, usd", + "NativeReferenceName": "Таможня, usd" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Сборка в другие товары, usd" + }, + "Name": "Основной отчет.Сборка, usd", + "NativeReferenceName": "Сборка, usd" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Сборка из других товаров, usd" + }, + "Name": "Основной отчет.Сборка из других товаров, usd", + "NativeReferenceName": "Сборка из других товаров, usd" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Сумма продаж + МП + РК, usd" + }, + "Name": "Основной отчет.Сумма плюс МП, usd", + "NativeReferenceName": "Сумма плюс МП, usd" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Торг. надбавка, usd" + }, + "Name": "Основной отчет.Торг. надбавка, usd", + "NativeReferenceName": "Торг. надбавка, usd" + }, + { + "HierarchyLevel": { + "Expression": { + "Hierarchy": { + "Expression": { + "PropertyVariationSource": { + "Expression": { + "SourceRef": { + "Source": "к" + } + }, + "Name": "Изменение", + "Property": "Дата" + } + }, + "Hierarchy": "Иерархия дат" + } + }, + "Level": "Год" + }, + "Name": ".Календарь.Дата.Изменение.Иерархия дат.Год", + "NativeReferenceName": "Дата Год" + }, + { + "HierarchyLevel": { + "Expression": { + "Hierarchy": { + "Expression": { + "PropertyVariationSource": { + "Expression": { + "SourceRef": { + "Source": "к" + } + }, + "Name": "Изменение", + "Property": "Дата" + } + }, + "Hierarchy": "Иерархия дат" + } + }, + "Level": "Квартал" + }, + "Name": ".Календарь.Дата.Изменение.Иерархия дат.Квартал", + "NativeReferenceName": "Дата Квартал" + }, + { + "HierarchyLevel": { + "Expression": { + "Hierarchy": { + "Expression": { + "PropertyVariationSource": { + "Expression": { + "SourceRef": { + "Source": "к" + } + }, + "Name": "Изменение", + "Property": "Дата" + } + }, + "Hierarchy": "Иерархия дат" + } + }, + "Level": "Месяц" + }, + "Name": ".Календарь.Дата.Изменение.Иерархия дат.Месяц", + "NativeReferenceName": "Дата Месяц" + }, + { + "HierarchyLevel": { + "Expression": { + "Hierarchy": { + "Expression": { + "PropertyVariationSource": { + "Expression": { + "SourceRef": { + "Source": "к" + } + }, + "Name": "Изменение", + "Property": "Дата" + } + }, + "Hierarchy": "Иерархия дат" + } + }, + "Level": "День" + }, + "Name": ".Календарь.Дата.Изменение.Иерархия дат.День", + "NativeReferenceName": "Дата День" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Учет.Доп расходы, usd" + }, + "Name": "Основной отчет.Учет.Доп расходы, usd", + "NativeReferenceName": "Учет.Доп расходы, usd" + } + ] + }, + "expansionStates": [ + { + "roles": [ + "Rows" + ], + "levels": [ + { + "queryRefs": [ + ".Календарь.Дата.Изменение.Иерархия дат.Год" + ], + "isCollapsed": true, + "identityKeys": [ + { + "Column": { + "Expression": { + "SourceRef": { + "Entity": "LocalDateTable_e0374236-67f4-4331-b4f5-c977a3082bab" + } + }, + "Property": "Год" + } + } + ], + "isPinned": true + }, + { + "queryRefs": [ + ".Календарь.Дата.Изменение.Иерархия дат.Квартал" + ], + "isCollapsed": true, + "isPinned": true + }, + { + "queryRefs": [ + ".Календарь.Дата.Изменение.Иерархия дат.Месяц" + ], + "isCollapsed": true + }, + { + "queryRefs": [ + ".Календарь.Дата.Изменение.Иерархия дат.День" + ], + "isCollapsed": true + } + ], + "root": { + "identityValues": null + } + } + ], + "drillFilterOtherVisuals": true, + "objects": { + "columnWidth": [ + { + "properties": { + "value": { + "expr": { + "Literal": { + "Value": "135.78525513679273D" + } + } + } + }, + "selector": { + "metadata": "Основной отчет.Сумма minus Расходы МП, usd" + } + }, + { + "properties": { + "value": { + "expr": { + "Literal": { + "Value": "115.96065779167289D" + } + } + } + }, + "selector": { + "metadata": "Основной отчет.Сборка, usd" + } + }, + { + "properties": { + "value": { + "expr": { + "Literal": { + "Value": "140.8768874231215D" + } + } + } + }, + "selector": { + "metadata": "Основной отчет.Сборка из других товаров, usd" + } + } + ], + "columnFormatting": [ + { + "properties": { + "labelPrecision": { + "expr": { + "Literal": { + "Value": "2L" + } + } + } + }, + "selector": { + "metadata": "Основной отчет.Торг. надбавка, usd" + } + }, + { + "properties": { + "labelPrecision": { + "expr": { + "Literal": { + "Value": "2L" + } + } + } + }, + "selector": { + "metadata": "Основной отчет.Сумма minus Расходы МП, usd" + } + }, + { + "properties": { + "labelPrecision": { + "expr": { + "Literal": { + "Value": "2L" + } + } + } + }, + "selector": { + "metadata": "Основной отчет.Сумма плюс МП, usd" + } + }, + { + "properties": { + "labelPrecision": { + "expr": { + "Literal": { + "Value": "2L" + } + } + } + }, + "selector": { + "metadata": "Основной отчет.Сумма учетная, usd" + } + }, + { + "properties": { + "labelPrecision": { + "expr": { + "Literal": { + "Value": "2L" + } + } + } + }, + "selector": { + "metadata": "Основной отчет.Закупка, usd" + } + }, + { + "properties": { + "labelPrecision": { + "expr": { + "Literal": { + "Value": "2L" + } + } + } + }, + "selector": { + "metadata": "Основной отчет.Доставка, usd" + } + }, + { + "properties": { + "labelPrecision": { + "expr": { + "Literal": { + "Value": "2L" + } + } + } + }, + "selector": { + "metadata": "Основной отчет.НДС, usd" + } + }, + { + "properties": { + "labelPrecision": { + "expr": { + "Literal": { + "Value": "2L" + } + } + } + }, + "selector": { + "metadata": "Основной отчет.Таможня, usd" + } + }, + { + "properties": { + "labelPrecision": { + "expr": { + "Literal": { + "Value": "2L" + } + } + } + }, + "selector": { + "metadata": "Основной отчет.Сборка, usd" + } + }, + { + "properties": { + "labelPrecision": { + "expr": { + "Literal": { + "Value": "2L" + } + } + } + }, + "selector": { + "metadata": "Основной отчет.Сборка из других товаров, usd" + } + } + ] + } + } +} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/001_Себестоимость для сверки/visualContainers/00000_pivotTable (94244)/filters.json b/analytics/pbi/model/report/Report/sections/001_Себестоимость для сверки/visualContainers/00000_pivotTable (94244)/filters.json new file mode 100644 index 0000000..968b169 --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/001_Себестоимость для сверки/visualContainers/00000_pivotTable (94244)/filters.json @@ -0,0 +1,18 @@ +[ + { + "name": "Filter064e79cb305a69cb0d82", + "expression": { + "Column": { + "Expression": { + "SourceRef": { + "Entity": "Себестоимость" + } + }, + "Property": "Вид операции" + } + }, + "type": "Categorical", + "howCreated": 1, + "objects": {} + } +] \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/001_Себестоимость для сверки/visualContainers/00000_pivotTable (94244)/visualContainer.json b/analytics/pbi/model/report/Report/sections/001_Себестоимость для сверки/visualContainers/00000_pivotTable (94244)/visualContainer.json new file mode 100644 index 0000000..2ce080d --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/001_Себестоимость для сверки/visualContainers/00000_pivotTable (94244)/visualContainer.json @@ -0,0 +1,8 @@ +{ + "height": 292.24, + "id": 5853011910, + "width": 1280, + "x": 0, + "y": 292.24, + "z": 1000 +} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/001_Себестоимость для сверки/visualContainers/00000_pivotTable (a77c8)/config.json b/analytics/pbi/model/report/Report/sections/001_Себестоимость для сверки/visualContainers/00000_pivotTable (a77c8)/config.json new file mode 100644 index 0000000..1b7789c --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/001_Себестоимость для сверки/visualContainers/00000_pivotTable (a77c8)/config.json @@ -0,0 +1,476 @@ +{ + "name": "a77c8acaaa486ec307d9", + "layouts": [ + { + "id": 0, + "position": { + "x": 0, + "y": 0, + "z": 0, + "width": 1280, + "height": 292.64169068203654, + "tabOrder": 0 + } + } + ], + "singleVisual": { + "visualType": "pivotTable", + "projections": { + "Rows": [ + { + "queryRef": ".Календарь.Дата.Изменение.Иерархия дат.Год", + "active": true + }, + { + "queryRef": ".Календарь.Дата.Изменение.Иерархия дат.Квартал" + }, + { + "queryRef": ".Календарь.Дата.Изменение.Иерархия дат.Месяц" + }, + { + "queryRef": ".Календарь.Дата.Изменение.Иерархия дат.День" + } + ], + "Values": [ + { + "queryRef": "Основной отчет.Сумма плюс МП, руб" + }, + { + "queryRef": "pbi СебестоимостьСводныйОт2022.Сумма minus Расходы МП, руб" + }, + { + "queryRef": "Основной отчет.Торг. надбавка, руб" + }, + { + "queryRef": "Основной отчет.Сумма учетная, руб" + }, + { + "queryRef": "Основной отчет.Закупка, руб" + }, + { + "queryRef": "Основной отчет.Доставка, руб" + }, + { + "queryRef": "Основной отчет.НДС, руб" + }, + { + "queryRef": "Основной отчет.Таможня, руб" + }, + { + "queryRef": "Основной отчет.Учет.Доп расходы, руб" + }, + { + "queryRef": "Основной отчет.Сборка, руб" + }, + { + "queryRef": "Основной отчет.Сборка из других товаров, руб" + } + ] + }, + "prototypeQuery": { + "Version": 2, + "From": [ + { + "Name": "о", + "Entity": "Основной отчет", + "Type": 0 + }, + { + "Name": "к", + "Entity": ".Календарь", + "Type": 0 + } + ], + "Select": [ + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Сумма продаж + РК, руб" + }, + "Name": "pbi СебестоимостьСводныйОт2022.Сумма minus Расходы МП, руб", + "NativeReferenceName": "Сумма, руб" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Сумма учетная, руб" + }, + "Name": "Основной отчет.Сумма учетная, руб", + "NativeReferenceName": "Сумма учетная, руб" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Учет.Закупка, руб" + }, + "Name": "Основной отчет.Закупка, руб", + "NativeReferenceName": "Закупка, руб" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Учет.НДС, руб" + }, + "Name": "Основной отчет.НДС, руб", + "NativeReferenceName": "НДС, руб" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Учет.Таможня, руб" + }, + "Name": "Основной отчет.Таможня, руб", + "NativeReferenceName": "Таможня, руб" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Учет.Доставка, руб" + }, + "Name": "Основной отчет.Доставка, руб", + "NativeReferenceName": "Доставка, руб" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Сборка в другие товары, руб" + }, + "Name": "Основной отчет.Сборка, руб", + "NativeReferenceName": "Сборка, руб" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Сборка из других товаров, руб" + }, + "Name": "Основной отчет.Сборка из других товаров, руб", + "NativeReferenceName": "Сборка из других товаров, руб" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Сумма продаж + МП + РК, руб" + }, + "Name": "Основной отчет.Сумма плюс МП, руб", + "NativeReferenceName": "Сумма плюс МП, руб" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Торг. надбавка, руб" + }, + "Name": "Основной отчет.Торг. надбавка, руб", + "NativeReferenceName": "Торг. надбавка, руб" + }, + { + "HierarchyLevel": { + "Expression": { + "Hierarchy": { + "Expression": { + "PropertyVariationSource": { + "Expression": { + "SourceRef": { + "Source": "к" + } + }, + "Name": "Изменение", + "Property": "Дата" + } + }, + "Hierarchy": "Иерархия дат" + } + }, + "Level": "Год" + }, + "Name": ".Календарь.Дата.Изменение.Иерархия дат.Год", + "NativeReferenceName": "Дата Год" + }, + { + "HierarchyLevel": { + "Expression": { + "Hierarchy": { + "Expression": { + "PropertyVariationSource": { + "Expression": { + "SourceRef": { + "Source": "к" + } + }, + "Name": "Изменение", + "Property": "Дата" + } + }, + "Hierarchy": "Иерархия дат" + } + }, + "Level": "Квартал" + }, + "Name": ".Календарь.Дата.Изменение.Иерархия дат.Квартал", + "NativeReferenceName": "Дата Квартал" + }, + { + "HierarchyLevel": { + "Expression": { + "Hierarchy": { + "Expression": { + "PropertyVariationSource": { + "Expression": { + "SourceRef": { + "Source": "к" + } + }, + "Name": "Изменение", + "Property": "Дата" + } + }, + "Hierarchy": "Иерархия дат" + } + }, + "Level": "Месяц" + }, + "Name": ".Календарь.Дата.Изменение.Иерархия дат.Месяц", + "NativeReferenceName": "Дата Месяц" + }, + { + "HierarchyLevel": { + "Expression": { + "Hierarchy": { + "Expression": { + "PropertyVariationSource": { + "Expression": { + "SourceRef": { + "Source": "к" + } + }, + "Name": "Изменение", + "Property": "Дата" + } + }, + "Hierarchy": "Иерархия дат" + } + }, + "Level": "День" + }, + "Name": ".Календарь.Дата.Изменение.Иерархия дат.День", + "NativeReferenceName": "Дата День" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Учет.Доп расходы, руб" + }, + "Name": "Основной отчет.Учет.Доп расходы, руб", + "NativeReferenceName": "Учет.Доп расходы, руб" + } + ], + "OrderBy": [ + { + "Direction": 1, + "Expression": { + "HierarchyLevel": { + "Expression": { + "Hierarchy": { + "Expression": { + "PropertyVariationSource": { + "Expression": { + "SourceRef": { + "Source": "к" + } + }, + "Name": "Изменение", + "Property": "Дата" + } + }, + "Hierarchy": "Иерархия дат" + } + }, + "Level": "Год" + } + } + } + ] + }, + "expansionStates": [ + { + "roles": [ + "Rows" + ], + "levels": [ + { + "queryRefs": [ + ".Календарь.Дата.Изменение.Иерархия дат.Год" + ], + "isCollapsed": true, + "identityKeys": [ + { + "Column": { + "Expression": { + "SourceRef": { + "Entity": "LocalDateTable_e0374236-67f4-4331-b4f5-c977a3082bab" + } + }, + "Property": "Год" + } + } + ], + "isPinned": true + }, + { + "queryRefs": [ + ".Календарь.Дата.Изменение.Иерархия дат.Квартал" + ], + "isCollapsed": true, + "identityKeys": [ + { + "Column": { + "Expression": { + "SourceRef": { + "Entity": "LocalDateTable_e0374236-67f4-4331-b4f5-c977a3082bab" + } + }, + "Property": "Квартал" + } + } + ], + "isPinned": true + }, + { + "queryRefs": [ + ".Календарь.Дата.Изменение.Иерархия дат.Месяц" + ], + "isCollapsed": true, + "isPinned": true + }, + { + "queryRefs": [ + ".Календарь.Дата.Изменение.Иерархия дат.День" + ], + "isCollapsed": true + } + ], + "root": { + "identityValues": null + } + } + ], + "drillFilterOtherVisuals": true, + "objects": { + "columnWidth": [ + { + "properties": { + "value": { + "expr": { + "Literal": { + "Value": "124.16443540679295D" + } + } + } + }, + "selector": { + "metadata": "pbi СебестоимостьСводныйОт2022.Сумма minus Расходы МП, руб" + } + }, + { + "properties": { + "value": { + "expr": { + "Literal": { + "Value": "121.30268199233717D" + } + } + } + }, + "selector": { + "metadata": "Основной отчет.Сборка, руб" + } + }, + { + "properties": { + "value": { + "expr": { + "Literal": { + "Value": "124.47509578544062D" + } + } + } + }, + "selector": { + "metadata": "Основной отчет.Сборка из других товаров, руб" + } + }, + { + "properties": { + "value": { + "expr": { + "Literal": { + "Value": "127.2452097095206D" + } + } + } + }, + "selector": { + "metadata": "Основной отчет.Доставка, руб" + } + }, + { + "properties": { + "value": { + "expr": { + "Literal": { + "Value": "100.68875966533231D" + } + } + } + }, + "selector": { + "metadata": "Основной отчет.НДС, руб" + } + } + ] + } + } +} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/001_Себестоимость для сверки/visualContainers/00000_pivotTable (a77c8)/filters.json b/analytics/pbi/model/report/Report/sections/001_Себестоимость для сверки/visualContainers/00000_pivotTable (a77c8)/filters.json new file mode 100644 index 0000000..968b169 --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/001_Себестоимость для сверки/visualContainers/00000_pivotTable (a77c8)/filters.json @@ -0,0 +1,18 @@ +[ + { + "name": "Filter064e79cb305a69cb0d82", + "expression": { + "Column": { + "Expression": { + "SourceRef": { + "Entity": "Себестоимость" + } + }, + "Property": "Вид операции" + } + }, + "type": "Categorical", + "howCreated": 1, + "objects": {} + } +] \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/001_Себестоимость для сверки/visualContainers/00000_pivotTable (a77c8)/visualContainer.json b/analytics/pbi/model/report/Report/sections/001_Себестоимость для сверки/visualContainers/00000_pivotTable (a77c8)/visualContainer.json new file mode 100644 index 0000000..244a226 --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/001_Себестоимость для сверки/visualContainers/00000_pivotTable (a77c8)/visualContainer.json @@ -0,0 +1,8 @@ +{ + "height": 292.64, + "id": 5853011911, + "width": 1280, + "x": 0, + "y": 0, + "z": 0 +} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/002_Закупка для сверки/config.json b/analytics/pbi/model/report/Report/sections/002_Закупка для сверки/config.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/002_Закупка для сверки/config.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/002_Закупка для сверки/filters.json b/analytics/pbi/model/report/Report/sections/002_Закупка для сверки/filters.json new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/002_Закупка для сверки/filters.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/002_Закупка для сверки/section.json b/analytics/pbi/model/report/Report/sections/002_Закупка для сверки/section.json new file mode 100644 index 0000000..a603450 --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/002_Закупка для сверки/section.json @@ -0,0 +1,8 @@ +{ + "displayName": "Закупка для сверки", + "displayOption": 1, + "height": 720, + "name": "754c9d1730b0f20a23b9", + "ordinal": 2, + "width": 1280 +} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/002_Закупка для сверки/visualContainers/00000_pivotTable (721f5)/config.json b/analytics/pbi/model/report/Report/sections/002_Закупка для сверки/visualContainers/00000_pivotTable (721f5)/config.json new file mode 100644 index 0000000..0b4b014 --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/002_Закупка для сверки/visualContainers/00000_pivotTable (721f5)/config.json @@ -0,0 +1,333 @@ +{ + "name": "721f5f03ab0fa208a447", + "layouts": [ + { + "id": 0, + "position": { + "x": 0, + "y": 360.35668789808915, + "z": 1000, + "width": 1200.1019108280254, + "height": 256, + "tabOrder": 1000 + } + } + ], + "singleVisual": { + "visualType": "pivotTable", + "projections": { + "Values": [ + { + "queryRef": "Закупки.Сумма закупки, usd" + }, + { + "queryRef": "Sum(Закупки.Закуп.Закупка, usd)" + }, + { + "queryRef": "Sum(Закупки.Закуп.Доставка, usd)" + }, + { + "queryRef": "Sum(Закупки.Закуп.Таможня, usd)" + }, + { + "queryRef": "Sum(Закупки.Закуп.НДС, usd)" + }, + { + "queryRef": "Sum(Закупки.Закуп.Производство, usd)" + }, + { + "queryRef": "Sum(Закупки.Закуп.Доп расходы, usd)" + } + ], + "Rows": [ + { + "queryRef": ".Календарь.Дата.Изменение.Иерархия дат.Год", + "active": true + }, + { + "queryRef": ".Календарь.Дата.Изменение.Иерархия дат.Квартал" + }, + { + "queryRef": ".Календарь.Дата.Изменение.Иерархия дат.Месяц" + }, + { + "queryRef": ".Календарь.Дата.Изменение.Иерархия дат.День" + } + ] + }, + "prototypeQuery": { + "Version": 2, + "From": [ + { + "Name": "з", + "Entity": "Закупки", + "Type": 0 + }, + { + "Name": "к", + "Entity": ".Календарь", + "Type": 0 + } + ], + "Select": [ + { + "Aggregation": { + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Source": "з" + } + }, + "Property": "Закуп.Закупка, usd" + } + }, + "Function": 0 + }, + "Name": "Sum(Закупки.Закуп.Закупка, usd)", + "NativeReferenceName": "Закуп.Закупка, usd" + }, + { + "HierarchyLevel": { + "Expression": { + "Hierarchy": { + "Expression": { + "PropertyVariationSource": { + "Expression": { + "SourceRef": { + "Source": "к" + } + }, + "Name": "Изменение", + "Property": "Дата" + } + }, + "Hierarchy": "Иерархия дат" + } + }, + "Level": "Год" + }, + "Name": ".Календарь.Дата.Изменение.Иерархия дат.Год", + "NativeReferenceName": "Дата Год" + }, + { + "HierarchyLevel": { + "Expression": { + "Hierarchy": { + "Expression": { + "PropertyVariationSource": { + "Expression": { + "SourceRef": { + "Source": "к" + } + }, + "Name": "Изменение", + "Property": "Дата" + } + }, + "Hierarchy": "Иерархия дат" + } + }, + "Level": "Квартал" + }, + "Name": ".Календарь.Дата.Изменение.Иерархия дат.Квартал", + "NativeReferenceName": "Дата Квартал" + }, + { + "HierarchyLevel": { + "Expression": { + "Hierarchy": { + "Expression": { + "PropertyVariationSource": { + "Expression": { + "SourceRef": { + "Source": "к" + } + }, + "Name": "Изменение", + "Property": "Дата" + } + }, + "Hierarchy": "Иерархия дат" + } + }, + "Level": "Месяц" + }, + "Name": ".Календарь.Дата.Изменение.Иерархия дат.Месяц", + "NativeReferenceName": "Дата Месяц" + }, + { + "HierarchyLevel": { + "Expression": { + "Hierarchy": { + "Expression": { + "PropertyVariationSource": { + "Expression": { + "SourceRef": { + "Source": "к" + } + }, + "Name": "Изменение", + "Property": "Дата" + } + }, + "Hierarchy": "Иерархия дат" + } + }, + "Level": "День" + }, + "Name": ".Календарь.Дата.Изменение.Иерархия дат.День", + "NativeReferenceName": "Дата День" + }, + { + "Aggregation": { + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Source": "з" + } + }, + "Property": "Закуп.Доставка, usd" + } + }, + "Function": 0 + }, + "Name": "Sum(Закупки.Закуп.Доставка, usd)", + "NativeReferenceName": "Закуп.Доставка, usd" + }, + { + "Aggregation": { + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Source": "з" + } + }, + "Property": "Закуп.Таможня, usd" + } + }, + "Function": 0 + }, + "Name": "Sum(Закупки.Закуп.Таможня, usd)", + "NativeReferenceName": "Закуп.Таможня, usd" + }, + { + "Aggregation": { + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Source": "з" + } + }, + "Property": "Закуп.НДС, usd" + } + }, + "Function": 0 + }, + "Name": "Sum(Закупки.Закуп.НДС, usd)", + "NativeReferenceName": "Закуп.НДС, usd" + }, + { + "Aggregation": { + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Source": "з" + } + }, + "Property": "Закуп.Производство, usd" + } + }, + "Function": 0 + }, + "Name": "Sum(Закупки.Закуп.Производство, usd)", + "NativeReferenceName": "Закуп.Производство, usd" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "з" + } + }, + "Property": "Сумма закупки, usd" + }, + "Name": "Закупки.Сумма закупки, usd", + "NativeReferenceName": "Сумма закупки, usd" + }, + { + "Aggregation": { + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Source": "з" + } + }, + "Property": "Закуп.Доп расходы, usd" + } + }, + "Function": 0 + }, + "Name": "Sum(Закупки.Закуп.Доп расходы, usd)", + "NativeReferenceName": "Закуп.Доп расходы, usd" + } + ] + }, + "expansionStates": [ + { + "roles": [ + "Rows" + ], + "levels": [ + { + "queryRefs": [ + ".Календарь.Дата.Изменение.Иерархия дат.Год" + ], + "isCollapsed": true, + "identityKeys": [ + { + "Column": { + "Expression": { + "SourceRef": { + "Entity": "LocalDateTable_e0374236-67f4-4331-b4f5-c977a3082bab" + } + }, + "Property": "Год" + } + } + ], + "isPinned": true + }, + { + "queryRefs": [ + ".Календарь.Дата.Изменение.Иерархия дат.Квартал" + ], + "isCollapsed": true, + "isPinned": true + }, + { + "queryRefs": [ + ".Календарь.Дата.Изменение.Иерархия дат.Месяц" + ], + "isCollapsed": true + }, + { + "queryRefs": [ + ".Календарь.Дата.Изменение.Иерархия дат.День" + ], + "isCollapsed": true + } + ], + "root": { + "identityValues": null + } + } + ], + "drillFilterOtherVisuals": true + } +} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/002_Закупка для сверки/visualContainers/00000_pivotTable (721f5)/filters.json b/analytics/pbi/model/report/Report/sections/002_Закупка для сверки/visualContainers/00000_pivotTable (721f5)/filters.json new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/002_Закупка для сверки/visualContainers/00000_pivotTable (721f5)/filters.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/002_Закупка для сверки/visualContainers/00000_pivotTable (721f5)/visualContainer.json b/analytics/pbi/model/report/Report/sections/002_Закупка для сверки/visualContainers/00000_pivotTable (721f5)/visualContainer.json new file mode 100644 index 0000000..da943a1 --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/002_Закупка для сверки/visualContainers/00000_pivotTable (721f5)/visualContainer.json @@ -0,0 +1,8 @@ +{ + "height": 256, + "id": 5853011909, + "width": 1200.1, + "x": 0, + "y": 360.36, + "z": 1000 +} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/002_Закупка для сверки/visualContainers/00000_pivotTable (ef9b1)/config.json b/analytics/pbi/model/report/Report/sections/002_Закупка для сверки/visualContainers/00000_pivotTable (ef9b1)/config.json new file mode 100644 index 0000000..6bbfbf0 --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/002_Закупка для сверки/visualContainers/00000_pivotTable (ef9b1)/config.json @@ -0,0 +1,446 @@ +{ + "name": "ef9b132ce1bf6dcb0fba", + "layouts": [ + { + "id": 0, + "position": { + "x": 0, + "y": 0, + "z": 0, + "width": 1280, + "height": 256, + "tabOrder": 0 + } + } + ], + "singleVisual": { + "visualType": "pivotTable", + "projections": { + "Values": [ + { + "queryRef": "Закупки.Сумма закупки, руб" + }, + { + "queryRef": "Sum(Закупки.Закуп.Закупка, руб)" + }, + { + "queryRef": "Sum(Закупки.Закуп.Доставка, руб)" + }, + { + "queryRef": "Sum(Закупки.Закуп.Таможня, руб)" + }, + { + "queryRef": "Sum(Закупки.Закуп.НДС, руб)" + }, + { + "queryRef": "Sum(Закупки.Закуп.Производство, руб)" + }, + { + "queryRef": "Sum(Закупки.Закуп.Доп расходы, руб)" + }, + { + "queryRef": "Sum(Себестоимость.АтсМаркировка)" + }, + { + "queryRef": "Sum(Себестоимость.ВремяВыполненияМинут)" + }, + { + "queryRef": "Sum(Себестоимость.СборкаЗаказа)" + }, + { + "queryRef": "Sum(Себестоимость.Приемка)" + } + ], + "Rows": [ + { + "queryRef": ".Календарь.Дата.Изменение.Иерархия дат.Год", + "active": true + }, + { + "queryRef": ".Календарь.Дата.Изменение.Иерархия дат.Квартал" + }, + { + "queryRef": ".Календарь.Дата.Изменение.Иерархия дат.Месяц" + }, + { + "queryRef": ".Календарь.Дата.Изменение.Иерархия дат.День" + } + ] + }, + "prototypeQuery": { + "Version": 2, + "From": [ + { + "Name": "з", + "Entity": "Закупки", + "Type": 0 + }, + { + "Name": "с", + "Entity": "Себестоимость", + "Type": 0 + }, + { + "Name": "к", + "Entity": ".Календарь", + "Type": 0 + } + ], + "Select": [ + { + "Aggregation": { + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Source": "з" + } + }, + "Property": "Закуп.Закупка, руб" + } + }, + "Function": 0 + }, + "Name": "Sum(Закупки.Закуп.Закупка, руб)", + "NativeReferenceName": "Закуп.Закупка, руб" + }, + { + "Aggregation": { + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Source": "с" + } + }, + "Property": "Приемка" + } + }, + "Function": 0 + }, + "Name": "Sum(Себестоимость.Приемка)", + "NativeReferenceName": "Приемка" + }, + { + "Aggregation": { + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Source": "с" + } + }, + "Property": "АтсМаркировка" + } + }, + "Function": 0 + }, + "Name": "Sum(Себестоимость.АтсМаркировка)", + "NativeReferenceName": "АтсМаркировка" + }, + { + "Aggregation": { + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Source": "с" + } + }, + "Property": "ВремяВыполненияМинут" + } + }, + "Function": 0 + }, + "Name": "Sum(Себестоимость.ВремяВыполненияМинут)", + "NativeReferenceName": "ВремяВыполненияМинут" + }, + { + "Aggregation": { + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Source": "с" + } + }, + "Property": "СборкаЗаказа" + } + }, + "Function": 0 + }, + "Name": "Sum(Себестоимость.СборкаЗаказа)", + "NativeReferenceName": "СборкаЗаказа" + }, + { + "HierarchyLevel": { + "Expression": { + "Hierarchy": { + "Expression": { + "PropertyVariationSource": { + "Expression": { + "SourceRef": { + "Source": "к" + } + }, + "Name": "Изменение", + "Property": "Дата" + } + }, + "Hierarchy": "Иерархия дат" + } + }, + "Level": "Год" + }, + "Name": ".Календарь.Дата.Изменение.Иерархия дат.Год", + "NativeReferenceName": "Дата Год" + }, + { + "HierarchyLevel": { + "Expression": { + "Hierarchy": { + "Expression": { + "PropertyVariationSource": { + "Expression": { + "SourceRef": { + "Source": "к" + } + }, + "Name": "Изменение", + "Property": "Дата" + } + }, + "Hierarchy": "Иерархия дат" + } + }, + "Level": "Квартал" + }, + "Name": ".Календарь.Дата.Изменение.Иерархия дат.Квартал", + "NativeReferenceName": "Дата Квартал" + }, + { + "HierarchyLevel": { + "Expression": { + "Hierarchy": { + "Expression": { + "PropertyVariationSource": { + "Expression": { + "SourceRef": { + "Source": "к" + } + }, + "Name": "Изменение", + "Property": "Дата" + } + }, + "Hierarchy": "Иерархия дат" + } + }, + "Level": "Месяц" + }, + "Name": ".Календарь.Дата.Изменение.Иерархия дат.Месяц", + "NativeReferenceName": "Дата Месяц" + }, + { + "HierarchyLevel": { + "Expression": { + "Hierarchy": { + "Expression": { + "PropertyVariationSource": { + "Expression": { + "SourceRef": { + "Source": "к" + } + }, + "Name": "Изменение", + "Property": "Дата" + } + }, + "Hierarchy": "Иерархия дат" + } + }, + "Level": "День" + }, + "Name": ".Календарь.Дата.Изменение.Иерархия дат.День", + "NativeReferenceName": "Дата День" + }, + { + "Aggregation": { + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Source": "з" + } + }, + "Property": "Закуп.Доставка, руб" + } + }, + "Function": 0 + }, + "Name": "Sum(Закупки.Закуп.Доставка, руб)", + "NativeReferenceName": "Закуп.Доставка, руб" + }, + { + "Aggregation": { + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Source": "з" + } + }, + "Property": "Закуп.НДС, руб" + } + }, + "Function": 0 + }, + "Name": "Sum(Закупки.Закуп.НДС, руб)", + "NativeReferenceName": "Закуп.НДС, руб" + }, + { + "Aggregation": { + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Source": "з" + } + }, + "Property": "Закуп.Производство, руб" + } + }, + "Function": 0 + }, + "Name": "Sum(Закупки.Закуп.Производство, руб)", + "NativeReferenceName": "Закуп.Производство, руб" + }, + { + "Aggregation": { + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Source": "з" + } + }, + "Property": "Закуп.Таможня, руб" + } + }, + "Function": 0 + }, + "Name": "Sum(Закупки.Закуп.Таможня, руб)", + "NativeReferenceName": "Закуп.Таможня, руб" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "з" + } + }, + "Property": "Сумма закупки, руб" + }, + "Name": "Закупки.Сумма закупки, руб", + "NativeReferenceName": "Сумма закупки, руб" + }, + { + "Aggregation": { + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Source": "з" + } + }, + "Property": "Закуп.Доп расходы, руб" + } + }, + "Function": 0 + }, + "Name": "Sum(Закупки.Закуп.Доп расходы, руб)", + "NativeReferenceName": "Закуп.Доп расходы, руб" + } + ], + "OrderBy": [ + { + "Direction": 1, + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Source": "к" + } + }, + "Property": "Дата" + } + } + } + ] + }, + "expansionStates": [ + { + "roles": [ + "Rows" + ], + "levels": [ + { + "queryRefs": [ + ".Календарь.Дата.Изменение.Иерархия дат.Год" + ], + "isCollapsed": true, + "identityKeys": [ + { + "Column": { + "Expression": { + "SourceRef": { + "Entity": "LocalDateTable_e0374236-67f4-4331-b4f5-c977a3082bab" + } + }, + "Property": "Год" + } + } + ], + "isPinned": true + }, + { + "queryRefs": [ + ".Календарь.Дата.Изменение.Иерархия дат.Квартал" + ], + "isCollapsed": true, + "identityKeys": [ + { + "Column": { + "Expression": { + "SourceRef": { + "Entity": "LocalDateTable_e0374236-67f4-4331-b4f5-c977a3082bab" + } + }, + "Property": "Квартал" + } + } + ], + "isPinned": true + }, + { + "queryRefs": [ + ".Календарь.Дата.Изменение.Иерархия дат.Месяц" + ], + "isCollapsed": true, + "isPinned": true + }, + { + "queryRefs": [ + ".Календарь.Дата.Изменение.Иерархия дат.День" + ], + "isCollapsed": true + } + ], + "root": { + "identityValues": null + } + } + ], + "drillFilterOtherVisuals": true + } +} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/002_Закупка для сверки/visualContainers/00000_pivotTable (ef9b1)/filters.json b/analytics/pbi/model/report/Report/sections/002_Закупка для сверки/visualContainers/00000_pivotTable (ef9b1)/filters.json new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/002_Закупка для сверки/visualContainers/00000_pivotTable (ef9b1)/filters.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/002_Закупка для сверки/visualContainers/00000_pivotTable (ef9b1)/visualContainer.json b/analytics/pbi/model/report/Report/sections/002_Закупка для сверки/visualContainers/00000_pivotTable (ef9b1)/visualContainer.json new file mode 100644 index 0000000..943d805 --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/002_Закупка для сверки/visualContainers/00000_pivotTable (ef9b1)/visualContainer.json @@ -0,0 +1,8 @@ +{ + "height": 256, + "id": 5853011908, + "width": 1280, + "x": 0, + "y": 0, + "z": 0 +} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/003_Проверка заказа/config.json b/analytics/pbi/model/report/Report/sections/003_Проверка заказа/config.json new file mode 100644 index 0000000..555bbbf --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/003_Проверка заказа/config.json @@ -0,0 +1,3 @@ +{ + "visibility": 1 +} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/003_Проверка заказа/filters.json b/analytics/pbi/model/report/Report/sections/003_Проверка заказа/filters.json new file mode 100644 index 0000000..d28ab5e --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/003_Проверка заказа/filters.json @@ -0,0 +1,24 @@ +[ + { + "name": "d7b101032c2fbd2a522e", + "expression": { + "Column": { + "Expression": { + "SourceRef": { + "Entity": "Группы" + } + }, + "Property": "Группа" + } + }, + "type": "Categorical", + "howCreated": 1, + "objects": { + "general": [ + { + "properties": {} + } + ] + } + } +] \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/003_Проверка заказа/section.json b/analytics/pbi/model/report/Report/sections/003_Проверка заказа/section.json new file mode 100644 index 0000000..993dfa6 --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/003_Проверка заказа/section.json @@ -0,0 +1,8 @@ +{ + "displayName": "Проверка заказа", + "displayOption": 1, + "height": 720, + "name": "093cb2f2f430784c9aa2", + "ordinal": 3, + "width": 1280 +} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/003_Проверка заказа/visualContainers/00000_tableEx (947fa)/config.json b/analytics/pbi/model/report/Report/sections/003_Проверка заказа/visualContainers/00000_tableEx (947fa)/config.json new file mode 100644 index 0000000..ca6f645 --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/003_Проверка заказа/visualContainers/00000_tableEx (947fa)/config.json @@ -0,0 +1,584 @@ +{ + "name": "947fadddc992e56fc1dc", + "layouts": [ + { + "id": 0, + "position": { + "x": 0, + "y": 3.5965316650203052, + "z": 1000, + "width": 1280.3652727472286, + "height": 715.70980133904072 + } + } + ], + "singleVisual": { + "visualType": "tableEx", + "projections": { + "Values": [ + { + "queryRef": "Номенклатура.Наименование" + }, + { + "queryRef": "Номенклатура.Фото" + }, + { + "queryRef": "Номенклатура.ABC статус 12м" + }, + { + "queryRef": "Номенклатура.ABC статус 3м" + }, + { + "queryRef": "Заказы все.Согласование упак." + }, + { + "queryRef": "Номенклатура.Дней с первой продажи" + }, + { + "queryRef": "Sum(Заказы все.Сумма в руб.)" + }, + { + "queryRef": "Номенклатура.Отчет продажи упак/день" + }, + { + "queryRef": "Номенклатура.Отчет ТН руб/день за 365 дней" + }, + { + "queryRef": "Номенклатура.Остаток дней продаж" + }, + { + "queryRef": "Номенклатура.Остаток дней продаж потенциальный" + }, + { + "queryRef": "Номенклатура.Остаток дней продаж потенциальный1" + }, + { + "queryRef": "Номенклатура.Рентабельность за год" + }, + { + "queryRef": "Основной отчет.Остаток конец, руб" + }, + { + "queryRef": "Основной отчет.Остаток конец, упак" + }, + { + "queryRef": "Sum(mp остатки.Остаток МП, упак)" + }, + { + "queryRef": "Номенклатура.Код УТ" + } + ] + }, + "prototypeQuery": { + "Version": 2, + "From": [ + { + "Name": "н", + "Entity": "Номенклатура", + "Type": 0 + }, + { + "Name": "о", + "Entity": "Основной отчет", + "Type": 0 + }, + { + "Name": "з", + "Entity": "Заказы все", + "Type": 0 + }, + { + "Name": "m", + "Entity": "mp остатки", + "Type": 0 + } + ], + "Select": [ + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "н" + } + }, + "Property": "Отчет ТН руб/день за 365 дней" + }, + "Name": "Номенклатура.Отчет ТН руб/день за 365 дней", + "NativeReferenceName": "Отчет ТН руб/день за 365 дней" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Остаток - МП конец, руб" + }, + "Name": "Основной отчет.Остаток конец, руб", + "NativeReferenceName": "Остаток - МП конец, руб" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Остаток - МП конец, упак" + }, + "Name": "Основной отчет.Остаток конец, упак", + "NativeReferenceName": "Остаток - МП конец, упак" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "н" + } + }, + "Property": "Остаток дней продаж потенциальный + согласование" + }, + "Name": "Номенклатура.Остаток дней продаж потенциальный", + "NativeReferenceName": "Остаток дней продаж потенциальный + согласование" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "н" + } + }, + "Property": "Остаток дней продаж -" + }, + "Name": "Номенклатура.Остаток дней продаж", + "NativeReferenceName": "Остаток дней продаж" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "з" + } + }, + "Property": "Согласование упак." + }, + "Name": "Заказы все.Согласование упак.", + "NativeReferenceName": "Согласование упак." + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "н" + } + }, + "Property": "Остаток дней продаж потенциальный" + }, + "Name": "Номенклатура.Остаток дней продаж потенциальный1", + "NativeReferenceName": "Остаток дней продаж потенциальный" + }, + { + "Aggregation": { + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Source": "з" + } + }, + "Property": "Сумма всего в руб" + } + }, + "Function": 0 + }, + "Name": "Sum(Заказы все.Сумма в руб.)", + "NativeReferenceName": "Сумма в руб." + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "н" + } + }, + "Property": "Отчет продажи упак/день" + }, + "Name": "Номенклатура.Отчет продажи упак/день", + "NativeReferenceName": "Отчет продажи упак/день" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "н" + } + }, + "Property": "Дней с первой продажи" + }, + "Name": "Номенклатура.Дней с первой продажи", + "NativeReferenceName": "Дней с первой продажи" + }, + { + "Column": { + "Expression": { + "SourceRef": { + "Source": "н" + } + }, + "Property": "Фото" + }, + "Name": "Номенклатура.Фото", + "NativeReferenceName": "Фото" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "н" + } + }, + "Property": "Рентабельность % за год" + }, + "Name": "Номенклатура.Рентабельность за год", + "NativeReferenceName": "Рентабельность за год" + }, + { + "Column": { + "Expression": { + "SourceRef": { + "Source": "н" + } + }, + "Property": "Наименование" + }, + "Name": "Номенклатура.Наименование", + "NativeReferenceName": "Наименование" + }, + { + "Column": { + "Expression": { + "SourceRef": { + "Source": "н" + } + }, + "Property": "ABC статус 3м" + }, + "Name": "Номенклатура.ABC статус 3м", + "NativeReferenceName": "ABC статус 3м" + }, + { + "Column": { + "Expression": { + "SourceRef": { + "Source": "н" + } + }, + "Property": "Код УТ" + }, + "Name": "Номенклатура.Код УТ", + "NativeReferenceName": "Код УТ" + }, + { + "Aggregation": { + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Source": "m" + } + }, + "Property": "Остаток МП, упак" + } + }, + "Function": 0 + }, + "Name": "Sum(mp остатки.Остаток МП, упак)", + "NativeReferenceName": "Остаток МП, упак" + }, + { + "Column": { + "Expression": { + "SourceRef": { + "Source": "н" + } + }, + "Property": "ABC статус 12м" + }, + "Name": "Номенклатура.ABC статус 12м", + "NativeReferenceName": "ABC статус 12м" + } + ], + "OrderBy": [ + { + "Direction": 1, + "Expression": { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "н" + } + }, + "Property": "Остаток дней продаж потенциальный + согласование" + } + } + } + ] + }, + "drillFilterOtherVisuals": true, + "objects": { + "columnWidth": [ + { + "properties": { + "value": { + "expr": { + "Literal": { + "Value": "106.06392603583824D" + } + } + } + }, + "selector": { + "metadata": "Номенклатура.Отчет ТН руб/день за 365 дней" + } + }, + { + "properties": { + "value": { + "expr": { + "Literal": { + "Value": "104.99317244380974D" + } + } + } + }, + "selector": { + "metadata": "Основной отчет.Остаток конец, руб" + } + }, + { + "properties": { + "value": { + "expr": { + "Literal": { + "Value": "119.81415456800187D" + } + } + } + }, + "selector": { + "metadata": "Основной отчет.Остаток конец, упак" + } + }, + { + "properties": { + "value": { + "expr": { + "Literal": { + "Value": "113.17945012099631D" + } + } + } + }, + "selector": { + "metadata": "Номенклатура.Остаток дней продаж потенциальный" + } + }, + { + "properties": { + "value": { + "expr": { + "Literal": { + "Value": "104.74347067134175D" + } + } + } + }, + "selector": { + "metadata": "Номенклатура.Остаток дней продаж" + } + }, + { + "properties": { + "value": { + "expr": { + "Literal": { + "Value": "92.74594956322099D" + } + } + } + }, + "selector": { + "metadata": "Номенклатура.Остаток дней продаж потенциальный1" + } + }, + { + "properties": { + "value": { + "expr": { + "Literal": { + "Value": "75.33762057877814D" + } + } + } + }, + "selector": { + "metadata": "Номенклатура.Отчет продажи упак/день" + } + }, + { + "properties": { + "value": { + "expr": { + "Literal": { + "Value": "58.741960765990065D" + } + } + } + }, + "selector": { + "metadata": "Заказы все.Согласование упак." + } + }, + { + "properties": { + "value": { + "expr": { + "Literal": { + "Value": "70.45016077170418D" + } + } + } + }, + "selector": { + "metadata": "Sum(Заказы все.Сумма в руб.)" + } + }, + { + "properties": { + "value": { + "expr": { + "Literal": { + "Value": "45.78778135048232D" + } + } + } + }, + "selector": { + "metadata": "Номенклатура.Дней с первой продажи" + } + }, + { + "properties": { + "value": { + "expr": { + "Literal": { + "Value": "89.8591887003569D" + } + } + } + }, + "selector": { + "metadata": "Номенклатура.Рентабельность за год" + } + }, + { + "properties": { + "value": { + "expr": { + "Literal": { + "Value": "227.08767172501183D" + } + } + } + }, + "selector": { + "metadata": "Номенклатура.Наименование" + } + } + ], + "values": [ + { + "properties": { + "backColor": { + "solid": { + "color": { + "expr": { + "Conditional": { + "Cases": [ + { + "Condition": { + "Comparison": { + "ComparisonKind": 3, + "Left": { + "Measure": { + "Expression": { + "SourceRef": { + "Entity": "Номенклатура" + } + }, + "Property": "Остаток дней продаж потенциальный + согласование" + } + }, + "Right": { + "Literal": { + "Value": "120D" + } + } + } + }, + "Value": { + "Literal": { + "Value": "'#c7b8e7'" + } + } + }, + { + "Condition": { + "Comparison": { + "ComparisonKind": 2, + "Left": { + "Measure": { + "Expression": { + "SourceRef": { + "Entity": "Номенклатура" + } + }, + "Property": "Остаток дней продаж потенциальный + согласование" + } + }, + "Right": { + "Literal": { + "Value": "365D" + } + } + } + }, + "Value": { + "Literal": { + "Value": "'#efb5b9'" + } + } + } + ] + } + } + } + } + } + }, + "selector": { + "data": [ + { + "dataViewWildcard": { + "matchingOption": 1 + } + } + ], + "metadata": "Номенклатура.Остаток дней продаж потенциальный" + } + } + ] + } + } +} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/003_Проверка заказа/visualContainers/00000_tableEx (947fa)/filters.json b/analytics/pbi/model/report/Report/sections/003_Проверка заказа/visualContainers/00000_tableEx (947fa)/filters.json new file mode 100644 index 0000000..7fa99df --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/003_Проверка заказа/visualContainers/00000_tableEx (947fa)/filters.json @@ -0,0 +1,24 @@ +[ + { + "name": "fae48656203ee0874d3e", + "expression": { + "Column": { + "Expression": { + "SourceRef": { + "Entity": "Группы" + } + }, + "Property": "Группа" + } + }, + "type": "Categorical", + "howCreated": 1, + "objects": { + "general": [ + { + "properties": {} + } + ] + } + } +] \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/003_Проверка заказа/visualContainers/00000_tableEx (947fa)/visualContainer.json b/analytics/pbi/model/report/Report/sections/003_Проверка заказа/visualContainers/00000_tableEx (947fa)/visualContainer.json new file mode 100644 index 0000000..8445de7 --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/003_Проверка заказа/visualContainers/00000_tableEx (947fa)/visualContainer.json @@ -0,0 +1,8 @@ +{ + "height": 715.71, + "id": 5853011904, + "width": 1280.37, + "x": 0, + "y": 3.6, + "z": 1000 +} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/004_Расходы по группам/config.json b/analytics/pbi/model/report/Report/sections/004_Расходы по группам/config.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/004_Расходы по группам/config.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/004_Расходы по группам/filters.json b/analytics/pbi/model/report/Report/sections/004_Расходы по группам/filters.json new file mode 100644 index 0000000..990f753 --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/004_Расходы по группам/filters.json @@ -0,0 +1,95 @@ +[ + { + "name": "fb75ada5c622021a796e", + "expression": { + "HierarchyLevel": { + "Expression": { + "Hierarchy": { + "Expression": { + "PropertyVariationSource": { + "Expression": { + "SourceRef": { + "Entity": ".Календарь" + } + }, + "Name": "Изменение", + "Property": "Дата" + } + }, + "Hierarchy": "Иерархия дат" + } + }, + "Level": "Год" + } + }, + "filter": { + "Version": 2, + "From": [ + { + "Name": "l", + "Entity": "LocalDateTable_e0374236-67f4-4331-b4f5-c977a3082bab", + "Type": 0 + } + ], + "Where": [ + { + "Condition": { + "In": { + "Expressions": [ + { + "Column": { + "Expression": { + "SourceRef": { + "Source": "l" + } + }, + "Property": "Год" + } + } + ], + "Values": [ + [ + { + "Literal": { + "Value": "2024L" + } + } + ] + ] + } + } + } + ] + }, + "type": "Categorical", + "cachedDisplayNames": [ + { + "id": { + "scopeId": { + "Comparison": { + "ComparisonKind": 0, + "Left": { + "Column": { + "Expression": { + "SourceRef": { + "Entity": "LocalDateTable_e0374236-67f4-4331-b4f5-c977a3082bab" + } + }, + "Property": "Год" + } + }, + "Right": { + "Literal": { + "Value": "2024L" + } + } + } + } + }, + "displayName": "2024" + } + ], + "howCreated": 1, + "objects": {} + } +] \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/004_Расходы по группам/section.json b/analytics/pbi/model/report/Report/sections/004_Расходы по группам/section.json new file mode 100644 index 0000000..8a62d25 --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/004_Расходы по группам/section.json @@ -0,0 +1,8 @@ +{ + "displayName": "Расходы по группам", + "displayOption": 1, + "height": 720, + "name": "26b06b855e040a3da6cd", + "ordinal": 4, + "width": 1280 +} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/004_Расходы по группам/visualContainers/00000_pivotTable (65554)/config.json b/analytics/pbi/model/report/Report/sections/004_Расходы по группам/visualContainers/00000_pivotTable (65554)/config.json new file mode 100644 index 0000000..07572bb --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/004_Расходы по группам/visualContainers/00000_pivotTable (65554)/config.json @@ -0,0 +1,316 @@ +{ + "name": "6555486b30c025a90968", + "layouts": [ + { + "id": 0, + "position": { + "x": 0, + "y": 0, + "z": 0, + "width": 1280, + "height": 701.85873605947961 + } + } + ], + "singleVisual": { + "visualType": "pivotTable", + "projections": { + "Rows": [ + { + "queryRef": "Группы.Группа", + "active": true + }, + { + "queryRef": "Группы.Подгруппа 1" + } + ], + "Values": [ + { + "queryRef": "Основной отчет.Торг. надбавка, руб" + }, + { + "queryRef": "Основной отчет.Сумма скидки, руб" + }, + { + "queryRef": "Расходы по годам.Чистая прибыль 2024" + }, + { + "queryRef": "Расходы по годам.% от выручки 2024" + }, + { + "queryRef": "Расходы по годам.Расходы на строку 2024" + }, + { + "queryRef": "Расходы по годам.Расходы на упаковку 2024" + }, + { + "queryRef": "Основной отчет.Торг. надбавка - 70р за упак, руб" + } + ] + }, + "prototypeQuery": { + "Version": 2, + "From": [ + { + "Name": "о", + "Entity": "Основной отчет", + "Type": 0 + }, + { + "Name": "г", + "Entity": "Группы", + "Type": 0 + }, + { + "Name": "р1", + "Entity": "Расходы по годам", + "Type": 0 + } + ], + "Select": [ + { + "Column": { + "Expression": { + "SourceRef": { + "Source": "г" + } + }, + "Property": "Группа" + }, + "Name": "Группы.Группа", + "NativeReferenceName": "Группа" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Торг. надбавка, руб" + }, + "Name": "Основной отчет.Торг. надбавка, руб", + "NativeReferenceName": "Торг. надбавка, руб" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "р1" + } + }, + "Property": "Чистая прибыль 2024" + }, + "Name": "Расходы по годам.Чистая прибыль 2024", + "NativeReferenceName": "Чистая прибыль 2024" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Торг. надбавка - 70р за упак, руб" + }, + "Name": "Основной отчет.Торг. надбавка - 70р за упак, руб", + "NativeReferenceName": "Торг. надбавка - 70р за упак, руб" + }, + { + "Column": { + "Expression": { + "SourceRef": { + "Source": "г" + } + }, + "Property": "Подгруппа 1" + }, + "Name": "Группы.Подгруппа 1", + "NativeReferenceName": "Подгруппа 1" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "р1" + } + }, + "Property": "% от выручки 2024" + }, + "Name": "Расходы по годам.% от выручки 2024", + "NativeReferenceName": "% от выручки 2024" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "р1" + } + }, + "Property": "Расходы на строку 2024" + }, + "Name": "Расходы по годам.Расходы на строку 2024", + "NativeReferenceName": "Расходы на строку 2024" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "р1" + } + }, + "Property": "Расходы на упаковку 2024" + }, + "Name": "Расходы по годам.Расходы на упаковку 2024", + "NativeReferenceName": "Расходы на упаковку 2024" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Сумма скидки, руб" + }, + "Name": "Основной отчет.Сумма скидки, руб", + "NativeReferenceName": "Сумма скидки, руб" + } + ], + "OrderBy": [ + { + "Direction": 2, + "Expression": { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Торг. надбавка, руб" + } + } + } + ] + }, + "expansionStates": [ + { + "roles": [ + "Rows" + ], + "levels": [ + { + "queryRefs": [ + "Группы.Группа" + ], + "isCollapsed": true, + "identityKeys": [ + { + "Column": { + "Expression": { + "SourceRef": { + "Entity": "Группы" + } + }, + "Property": "Группа" + } + } + ], + "isPinned": true + }, + { + "queryRefs": [ + "Группы.Подгруппа 1" + ], + "isCollapsed": true, + "isPinned": true + } + ], + "root": { + "identityValues": null + } + } + ], + "drillFilterOtherVisuals": true, + "objects": { + "columnWidth": [ + { + "properties": { + "value": { + "expr": { + "Literal": { + "Value": "218.94376371840957D" + } + } + } + }, + "selector": { + "metadata": "Группы.Группа" + } + }, + { + "properties": { + "value": { + "expr": { + "Literal": { + "Value": "91.7927927927928D" + } + } + } + }, + "selector": { + "metadata": "Основной отчет.Торг. надбавка, руб" + } + }, + { + "properties": { + "value": { + "expr": { + "Literal": { + "Value": "86.20819112627987D" + } + } + } + }, + "selector": { + "metadata": "Расходы по годам.Чистая прибыль 2024" + } + }, + { + "properties": { + "value": { + "expr": { + "Literal": { + "Value": "119.51194539249147D" + } + } + } + }, + "selector": { + "metadata": "Основной отчет.Торг. надбавка - 70р за упак, руб" + } + } + ], + "subTotals": [ + { + "properties": { + "columnSubtotals": { + "expr": { + "Literal": { + "Value": "true" + } + } + }, + "rowSubtotals": { + "expr": { + "Literal": { + "Value": "true" + } + } + } + } + } + ] + } + } +} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/004_Расходы по группам/visualContainers/00000_pivotTable (65554)/filters.json b/analytics/pbi/model/report/Report/sections/004_Расходы по группам/visualContainers/00000_pivotTable (65554)/filters.json new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/004_Расходы по группам/visualContainers/00000_pivotTable (65554)/filters.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/004_Расходы по группам/visualContainers/00000_pivotTable (65554)/visualContainer.json b/analytics/pbi/model/report/Report/sections/004_Расходы по группам/visualContainers/00000_pivotTable (65554)/visualContainer.json new file mode 100644 index 0000000..6224553 --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/004_Расходы по группам/visualContainers/00000_pivotTable (65554)/visualContainer.json @@ -0,0 +1,8 @@ +{ + "height": 701.86, + "id": 5853011906, + "width": 1280, + "x": 0, + "y": 0, + "z": 0 +} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/005_Расходы по партнерам/config.json b/analytics/pbi/model/report/Report/sections/005_Расходы по партнерам/config.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/005_Расходы по партнерам/config.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/005_Расходы по партнерам/filters.json b/analytics/pbi/model/report/Report/sections/005_Расходы по партнерам/filters.json new file mode 100644 index 0000000..6b7b0e0 --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/005_Расходы по партнерам/filters.json @@ -0,0 +1,95 @@ +[ + { + "name": "353705c00c3625430515", + "expression": { + "HierarchyLevel": { + "Expression": { + "Hierarchy": { + "Expression": { + "PropertyVariationSource": { + "Expression": { + "SourceRef": { + "Entity": ".Календарь" + } + }, + "Name": "Изменение", + "Property": "Дата" + } + }, + "Hierarchy": "Иерархия дат" + } + }, + "Level": "Год" + } + }, + "filter": { + "Version": 2, + "From": [ + { + "Name": "l", + "Entity": "LocalDateTable_e0374236-67f4-4331-b4f5-c977a3082bab", + "Type": 0 + } + ], + "Where": [ + { + "Condition": { + "In": { + "Expressions": [ + { + "Column": { + "Expression": { + "SourceRef": { + "Source": "l" + } + }, + "Property": "Год" + } + } + ], + "Values": [ + [ + { + "Literal": { + "Value": "2024L" + } + } + ] + ] + } + } + } + ] + }, + "type": "Categorical", + "cachedDisplayNames": [ + { + "id": { + "scopeId": { + "Comparison": { + "ComparisonKind": 0, + "Left": { + "Column": { + "Expression": { + "SourceRef": { + "Entity": "LocalDateTable_e0374236-67f4-4331-b4f5-c977a3082bab" + } + }, + "Property": "Год" + } + }, + "Right": { + "Literal": { + "Value": "2024L" + } + } + } + } + }, + "displayName": "2024" + } + ], + "howCreated": 1, + "objects": {} + } +] \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/005_Расходы по партнерам/section.json b/analytics/pbi/model/report/Report/sections/005_Расходы по партнерам/section.json new file mode 100644 index 0000000..74201a6 --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/005_Расходы по партнерам/section.json @@ -0,0 +1,8 @@ +{ + "displayName": "Расходы по партнерам", + "displayOption": 1, + "height": 720, + "name": "5c3b66599c2024e88c47", + "ordinal": 5, + "width": 1280 +} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/005_Расходы по партнерам/visualContainers/00000_tableEx (3c685)/config.json b/analytics/pbi/model/report/Report/sections/005_Расходы по партнерам/visualContainers/00000_tableEx (3c685)/config.json new file mode 100644 index 0000000..71f8ca5 --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/005_Расходы по партнерам/visualContainers/00000_tableEx (3c685)/config.json @@ -0,0 +1,263 @@ +{ + "name": "3c6856dee85223b3d705", + "layouts": [ + { + "id": 0, + "position": { + "x": 0, + "y": 0, + "z": 0, + "width": 1280.3855421686746, + "height": 719.42168674698792 + } + } + ], + "singleVisual": { + "visualType": "tableEx", + "projections": { + "Values": [ + { + "queryRef": "Партнер.Партнер" + }, + { + "queryRef": "Основной отчет.Сумма продаж, руб" + }, + { + "queryRef": "Основной отчет.Торг. надбавка, руб" + }, + { + "queryRef": "Sum(Себестоимость.Сумма скидки)" + }, + { + "queryRef": "Распределение расходов.Чистая прибыль 2024" + }, + { + "queryRef": "Расходы по годам.% от выручки 2024" + }, + { + "queryRef": "Расходы по годам.Расходы на строку 2024" + }, + { + "queryRef": "Расходы по годам.Расходы на упаковку 2024" + } + ] + }, + "prototypeQuery": { + "Version": 2, + "From": [ + { + "Name": "п", + "Entity": "Партнер", + "Type": 0 + }, + { + "Name": "о", + "Entity": "Основной отчет", + "Type": 0 + }, + { + "Name": "р1", + "Entity": "Расходы по годам", + "Type": 0 + }, + { + "Name": "с", + "Entity": "Себестоимость", + "Type": 0 + } + ], + "Select": [ + { + "Column": { + "Expression": { + "SourceRef": { + "Source": "п" + } + }, + "Property": "Партнер" + }, + "Name": "Партнер.Партнер", + "NativeReferenceName": "Партнер" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Сумма продаж + РК, руб" + }, + "Name": "Основной отчет.Сумма продаж, руб", + "NativeReferenceName": "Сумма продаж, руб" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Торг. надбавка, руб" + }, + "Name": "Основной отчет.Торг. надбавка, руб", + "NativeReferenceName": "Торг. надбавка, руб" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "р1" + } + }, + "Property": "Чистая прибыль 2024" + }, + "Name": "Распределение расходов.Чистая прибыль 2024", + "NativeReferenceName": "Чистая прибыль 2024" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "р1" + } + }, + "Property": "% от выручки 2024" + }, + "Name": "Расходы по годам.% от выручки 2024", + "NativeReferenceName": "% от выручки 2024" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "р1" + } + }, + "Property": "Расходы на строку 2024" + }, + "Name": "Расходы по годам.Расходы на строку 2024", + "NativeReferenceName": "Расходы на строку 2024" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "р1" + } + }, + "Property": "Расходы на упаковку 2024" + }, + "Name": "Расходы по годам.Расходы на упаковку 2024", + "NativeReferenceName": "Расходы на упаковку 2024" + }, + { + "Aggregation": { + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Source": "с" + } + }, + "Property": "Сумма скидки" + } + }, + "Function": 0 + }, + "Name": "Sum(Себестоимость.Сумма скидки)", + "NativeReferenceName": "Сумма скидки" + } + ], + "OrderBy": [ + { + "Direction": 1, + "Expression": { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "р1" + } + }, + "Property": "Чистая прибыль 2024" + } + } + } + ] + }, + "drillFilterOtherVisuals": true, + "objects": { + "columnWidth": [ + { + "properties": { + "value": { + "expr": { + "Literal": { + "Value": "365.2072072072072D" + } + } + } + }, + "selector": { + "metadata": "Партнер.Партнер" + } + }, + { + "properties": { + "value": { + "expr": { + "Literal": { + "Value": "98.26023317010026D" + } + } + } + }, + "selector": { + "metadata": "Расходы по годам.% от выручки 2024" + } + }, + { + "properties": { + "value": { + "expr": { + "Literal": { + "Value": "104.65797804126939D" + } + } + } + }, + "selector": { + "metadata": "Расходы по годам.Расходы на строку 2024" + } + }, + { + "properties": { + "value": { + "expr": { + "Literal": { + "Value": "101.81410861738318D" + } + } + } + }, + "selector": { + "metadata": "Расходы по годам.Расходы на упаковку 2024" + } + } + ], + "total": [ + { + "properties": { + "totals": { + "expr": { + "Literal": { + "Value": "false" + } + } + } + } + } + ] + } + } +} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/005_Расходы по партнерам/visualContainers/00000_tableEx (3c685)/filters.json b/analytics/pbi/model/report/Report/sections/005_Расходы по партнерам/visualContainers/00000_tableEx (3c685)/filters.json new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/005_Расходы по партнерам/visualContainers/00000_tableEx (3c685)/filters.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/005_Расходы по партнерам/visualContainers/00000_tableEx (3c685)/visualContainer.json b/analytics/pbi/model/report/Report/sections/005_Расходы по партнерам/visualContainers/00000_tableEx (3c685)/visualContainer.json new file mode 100644 index 0000000..cb3f9ec --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/005_Расходы по партнерам/visualContainers/00000_tableEx (3c685)/visualContainer.json @@ -0,0 +1,8 @@ +{ + "height": 719.42, + "id": 5853011907, + "width": 1280.39, + "x": 0, + "y": 0, + "z": 0 +} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/006_Потенциальный рост/config.json b/analytics/pbi/model/report/Report/sections/006_Потенциальный рост/config.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/006_Потенциальный рост/config.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/006_Потенциальный рост/filters.json b/analytics/pbi/model/report/Report/sections/006_Потенциальный рост/filters.json new file mode 100644 index 0000000..a42097c --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/006_Потенциальный рост/filters.json @@ -0,0 +1,95 @@ +[ + { + "name": "9f55bace5e906010cd81", + "expression": { + "HierarchyLevel": { + "Expression": { + "Hierarchy": { + "Expression": { + "PropertyVariationSource": { + "Expression": { + "SourceRef": { + "Entity": ".Календарь" + } + }, + "Name": "Изменение", + "Property": "Дата" + } + }, + "Hierarchy": "Иерархия дат" + } + }, + "Level": "Год" + } + }, + "filter": { + "Version": 2, + "From": [ + { + "Name": "l", + "Entity": "LocalDateTable_e0374236-67f4-4331-b4f5-c977a3082bab", + "Type": 0 + } + ], + "Where": [ + { + "Condition": { + "In": { + "Expressions": [ + { + "Column": { + "Expression": { + "SourceRef": { + "Source": "l" + } + }, + "Property": "Год" + } + } + ], + "Values": [ + [ + { + "Literal": { + "Value": "2024L" + } + } + ] + ] + } + } + } + ] + }, + "type": "Categorical", + "cachedDisplayNames": [ + { + "id": { + "scopeId": { + "Comparison": { + "ComparisonKind": 0, + "Left": { + "Column": { + "Expression": { + "SourceRef": { + "Entity": "LocalDateTable_e0374236-67f4-4331-b4f5-c977a3082bab" + } + }, + "Property": "Год" + } + }, + "Right": { + "Literal": { + "Value": "2024L" + } + } + } + } + }, + "displayName": "2024" + } + ], + "howCreated": 1, + "objects": {} + } +] \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/006_Потенциальный рост/section.json b/analytics/pbi/model/report/Report/sections/006_Потенциальный рост/section.json new file mode 100644 index 0000000..d6bf127 --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/006_Потенциальный рост/section.json @@ -0,0 +1,8 @@ +{ + "displayName": "Потенциальный рост", + "displayOption": 1, + "height": 720, + "name": "a07f5b013d6bb8da3e20", + "ordinal": 6, + "width": 1280 +} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/006_Потенциальный рост/visualContainers/00000_tableEx (2bf35)/config.json b/analytics/pbi/model/report/Report/sections/006_Потенциальный рост/visualContainers/00000_tableEx (2bf35)/config.json new file mode 100644 index 0000000..0d0d5e2 --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/006_Потенциальный рост/visualContainers/00000_tableEx (2bf35)/config.json @@ -0,0 +1,180 @@ +{ + "name": "2bf35ef151b0e0a76547", + "layouts": [ + { + "id": 0, + "position": { + "x": 0, + "y": 0, + "z": 0, + "width": 1280, + "height": 720.20743301642176 + } + } + ], + "singleVisual": { + "visualType": "tableEx", + "projections": { + "Values": [ + { + "queryRef": "Группы.Группа" + }, + { + "queryRef": "Основной отчет.Остаток конец, руб" + }, + { + "queryRef": "Упущенные продажи.Упущ. торг. надбавка, руб" + }, + { + "queryRef": "Основной отчет.Потенциальный остаток, руб" + }, + { + "queryRef": "Основной отчет.Торг. надбавка, руб, %" + }, + { + "queryRef": "Основной отчет.Потенциальная ТН" + }, + { + "queryRef": "Основной отчет.Оборачиваемость" + }, + { + "queryRef": "Основной отчет.Рентаб. активов" + } + ] + }, + "prototypeQuery": { + "Version": 2, + "From": [ + { + "Name": "о", + "Entity": "Основной отчет", + "Type": 0 + }, + { + "Name": "г", + "Entity": "Группы", + "Type": 0 + }, + { + "Name": "у", + "Entity": "Упущенные продажи", + "Type": 0 + } + ], + "Select": [ + { + "Column": { + "Expression": { + "SourceRef": { + "Source": "г" + } + }, + "Property": "Группа" + }, + "Name": "Группы.Группа", + "NativeReferenceName": "Группа" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Торг. надбавка, руб, %" + }, + "Name": "Основной отчет.Торг. надбавка, руб, %", + "NativeReferenceName": "Торг. надбавка, руб, %" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Потенциальный остаток, руб" + }, + "Name": "Основной отчет.Потенциальный остаток, руб", + "NativeReferenceName": "Потенциальный остаток, руб" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Потенциальная ТН" + }, + "Name": "Основной отчет.Потенциальная ТН", + "NativeReferenceName": "Потенциальная ТН" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Оборачиваемость" + }, + "Name": "Основной отчет.Оборачиваемость", + "NativeReferenceName": "Оборачиваемость" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Рентаб. активов" + }, + "Name": "Основной отчет.Рентаб. активов", + "NativeReferenceName": "Рентаб. активов" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Остаток - МП конец, руб" + }, + "Name": "Основной отчет.Остаток конец, руб", + "NativeReferenceName": "Остаток конец, руб" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "у" + } + }, + "Property": "Упущ. торг. надбавка, руб" + }, + "Name": "Упущенные продажи.Упущ. торг. надбавка, руб", + "NativeReferenceName": "Упущ. торг. надбавка, руб" + } + ], + "OrderBy": [ + { + "Direction": 2, + "Expression": { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Потенциальная ТН" + } + } + } + ] + }, + "drillFilterOtherVisuals": true + } +} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/006_Потенциальный рост/visualContainers/00000_tableEx (2bf35)/filters.json b/analytics/pbi/model/report/Report/sections/006_Потенциальный рост/visualContainers/00000_tableEx (2bf35)/filters.json new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/006_Потенциальный рост/visualContainers/00000_tableEx (2bf35)/filters.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/006_Потенциальный рост/visualContainers/00000_tableEx (2bf35)/visualContainer.json b/analytics/pbi/model/report/Report/sections/006_Потенциальный рост/visualContainers/00000_tableEx (2bf35)/visualContainer.json new file mode 100644 index 0000000..c622036 --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/006_Потенциальный рост/visualContainers/00000_tableEx (2bf35)/visualContainer.json @@ -0,0 +1,8 @@ +{ + "height": 720.21, + "id": 5853011905, + "width": 1280, + "x": 0, + "y": 0, + "z": 0 +} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/007_Страница 1/config.json b/analytics/pbi/model/report/Report/sections/007_Страница 1/config.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/007_Страница 1/config.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/007_Страница 1/filters.json b/analytics/pbi/model/report/Report/sections/007_Страница 1/filters.json new file mode 100644 index 0000000..03f2aaa --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/007_Страница 1/filters.json @@ -0,0 +1,57 @@ +[ + { + "name": "ccbf6ee4bd4d8afd81a9", + "expression": { + "Column": { + "Expression": { + "SourceRef": { + "Entity": "Группы" + } + }, + "Property": "Группа" + } + }, + "filter": { + "Version": 2, + "From": [ + { + "Name": "г", + "Entity": "Группы", + "Type": 0 + } + ], + "Where": [ + { + "Condition": { + "In": { + "Expressions": [ + { + "Column": { + "Expression": { + "SourceRef": { + "Source": "г" + } + }, + "Property": "Группа" + } + } + ], + "Values": [ + [ + { + "Literal": { + "Value": "'Игрушки'" + } + } + ] + ] + } + } + } + ] + }, + "type": "Categorical", + "howCreated": 1, + "objects": {} + } +] \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/007_Страница 1/section.json b/analytics/pbi/model/report/Report/sections/007_Страница 1/section.json new file mode 100644 index 0000000..ab838be --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/007_Страница 1/section.json @@ -0,0 +1,8 @@ +{ + "displayName": "Страница 1", + "displayOption": 1, + "height": 720, + "name": "ffe36beceba1857dfa1f", + "ordinal": 7, + "width": 1280 +} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/007_Страница 1/visualContainers/00000_tableEx (c1173)/config.json b/analytics/pbi/model/report/Report/sections/007_Страница 1/visualContainers/00000_tableEx (c1173)/config.json new file mode 100644 index 0000000..c528718 --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/007_Страница 1/visualContainers/00000_tableEx (c1173)/config.json @@ -0,0 +1,406 @@ +{ + "name": "c117337a02c215e4ae5d", + "layouts": [ + { + "id": 0, + "position": { + "x": 0, + "y": 0, + "z": 0, + "width": 1280, + "height": 720.25723472668813 + } + } + ], + "singleVisual": { + "visualType": "tableEx", + "projections": { + "Values": [ + { + "queryRef": "Номенклатура.Фото" + }, + { + "queryRef": "Номенклатура.Код УТ" + }, + { + "queryRef": "Sum(Номенклатура.max_year_quantity)" + }, + { + "queryRef": "Sum(Номенклатура.max_quarter_quantity)" + }, + { + "queryRef": "Sum(Номенклатура.Цена учетная, руб)" + }, + { + "queryRef": "Основной отчет.Торг. надбавка, руб" + }, + { + "queryRef": "Номенклатура.ТН за квартал" + }, + { + "queryRef": "Номенклатура.ТН за год" + }, + { + "queryRef": "Основной отчет.Торг. надбавка минус РК, руб" + }, + { + "queryRef": "Номенклатура.Остаток МАКС за год, руб" + }, + { + "queryRef": "Номенклатура.Остаток МАКС за квартал, руб" + }, + { + "queryRef": "Номенклатура.Рентабельность %" + }, + { + "queryRef": "Номенклатура.Рентабельность за год" + }, + { + "queryRef": "Sum(Упущенные продажи.Дней в продаже)" + } + ] + }, + "prototypeQuery": { + "Version": 2, + "From": [ + { + "Name": "н", + "Entity": "Номенклатура", + "Type": 0 + }, + { + "Name": "о", + "Entity": "Основной отчет", + "Type": 0 + }, + { + "Name": "у", + "Entity": "Упущенные продажи", + "Type": 0 + } + ], + "Select": [ + { + "Column": { + "Expression": { + "SourceRef": { + "Source": "н" + } + }, + "Property": "Фото" + }, + "Name": "Номенклатура.Фото", + "NativeReferenceName": "Фото" + }, + { + "Column": { + "Expression": { + "SourceRef": { + "Source": "н" + } + }, + "Property": "Код УТ" + }, + "Name": "Номенклатура.Код УТ", + "NativeReferenceName": "Код УТ" + }, + { + "Aggregation": { + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Source": "н" + } + }, + "Property": "max_year_quantity" + } + }, + "Function": 0 + }, + "Name": "Sum(Номенклатура.max_year_quantity)", + "NativeReferenceName": "max_year_quantity" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "н" + } + }, + "Property": "Остаток МАКС за год, руб" + }, + "Name": "Номенклатура.Остаток МАКС за год, руб", + "NativeReferenceName": "Остаток МАКС за год, руб" + }, + { + "Aggregation": { + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Source": "н" + } + }, + "Property": "Цена учетная, руб" + } + }, + "Function": 0 + }, + "Name": "Sum(Номенклатура.Цена учетная, руб)", + "NativeReferenceName": "Цена учетная, руб" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "н" + } + }, + "Property": "Рентабельность % за квартал" + }, + "Name": "Номенклатура.Рентабельность %", + "NativeReferenceName": "Рентабельность % за квартал" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "н" + } + }, + "Property": "Рентабельность % за год" + }, + "Name": "Номенклатура.Рентабельность за год", + "NativeReferenceName": "Рентабельность % за год" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "н" + } + }, + "Property": "Остаток МАКС за квартал, руб" + }, + "Name": "Номенклатура.Остаток МАКС за квартал, руб", + "NativeReferenceName": "Остаток МАКС за квартал, руб" + }, + { + "Aggregation": { + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Source": "н" + } + }, + "Property": "max_quarter_quantity" + } + }, + "Function": 0 + }, + "Name": "Sum(Номенклатура.max_quarter_quantity)", + "NativeReferenceName": "max_quarter_quantity" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Торг. надбавка, руб" + }, + "Name": "Основной отчет.Торг. надбавка, руб", + "NativeReferenceName": "Торг. надбавка, руб" + }, + { + "Aggregation": { + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Source": "у" + } + }, + "Property": "Дней в продаже" + } + }, + "Function": 0 + }, + "Name": "Sum(Упущенные продажи.Дней в продаже)", + "NativeReferenceName": "Дней в продаже" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "н" + } + }, + "Property": "ТН за квартал" + }, + "Name": "Номенклатура.ТН за квартал", + "NativeReferenceName": "ТН за квартал" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "н" + } + }, + "Property": "ТН за год" + }, + "Name": "Номенклатура.ТН за год", + "NativeReferenceName": "ТН за год" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Торг. надбавка + РК, руб" + }, + "Name": "Основной отчет.Торг. надбавка минус РК, руб", + "NativeReferenceName": "Торг. надбавка минус РК, руб" + } + ], + "OrderBy": [ + { + "Direction": 2, + "Expression": { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "н" + } + }, + "Property": "Рентабельность % за год" + } + } + } + ] + }, + "drillFilterOtherVisuals": true, + "objects": { + "columnWidth": [ + { + "properties": { + "value": { + "expr": { + "Literal": { + "Value": "112.08922174722824D" + } + } + } + }, + "selector": { + "metadata": "Номенклатура.Остаток МАКС за год, руб" + } + }, + { + "properties": { + "value": { + "expr": { + "Literal": { + "Value": "86.87160050508506D" + } + } + } + }, + "selector": { + "metadata": "Номенклатура.Остаток МАКС за квартал, руб" + } + }, + { + "properties": { + "value": { + "expr": { + "Literal": { + "Value": "101.97026022304833D" + } + } + } + }, + "selector": { + "metadata": "Номенклатура.Рентабельность %" + } + }, + { + "properties": { + "value": { + "expr": { + "Literal": { + "Value": "72.78064515261566D" + } + } + } + }, + "selector": { + "metadata": "Номенклатура.Рентабельность за год" + } + }, + { + "properties": { + "value": { + "expr": { + "Literal": { + "Value": "72.0686106261079D" + } + } + } + }, + "selector": { + "metadata": "Основной отчет.Торг. надбавка, руб" + } + }, + { + "properties": { + "value": { + "expr": { + "Literal": { + "Value": "135.08550263750448D" + } + } + } + }, + "selector": { + "metadata": "Sum(Номенклатура.Цена учетная, руб)" + } + }, + { + "properties": { + "value": { + "expr": { + "Literal": { + "Value": "82.44979918627925D" + } + } + } + }, + "selector": { + "metadata": "Sum(Упущенные продажи.Дней в продаже)" + } + }, + { + "properties": { + "value": { + "expr": { + "Literal": { + "Value": "92.72668604258257D" + } + } + } + }, + "selector": { + "metadata": "Sum(Номенклатура.max_quarter_quantity)" + } + } + ] + } + } +} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/007_Страница 1/visualContainers/00000_tableEx (c1173)/filters.json b/analytics/pbi/model/report/Report/sections/007_Страница 1/visualContainers/00000_tableEx (c1173)/filters.json new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/007_Страница 1/visualContainers/00000_tableEx (c1173)/filters.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/007_Страница 1/visualContainers/00000_tableEx (c1173)/visualContainer.json b/analytics/pbi/model/report/Report/sections/007_Страница 1/visualContainers/00000_tableEx (c1173)/visualContainer.json new file mode 100644 index 0000000..66c38bf --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/007_Страница 1/visualContainers/00000_tableEx (c1173)/visualContainer.json @@ -0,0 +1,8 @@ +{ + "height": 720.26, + "id": 5853011913, + "width": 1280, + "x": 0, + "y": 0, + "z": 0 +} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/008_Учетная цена остатка/config.json b/analytics/pbi/model/report/Report/sections/008_Учетная цена остатка/config.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/008_Учетная цена остатка/config.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/008_Учетная цена остатка/filters.json b/analytics/pbi/model/report/Report/sections/008_Учетная цена остатка/filters.json new file mode 100644 index 0000000..09032a2 --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/008_Учетная цена остатка/filters.json @@ -0,0 +1,57 @@ +[ + { + "name": "ef4eee37ea4e1dce7a95", + "expression": { + "Column": { + "Expression": { + "SourceRef": { + "Entity": "Номенклатура" + } + }, + "Property": "Код УТ" + } + }, + "filter": { + "Version": 2, + "From": [ + { + "Name": "н", + "Entity": "Номенклатура", + "Type": 0 + } + ], + "Where": [ + { + "Condition": { + "In": { + "Expressions": [ + { + "Column": { + "Expression": { + "SourceRef": { + "Source": "н" + } + }, + "Property": "Код УТ" + } + } + ], + "Values": [ + [ + { + "Literal": { + "Value": "'УТ-00210673'" + } + } + ] + ] + } + } + } + ] + }, + "type": "Categorical", + "howCreated": 1, + "objects": {} + } +] \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/008_Учетная цена остатка/section.json b/analytics/pbi/model/report/Report/sections/008_Учетная цена остатка/section.json new file mode 100644 index 0000000..13d102e --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/008_Учетная цена остатка/section.json @@ -0,0 +1,8 @@ +{ + "displayName": "Учетная цена остатка", + "displayOption": 1, + "height": 720, + "name": "21a1880180a03c12e6c2", + "ordinal": 8, + "width": 1280 +} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/008_Учетная цена остатка/visualContainers/00000_pivotTable (814c2)/config.json b/analytics/pbi/model/report/Report/sections/008_Учетная цена остатка/visualContainers/00000_pivotTable (814c2)/config.json new file mode 100644 index 0000000..02045dd --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/008_Учетная цена остатка/visualContainers/00000_pivotTable (814c2)/config.json @@ -0,0 +1,474 @@ +{ + "name": "814c26460b52bb93ad35", + "layouts": [ + { + "id": 0, + "position": { + "x": 11.307498533420752, + "y": 0, + "z": 0, + "width": 1269.2667103764795, + "height": 407.06994720314708, + "tabOrder": 0 + } + } + ], + "singleVisual": { + "visualType": "pivotTable", + "projections": { + "Rows": [ + { + "queryRef": ".Календарь.Дата.Изменение.Иерархия дат.Год", + "active": true + }, + { + "queryRef": ".Календарь.Дата.Изменение.Иерархия дат.Месяц", + "active": true + }, + { + "queryRef": ".Календарь.Дата.Изменение.Иерархия дат.День", + "active": true + }, + { + "queryRef": "Закупки.Статья", + "active": true + } + ], + "Values": [ + { + "queryRef": "Закупки.Сумма закупки, руб" + }, + { + "queryRef": "Sum(Закупки.Кол-во закупка, шт)" + }, + { + "queryRef": "Sum(Номенклатура.Цена учетная, руб)" + }, + { + "queryRef": "Sum(Закупки.Закуп.Закупка, руб)" + }, + { + "queryRef": "Sum(Закупки.Закуп.Доставка, руб)" + }, + { + "queryRef": "Sum(Закупки.Закуп.НДС, руб)" + }, + { + "queryRef": "Sum(Закупки.Закуп.Таможня, руб)" + }, + { + "queryRef": "Sum(Закупки.Закуп.Производство, руб)" + }, + { + "queryRef": "Sum(Закупки.Закуп.Доп расходы, руб)" + } + ] + }, + "prototypeQuery": { + "Version": 2, + "From": [ + { + "Name": "к", + "Entity": ".Календарь", + "Type": 0 + }, + { + "Name": "з", + "Entity": "Закупки", + "Type": 0 + }, + { + "Name": "н", + "Entity": "Номенклатура", + "Type": 0 + } + ], + "Select": [ + { + "HierarchyLevel": { + "Expression": { + "Hierarchy": { + "Expression": { + "PropertyVariationSource": { + "Expression": { + "SourceRef": { + "Source": "к" + } + }, + "Name": "Изменение", + "Property": "Дата" + } + }, + "Hierarchy": "Иерархия дат" + } + }, + "Level": "Год" + }, + "Name": ".Календарь.Дата.Изменение.Иерархия дат.Год", + "NativeReferenceName": "Дата Год" + }, + { + "HierarchyLevel": { + "Expression": { + "Hierarchy": { + "Expression": { + "PropertyVariationSource": { + "Expression": { + "SourceRef": { + "Source": "к" + } + }, + "Name": "Изменение", + "Property": "Дата" + } + }, + "Hierarchy": "Иерархия дат" + } + }, + "Level": "Месяц" + }, + "Name": ".Календарь.Дата.Изменение.Иерархия дат.Месяц", + "NativeReferenceName": "Дата Месяц" + }, + { + "HierarchyLevel": { + "Expression": { + "Hierarchy": { + "Expression": { + "PropertyVariationSource": { + "Expression": { + "SourceRef": { + "Source": "к" + } + }, + "Name": "Изменение", + "Property": "Дата" + } + }, + "Hierarchy": "Иерархия дат" + } + }, + "Level": "День" + }, + "Name": ".Календарь.Дата.Изменение.Иерархия дат.День", + "NativeReferenceName": "Дата День" + }, + { + "Aggregation": { + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Source": "з" + } + }, + "Property": "Закуп.Закупка, руб" + } + }, + "Function": 0 + }, + "Name": "Sum(Закупки.Закуп.Закупка, руб)", + "NativeReferenceName": "Закуп.Закупка, руб" + }, + { + "Aggregation": { + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Source": "з" + } + }, + "Property": "Закуп.Доставка, руб" + } + }, + "Function": 0 + }, + "Name": "Sum(Закупки.Закуп.Доставка, руб)", + "NativeReferenceName": "Закуп.Доставка, руб" + }, + { + "Aggregation": { + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Source": "з" + } + }, + "Property": "Закуп.НДС, руб" + } + }, + "Function": 0 + }, + "Name": "Sum(Закупки.Закуп.НДС, руб)", + "NativeReferenceName": "Закуп.НДС, руб" + }, + { + "Aggregation": { + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Source": "з" + } + }, + "Property": "Закуп.Таможня, руб" + } + }, + "Function": 0 + }, + "Name": "Sum(Закупки.Закуп.Таможня, руб)", + "NativeReferenceName": "Закуп.Таможня, руб" + }, + { + "Aggregation": { + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Source": "з" + } + }, + "Property": "Закуп.Производство, руб" + } + }, + "Function": 0 + }, + "Name": "Sum(Закупки.Закуп.Производство, руб)", + "NativeReferenceName": "Закуп.Производство, руб" + }, + { + "Aggregation": { + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Source": "з" + } + }, + "Property": "Закуп.Доп расходы, руб" + } + }, + "Function": 0 + }, + "Name": "Sum(Закупки.Закуп.Доп расходы, руб)", + "NativeReferenceName": "Закуп.Доп расходы, руб" + }, + { + "Column": { + "Expression": { + "SourceRef": { + "Source": "з" + } + }, + "Property": "Статья" + }, + "Name": "Закупки.Статья", + "NativeReferenceName": "Статья" + }, + { + "Aggregation": { + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Source": "з" + } + }, + "Property": "Кол-во закупка, шт" + } + }, + "Function": 0 + }, + "Name": "Sum(Закупки.Кол-во закупка, шт)", + "NativeReferenceName": "Кол-во закупка, шт" + }, + { + "Aggregation": { + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Source": "н" + } + }, + "Property": "Цена учетная, руб" + } + }, + "Function": 0 + }, + "Name": "Sum(Номенклатура.Цена учетная, руб)", + "NativeReferenceName": "Цена учетная, руб" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "з" + } + }, + "Property": "Сумма закупки, руб" + }, + "Name": "Закупки.Сумма закупки, руб", + "NativeReferenceName": "Сумма закупки, руб" + } + ] + }, + "expansionStates": [ + { + "roles": [ + "Rows" + ], + "levels": [ + { + "queryRefs": [ + ".Календарь.Дата.Изменение.Иерархия дат.Год" + ], + "isCollapsed": true, + "identityKeys": [ + { + "Column": { + "Expression": { + "SourceRef": { + "Entity": "LocalDateTable_e0374236-67f4-4331-b4f5-c977a3082bab" + } + }, + "Property": "Год" + } + } + ], + "isPinned": true + }, + { + "queryRefs": [ + ".Календарь.Дата.Изменение.Иерархия дат.Месяц" + ], + "isCollapsed": true, + "identityKeys": [ + { + "Column": { + "Expression": { + "SourceRef": { + "Entity": "LocalDateTable_e0374236-67f4-4331-b4f5-c977a3082bab" + } + }, + "Property": "Месяц" + } + } + ], + "isPinned": true + }, + { + "queryRefs": [ + ".Календарь.Дата.Изменение.Иерархия дат.День" + ], + "isCollapsed": true, + "identityKeys": [ + { + "Column": { + "Expression": { + "SourceRef": { + "Entity": "LocalDateTable_e0374236-67f4-4331-b4f5-c977a3082bab" + } + }, + "Property": "День" + } + } + ], + "isPinned": true + }, + { + "queryRefs": [ + "Закупки.Статья" + ], + "isCollapsed": true, + "isPinned": true + } + ], + "root": { + "identityValues": null, + "children": [ + { + "identityValues": [ + { + "Literal": { + "Value": "2025L" + } + } + ], + "isToggled": true, + "children": [ + { + "identityValues": [ + { + "Literal": { + "Value": "'Октябрь'" + } + } + ], + "isToggled": true, + "children": [ + { + "identityValues": [ + { + "Literal": { + "Value": "6L" + } + } + ], + "isToggled": true + }, + { + "identityValues": [ + { + "Literal": { + "Value": "14L" + } + } + ], + "isToggled": true + } + ] + }, + { + "identityValues": [ + { + "Literal": { + "Value": "'Сентябрь'" + } + } + ], + "isToggled": true, + "children": [ + { + "identityValues": [ + { + "Literal": { + "Value": "26L" + } + } + ], + "isToggled": true + }, + { + "identityValues": [ + { + "Literal": { + "Value": "10L" + } + } + ], + "isToggled": true + } + ] + } + ] + } + ] + } + } + ], + "drillFilterOtherVisuals": true + } +} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/008_Учетная цена остатка/visualContainers/00000_pivotTable (814c2)/filters.json b/analytics/pbi/model/report/Report/sections/008_Учетная цена остатка/visualContainers/00000_pivotTable (814c2)/filters.json new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/008_Учетная цена остатка/visualContainers/00000_pivotTable (814c2)/filters.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/008_Учетная цена остатка/visualContainers/00000_pivotTable (814c2)/visualContainer.json b/analytics/pbi/model/report/Report/sections/008_Учетная цена остатка/visualContainers/00000_pivotTable (814c2)/visualContainer.json new file mode 100644 index 0000000..678ad35 --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/008_Учетная цена остатка/visualContainers/00000_pivotTable (814c2)/visualContainer.json @@ -0,0 +1,8 @@ +{ + "height": 407.07, + "id": 5853011914, + "width": 1269.27, + "x": 11.31, + "y": 0, + "z": 0 +} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/009_МП оборот и расходы/config.json b/analytics/pbi/model/report/Report/sections/009_МП оборот и расходы/config.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/009_МП оборот и расходы/config.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/009_МП оборот и расходы/filters.json b/analytics/pbi/model/report/Report/sections/009_МП оборот и расходы/filters.json new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/009_МП оборот и расходы/filters.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/009_МП оборот и расходы/section.json b/analytics/pbi/model/report/Report/sections/009_МП оборот и расходы/section.json new file mode 100644 index 0000000..fc8a1d0 --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/009_МП оборот и расходы/section.json @@ -0,0 +1,8 @@ +{ + "displayName": "МП оборот и расходы", + "displayOption": 1, + "height": 720, + "name": "ecf3d6be773af5b9f903", + "ordinal": 9, + "width": 1280 +} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/009_МП оборот и расходы/visualContainers/00000_pivotTable (19efe)/config.json b/analytics/pbi/model/report/Report/sections/009_МП оборот и расходы/visualContainers/00000_pivotTable (19efe)/config.json new file mode 100644 index 0000000..a1f7b60 --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/009_МП оборот и расходы/visualContainers/00000_pivotTable (19efe)/config.json @@ -0,0 +1,626 @@ +{ + "name": "19efe866dcf60ed65995", + "layouts": [ + { + "id": 0, + "position": { + "x": 10.684520574745125, + "y": 0, + "z": 0, + "width": 1269.6771949655456, + "height": 632.16746733908656, + "tabOrder": 0 + } + } + ], + "singleVisual": { + "visualType": "pivotTable", + "projections": { + "Rows": [ + { + "queryRef": "Группы.Группа", + "active": true + }, + { + "queryRef": "Партнер.Партнер" + }, + { + "queryRef": ".Календарь.Дата.Изменение.Иерархия дат.Год" + }, + { + "queryRef": ".Календарь.Дата.Изменение.Иерархия дат.Месяц" + } + ], + "Values": [ + { + "queryRef": "Основной отчет.Торг. надбавка, руб" + }, + { + "queryRef": "mp оборот.НДС_20 по расходам, руб" + }, + { + "queryRef": "mp оборот.Расходы МП + РК + СПП, руб" + }, + { + "queryRef": "Основной отчет.Торг. надбавка, руб, %" + }, + { + "queryRef": "mp оборот.Расходы к учетной сумме, %" + }, + { + "queryRef": "mp оборот.Расходы к обороту, %" + }, + { + "queryRef": "Sum(mp оборот.Сумма оборот МП, руб)" + }, + { + "queryRef": "Основной отчет.Сумма продаж, руб" + }, + { + "queryRef": "Sum(Стоимость МП.Расходы МП, руб)" + }, + { + "queryRef": "Sum(mp реклама.Затраты РК, руб)" + }, + { + "queryRef": "Основной отчет.Сумма продаж + МП + РК, руб" + } + ] + }, + "prototypeQuery": { + "Version": 2, + "From": [ + { + "Name": "к", + "Entity": ".Календарь", + "Type": 0 + }, + { + "Name": "m", + "Entity": "mp оборот", + "Type": 0 + }, + { + "Name": "о", + "Entity": "Основной отчет", + "Type": 0 + }, + { + "Name": "с", + "Entity": "Стоимость МП", + "Type": 0 + }, + { + "Name": "m1", + "Entity": "mp реклама", + "Type": 0 + }, + { + "Name": "г", + "Entity": "Группы", + "Type": 0 + }, + { + "Name": "п", + "Entity": "Партнер", + "Type": 0 + } + ], + "Select": [ + { + "HierarchyLevel": { + "Expression": { + "Hierarchy": { + "Expression": { + "PropertyVariationSource": { + "Expression": { + "SourceRef": { + "Source": "к" + } + }, + "Name": "Изменение", + "Property": "Дата" + } + }, + "Hierarchy": "Иерархия дат" + } + }, + "Level": "Год" + }, + "Name": ".Календарь.Дата.Изменение.Иерархия дат.Год", + "NativeReferenceName": "Дата Год" + }, + { + "HierarchyLevel": { + "Expression": { + "Hierarchy": { + "Expression": { + "PropertyVariationSource": { + "Expression": { + "SourceRef": { + "Source": "к" + } + }, + "Name": "Изменение", + "Property": "Дата" + } + }, + "Hierarchy": "Иерархия дат" + } + }, + "Level": "Месяц" + }, + "Name": ".Календарь.Дата.Изменение.Иерархия дат.Месяц", + "NativeReferenceName": "Дата Месяц" + }, + { + "Aggregation": { + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Source": "m" + } + }, + "Property": "Сумма оборот МП, руб" + } + }, + "Function": 0 + }, + "Name": "Sum(mp оборот.Сумма оборот МП, руб)", + "NativeReferenceName": "Сумма оборот МП, руб" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Сумма продаж, руб" + }, + "Name": "Основной отчет.Сумма продаж, руб", + "NativeReferenceName": "Сумма продаж, руб" + }, + { + "Aggregation": { + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Source": "с" + } + }, + "Property": "Расходы МП, руб" + } + }, + "Function": 0 + }, + "Name": "Sum(Стоимость МП.Расходы МП, руб)", + "NativeReferenceName": "Расходы МП, руб" + }, + { + "Aggregation": { + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Source": "m1" + } + }, + "Property": "Затраты РК, руб" + } + }, + "Function": 0 + }, + "Name": "Sum(mp реклама.Затраты РК, руб)", + "NativeReferenceName": "Затраты РК, руб" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Сумма продаж + МП + РК, руб" + }, + "Name": "Основной отчет.Сумма продаж + МП + РК, руб", + "NativeReferenceName": "Сумма продаж + МП + РК, руб" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "m" + } + }, + "Property": "Расходы к обороту, %" + }, + "Name": "mp оборот.Расходы к обороту, %", + "NativeReferenceName": "Расходы к обороту, %" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Торг. надбавка, руб" + }, + "Name": "Основной отчет.Торг. надбавка, руб", + "NativeReferenceName": "Торг. надбавка, руб" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "m" + } + }, + "Property": "Расходы МП + РК + СПП, руб" + }, + "Name": "mp оборот.Расходы МП + РК + СПП, руб", + "NativeReferenceName": "Расходы МП + РК + СПП, руб" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "m" + } + }, + "Property": "НДС_20 по расходам, руб" + }, + "Name": "mp оборот.НДС_20 по расходам, руб", + "NativeReferenceName": "НДС_20 по расходам, руб" + }, + { + "Column": { + "Expression": { + "SourceRef": { + "Source": "г" + } + }, + "Property": "Группа" + }, + "Name": "Группы.Группа", + "NativeReferenceName": "Группа" + }, + { + "Column": { + "Expression": { + "SourceRef": { + "Source": "п" + } + }, + "Property": "Партнер" + }, + "Name": "Партнер.Партнер", + "NativeReferenceName": "Партнер" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "m" + } + }, + "Property": "Расходы к учетной сумме, %" + }, + "Name": "mp оборот.Расходы к учетной сумме, %", + "NativeReferenceName": "Расходы к учетной сумме, %" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Торг. надбавка, руб, %" + }, + "Name": "Основной отчет.Торг. надбавка, руб, %", + "NativeReferenceName": "Торг. надбавка, руб, %" + } + ] + }, + "expansionStates": [ + { + "roles": [ + "Rows" + ], + "levels": [ + { + "queryRefs": [ + "Группы.Группа" + ], + "isCollapsed": true, + "identityKeys": [ + { + "Column": { + "Expression": { + "SourceRef": { + "Entity": "Группы" + } + }, + "Property": "Группа" + } + } + ], + "isPinned": true + }, + { + "queryRefs": [ + "Партнер.Партнер" + ], + "isCollapsed": true, + "identityKeys": [ + { + "Column": { + "Expression": { + "SourceRef": { + "Entity": "Партнер" + } + }, + "Property": "Партнер" + } + } + ], + "isPinned": true + }, + { + "queryRefs": [ + ".Календарь.Дата.Изменение.Иерархия дат.Год" + ], + "isCollapsed": true, + "identityKeys": [ + { + "Column": { + "Expression": { + "SourceRef": { + "Entity": "LocalDateTable_e0374236-67f4-4331-b4f5-c977a3082bab" + } + }, + "Property": "Год" + } + } + ], + "isPinned": true + }, + { + "queryRefs": [ + ".Календарь.Дата.Изменение.Иерархия дат.Месяц" + ], + "isCollapsed": true, + "identityKeys": [ + { + "Column": { + "Expression": { + "SourceRef": { + "Entity": "LocalDateTable_e0374236-67f4-4331-b4f5-c977a3082bab" + } + }, + "Property": "Месяц" + } + } + ], + "isPinned": true + } + ], + "root": { + "identityValues": null, + "children": [ + { + "identityValues": [ + { + "Literal": { + "Value": "'Клеевые материалы'" + } + } + ], + "children": [ + { + "identityValues": [ + { + "Literal": { + "Value": "'ИНТЕРНЕТ РЕШЕНИЯ ООО'" + } + } + ], + "isToggled": true, + "children": [ + { + "identityValues": [ + { + "Literal": { + "Value": "2025L" + } + } + ], + "isToggled": true + } + ] + } + ] + }, + { + "identityValues": [ + { + "Literal": { + "Value": "'Пленки виниловые'" + } + } + ], + "children": [ + { + "identityValues": [ + { + "Literal": { + "Value": "'ИНТЕРНЕТ РЕШЕНИЯ ООО'" + } + } + ], + "isToggled": true, + "children": [ + { + "identityValues": [ + { + "Literal": { + "Value": "2025L" + } + } + ], + "isToggled": true + } + ] + } + ] + }, + { + "identityValues": [ + { + "Literal": { + "Value": "'Пряжа'" + } + } + ], + "children": [ + { + "identityValues": [ + { + "Literal": { + "Value": "'ИНТЕРНЕТ РЕШЕНИЯ ООО'" + } + } + ], + "isToggled": true, + "children": [ + { + "identityValues": [ + { + "Literal": { + "Value": "2025L" + } + } + ], + "isToggled": true + } + ] + } + ] + }, + { + "identityValues": [ + { + "Literal": { + "Value": "'Резинка'" + } + } + ], + "children": [ + { + "identityValues": [ + { + "Literal": { + "Value": "'ИНТЕРНЕТ РЕШЕНИЯ ООО'" + } + } + ], + "isToggled": true, + "children": [ + { + "identityValues": [ + { + "Literal": { + "Value": "2025L" + } + } + ], + "isToggled": true + } + ] + }, + { + "identityValues": [ + { + "Literal": { + "Value": "'ВАЙЛДБЕРРИЗ ООО'" + } + } + ], + "isToggled": true, + "children": [ + { + "identityValues": [ + { + "Literal": { + "Value": "2025L" + } + } + ], + "isToggled": true + } + ] + } + ] + }, + { + "identityValues": [ + { + "Literal": { + "Value": "'Ткани'" + } + } + ], + "children": [ + { + "identityValues": [ + { + "Literal": { + "Value": "'ИНТЕРНЕТ РЕШЕНИЯ ООО'" + } + } + ], + "isToggled": true, + "children": [ + { + "identityValues": [ + { + "Literal": { + "Value": "2025L" + } + } + ], + "isToggled": true + } + ] + } + ] + } + ] + } + } + ], + "drillFilterOtherVisuals": true, + "objects": { + "columnWidth": [ + { + "properties": { + "value": { + "expr": { + "Literal": { + "Value": "139.22256829004024D" + } + } + } + }, + "selector": { + "metadata": "mp оборот.Расходы МП + РК + СПП, руб" + } + } + ] + } + } +} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/009_МП оборот и расходы/visualContainers/00000_pivotTable (19efe)/dataTransforms.json b/analytics/pbi/model/report/Report/sections/009_МП оборот и расходы/visualContainers/00000_pivotTable (19efe)/dataTransforms.json new file mode 100644 index 0000000..4cf361a --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/009_МП оборот и расходы/visualContainers/00000_pivotTable (19efe)/dataTransforms.json @@ -0,0 +1,1090 @@ +{ + "objects": { + "columnWidth": [ + { + "properties": { + "value": { + "expr": { + "Literal": { + "Value": "139.22256829004024D" + } + } + } + }, + "selector": { + "metadata": "mp оборот.Расходы МП + РК + СПП, руб" + } + } + ] + }, + "projectionOrdering": { + "Rows": [ + 11, + 12, + 0, + 1 + ], + "Values": [ + 8, + 10, + 9, + 14, + 13, + 7, + 2, + 3, + 4, + 5, + 6 + ] + }, + "projectionActiveItems": { + "Rows": [ + { + "queryRef": "Группы.Группа", + "suppressConcat": false + } + ] + }, + "queryMetadata": { + "Select": [ + { + "Restatement": "Год", + "Name": ".Календарь.Дата.Изменение.Иерархия дат.Год", + "Type": 3 + }, + { + "Restatement": "Месяц", + "Name": ".Календарь.Дата.Изменение.Иерархия дат.Месяц", + "Type": 2048 + }, + { + "Restatement": "Сумма оборот МП, руб", + "Name": "Sum(mp оборот.Сумма оборот МП, руб)", + "Type": 1, + "Format": "#,0" + }, + { + "Restatement": "Сумма продаж, руб", + "Name": "Основной отчет.Сумма продаж, руб", + "Type": 1, + "Format": "#,0" + }, + { + "Restatement": "Расходы МП, руб", + "Name": "Sum(Стоимость МП.Расходы МП, руб)", + "Type": 1 + }, + { + "Restatement": "Затраты РК, руб", + "Name": "Sum(mp реклама.Затраты РК, руб)", + "Type": 1, + "Format": "#,0" + }, + { + "Restatement": "Сумма продаж + МП + РК, руб", + "Name": "Основной отчет.Сумма продаж + МП + РК, руб", + "Type": 1, + "Format": "#,0" + }, + { + "Restatement": "Расходы к обороту, %", + "Name": "mp оборот.Расходы к обороту, %", + "Type": 1 + }, + { + "Restatement": "Торг. надбавка, руб", + "Name": "Основной отчет.Торг. надбавка, руб", + "Type": 1, + "Format": "#,0" + }, + { + "Restatement": "Расходы МП + РК + СПП, руб", + "Name": "mp оборот.Расходы МП + РК + СПП, руб", + "Type": 1, + "Format": "#,0" + }, + { + "Restatement": "НДС_20 по расходам, руб", + "Name": "mp оборот.НДС_20 по расходам, руб", + "Type": 1, + "Format": "#,0" + }, + { + "Restatement": "Группа", + "Name": "Группы.Группа", + "Type": 2048 + }, + { + "Restatement": "Партнер", + "Name": "Партнер.Партнер", + "Type": 2048 + }, + { + "Restatement": "Расходы к учетной сумме, %", + "Name": "mp оборот.Расходы к учетной сумме, %", + "Type": 1 + }, + { + "Restatement": "Торг. надбавка, руб, %", + "Name": "Основной отчет.Торг. надбавка, руб, %", + "Type": 1, + "Format": "#,0" + } + ], + "Filters": [ + { + "type": 0, + "expression": { + "HierarchyLevel": { + "Expression": { + "Hierarchy": { + "Expression": { + "PropertyVariationSource": { + "Expression": { + "SourceRef": { + "Entity": ".Календарь" + } + }, + "Name": "Изменение", + "Property": "Дата" + } + }, + "Hierarchy": "Иерархия дат" + } + }, + "Level": "Год" + } + } + }, + { + "type": 0, + "expression": { + "HierarchyLevel": { + "Expression": { + "Hierarchy": { + "Expression": { + "PropertyVariationSource": { + "Expression": { + "SourceRef": { + "Entity": ".Календарь" + } + }, + "Name": "Изменение", + "Property": "Дата" + } + }, + "Hierarchy": "Иерархия дат" + } + }, + "Level": "Месяц" + } + } + }, + { + "type": 0, + "expression": { + "Column": { + "Expression": { + "SourceRef": { + "Entity": "Партнер" + } + }, + "Property": "Партнер" + } + } + }, + { + "type": 2, + "expression": { + "Aggregation": { + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Entity": "mp оборот" + } + }, + "Property": "Сумма оборот МП, руб" + } + }, + "Function": 0 + } + } + }, + { + "type": 2, + "expression": { + "Measure": { + "Expression": { + "SourceRef": { + "Entity": "Основной отчет" + } + }, + "Property": "Сумма продаж, руб" + } + } + }, + { + "type": 2, + "expression": { + "Aggregation": { + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Entity": "Стоимость МП" + } + }, + "Property": "Расходы МП, руб" + } + }, + "Function": 0 + } + } + }, + { + "type": 2, + "expression": { + "Aggregation": { + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Entity": "mp реклама" + } + }, + "Property": "Затраты РК, руб" + } + }, + "Function": 0 + } + } + }, + { + "type": 2, + "expression": { + "Measure": { + "Expression": { + "SourceRef": { + "Entity": "Основной отчет" + } + }, + "Property": "Сумма продаж + МП + РК, руб" + } + } + }, + { + "type": 2, + "expression": { + "Measure": { + "Expression": { + "SourceRef": { + "Entity": "Основной отчет" + } + }, + "Property": "Торг. надбавка, руб" + } + } + }, + { + "type": 2, + "expression": { + "Measure": { + "Expression": { + "SourceRef": { + "Entity": "mp оборот" + } + }, + "Property": "Расходы МП + РК + СПП, руб" + } + } + }, + { + "type": 2, + "expression": { + "Measure": { + "Expression": { + "SourceRef": { + "Entity": "mp оборот" + } + }, + "Property": "НДС_20 по расходам, руб" + } + } + }, + { + "type": 2, + "expression": { + "Measure": { + "Expression": { + "SourceRef": { + "Entity": "mp оборот" + } + }, + "Property": "Расходы к обороту, %" + } + } + }, + { + "type": 2, + "expression": { + "Measure": { + "Expression": { + "SourceRef": { + "Entity": "mp оборот" + } + }, + "Property": "Расходы к учетной сумме, %" + } + } + }, + { + "type": 0, + "expression": { + "Column": { + "Expression": { + "SourceRef": { + "Entity": "Группы" + } + }, + "Property": "Группа" + } + } + }, + { + "type": 2, + "expression": { + "Measure": { + "Expression": { + "SourceRef": { + "Entity": "Основной отчет" + } + }, + "Property": "Торг. надбавка, руб, %" + } + } + } + ] + }, + "visualElements": [ + { + "DataRoles": [ + { + "Name": "Rows", + "Projection": 11, + "isActive": true + }, + { + "Name": "Rows", + "Projection": 12, + "isActive": false + }, + { + "Name": "Rows", + "Projection": 0, + "isActive": false + }, + { + "Name": "Rows", + "Projection": 1, + "isActive": false + }, + { + "Name": "Values", + "Projection": 8, + "isActive": false + }, + { + "Name": "Values", + "Projection": 10, + "isActive": false + }, + { + "Name": "Values", + "Projection": 9, + "isActive": false + }, + { + "Name": "Values", + "Projection": 14, + "isActive": false + }, + { + "Name": "Values", + "Projection": 13, + "isActive": false + }, + { + "Name": "Values", + "Projection": 7, + "isActive": false + }, + { + "Name": "Values", + "Projection": 2, + "isActive": false + }, + { + "Name": "Values", + "Projection": 3, + "isActive": false + }, + { + "Name": "Values", + "Projection": 4, + "isActive": false + }, + { + "Name": "Values", + "Projection": 5, + "isActive": false + }, + { + "Name": "Values", + "Projection": 6, + "isActive": false + } + ] + } + ], + "selects": [ + { + "displayName": "Год", + "queryName": ".Календарь.Дата.Изменение.Иерархия дат.Год", + "roles": { + "Rows": true + }, + "type": { + "category": "Years", + "underlyingType": 66308 + }, + "expr": { + "HierarchyLevel": { + "Expression": { + "Hierarchy": { + "Expression": { + "PropertyVariationSource": { + "Expression": { + "SourceRef": { + "Entity": ".Календарь" + } + }, + "Name": "Изменение", + "Property": "Дата" + } + }, + "Hierarchy": "Иерархия дат" + } + }, + "Level": "Год" + } + } + }, + { + "displayName": "Месяц", + "queryName": ".Календарь.Дата.Изменение.Иерархия дат.Месяц", + "roles": { + "Rows": true + }, + "type": { + "category": "Months", + "underlyingType": 131585 + }, + "expr": { + "HierarchyLevel": { + "Expression": { + "Hierarchy": { + "Expression": { + "PropertyVariationSource": { + "Expression": { + "SourceRef": { + "Entity": ".Календарь" + } + }, + "Name": "Изменение", + "Property": "Дата" + } + }, + "Hierarchy": "Иерархия дат" + } + }, + "Level": "Месяц" + } + } + }, + { + "displayName": "Сумма оборот МП, руб", + "format": "#,0", + "queryName": "Sum(mp оборот.Сумма оборот МП, руб)", + "roles": { + "Values": true + }, + "type": { + "category": null, + "underlyingType": 259 + }, + "expr": { + "Aggregation": { + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Entity": "mp оборот" + } + }, + "Property": "Сумма оборот МП, руб" + } + }, + "Function": 0 + } + } + }, + { + "displayName": "Сумма продаж, руб", + "format": "#,0", + "queryName": "Основной отчет.Сумма продаж, руб", + "roles": { + "Values": true + }, + "type": { + "category": null, + "underlyingType": 259 + }, + "expr": { + "Measure": { + "Expression": { + "SourceRef": { + "Entity": "Основной отчет" + } + }, + "Property": "Сумма продаж, руб" + } + } + }, + { + "displayName": "Расходы МП, руб", + "queryName": "Sum(Стоимость МП.Расходы МП, руб)", + "roles": { + "Values": true + }, + "type": { + "category": null, + "underlyingType": 259 + }, + "expr": { + "Aggregation": { + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Entity": "Стоимость МП" + } + }, + "Property": "Расходы МП, руб" + } + }, + "Function": 0 + } + } + }, + { + "displayName": "Затраты РК, руб", + "format": "#,0", + "queryName": "Sum(mp реклама.Затраты РК, руб)", + "roles": { + "Values": true + }, + "type": { + "category": null, + "underlyingType": 259 + }, + "expr": { + "Aggregation": { + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Entity": "mp реклама" + } + }, + "Property": "Затраты РК, руб" + } + }, + "Function": 0 + } + } + }, + { + "displayName": "Сумма продаж + МП + РК, руб", + "format": "#,0", + "queryName": "Основной отчет.Сумма продаж + МП + РК, руб", + "roles": { + "Values": true + }, + "type": { + "category": null, + "underlyingType": 259 + }, + "expr": { + "Measure": { + "Expression": { + "SourceRef": { + "Entity": "Основной отчет" + } + }, + "Property": "Сумма продаж + МП + РК, руб" + } + } + }, + { + "displayName": "Расходы к обороту, %", + "queryName": "mp оборот.Расходы к обороту, %", + "roles": { + "Values": true + }, + "type": { + "category": null, + "underlyingType": 259 + }, + "expr": { + "Measure": { + "Expression": { + "SourceRef": { + "Entity": "mp оборот" + } + }, + "Property": "Расходы к обороту, %" + } + } + }, + { + "displayName": "Торг. надбавка, руб", + "format": "#,0", + "queryName": "Основной отчет.Торг. надбавка, руб", + "roles": { + "Values": true + }, + "type": { + "category": null, + "underlyingType": 259 + }, + "expr": { + "Measure": { + "Expression": { + "SourceRef": { + "Entity": "Основной отчет" + } + }, + "Property": "Торг. надбавка, руб" + } + } + }, + { + "displayName": "Расходы МП + РК + СПП, руб", + "format": "#,0", + "queryName": "mp оборот.Расходы МП + РК + СПП, руб", + "roles": { + "Values": true + }, + "type": { + "category": null, + "underlyingType": 259 + }, + "expr": { + "Measure": { + "Expression": { + "SourceRef": { + "Entity": "mp оборот" + } + }, + "Property": "Расходы МП + РК + СПП, руб" + } + } + }, + { + "displayName": "НДС_20 по расходам, руб", + "format": "#,0", + "queryName": "mp оборот.НДС_20 по расходам, руб", + "roles": { + "Values": true + }, + "type": { + "category": null, + "underlyingType": 259 + }, + "expr": { + "Measure": { + "Expression": { + "SourceRef": { + "Entity": "mp оборот" + } + }, + "Property": "НДС_20 по расходам, руб" + } + } + }, + { + "displayName": "Группа", + "queryName": "Группы.Группа", + "roles": { + "Rows": true + }, + "type": { + "category": null, + "underlyingType": 1 + }, + "expr": { + "Column": { + "Expression": { + "SourceRef": { + "Entity": "Группы" + } + }, + "Property": "Группа" + } + } + }, + { + "displayName": "Партнер", + "queryName": "Партнер.Партнер", + "roles": { + "Rows": true + }, + "type": { + "category": null, + "underlyingType": 1 + }, + "expr": { + "Column": { + "Expression": { + "SourceRef": { + "Entity": "Партнер" + } + }, + "Property": "Партнер" + } + } + }, + { + "displayName": "Расходы к учетной сумме, %", + "queryName": "mp оборот.Расходы к учетной сумме, %", + "roles": { + "Values": true + }, + "type": { + "category": null, + "underlyingType": 259 + }, + "expr": { + "Measure": { + "Expression": { + "SourceRef": { + "Entity": "mp оборот" + } + }, + "Property": "Расходы к учетной сумме, %" + } + } + }, + { + "displayName": "Торг. надбавка, руб, %", + "format": "#,0", + "queryName": "Основной отчет.Торг. надбавка, руб, %", + "roles": { + "Values": true + }, + "type": { + "category": null, + "underlyingType": 259 + }, + "expr": { + "Measure": { + "Expression": { + "SourceRef": { + "Entity": "Основной отчет" + } + }, + "Property": "Торг. надбавка, руб, %" + } + } + } + ], + "expansionStates": [ + { + "roles": [ + "Rows" + ], + "levels": [ + { + "queryRefs": [ + "Группы.Группа" + ], + "isCollapsed": true, + "identityKeys": [ + { + "Column": { + "Expression": { + "SourceRef": { + "Entity": "Группы" + } + }, + "Property": "Группа" + } + } + ], + "isPinned": true + }, + { + "queryRefs": [ + "Партнер.Партнер" + ], + "isCollapsed": true, + "identityKeys": [ + { + "Column": { + "Expression": { + "SourceRef": { + "Entity": "Партнер" + } + }, + "Property": "Партнер" + } + } + ], + "isPinned": true + }, + { + "queryRefs": [ + ".Календарь.Дата.Изменение.Иерархия дат.Год" + ], + "isCollapsed": true, + "identityKeys": [ + { + "Column": { + "Expression": { + "SourceRef": { + "Entity": "LocalDateTable_e0374236-67f4-4331-b4f5-c977a3082bab" + } + }, + "Property": "Год" + } + } + ], + "isPinned": true + }, + { + "queryRefs": [ + ".Календарь.Дата.Изменение.Иерархия дат.Месяц" + ], + "isCollapsed": true, + "identityKeys": [ + { + "Column": { + "Expression": { + "SourceRef": { + "Entity": "LocalDateTable_e0374236-67f4-4331-b4f5-c977a3082bab" + } + }, + "Property": "Месяц" + } + } + ], + "isPinned": true + } + ], + "root": { + "identityValues": null, + "children": [ + { + "identityValues": [ + { + "Literal": { + "Value": "'Клеевые материалы'" + } + } + ], + "children": [ + { + "identityValues": [ + { + "Literal": { + "Value": "'ИНТЕРНЕТ РЕШЕНИЯ ООО'" + } + } + ], + "isToggled": true, + "children": [ + { + "identityValues": [ + { + "Literal": { + "Value": "2025L" + } + } + ], + "isToggled": true + } + ] + } + ] + }, + { + "identityValues": [ + { + "Literal": { + "Value": "'Пленки виниловые'" + } + } + ], + "children": [ + { + "identityValues": [ + { + "Literal": { + "Value": "'ИНТЕРНЕТ РЕШЕНИЯ ООО'" + } + } + ], + "isToggled": true, + "children": [ + { + "identityValues": [ + { + "Literal": { + "Value": "2025L" + } + } + ], + "isToggled": true + } + ] + } + ] + }, + { + "identityValues": [ + { + "Literal": { + "Value": "'Пряжа'" + } + } + ], + "children": [ + { + "identityValues": [ + { + "Literal": { + "Value": "'ИНТЕРНЕТ РЕШЕНИЯ ООО'" + } + } + ], + "isToggled": true, + "children": [ + { + "identityValues": [ + { + "Literal": { + "Value": "2025L" + } + } + ], + "isToggled": true + } + ] + } + ] + }, + { + "identityValues": [ + { + "Literal": { + "Value": "'Резинка'" + } + } + ], + "children": [ + { + "identityValues": [ + { + "Literal": { + "Value": "'ИНТЕРНЕТ РЕШЕНИЯ ООО'" + } + } + ], + "isToggled": true, + "children": [ + { + "identityValues": [ + { + "Literal": { + "Value": "2025L" + } + } + ], + "isToggled": true + } + ] + }, + { + "identityValues": [ + { + "Literal": { + "Value": "'ВАЙЛДБЕРРИЗ ООО'" + } + } + ], + "isToggled": true, + "children": [ + { + "identityValues": [ + { + "Literal": { + "Value": "2025L" + } + } + ], + "isToggled": true + } + ] + } + ] + }, + { + "identityValues": [ + { + "Literal": { + "Value": "'Ткани'" + } + } + ], + "children": [ + { + "identityValues": [ + { + "Literal": { + "Value": "'ИНТЕРНЕТ РЕШЕНИЯ ООО'" + } + } + ], + "isToggled": true, + "children": [ + { + "identityValues": [ + { + "Literal": { + "Value": "2025L" + } + } + ], + "isToggled": true + } + ] + } + ] + } + ] + } + } + ] +} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/009_МП оборот и расходы/visualContainers/00000_pivotTable (19efe)/filters.json b/analytics/pbi/model/report/Report/sections/009_МП оборот и расходы/visualContainers/00000_pivotTable (19efe)/filters.json new file mode 100644 index 0000000..311c52f --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/009_МП оборот и расходы/visualContainers/00000_pivotTable (19efe)/filters.json @@ -0,0 +1,159 @@ +[ + { + "name": "f083b0373665c2fecd27", + "expression": { + "HierarchyLevel": { + "Expression": { + "Hierarchy": { + "Expression": { + "PropertyVariationSource": { + "Expression": { + "SourceRef": { + "Entity": ".Календарь" + } + }, + "Name": "Изменение", + "Property": "Дата" + } + }, + "Hierarchy": "Иерархия дат" + } + }, + "Level": "Год" + } + }, + "filter": { + "Version": 2, + "From": [ + { + "Name": "l", + "Entity": "LocalDateTable_e0374236-67f4-4331-b4f5-c977a3082bab", + "Type": 0 + } + ], + "Where": [ + { + "Condition": { + "In": { + "Expressions": [ + { + "Column": { + "Expression": { + "SourceRef": { + "Source": "l" + } + }, + "Property": "Год" + } + } + ], + "Values": [ + [ + { + "Literal": { + "Value": "2025L" + } + } + ] + ] + } + } + } + ] + }, + "type": "Categorical", + "cachedDisplayNames": [ + { + "id": { + "scopeId": { + "Comparison": { + "ComparisonKind": 0, + "Left": { + "Column": { + "Expression": { + "SourceRef": { + "Entity": "LocalDateTable_e0374236-67f4-4331-b4f5-c977a3082bab" + } + }, + "Property": "Год" + } + }, + "Right": { + "Literal": { + "Value": "2025L" + } + } + } + } + }, + "displayName": "2025" + } + ], + "howCreated": 0, + "objects": {}, + "isHiddenInViewMode": false + }, + { + "name": "cf47c7a1257b5bb31e24", + "expression": { + "Column": { + "Expression": { + "SourceRef": { + "Entity": "Партнер" + } + }, + "Property": "Партнер" + } + }, + "filter": { + "Version": 2, + "From": [ + { + "Name": "п", + "Entity": "Партнер", + "Type": 0 + } + ], + "Where": [ + { + "Condition": { + "In": { + "Expressions": [ + { + "Column": { + "Expression": { + "SourceRef": { + "Source": "п" + } + }, + "Property": "Партнер" + } + } + ], + "Values": [ + [ + { + "Literal": { + "Value": "'ВАЙЛДБЕРРИЗ ООО'" + } + } + ], + [ + { + "Literal": { + "Value": "'ИНТЕРНЕТ РЕШЕНИЯ ООО'" + } + } + ] + ] + } + } + } + ] + }, + "type": "Categorical", + "howCreated": 0, + "objects": {}, + "isHiddenInViewMode": false + } +] \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/009_МП оборот и расходы/visualContainers/00000_pivotTable (19efe)/query.json b/analytics/pbi/model/report/Report/sections/009_МП оборот и расходы/visualContainers/00000_pivotTable (19efe)/query.json new file mode 100644 index 0000000..368f8ca --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/009_МП оборот и расходы/visualContainers/00000_pivotTable (19efe)/query.json @@ -0,0 +1,368 @@ +{ + "Commands": [ + { + "SemanticQueryDataShapeCommand": { + "Query": { + "Version": 2, + "From": [ + { + "Name": "к", + "Entity": ".Календарь", + "Type": 0 + }, + { + "Name": "m", + "Entity": "mp оборот", + "Type": 0 + }, + { + "Name": "о", + "Entity": "Основной отчет", + "Type": 0 + }, + { + "Name": "с", + "Entity": "Стоимость МП", + "Type": 0 + }, + { + "Name": "m1", + "Entity": "mp реклама", + "Type": 0 + }, + { + "Name": "г", + "Entity": "Группы", + "Type": 0 + }, + { + "Name": "п", + "Entity": "Партнер", + "Type": 0 + }, + { + "Name": "l", + "Entity": "LocalDateTable_e0374236-67f4-4331-b4f5-c977a3082bab", + "Type": 0 + } + ], + "Select": [ + { + "HierarchyLevel": { + "Expression": { + "Hierarchy": { + "Expression": { + "PropertyVariationSource": { + "Expression": { + "SourceRef": { + "Source": "к" + } + }, + "Name": "Изменение", + "Property": "Дата" + } + }, + "Hierarchy": "Иерархия дат" + } + }, + "Level": "Год" + }, + "Name": ".Календарь.Дата.Изменение.Иерархия дат.Год", + "NativeReferenceName": "Дата Год" + }, + { + "HierarchyLevel": { + "Expression": { + "Hierarchy": { + "Expression": { + "PropertyVariationSource": { + "Expression": { + "SourceRef": { + "Source": "к" + } + }, + "Name": "Изменение", + "Property": "Дата" + } + }, + "Hierarchy": "Иерархия дат" + } + }, + "Level": "Месяц" + }, + "Name": ".Календарь.Дата.Изменение.Иерархия дат.Месяц", + "NativeReferenceName": "Дата Месяц" + }, + { + "Aggregation": { + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Source": "m" + } + }, + "Property": "Сумма оборот МП, руб" + } + }, + "Function": 0 + }, + "Name": "Sum(mp оборот.Сумма оборот МП, руб)", + "NativeReferenceName": "Сумма оборот МП, руб" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Сумма продаж, руб" + }, + "Name": "Основной отчет.Сумма продаж, руб", + "NativeReferenceName": "Сумма продаж, руб" + }, + { + "Aggregation": { + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Source": "с" + } + }, + "Property": "Расходы МП, руб" + } + }, + "Function": 0 + }, + "Name": "Sum(Стоимость МП.Расходы МП, руб)", + "NativeReferenceName": "Расходы МП, руб" + }, + { + "Aggregation": { + "Expression": { + "Column": { + "Expression": { + "SourceRef": { + "Source": "m1" + } + }, + "Property": "Затраты РК, руб" + } + }, + "Function": 0 + }, + "Name": "Sum(mp реклама.Затраты РК, руб)", + "NativeReferenceName": "Затраты РК, руб" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Сумма продаж + МП + РК, руб" + }, + "Name": "Основной отчет.Сумма продаж + МП + РК, руб", + "NativeReferenceName": "Сумма продаж + МП + РК, руб" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "m" + } + }, + "Property": "Расходы к обороту, %" + }, + "Name": "mp оборот.Расходы к обороту, %", + "NativeReferenceName": "Расходы к обороту, %" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Торг. надбавка, руб" + }, + "Name": "Основной отчет.Торг. надбавка, руб", + "NativeReferenceName": "Торг. надбавка, руб" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "m" + } + }, + "Property": "Расходы МП + РК + СПП, руб" + }, + "Name": "mp оборот.Расходы МП + РК + СПП, руб", + "NativeReferenceName": "Расходы МП + РК + СПП, руб" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "m" + } + }, + "Property": "НДС_20 по расходам, руб" + }, + "Name": "mp оборот.НДС_20 по расходам, руб", + "NativeReferenceName": "НДС_20 по расходам, руб" + }, + { + "Column": { + "Expression": { + "SourceRef": { + "Source": "г" + } + }, + "Property": "Группа" + }, + "Name": "Группы.Группа", + "NativeReferenceName": "Группа" + }, + { + "Column": { + "Expression": { + "SourceRef": { + "Source": "п" + } + }, + "Property": "Партнер" + }, + "Name": "Партнер.Партнер", + "NativeReferenceName": "Партнер" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "m" + } + }, + "Property": "Расходы к учетной сумме, %" + }, + "Name": "mp оборот.Расходы к учетной сумме, %", + "NativeReferenceName": "Расходы к учетной сумме, %" + }, + { + "Measure": { + "Expression": { + "SourceRef": { + "Source": "о" + } + }, + "Property": "Торг. надбавка, руб, %" + }, + "Name": "Основной отчет.Торг. надбавка, руб, %", + "NativeReferenceName": "Торг. надбавка, руб, %" + } + ], + "Where": [ + { + "Condition": { + "In": { + "Expressions": [ + { + "Column": { + "Expression": { + "SourceRef": { + "Source": "l" + } + }, + "Property": "Год" + } + } + ], + "Values": [ + [ + { + "Literal": { + "Value": "2025L" + } + } + ] + ] + } + } + }, + { + "Condition": { + "In": { + "Expressions": [ + { + "Column": { + "Expression": { + "SourceRef": { + "Source": "п" + } + }, + "Property": "Партнер" + } + } + ], + "Values": [ + [ + { + "Literal": { + "Value": "'ВАЙЛДБЕРРИЗ ООО'" + } + } + ], + [ + { + "Literal": { + "Value": "'ИНТЕРНЕТ РЕШЕНИЯ ООО'" + } + } + ] + ] + } + } + } + ] + }, + "Binding": { + "Primary": { + "Groupings": [ + { + "Projections": [ + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 13, + 14 + ], + "Subtotal": 1 + } + ] + }, + "DataReduction": { + "DataVolume": 3, + "Primary": { + "Window": { + "Count": 500 + } + } + }, + "Version": 1 + }, + "ExecutionMetricsKind": 1 + } + } + ] +} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/009_МП оборот и расходы/visualContainers/00000_pivotTable (19efe)/visualContainer.json b/analytics/pbi/model/report/Report/sections/009_МП оборот и расходы/visualContainers/00000_pivotTable (19efe)/visualContainer.json new file mode 100644 index 0000000..20e3727 --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/009_МП оборот и расходы/visualContainers/00000_pivotTable (19efe)/visualContainer.json @@ -0,0 +1,8 @@ +{ + "height": 632.17, + "id": 5853011903, + "width": 1269.68, + "x": 10.68, + "y": 0, + "z": 0 +} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/999_Обновление/config.json b/analytics/pbi/model/report/Report/sections/999_Обновление/config.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/999_Обновление/config.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/999_Обновление/filters.json b/analytics/pbi/model/report/Report/sections/999_Обновление/filters.json new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/999_Обновление/filters.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/999_Обновление/section.json b/analytics/pbi/model/report/Report/sections/999_Обновление/section.json new file mode 100644 index 0000000..6248e09 --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/999_Обновление/section.json @@ -0,0 +1,7 @@ +{ + "displayName": "Обновление", + "displayOption": 1, + "height": 720, + "name": "ReportSectionbde6a9de8b7cb9bc9375", + "width": 1280 +} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/999_Обновление/visualContainers/00000_textbox (2067c)/config.json b/analytics/pbi/model/report/Report/sections/999_Обновление/visualContainers/00000_textbox (2067c)/config.json new file mode 100644 index 0000000..b28af5d --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/999_Обновление/visualContainers/00000_textbox (2067c)/config.json @@ -0,0 +1,4028 @@ +{ + "name": "2067c8cf099df281d0a8", + "layouts": [ + { + "id": 0, + "position": { + "x": 10.174922889022294, + "y": 20.349845778044589, + "z": 0, + "width": 1270.1695406462832, + "height": 700.37385886103471, + "tabOrder": 0 + } + } + ], + "singleVisual": { + "visualType": "textbox", + "drillFilterOtherVisuals": true, + "objects": { + "general": [ + { + "properties": { + "paragraphs": [ + { + "textRuns": [ + { + "value": "ИСТОРИЯ ОБНОВЛЕНИЙ", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "26.01.2026" + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлена мера 'mp оборот' [Расходы к обороту, %] = (Оборот - Сумма продаж) / Оборот" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "14.01.2026" + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлена таблица 'mp оборот'" + } + ] + }, + { + "textRuns": [ + { + "value": "Сумма продаж по данным МП до вычета Скидки постоянного покупателя (СПП) и расходов, по установленным нами ценам." + } + ] + }, + { + "textRuns": [ + { + "value": "Другими словами, Сумма продаж + РК + СПП, по данным маркетплейсов." + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "08.12.2025" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "Таблица Номенклатура, папка Аналитика" + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлены столбцы [Оплаченный остаток], [Рентабельность остатка]" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "Таблица Номенклатура, папка Измерения" + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлены столбцы [Количество упак в кванте], [Количество упак в коробе]" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "Таблица 'Заказы все'" + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлены папки 'Заказы согласование', 'Заказы выгружены на складе'" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "27.10.2025" + } + ] + }, + { + "textRuns": [ + { + "value": "Таблица '.Календарь'." + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлен столбец [Год неделя]" + } + ] + }, + { + "textRuns": [ + { + "value": "Показывает год и номер недели с начала года. " + } + ] + }, + { + "textRuns": [ + { + "value": "Подходит для понедельного отчета." + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "Таблица Номенклатура. Папка Свойства" + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлены столбцы [Особенность], [Размер], [Форма]" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "15.10.2025" + } + ] + }, + { + "textRuns": [ + { + "value": "Партнер. " + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлены столбцы из 1с" + } + ] + }, + { + "textRuns": [ + { + "value": "Статус по динамике 2025/2024" + } + ] + }, + { + "textRuns": [ + { + "value": "Статус по обороту 2025" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "Менеджеры." + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлен столбец Вышестоящее подразделение" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "28.09.2025" + } + ] + }, + { + "textRuns": [ + { + "value": "Номенклатура, папка Маркеты" + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлен столбец [маркеты.Ozon] из 1с" + } + ] + }, + { + "textRuns": [ + { + "value": "Удален столбец [маркеты.FBS]" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "Номенклатура, папка Аналитика" + } + ] + }, + { + "textRuns": [ + { + "value": "Ср. цена продажи упак, руб x 1000" + } + ] + }, + { + "textRuns": [ + { + "value": "Ср. цена учетная упак, руб x 1000" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "(Сумма продаж + МП + РК) * 1000 / Количество проданных упак" + } + ] + }, + { + "textRuns": [ + { + "value": "(Сумма учетная) * 1000 / Количество проданных упак" + } + ] + }, + { + "textRuns": [ + { + "value": "Меры рассчитаны по данным за последние 365 дней" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "ПРАЙСлист" + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлена мера [Цена отпускная упак все в руб]" + } + ] + }, + { + "textRuns": [ + { + "value": "Отпускная цена для всех товаров (руб и вал) за упаковку в рублях" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "09.09.2025" + } + ] + }, + { + "textRuns": [ + { + "value": "Таблица Партнер. Добавлены столбцы" + } + ] + }, + { + "textRuns": [ + { + "value": "Дата первого заказа" + } + ] + }, + { + "textRuns": [ + { + "value": "Когорта" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "Таблица Номенклатура, папка Статусы. Добавлены столбцы из 1с" + } + ] + }, + { + "textRuns": [ + { + "value": "Неликвид" + } + ] + }, + { + "textRuns": [ + { + "value": "ABC статус 12м 08.25" + } + ] + }, + { + "textRuns": [ + { + "value": "ABC статус 3м 08.25" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "02.09.2025" + } + ] + }, + { + "textRuns": [ + { + "value": "Таблица План продаж менеджеров. Добавлены меры " + } + ] + }, + { + "textRuns": [ + { + "value": "План продаж менеджеров год, руб" + } + ] + }, + { + "textRuns": [ + { + "value": "% годового плана" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "Отношение Суммы продаж + РК, руб к годовому плану" + } + ] + }, + { + "textRuns": [ + { + "value": "Годовой план рассчитан как сумма планов по месяцам" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "Таблица Основной отчет. Добавлена мера" + } + ] + }, + { + "textRuns": [ + { + "value": "Продажи за год, руб" + } + ] + }, + { + "textRuns": [ + { + "value": "Показывает 'Сумму продаж + РК, руб' за выбранный год" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "Таблица Резервы. Удалены столбцы" + } + ] + }, + { + "textRuns": [ + { + "value": "В резерве со склада, шт" + } + ] + }, + { + "textRuns": [ + { + "value": "В резерве под заказ, шт" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "31.08.2025" + } + ] + }, + { + "textRuns": [ + { + "value": "Таблица Партнер. Добавлен столбец 'Статус партнера' из карточки в 1с" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "19.08.2025" + } + ] + }, + { + "textRuns": [ + { + "value": "Таблица Номенклатура. Удален столбец 'XYZ статус'" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "Таблица 'mp реклама'. Изменились названия столбцов" + } + ] + }, + { + "textRuns": [ + { + "value": "Затраты, руб/usd заменено на Затраты РК, руб/usd" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "Таблица Основной отчет. " + } + ] + }, + { + "textRuns": [ + { + "value": "Изменены названия столбцов. Новые названия:" + } + ] + }, + { + "textRuns": [ + { + "value": "Сумма продаж + МП + РК" + } + ] + }, + { + "textRuns": [ + { + "value": "Сумма продаж + РК" + } + ] + }, + { + "textRuns": [ + { + "value": "Сумма продаж" + } + ] + }, + { + "textRuns": [ + { + "value": "где Сумма продаж - это чистая сумма, после вычета МП и РК " + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлена мера:" + } + ] + }, + { + "textRuns": [ + { + "value": "Сумма продаж + РК Маркеты" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "17.08.2025" + } + ] + }, + { + "textRuns": [ + { + "value": "Таблица Номенклатура, папка Статусы. " + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлены столбцы из карточки товара в 1с:" + } + ] + }, + { + "textRuns": [ + { + "value": "XYZ статус 12м" + } + ] + }, + { + "textRuns": [ + { + "value": "XYZ статус 3м" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "Таблица Номенклатура, папка Описание" + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлены столбцы из внешних источников" + } + ] + }, + { + "textRuns": [ + { + "value": "Качество контента Magok" + } + ] + }, + { + "textRuns": [ + { + "value": "Качество контента Ozon" + } + ] + }, + { + "textRuns": [ + { + "value": "Качество контента WB" + } + ] + }, + { + "textRuns": [ + { + "value": "Качество контента WB by Ozon" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "14.08.2025" + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлены меры ДРР. Отношение рекламных расходов из таблицы 'mp реклама' к сумме продаж/заказов" + } + ] + }, + { + "textRuns": [ + { + "value": "ДРР реальный от продаж, % = ", + "textStyle": { + "fontFamily": "Consolas, Courier New, monospace", + "fontSize": "12px", + "color": "#000000" + } + }, + { + "value": "затраты, руб / Сумма плюс МП, руб (Основной отчет)", + "textStyle": { + "fontFamily": "system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Ubuntu, Helvetica Neue, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol", + "color": "#151515" + } + } + ] + }, + { + "textRuns": [ + { + "value": "ДРР заказы по рекламе, % = затраты, руб / с" + }, + { + "value": "умма заказов (mp реклама)", + "textStyle": { + "fontFamily": "system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Ubuntu, Helvetica Neue, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol", + "fontSize": "14.5px", + "color": "#151515" + } + } + ] + }, + { + "textRuns": [ + { + "value": "ДРР заказы все, % = затраты, руб / Продано, руб (mp аналитика продаж, вид загрузки = ЗаказыВС)", + "textStyle": { + "fontFamily": "system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Ubuntu, Helvetica Neue, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol", + "fontSize": "14.5px", + "color": "#151515" + } + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "В таблицу 'mp реклама' добавлен столбец Затраты, usd" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлены меры" + } + ] + }, + { + "textRuns": [ + { + "value": "Сумма продаж минус РК, usd" + } + ] + }, + { + "textRuns": [ + { + "value": "Торг. надбавка + РК, руб, %" + } + ] + }, + { + "textRuns": [ + { + "value": "Торг. надбавка + РК, usd, %" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "Изменилась формула расчета торговой надбавки в руб и usd." + } + ] + }, + { + "textRuns": [ + { + "value": "Было: Торг. надбавка = Сумма продаж - Сумма учетная - МП" + } + ] + }, + { + "textRuns": [ + { + "value": "Стало: Торг. надбавка = Сумма продаж - Сумма учетная - МП - РК" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "07.08.2025" + } + ] + }, + { + "textRuns": [ + { + "value": "Таблица Номенклатура, папка Статистика" + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлены столбцы" + } + ] + }, + { + "textRuns": [ + { + "value": "Средние месячные продажи, упак " + } + ] + }, + { + "textRuns": [ + { + "value": "СКО месячных продаж, упак" + } + ] + }, + { + "textRuns": [ + { + "value": "Средние продажи в месяц и среднее квадратичное отклонение продаж в месяц за последние 12 полных месяцев, в упаковках" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлена мера Коэффициент вариации = СКО/Средние продажи" + } + ] + }, + { + "textRuns": [ + { + "value": "Чем выше коэффициент, тем нестабильнее продажи (сезонность, акции, другие причины)" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "Таблица Основной отчет. Добавлена мера" + } + ] + }, + { + "textRuns": [ + { + "value": "Торг. надбавка минус РК, руб, %", + "textStyle": { + "fontFamily": "Consolas, Courier New, monospace", + "fontSize": "12px", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Торговая надбавка за вычетом расходов на рекламу маркетов, рассчитана от сумм в рублях, выражена в %." + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "06.08.2025" + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлена таблица Резервы." + } + ] + }, + { + "textRuns": [ + { + "value": "Количество товаров в резерве на складе и под заказ на сегодня, без динамики по дням" + } + ] + }, + { + "textRuns": [ + { + "value": "Учтены резервы, созданные после 01.01.2025, резервы до 2025 г. не учитываются." + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлены меры в Основной отчет/Остаток склад:" + } + ] + }, + { + "textRuns": [ + { + "value": "Остаток - МП - резерв, руб", + "textStyle": { + "fontFamily": "Consolas, Courier New, monospace", + "fontSize": "12px", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Остаток - МП - резерв, упак", + "textStyle": { + "fontFamily": "Consolas, Courier New, monospace", + "fontSize": "12px", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Остаток - МП - резерв, шт", + "textStyle": { + "fontFamily": "Consolas, Courier New, monospace", + "fontSize": "12px", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Свободный остаток на нашем складе на сегодня, мп и резерв без динамики по дням" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "05.08.2025" + } + ] + }, + { + "textRuns": [ + { + "value": "В таблицу Номенклатура, папка Описание добавлены ID OZON и ID WB" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "28.07.2025" + } + ] + }, + { + "textRuns": [ + { + "value": "В Основной отчет добавлена папка Магок и маркеты." + } + ] + }, + { + "textRuns": [ + { + "value": "Здесь привычные меры с фильтром." + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "Маркеты - это отбор по партнерам \"ВАЙЛДБЕРРИЗ ООО\", \"ИНТЕРНЕТ РЕШЕНИЯ ООО\"," + } + ] + }, + { + "textRuns": [ + { + "value": " \"ИНТЕРНЕТ РЕШЕНИЯ ООО юр. лица\", \"ЯНДЕКС.МАРКЕТ ООО\", \"ЯНДЕКС.МАРКЕТ ООО юр.лица\"" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "Магок - это все остальные партнеры" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "_________________________________________________________________________" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "Изменились названия мер в папке Основной отчет/Остаток склад:" + } + ] + }, + { + "textRuns": [ + { + "value": "\"Остаток - МП\" = Остаток на нашем складе" + } + ] + }, + { + "textRuns": [ + { + "value": "\"Остаток\" = Остаток на нашем складе + остаток на маркетплейсах" + } + ] + }, + { + "textRuns": [ + { + "value": "\"Остаток потенциальный\" = Остаток склад + маркетплейсы + в пути + в производстве" + } + ] + }, + { + "textRuns": [ + { + "value": "\"Остаток потенциальный + согласование\" = Остаток потенциальный + заказы поставщикам в статусе на согласовании" + } + ] + }, + { + "textRuns": [ + { + "value": "__________________________________________________________________________" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "Удалила меры в Основном отчете:" + } + ] + }, + { + "textRuns": [ + { + "value": "Продажи, шт и Продажи, упак" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "Такие меры уже есть:" + } + ] + }, + { + "textRuns": [ + { + "value": "Количество продаж, шт и Количество продаж, упак" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "23.07.2025" + } + ] + }, + { + "textRuns": [ + { + "value": "Добавила меры в таблицу Основной отчет:" + } + ] + }, + { + "textRuns": [ + { + "value": "\t" + }, + { + "value": "Учет.Списание товара, руб -- Стоимость списанного товара (недостача)", + "textStyle": { + "fontFamily": "Consolas, Courier New, monospace", + "fontSize": "12px", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "\t" + }, + { + "value": "Учет.Списание товара, usd", + "textStyle": { + "fontFamily": "Consolas, Courier New, monospace", + "fontSize": "12px", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "\tМеры Сумма учетная, руб и Сумма учетная, usd увеличены, добавлена стоимость списанного товара" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "В таблицу Закупки добавлена Статья Оприходование излишков товара. " + } + ] + }, + { + "textRuns": [ + { + "value": "Увеличивает суммарное значение в столбцах Кол-во закупка, упак и Кол-во закупка, шт" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "03.06.2025" + } + ] + }, + { + "textRuns": [ + { + "value": "Добавила столбцы в таблицу Заказы все:" + } + ] + }, + { + "textRuns": [ + { + "value": "\tПартнер" + } + ] + }, + { + "textRuns": [ + { + "value": "\tСумма всего в usd2. --Сумма всех заказов, пересчитанная по курсу USD2+2" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "Добавила меры в таблицу Заказы все:" + } + ] + }, + { + "textRuns": [ + { + "value": "\t" + }, + { + "value": "В производстве/ в пути / тех заказ сумма всего в руб", + "textStyle": { + "fontSize": "13.3333px" + } + }, + { + "value": " " + } + ] + }, + { + "textRuns": [ + { + "value": "\t" + }, + { + "value": "В производстве / в пути / тех заказ сумма всего в usd2", + "textStyle": { + "fontSize": "13.3333px" + } + } + ] + }, + { + "textRuns": [ + { + "value": "-- Сумма всех заказов, пересчитанная в руб и usd2+2" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "Добавила меру в Основной отчет:" + } + ] + }, + { + "textRuns": [ + { + "value": "\t" + }, + { + "value": "Остаток склад + в пути + произв., руб ", + "textStyle": { + "fontSize": "13.3333px" + } + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "27.05.2025" + } + ] + }, + { + "textRuns": [ + { + "value": "Добавила меры" + } + ] + }, + { + "textRuns": [ + { + "value": "\tОстаток склад + в пути + произв., шт\t" + } + ] + }, + { + "textRuns": [ + { + "value": "\tОтчет продажи шт/день" + } + ] + }, + { + "textRuns": [ + { + "value": "\tОстаток дней продаж потенциальный без МП, шт" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "26.05.2025" + } + ] + }, + { + "textRuns": [ + { + "value": "В таблицу Номенклатура добавила столбцы:" + } + ] + }, + { + "textRuns": [ + { + "value": "\tЦеновой сегмент Магок" + } + ] + }, + { + "textRuns": [ + { + "value": "\tЦеновой сегмент МП" + } + ] + }, + { + "textRuns": [ + { + "value": "\tКол-во упак в заказе Магок" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "23.05.2025" + } + ] + }, + { + "textRuns": [ + { + "value": "Изменила меры. Из учетной суммы вычла Себестоимость. Доп расходы и Доп расходы USD2+2" + } + ] + }, + { + "textRuns": [ + { + "value": "\tОсновной учет. Сумма учетная, руб (мера по старой схеме)" + } + ] + }, + { + "textRuns": [ + { + "value": "\tОсновном учет. Сумма учетная, usd " + }, + { + "value": "(мера по старой схеме)", + "textStyle": { + "fontSize": "13.3333px" + } + } + ] + }, + { + "textRuns": [ + { + "value": "\tЗакупки. Сумма закупки, руб" + } + ] + }, + { + "textRuns": [ + { + "value": "\t" + }, + { + "value": "Закупки. Сумма закупки, usd", + "textStyle": { + "fontSize": "13.3333px" + } + } + ] + }, + { + "textRuns": [ + { + "value": "\tСебестоимость. Сумма учетная " + }, + { + "value": "(мера по новой схеме)", + "textStyle": { + "fontSize": "13.3333px" + } + } + ] + }, + { + "textRuns": [ + { + "value": "\t" + }, + { + "value": "Себестоимость. Сумма учетная, usd (мера по новой схеме)", + "textStyle": { + "fontSize": "13.3333px" + } + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "Добавила меры:" + } + ] + }, + { + "textRuns": [ + { + "value": "\tОсновной учет. Учет" + }, + { + "value": ".", + "textStyle": { + "color": "#098658" + } + }, + { + "value": "Доп расходы, руб" + } + ] + }, + { + "textRuns": [ + { + "value": "\t" + }, + { + "value": "Основной учет. Учет", + "textStyle": { + "fontSize": "13.3333px" + } + }, + { + "value": ".", + "textStyle": { + "fontSize": "13.3333px", + "color": "#098658" + } + }, + { + "value": "Доп расходы, usd", + "textStyle": { + "fontSize": "13.3333px" + } + } + ] + }, + { + "textRuns": [ + { + "value": "\tЗакупки. Закуп.Доп расходы, руб" + } + ] + }, + { + "textRuns": [ + { + "value": "\t" + }, + { + "value": "Закупки. Закуп.Доп расходы, usd", + "textStyle": { + "fontSize": "13.3333px" + } + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "21.05.2025" + } + ] + }, + { + "textRuns": [ + { + "value": "Добавила меры в таблицу 'Заказы все':" + } + ] + }, + { + "textRuns": [ + { + "value": "\tОстаток склад + МП + в пути + произв. актуальные, упак" + } + ] + }, + { + "textRuns": [ + { + "value": "\tПродажи актуальных, упак" + } + ] + }, + { + "textRuns": [ + { + "value": "\tСумма учетная продаж актуальные, руб" + } + ] + }, + { + "textRuns": [ + { + "value": "\tТорг. надбавка актуальные, руб" + } + ] + }, + { + "textRuns": [ + { + "value": "Меры рассчитывают товарный остаток и суммы продаж только по тем товарам, которые есть в Заказах поставщикам." + } + ] + }, + { + "textRuns": [ + { + "value": "Необходимо для фильтрации мер по заказам поставщикам", + "textStyle": { + "fontSize": "13.3333px" + } + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "Дополнила меры в папке 'Номенклатура' Аналитика." + } + ] + }, + { + "textRuns": [ + { + "value": "Добавила условие: рассчитывать показатели только по тем товарам, которые есть в Заказе поставщику." + } + ] + }, + { + "textRuns": [ + { + "value": "Необходимо для фильтрации мер по заказам поставщикам" + } + ] + }, + { + "textRuns": [ + { + "value": "Измененные меры:" + } + ] + }, + { + "textRuns": [ + { + "value": "\tДней в продаже" + } + ] + }, + { + "textRuns": [ + { + "value": "\tДней с первой продажи" + } + ] + }, + { + "textRuns": [ + { + "value": "\tОстаток дней продаж" + } + ] + }, + { + "textRuns": [ + { + "value": "\tОстаток дней продаж потенциальный" + } + ] + }, + { + "textRuns": [ + { + "value": "\tОстаток МАКС за год, руб" + } + ] + }, + { + "textRuns": [ + { + "value": "\tОтчет ТН руб/день за 365 дней" + } + ] + }, + { + "textRuns": [ + { + "value": "\tРентабельность за год" + } + ] + }, + { + "textRuns": [ + { + "value": "\tУпущ. сумма продаж, руб\t" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "20.05.2025" + } + ] + }, + { + "textRuns": [ + { + "value": "Добавила меры Остаток конец, кг и Остаток конец, м3. " + } + ] + }, + { + "textRuns": [ + { + "value": "Вес и объем товара на складах на конец периода" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "15.05.2025" + } + ] + }, + { + "textRuns": [ + { + "value": "Добавил распределение прибыли и расходов по товарам и клиентам. " + } + ] + }, + { + "textRuns": [ + { + "value": "Добавил скидки" + } + ] + }, + { + "textRuns": [ + { + "value": "Добавил меры с потенциальными цифрами - отталкиваясь от остатка у нас и товаров в пути и производстве" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "11.05.2025" + } + ] + }, + { + "textRuns": [ + { + "value": "Добавила Объем в таблицу Заказы все, в пути, в производстве, тех. заказы" + } + ] + }, + { + "textRuns": [ + { + "value": "Добавила меры Сумма в производстве только руб/cny/try/usd2 c отбором по валюте" + } + ] + }, + { + "textRuns": [ + { + "value": "Добавила меры Сумма в пути только руб/cny/try/usd2 c отбором по валюте", + "textStyle": { + "fontSize": "13.3333px" + } + } + ] + }, + { + "textRuns": [ + { + "value": "mp аналитика продаж Установила ограничение по дате в Power Query, дата 01.01.2024 или позже (для уменьшения размера файла)", + "textStyle": { + "fontSize": "13.3333px" + } + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "07.05.2025" + } + ] + }, + { + "textRuns": [ + { + "value": "Добавил таблицу ЗАКАЗЫ Все. Сделал меры для в пути, в произв, тех заказ" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "Добавил Упущенные продажи " + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "'Номенклатура':" + } + ] + }, + { + "textRuns": [ + { + "value": "\tразбил по папкам " + } + ] + }, + { + "textRuns": [ + { + "value": "\tпапка Аналитика" + } + ] + }, + { + "textRuns": [ + { + "value": "\t[Остаток МАКС за год, руб] " + } + ] + }, + { + "textRuns": [ + { + "value": "\t[Рентабельность за год]" + } + ] + }, + { + "textRuns": [ + { + "value": "\t[Ср. уч. цена]" + } + ] + }, + { + "textRuns": [ + { + "value": "\tОстаток дней продаж потенциальный - Остаток склад + мп + в пути + в производстве / продажи упак в день" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "mp_ostatki - в базовой вью добавил отбор только по последней дате. Получили остатки на текущий день.", + "textStyle": { + "fontSize": "13.3333px" + } + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "'Основной отчет'[продажи упак]" + } + ] + }, + { + "textRuns": [ + { + "value": "'Основной отчет'[продажи шт]", + "textStyle": { + "fontSize": "13.3333px" + } + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "'Основной отчет'[Остаток склад + МП] - реалльный остаток", + "textStyle": { + "fontSize": "13.3333px" + } + } + ] + }, + { + "textRuns": [ + { + "value": "'Основной отчет'[Остаток склад + МП + в пути + в произв] - потенциальный остаток", + "textStyle": { + "fontSize": "13.3333px" + } + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "'Основной отчет'", + "textStyle": { + "fontSize": "13.3333px" + } + }, + { + "value": "Торг. надбавка - 70р за упак, руб" + }, + { + "value": "]", + "textStyle": { + "fontSize": "13.3333px" + } + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "08.04.2025" + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлена таблица 'Заказы тех'. Заказы поставщикам со статусом \"Тех. заказ\" (Несогласованный)" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "07.04.2024" + } + ] + }, + { + "textRuns": [ + { + "value": "АБС план" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "03.04.2025" + } + ] + }, + { + "textRuns": [ + { + "value": "Цена учетная по закупкам, руб" + } + ] + }, + { + "textRuns": [ + { + "value": "Цена учетная последняя известная, руб" + } + ] + }, + { + "textRuns": [ + { + "value": "Остаток конец по средней закупке, руб" + } + ] + }, + { + "textRuns": [ + { + "value": "Остаток конец по последней закупке, руб" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "01.04.2025" + } + ] + }, + { + "textRuns": [ + { + "value": "YTD Сумма продаж с начала года, шт" + } + ] + }, + { + "textRuns": [ + { + "value": "Аппроксимация год, шт" + } + ] + }, + { + "textRuns": [ + { + "value": "Оборачиваемость, шт" + } + ] + }, + { + "textRuns": [ + { + "value": "Остаток средний, шт" + } + ] + }, + { + "textRuns": [ + { + "value": "План закупки ост" + }, + { + "value": ".", + "textStyle": { + "color": "#098658" + } + }, + { + "value": " период, шт" + } + ] + }, + { + "textRuns": [ + { + "value": "План закупки ост" + }, + { + "value": ".", + "textStyle": { + "color": "#098658" + } + }, + { + "value": " период, руб" + } + ] + }, + { + "textRuns": [ + { + "value": "План закупки ост" + }, + { + "value": ".", + "textStyle": { + "color": "#098658" + } + }, + { + "value": " период, usd" + } + ] + }, + { + "textRuns": [ + { + "value": "Курс TODAY-1, usd2" + } + ] + }, + { + "textRuns": [ + { + "value": "Закупки.Статья" + } + ] + }, + { + "textRuns": [ + { + "value": "Цена учетная по закупкам, руб" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "25.03.2025" + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлены меры в Основной отчет, папка MAA, MAT, MTD, PY, YTD:" + } + ] + }, + { + "textRuns": [ + { + "value": "PP Продажи за прошлый период, руб/шт/упак" + } + ] + }, + { + "textRuns": [ + { + "value": "PP Прирост к прошлому периоду, руб/шт/упак" + } + ] + }, + { + "textRuns": [ + { + "value": "PP Прирост к прошлому периоду, руб/шт/упак, %" + } + ] + }, + { + "textRuns": [ + { + "value": "Показывают продажи за период той же продолжительности, что и выбранный, но заканчивающийся перед его началом." + } + ] + }, + { + "textRuns": [ + { + "value": "А также прирост (абсолютн. и %) в текущем периоде к прошлому периоду." + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "03.03.2025" + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлена мера 'Основной отчет'[Артикулы продающие]. Выводит количество проданных уникальных артикулов за выбранный период." + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлена мера 'Основной отчет'[Количество реализаций] Выводит количество уникальных номеров реализации за выбранный период." + } + ] + }, + { + "textRuns": [ + { + "value": "Удален столбец 'Номенклатура'[Тип плетения] Сидорова М.А." + } + ] + }, + { + "textRuns": [ + { + "value": "Удален столбец 'Номенклатура'[Тип шнура] Сидорова М.А.", + "textStyle": { + "fontSize": "13.3333px" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Удалена таблица 'Сохраненные настройки 1С для PowerBI' Сидорова М.А.", + "textStyle": { + "fontSize": "13.3333px" + } + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "28.02.2025", + "textStyle": { + "fontSize": "12pt" + } + } + ] + }, + { + "textRuns": [ + { + "value": "ПРАЙСлист. Добавлены меры:", + "textStyle": { + "fontSize": "12pt" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Учетная цена (вал),", + "textStyle": { + "fontSize": "12pt" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Учетная цена (руб),", + "textStyle": { + "fontSize": "12pt" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Цена инвойс (вал),", + "textStyle": { + "fontSize": "12pt" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Цена отпускная (руб),", + "textStyle": { + "fontSize": "12pt" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Цена отпускная вал в раб", + "textStyle": { + "fontSize": "12pt" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Выводит последнюю известную цену на дату, указанную в визуализации ", + "textStyle": { + "fontSize": "12pt" + } + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "17.04.2024", + "textStyle": { + "fontSize": "12pt" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Удалена мера Когорта = ", + "textStyle": { + "fontSize": "12pt" + } + }, + { + "value": "FORMAT", + "textStyle": { + "fontSize": "12pt", + "color": "#3165bb" + } + }, + { + "value": "(", + "textStyle": { + "fontSize": "12pt" + } + }, + { + "value": "'Партнер'", + "textStyle": { + "fontSize": "12pt", + "color": "#001080" + } + }, + { + "value": "[Дата первого заказа]", + "textStyle": { + "fontSize": "12pt", + "color": "#5f5f5f" + } + }, + { + "value": ", ", + "textStyle": { + "fontSize": "12pt" + } + }, + { + "value": "\"YYYY-MM\"", + "textStyle": { + "fontSize": "12pt", + "color": "#a31515" + } + }, + { + "value": ")", + "textStyle": { + "fontSize": "12pt" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Причина: ошибка, нет столбца [Дата первого заказа]", + "textStyle": { + "fontSize": "12pt" + } + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "25.03.2024", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлена мера 'Основной отчет'[Учет.Доставка, usd]", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлена мера 'Основной отчет'[Учет.Закупка ПТУ, usd]", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлена мера 'Основной отчет'[Учет.НДС, usd]", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлена мера 'Основной отчет'[Учет.Сборка, usd]", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлена мера 'Основной отчет'[Учет.Таможня, usd]", + "textStyle": { + "fontSize": "16px", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлен вычисляемый столбец 'pbi Себестоимость'[Доставка, usd]", + "textStyle": { + "fontSize": "16px", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлен вычисляемый столбец 'pbi Себестоимость'[НДС, usd]", + "textStyle": { + "fontSize": "16px", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлен вычисляемый столбец 'pbi Себестоимость'[Сборка, usd]", + "textStyle": { + "fontSize": "16px", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлен вычисляемый столбец 'pbi Себестоимость'[Таможня, usd]", + "textStyle": { + "fontSize": "16px", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "29.12.2023", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлен столбец 'Партнер'[Дата последнего звонка] из Bitrix24", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Подключен новый источник Bitrix24", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлен столбец 'Партнер'[partner_link]", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "28.12.2023", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлена мера 'Прайс'[Учетная цена прайс, вал]", + "textStyle": { + "fontSize": "16px", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлена мера 'Прайс'[Учетная цена прайс, руб]", + "textStyle": { + "fontSize": "16px", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлена мера 'Основной отчет'[Средний чек]", + "textStyle": { + "fontSize": "16px", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлена мера 'Основной отчет'[Средний чек, вал]", + "textStyle": { + "fontSize": "16px", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Поле 'Номенклатура'[Наполнитель] переименовано в 'Номенклатура'[XYZ статус]", + "textStyle": { + "fontSize": "16px", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлена таблица 'pbi Внешние остатки'", + "textStyle": { + "fontSize": "16px", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлена таблица 'pbi Внешние продажи'", + "textStyle": { + "fontSize": "16px", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "27.12.2023", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлена мера 'Закупки регистр'[Сборка]", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлена мера 'Закупки регистр'[Таможня]", + "textStyle": { + "fontSize": "16px", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлена мера 'Закупки регистр'[Сумма, usd]", + "textStyle": { + "fontSize": "16px", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлена мера 'Основной отчет'[Сумма скидки, руб]", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлена мера 'Основной отчет'[% Скидки, руб]", + "textStyle": { + "fontSize": "16px", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлена мера 'Прайс'[Цена Инвойс, вал]", + "textStyle": { + "fontSize": "16px", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлена мера 'Прайс'[Цена отпускная, руб]", + "textStyle": { + "fontSize": "16px", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлена мера 'Прайс'[Цена отпускная, вал в руб]", + "textStyle": { + "fontSize": "16px", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "26.12.2023", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлен столбец 'Номенклатура'[Да/Нет Собственное пр-во]", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "25.12.2023", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлена таблица 'Прайс'", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "21.12.2023", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлен столбец 'Партнер'[Сегмент]", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Удалена таблица 'Партнеры.Сегменты'", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Обновлена таблица 'Стоимость МП'. Заполнены организации и партнеры в пустых полях. Добавлен столбец 'ПартнерКод'", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлена таблица-справочник 'Организация'. Добавлены связи с таблицами фактов.", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Скрыты поля 'artic_id', 'partner_id', 'Период', 'Организация' в таблицах фактов: 'pbi Себестоимость', 'Закупки регистр', 'Стоимость МП'", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "20.12.2023", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлена мера 'Основной отчет'[Сумма продаж, руб] = Сумма, руб - Расходы МП, руб", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлена мера 'Основной отчет'[Сумма продаж, usd] = Сумма, usd - Расходы МП, usd", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Удалены меры 'Стоимость МП': [Продажи - расходы МП, руб], [Продажи - расходы МП, usd], ", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "[ТН - расходы МП, руб], [ТН - расходы МП, usd], [% ТН - расходы МП, руб], [% ТН - расходы МП, usd]", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Удален вычисляемый столбец 'pbi Себестоимость'[Закупка учетная]", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Удален вычисляемый столбец 'pbi Себестоимость'[Закупка учетная, usd2]", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Удалена таблица 'Партнеры.Контрагенты', не используется (согласовано с Коваленко И.)", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлен столбец 'pbi ostatki'[Учетная цена по себест]", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлен столбец 'pbi ostatki'[Учетная цена по себест, usd]", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлен вычисляемый столбец 'pbi ostatki'[Учетная стоимость, usd]", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлена мера 'Основной отчет'[Остаток Начало, usd]", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлена мера 'Основной отчет'[Остаток Конец, usd]", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлена мера 'Основной отчет'[Оборачиваемость, usd]", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлена мера 'Основной отчет'[Рентаб. активов, usd]", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Меры Основного отчета приведены к формату Целое число, Разделение разрядов тысяч", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "19.12.2023", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлен столбец 'Партнеры'[ДатаРегистрации]", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлен столбец 'Партнеры'[bitrix_id]", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлена мера 'Заказано_в_производстве'[Сумма в производстве, usd2]", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлена мера 'Заказано_в_пути'[Сумма в пути, usd2]", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлена мера 'План продаж менеджеров'[Осталось до плана]", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Удалена таблица 'Сегменты номенклатуры', не используется (согласовано с Дивеевой И.)", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Удалена таблица 'Google Analytics', не используется (согласовано с Дивеевой И.)", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "17.12.2023", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлен вычисляемый столбец 'pbi Себестоимость'[Закупка учетная]", + "textStyle": { + "fontSize": "16px", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлен вычисляемый столбец 'pbi Себестоимость'[Закупка учетная, usd2]", + "textStyle": { + "fontSize": "16px", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлен вычисляемый столбец 'pbi Себестоимость'[Сумма продаж, usd]", + "textStyle": { + "fontSize": "16px", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "В таблице 'pbi Себестоимость' значения в рублях округлены до 5 знаков после запятой, значения в usd округлены до 7 знаков после запятой ", + "textStyle": { + "fontSize": "16px", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Удалена мера 'Основной отчет'[Учет.ЕАЭС, руб]", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "15.12.2023", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлена новая таблица 'pbi Себестоимость' из view [mag_pbi].[pbi].[Себестоимость+СебестоимостьПродаж]", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлен вычисляемый столбец 'pbi Себестоимость'[Цена продажи]", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Удалена таблица 'pbi Себестоимость' из [mag_pbi].[pbi].[Себестоимость]", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Удалена мера 'Группы'[План продаж 2020, руб]", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Удалена мера 'Менеджеры 1С'[Кол. заказов с обратной связью]", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Удалена мера 'Менеджеры 1С'[Рейтинг]", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + }, + { + "textRuns": [ + { + "value": "14.12.2023", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлена мера 'Закупки регистр'[Доставка]", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлена мера 'Закупки регистр'[НДС]", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "Добавлено поле 'Номенклатура'[Номер цвета]", + "textStyle": { + "fontSize": "12pt", + "color": "#000000" + } + } + ] + }, + { + "textRuns": [ + { + "value": "" + } + ] + } + ] + } + } + ] + } + } +} \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/999_Обновление/visualContainers/00000_textbox (2067c)/filters.json b/analytics/pbi/model/report/Report/sections/999_Обновление/visualContainers/00000_textbox (2067c)/filters.json new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/999_Обновление/visualContainers/00000_textbox (2067c)/filters.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/analytics/pbi/model/report/Report/sections/999_Обновление/visualContainers/00000_textbox (2067c)/visualContainer.json b/analytics/pbi/model/report/Report/sections/999_Обновление/visualContainers/00000_textbox (2067c)/visualContainer.json new file mode 100644 index 0000000..9d58022 --- /dev/null +++ b/analytics/pbi/model/report/Report/sections/999_Обновление/visualContainers/00000_textbox (2067c)/visualContainer.json @@ -0,0 +1,8 @@ +{ + "height": 700.37, + "id": 5853011912, + "width": 1270.17, + "x": 10.17, + "y": 20.35, + "z": 0 +} \ No newline at end of file diff --git a/analytics/pbi/model/report/ReportMetadata.json b/analytics/pbi/model/report/ReportMetadata.json new file mode 100644 index 0000000..abcdf8a --- /dev/null +++ b/analytics/pbi/model/report/ReportMetadata.json @@ -0,0 +1,6 @@ +{ + "Version": 5, + "AutoCreatedRelationships": [], + "CreatedFrom": "Cloud", + "CreatedFromRelease": "2026.01" +} \ No newline at end of file diff --git a/analytics/pbi/model/report/ReportSettings.json b/analytics/pbi/model/report/ReportSettings.json new file mode 100644 index 0000000..3b2c5e7 --- /dev/null +++ b/analytics/pbi/model/report/ReportSettings.json @@ -0,0 +1,11 @@ +{ + "Version": 1, + "ReportSettings": { + "UserConsentsToCompositeModels": true + }, + "QueriesSettings": { + "TypeDetectionEnabled": true, + "RelationshipImportEnabled": true, + "Version": "2.73.5586.802" + } +} \ No newline at end of file diff --git a/analytics/pbi/model/report/StaticResources/SharedResources/BaseThemes/CY20SU09.json b/analytics/pbi/model/report/StaticResources/SharedResources/BaseThemes/CY20SU09.json new file mode 100644 index 0000000..d1ff078 --- /dev/null +++ b/analytics/pbi/model/report/StaticResources/SharedResources/BaseThemes/CY20SU09.json @@ -0,0 +1,391 @@ +{ + "name": "CY20SU09", + "dataColors": [ + "#118DFF", + "#12239E", + "#E66C37", + "#6B007B", + "#E044A7", + "#744EC2", + "#D9B300", + "#D64550", + "#197278", + "#1AAB40", + "#15C6F4", + "#4092FF", + "#FFA058", + "#BE5DC9", + "#F472D0", + "#B5A1FF", + "#C4A200", + "#FF8080", + "#00DBBC", + "#5BD667", + "#0091D5", + "#4668C5", + "#FF6300", + "#99008A", + "#EC008C", + "#533285", + "#99700A", + "#FF4141", + "#1F9A85", + "#25891C", + "#0057A2", + "#002050", + "#C94F0F", + "#450F54", + "#B60064", + "#34124F", + "#6A5A29", + "#1AAB40", + "#BA141A", + "#0C3D37", + "#0B511F" + ], + "foreground": "#252423", + "foregroundNeutralSecondary": "#605E5C", + "foregroundNeutralTertiary": "#B3B0AD", + "background": "#FFFFFF", + "backgroundLight": "#F3F2F1", + "backgroundNeutral": "#C8C6C4", + "tableAccent": "#118DFF", + "good": "#1AAB40", + "neutral": "#D9B300", + "bad": "#D64554", + "maximum": "#118DFF", + "center": "#D9B300", + "minimum": "#DEEFFF", + "null": "#FF7F48", + "hyperlink": "#0078d4", + "visitedHyperlink": "#0078d4", + "textClasses": { + "callout": { + "fontSize": 45, + "fontFace": "DIN", + "color": "#252423" + }, + "title": { + "fontSize": 12, + "fontFace": "DIN", + "color": "#252423" + }, + "header": { + "fontSize": 12, + "fontFace": "Segoe UI Semibold", + "color": "#252423" + }, + "label": { + "fontSize": 10, + "fontFace": "Segoe UI", + "color": "#252423" + } + }, + "visualStyles": { + "*": { + "*": { + "*": [{ + "wordWrap": true + }], + "line":[{ + "transparency": 0 + }], + "outline":[{ + "transparency": 0 + }], + "plotArea":[{ + "transparency": 0 + }], + "categoryAxis":[{ + "showAxisTitle": true, + "gridlineStyle": "dotted" + }], + "valueAxis":[{ + "showAxisTitle": true, + "gridlineStyle": "dotted" + }], + "title": [{ + "titleWrap": true + }], + "lineStyles":[{ + "strokeWidth":3 + }], + "wordWrap": [{ + "show": true + }], + "background": [{ + "show": true, + "transparency": 0 + }], + "outspacePane": [{ + "backgroundColor": {"solid": {"color": "#ffffff"}}, + "foregroundColor": {"solid": {"color": "#252423"}}, + "transparency": 0, + "border": true, + "borderColor": {"solid": {"color": "#B3B0AD"}} + }], + "filterCard": [ + { + "$id": "Applied", + "transparency": 0, + "foregroundColor": {"solid": {"color": "#252423"}}, + "border": true + }, + { + "$id": "Available", + "transparency": 0, + "foregroundColor": {"solid": {"color": "#252423"}}, + "border": true + }] + } + }, + "scatterChart":{ + "*":{ + "bubbles":[{ + "bubbleSize":-10 + }], + "general": [{ + "responsive": true + }], + "fillPoint": [{ + "show": true + }], + "legend": [{ + "showGradientLegend": true + }] + } + }, + "lineChart": { + "*": { + "general": [{ + "responsive": true + }] + } + }, + "map":{ + "*":{ + "bubbles":[{ + "bubbleSize":-10 + }] + } + }, + "pieChart":{ + "*":{ + "legend":[{ + "show":true, + "position":"RightCenter" + }], + "labels":[{ + "labelStyle": "Data value, percent of total" + }] + } + }, + "donutChart":{ + "*":{ + "legend":[{ + "show":true, + "position":"RightCenter" + }], + "labels":[{ + "labelStyle": "Data value, percent of total" + }] + } + }, + "pivotTable": { + "*": { + "*": [{ + "showExpandCollapseButtons": true + }] + } + }, + "multiRowCard": { + "*": { + "card": [{ + "outlineWeight": 2, + "barShow": true, + "barWeight": 2 + }] + } + }, + "kpi": { + "*": { + "trendline": [{ + "transparency": 20 + }] + } + }, + "slicer": { + "*": { + "general": [{ + "responsive": true + }] + } + }, + "waterfallChart": { + "*": { + "general": [{ + "responsive": true + }] + } + }, + "columnChart": { + "*": { + "general": [{ + "responsive": true + }], + "legend": [{ + "showGradientLegend": true + }] + } + }, + "clusteredColumnChart": { + "*": { + "general": [{ + "responsive": true + }], + "legend": [{ + "showGradientLegend": true + }] + } + }, + "hundredPercentStackedColumnChart": { + "*": { + "general": [{ + "responsive": true + }], + "legend": [{ + "showGradientLegend": true + }] + } + }, + "barChart": { + "*": { + "general": [{ + "responsive": true + }], + "legend": [{ + "showGradientLegend": true + }] + } + }, + "clusteredBarChart": { + "*": { + "general": [{ + "responsive": true + }], + "legend": [{ + "showGradientLegend": true + }] + } + }, + "hundredPercentStackedBarChart": { + "*": { + "general": [{ + "responsive": true + }], + "legend": [{ + "showGradientLegend": true + }] + } + }, + "areaChart": { + "*": { + "general": [{ + "responsive": true + }] + } + }, + "stackedAreaChart": { + "*": { + "general": [{ + "responsive": true + }] + } + }, + "lineClusteredColumnComboChart": { + "*": { + "general": [{ + "responsive": true + }] + } + }, + "lineStackedColumnComboChart": { + "*": { + "general": [{ + "responsive": true + }] + } + }, + "ribbonChart": { + "*": { + "general": [{ + "responsive": true + }] + } + }, + "group": { + "*": { + "background": [{ + "show": false + }] + } + }, + "basicShape": { + "*": { + "background": [{ + "show": false + }], + "general": [{ + "keepLayerOrder": true + }], + "visualHeader": [{ + "show": false + }] + } + }, + "image": { + "*": { + "background": [{ + "show": false + }], + "general": [{ + "keepLayerOrder": true + }], + "visualHeader": [{ + "show": false + }] + } + }, + "actionButton": { + "*": { + "visualHeader": [{ + "show": false + }] + } + }, + "textbox": { + "*": { + "general": [{ + "keepLayerOrder": true + }], + "visualHeader": [{ + "show": false + }] + } + }, + "page": { + "*": { + "outspace": [ + { + "color": { "solid": { "color": "#FFFFFF" } } + } + ], + "background": [ + { + "transparency": 100 + } + ] + } + } + } +} \ No newline at end of file diff --git a/analytics/pbi/model/report/Version.txt b/analytics/pbi/model/report/Version.txt new file mode 100644 index 0000000..9244395 --- /dev/null +++ b/analytics/pbi/model/report/Version.txt @@ -0,0 +1 @@ +1.31 \ No newline at end of file diff --git a/analytics/python skript/Calculationofthecostofproductionreferences.bat b/analytics/python skript/Calculationofthecostofproductionreferences.bat new file mode 100644 index 0000000..47687bd --- /dev/null +++ b/analytics/python skript/Calculationofthecostofproductionreferences.bat @@ -0,0 +1,2 @@ +"C:\Users\administrator\AppData\Local\Programs\Python\Python312\python.exe" "F:\python skript\Calculationofthecostofproductionreferences.py" +exit \ No newline at end of file diff --git a/analytics/python skript/Calculationofthecostofproductionreferences.py b/analytics/python skript/Calculationofthecostofproductionreferences.py new file mode 100644 index 0000000..a6bce3a --- /dev/null +++ b/analytics/python skript/Calculationofthecostofproductionreferences.py @@ -0,0 +1,950 @@ +import decimal +import time +import numpy as np +import pyodbc + + +def sql_connect(): + server = '192.168.35.207' + database = 'mag_pbi' + username = 'goglev' + password = 'BOMoGbUZ1p' + connection_string = f'DRIVER={{ODBC Driver 17 for SQL Server}};SERVER={server};DATABASE={database};UID={username};PWD={password}' + + conn = pyodbc.connect(connection_string) + print("successfully connected...") + print("#" * 20) + return conn + + +def get_totals(conn, counter, group): + sql_query = """ + SELECT --TOP (1000) + id, -- 0 + artic_id, -- 1 + COALESCE([Количество], 0) AS [Количество], -- 2 + COALESCE([ЗатратыМП], 0) AS ЗатратыМП, -- 3 + COALESCE([Закупка], 0) AS [Закупка], -- 4 + COALESCE([Доставка], 0) AS [Доставка], -- 5 + COALESCE([НДС], 0) AS [НДС], -- 6 + COALESCE([Производство], 0) AS [Производство], -- 7 + COALESCE([Таможня], 0) AS [Таможня], -- 8 + [Курс usd2] AS [Курс usd2], -- 9 + [Период] AS [Период], -- 10 + [Валюта документа] AS [Валюта документа], -- 11 + [Вид операции] AS [Вид операции], -- 12 + [Статья] AS [Статья], -- 13 + COALESCE([ЗатратыСкладХранение], 0) AS [ЗатратыСкладХранение], -- 14 + COALESCE([Приемка], 0) AS [Приемка], -- 15 + COALESCE([АтсМаркировка], 0) AS [АтсМаркировка], -- 16 + COALESCE([СборкаЗаказа], 0) AS [СборкаЗаказа], -- 17 + COALESCE([Закупка, usd2], 0) AS [Закупка, usd2], -- 18 + COALESCE([Доставка USD2+2], 0) AS [Доставка USD2+2], -- 19 + COALESCE([НДС USD2+2], 0) AS [НДС USD2+2], -- 20 + COALESCE([Таможня USD2+2], 0) AS [Таможня USD2+2], -- 21 + COALESCE([Производство USD2+2], 0) AS [Производство USD2+2], -- 22 + COALESCE([Доп расходы], 0) AS [Доп расходы], -- 23 + COALESCE([Доп расходы USD2+2], 0) AS [Доп расходы USD2+2] -- 24 + FROM + ( + SELECT + id, + artic_id, + COALESCE([Количество], 0) AS [Количество], + [ЗатратыМП], + COALESCE([Закупка], 0) AS [Закупка], + COALESCE([Доставка], 0) AS [Доставка], + [НДС], + COALESCE([Производство], 0) AS [Производство], + COALESCE([Таможня], 0) AS [Таможня], + [Курс usd2], + [Период], + [Валюта документа], + [Вид операции], + [Статья], + [ЗатратыСкладХранение], + [Приемка], + [АтсМаркировка], + [СборкаЗаказа], + COALESCE([Закупка, usd2], 0) AS [Закупка, usd2], + COALESCE([Доставка USD2+2], 0) AS [Доставка USD2+2], + COALESCE([НДС USD2+2], 0) AS [НДС USD2+2], + COALESCE([Таможня USD2+2], 0) AS [Таможня USD2+2], + COALESCE([Производство USD2+2], 0) AS [Производство USD2+2], + COALESCE([Доп расходы], 0) AS [Доп расходы], + COALESCE([Доп расходы USD2+2], 0) AS [Доп расходы USD2+2] + + FROM [mag_pbi].[pbiProd].[СебестоимостьОт2022] + WHERE + 1=1 + --and [artic_id] = 'c4bbfb4b-cf25-11ef-998c-b49691d57efd' + and [artic_id] IN (SELECT + [artic_id] + FROM [mag_pbi].[pbiProd].[GroupsOfNomenclature] + where """ + group + """ = """ + str(counter) + """) + and [Период] >= '2022' + + + UNION ALL + + SELECT + id, + artic_id, + COALESCE([Количество], 0), + [ЗатратыМП], + COALESCE([Закупка], 0), + COALESCE([Доставка], 0), + [НДС], + COALESCE([Сборка], 0), + COALESCE([Таможня], 0), + 0, + '2021', + NULL, + 'Приход', + 'Ввод остатков до 22', + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + FROM [mag_pbi].[pbiProd].[СебестоимостьИтогиДо2022] + where + 1 = 1 + --and [artic_id] = 'c4bbfb4b-cf25-11ef-998c-b49691d57efd' + and [artic_id] IN (SELECT + [artic_id] + FROM [mag_pbi].[pbiProd].[GroupsOfNomenclature] + where """ + group + """ = """ + str(counter) + """) + ) AS tabMain + --WHERE 1=1 + + ORDER BY + [artic_id], [Период] ASC, [Закупка] DESC; + """ + cursor = conn.cursor() + cursor.execute(sql_query) + pbi_totals = cursor.fetchall() + print(time.ctime(), ' Записей к обработке: ', len(pbi_totals)) + return pbi_totals + + + +def get_totalsManufacture(conn, manufactureLevel, start_range, end_range): + sql_query = """ + SELECT --TOP (1000) + id, -- 0 + artic_id, -- 1 + COALESCE([Количество], 0) AS [Количество], -- 2 + COALESCE([ЗатратыМП], 0) AS ЗатратыМП, -- 3 + COALESCE([Закупка], 0) AS [Закупка], -- 4 + COALESCE([Доставка], 0) AS [Доставка], -- 5 + COALESCE([НДС], 0) AS [НДС], -- 6 + COALESCE([Производство], 0) AS [Производство], -- 7 + COALESCE([Таможня], 0) AS [Таможня], -- 8 + [Курс usd2] AS [Курс usd2], -- 9 + [Период] AS [Период], -- 10 + [Валюта документа] AS [Валюта документа], -- 11 + [Вид операции] AS [Вид операции], -- 12 + [Статья] AS [Статья], -- 13 + COALESCE([ЗатратыСкладХранение], 0) AS [ЗатратыСкладХранение], -- 14 + COALESCE([Приемка], 0) AS [Приемка], -- 15 + COALESCE([АтсМаркировка], 0) AS [АтсМаркировка], -- 16 + COALESCE([СборкаЗаказа], 0) AS [СборкаЗаказа], -- 17 + COALESCE([Закупка, usd2], 0) AS [Закупка, usd2], -- 18 + COALESCE([Доставка USD2+2], 0) AS [Доставка USD2+2], -- 19 + COALESCE([НДС USD2+2], 0) AS [НДС USD2+2], -- 20 + COALESCE([Таможня USD2+2], 0) AS [Таможня USD2+2], -- 21 + COALESCE([Производство USD2+2], 0) AS [Производство USD2+2], -- 22 + COALESCE([Доп расходы], 0) AS [Доп расходы], -- 23 + COALESCE([Доп расходы USD2+2], 0) AS [Доп расходы USD2+2] -- 24 + FROM + ( + SELECT + id, + artic_id, + COALESCE([Количество], 0) AS [Количество], + [ЗатратыМП], + COALESCE([Закупка], 0) AS [Закупка], + COALESCE([Доставка], 0) AS [Доставка], + [НДС], + COALESCE([Производство], 0) AS [Производство], + COALESCE([Таможня], 0) AS [Таможня], + [Курс usd2], + [Период], + [Валюта документа], + [Вид операции], + [Статья], + [ЗатратыСкладХранение], + [Приемка], + [АтсМаркировка], + [СборкаЗаказа], + COALESCE([Закупка, usd2], 0) AS [Закупка, usd2], + COALESCE([Доставка USD2+2], 0) AS [Доставка USD2+2], + COALESCE([НДС USD2+2], 0) AS [НДС USD2+2], + COALESCE([Таможня USD2+2], 0) AS [Таможня USD2+2], + COALESCE([Производство USD2+2], 0) AS [Производство USD2+2], + COALESCE([Доп расходы], 0) AS [Доп расходы], + COALESCE([Доп расходы USD2+2], 0) AS [Доп расходы USD2+2] + FROM [mag_pbi].[pbiProd].[СебестоимостьОт2022] + WHERE + 1=1 + --and [artic_id] = '24d0c24b-3a60-11e9-ae9c-b496910dcfd6' + and [1c_id] IN (SELECT + [1c_id] + FROM [mag_pbi].[pbiProd].[НоменклатураВПроизводствеПоУровням] + where [УровеньПроизводства] = """ + str(manufactureLevel) + """ + and [RowNum] BETWEEN """ + str(start_range) + """ AND """ + str(end_range) + """ + --and [1c_id] = 0x9981B49691D57EFD11EDDE7DA97A5E64 + ) + and [Период] >= '2022' + + + UNION ALL + + SELECT + id, + artic_id, + COALESCE([Количество], 0), + [ЗатратыМП], + COALESCE([Закупка], 0), + COALESCE([Доставка], 0), + [НДС], + COALESCE([Сборка], 0), + COALESCE([Таможня], 0), + 0, + '2021', + NULL, + 'Приход', + 'Ввод остатков до 22', + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + FROM [mag_pbi].[pbiProd].[СебестоимостьИтогиДо2022] + where + 1 = 1 + --and [artic_id] = '24d0c24b-3a60-11e9-ae9c-b496910dcfd6' + and [1c_id] IN (SELECT + [1c_id] + FROM [mag_pbi].[pbiProd].[НоменклатураВПроизводствеПоУровням] + where [УровеньПроизводства] = """ + str(manufactureLevel) + """ + and [RowNum] BETWEEN """ + str(start_range) + """ AND """ + str(end_range) + """ + --and [1c_id] = 0x9981B49691D57EFD11EDDE7DA97A5E64 + ) + ) AS tabMain + --WHERE 1=1 + + ORDER BY + [artic_id], [Период] ASC, [Закупка] DESC; + """ + cursor = conn.cursor() + cursor.execute(sql_query) + pbi_totals = cursor.fetchall() + print(time.ctime(), ' Записей к обработке: ', len(pbi_totals)) + return pbi_totals + +def find_sumof_total(sebes_sales, date, current_sales_id, current_params, last_string_values): + quantity = current_params['quantity'] + sumZakupka = current_params['sumZakupka'] + sumZakupkaUSD2 = current_params['sumZakupkaUSD2'] + sum_dostavka = current_params['sum_dostavka'] + sum_dostavkaUSD2 = current_params['sum_dostavkaUSD2'] + sum_NAT = current_params['sum_NAT'] + sum_NATUSD2 = current_params['sum_NATUSD2'] + sum_production = current_params['sum_production'] + sum_productionUSD2 = current_params['sum_productionUSD2'] + sum_zatratiMP = current_params['sum_zatratiMP'] + sum_custom = current_params['sum_custom'] + sum_customUSD2 = current_params['sum_customUSD2'] + sum_skladHranenie = current_params['sum_skladHranenie'] + sum_Priemka = current_params['sum_Priemka'] + sum_AtsMarkirovka = current_params['sum_AtsMarkirovka'] + sum_SborkaZakaza = current_params['sum_SborkaZakaza'] + sum_DopRashod = current_params['sum_DopRashod'] + sum_DopRashodUSD2 = current_params['sum_DopRashodUSD2'] + i = current_params['counter'] + len_sebes_sales = len(sebes_sales) + while i < len_sebes_sales: + try: + curr_str = sebes_sales[i] + except: + print('Ошибка в иттераторе, тек ид =', current_sales_id) + print(i) + print(len_sebes_sales) + break + + if curr_str[10] > date or current_sales_id != curr_str[0]: + break + else: + i += 1 + + if curr_str[12] == 'Приход': + + # кажется что можно и нужно удалить ... + if curr_str[13] == 'Закупка' or curr_str[13] == 'Ввод остатков до 22' or curr_str[13] == 'Производство товара' or curr_str[13] == 'Пересчет товара': + quantity += curr_str[2] + + + if curr_str[9] > 0: + usd2_course = curr_str[9] + else: + if curr_str[13] == 'Ввод остатков до 22': + # для ввода остатков возьём курс на 1 января 2023 года + usd2_course = 75.7785 + else: + usd2_course = 1 + + sumZakupka += curr_str[4] + if curr_str[13] == 'Ввод остатков до 22': + sumZakupkaUSD2 += decimal.Decimal(float(sumZakupka) / usd2_course) + else: + sumZakupkaUSD2 += curr_str[18] + + + #if curr_str[11] == 'руб.': + # sumZakupkaUSD += sumZakupka / usd2_course + + sum_dostavka += curr_str[5] + sum_dostavkaUSD2 += curr_str[19] + sum_NAT += curr_str[6] + sum_NATUSD2 += curr_str[20] + sum_production += curr_str[7] + sum_productionUSD2 += curr_str[22] + sum_zatratiMP += curr_str[3] + sum_custom += curr_str[8] + sum_customUSD2 += curr_str[21] + sum_skladHranenie += curr_str[14] + sum_Priemka += curr_str[15] + sum_AtsMarkirovka += curr_str[16] + sum_SborkaZakaza += curr_str[17] + sum_DopRashod += curr_str[23] + sum_DopRashodUSD2 += curr_str[24] + + if curr_str[12] == 'Расход': + quantity -= last_string_values['quantity'] + sumZakupka -= last_string_values['sumZakupka'] + sumZakupkaUSD2 -= last_string_values['sumZakupkaUSD2'] + sum_dostavka -= last_string_values['sum_dostavka'] + sum_dostavkaUSD2 -= last_string_values['sum_dostavkaUSD2'] + sum_NAT -= last_string_values['sum_NAT'] + sum_NATUSD2 -= last_string_values['sum_NATUSD2'] + sum_production -= last_string_values['sum_production'] + sum_productionUSD2 -= last_string_values['sum_productionUSD2'] + sum_zatratiMP -= last_string_values['sum_zatratiMP'] + sum_custom -= last_string_values['sum_custom'] + sum_customUSD2 -= last_string_values['sum_customUSD2'] + sum_skladHranenie -= last_string_values['sum_skladHranenie'] + sum_Priemka -= last_string_values['sum_Priemka'] + sum_AtsMarkirovka -= last_string_values['sum_AtsMarkirovka'] + sum_SborkaZakaza -= last_string_values['sum_SborkaZakaza'] + sum_DopRashod -= last_string_values['sum_DopRashod'] + sum_DopRashodUSD2 -= last_string_values['sum_DopRashodUSD2'] + + if quantity <= 0: + quantity = 0 + sumZakupka = 0 + sumZakupkaUSD2 = 0 + sum_dostavka = 0 + sum_NAT = 0 + sum_production = 0 + sum_zatratiMP = 0 + sum_custom = 0 + sum_skladHranenie = 0 + sum_Priemka = 0 + sum_AtsMarkirovka = 0 + sum_SborkaZakaza = 0 + sum_dostavkaUSD2 = 0 + sum_NATUSD2 = 0 + sum_productionUSD2 = 0 + sum_customUSD2 = 0 + sum_DopRashod = 0 + sum_DopRashodUSD2 = 0 + + + return {'quantity': quantity, 'sumZakupka': sumZakupka, 'sumZakupkaUSD2': sumZakupkaUSD2, + 'sum_dostavka': sum_dostavka, + 'sum_NAT': sum_NAT, 'sum_production': sum_production, 'sum_zatratiMP': sum_zatratiMP, 'sum_custom': sum_custom, + 'sum_skladHranenie': sum_skladHranenie, 'sum_Priemka': sum_Priemka, 'sum_AtsMarkirovka': sum_AtsMarkirovka, 'sum_SborkaZakaza': sum_SborkaZakaza, + 'sum_dostavkaUSD2': sum_dostavkaUSD2, 'sum_NATUSD2': sum_NATUSD2, 'sum_productionUSD2': sum_productionUSD2, 'sum_customUSD2': sum_customUSD2, + 'sum_DopRashod': sum_DopRashod, 'sum_DopRashodUSD2': sum_DopRashodUSD2, + 'counter': i} + + +def insert_to_DB_Production(arr, conn): + try: + cursor = conn.cursor() + conn.autocommit = False + cursor.fast_executemany = True + table = '[СебестоимостьПроизводствоОт2022]' + + cursor.executemany(""" + INSERT INTO [mag_pbi].[pbiProd].[СебестоимостьПроизводствоОт2022] + ([Период], [artic_id], [Учетная цена], [Учетная цена USD2+2]) + VALUES (?, ?, ?, ?); + """, arr) + + + except pyodbc.DatabaseError as err: + print('ошибка', err) + conn.rollback() + else: + conn.commit() + print(time.ctime(), 'обновлено', len(arr), ': записей') + finally: + conn.autocommit = True + +def update_to_DB_Sales(arr, conn, year): + try: + cursor = conn.cursor() + conn.autocommit = False + cursor.fast_executemany = True + table = '[СебестоимостьОт2022]' + if year == '2022': + table = '[СебестоимостьОт2022]' + elif year == '2023': + table = '[Себестоимость2023]' + elif year == '2024': + table = '[Себестоимость2024]' + + cursor.executemany( + """UPDATE [mag_pbi].[pbiProd].""" + table + """ + SET + [Закупка] = ? -- 0 + , [Закупка, usd2] = ? -- 1 + , [Доставка] = ? -- 2 + , [Производство] = ? -- 3 + , [НДС] = ? -- 4 + , [ЗатратыМП] = ? -- 5 + , [Таможня] = ? -- 6 + , [ЗатратыСкладХранение] = ? -- 7 + , [Учетная стоимость] = ? -- 8 + , [Учетная стоимость USD2+2] = ? -- 9 + , [Учетная цена] = ? -- 10 + , [Учетная цена USD2+2] = ? -- 11 + , [artic_id] = ? -- 12 + , [Приемка] = ? -- 13 + , [АтсМаркировка] = ? -- 14 + , [СборкаЗаказа] = ? -- 15 + , [Доставка USD2+2] = ? -- 16 + , [НДС USD2+2] = ? -- 17 + , [Таможня USD2+2] = ? -- 18 + , [Производство USD2+2] = ? -- 19 + , [Доп расходы] = ? -- 20 + , [Доп расходы USD2+2] = ? -- 21 + WHERE id = ?""", + arr) + + + except pyodbc.DatabaseError as err: + print('ошибка', err) + conn.rollback() + else: + conn.commit() + print(time.ctime(), 'обновлено', len(arr), ': записей') + finally: + conn.autocommit = True + + +def update_to_DB_sebest(arr, conn, year): + try: + cursor = conn.cursor() + conn.autocommit = False + cursor.fast_executemany = True + table = '[СебестоимостьОт2022]' + # if year == '2022': + # table = '[СебестоимостьОт2022]' + # elif year == '2023': + # table = '[Себестоимость2023]' + # elif year == '2024': + # table = '[Себестоимость2024]' + cursor.executemany( + "UPDATE [mag_pbi].[pbiProd]." + table + " SET [Учетная стоимость] = ?, [Учетная стоимость USD2+2] = ?, [Учетная цена] = ?, [Учетная цена USD2+2] = ? WHERE id = ?", + arr) + + + except pyodbc.DatabaseError as err: + print('ошибка', err) + conn.rollback() + else: + conn.commit() + print(time.ctime(), 'обновлено', len(arr), ': записей') + finally: + conn.autocommit = True + + +def exec_procedure(conn, procedure_name): + sql_query = 'EXEC ' + procedure_name + cursor = conn.cursor() + cursor.execute(sql_query).commit() + + +def getMaxCounter(conn, group): + sql_query = "SELECT MAX(" + group + ") FROM [mag_pbi].[pbiProd].[GroupsOfNomenclature]" + + cursor = conn.cursor() + cursor.execute(sql_query) + maxCounter = cursor.fetchall() + return maxCounter[0][0] + + + +def count_sebest(connect, counter = '2k', group = '1', manufactureLevel = 0, manufacture = False, start_range = 0, end_range = 0): + upload = True + ind = 0 + arr_sebes = [] + arr_sales = [] + arr_production = [] + arr_price = [] + last_utid = '' + last_operation = '' + last_state = '' + + if manufacture: + pbi_all = get_totalsManufacture(connect, manufactureLevel, start_range, end_range) + else: + pbi_all = get_totals(connect, counter, group) + + + nparr_all = np.asarray(pbi_all) + + for str in pbi_all: + ind += 1 + date = str[10] + utid = str[1] + id = str[0] + tableGod = str[14] + zakupkaRUB = round(0, 9) + zakupkaUSD2 = round(0, 9) + NAT = round(0, 9) + NATUSD2 = round(0, 9) + zatratiMP = round(0, 9) + production = round(0, 9) + dostavka = round(0, 9) + dostavkaUSD2 = round(0, 9) + custom = round(0, 9) + customUSD2 = round(0, 9) + skladHranenie = round(0, 9) + priemka = round(0, 9) + atsMarkirovka = round(0, 9) + sborkaZakaza = round(0, 9) + uchet_price = round(0, 9) + uchet_price_usd22 = round(0, 9) + dop_rashod = round(0, 9) + dop_rashod_usd22 = round(0, 9) + + + if utid != last_utid: + ## если последняя операция не Реализация Расход, то сделаем фейковую продажу чтобы посчитать цену на сегодня ... + if last_operation != 'Расход' and last_state != 'Реализация' and last_operation != '' and False: + arr_price.append(count_price(all_params, last_utid, connect)) + + + fltr = np.asarray([utid]) + pbi_all_current_utid = nparr_all[np.in1d(nparr_all[:, 1], fltr)] + last_utid = utid + current_params = {'quantity': 0, 'sumZakupka': 0, 'sumZakupkaUSD2': 0, + 'sum_dostavka': 0, 'sum_NAT': 0, 'sum_production': 0, 'sum_zatratiMP': 0, 'sum_custom': 0, 'sum_skladHranenie': 0, 'sum_Priemka': 0, + 'sum_AtsMarkirovka': 0, 'sum_SborkaZakaza': 0, 'sum_dostavkaUSD2': 0, 'sum_NATUSD2': 0, 'sum_productionUSD2': 0, 'sum_customUSD2': 0, + 'sum_zakupkaUSD2': 0, 'sum_DopRashod': 0, 'sum_DopRashodUSD2': 0, + 'counter': 0} + last_string_values = {'quantity': 0, 'sumZakupka': 0, 'sumZakupkaUSD2': 0, + 'sum_dostavka': 0, 'sum_NAT': 0, 'sum_production': 0, 'sum_zatratiMP': 0, 'sum_custom': 0, 'sum_skladHranenie': 0, 'sum_Priemka': 0, + 'sum_AtsMarkirovka': 0, 'sum_SborkaZakaza': 0, 'sum_dostavkaUSD2': 0, 'sum_NATUSD2': 0, 'sum_productionUSD2': 0, 'sum_customUSD2': 0, + 'sum_DopRashod': 0, 'sum_DopRashodUSD2': 0, + 'sum_zakupkaUSD2': 0} + + all_params = find_sumof_total(pbi_all_current_utid, date, str[0], current_params, last_string_values) + current_params = all_params.copy() + + + last_operation = str[12] + last_state = str[13] + sale_quantity = str[2] + + if str[9] > 0: + usd2_course = str[9] + else: + usd2_course = 1 + + sum_quantity = all_params['quantity'] + sum_zakupka = all_params['sumZakupka'] + sum_zakupkaUSD2 = all_params['sumZakupkaUSD2'] + sum_dostavka = all_params['sum_dostavka'] + sum_dostavkaUSD2 = all_params['sum_dostavkaUSD2'] + sum_NAT = all_params['sum_NAT'] + sum_NATUSD2 = all_params['sum_NATUSD2'] + sum_production = all_params['sum_production'] + sum_productionUSD2 = all_params['sum_productionUSD2'] + sum_zatratiMP = all_params['sum_zatratiMP'] + sum_custom = all_params['sum_custom'] + sum_customUSD2 = all_params['sum_customUSD2'] + sum_skladHranenie = all_params['sum_skladHranenie'] + sum_Priemka = all_params['sum_Priemka'] + sum_AtsMarkirovka = all_params['sum_AtsMarkirovka'] + sum_SborkaZakaza = all_params['sum_SborkaZakaza'] + sum_DopRashod = all_params['sum_DopRashod'] + sum_DopRashodUSD2 = all_params['sum_DopRashodUSD2'] + + + if (str[12] == 'Приход') and str[13] != 'Ввод остатков до 22': + + uchet_price = 0 + uchet_price_usd22 = 0 + uchet_stoimost = 0 + uchet_stoimost_usd22 = 0 + + zakupkaRUB = round(sum_zakupka, 9) + zakupkaUSD2 = round(sum_zakupkaUSD2, 9) + + + if sum_quantity != 0: + dostavka = round(sum_dostavka, 9) + dostavkaUSD2 = round(sum_dostavkaUSD2, 9) + NAT = round(sum_NAT, 9) + NATUSD2 = round(sum_NATUSD2, 9) + production = round(sum_production, 9) + productionUSD2 = round(sum_productionUSD2, 9) + zatratiMP = round(sum_zatratiMP, 9) + custom = round(sum_custom, 9) + customUSD2 = round(sum_customUSD2, 9) + skladHranenie = round(sum_skladHranenie, 9) + priemka = round(sum_Priemka, 9) + atsMarkirovka = round(sum_AtsMarkirovka, 9) + sborkaZakaza = round(sum_SborkaZakaza, 9) + dop_rashod = round(sum_DopRashod, 9) + dop_rashod_usd22 = round(sum_DopRashodUSD2, 9) + + uchet_price = round((dostavka + NAT + zakupkaRUB + custom + production) / sum_quantity, 9) + uchet_price_usd22 = round((dostavkaUSD2 + NATUSD2 + zakupkaUSD2 + customUSD2 + productionUSD2) / sum_quantity, 9) + + if sale_quantity != 0: + uchet_stoimost = round(uchet_price * sale_quantity, 9) + uchet_stoimost_usd22 = round(uchet_price_usd22 * sale_quantity, 9) + + + arr_sebes.append((uchet_stoimost, uchet_stoimost_usd22, uchet_price, uchet_price_usd22, id)) + + + elif str[12] == 'Расход': + + if sale_quantity != 0: + + if sum_zakupka < 0: + sum_zakupka = 0 + + if sale_quantity > sum_quantity or sum_quantity == 0: + zakupkaRUB = round(sum_zakupka, 9) + zakupkaUSD2 = round(sum_zakupkaUSD2, 9) + else: + zakupkaRUB = round(decimal.Decimal(sum_zakupka) / sum_quantity * sale_quantity, 9) + zakupkaUSD2 = round(decimal.Decimal(sum_zakupkaUSD2) / sum_quantity * sale_quantity, 9) + + #zakupkaUSD2 = round(sum_zakupkaUSD2 / usd2_course, 15) + + if sale_quantity > sum_quantity or sum_quantity == 0: + dostavka = round(sum_dostavka, 9) + dostavkaUSD2 = round(sum_dostavkaUSD2, 9) + NAT = round(sum_NAT, 9) + NATUSD2 = round(sum_NATUSD2, 9) + production = round(sum_production, 9) + productionUSD2 = round(sum_productionUSD2, 9) + zatratiMP = round(sum_zatratiMP, 9) + custom = round(sum_custom, 9) + customUSD2 = round(sum_customUSD2, 9) + skladHranenie = round(sum_skladHranenie, 9) + priemka = round(sum_Priemka, 9) + atsMarkirovka = round(sum_AtsMarkirovka, 9) + sborkaZakaza = round(sum_SborkaZakaza, 9) + dop_rashod = round(sum_DopRashod, 9) + dop_rashod_usd22 = round(sum_DopRashodUSD2, 9) + else: + dostavka = round(sum_dostavka / sum_quantity * sale_quantity, 9) + dostavkaUSD2 = round(sum_dostavkaUSD2 / sum_quantity * sale_quantity, 9) + NAT = round(sum_NAT / sum_quantity * sale_quantity, 9) + NATUSD2 = round(sum_NATUSD2 / sum_quantity * sale_quantity, 9) + production = round(sum_production / sum_quantity * sale_quantity, 9) + productionUSD2 = round(sum_productionUSD2 / sum_quantity * sale_quantity, 9) + zatratiMP = round(sum_zatratiMP / sum_quantity * sale_quantity, 9) + custom = round(sum_custom / sum_quantity * sale_quantity, 9) + customUSD2 = round(sum_customUSD2 / sum_quantity * sale_quantity, 9) + skladHranenie = round(sum_skladHranenie / sum_quantity * sale_quantity, 9) + priemka = round(sum_Priemka / sum_quantity * sale_quantity, 9) + atsMarkirovka = round(sum_AtsMarkirovka / sum_quantity * sale_quantity, 9) + sborkaZakaza = round(sum_SborkaZakaza / sum_quantity * sale_quantity, 9) + dop_rashod = round(sum_DopRashod / sum_quantity * sale_quantity, 9) + dop_rashod_usd22 = round(sum_DopRashodUSD2 / sum_quantity * sale_quantity, 9) + + + last_string_values = {'quantity': sale_quantity, 'sumZakupka': zakupkaRUB, 'sumZakupkaUSD2': zakupkaUSD2, + 'sum_dostavka': dostavka, + 'sum_NAT': NAT, 'sum_production': production, 'sum_zatratiMP': zatratiMP, + 'sum_custom': custom, 'sum_skladHranenie': skladHranenie, 'sum_Priemka': priemka, + 'sum_AtsMarkirovka': atsMarkirovka, 'sum_SborkaZakaza': sborkaZakaza, + 'sum_dostavkaUSD2': dostavkaUSD2, 'sum_NATUSD2': NATUSD2, 'sum_productionUSD2': productionUSD2, 'sum_customUSD2': customUSD2, + 'sum_DopRashod': dop_rashod, 'sum_DopRashodUSD2': dop_rashod_usd22} + + if zakupkaRUB != 0 or zakupkaUSD2 != 0 or NAT != 0 or production != 0 or dostavka != 0 or custom != 0: + uchet_stoimost = round((dostavka + NAT + zakupkaRUB + custom + production), 9) + uchet_stoimost_usd22 = round((dostavkaUSD2 + NATUSD2 + zakupkaUSD2 + customUSD2 + productionUSD2), 9) + uchet_price = round((dostavka + NAT + zakupkaRUB + custom + production) / sale_quantity, 9) + uchet_price_usd22 = round((dostavkaUSD2 + NATUSD2 + zakupkaUSD2 + customUSD2 + productionUSD2) / sale_quantity, 9) + + arr_sales.append( + (float(-zakupkaRUB), float(-zakupkaUSD2), float(-dostavka), float(-production), float(-NAT), float(-zatratiMP), float(-custom), + float(-skladHranenie), float(uchet_stoimost), + float(uchet_stoimost_usd22), float(uchet_price), float(uchet_price_usd22), utid, float(-priemka), float(-atsMarkirovka), float(-sborkaZakaza), + float(-dostavkaUSD2), float(-NATUSD2), float(-productionUSD2), float(-customUSD2), float(-dop_rashod), float(-dop_rashod_usd22), + id)) + + if str[13] == 'Производство товара': + arr_production.append((str[10], str[1], float(uchet_price), float(uchet_price_usd22))) + + + # break + + if ind % 10000 == 0: + print(time.ctime(), ' ', ind, 'проходов') + + if len(arr_price) > 0 and False: + insert_to_DB_UchetPrice(arr_price, connect) + + if len(arr_production) > 0 and manufacture: + insert_to_DB_Production(arr_production, connect) + + + if upload and manufacture == False: + if len(arr_sales) > 0: + print(time.ctime(), ' записей sales: ', len(arr_sales)) + update_to_DB_Sales(arr_sales, connect, '2022') + + if len(arr_sebes) > 0: + print(time.ctime(), ' записей sebest: ', len(arr_sebes)) + update_to_DB_sebest(arr_sebes, connect, '2022') + + + upload = False + + +def fill_table_sebestoim2022(connect, skip = False): + + if skip: + return + + + #флаг для обработки без заполнения таблиц ... + prepare_table = True + fill_AtsMarkirovka = True + fill_DopRashod = True + fill_Dostavka = True + fill_Zakupka = True + fill_ZatratiMp = False + fill_Pereschet = True + fill_PereschetSklad = True + fill_Priemka = True + fill_Prodaji = True + fill_Proizvodstvo = True + fill_Sborka = True + + if prepare_table: + print('Подготовка таблицы СебестоимостьОт2022 ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Подготовка таблицы СебестоимостьОт2022]') + + # заполним таблицы данными закупки ... + if fill_AtsMarkirovka: + print('Заполнение таблицы данными: АтсМаркировка ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(АтсМаркировка)]') + + if fill_DopRashod: + print('Заполнение таблицы данными: Доп расходы ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(ДопРасходы)]') + + if fill_Dostavka: + print('Заполнение таблицы данными: Доставка ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(Доставка)]') + + if fill_Zakupka: + print('Заполнение таблицы данными: Закупка ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(Закупка)]') + + if fill_ZatratiMp: + print('Заполнение таблицы данными: ЗатратыМП ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(ЗатратыМП)]') + + if fill_Pereschet: + print('Заполнение таблицы данными: Пересчет ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(Перерасчет)]') + + if fill_PereschetSklad: + print('Заполнение таблицы данными: Пересчет ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(ПерерасчетСкладскойКонтур)]') + + if fill_Priemka: + print('Заполнение таблицы данными: Приемка ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(Приемка)]') + + if fill_Prodaji: + print('Заполнение таблицы данными: Продажи ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(Продажи)]') + + if fill_Proizvodstvo: + print('Заполнение таблицы данными: Производство ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(Производство)]') + + if fill_Sborka: + print('Заполнение таблицы данными: Сборка ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(Сборка)]') + +def count_price(all_params, last_utid, conn): + arr_price = [] + uchet_price = 0 + uchet_price_usd22 = 0 + sale_quantity = 1 + sum_quantity = all_params['quantity'] + sum_zakupka = all_params['sumZakupka'] + sum_zakupkaUSD2 = all_params['sumZakupkaUSD2'] + sum_dostavka = all_params['sum_dostavka'] + sum_dostavkaUSD2 = all_params['sum_dostavkaUSD2'] + sum_NAT = all_params['sum_NAT'] + sum_NATUSD2 = all_params['sum_NATUSD2'] + sum_production = all_params['sum_production'] + sum_productionUSD2 = all_params['sum_productionUSD2'] + sum_custom = all_params['sum_custom'] + sum_customUSD2 = all_params['sum_customUSD2'] + + + if sale_quantity != 0: + + + if sale_quantity > sum_quantity or sum_quantity == 0: + zakupkaRUB = round(sum_zakupka, 9) + zakupkaUSD2 = round(sum_zakupkaUSD2, 9) + else: + zakupkaRUB = round(decimal.Decimal(sum_zakupka) / sum_quantity * sale_quantity, 9) + zakupkaUSD2 = round(decimal.Decimal(sum_zakupkaUSD2) / sum_quantity * sale_quantity, 9) + + + if sale_quantity > sum_quantity or sum_quantity == 0: + dostavka = round(sum_dostavka, 9) + dostavkaUSD2 = round(sum_dostavkaUSD2, 9) + NAT = round(sum_NAT, 9) + NATUSD2 = round(sum_NATUSD2, 9) + production = round(sum_production, 9) + productionUSD2 = round(sum_productionUSD2, 9) + custom = round(sum_custom, 9) + customUSD2 = round(sum_customUSD2, 9) + else: + dostavka = round(sum_dostavka / sum_quantity * sale_quantity, 9) + dostavkaUSD2 = round(sum_dostavkaUSD2 / sum_quantity * sale_quantity, 9) + NAT = round(sum_NAT / sum_quantity * sale_quantity, 9) + NATUSD2 = round(sum_NATUSD2 / sum_quantity * sale_quantity, 9) + production = round(sum_production / sum_quantity * sale_quantity, 9) + productionUSD2 = round(sum_productionUSD2 / sum_quantity * sale_quantity, 9) + custom = round(sum_custom / sum_quantity * sale_quantity, 9) + customUSD2 = round(sum_customUSD2 / sum_quantity * sale_quantity, 9) + + + + if zakupkaRUB != 0 or zakupkaUSD2 != 0 or NAT != 0 or production != 0 or dostavka != 0 or custom != 0: + uchet_price = round((dostavka + NAT + zakupkaRUB + custom + production) / sale_quantity, 9) + uchet_price_usd22 = round((dostavkaUSD2 + NATUSD2 + zakupkaUSD2 + customUSD2 + productionUSD2) / sale_quantity, 9) + + + return (last_utid, float(uchet_price), float(uchet_price_usd22)) + #arr_price.append((last_utid, float(uchet_price), float(uchet_price_usd22))) + #if len(arr_price) > 0: + # insert_to_DB_UchetPrice(arr_price, conn) + + + + + + + + +def insert_to_DB_UchetPrice(arr, conn): + try: + cursor = conn.cursor() + conn.autocommit = False + cursor.fast_executemany = True + table = '[pbiProd].[УчетнаяЦенаПоСебестоимости]' + + cursor.executemany(""" + INSERT INTO [mag_pbi].[pbiProd].[УчетнаяЦенаПоСебестоимости] + ( [Период], [artic_id], [Учетная цена], [Учетная цена USD2+2]) + VALUES (CONVERT(date, GETDATE()), ?, ?, ?); + """, arr) + + + except pyodbc.DatabaseError as err: + print('ошибка', err) + conn.rollback() + else: + conn.commit() + print(time.ctime(), 'обновлено', len(arr), ': записей') + finally: + conn.autocommit = True + + + + +union_sebes = True +print('start time', time.ctime()) +connect = sql_connect() +ComputeManufacture = False +maxLvl = 1 + +if ComputeManufacture: + maxLvl = 4 + exec_procedure(connect, '[pbiProd].[Подготовка Производство: единая процедура для подготовки]') + + + +for stRange in range(0, maxLvl): + # Заполнение таблицы + skip = False + fill_table_sebestoim2022(connect, skip) + + if True: + group = '[2k]' + max_counter = getMaxCounter(connect, group) + print('Группа: ', group, ' Всего групп - ', max_counter) + for counter in range(max_counter): + counter += 1 + count_sebest(connect, counter, group) + print(time.ctime(), ' группа ', counter, ' обработана') + + + # Расчитаем товары которые учавствуют в производстве + if ComputeManufacture: + start_range = 0 + for i in range(stRange, stRange + 1): + for i_range in range(2000, 20000, 2000): + end_range = i_range + count_sebest(connect, "", "", i, True, start_range, end_range) + start_range = i_range + + # Нужно добавить 1с_id в таблицу .... + exec_procedure(connect, '[pbiProd].[Производство: Заполнить 1сid для СебестоимостьПроизводствоОт2022]') + + +# заполним сводную таблицу (финальную) для загрузки в пби ... +if union_sebes: + print('Объединение в сводную таблицу ~ 10 мин ...') + exec_procedure(connect, '[pbiProd].[ЗаполнитьСебестоимостьСводныйОт2022]') + + +connect.close() +print('end time ', time.ctime()) diff --git a/analytics/python skript/Calculationofthecostofreproduction.bat b/analytics/python skript/Calculationofthecostofreproduction.bat new file mode 100644 index 0000000..fb46a3e --- /dev/null +++ b/analytics/python skript/Calculationofthecostofreproduction.bat @@ -0,0 +1,2 @@ +"C:\Users\administrator\AppData\Local\Programs\Python\Python312\python.exe" "F:\python skript\Calculationofthecostofreproduction.py" +exit \ No newline at end of file diff --git a/analytics/python skript/Calculationofthecostofreproduction.py b/analytics/python skript/Calculationofthecostofreproduction.py new file mode 100644 index 0000000..a6627b2 --- /dev/null +++ b/analytics/python skript/Calculationofthecostofreproduction.py @@ -0,0 +1,950 @@ +import decimal +import time +import numpy as np +import pyodbc + + +def sql_connect(): + server = '192.168.35.207' + database = 'mag_pbi' + username = 'goglev' + password = 'BOMoGbUZ1p' + connection_string = f'DRIVER={{ODBC Driver 17 for SQL Server}};SERVER={server};DATABASE={database};UID={username};PWD={password}' + + conn = pyodbc.connect(connection_string) + print("successfully connected...") + print("#" * 20) + return conn + + +def get_totals(conn, counter, group): + sql_query = """ + SELECT --TOP (1000) + id, -- 0 + artic_id, -- 1 + COALESCE([Количество], 0) AS [Количество], -- 2 + COALESCE([ЗатратыМП], 0) AS ЗатратыМП, -- 3 + COALESCE([Закупка], 0) AS [Закупка], -- 4 + COALESCE([Доставка], 0) AS [Доставка], -- 5 + COALESCE([НДС], 0) AS [НДС], -- 6 + COALESCE([Производство], 0) AS [Производство], -- 7 + COALESCE([Таможня], 0) AS [Таможня], -- 8 + [Курс usd2] AS [Курс usd2], -- 9 + [Период] AS [Период], -- 10 + [Валюта документа] AS [Валюта документа], -- 11 + [Вид операции] AS [Вид операции], -- 12 + [Статья] AS [Статья], -- 13 + COALESCE([ЗатратыСкладХранение], 0) AS [ЗатратыСкладХранение], -- 14 + COALESCE([Приемка], 0) AS [Приемка], -- 15 + COALESCE([АтсМаркировка], 0) AS [АтсМаркировка], -- 16 + COALESCE([СборкаЗаказа], 0) AS [СборкаЗаказа], -- 17 + COALESCE([Закупка, usd2], 0) AS [Закупка, usd2], -- 18 + COALESCE([Доставка USD2+2], 0) AS [Доставка USD2+2], -- 19 + COALESCE([НДС USD2+2], 0) AS [НДС USD2+2], -- 20 + COALESCE([Таможня USD2+2], 0) AS [Таможня USD2+2], -- 21 + COALESCE([Производство USD2+2], 0) AS [Производство USD2+2], -- 22 + COALESCE([Доп расходы], 0) AS [Доп расходы], -- 23 + COALESCE([Доп расходы USD2+2], 0) AS [Доп расходы USD2+2] -- 24 + FROM + ( + SELECT + id, + artic_id, + COALESCE([Количество], 0) AS [Количество], + [ЗатратыМП], + COALESCE([Закупка], 0) AS [Закупка], + COALESCE([Доставка], 0) AS [Доставка], + [НДС], + COALESCE([Производство], 0) AS [Производство], + COALESCE([Таможня], 0) AS [Таможня], + [Курс usd2], + [Период], + [Валюта документа], + [Вид операции], + [Статья], + [ЗатратыСкладХранение], + [Приемка], + [АтсМаркировка], + [СборкаЗаказа], + COALESCE([Закупка, usd2], 0) AS [Закупка, usd2], + COALESCE([Доставка USD2+2], 0) AS [Доставка USD2+2], + COALESCE([НДС USD2+2], 0) AS [НДС USD2+2], + COALESCE([Таможня USD2+2], 0) AS [Таможня USD2+2], + COALESCE([Производство USD2+2], 0) AS [Производство USD2+2], + COALESCE([Доп расходы], 0) AS [Доп расходы], + COALESCE([Доп расходы USD2+2], 0) AS [Доп расходы USD2+2] + + FROM [mag_pbi].[pbiProd].[СебестоимостьОт2022] + WHERE + 1=1 + --and [artic_id] = 'c4bbfb4b-cf25-11ef-998c-b49691d57efd' + and [artic_id] IN (SELECT + [artic_id] + FROM [mag_pbi].[pbiProd].[GroupsOfNomenclature] + where """ + group + """ = """ + str(counter) + """) + and [Период] >= '2022' + + + UNION ALL + + SELECT + id, + artic_id, + COALESCE([Количество], 0), + [ЗатратыМП], + COALESCE([Закупка], 0), + COALESCE([Доставка], 0), + [НДС], + COALESCE([Сборка], 0), + COALESCE([Таможня], 0), + 0, + '2021', + NULL, + 'Приход', + 'Ввод остатков до 22', + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + FROM [mag_pbi].[pbiProd].[СебестоимостьИтогиДо2022] + where + 1 = 1 + --and [artic_id] = 'c4bbfb4b-cf25-11ef-998c-b49691d57efd' + and [artic_id] IN (SELECT + [artic_id] + FROM [mag_pbi].[pbiProd].[GroupsOfNomenclature] + where """ + group + """ = """ + str(counter) + """) + ) AS tabMain + --WHERE 1=1 + + ORDER BY + [artic_id], [Период] ASC, [Закупка] DESC; + """ + cursor = conn.cursor() + cursor.execute(sql_query) + pbi_totals = cursor.fetchall() + print(time.ctime(), ' Записей к обработке: ', len(pbi_totals)) + return pbi_totals + + + +def get_totalsManufacture(conn, manufactureLevel, start_range, end_range): + sql_query = """ + SELECT --TOP (1000) + id, -- 0 + artic_id, -- 1 + COALESCE([Количество], 0) AS [Количество], -- 2 + COALESCE([ЗатратыМП], 0) AS ЗатратыМП, -- 3 + COALESCE([Закупка], 0) AS [Закупка], -- 4 + COALESCE([Доставка], 0) AS [Доставка], -- 5 + COALESCE([НДС], 0) AS [НДС], -- 6 + COALESCE([Производство], 0) AS [Производство], -- 7 + COALESCE([Таможня], 0) AS [Таможня], -- 8 + [Курс usd2] AS [Курс usd2], -- 9 + [Период] AS [Период], -- 10 + [Валюта документа] AS [Валюта документа], -- 11 + [Вид операции] AS [Вид операции], -- 12 + [Статья] AS [Статья], -- 13 + COALESCE([ЗатратыСкладХранение], 0) AS [ЗатратыСкладХранение], -- 14 + COALESCE([Приемка], 0) AS [Приемка], -- 15 + COALESCE([АтсМаркировка], 0) AS [АтсМаркировка], -- 16 + COALESCE([СборкаЗаказа], 0) AS [СборкаЗаказа], -- 17 + COALESCE([Закупка, usd2], 0) AS [Закупка, usd2], -- 18 + COALESCE([Доставка USD2+2], 0) AS [Доставка USD2+2], -- 19 + COALESCE([НДС USD2+2], 0) AS [НДС USD2+2], -- 20 + COALESCE([Таможня USD2+2], 0) AS [Таможня USD2+2], -- 21 + COALESCE([Производство USD2+2], 0) AS [Производство USD2+2], -- 22 + COALESCE([Доп расходы], 0) AS [Доп расходы], -- 23 + COALESCE([Доп расходы USD2+2], 0) AS [Доп расходы USD2+2] -- 24 + FROM + ( + SELECT + id, + artic_id, + COALESCE([Количество], 0) AS [Количество], + [ЗатратыМП], + COALESCE([Закупка], 0) AS [Закупка], + COALESCE([Доставка], 0) AS [Доставка], + [НДС], + COALESCE([Производство], 0) AS [Производство], + COALESCE([Таможня], 0) AS [Таможня], + [Курс usd2], + [Период], + [Валюта документа], + [Вид операции], + [Статья], + [ЗатратыСкладХранение], + [Приемка], + [АтсМаркировка], + [СборкаЗаказа], + COALESCE([Закупка, usd2], 0) AS [Закупка, usd2], + COALESCE([Доставка USD2+2], 0) AS [Доставка USD2+2], + COALESCE([НДС USD2+2], 0) AS [НДС USD2+2], + COALESCE([Таможня USD2+2], 0) AS [Таможня USD2+2], + COALESCE([Производство USD2+2], 0) AS [Производство USD2+2], + COALESCE([Доп расходы], 0) AS [Доп расходы], + COALESCE([Доп расходы USD2+2], 0) AS [Доп расходы USD2+2] + FROM [mag_pbi].[pbiProd].[СебестоимостьОт2022] + WHERE + 1=1 + --and [artic_id] = '24d0c24b-3a60-11e9-ae9c-b496910dcfd6' + and [1c_id] IN (SELECT + [1c_id] + FROM [mag_pbi].[pbiProd].[НоменклатураВПроизводствеПоУровням] + where [УровеньПроизводства] = """ + str(manufactureLevel) + """ + and [RowNum] BETWEEN """ + str(start_range) + """ AND """ + str(end_range) + """ + --and [1c_id] = 0x9981B49691D57EFD11EDDE7DA97A5E64 + ) + and [Период] >= '2022' + + + UNION ALL + + SELECT + id, + artic_id, + COALESCE([Количество], 0), + [ЗатратыМП], + COALESCE([Закупка], 0), + COALESCE([Доставка], 0), + [НДС], + COALESCE([Сборка], 0), + COALESCE([Таможня], 0), + 0, + '2021', + NULL, + 'Приход', + 'Ввод остатков до 22', + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + FROM [mag_pbi].[pbiProd].[СебестоимостьИтогиДо2022] + where + 1 = 1 + --and [artic_id] = '24d0c24b-3a60-11e9-ae9c-b496910dcfd6' + and [1c_id] IN (SELECT + [1c_id] + FROM [mag_pbi].[pbiProd].[НоменклатураВПроизводствеПоУровням] + where [УровеньПроизводства] = """ + str(manufactureLevel) + """ + and [RowNum] BETWEEN """ + str(start_range) + """ AND """ + str(end_range) + """ + --and [1c_id] = 0x9981B49691D57EFD11EDDE7DA97A5E64 + ) + ) AS tabMain + --WHERE 1=1 + + ORDER BY + [artic_id], [Период] ASC, [Закупка] DESC; + """ + cursor = conn.cursor() + cursor.execute(sql_query) + pbi_totals = cursor.fetchall() + print(time.ctime(), ' Записей к обработке: ', len(pbi_totals)) + return pbi_totals + +def find_sumof_total(sebes_sales, date, current_sales_id, current_params, last_string_values): + quantity = current_params['quantity'] + sumZakupka = current_params['sumZakupka'] + sumZakupkaUSD2 = current_params['sumZakupkaUSD2'] + sum_dostavka = current_params['sum_dostavka'] + sum_dostavkaUSD2 = current_params['sum_dostavkaUSD2'] + sum_NAT = current_params['sum_NAT'] + sum_NATUSD2 = current_params['sum_NATUSD2'] + sum_production = current_params['sum_production'] + sum_productionUSD2 = current_params['sum_productionUSD2'] + sum_zatratiMP = current_params['sum_zatratiMP'] + sum_custom = current_params['sum_custom'] + sum_customUSD2 = current_params['sum_customUSD2'] + sum_skladHranenie = current_params['sum_skladHranenie'] + sum_Priemka = current_params['sum_Priemka'] + sum_AtsMarkirovka = current_params['sum_AtsMarkirovka'] + sum_SborkaZakaza = current_params['sum_SborkaZakaza'] + sum_DopRashod = current_params['sum_DopRashod'] + sum_DopRashodUSD2 = current_params['sum_DopRashodUSD2'] + i = current_params['counter'] + len_sebes_sales = len(sebes_sales) + while i < len_sebes_sales: + try: + curr_str = sebes_sales[i] + except: + print('Ошибка в иттераторе, тек ид =', current_sales_id) + print(i) + print(len_sebes_sales) + break + + if curr_str[10] > date or current_sales_id != curr_str[0]: + break + else: + i += 1 + + if curr_str[12] == 'Приход': + + # кажется что можно и нужно удалить ... + if curr_str[13] == 'Закупка' or curr_str[13] == 'Ввод остатков до 22' or curr_str[13] == 'Производство товара' or curr_str[13] == 'Пересчет товара': + quantity += curr_str[2] + + + if curr_str[9] > 0: + usd2_course = curr_str[9] + else: + if curr_str[13] == 'Ввод остатков до 22': + # для ввода остатков возьём курс на 1 января 2023 года + usd2_course = 75.7785 + else: + usd2_course = 1 + + sumZakupka += curr_str[4] + if curr_str[13] == 'Ввод остатков до 22': + sumZakupkaUSD2 += decimal.Decimal(float(sumZakupka) / usd2_course) + else: + sumZakupkaUSD2 += curr_str[18] + + + #if curr_str[11] == 'руб.': + # sumZakupkaUSD += sumZakupka / usd2_course + + sum_dostavka += curr_str[5] + sum_dostavkaUSD2 += curr_str[19] + sum_NAT += curr_str[6] + sum_NATUSD2 += curr_str[20] + sum_production += curr_str[7] + sum_productionUSD2 += curr_str[22] + sum_zatratiMP += curr_str[3] + sum_custom += curr_str[8] + sum_customUSD2 += curr_str[21] + sum_skladHranenie += curr_str[14] + sum_Priemka += curr_str[15] + sum_AtsMarkirovka += curr_str[16] + sum_SborkaZakaza += curr_str[17] + sum_DopRashod += curr_str[23] + sum_DopRashodUSD2 += curr_str[24] + + if curr_str[12] == 'Расход': + quantity -= last_string_values['quantity'] + sumZakupka -= last_string_values['sumZakupka'] + sumZakupkaUSD2 -= last_string_values['sumZakupkaUSD2'] + sum_dostavka -= last_string_values['sum_dostavka'] + sum_dostavkaUSD2 -= last_string_values['sum_dostavkaUSD2'] + sum_NAT -= last_string_values['sum_NAT'] + sum_NATUSD2 -= last_string_values['sum_NATUSD2'] + sum_production -= last_string_values['sum_production'] + sum_productionUSD2 -= last_string_values['sum_productionUSD2'] + sum_zatratiMP -= last_string_values['sum_zatratiMP'] + sum_custom -= last_string_values['sum_custom'] + sum_customUSD2 -= last_string_values['sum_customUSD2'] + sum_skladHranenie -= last_string_values['sum_skladHranenie'] + sum_Priemka -= last_string_values['sum_Priemka'] + sum_AtsMarkirovka -= last_string_values['sum_AtsMarkirovka'] + sum_SborkaZakaza -= last_string_values['sum_SborkaZakaza'] + sum_DopRashod -= last_string_values['sum_DopRashod'] + sum_DopRashodUSD2 -= last_string_values['sum_DopRashodUSD2'] + + if quantity <= 0: + quantity = 0 + sumZakupka = 0 + sumZakupkaUSD2 = 0 + sum_dostavka = 0 + sum_NAT = 0 + sum_production = 0 + sum_zatratiMP = 0 + sum_custom = 0 + sum_skladHranenie = 0 + sum_Priemka = 0 + sum_AtsMarkirovka = 0 + sum_SborkaZakaza = 0 + sum_dostavkaUSD2 = 0 + sum_NATUSD2 = 0 + sum_productionUSD2 = 0 + sum_customUSD2 = 0 + sum_DopRashod = 0 + sum_DopRashodUSD2 = 0 + + + return {'quantity': quantity, 'sumZakupka': sumZakupka, 'sumZakupkaUSD2': sumZakupkaUSD2, + 'sum_dostavka': sum_dostavka, + 'sum_NAT': sum_NAT, 'sum_production': sum_production, 'sum_zatratiMP': sum_zatratiMP, 'sum_custom': sum_custom, + 'sum_skladHranenie': sum_skladHranenie, 'sum_Priemka': sum_Priemka, 'sum_AtsMarkirovka': sum_AtsMarkirovka, 'sum_SborkaZakaza': sum_SborkaZakaza, + 'sum_dostavkaUSD2': sum_dostavkaUSD2, 'sum_NATUSD2': sum_NATUSD2, 'sum_productionUSD2': sum_productionUSD2, 'sum_customUSD2': sum_customUSD2, + 'sum_DopRashod': sum_DopRashod, 'sum_DopRashodUSD2': sum_DopRashodUSD2, + 'counter': i} + + +def insert_to_DB_Production(arr, conn): + try: + cursor = conn.cursor() + conn.autocommit = False + cursor.fast_executemany = True + table = '[СебестоимостьПроизводствоОт2022]' + + cursor.executemany(""" + INSERT INTO [mag_pbi].[pbiProd].[СебестоимостьПроизводствоОт2022] + ([Период], [artic_id], [Учетная цена], [Учетная цена USD2+2]) + VALUES (?, ?, ?, ?); + """, arr) + + + except pyodbc.DatabaseError as err: + print('ошибка', err) + conn.rollback() + else: + conn.commit() + print(time.ctime(), 'обновлено', len(arr), ': записей') + finally: + conn.autocommit = True + +def update_to_DB_Sales(arr, conn, year): + try: + cursor = conn.cursor() + conn.autocommit = False + cursor.fast_executemany = True + table = '[СебестоимостьОт2022]' + if year == '2022': + table = '[СебестоимостьОт2022]' + elif year == '2023': + table = '[Себестоимость2023]' + elif year == '2024': + table = '[Себестоимость2024]' + + cursor.executemany( + """UPDATE [mag_pbi].[pbiProd].""" + table + """ + SET + [Закупка] = ? -- 0 + , [Закупка, usd2] = ? -- 1 + , [Доставка] = ? -- 2 + , [Производство] = ? -- 3 + , [НДС] = ? -- 4 + , [ЗатратыМП] = ? -- 5 + , [Таможня] = ? -- 6 + , [ЗатратыСкладХранение] = ? -- 7 + , [Учетная стоимость] = ? -- 8 + , [Учетная стоимость USD2+2] = ? -- 9 + , [Учетная цена] = ? -- 10 + , [Учетная цена USD2+2] = ? -- 11 + , [artic_id] = ? -- 12 + , [Приемка] = ? -- 13 + , [АтсМаркировка] = ? -- 14 + , [СборкаЗаказа] = ? -- 15 + , [Доставка USD2+2] = ? -- 16 + , [НДС USD2+2] = ? -- 17 + , [Таможня USD2+2] = ? -- 18 + , [Производство USD2+2] = ? -- 19 + , [Доп расходы] = ? -- 20 + , [Доп расходы USD2+2] = ? -- 21 + WHERE id = ?""", + arr) + + + except pyodbc.DatabaseError as err: + print('ошибка', err) + conn.rollback() + else: + conn.commit() + print(time.ctime(), 'обновлено', len(arr), ': записей') + finally: + conn.autocommit = True + + +def update_to_DB_sebest(arr, conn, year): + try: + cursor = conn.cursor() + conn.autocommit = False + cursor.fast_executemany = True + table = '[СебестоимостьОт2022]' + # if year == '2022': + # table = '[СебестоимостьОт2022]' + # elif year == '2023': + # table = '[Себестоимость2023]' + # elif year == '2024': + # table = '[Себестоимость2024]' + cursor.executemany( + "UPDATE [mag_pbi].[pbiProd]." + table + " SET [Учетная стоимость] = ?, [Учетная стоимость USD2+2] = ?, [Учетная цена] = ?, [Учетная цена USD2+2] = ? WHERE id = ?", + arr) + + + except pyodbc.DatabaseError as err: + print('ошибка', err) + conn.rollback() + else: + conn.commit() + print(time.ctime(), 'обновлено', len(arr), ': записей') + finally: + conn.autocommit = True + + +def exec_procedure(conn, procedure_name): + sql_query = 'EXEC ' + procedure_name + cursor = conn.cursor() + cursor.execute(sql_query).commit() + + +def getMaxCounter(conn, group): + sql_query = "SELECT MAX(" + group + ") FROM [mag_pbi].[pbiProd].[GroupsOfNomenclature]" + + cursor = conn.cursor() + cursor.execute(sql_query) + maxCounter = cursor.fetchall() + return maxCounter[0][0] + + + +def count_sebest(connect, counter = '2k', group = '1', manufactureLevel = 0, manufacture = False, start_range = 0, end_range = 0): + upload = True + ind = 0 + arr_sebes = [] + arr_sales = [] + arr_production = [] + arr_price = [] + last_utid = '' + last_operation = '' + last_state = '' + + if manufacture: + pbi_all = get_totalsManufacture(connect, manufactureLevel, start_range, end_range) + else: + pbi_all = get_totals(connect, counter, group) + + + nparr_all = np.asarray(pbi_all) + + for str in pbi_all: + ind += 1 + date = str[10] + utid = str[1] + id = str[0] + tableGod = str[14] + zakupkaRUB = round(0, 9) + zakupkaUSD2 = round(0, 9) + NAT = round(0, 9) + NATUSD2 = round(0, 9) + zatratiMP = round(0, 9) + production = round(0, 9) + dostavka = round(0, 9) + dostavkaUSD2 = round(0, 9) + custom = round(0, 9) + customUSD2 = round(0, 9) + skladHranenie = round(0, 9) + priemka = round(0, 9) + atsMarkirovka = round(0, 9) + sborkaZakaza = round(0, 9) + uchet_price = round(0, 9) + uchet_price_usd22 = round(0, 9) + dop_rashod = round(0, 9) + dop_rashod_usd22 = round(0, 9) + + + if utid != last_utid: + ## если последняя операция не Реализация Расход, то сделаем фейковую продажу чтобы посчитать цену на сегодня ... + if last_operation != 'Расход' and last_state != 'Реализация' and last_operation != '' and False: + arr_price.append(count_price(all_params, last_utid, connect)) + + + fltr = np.asarray([utid]) + pbi_all_current_utid = nparr_all[np.in1d(nparr_all[:, 1], fltr)] + last_utid = utid + current_params = {'quantity': 0, 'sumZakupka': 0, 'sumZakupkaUSD2': 0, + 'sum_dostavka': 0, 'sum_NAT': 0, 'sum_production': 0, 'sum_zatratiMP': 0, 'sum_custom': 0, 'sum_skladHranenie': 0, 'sum_Priemka': 0, + 'sum_AtsMarkirovka': 0, 'sum_SborkaZakaza': 0, 'sum_dostavkaUSD2': 0, 'sum_NATUSD2': 0, 'sum_productionUSD2': 0, 'sum_customUSD2': 0, + 'sum_zakupkaUSD2': 0, 'sum_DopRashod': 0, 'sum_DopRashodUSD2': 0, + 'counter': 0} + last_string_values = {'quantity': 0, 'sumZakupka': 0, 'sumZakupkaUSD2': 0, + 'sum_dostavka': 0, 'sum_NAT': 0, 'sum_production': 0, 'sum_zatratiMP': 0, 'sum_custom': 0, 'sum_skladHranenie': 0, 'sum_Priemka': 0, + 'sum_AtsMarkirovka': 0, 'sum_SborkaZakaza': 0, 'sum_dostavkaUSD2': 0, 'sum_NATUSD2': 0, 'sum_productionUSD2': 0, 'sum_customUSD2': 0, + 'sum_DopRashod': 0, 'sum_DopRashodUSD2': 0, + 'sum_zakupkaUSD2': 0} + + all_params = find_sumof_total(pbi_all_current_utid, date, str[0], current_params, last_string_values) + current_params = all_params.copy() + + + last_operation = str[12] + last_state = str[13] + sale_quantity = str[2] + + if str[9] > 0: + usd2_course = str[9] + else: + usd2_course = 1 + + sum_quantity = all_params['quantity'] + sum_zakupka = all_params['sumZakupka'] + sum_zakupkaUSD2 = all_params['sumZakupkaUSD2'] + sum_dostavka = all_params['sum_dostavka'] + sum_dostavkaUSD2 = all_params['sum_dostavkaUSD2'] + sum_NAT = all_params['sum_NAT'] + sum_NATUSD2 = all_params['sum_NATUSD2'] + sum_production = all_params['sum_production'] + sum_productionUSD2 = all_params['sum_productionUSD2'] + sum_zatratiMP = all_params['sum_zatratiMP'] + sum_custom = all_params['sum_custom'] + sum_customUSD2 = all_params['sum_customUSD2'] + sum_skladHranenie = all_params['sum_skladHranenie'] + sum_Priemka = all_params['sum_Priemka'] + sum_AtsMarkirovka = all_params['sum_AtsMarkirovka'] + sum_SborkaZakaza = all_params['sum_SborkaZakaza'] + sum_DopRashod = all_params['sum_DopRashod'] + sum_DopRashodUSD2 = all_params['sum_DopRashodUSD2'] + + + if (str[12] == 'Приход') and str[13] != 'Ввод остатков до 22': + + uchet_price = 0 + uchet_price_usd22 = 0 + uchet_stoimost = 0 + uchet_stoimost_usd22 = 0 + + zakupkaRUB = round(sum_zakupka, 9) + zakupkaUSD2 = round(sum_zakupkaUSD2, 9) + + + if sum_quantity != 0: + dostavka = round(sum_dostavka, 9) + dostavkaUSD2 = round(sum_dostavkaUSD2, 9) + NAT = round(sum_NAT, 9) + NATUSD2 = round(sum_NATUSD2, 9) + production = round(sum_production, 9) + productionUSD2 = round(sum_productionUSD2, 9) + zatratiMP = round(sum_zatratiMP, 9) + custom = round(sum_custom, 9) + customUSD2 = round(sum_customUSD2, 9) + skladHranenie = round(sum_skladHranenie, 9) + priemka = round(sum_Priemka, 9) + atsMarkirovka = round(sum_AtsMarkirovka, 9) + sborkaZakaza = round(sum_SborkaZakaza, 9) + dop_rashod = round(sum_DopRashod, 9) + dop_rashod_usd22 = round(sum_DopRashodUSD2, 9) + + uchet_price = round((dostavka + NAT + zakupkaRUB + custom + production) / sum_quantity, 9) + uchet_price_usd22 = round((dostavkaUSD2 + NATUSD2 + zakupkaUSD2 + customUSD2 + productionUSD2) / sum_quantity, 9) + + if sale_quantity != 0: + uchet_stoimost = round(uchet_price * sale_quantity, 9) + uchet_stoimost_usd22 = round(uchet_price_usd22 * sale_quantity, 9) + + + arr_sebes.append((uchet_stoimost, uchet_stoimost_usd22, uchet_price, uchet_price_usd22, id)) + + + elif str[12] == 'Расход': + + if sale_quantity != 0: + + if sum_zakupka < 0: + sum_zakupka = 0 + + if sale_quantity > sum_quantity or sum_quantity == 0: + zakupkaRUB = round(sum_zakupka, 9) + zakupkaUSD2 = round(sum_zakupkaUSD2, 9) + else: + zakupkaRUB = round(decimal.Decimal(sum_zakupka) / sum_quantity * sale_quantity, 9) + zakupkaUSD2 = round(decimal.Decimal(sum_zakupkaUSD2) / sum_quantity * sale_quantity, 9) + + #zakupkaUSD2 = round(sum_zakupkaUSD2 / usd2_course, 15) + + if sale_quantity > sum_quantity or sum_quantity == 0: + dostavka = round(sum_dostavka, 9) + dostavkaUSD2 = round(sum_dostavkaUSD2, 9) + NAT = round(sum_NAT, 9) + NATUSD2 = round(sum_NATUSD2, 9) + production = round(sum_production, 9) + productionUSD2 = round(sum_productionUSD2, 9) + zatratiMP = round(sum_zatratiMP, 9) + custom = round(sum_custom, 9) + customUSD2 = round(sum_customUSD2, 9) + skladHranenie = round(sum_skladHranenie, 9) + priemka = round(sum_Priemka, 9) + atsMarkirovka = round(sum_AtsMarkirovka, 9) + sborkaZakaza = round(sum_SborkaZakaza, 9) + dop_rashod = round(sum_DopRashod, 9) + dop_rashod_usd22 = round(sum_DopRashodUSD2, 9) + else: + dostavka = round(sum_dostavka / sum_quantity * sale_quantity, 9) + dostavkaUSD2 = round(sum_dostavkaUSD2 / sum_quantity * sale_quantity, 9) + NAT = round(sum_NAT / sum_quantity * sale_quantity, 9) + NATUSD2 = round(sum_NATUSD2 / sum_quantity * sale_quantity, 9) + production = round(sum_production / sum_quantity * sale_quantity, 9) + productionUSD2 = round(sum_productionUSD2 / sum_quantity * sale_quantity, 9) + zatratiMP = round(sum_zatratiMP / sum_quantity * sale_quantity, 9) + custom = round(sum_custom / sum_quantity * sale_quantity, 9) + customUSD2 = round(sum_customUSD2 / sum_quantity * sale_quantity, 9) + skladHranenie = round(sum_skladHranenie / sum_quantity * sale_quantity, 9) + priemka = round(sum_Priemka / sum_quantity * sale_quantity, 9) + atsMarkirovka = round(sum_AtsMarkirovka / sum_quantity * sale_quantity, 9) + sborkaZakaza = round(sum_SborkaZakaza / sum_quantity * sale_quantity, 9) + dop_rashod = round(sum_DopRashod / sum_quantity * sale_quantity, 9) + dop_rashod_usd22 = round(sum_DopRashodUSD2 / sum_quantity * sale_quantity, 9) + + + last_string_values = {'quantity': sale_quantity, 'sumZakupka': zakupkaRUB, 'sumZakupkaUSD2': zakupkaUSD2, + 'sum_dostavka': dostavka, + 'sum_NAT': NAT, 'sum_production': production, 'sum_zatratiMP': zatratiMP, + 'sum_custom': custom, 'sum_skladHranenie': skladHranenie, 'sum_Priemka': priemka, + 'sum_AtsMarkirovka': atsMarkirovka, 'sum_SborkaZakaza': sborkaZakaza, + 'sum_dostavkaUSD2': dostavkaUSD2, 'sum_NATUSD2': NATUSD2, 'sum_productionUSD2': productionUSD2, 'sum_customUSD2': customUSD2, + 'sum_DopRashod': dop_rashod, 'sum_DopRashodUSD2': dop_rashod_usd22} + + if zakupkaRUB != 0 or zakupkaUSD2 != 0 or NAT != 0 or production != 0 or dostavka != 0 or custom != 0: + uchet_stoimost = round((dostavka + NAT + zakupkaRUB + custom + production), 9) + uchet_stoimost_usd22 = round((dostavkaUSD2 + NATUSD2 + zakupkaUSD2 + customUSD2 + productionUSD2), 9) + uchet_price = round((dostavka + NAT + zakupkaRUB + custom + production) / sale_quantity, 9) + uchet_price_usd22 = round((dostavkaUSD2 + NATUSD2 + zakupkaUSD2 + customUSD2 + productionUSD2) / sale_quantity, 9) + + arr_sales.append( + (float(-zakupkaRUB), float(-zakupkaUSD2), float(-dostavka), float(-production), float(-NAT), float(-zatratiMP), float(-custom), + float(-skladHranenie), float(uchet_stoimost), + float(uchet_stoimost_usd22), float(uchet_price), float(uchet_price_usd22), utid, float(-priemka), float(-atsMarkirovka), float(-sborkaZakaza), + float(-dostavkaUSD2), float(-NATUSD2), float(-productionUSD2), float(-customUSD2), float(-dop_rashod), float(-dop_rashod_usd22), + id)) + + if str[13] == 'Производство товара': + arr_production.append((str[10], str[1], float(uchet_price), float(uchet_price_usd22))) + + + # break + + if ind % 10000 == 0: + print(time.ctime(), ' ', ind, 'проходов') + + if len(arr_price) > 0 and False: + insert_to_DB_UchetPrice(arr_price, connect) + + if len(arr_production) > 0 and manufacture: + insert_to_DB_Production(arr_production, connect) + + + if upload and manufacture == False: + if len(arr_sales) > 0: + print(time.ctime(), ' записей sales: ', len(arr_sales)) + update_to_DB_Sales(arr_sales, connect, '2022') + + if len(arr_sebes) > 0: + print(time.ctime(), ' записей sebest: ', len(arr_sebes)) + update_to_DB_sebest(arr_sebes, connect, '2022') + + + upload = False + + +def fill_table_sebestoim2022(connect, skip = False): + + if skip: + return + + + #флаг для обработки без заполнения таблиц ... + prepare_table = True + fill_AtsMarkirovka = True + fill_DopRashod = True + fill_Dostavka = True + fill_Zakupka = True + fill_ZatratiMp = False + fill_Pereschet = True + fill_PereschetSklad = True + fill_Priemka = True + fill_Prodaji = True + fill_Proizvodstvo = True + fill_Sborka = True + + if prepare_table: + print('Подготовка таблицы СебестоимостьОт2022 ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Подготовка таблицы СебестоимостьОт2022]') + + # заполним таблицы данными закупки ... + if fill_AtsMarkirovka: + print('Заполнение таблицы данными: АтсМаркировка ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(АтсМаркировка)]') + + if fill_DopRashod: + print('Заполнение таблицы данными: Доп расходы ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(ДопРасходы)]') + + if fill_Dostavka: + print('Заполнение таблицы данными: Доставка ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(Доставка)]') + + if fill_Zakupka: + print('Заполнение таблицы данными: Закупка ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(Закупка)]') + + if fill_ZatratiMp: + print('Заполнение таблицы данными: ЗатратыМП ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(ЗатратыМП)]') + + if fill_Pereschet: + print('Заполнение таблицы данными: Пересчет ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(Перерасчет)]') + + if fill_PereschetSklad: + print('Заполнение таблицы данными: Пересчет ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(ПерерасчетСкладскойКонтур)]') + + if fill_Priemka: + print('Заполнение таблицы данными: Приемка ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(Приемка)]') + + if fill_Prodaji: + print('Заполнение таблицы данными: Продажи ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(Продажи)]') + + if fill_Proizvodstvo: + print('Заполнение таблицы данными: Производство ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(Производство)]') + + if fill_Sborka: + print('Заполнение таблицы данными: Сборка ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(Сборка)]') + +def count_price(all_params, last_utid, conn): + arr_price = [] + uchet_price = 0 + uchet_price_usd22 = 0 + sale_quantity = 1 + sum_quantity = all_params['quantity'] + sum_zakupka = all_params['sumZakupka'] + sum_zakupkaUSD2 = all_params['sumZakupkaUSD2'] + sum_dostavka = all_params['sum_dostavka'] + sum_dostavkaUSD2 = all_params['sum_dostavkaUSD2'] + sum_NAT = all_params['sum_NAT'] + sum_NATUSD2 = all_params['sum_NATUSD2'] + sum_production = all_params['sum_production'] + sum_productionUSD2 = all_params['sum_productionUSD2'] + sum_custom = all_params['sum_custom'] + sum_customUSD2 = all_params['sum_customUSD2'] + + + if sale_quantity != 0: + + + if sale_quantity > sum_quantity or sum_quantity == 0: + zakupkaRUB = round(sum_zakupka, 9) + zakupkaUSD2 = round(sum_zakupkaUSD2, 9) + else: + zakupkaRUB = round(decimal.Decimal(sum_zakupka) / sum_quantity * sale_quantity, 9) + zakupkaUSD2 = round(decimal.Decimal(sum_zakupkaUSD2) / sum_quantity * sale_quantity, 9) + + + if sale_quantity > sum_quantity or sum_quantity == 0: + dostavka = round(sum_dostavka, 9) + dostavkaUSD2 = round(sum_dostavkaUSD2, 9) + NAT = round(sum_NAT, 9) + NATUSD2 = round(sum_NATUSD2, 9) + production = round(sum_production, 9) + productionUSD2 = round(sum_productionUSD2, 9) + custom = round(sum_custom, 9) + customUSD2 = round(sum_customUSD2, 9) + else: + dostavka = round(sum_dostavka / sum_quantity * sale_quantity, 9) + dostavkaUSD2 = round(sum_dostavkaUSD2 / sum_quantity * sale_quantity, 9) + NAT = round(sum_NAT / sum_quantity * sale_quantity, 9) + NATUSD2 = round(sum_NATUSD2 / sum_quantity * sale_quantity, 9) + production = round(sum_production / sum_quantity * sale_quantity, 9) + productionUSD2 = round(sum_productionUSD2 / sum_quantity * sale_quantity, 9) + custom = round(sum_custom / sum_quantity * sale_quantity, 9) + customUSD2 = round(sum_customUSD2 / sum_quantity * sale_quantity, 9) + + + + if zakupkaRUB != 0 or zakupkaUSD2 != 0 or NAT != 0 or production != 0 or dostavka != 0 or custom != 0: + uchet_price = round((dostavka + NAT + zakupkaRUB + custom + production) / sale_quantity, 9) + uchet_price_usd22 = round((dostavkaUSD2 + NATUSD2 + zakupkaUSD2 + customUSD2 + productionUSD2) / sale_quantity, 9) + + + return (last_utid, float(uchet_price), float(uchet_price_usd22)) + #arr_price.append((last_utid, float(uchet_price), float(uchet_price_usd22))) + #if len(arr_price) > 0: + # insert_to_DB_UchetPrice(arr_price, conn) + + + + + + + + +def insert_to_DB_UchetPrice(arr, conn): + try: + cursor = conn.cursor() + conn.autocommit = False + cursor.fast_executemany = True + table = '[pbiProd].[УчетнаяЦенаПоСебестоимости]' + + cursor.executemany(""" + INSERT INTO [mag_pbi].[pbiProd].[УчетнаяЦенаПоСебестоимости] + ( [Период], [artic_id], [Учетная цена], [Учетная цена USD2+2]) + VALUES (CONVERT(date, GETDATE()), ?, ?, ?); + """, arr) + + + except pyodbc.DatabaseError as err: + print('ошибка', err) + conn.rollback() + else: + conn.commit() + print(time.ctime(), 'обновлено', len(arr), ': записей') + finally: + conn.autocommit = True + + + + +union_sebes = True +print('start time', time.ctime()) +connect = sql_connect() +ComputeManufacture = True +maxLvl = 1 + +if ComputeManufacture: + maxLvl = 4 + exec_procedure(connect, '[pbiProd].[Подготовка Производство: единая процедура для подготовки]') + + + +for stRange in range(0, maxLvl): + # Заполнение таблицы + skip = False + fill_table_sebestoim2022(connect, skip) + + if True: + group = '[2k]' + max_counter = getMaxCounter(connect, group) + print('Группа: ', group, ' Всего групп - ', max_counter) + for counter in range(max_counter): + counter += 1 + count_sebest(connect, counter, group) + print(time.ctime(), ' группа ', counter, ' обработана') + + + # Расчитаем товары которые учавствуют в производстве + if ComputeManufacture: + start_range = 0 + for i in range(stRange, stRange + 1): + for i_range in range(2000, 20000, 2000): + end_range = i_range + count_sebest(connect, "", "", i, True, start_range, end_range) + start_range = i_range + + # Нужно добавить 1с_id в таблицу .... + exec_procedure(connect, '[pbiProd].[Производство: Заполнить 1сid для СебестоимостьПроизводствоОт2022]') + + +# заполним сводную таблицу (финальную) для загрузки в пби ... +if union_sebes: + print('Объединение в сводную таблицу ~ 10 мин ...') + exec_procedure(connect, '[pbiProd].[ЗаполнитьСебестоимостьСводныйОт2022]') + + +connect.close() +print('end time ', time.ctime()) diff --git a/analytics/python skript/CostCalculationFrom2022_1_5.bat b/analytics/python skript/CostCalculationFrom2022_1_5.bat new file mode 100644 index 0000000..0d8e173 --- /dev/null +++ b/analytics/python skript/CostCalculationFrom2022_1_5.bat @@ -0,0 +1,2 @@ +"C:\Users\administrator\AppData\Local\Programs\Python\Python312\python.exe" "F:\python skript\CostCalculationFrom2022_1_5.py" +exit \ No newline at end of file diff --git a/analytics/python skript/CostCalculationFrom2022_1_5.py b/analytics/python skript/CostCalculationFrom2022_1_5.py new file mode 100644 index 0000000..d0328fd --- /dev/null +++ b/analytics/python skript/CostCalculationFrom2022_1_5.py @@ -0,0 +1,887 @@ +import decimal +import time +import numpy as np +import pyodbc + + +def sql_connect(): + server = 'prdsql.mag-fur.ru' + #server = 'cloud.magok.ru' + database = 'mag_pbi' + username = 'goglev' + password = 'BOMoGbUZ1p' + connection_string = f'DRIVER={{ODBC Driver 17 for SQL Server}};SERVER={server};DATABASE={database};UID={username};PWD={password}' + + conn = pyodbc.connect(connection_string) + print("successfully connected...") + print("#" * 20) + return conn + + +def get_totals(conn, counter, group): + sql_query = """ + SELECT --TOP (1000) + id, -- 0 + artic_id, -- 1 + COALESCE([Количество], 0) AS [Количество], -- 2 + COALESCE([ЗатратыМП], 0) AS ЗатратыМП, -- 3 + COALESCE([Закупка], 0) AS [Закупка], -- 4 + COALESCE([Доставка], 0) AS [Доставка], -- 5 + COALESCE([НДС], 0) AS [НДС], -- 6 + COALESCE([Производство], 0) AS [Производство], -- 7 + COALESCE([Таможня], 0) AS [Таможня], -- 8 + [Курс usd2] AS [Курс usd2], -- 9 + [Период] AS [Период], -- 10 + [Валюта документа] AS [Валюта документа], -- 11 + [Вид операции] AS [Вид операции], -- 12 + [Статья] AS [Статья], -- 13 + COALESCE([ЗатратыСкладХранение], 0) AS [ЗатратыСкладХранение], -- 14 + COALESCE([Приемка], 0) AS [Приемка], -- 15 + COALESCE([АтсМаркировка], 0) AS [АтсМаркировка], -- 16 + COALESCE([СборкаЗаказа], 0) AS [СборкаЗаказа], -- 17 + COALESCE([Закупка, usd2], 0) AS [Закупка, usd2], -- 18 + COALESCE([Доставка USD2+2], 0) AS [Доставка USD2+2], -- 19 + COALESCE([НДС USD2+2], 0) AS [НДС USD2+2], -- 20 + COALESCE([Таможня USD2+2], 0) AS [Таможня USD2+2], -- 21 + COALESCE([Производство USD2+2], 0) AS [Производство USD2+2] -- 22 + FROM + ( + SELECT + id, + artic_id, + COALESCE([Количество], 0) AS [Количество], + [ЗатратыМП], + COALESCE([Закупка], 0) AS [Закупка], + COALESCE([Доставка], 0) AS [Доставка], + [НДС], + COALESCE([Производство], 0) AS [Производство], + COALESCE([Таможня], 0) AS [Таможня], + [Курс usd2], + [Период], + [Валюта документа], + [Вид операции], + [Статья], + [ЗатратыСкладХранение], + [Приемка], + [АтсМаркировка], + [СборкаЗаказа], + COALESCE([Закупка, usd2], 0) AS [Закупка, usd2], + COALESCE([Доставка USD2+2], 0) AS [Доставка USD2+2], + COALESCE([НДС USD2+2], 0) AS [НДС USD2+2], + COALESCE([Таможня USD2+2], 0) AS [Таможня USD2+2], + COALESCE([Производство USD2+2], 0) AS [Производство USD2+2] + FROM [mag_pbi].[pbiProd].[СебестоимостьОт2022] + WHERE + 1=1 + --and [artic_id] = '24d0c24b-3a60-11e9-ae9c-b496910dcfd6' + and [artic_id] IN (SELECT + [artic_id] + FROM [mag_pbi].[pbiProd].[GroupsOfNomenclature] + where """ + group + """ = """ + str(counter) + """) + and [Период] >= '2022' + + + UNION ALL + + SELECT + id, + artic_id, + COALESCE([Количество], 0), + [ЗатратыМП], + COALESCE([Закупка], 0), + COALESCE([Доставка], 0), + [НДС], + COALESCE([Сборка], 0), + COALESCE([Таможня], 0), + 0, + '2021', + NULL, + 'Приход', + 'Ввод остатков до 22', + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + FROM [mag_pbi].[pbiProd].[СебестоимостьИтогиДо2022] + where + 1 = 1 + --and [artic_id] = '24d0c24b-3a60-11e9-ae9c-b496910dcfd6' + and [artic_id] IN (SELECT + [artic_id] + FROM [mag_pbi].[pbiProd].[GroupsOfNomenclature] + where """ + group + """ = """ + str(counter) + """) + ) AS tabMain + --WHERE 1=1 + + ORDER BY + [artic_id], [Период] ASC, [Закупка] DESC; + """ + cursor = conn.cursor() + cursor.execute(sql_query) + pbi_totals = cursor.fetchall() + print(time.ctime(), ' Записей к обработке: ', len(pbi_totals)) + return pbi_totals + + + +def get_totalsManufacture(conn, manufactureLevel, start_range, end_range): + sql_query = """ + SELECT --TOP (1000) + id, -- 0 + artic_id, -- 1 + COALESCE([Количество], 0) AS [Количество], -- 2 + COALESCE([ЗатратыМП], 0) AS ЗатратыМП, -- 3 + COALESCE([Закупка], 0) AS [Закупка], -- 4 + COALESCE([Доставка], 0) AS [Доставка], -- 5 + COALESCE([НДС], 0) AS [НДС], -- 6 + COALESCE([Производство], 0) AS [Производство], -- 7 + COALESCE([Таможня], 0) AS [Таможня], -- 8 + [Курс usd2] AS [Курс usd2], -- 9 + [Период] AS [Период], -- 10 + [Валюта документа] AS [Валюта документа], -- 11 + [Вид операции] AS [Вид операции], -- 12 + [Статья] AS [Статья], -- 13 + COALESCE([ЗатратыСкладХранение], 0) AS [ЗатратыСкладХранение], -- 14 + COALESCE([Приемка], 0) AS [Приемка], -- 15 + COALESCE([АтсМаркировка], 0) AS [АтсМаркировка], -- 16 + COALESCE([СборкаЗаказа], 0) AS [СборкаЗаказа], -- 17 + COALESCE([Закупка, usd2], 0) AS [Закупка, usd2], -- 18 + COALESCE([Доставка USD2+2], 0) AS [Доставка USD2+2], -- 19 + COALESCE([НДС USD2+2], 0) AS [НДС USD2+2], -- 20 + COALESCE([Таможня USD2+2], 0) AS [Таможня USD2+2], -- 21 + COALESCE([Производство USD2+2], 0) AS [Производство USD2+2] -- 22 + FROM + ( + SELECT + id, + artic_id, + COALESCE([Количество], 0) AS [Количество], + [ЗатратыМП], + COALESCE([Закупка], 0) AS [Закупка], + COALESCE([Доставка], 0) AS [Доставка], + [НДС], + COALESCE([Производство], 0) AS [Производство], + COALESCE([Таможня], 0) AS [Таможня], + [Курс usd2], + [Период], + [Валюта документа], + [Вид операции], + [Статья], + [ЗатратыСкладХранение], + [Приемка], + [АтсМаркировка], + [СборкаЗаказа], + COALESCE([Закупка, usd2], 0) AS [Закупка, usd2], + COALESCE([Доставка USD2+2], 0) AS [Доставка USD2+2], + COALESCE([НДС USD2+2], 0) AS [НДС USD2+2], + COALESCE([Таможня USD2+2], 0) AS [Таможня USD2+2], + COALESCE([Производство USD2+2], 0) AS [Производство USD2+2] + FROM [mag_pbi].[pbiProd].[СебестоимостьОт2022] + WHERE + 1=1 + --and [artic_id] = '24d0c24b-3a60-11e9-ae9c-b496910dcfd6' + and [1c_id] IN (SELECT + [1c_id] + FROM [mag_pbi].[pbiProd].[НоменклатураВПроизводствеПоУровням] + where [УровеньПроизводства] = """ + str(manufactureLevel) + """ + and [RowNum] BETWEEN """ + str(start_range) + """ AND """ + str(end_range) + """ + --and [1c_id] = 0x9981B49691D57EFD11EDDE7DA97A5E64 + ) + and [Период] >= '2022' + + + UNION ALL + + SELECT + id, + artic_id, + COALESCE([Количество], 0), + [ЗатратыМП], + COALESCE([Закупка], 0), + COALESCE([Доставка], 0), + [НДС], + COALESCE([Сборка], 0), + COALESCE([Таможня], 0), + 0, + '2021', + NULL, + 'Приход', + 'Ввод остатков до 22', + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + FROM [mag_pbi].[pbiProd].[СебестоимостьИтогиДо2022] + where + 1 = 1 + --and [artic_id] = '24d0c24b-3a60-11e9-ae9c-b496910dcfd6' + and [1c_id] IN (SELECT + [1c_id] + FROM [mag_pbi].[pbiProd].[НоменклатураВПроизводствеПоУровням] + where [УровеньПроизводства] = """ + str(manufactureLevel) + """ + and [RowNum] BETWEEN """ + str(start_range) + """ AND """ + str(end_range) + """ + --and [1c_id] = 0x9981B49691D57EFD11EDDE7DA97A5E64 + ) + ) AS tabMain + --WHERE 1=1 + + ORDER BY + [artic_id], [Период] ASC, [Закупка] DESC; + """ + cursor = conn.cursor() + cursor.execute(sql_query) + pbi_totals = cursor.fetchall() + print(time.ctime(), ' Записей к обработке: ', len(pbi_totals)) + return pbi_totals + +def find_sumof_total(sebes_sales, date, current_sales_id, current_params, last_string_values): + quantity = current_params['quantity'] + sumZakupka = current_params['sumZakupka'] + sumZakupkaUSD2 = current_params['sumZakupkaUSD2'] + sum_dostavka = current_params['sum_dostavka'] + sum_dostavkaUSD2 = current_params['sum_dostavkaUSD2'] + sum_NAT = current_params['sum_NAT'] + sum_NATUSD2 = current_params['sum_NATUSD2'] + sum_production = current_params['sum_production'] + sum_productionUSD2 = current_params['sum_productionUSD2'] + sum_zatratiMP = current_params['sum_zatratiMP'] + sum_custom = current_params['sum_custom'] + sum_customUSD2 = current_params['sum_customUSD2'] + sum_skladHranenie = current_params['sum_skladHranenie'] + sum_Priemka = current_params['sum_Priemka'] + sum_AtsMarkirovka = current_params['sum_AtsMarkirovka'] + sum_SborkaZakaza = current_params['sum_SborkaZakaza'] + i = current_params['counter'] + len_sebes_sales = len(sebes_sales) + while i < len_sebes_sales: + try: + curr_str = sebes_sales[i] + except: + print('Ошибка в иттераторе, тек ид =', current_sales_id) + print(i) + print(len_sebes_sales) + break + + if curr_str[10] > date or current_sales_id != curr_str[0]: + break + else: + i += 1 + + if curr_str[12] == 'Приход': + + if curr_str[13] == 'Закупка' or curr_str[13] == 'Ввод остатков до 22' or curr_str[13] == 'Производство товара': + quantity += curr_str[2] + + + if curr_str[9] > 0: + usd2_course = curr_str[9] + else: + if curr_str[13] == 'Ввод остатков до 22': + # для ввода остатков возьём курс на 1 января 2023 года + usd2_course = 75.7785 + else: + usd2_course = 1 + + sumZakupka += curr_str[4] + if curr_str[13] == 'Ввод остатков до 22': + sumZakupkaUSD2 += decimal.Decimal(float(sumZakupka) / usd2_course) + else: + sumZakupkaUSD2 += curr_str[18] + + + #if curr_str[11] == 'руб.': + # sumZakupkaUSD += sumZakupka / usd2_course + + sum_dostavka += curr_str[5] + sum_dostavkaUSD2 += curr_str[19] + sum_NAT += curr_str[6] + sum_NATUSD2 += curr_str[20] + sum_production += curr_str[7] + sum_productionUSD2 += curr_str[22] + sum_zatratiMP += curr_str[3] + sum_custom += curr_str[8] + sum_customUSD2 += curr_str[21] + sum_skladHranenie += curr_str[14] + sum_Priemka += curr_str[15] + sum_AtsMarkirovka += curr_str[16] + sum_SborkaZakaza += curr_str[17] + + if curr_str[12] == 'Расход': + quantity -= last_string_values['quantity'] + sumZakupka -= last_string_values['sumZakupka'] + sumZakupkaUSD2 -= last_string_values['sumZakupkaUSD2'] + sum_dostavka -= last_string_values['sum_dostavka'] + sum_dostavkaUSD2 -= last_string_values['sum_dostavkaUSD2'] + sum_NAT -= last_string_values['sum_NAT'] + sum_NATUSD2 -= last_string_values['sum_NATUSD2'] + sum_production -= last_string_values['sum_production'] + sum_productionUSD2 -= last_string_values['sum_productionUSD2'] + sum_zatratiMP -= last_string_values['sum_zatratiMP'] + sum_custom -= last_string_values['sum_custom'] + sum_customUSD2 -= last_string_values['sum_customUSD2'] + sum_skladHranenie -= last_string_values['sum_skladHranenie'] + sum_Priemka -= last_string_values['sum_Priemka'] + sum_AtsMarkirovka -= last_string_values['sum_AtsMarkirovka'] + sum_SborkaZakaza -= last_string_values['sum_SborkaZakaza'] + + if quantity <= 0: + quantity = 0 + sumZakupka = 0 + sumZakupkaUSD2 = 0 + sum_dostavka = 0 + sum_NAT = 0 + sum_production = 0 + sum_zatratiMP = 0 + sum_custom = 0 + sum_skladHranenie = 0 + sum_Priemka = 0 + sum_AtsMarkirovka = 0 + sum_SborkaZakaza = 0 + sum_dostavkaUSD2 = 0 + sum_NATUSD2 = 0 + sum_productionUSD2 = 0 + sum_customUSD2 = 0 + + + return {'quantity': quantity, 'sumZakupka': sumZakupka, 'sumZakupkaUSD2': sumZakupkaUSD2, + 'sum_dostavka': sum_dostavka, + 'sum_NAT': sum_NAT, 'sum_production': sum_production, 'sum_zatratiMP': sum_zatratiMP, 'sum_custom': sum_custom, + 'sum_skladHranenie': sum_skladHranenie, 'sum_Priemka': sum_Priemka, 'sum_AtsMarkirovka': sum_AtsMarkirovka, 'sum_SborkaZakaza': sum_SborkaZakaza, + 'sum_dostavkaUSD2': sum_dostavkaUSD2, 'sum_NATUSD2': sum_NATUSD2, 'sum_productionUSD2': sum_productionUSD2, 'sum_customUSD2': sum_customUSD2, + 'counter': i} + + +def insert_to_DB_Production(arr, conn): + try: + cursor = conn.cursor() + conn.autocommit = False + cursor.fast_executemany = True + table = '[СебестоимостьПроизводствоОт2022]' + + cursor.executemany(""" + INSERT INTO [mag_pbi].[pbiProd].[СебестоимостьПроизводствоОт2022] + ([Период], [artic_id], [Учетная цена], [Учетная цена USD2+2]) + VALUES (?, ?, ?, ?); + """, arr) + + + except pyodbc.DatabaseError as err: + print('ошибка', err) + conn.rollback() + else: + conn.commit() + print(time.ctime(), 'обновлено', len(arr), ': записей') + finally: + conn.autocommit = True + +def update_to_DB_Sales(arr, conn, year): + try: + cursor = conn.cursor() + conn.autocommit = False + cursor.fast_executemany = True + table = '[СебестоимостьОт2022]' + if year == '2022': + table = '[СебестоимостьОт2022]' + elif year == '2023': + table = '[Себестоимость2023]' + elif year == '2024': + table = '[Себестоимость2024]' + + cursor.executemany( + """UPDATE [mag_pbi].[pbiProd].""" + table + """ + SET + [Закупка] = ? -- 0 + , [Закупка, usd2] = ? -- 1 + , [Доставка] = ? -- 2 + , [Производство] = ? -- 3 + , [НДС] = ? -- 4 + , [ЗатратыМП] = ? -- 5 + , [Таможня] = ? -- 6 + , [ЗатратыСкладХранение] = ? -- 7 + , [Учетная стоимость] = ? -- 8 + , [Учетная стоимость USD2+2] = ? -- 9 + , [Учетная цена] = ? -- 10 + , [Учетная цена USD2+2] = ? -- 11 + , [artic_id] = ? -- 12 + , [Приемка] = ? -- 13 + , [АтсМаркировка] = ? -- 14 + , [СборкаЗаказа] = ? -- 15 + , [Доставка USD2+2] = ? -- 16 + , [НДС USD2+2] = ? -- 17 + , [Таможня USD2+2] = ? -- 18 + , [Производство USD2+2] = ? -- 19 + WHERE id = ?""", + arr) + + + except pyodbc.DatabaseError as err: + print('ошибка', err) + conn.rollback() + else: + conn.commit() + print(time.ctime(), 'обновлено', len(arr), ': записей') + finally: + conn.autocommit = True + + +def update_to_DB_sebest(arr, conn, year): + try: + cursor = conn.cursor() + conn.autocommit = False + cursor.fast_executemany = True + table = '[СебестоимостьОт2022]' + if year == '2022': + table = '[СебестоимостьОт2022]' + elif year == '2023': + table = '[Себестоимость2023]' + elif year == '2024': + table = '[Себестоимость2024]' + cursor.executemany( + "UPDATE [mag_pbi].[pbiProd]." + table + " SET [Учетная стоимость] = ?, [Учетная стоимость USD2+2] = ?, [Учетная цена] = ?, [Учетная цена USD2+2] = ? WHERE id = ?", + arr) + + + except pyodbc.DatabaseError as err: + print('ошибка', err) + conn.rollback() + else: + conn.commit() + print(time.ctime(), 'обновлено', len(arr), ': записей') + finally: + conn.autocommit = True + + +def exec_procedure(conn, procedure_name): + sql_query = 'EXEC ' + procedure_name + cursor = conn.cursor() + cursor.execute(sql_query).commit() + + +def getMaxCounter(conn, group): + sql_query = "SELECT MAX(" + group + ") FROM [mag_pbi].[pbiProd].[GroupsOfNomenclature]" + + cursor = conn.cursor() + cursor.execute(sql_query) + maxCounter = cursor.fetchall() + return maxCounter[0][0] + + + +def count_sebest(connect, counter = '2k', group = '1', manufactureLevel = 0, manufacture = False, start_range = 0, end_range = 0): + upload = True + ind = 0 + arr_sebes = [] + arr_sales = [] + arr_production = [] + arr_price = [] + last_utid = '' + last_operation = '' + last_state = '' + + if manufacture: + pbi_all = get_totalsManufacture(connect, manufactureLevel, start_range, end_range) + else: + pbi_all = get_totals(connect, counter, group) + + + nparr_all = np.asarray(pbi_all) + + for str in pbi_all: + ind += 1 + date = str[10] + utid = str[1] + id = str[0] + tableGod = str[14] + zakupkaRUB = round(0, 9) + zakupkaUSD2 = round(0, 9) + NAT = round(0, 9) + NATUSD2 = round(0, 9) + zatratiMP = round(0, 9) + production = round(0, 9) + dostavka = round(0, 9) + dostavkaUSD2 = round(0, 9) + custom = round(0, 9) + customUSD2 = round(0, 9) + skladHranenie = round(0, 9) + priemka = round(0, 9) + atsMarkirovka = round(0, 9) + sborkaZakaza = round(0, 9) + + + if utid != last_utid: + ## если последняя операция не Реализация Расход, то сделаем фейковую продажу чтобы посчитать цену на сегодня ... + if last_operation != 'Расход' and last_state != 'Реализация' and last_operation != '' and False: + arr_price.append(count_price(all_params, last_utid, connect)) + + + fltr = np.asarray([utid]) + pbi_all_current_utid = nparr_all[np.in1d(nparr_all[:, 1], fltr)] + last_utid = utid + current_params = {'quantity': 0, 'sumZakupka': 0, 'sumZakupkaUSD2': 0, + 'sum_dostavka': 0, 'sum_NAT': 0, 'sum_production': 0, 'sum_zatratiMP': 0, 'sum_custom': 0, 'sum_skladHranenie': 0, 'sum_Priemka': 0, + 'sum_AtsMarkirovka': 0, 'sum_SborkaZakaza': 0, 'sum_dostavkaUSD2': 0, 'sum_NATUSD2': 0, 'sum_productionUSD2': 0, 'sum_customUSD2': 0, + 'sum_zakupkaUSD2': 0, + 'counter': 0} + last_string_values = {'quantity': 0, 'sumZakupka': 0, 'sumZakupkaUSD2': 0, + 'sum_dostavka': 0, 'sum_NAT': 0, 'sum_production': 0, 'sum_zatratiMP': 0, 'sum_custom': 0, 'sum_skladHranenie': 0, 'sum_Priemka': 0, + 'sum_AtsMarkirovka': 0, 'sum_SborkaZakaza': 0, 'sum_dostavkaUSD2': 0, 'sum_NATUSD2': 0, 'sum_productionUSD2': 0, 'sum_customUSD2': 0, + 'sum_zakupkaUSD2': 0} + + all_params = find_sumof_total(pbi_all_current_utid, date, str[0], current_params, last_string_values) + current_params = all_params.copy() + + + last_operation = str[12] + last_state = str[13] + sale_quantity = str[2] + + if str[9] > 0: + usd2_course = str[9] + else: + usd2_course = 1 + + sum_quantity = all_params['quantity'] + sum_zakupka = all_params['sumZakupka'] + sum_zakupkaUSD2 = all_params['sumZakupkaUSD2'] + sum_dostavka = all_params['sum_dostavka'] + sum_dostavkaUSD2 = all_params['sum_dostavkaUSD2'] + sum_NAT = all_params['sum_NAT'] + sum_NATUSD2 = all_params['sum_NATUSD2'] + sum_production = all_params['sum_production'] + sum_productionUSD2 = all_params['sum_productionUSD2'] + sum_zatratiMP = all_params['sum_zatratiMP'] + sum_custom = all_params['sum_custom'] + sum_customUSD2 = all_params['sum_customUSD2'] + sum_skladHranenie = all_params['sum_skladHranenie'] + sum_Priemka = all_params['sum_Priemka'] + sum_AtsMarkirovka = all_params['sum_AtsMarkirovka'] + sum_SborkaZakaza = all_params['sum_SborkaZakaza'] + + + if (str[12] == 'Приход') and str[13] != 'Ввод остатков до 22': + + uchet_price = 0 + uchet_price_usd22 = 0 + uchet_stoimost = 0 + uchet_stoimost_usd22 = 0 + + zakupkaRUB = round(sum_zakupka, 9) + zakupkaUSD2 = round(sum_zakupkaUSD2, 9) + + + if sum_quantity != 0: + dostavka = round(sum_dostavka, 9) + dostavkaUSD2 = round(sum_dostavkaUSD2, 9) + NAT = round(sum_NAT, 9) + NATUSD2 = round(sum_NATUSD2, 9) + production = round(sum_production, 9) + productionUSD2 = round(sum_productionUSD2, 9) + zatratiMP = round(sum_zatratiMP, 9) + custom = round(sum_custom, 9) + customUSD2 = round(sum_customUSD2, 9) + skladHranenie = round(sum_skladHranenie, 9) + priemka = round(sum_Priemka, 9) + atsMarkirovka = round(sum_AtsMarkirovka, 9) + sborkaZakaza = round(sum_SborkaZakaza, 9) + + uchet_price = round((dostavka + NAT + zakupkaRUB + custom + production) / sum_quantity, 9) + uchet_price_usd22 = round((dostavkaUSD2 + NATUSD2 + zakupkaUSD2 + customUSD2 + productionUSD2) / sum_quantity, 9) + + if sale_quantity != 0: + uchet_stoimost = round(uchet_price * sale_quantity, 9) + uchet_stoimost_usd22 = round(uchet_price_usd22 * sale_quantity, 9) + + + arr_sebes.append((uchet_stoimost, uchet_stoimost_usd22, uchet_price, uchet_price_usd22, id)) + + + elif str[12] == 'Расход': + + if sale_quantity != 0: + + if sum_zakupka < 0: + sum_zakupka = 0 + + if sale_quantity > sum_quantity or sum_quantity == 0: + zakupkaRUB = round(sum_zakupka, 9) + zakupkaUSD2 = round(sum_zakupkaUSD2, 9) + else: + zakupkaRUB = round(decimal.Decimal(sum_zakupka) / sum_quantity * sale_quantity, 9) + zakupkaUSD2 = round(decimal.Decimal(sum_zakupkaUSD2) / sum_quantity * sale_quantity, 9) + + #zakupkaUSD2 = round(sum_zakupkaUSD2 / usd2_course, 15) + + if sale_quantity > sum_quantity or sum_quantity == 0: + dostavka = round(sum_dostavka, 9) + dostavkaUSD2 = round(sum_dostavkaUSD2, 9) + NAT = round(sum_NAT, 9) + NATUSD2 = round(sum_NATUSD2, 9) + production = round(sum_production, 9) + productionUSD2 = round(sum_productionUSD2, 9) + zatratiMP = round(sum_zatratiMP, 9) + custom = round(sum_custom, 9) + customUSD2 = round(sum_customUSD2, 9) + skladHranenie = round(sum_skladHranenie, 9) + priemka = round(sum_Priemka, 9) + atsMarkirovka = round(sum_AtsMarkirovka, 9) + sborkaZakaza = round(sum_SborkaZakaza, 9) + else: + dostavka = round(sum_dostavka / sum_quantity * sale_quantity, 9) + dostavkaUSD2 = round(sum_dostavkaUSD2 / sum_quantity * sale_quantity, 9) + NAT = round(sum_NAT / sum_quantity * sale_quantity, 9) + NATUSD2 = round(sum_NATUSD2 / sum_quantity * sale_quantity, 9) + production = round(sum_production / sum_quantity * sale_quantity, 9) + productionUSD2 = round(sum_productionUSD2 / sum_quantity * sale_quantity, 9) + zatratiMP = round(sum_zatratiMP / sum_quantity * sale_quantity, 9) + custom = round(sum_custom / sum_quantity * sale_quantity, 9) + customUSD2 = round(sum_customUSD2 / sum_quantity * sale_quantity, 9) + skladHranenie = round(sum_skladHranenie / sum_quantity * sale_quantity, 9) + priemka = round(sum_Priemka / sum_quantity * sale_quantity, 9) + atsMarkirovka = round(sum_AtsMarkirovka / sum_quantity * sale_quantity, 9) + sborkaZakaza = round(sum_SborkaZakaza / sum_quantity * sale_quantity, 9) + + + last_string_values = {'quantity': sale_quantity, 'sumZakupka': zakupkaRUB, 'sumZakupkaUSD2': zakupkaUSD2, + 'sum_dostavka': dostavka, + 'sum_NAT': NAT, 'sum_production': production, 'sum_zatratiMP': zatratiMP, + 'sum_custom': custom, 'sum_skladHranenie': skladHranenie, 'sum_Priemka': priemka, + 'sum_AtsMarkirovka': atsMarkirovka, 'sum_SborkaZakaza': sborkaZakaza, + 'sum_dostavkaUSD2': dostavkaUSD2, 'sum_NATUSD2': NATUSD2, 'sum_productionUSD2': productionUSD2, 'sum_customUSD2': customUSD2} + + if zakupkaRUB != 0 or zakupkaUSD2 != 0 or NAT != 0 or production != 0 or dostavka != 0 or custom != 0: + uchet_stoimost = round((dostavka + NAT + zakupkaRUB + custom + production), 9) + uchet_stoimost_usd22 = round((dostavkaUSD2 + NATUSD2 + zakupkaUSD2 + customUSD2 + productionUSD2), 9) + uchet_price = round((dostavka + NAT + zakupkaRUB + custom + production) / sale_quantity, 9) + uchet_price_usd22 = round((dostavkaUSD2 + NATUSD2 + zakupkaUSD2 + customUSD2 + productionUSD2) / sale_quantity, 9) + + arr_sales.append( + (float(-zakupkaRUB), float(-zakupkaUSD2), float(-dostavka), float(-production), float(-NAT), float(-zatratiMP), float(-custom), + float(-skladHranenie), float(uchet_stoimost), + float(uchet_stoimost_usd22), float(uchet_price), float(uchet_price_usd22), utid, float(-priemka), float(-atsMarkirovka), float(-sborkaZakaza), + float(-dostavkaUSD2), float(-NATUSD2), float(-productionUSD2), float(-customUSD2), + id)) + + if str[13] == 'Производство товара': + arr_production.append((str[10], str[1], float(uchet_price), float(uchet_price_usd22))) + + + # break + + if ind % 10000 == 0: + print(time.ctime(), ' ', ind, 'проходов') + + if len(arr_price) > 0 and False: + insert_to_DB_UchetPrice(arr_price, connect) + + if len(arr_production) > 0 and manufacture: + insert_to_DB_Production(arr_production, connect) + + + if upload and manufacture == False: + if len(arr_sales) > 0: + print(time.ctime(), ' записей sales: ', len(arr_sales)) + update_to_DB_Sales(arr_sales, connect, '2022') + + if len(arr_sebes) > 0: + print(time.ctime(), ' записей sebest: ', len(arr_sebes)) + update_to_DB_sebest(arr_sebes, connect, '2022') + + + upload = False + + +def fill_table_sebestoim2022(connect, skip = False): + + if skip: + return + + + #флаг для обработки без заполнения таблиц ... + prepare_table = True + fill_AtsMarkirovka = True + fill_Dostavka = True + fill_Zakupka = True + fill_ZatratiMp = False + fill_Priemka = True + fill_Prodaji = True + fill_Proizvodstvo = True + fill_Sborka = True + + if prepare_table: + print('Подготовка таблицы СебестоимостьОт2022 ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Подготовка таблицы СебестоимостьОт2022]') + + # заполним таблицы данными закупки ... + if fill_AtsMarkirovka: + print('Заполнение таблицы данными: АтсМаркировка ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(АтсМаркировка)]') + + if fill_Dostavka: + print('Заполнение таблицы данными: Доставка ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(Доставка)]') + + if fill_Zakupka: + print('Заполнение таблицы данными: Закупка ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(Закупка)]') + + if fill_ZatratiMp: + print('Заполнение таблицы данными: ЗатратыМП ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(ЗатратыМП)]') + + if fill_Priemka: + print('Заполнение таблицы данными: Приемка ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(Приемка)]') + + if fill_Prodaji: + print('Заполнение таблицы данными: Продажи ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(Продажи)]') + + if fill_Proizvodstvo: + print('Заполнение таблицы данными: Производство ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(Производство)]') + + if fill_Sborka: + print('Заполнение таблицы данными: Сборка ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(Сборка)]') + +def count_price(all_params, last_utid, conn): + arr_price = [] + uchet_price = 0 + uchet_price_usd22 = 0 + sale_quantity = 1 + sum_quantity = all_params['quantity'] + sum_zakupka = all_params['sumZakupka'] + sum_zakupkaUSD2 = all_params['sumZakupkaUSD2'] + sum_dostavka = all_params['sum_dostavka'] + sum_dostavkaUSD2 = all_params['sum_dostavkaUSD2'] + sum_NAT = all_params['sum_NAT'] + sum_NATUSD2 = all_params['sum_NATUSD2'] + sum_production = all_params['sum_production'] + sum_productionUSD2 = all_params['sum_productionUSD2'] + sum_custom = all_params['sum_custom'] + sum_customUSD2 = all_params['sum_customUSD2'] + + + if sale_quantity != 0: + + + if sale_quantity > sum_quantity or sum_quantity == 0: + zakupkaRUB = round(sum_zakupka, 9) + zakupkaUSD2 = round(sum_zakupkaUSD2, 9) + else: + zakupkaRUB = round(decimal.Decimal(sum_zakupka) / sum_quantity * sale_quantity, 9) + zakupkaUSD2 = round(decimal.Decimal(sum_zakupkaUSD2) / sum_quantity * sale_quantity, 9) + + + if sale_quantity > sum_quantity or sum_quantity == 0: + dostavka = round(sum_dostavka, 9) + dostavkaUSD2 = round(sum_dostavkaUSD2, 9) + NAT = round(sum_NAT, 9) + NATUSD2 = round(sum_NATUSD2, 9) + production = round(sum_production, 9) + productionUSD2 = round(sum_productionUSD2, 9) + custom = round(sum_custom, 9) + customUSD2 = round(sum_customUSD2, 9) + else: + dostavka = round(sum_dostavka / sum_quantity * sale_quantity, 9) + dostavkaUSD2 = round(sum_dostavkaUSD2 / sum_quantity * sale_quantity, 9) + NAT = round(sum_NAT / sum_quantity * sale_quantity, 9) + NATUSD2 = round(sum_NATUSD2 / sum_quantity * sale_quantity, 9) + production = round(sum_production / sum_quantity * sale_quantity, 9) + productionUSD2 = round(sum_productionUSD2 / sum_quantity * sale_quantity, 9) + custom = round(sum_custom / sum_quantity * sale_quantity, 9) + customUSD2 = round(sum_customUSD2 / sum_quantity * sale_quantity, 9) + + + + if zakupkaRUB != 0 or zakupkaUSD2 != 0 or NAT != 0 or production != 0 or dostavka != 0 or custom != 0: + uchet_price = round((dostavka + NAT + zakupkaRUB + custom + production) / sale_quantity, 9) + uchet_price_usd22 = round((dostavkaUSD2 + NATUSD2 + zakupkaUSD2 + customUSD2 + productionUSD2) / sale_quantity, 9) + + + return (last_utid, float(uchet_price), float(uchet_price_usd22)) + #arr_price.append((last_utid, float(uchet_price), float(uchet_price_usd22))) + #if len(arr_price) > 0: + # insert_to_DB_UchetPrice(arr_price, conn) + + + + + + + + +def insert_to_DB_UchetPrice(arr, conn): + try: + cursor = conn.cursor() + conn.autocommit = False + cursor.fast_executemany = True + table = '[pbiProd].[УчетнаяЦенаПоСебестоимости]' + + cursor.executemany(""" + INSERT INTO [mag_pbi].[pbiProd].[УчетнаяЦенаПоСебестоимости] + ( [Период], [artic_id], [Учетная цена], [Учетная цена USD2+2]) + VALUES (CONVERT(date, GETDATE()), ?, ?, ?); + """, arr) + + + except pyodbc.DatabaseError as err: + print('ошибка', err) + conn.rollback() + else: + conn.commit() + print(time.ctime(), 'обновлено', len(arr), ': записей') + finally: + conn.autocommit = True + + + +union_sebes = True +print('start time', time.ctime()) +connect = sql_connect() + +for stRange in range(0, 1): + # Заполнение таблицы себестоимостьОт2022 + fill_table_sebestoim2022(connect, False) + + if True: + group = '[2k]' + max_counter = getMaxCounter(connect, group) + print('Группа: ', group, ' Всего групп - ', max_counter) + for counter in range(max_counter): + counter += 1 + count_sebest(connect, counter, group) + print(time.ctime(), ' группа ', counter, ' обработана') + + + # Расчитаем товары которые учавствуют в производстве + if False: + start_range = 0 + for i in range(stRange, stRange + 1): + for i_range in range(2000, 15000, 2000): + end_range = i_range + count_sebest(connect, "", "", i, True, start_range, end_range) + start_range = i_range + + # Нужно добавить 1с_id в таблицу .... + exec_procedure(connect, '[pbiProd].[Производство: Заполнить 1сid для СебестоимостьПроизводствоОт2022]') + + +# заполним сводную таблицу (финальную) для загрузки в пби ... +if union_sebes: + print('Объединение в сводную таблицу ~ 10 мин ...') + exec_procedure(connect, '[pbiProd].[ЗаполнитьСебестоимостьСводныйОт2022]') + + +connect.close() +print('end time ', time.ctime()) diff --git a/analytics/python skript/main (3).py b/analytics/python skript/main (3).py new file mode 100644 index 0000000..1e60649 --- /dev/null +++ b/analytics/python skript/main (3).py @@ -0,0 +1,566 @@ +import decimal +import time +import numpy as np +import pyodbc + + +def sql_connect(): + server = 'prdsql' + #server = 'cloud.magok.ru' + database = 'mag_pbi' + username = 'goglev' + password = 'BOMoGbUZ1p' + connection_string = f'DRIVER={{ODBC Driver 17 for SQL Server}};SERVER={server};DATABASE={database};UID={username};PWD={password}' + + conn = pyodbc.connect(connection_string) + print("successfully connected...") + print("#" * 20) + return conn + + +def get_totals(conn, counter, group): + sql_query = """ + SELECT --TOP (1000) + id, -- 0 + artic_id, -- 1 + COALESCE([Количество], 0) AS [Количество], -- 2 + [ЗатратыМП], -- 3 + COALESCE([Закупка], 0) AS [Закупка], -- 4 + COALESCE([Доставка], 0) AS [Доставка], -- 5 + [НДС], -- 6 + COALESCE([Сборка], 0) AS [Сборка], -- 7 + COALESCE([Таможня], 0) AS [Таможня], -- 8 + [Курс usd2] AS [Курс usd2], -- 9 + [Период] AS [Период], -- 10 + [Валюта документа] AS [Валюта документа], -- 11 + [Вид операции] AS [Вид операции], -- 12 + [Статья] AS [Статья], -- 13 + COALESCE([ЗатратыСкладХранение], 0) AS [ЗатратыСкладХранение], -- 14 + COALESCE([Приемка], 0) AS [Приемка], -- 15 + COALESCE([АтсМаркировка], 0) AS [АтсМаркировка], -- 16 + COALESCE([СборкаЗаказа], 0) AS [СборкаЗаказа], -- 17 + COALESCE([Закупка, usd2], 0) AS [Закупка, usd2], -- 18 + COALESCE([Доставка USD2+2], 0) AS [Доставка USD2+2], -- 19 + COALESCE([НДС USD2+2], 0) AS [НДС USD2+2], -- 20 + COALESCE([Таможня USD2+2], 0) AS [Таможня USD2+2], -- 21 + COALESCE([Сборка USD2+2], 0) AS [Сборка USD2+2] -- 22 + FROM + ( + SELECT + id, + artic_id, + COALESCE([Количество], 0) AS [Количество], + [ЗатратыМП], + COALESCE([Закупка], 0) AS [Закупка], + COALESCE([Доставка], 0) AS [Доставка], + [НДС], + COALESCE([Сборка], 0) AS [Сборка], + COALESCE([Таможня], 0) AS [Таможня], + [Курс usd2], + [Период], + [Валюта документа], + [Вид операции], + [Статья], + [ЗатратыСкладХранение], + [Приемка], + [АтсМаркировка], + [СборкаЗаказа], + COALESCE([Закупка, usd2], 0) AS [Закупка, usd2], + COALESCE([Доставка USD2+2], 0) AS [Доставка USD2+2], + COALESCE([НДС USD2+2], 0) AS [НДС USD2+2], + COALESCE([Таможня USD2+2], 0) AS [Таможня USD2+2], + COALESCE([Сборка USD2+2], 0) AS [Сборка USD2+2] + FROM [mag_pbi].[pbi].[СебестоимостьОт2022] + WHERE + [artic_id] IN (SELECT + [artic_id] + FROM [mag_pbi].[pbi].[GroupsOfNomenclature] + where """ + group + """ = """ + str(counter) + """) + and [Период] >= '2022' + --and [artic_id] = 'e4532cdc-a827-11e5-80c7-305a3a00e12b' + + UNION ALL + + SELECT + id, + artic_id, + COALESCE([Количество], 0), + [ЗатратыМП], + COALESCE([Закупка], 0), + COALESCE([Доставка], 0), + [НДС], + COALESCE([Сборка], 0), + COALESCE([Таможня], 0), + 0, + '2021', + NULL, + 'Закупка', + 'Ввод остатков до 22', + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + FROM [mag_pbi].[pbi].[СебестоимостьИтогиДо2022] + where [artic_id] IN (SELECT + [artic_id] + FROM [mag_pbi].[pbi].[GroupsOfNomenclature] + where """ + group + """ = """ + str(counter) + """) + -- and [artic_id] = 'e4532cdc-a827-11e5-80c7-305a3a00e12b' + ) AS tabMain + --WHERE 1=1 + + ORDER BY + [artic_id], [Период] ASC, [Закупка] DESC; + """ + cursor = conn.cursor() + cursor.execute(sql_query) + pbi_totals = cursor.fetchall() + print(time.ctime(), ' Записей к обработке: ', len(pbi_totals)) + return pbi_totals + + +def find_sumof_total(sebes_sales, date, current_sales_id, current_params, last_string_values): + quantity = current_params['quantity'] + sumZakupka = current_params['sumZakupka'] + sumZakupkaUSD2 = current_params['sumZakupkaUSD2'] + sum_dostavka = current_params['sum_dostavka'] + sum_dostavkaUSD2 = current_params['sum_dostavkaUSD2'] + sum_NAT = current_params['sum_NAT'] + sum_NATUSD2 = current_params['sum_NATUSD2'] + sum_sborka = current_params['sum_sborka'] + sum_sborkaUSD2 = current_params['sum_sborkaUSD2'] + sum_zatratiMP = current_params['sum_zatratiMP'] + sum_custom = current_params['sum_custom'] + sum_customUSD2 = current_params['sum_customUSD2'] + sum_skladHranenie = current_params['sum_skladHranenie'] + sum_Priemka = current_params['sum_Priemka'] + sum_AtsMarkirovka = current_params['sum_AtsMarkirovka'] + sum_SborkaZakaza = current_params['sum_SborkaZakaza'] + i = current_params['counter'] + len_sebes_sales = len(sebes_sales) + while i < len_sebes_sales: + try: + curr_str = sebes_sales[i] + except: + print('Ошибка в иттераторе, тек ид =', current_sales_id) + print(i) + print(len_sebes_sales) + break + + if curr_str[10] > date or current_sales_id != curr_str[0]: + break + else: + i += 1 + + if curr_str[12] == 'Закупка' or curr_str[12] == 'Сборка заказа' or curr_str[12] == 'Приемка' or curr_str[12] == 'Атс маркировка': + quantity += curr_str[2] + + if curr_str[9] > 0: + usd2_course = curr_str[9] + else: + if curr_str[13] == 'Ввод остатков до 22': + # для ввода остатков возьём курс на 1 января 2023 года + usd2_course = 75.7785 + else: + usd2_course = 1 + + sumZakupka += curr_str[4] + if curr_str[13] == 'Ввод остатков до 22': + sumZakupkaUSD2 += decimal.Decimal(float(sumZakupka) / usd2_course) + else: + sumZakupkaUSD2 += curr_str[18] + + + #if curr_str[11] == 'руб.': + # sumZakupkaUSD += sumZakupka / usd2_course + + sum_dostavka += curr_str[5] + sum_dostavkaUSD2 += curr_str[19] + sum_NAT += curr_str[6] + sum_NATUSD2 += curr_str[20] + sum_sborka += curr_str[7] + sum_sborkaUSD2 += curr_str[22] + sum_zatratiMP += curr_str[3] + sum_custom += curr_str[8] + sum_customUSD2 += curr_str[21] + sum_skladHranenie += curr_str[14] + sum_Priemka += curr_str[15] + sum_AtsMarkirovka += curr_str[16] + sum_SborkaZakaza += curr_str[17] + + if curr_str[12] == 'Продажа': + quantity -= last_string_values['quantity'] + sumZakupka -= last_string_values['sumZakupka'] + sumZakupkaUSD2 -= last_string_values['sumZakupkaUSD2'] + sum_dostavka -= last_string_values['sum_dostavka'] + sum_dostavkaUSD2 -= last_string_values['sum_dostavkaUSD2'] + sum_NAT -= last_string_values['sum_NAT'] + sum_NATUSD2 -= last_string_values['sum_NATUSD2'] + sum_sborka -= last_string_values['sum_sborka'] + sum_sborkaUSD2 -= last_string_values['sum_sborkaUSD2'] + sum_zatratiMP -= last_string_values['sum_zatratiMP'] + sum_custom -= last_string_values['sum_custom'] + sum_customUSD2 -= last_string_values['sum_customUSD2'] + sum_skladHranenie -= last_string_values['sum_skladHranenie'] + sum_Priemka -= last_string_values['sum_Priemka'] + sum_AtsMarkirovka -= last_string_values['sum_AtsMarkirovka'] + sum_SborkaZakaza -= last_string_values['sum_SborkaZakaza'] + + if quantity <= 0: + quantity = 0 + sumZakupka = 0 + sumZakupkaUSD2 = 0 + sum_dostavka = 0 + sum_NAT = 0 + sum_sborka = 0 + sum_zatratiMP = 0 + sum_custom = 0 + sum_skladHranenie = 0 + sum_Priemka = 0 + sum_AtsMarkirovka = 0 + sum_SborkaZakaza = 0 + sum_dostavkaUSD2 = 0 + sum_NATUSD2 = 0 + sum_sborkaUSD2 = 0 + sum_customUSD2 = 0 + + + return {'quantity': quantity, 'sumZakupka': sumZakupka, 'sumZakupkaUSD2': sumZakupkaUSD2, + 'sum_dostavka': sum_dostavka, + 'sum_NAT': sum_NAT, 'sum_sborka': sum_sborka, 'sum_zatratiMP': sum_zatratiMP, 'sum_custom': sum_custom, + 'sum_skladHranenie': sum_skladHranenie, 'sum_Priemka': sum_Priemka, 'sum_AtsMarkirovka': sum_AtsMarkirovka, 'sum_SborkaZakaza': sum_SborkaZakaza, + 'sum_dostavkaUSD2': sum_dostavkaUSD2, 'sum_NATUSD2': sum_NATUSD2, 'sum_sborkaUSD2': sum_sborkaUSD2, 'sum_customUSD2': sum_customUSD2, + 'counter': i} + + + +def update_to_DB_Sales(arr, conn, year): + try: + cursor = conn.cursor() + conn.autocommit = False + cursor.fast_executemany = True + table = '[СебестоимостьОт2022]' + if year == '2022': + table = '[СебестоимостьОт2022]' + elif year == '2023': + table = '[Себестоимость2023]' + elif year == '2024': + table = '[Себестоимость2024]' + + cursor.executemany( + """UPDATE [mag_pbi].[pbi].""" + table + """ + SET + [Закупка] = ? -- 0 + , [Закупка, usd2] = ? -- 1 + , [Доставка] = ? -- 2 + , [Сборка] = ? -- 3 + , [НДС] = ? -- 4 + , [ЗатратыМП] = ? -- 5 + , [Таможня] = ? -- 6 + , [ЗатратыСкладХранение] = ? -- 7 + , [Учетная стоимость] = ? -- 8 + , [Учетная стоимость USD2+2] = ? -- 9 + , [Учетная цена] = ? -- 10 + , [Учетная цена USD2+2] = ? -- 11 + , [artic_id] = ? -- 12 + , [Приемка] = ? -- 13 + , [АтсМаркировка] = ? -- 14 + , [СборкаЗаказа] = ? -- 15 + , [Доставка USD2+2] = ? -- 16 + , [НДС USD2+2] = ? -- 17 + , [Таможня USD2+2] = ? -- 18 + , [Сборка USD2+2] = ? -- 19 + WHERE id = ?""", + arr) + + + except pyodbc.DatabaseError as err: + print('ошибка', err) + conn.rollback() + else: + conn.commit() + print(time.ctime(), 'обновлено', len(arr), ': записей') + finally: + conn.autocommit = True + + +def update_to_DB_sebest(arr, conn, year): + try: + cursor = conn.cursor() + conn.autocommit = False + cursor.fast_executemany = True + table = '[СебестоимостьОт2022]' + if year == '2022': + table = '[СебестоимостьОт2022]' + elif year == '2023': + table = '[Себестоимость2023]' + elif year == '2024': + table = '[Себестоимость2024]' + cursor.executemany( + "UPDATE [mag_pbi].[pbi]." + table + " SET [Учетная стоимость] = ?, [Учетная стоимость USD2+2] = ?, [Учетная цена] = ?, [Учетная цена USD2+2] = ? WHERE id = ?", + arr) + + + except pyodbc.DatabaseError as err: + print('ошибка', err) + conn.rollback() + else: + conn.commit() + print(time.ctime(), 'обновлено', len(arr), ': записей') + finally: + conn.autocommit = True + + +def exec_procedure(conn, procedure_name): + sql_query = 'EXEC ' + procedure_name + cursor = conn.cursor() + cursor.execute(sql_query).commit() + + +def getMaxCounter(conn, group): + sql_query = "SELECT MAX(" + group + ") FROM [mag_pbi].[pbi].[GroupsOfNomenclature]" + + cursor = conn.cursor() + cursor.execute(sql_query) + maxCounter = cursor.fetchall() + return maxCounter[0][0] + + + +def arr_to_nparr(arr): + return np.asarray(arr) + + +def count_sebest(connect, counter, group): + upload = True + ind = 0 + arr_sebes = [] + arr_sales = [] + last_utid = '' + pbi_all = get_totals(connect, counter, group) + nparr_all = arr_to_nparr(pbi_all) + + for str in pbi_all: + ind += 1 + date = str[10] + utid = str[1] + id = str[0] + tableGod = str[14] + zakupkaRUB = round(0, 15) + zakupkaUSD2 = round(0, 15) + NAT = round(0, 15) + NATUSD2 = round(0, 15) + zatratiMP = round(0, 15) + sborka = round(0, 15) + dostavka = round(0, 15) + dostavkaUSD2 = round(0, 15) + custom = round(0, 15) + customUSD2 = round(0, 15) + skladHranenie = round(0, 15) + priemka = round(0, 15) + atsMarkirovka = round(0, 15) + sborkaZakaza = round(0, 15) + + + if utid != last_utid: + fltr = np.asarray([utid]) + pbi_all_current_utid = nparr_all[np.in1d(nparr_all[:, 1], fltr)] + last_utid = utid + current_params = {'quantity': 0, 'sumZakupka': 0, 'sumZakupkaUSD2': 0, + 'sum_dostavka': 0, 'sum_NAT': 0, 'sum_sborka': 0, 'sum_zatratiMP': 0, 'sum_custom': 0, 'sum_skladHranenie': 0, 'sum_Priemka': 0, + 'sum_AtsMarkirovka': 0, 'sum_SborkaZakaza': 0, 'sum_dostavkaUSD2': 0, 'sum_NATUSD2': 0, 'sum_sborkaUSD2': 0, 'sum_customUSD2': 0, + 'sum_zakupkaUSD2': 0, + 'counter': 0} + last_string_values = {'quantity': 0, 'sumZakupka': 0, 'sumZakupkaUSD2': 0, + 'sum_dostavka': 0, 'sum_NAT': 0, 'sum_sborka': 0, 'sum_zatratiMP': 0, 'sum_custom': 0, 'sum_skladHranenie': 0, 'sum_Priemka': 0, + 'sum_AtsMarkirovka': 0, 'sum_SborkaZakaza': 0, 'sum_dostavkaUSD2': 0, 'sum_NATUSD2': 0, 'sum_sborkaUSD2': 0, 'sum_customUSD2': 0, + 'sum_zakupkaUSD2': 0} + + all_params = find_sumof_total(pbi_all_current_utid, date, str[0], current_params, last_string_values) + current_params = all_params.copy() + + sale_quantity = str[2] + + if str[9] > 0: + usd2_course = str[9] + else: + usd2_course = 1 + + sum_quantity = all_params['quantity'] + sum_zakupka = all_params['sumZakupka'] + sum_zakupkaUSD2 = all_params['sumZakupkaUSD2'] + sum_dostavka = all_params['sum_dostavka'] + sum_dostavkaUSD2 = all_params['sum_dostavkaUSD2'] + sum_NAT = all_params['sum_NAT'] + sum_NATUSD2 = all_params['sum_NATUSD2'] + sum_sborka = all_params['sum_sborka'] + sum_sborkaUSD2 = all_params['sum_sborkaUSD2'] + sum_zatratiMP = all_params['sum_zatratiMP'] + sum_custom = all_params['sum_custom'] + sum_customUSD2 = all_params['sum_customUSD2'] + sum_skladHranenie = all_params['sum_skladHranenie'] + sum_Priemka = all_params['sum_Priemka'] + sum_AtsMarkirovka = all_params['sum_AtsMarkirovka'] + sum_SborkaZakaza = all_params['sum_SborkaZakaza'] + + + if (str[12] == 'Закупка' or str[12] == 'Сборка заказа' or str[12] == 'Приемка' or str[12] == 'Атс маркировка') and str[13] != 'Ввод остатков до 22': + + uchet_price = 0 + uchet_price_usd22 = 0 + uchet_stoimost = 0 + uchet_stoimost_usd22 = 0 + + zakupkaRUB = round(sum_zakupka, 15) + zakupkaUSD2 = round(sum_zakupkaUSD2, 15) + + + if sum_quantity != 0: + dostavka = round(sum_dostavka, 15) + dostavkaUSD2 = round(sum_dostavkaUSD2, 15) + NAT = round(sum_NAT, 15) + NATUSD2 = round(sum_NATUSD2, 15) + sborka = round(sum_sborka, 15) + sborkaUSD2 = round(sum_sborkaUSD2, 15) + zatratiMP = round(sum_zatratiMP, 15) + custom = round(sum_custom, 15) + customUSD2 = round(sum_customUSD2, 15) + skladHranenie = round(sum_skladHranenie, 15) + priemka = round(sum_Priemka, 15) + atsMarkirovka = round(sum_AtsMarkirovka, 15) + sborkaZakaza = round(sum_SborkaZakaza, 15) + + uchet_price = round((dostavka + NAT + zakupkaRUB + custom + sborka) / sum_quantity, 15) + uchet_price_usd22 = round((dostavkaUSD2 + NATUSD2 + zakupkaUSD2 + customUSD2 + sborkaUSD2) / sum_quantity, 15) + + if sale_quantity != 0: + uchet_stoimost = round(uchet_price * sale_quantity, 15) + uchet_stoimost_usd22 = round(uchet_price_usd22 * sale_quantity, 15) + + + arr_sebes.append((uchet_stoimost, uchet_stoimost_usd22, uchet_price, uchet_price_usd22, id)) + + + elif str[12] == 'Продажа': + + if sale_quantity != 0: + + if sum_zakupka < 0: + sum_zakupka = 0 + + if sale_quantity > sum_quantity or sum_quantity == 0: + zakupkaRUB = round(sum_zakupka, 15) + zakupkaUSD2 = round(sum_zakupkaUSD2, 15) + else: + zakupkaRUB = round(decimal.Decimal(sum_zakupka) / sum_quantity * sale_quantity, 15) + zakupkaUSD2 = round(decimal.Decimal(sum_zakupkaUSD2) / sum_quantity * sale_quantity, 15) + + #zakupkaUSD2 = round(sum_zakupkaUSD2 / usd2_course, 15) + + if sale_quantity > sum_quantity or sum_quantity == 0: + dostavka = round(sum_dostavka, 15) + dostavkaUSD2 = round(sum_dostavkaUSD2, 15) + NAT = round(sum_NAT, 15) + NATUSD2 = round(sum_NATUSD2, 15) + sborka = round(sum_sborka, 15) + sborkaUSD2 = round(sum_sborkaUSD2, 15) + zatratiMP = round(sum_zatratiMP, 15) + custom = round(sum_custom, 15) + customUSD2 = round(sum_customUSD2, 15) + skladHranenie = round(sum_skladHranenie, 15) + priemka = round(sum_Priemka, 15) + atsMarkirovka = round(sum_AtsMarkirovka, 15) + sborkaZakaza = round(sum_SborkaZakaza, 15) + else: + dostavka = round(sum_dostavka / sum_quantity * sale_quantity, 15) + dostavkaUSD2 = round(sum_dostavkaUSD2 / sum_quantity * sale_quantity, 15) + NAT = round(sum_NAT / sum_quantity * sale_quantity, 15) + NATUSD2 = round(sum_NATUSD2 / sum_quantity * sale_quantity, 15) + sborka = round(sum_sborka / sum_quantity * sale_quantity, 15) + sborkaUSD2 = round(sum_sborkaUSD2 / sum_quantity * sale_quantity, 15) + zatratiMP = round(sum_zatratiMP / sum_quantity * sale_quantity, 15) + custom = round(sum_custom / sum_quantity * sale_quantity, 15) + customUSD2 = round(sum_customUSD2 / sum_quantity * sale_quantity, 15) + skladHranenie = round(sum_skladHranenie / sum_quantity * sale_quantity, 15) + priemka = round(sum_Priemka / sum_quantity * sale_quantity, 15) + atsMarkirovka = round(sum_AtsMarkirovka / sum_quantity * sale_quantity, 15) + sborkaZakaza = round(sum_SborkaZakaza / sum_quantity * sale_quantity, 15) + + + last_string_values = {'quantity': sale_quantity, 'sumZakupka': zakupkaRUB, 'sumZakupkaUSD2': zakupkaUSD2, + 'sum_dostavka': dostavka, + 'sum_NAT': NAT, 'sum_sborka': sborka, 'sum_zatratiMP': zatratiMP, + 'sum_custom': custom, 'sum_skladHranenie': skladHranenie, 'sum_Priemka': priemka, + 'sum_AtsMarkirovka': atsMarkirovka, 'sum_SborkaZakaza': sborkaZakaza, + 'sum_dostavkaUSD2': dostavkaUSD2, 'sum_NATUSD2': NATUSD2, 'sum_sborkaUSD2': sborkaUSD2, 'sum_customUSD2': customUSD2} + + if zakupkaRUB != 0 or zakupkaUSD2 != 0 or NAT != 0 or sborka != 0 or dostavka != 0 or custom != 0: + uchet_stoimost = round((dostavka + NAT + zakupkaRUB + custom + sborka), 15) + uchet_stoimost_usd22 = round((dostavkaUSD2 + NATUSD2 + zakupkaUSD2 + customUSD2 + sborkaUSD2), 15) + uchet_price = round((dostavka + NAT + zakupkaRUB + custom + sborka) / sale_quantity, 15) + uchet_price_usd22 = round((dostavkaUSD2 + NATUSD2 + zakupkaUSD2 + customUSD2 + sborkaUSD2) / sale_quantity, 15) + + arr_sales.append( + (float(-zakupkaRUB), float(-zakupkaUSD2), float(-dostavka), float(-sborka), float(-NAT), float(-zatratiMP), float(-custom), + float(-skladHranenie), float(uchet_stoimost), + float(uchet_stoimost_usd22), float(uchet_price), float(uchet_price_usd22), utid, float(-priemka), float(-atsMarkirovka), float(-sborkaZakaza), + float(-dostavkaUSD2), float(-NATUSD2), float(-sborkaUSD2), float(-customUSD2), + id)) + + # break + + if ind % 10000 == 0: + print(time.ctime(), ' ', ind, 'проходов') + if upload: + if len(arr_sales) > 0: + print(time.ctime(), ' записей sales: ', len(arr_sales)) + update_to_DB_Sales(arr_sales, connect, '2022') + + if len(arr_sebes) > 0: + print(time.ctime(), ' записей sebest: ', len(arr_sebes)) + update_to_DB_sebest(arr_sebes, connect, '2022') + + + upload = False + + + +#флаг для обработки без заполнения таблиц ... +fill_BuysSells = True +fill_PriemkaMarkSborka = True +union_sebes = True +print('start time', time.ctime()) +connect = sql_connect() +# заполним таблицы данными закупки ... +if fill_BuysSells: + print('Заполнение таблицы данными ~ 14 мин, 8kk записей ...') + exec_procedure(connect, '[sebest].[Заполнить себестоимостьОт2022(закупки+продажи)]') + +if fill_PriemkaMarkSborka: + print('Заполнение таблицы данными ~ 30 мин, 5kk записей ...') + exec_procedure(connect, '[sebest].[Заполнить себестоимостьОт2022(Сборка)]') + + + +group = '[2k]' +max_counter = getMaxCounter(connect, group) +print('Группа: ', group, ' Всего групп - ', max_counter) +for counter in range(max_counter): + counter += 1 + count_sebest(connect, counter, group) + print(time.ctime(), ' группа ', counter, ' обработана') + + +# заполним сводную таблицу для дальнейшего использования ... +if union_sebes: + print('Объединение в сводную таблицу ~ 10 мин ...') + exec_procedure(connect, '[pbi].[ЗаполнитьСебестоимостьСводныйОт2022]') + + +connect.close() +print('end time ', time.ctime()) \ No newline at end of file diff --git a/analytics/python skript/main3.bat b/analytics/python skript/main3.bat new file mode 100644 index 0000000..e73c4f1 --- /dev/null +++ b/analytics/python skript/main3.bat @@ -0,0 +1,2 @@ +"C:\Users\administrator\AppData\Local\Programs\Python\Python312\python.exe" "F:\python skript\python skript\main (3).py" +exit \ No newline at end of file diff --git a/analytics/python skript/old/РасчетСебестоимостиБезПроизводства.py b/analytics/python skript/old/РасчетСебестоимостиБезПроизводства.py new file mode 100644 index 0000000..1932c0a --- /dev/null +++ b/analytics/python skript/old/РасчетСебестоимостиБезПроизводства.py @@ -0,0 +1,951 @@ +import decimal +import time +import numpy as np +import pyodbc + + +def sql_connect(): + server = '192.168.35.207' + server = 'cloud.magok.ru' + database = 'mag_pbi' + username = 'goglev' + password = 'BOMoGbUZ1p' + connection_string = f'DRIVER={{ODBC Driver 17 for SQL Server}};SERVER={server};DATABASE={database};UID={username};PWD={password}' + + conn = pyodbc.connect(connection_string) + print("successfully connected...") + print("#" * 20) + return conn + + +def get_totals(conn, counter, group): + sql_query = """ + SELECT --TOP (1000) + id, -- 0 + artic_id, -- 1 + COALESCE([Количество], 0) AS [Количество], -- 2 + COALESCE([ЗатратыМП], 0) AS ЗатратыМП, -- 3 + COALESCE([Закупка], 0) AS [Закупка], -- 4 + COALESCE([Доставка], 0) AS [Доставка], -- 5 + COALESCE([НДС], 0) AS [НДС], -- 6 + COALESCE([Производство], 0) AS [Производство], -- 7 + COALESCE([Таможня], 0) AS [Таможня], -- 8 + [Курс usd2] AS [Курс usd2], -- 9 + [Период] AS [Период], -- 10 + [Валюта документа] AS [Валюта документа], -- 11 + [Вид операции] AS [Вид операции], -- 12 + [Статья] AS [Статья], -- 13 + COALESCE([ЗатратыСкладХранение], 0) AS [ЗатратыСкладХранение], -- 14 + COALESCE([Приемка], 0) AS [Приемка], -- 15 + COALESCE([АтсМаркировка], 0) AS [АтсМаркировка], -- 16 + COALESCE([СборкаЗаказа], 0) AS [СборкаЗаказа], -- 17 + COALESCE([Закупка, usd2], 0) AS [Закупка, usd2], -- 18 + COALESCE([Доставка USD2+2], 0) AS [Доставка USD2+2], -- 19 + COALESCE([НДС USD2+2], 0) AS [НДС USD2+2], -- 20 + COALESCE([Таможня USD2+2], 0) AS [Таможня USD2+2], -- 21 + COALESCE([Производство USD2+2], 0) AS [Производство USD2+2], -- 22 + COALESCE([Доп расходы], 0) AS [Доп расходы], -- 23 + COALESCE([Доп расходы USD2+2], 0) AS [Доп расходы USD2+2] -- 24 + FROM + ( + SELECT + id, + artic_id, + COALESCE([Количество], 0) AS [Количество], + [ЗатратыМП], + COALESCE([Закупка], 0) AS [Закупка], + COALESCE([Доставка], 0) AS [Доставка], + [НДС], + COALESCE([Производство], 0) AS [Производство], + COALESCE([Таможня], 0) AS [Таможня], + [Курс usd2], + [Период], + [Валюта документа], + [Вид операции], + [Статья], + [ЗатратыСкладХранение], + [Приемка], + [АтсМаркировка], + [СборкаЗаказа], + COALESCE([Закупка, usd2], 0) AS [Закупка, usd2], + COALESCE([Доставка USD2+2], 0) AS [Доставка USD2+2], + COALESCE([НДС USD2+2], 0) AS [НДС USD2+2], + COALESCE([Таможня USD2+2], 0) AS [Таможня USD2+2], + COALESCE([Производство USD2+2], 0) AS [Производство USD2+2], + COALESCE([Доп расходы], 0) AS [Доп расходы], + COALESCE([Доп расходы USD2+2], 0) AS [Доп расходы USD2+2] + + FROM [mag_pbi].[pbiProd].[СебестоимостьОт2022] + WHERE + 1=1 + --and [artic_id] = 'c4bbfb4b-cf25-11ef-998c-b49691d57efd' + and [artic_id] IN (SELECT + [artic_id] + FROM [mag_pbi].[pbiProd].[GroupsOfNomenclature] + where """ + group + """ = """ + str(counter) + """) + and [Период] >= '2022' + + + UNION ALL + + SELECT + id, + artic_id, + COALESCE([Количество], 0), + [ЗатратыМП], + COALESCE([Закупка], 0), + COALESCE([Доставка], 0), + [НДС], + COALESCE([Сборка], 0), + COALESCE([Таможня], 0), + 0, + '2021', + NULL, + 'Приход', + 'Ввод остатков до 22', + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + FROM [mag_pbi].[pbiProd].[СебестоимостьИтогиДо2022] + where + 1 = 1 + --and [artic_id] = 'c4bbfb4b-cf25-11ef-998c-b49691d57efd' + and [artic_id] IN (SELECT + [artic_id] + FROM [mag_pbi].[pbiProd].[GroupsOfNomenclature] + where """ + group + """ = """ + str(counter) + """) + ) AS tabMain + --WHERE 1=1 + + ORDER BY + [artic_id], [Период] ASC, [Закупка] DESC; + """ + cursor = conn.cursor() + cursor.execute(sql_query) + pbi_totals = cursor.fetchall() + print(time.ctime(), ' Записей к обработке: ', len(pbi_totals)) + return pbi_totals + + + +def get_totalsManufacture(conn, manufactureLevel, start_range, end_range): + sql_query = """ + SELECT --TOP (1000) + id, -- 0 + artic_id, -- 1 + COALESCE([Количество], 0) AS [Количество], -- 2 + COALESCE([ЗатратыМП], 0) AS ЗатратыМП, -- 3 + COALESCE([Закупка], 0) AS [Закупка], -- 4 + COALESCE([Доставка], 0) AS [Доставка], -- 5 + COALESCE([НДС], 0) AS [НДС], -- 6 + COALESCE([Производство], 0) AS [Производство], -- 7 + COALESCE([Таможня], 0) AS [Таможня], -- 8 + [Курс usd2] AS [Курс usd2], -- 9 + [Период] AS [Период], -- 10 + [Валюта документа] AS [Валюта документа], -- 11 + [Вид операции] AS [Вид операции], -- 12 + [Статья] AS [Статья], -- 13 + COALESCE([ЗатратыСкладХранение], 0) AS [ЗатратыСкладХранение], -- 14 + COALESCE([Приемка], 0) AS [Приемка], -- 15 + COALESCE([АтсМаркировка], 0) AS [АтсМаркировка], -- 16 + COALESCE([СборкаЗаказа], 0) AS [СборкаЗаказа], -- 17 + COALESCE([Закупка, usd2], 0) AS [Закупка, usd2], -- 18 + COALESCE([Доставка USD2+2], 0) AS [Доставка USD2+2], -- 19 + COALESCE([НДС USD2+2], 0) AS [НДС USD2+2], -- 20 + COALESCE([Таможня USD2+2], 0) AS [Таможня USD2+2], -- 21 + COALESCE([Производство USD2+2], 0) AS [Производство USD2+2], -- 22 + COALESCE([Доп расходы], 0) AS [Доп расходы], -- 23 + COALESCE([Доп расходы USD2+2], 0) AS [Доп расходы USD2+2] -- 24 + FROM + ( + SELECT + id, + artic_id, + COALESCE([Количество], 0) AS [Количество], + [ЗатратыМП], + COALESCE([Закупка], 0) AS [Закупка], + COALESCE([Доставка], 0) AS [Доставка], + [НДС], + COALESCE([Производство], 0) AS [Производство], + COALESCE([Таможня], 0) AS [Таможня], + [Курс usd2], + [Период], + [Валюта документа], + [Вид операции], + [Статья], + [ЗатратыСкладХранение], + [Приемка], + [АтсМаркировка], + [СборкаЗаказа], + COALESCE([Закупка, usd2], 0) AS [Закупка, usd2], + COALESCE([Доставка USD2+2], 0) AS [Доставка USD2+2], + COALESCE([НДС USD2+2], 0) AS [НДС USD2+2], + COALESCE([Таможня USD2+2], 0) AS [Таможня USD2+2], + COALESCE([Производство USD2+2], 0) AS [Производство USD2+2], + COALESCE([Доп расходы], 0) AS [Доп расходы], + COALESCE([Доп расходы USD2+2], 0) AS [Доп расходы USD2+2] + FROM [mag_pbi].[pbiProd].[СебестоимостьОт2022] + WHERE + 1=1 + --and [artic_id] = '24d0c24b-3a60-11e9-ae9c-b496910dcfd6' + and [1c_id] IN (SELECT + [1c_id] + FROM [mag_pbi].[pbiProd].[НоменклатураВПроизводствеПоУровням] + where [УровеньПроизводства] = """ + str(manufactureLevel) + """ + and [RowNum] BETWEEN """ + str(start_range) + """ AND """ + str(end_range) + """ + --and [1c_id] = 0x9981B49691D57EFD11EDDE7DA97A5E64 + ) + and [Период] >= '2022' + + + UNION ALL + + SELECT + id, + artic_id, + COALESCE([Количество], 0), + [ЗатратыМП], + COALESCE([Закупка], 0), + COALESCE([Доставка], 0), + [НДС], + COALESCE([Сборка], 0), + COALESCE([Таможня], 0), + 0, + '2021', + NULL, + 'Приход', + 'Ввод остатков до 22', + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + FROM [mag_pbi].[pbiProd].[СебестоимостьИтогиДо2022] + where + 1 = 1 + --and [artic_id] = '24d0c24b-3a60-11e9-ae9c-b496910dcfd6' + and [1c_id] IN (SELECT + [1c_id] + FROM [mag_pbi].[pbiProd].[НоменклатураВПроизводствеПоУровням] + where [УровеньПроизводства] = """ + str(manufactureLevel) + """ + and [RowNum] BETWEEN """ + str(start_range) + """ AND """ + str(end_range) + """ + --and [1c_id] = 0x9981B49691D57EFD11EDDE7DA97A5E64 + ) + ) AS tabMain + --WHERE 1=1 + + ORDER BY + [artic_id], [Период] ASC, [Закупка] DESC; + """ + cursor = conn.cursor() + cursor.execute(sql_query) + pbi_totals = cursor.fetchall() + print(time.ctime(), ' Записей к обработке: ', len(pbi_totals)) + return pbi_totals + +def find_sumof_total(sebes_sales, date, current_sales_id, current_params, last_string_values): + quantity = current_params['quantity'] + sumZakupka = current_params['sumZakupka'] + sumZakupkaUSD2 = current_params['sumZakupkaUSD2'] + sum_dostavka = current_params['sum_dostavka'] + sum_dostavkaUSD2 = current_params['sum_dostavkaUSD2'] + sum_NAT = current_params['sum_NAT'] + sum_NATUSD2 = current_params['sum_NATUSD2'] + sum_production = current_params['sum_production'] + sum_productionUSD2 = current_params['sum_productionUSD2'] + sum_zatratiMP = current_params['sum_zatratiMP'] + sum_custom = current_params['sum_custom'] + sum_customUSD2 = current_params['sum_customUSD2'] + sum_skladHranenie = current_params['sum_skladHranenie'] + sum_Priemka = current_params['sum_Priemka'] + sum_AtsMarkirovka = current_params['sum_AtsMarkirovka'] + sum_SborkaZakaza = current_params['sum_SborkaZakaza'] + sum_DopRashod = current_params['sum_DopRashod'] + sum_DopRashodUSD2 = current_params['sum_DopRashodUSD2'] + i = current_params['counter'] + len_sebes_sales = len(sebes_sales) + while i < len_sebes_sales: + try: + curr_str = sebes_sales[i] + except: + print('Ошибка в иттераторе, тек ид =', current_sales_id) + print(i) + print(len_sebes_sales) + break + + if curr_str[10] > date or current_sales_id != curr_str[0]: + break + else: + i += 1 + + if curr_str[12] == 'Приход': + + # кажется что можно и нужно удалить ... + if curr_str[13] == 'Закупка' or curr_str[13] == 'Ввод остатков до 22' or curr_str[13] == 'Производство товара' or curr_str[13] == 'Пересчет товара': + quantity += curr_str[2] + + + if curr_str[9] > 0: + usd2_course = curr_str[9] + else: + if curr_str[13] == 'Ввод остатков до 22': + # для ввода остатков возьём курс на 1 января 2023 года + usd2_course = 75.7785 + else: + usd2_course = 1 + + sumZakupka += curr_str[4] + if curr_str[13] == 'Ввод остатков до 22': + sumZakupkaUSD2 += decimal.Decimal(float(sumZakupka) / usd2_course) + else: + sumZakupkaUSD2 += curr_str[18] + + + #if curr_str[11] == 'руб.': + # sumZakupkaUSD += sumZakupka / usd2_course + + sum_dostavka += curr_str[5] + sum_dostavkaUSD2 += curr_str[19] + sum_NAT += curr_str[6] + sum_NATUSD2 += curr_str[20] + sum_production += curr_str[7] + sum_productionUSD2 += curr_str[22] + sum_zatratiMP += curr_str[3] + sum_custom += curr_str[8] + sum_customUSD2 += curr_str[21] + sum_skladHranenie += curr_str[14] + sum_Priemka += curr_str[15] + sum_AtsMarkirovka += curr_str[16] + sum_SborkaZakaza += curr_str[17] + sum_DopRashod += curr_str[23] + sum_DopRashodUSD2 += curr_str[24] + + if curr_str[12] == 'Расход': + quantity -= last_string_values['quantity'] + sumZakupka -= last_string_values['sumZakupka'] + sumZakupkaUSD2 -= last_string_values['sumZakupkaUSD2'] + sum_dostavka -= last_string_values['sum_dostavka'] + sum_dostavkaUSD2 -= last_string_values['sum_dostavkaUSD2'] + sum_NAT -= last_string_values['sum_NAT'] + sum_NATUSD2 -= last_string_values['sum_NATUSD2'] + sum_production -= last_string_values['sum_production'] + sum_productionUSD2 -= last_string_values['sum_productionUSD2'] + sum_zatratiMP -= last_string_values['sum_zatratiMP'] + sum_custom -= last_string_values['sum_custom'] + sum_customUSD2 -= last_string_values['sum_customUSD2'] + sum_skladHranenie -= last_string_values['sum_skladHranenie'] + sum_Priemka -= last_string_values['sum_Priemka'] + sum_AtsMarkirovka -= last_string_values['sum_AtsMarkirovka'] + sum_SborkaZakaza -= last_string_values['sum_SborkaZakaza'] + sum_DopRashod -= last_string_values['sum_DopRashod'] + sum_DopRashodUSD2 -= last_string_values['sum_DopRashodUSD2'] + + if quantity <= 0: + quantity = 0 + sumZakupka = 0 + sumZakupkaUSD2 = 0 + sum_dostavka = 0 + sum_NAT = 0 + sum_production = 0 + sum_zatratiMP = 0 + sum_custom = 0 + sum_skladHranenie = 0 + sum_Priemka = 0 + sum_AtsMarkirovka = 0 + sum_SborkaZakaza = 0 + sum_dostavkaUSD2 = 0 + sum_NATUSD2 = 0 + sum_productionUSD2 = 0 + sum_customUSD2 = 0 + sum_DopRashod = 0 + sum_DopRashodUSD2 = 0 + + + return {'quantity': quantity, 'sumZakupka': sumZakupka, 'sumZakupkaUSD2': sumZakupkaUSD2, + 'sum_dostavka': sum_dostavka, + 'sum_NAT': sum_NAT, 'sum_production': sum_production, 'sum_zatratiMP': sum_zatratiMP, 'sum_custom': sum_custom, + 'sum_skladHranenie': sum_skladHranenie, 'sum_Priemka': sum_Priemka, 'sum_AtsMarkirovka': sum_AtsMarkirovka, 'sum_SborkaZakaza': sum_SborkaZakaza, + 'sum_dostavkaUSD2': sum_dostavkaUSD2, 'sum_NATUSD2': sum_NATUSD2, 'sum_productionUSD2': sum_productionUSD2, 'sum_customUSD2': sum_customUSD2, + 'sum_DopRashod': sum_DopRashod, 'sum_DopRashodUSD2': sum_DopRashodUSD2, + 'counter': i} + + +def insert_to_DB_Production(arr, conn): + try: + cursor = conn.cursor() + conn.autocommit = False + cursor.fast_executemany = True + table = '[СебестоимостьПроизводствоОт2022]' + + cursor.executemany(""" + INSERT INTO [mag_pbi].[pbiProd].[СебестоимостьПроизводствоОт2022] + ([Период], [artic_id], [Учетная цена], [Учетная цена USD2+2]) + VALUES (?, ?, ?, ?); + """, arr) + + + except pyodbc.DatabaseError as err: + print('ошибка', err) + conn.rollback() + else: + conn.commit() + print(time.ctime(), 'обновлено', len(arr), ': записей') + finally: + conn.autocommit = True + +def update_to_DB_Sales(arr, conn, year): + try: + cursor = conn.cursor() + conn.autocommit = False + cursor.fast_executemany = True + table = '[СебестоимостьОт2022]' + if year == '2022': + table = '[СебестоимостьОт2022]' + elif year == '2023': + table = '[Себестоимость2023]' + elif year == '2024': + table = '[Себестоимость2024]' + + cursor.executemany( + """UPDATE [mag_pbi].[pbiProd].""" + table + """ + SET + [Закупка] = ? -- 0 + , [Закупка, usd2] = ? -- 1 + , [Доставка] = ? -- 2 + , [Производство] = ? -- 3 + , [НДС] = ? -- 4 + , [ЗатратыМП] = ? -- 5 + , [Таможня] = ? -- 6 + , [ЗатратыСкладХранение] = ? -- 7 + , [Учетная стоимость] = ? -- 8 + , [Учетная стоимость USD2+2] = ? -- 9 + , [Учетная цена] = ? -- 10 + , [Учетная цена USD2+2] = ? -- 11 + , [artic_id] = ? -- 12 + , [Приемка] = ? -- 13 + , [АтсМаркировка] = ? -- 14 + , [СборкаЗаказа] = ? -- 15 + , [Доставка USD2+2] = ? -- 16 + , [НДС USD2+2] = ? -- 17 + , [Таможня USD2+2] = ? -- 18 + , [Производство USD2+2] = ? -- 19 + , [Доп расходы] = ? -- 20 + , [Доп расходы USD2+2] = ? -- 21 + WHERE id = ?""", + arr) + + + except pyodbc.DatabaseError as err: + print('ошибка', err) + conn.rollback() + else: + conn.commit() + print(time.ctime(), 'обновлено', len(arr), ': записей') + finally: + conn.autocommit = True + + +def update_to_DB_sebest(arr, conn, year): + try: + cursor = conn.cursor() + conn.autocommit = False + cursor.fast_executemany = True + table = '[СебестоимостьОт2022]' + # if year == '2022': + # table = '[СебестоимостьОт2022]' + # elif year == '2023': + # table = '[Себестоимость2023]' + # elif year == '2024': + # table = '[Себестоимость2024]' + cursor.executemany( + "UPDATE [mag_pbi].[pbiProd]." + table + " SET [Учетная стоимость] = ?, [Учетная стоимость USD2+2] = ?, [Учетная цена] = ?, [Учетная цена USD2+2] = ? WHERE id = ?", + arr) + + + except pyodbc.DatabaseError as err: + print('ошибка', err) + conn.rollback() + else: + conn.commit() + print(time.ctime(), 'обновлено', len(arr), ': записей') + finally: + conn.autocommit = True + + +def exec_procedure(conn, procedure_name): + sql_query = 'EXEC ' + procedure_name + cursor = conn.cursor() + cursor.execute(sql_query).commit() + + +def getMaxCounter(conn, group): + sql_query = "SELECT MAX(" + group + ") FROM [mag_pbi].[pbiProd].[GroupsOfNomenclature]" + + cursor = conn.cursor() + cursor.execute(sql_query) + maxCounter = cursor.fetchall() + return maxCounter[0][0] + + + +def count_sebest(connect, counter = '2k', group = '1', manufactureLevel = 0, manufacture = False, start_range = 0, end_range = 0): + upload = True + ind = 0 + arr_sebes = [] + arr_sales = [] + arr_production = [] + arr_price = [] + last_utid = '' + last_operation = '' + last_state = '' + + if manufacture: + pbi_all = get_totalsManufacture(connect, manufactureLevel, start_range, end_range) + else: + pbi_all = get_totals(connect, counter, group) + + + nparr_all = np.asarray(pbi_all) + + for str in pbi_all: + ind += 1 + date = str[10] + utid = str[1] + id = str[0] + tableGod = str[14] + zakupkaRUB = round(0, 9) + zakupkaUSD2 = round(0, 9) + NAT = round(0, 9) + NATUSD2 = round(0, 9) + zatratiMP = round(0, 9) + production = round(0, 9) + dostavka = round(0, 9) + dostavkaUSD2 = round(0, 9) + custom = round(0, 9) + customUSD2 = round(0, 9) + skladHranenie = round(0, 9) + priemka = round(0, 9) + atsMarkirovka = round(0, 9) + sborkaZakaza = round(0, 9) + uchet_price = round(0, 9) + uchet_price_usd22 = round(0, 9) + dop_rashod = round(0, 9) + dop_rashod_usd22 = round(0, 9) + + + if utid != last_utid: + ## если последняя операция не Реализация Расход, то сделаем фейковую продажу чтобы посчитать цену на сегодня ... + if last_operation != 'Расход' and last_state != 'Реализация' and last_operation != '' and False: + arr_price.append(count_price(all_params, last_utid, connect)) + + + fltr = np.asarray([utid]) + pbi_all_current_utid = nparr_all[np.in1d(nparr_all[:, 1], fltr)] + last_utid = utid + current_params = {'quantity': 0, 'sumZakupka': 0, 'sumZakupkaUSD2': 0, + 'sum_dostavka': 0, 'sum_NAT': 0, 'sum_production': 0, 'sum_zatratiMP': 0, 'sum_custom': 0, 'sum_skladHranenie': 0, 'sum_Priemka': 0, + 'sum_AtsMarkirovka': 0, 'sum_SborkaZakaza': 0, 'sum_dostavkaUSD2': 0, 'sum_NATUSD2': 0, 'sum_productionUSD2': 0, 'sum_customUSD2': 0, + 'sum_zakupkaUSD2': 0, 'sum_DopRashod': 0, 'sum_DopRashodUSD2': 0, + 'counter': 0} + last_string_values = {'quantity': 0, 'sumZakupka': 0, 'sumZakupkaUSD2': 0, + 'sum_dostavka': 0, 'sum_NAT': 0, 'sum_production': 0, 'sum_zatratiMP': 0, 'sum_custom': 0, 'sum_skladHranenie': 0, 'sum_Priemka': 0, + 'sum_AtsMarkirovka': 0, 'sum_SborkaZakaza': 0, 'sum_dostavkaUSD2': 0, 'sum_NATUSD2': 0, 'sum_productionUSD2': 0, 'sum_customUSD2': 0, + 'sum_DopRashod': 0, 'sum_DopRashodUSD2': 0, + 'sum_zakupkaUSD2': 0} + + all_params = find_sumof_total(pbi_all_current_utid, date, str[0], current_params, last_string_values) + current_params = all_params.copy() + + + last_operation = str[12] + last_state = str[13] + sale_quantity = str[2] + + if str[9] > 0: + usd2_course = str[9] + else: + usd2_course = 1 + + sum_quantity = all_params['quantity'] + sum_zakupka = all_params['sumZakupka'] + sum_zakupkaUSD2 = all_params['sumZakupkaUSD2'] + sum_dostavka = all_params['sum_dostavka'] + sum_dostavkaUSD2 = all_params['sum_dostavkaUSD2'] + sum_NAT = all_params['sum_NAT'] + sum_NATUSD2 = all_params['sum_NATUSD2'] + sum_production = all_params['sum_production'] + sum_productionUSD2 = all_params['sum_productionUSD2'] + sum_zatratiMP = all_params['sum_zatratiMP'] + sum_custom = all_params['sum_custom'] + sum_customUSD2 = all_params['sum_customUSD2'] + sum_skladHranenie = all_params['sum_skladHranenie'] + sum_Priemka = all_params['sum_Priemka'] + sum_AtsMarkirovka = all_params['sum_AtsMarkirovka'] + sum_SborkaZakaza = all_params['sum_SborkaZakaza'] + sum_DopRashod = all_params['sum_DopRashod'] + sum_DopRashodUSD2 = all_params['sum_DopRashodUSD2'] + + + if (str[12] == 'Приход') and str[13] != 'Ввод остатков до 22': + + uchet_price = 0 + uchet_price_usd22 = 0 + uchet_stoimost = 0 + uchet_stoimost_usd22 = 0 + + zakupkaRUB = round(sum_zakupka, 9) + zakupkaUSD2 = round(sum_zakupkaUSD2, 9) + + + if sum_quantity != 0: + dostavka = round(sum_dostavka, 9) + dostavkaUSD2 = round(sum_dostavkaUSD2, 9) + NAT = round(sum_NAT, 9) + NATUSD2 = round(sum_NATUSD2, 9) + production = round(sum_production, 9) + productionUSD2 = round(sum_productionUSD2, 9) + zatratiMP = round(sum_zatratiMP, 9) + custom = round(sum_custom, 9) + customUSD2 = round(sum_customUSD2, 9) + skladHranenie = round(sum_skladHranenie, 9) + priemka = round(sum_Priemka, 9) + atsMarkirovka = round(sum_AtsMarkirovka, 9) + sborkaZakaza = round(sum_SborkaZakaza, 9) + dop_rashod = round(sum_DopRashod, 9) + dop_rashod_usd22 = round(sum_DopRashodUSD2, 9) + + uchet_price = round((dostavka + NAT + zakupkaRUB + custom + production) / sum_quantity, 9) + uchet_price_usd22 = round((dostavkaUSD2 + NATUSD2 + zakupkaUSD2 + customUSD2 + productionUSD2) / sum_quantity, 9) + + if sale_quantity != 0: + uchet_stoimost = round(uchet_price * sale_quantity, 9) + uchet_stoimost_usd22 = round(uchet_price_usd22 * sale_quantity, 9) + + + arr_sebes.append((uchet_stoimost, uchet_stoimost_usd22, uchet_price, uchet_price_usd22, id)) + + + elif str[12] == 'Расход': + + if sale_quantity != 0: + + if sum_zakupka < 0: + sum_zakupka = 0 + + if sale_quantity > sum_quantity or sum_quantity == 0: + zakupkaRUB = round(sum_zakupka, 9) + zakupkaUSD2 = round(sum_zakupkaUSD2, 9) + else: + zakupkaRUB = round(decimal.Decimal(sum_zakupka) / sum_quantity * sale_quantity, 9) + zakupkaUSD2 = round(decimal.Decimal(sum_zakupkaUSD2) / sum_quantity * sale_quantity, 9) + + #zakupkaUSD2 = round(sum_zakupkaUSD2 / usd2_course, 15) + + if sale_quantity > sum_quantity or sum_quantity == 0: + dostavka = round(sum_dostavka, 9) + dostavkaUSD2 = round(sum_dostavkaUSD2, 9) + NAT = round(sum_NAT, 9) + NATUSD2 = round(sum_NATUSD2, 9) + production = round(sum_production, 9) + productionUSD2 = round(sum_productionUSD2, 9) + zatratiMP = round(sum_zatratiMP, 9) + custom = round(sum_custom, 9) + customUSD2 = round(sum_customUSD2, 9) + skladHranenie = round(sum_skladHranenie, 9) + priemka = round(sum_Priemka, 9) + atsMarkirovka = round(sum_AtsMarkirovka, 9) + sborkaZakaza = round(sum_SborkaZakaza, 9) + dop_rashod = round(sum_DopRashod, 9) + dop_rashod_usd22 = round(sum_DopRashodUSD2, 9) + else: + dostavka = round(sum_dostavka / sum_quantity * sale_quantity, 9) + dostavkaUSD2 = round(sum_dostavkaUSD2 / sum_quantity * sale_quantity, 9) + NAT = round(sum_NAT / sum_quantity * sale_quantity, 9) + NATUSD2 = round(sum_NATUSD2 / sum_quantity * sale_quantity, 9) + production = round(sum_production / sum_quantity * sale_quantity, 9) + productionUSD2 = round(sum_productionUSD2 / sum_quantity * sale_quantity, 9) + zatratiMP = round(sum_zatratiMP / sum_quantity * sale_quantity, 9) + custom = round(sum_custom / sum_quantity * sale_quantity, 9) + customUSD2 = round(sum_customUSD2 / sum_quantity * sale_quantity, 9) + skladHranenie = round(sum_skladHranenie / sum_quantity * sale_quantity, 9) + priemka = round(sum_Priemka / sum_quantity * sale_quantity, 9) + atsMarkirovka = round(sum_AtsMarkirovka / sum_quantity * sale_quantity, 9) + sborkaZakaza = round(sum_SborkaZakaza / sum_quantity * sale_quantity, 9) + dop_rashod = round(sum_DopRashod / sum_quantity * sale_quantity, 9) + dop_rashod_usd22 = round(sum_DopRashodUSD2 / sum_quantity * sale_quantity, 9) + + + last_string_values = {'quantity': sale_quantity, 'sumZakupka': zakupkaRUB, 'sumZakupkaUSD2': zakupkaUSD2, + 'sum_dostavka': dostavka, + 'sum_NAT': NAT, 'sum_production': production, 'sum_zatratiMP': zatratiMP, + 'sum_custom': custom, 'sum_skladHranenie': skladHranenie, 'sum_Priemka': priemka, + 'sum_AtsMarkirovka': atsMarkirovka, 'sum_SborkaZakaza': sborkaZakaza, + 'sum_dostavkaUSD2': dostavkaUSD2, 'sum_NATUSD2': NATUSD2, 'sum_productionUSD2': productionUSD2, 'sum_customUSD2': customUSD2, + 'sum_DopRashod': dop_rashod, 'sum_DopRashodUSD2': dop_rashod_usd22} + + if zakupkaRUB != 0 or zakupkaUSD2 != 0 or NAT != 0 or production != 0 or dostavka != 0 or custom != 0: + uchet_stoimost = round((dostavka + NAT + zakupkaRUB + custom + production), 9) + uchet_stoimost_usd22 = round((dostavkaUSD2 + NATUSD2 + zakupkaUSD2 + customUSD2 + productionUSD2), 9) + uchet_price = round((dostavka + NAT + zakupkaRUB + custom + production) / sale_quantity, 9) + uchet_price_usd22 = round((dostavkaUSD2 + NATUSD2 + zakupkaUSD2 + customUSD2 + productionUSD2) / sale_quantity, 9) + + arr_sales.append( + (float(-zakupkaRUB), float(-zakupkaUSD2), float(-dostavka), float(-production), float(-NAT), float(-zatratiMP), float(-custom), + float(-skladHranenie), float(uchet_stoimost), + float(uchet_stoimost_usd22), float(uchet_price), float(uchet_price_usd22), utid, float(-priemka), float(-atsMarkirovka), float(-sborkaZakaza), + float(-dostavkaUSD2), float(-NATUSD2), float(-productionUSD2), float(-customUSD2), float(-dop_rashod), float(-dop_rashod_usd22), + id)) + + if str[13] == 'Производство товара': + arr_production.append((str[10], str[1], float(uchet_price), float(uchet_price_usd22))) + + + # break + + if ind % 10000 == 0: + print(time.ctime(), ' ', ind, 'проходов') + + if len(arr_price) > 0 and False: + insert_to_DB_UchetPrice(arr_price, connect) + + if len(arr_production) > 0 and manufacture: + insert_to_DB_Production(arr_production, connect) + + + if upload and manufacture == False: + if len(arr_sales) > 0: + print(time.ctime(), ' записей sales: ', len(arr_sales)) + update_to_DB_Sales(arr_sales, connect, '2022') + + if len(arr_sebes) > 0: + print(time.ctime(), ' записей sebest: ', len(arr_sebes)) + update_to_DB_sebest(arr_sebes, connect, '2022') + + + upload = False + + +def fill_table_sebestoim2022(connect, skip = False): + + if skip: + return + + + #флаг для обработки без заполнения таблиц ... + prepare_table = True + fill_AtsMarkirovka = True + fill_DopRashod = True + fill_Dostavka = True + fill_Zakupka = True + fill_ZatratiMp = False + fill_Pereschet = True + fill_PereschetSklad = True + fill_Priemka = True + fill_Prodaji = True + fill_Proizvodstvo = True + fill_Sborka = True + + if prepare_table: + print('Подготовка таблицы СебестоимостьОт2022 ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Подготовка таблицы СебестоимостьОт2022]') + + # заполним таблицы данными закупки ... + if fill_AtsMarkirovka: + print('Заполнение таблицы данными: АтсМаркировка ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(АтсМаркировка)]') + + if fill_DopRashod: + print('Заполнение таблицы данными: Доп расходы ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(ДопРасходы)]') + + if fill_Dostavka: + print('Заполнение таблицы данными: Доставка ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(Доставка)]') + + if fill_Zakupka: + print('Заполнение таблицы данными: Закупка ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(Закупка)]') + + if fill_ZatratiMp: + print('Заполнение таблицы данными: ЗатратыМП ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(ЗатратыМП)]') + + if fill_Pereschet: + print('Заполнение таблицы данными: Пересчет ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(Перерасчет)]') + + if fill_PereschetSklad: + print('Заполнение таблицы данными: Пересчет ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(ПерерасчетСкладскойКонтур)]') + + if fill_Priemka: + print('Заполнение таблицы данными: Приемка ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(Приемка)]') + + if fill_Prodaji: + print('Заполнение таблицы данными: Продажи ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(Продажи)]') + + if fill_Proizvodstvo: + print('Заполнение таблицы данными: Производство ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(Производство)]') + + if fill_Sborka: + print('Заполнение таблицы данными: Сборка ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(Сборка)]') + +def count_price(all_params, last_utid, conn): + arr_price = [] + uchet_price = 0 + uchet_price_usd22 = 0 + sale_quantity = 1 + sum_quantity = all_params['quantity'] + sum_zakupka = all_params['sumZakupka'] + sum_zakupkaUSD2 = all_params['sumZakupkaUSD2'] + sum_dostavka = all_params['sum_dostavka'] + sum_dostavkaUSD2 = all_params['sum_dostavkaUSD2'] + sum_NAT = all_params['sum_NAT'] + sum_NATUSD2 = all_params['sum_NATUSD2'] + sum_production = all_params['sum_production'] + sum_productionUSD2 = all_params['sum_productionUSD2'] + sum_custom = all_params['sum_custom'] + sum_customUSD2 = all_params['sum_customUSD2'] + + + if sale_quantity != 0: + + + if sale_quantity > sum_quantity or sum_quantity == 0: + zakupkaRUB = round(sum_zakupka, 9) + zakupkaUSD2 = round(sum_zakupkaUSD2, 9) + else: + zakupkaRUB = round(decimal.Decimal(sum_zakupka) / sum_quantity * sale_quantity, 9) + zakupkaUSD2 = round(decimal.Decimal(sum_zakupkaUSD2) / sum_quantity * sale_quantity, 9) + + + if sale_quantity > sum_quantity or sum_quantity == 0: + dostavka = round(sum_dostavka, 9) + dostavkaUSD2 = round(sum_dostavkaUSD2, 9) + NAT = round(sum_NAT, 9) + NATUSD2 = round(sum_NATUSD2, 9) + production = round(sum_production, 9) + productionUSD2 = round(sum_productionUSD2, 9) + custom = round(sum_custom, 9) + customUSD2 = round(sum_customUSD2, 9) + else: + dostavka = round(sum_dostavka / sum_quantity * sale_quantity, 9) + dostavkaUSD2 = round(sum_dostavkaUSD2 / sum_quantity * sale_quantity, 9) + NAT = round(sum_NAT / sum_quantity * sale_quantity, 9) + NATUSD2 = round(sum_NATUSD2 / sum_quantity * sale_quantity, 9) + production = round(sum_production / sum_quantity * sale_quantity, 9) + productionUSD2 = round(sum_productionUSD2 / sum_quantity * sale_quantity, 9) + custom = round(sum_custom / sum_quantity * sale_quantity, 9) + customUSD2 = round(sum_customUSD2 / sum_quantity * sale_quantity, 9) + + + + if zakupkaRUB != 0 or zakupkaUSD2 != 0 or NAT != 0 or production != 0 or dostavka != 0 or custom != 0: + uchet_price = round((dostavka + NAT + zakupkaRUB + custom + production) / sale_quantity, 9) + uchet_price_usd22 = round((dostavkaUSD2 + NATUSD2 + zakupkaUSD2 + customUSD2 + productionUSD2) / sale_quantity, 9) + + + return (last_utid, float(uchet_price), float(uchet_price_usd22)) + #arr_price.append((last_utid, float(uchet_price), float(uchet_price_usd22))) + #if len(arr_price) > 0: + # insert_to_DB_UchetPrice(arr_price, conn) + + + + + + + + +def insert_to_DB_UchetPrice(arr, conn): + try: + cursor = conn.cursor() + conn.autocommit = False + cursor.fast_executemany = True + table = '[pbiProd].[УчетнаяЦенаПоСебестоимости]' + + cursor.executemany(""" + INSERT INTO [mag_pbi].[pbiProd].[УчетнаяЦенаПоСебестоимости] + ( [Период], [artic_id], [Учетная цена], [Учетная цена USD2+2]) + VALUES (CONVERT(date, GETDATE()), ?, ?, ?); + """, arr) + + + except pyodbc.DatabaseError as err: + print('ошибка', err) + conn.rollback() + else: + conn.commit() + print(time.ctime(), 'обновлено', len(arr), ': записей') + finally: + conn.autocommit = True + + + + +union_sebes = True +print('start time', time.ctime()) +connect = sql_connect() +ComputeManufacture = False +maxLvl = 1 + +if ComputeManufacture: + maxLvl = 4 + exec_procedure(connect, '[pbiProd].[Подготовка Производство: единая процедура для подготовки]') + + + +for stRange in range(0, maxLvl): + # Заполнение таблицы + skip = False + fill_table_sebestoim2022(connect, skip) + + if True: + group = '[2k]' + max_counter = getMaxCounter(connect, group) + print('Группа: ', group, ' Всего групп - ', max_counter) + for counter in range(max_counter): + counter += 1 + count_sebest(connect, counter, group) + print(time.ctime(), ' группа ', counter, ' обработана') + + + # Расчитаем товары которые учавствуют в производстве + if ComputeManufacture: + start_range = 0 + for i in range(stRange, stRange + 1): + for i_range in range(2000, 20000, 2000): + end_range = i_range + count_sebest(connect, "", "", i, True, start_range, end_range) + start_range = i_range + + # Нужно добавить 1с_id в таблицу .... + exec_procedure(connect, '[pbiProd].[Производство: Заполнить 1сid для СебестоимостьПроизводствоОт2022]') + + +# заполним сводную таблицу (финальную) для загрузки в пби ... +if union_sebes: + print('Объединение в сводную таблицу ~ 10 мин ...') + exec_procedure(connect, '[pbiProd].[ЗаполнитьСебестоимостьСводныйОт2022]') + + +connect.close() +print('end time ', time.ctime()) diff --git a/analytics/python skript/old/РасчетСебестоимостиСПроизводством.py b/analytics/python skript/old/РасчетСебестоимостиСПроизводством.py new file mode 100644 index 0000000..0200488 --- /dev/null +++ b/analytics/python skript/old/РасчетСебестоимостиСПроизводством.py @@ -0,0 +1,951 @@ +import decimal +import time +import numpy as np +import pyodbc + + +def sql_connect(): + server = '192.168.35.207' + server = 'cloud.magok.ru' + database = 'mag_pbi' + username = 'goglev' + password = 'BOMoGbUZ1p' + connection_string = f'DRIVER={{ODBC Driver 17 for SQL Server}};SERVER={server};DATABASE={database};UID={username};PWD={password}' + + conn = pyodbc.connect(connection_string) + print("successfully connected...") + print("#" * 20) + return conn + + +def get_totals(conn, counter, group): + sql_query = """ + SELECT --TOP (1000) + id, -- 0 + artic_id, -- 1 + COALESCE([Количество], 0) AS [Количество], -- 2 + COALESCE([ЗатратыМП], 0) AS ЗатратыМП, -- 3 + COALESCE([Закупка], 0) AS [Закупка], -- 4 + COALESCE([Доставка], 0) AS [Доставка], -- 5 + COALESCE([НДС], 0) AS [НДС], -- 6 + COALESCE([Производство], 0) AS [Производство], -- 7 + COALESCE([Таможня], 0) AS [Таможня], -- 8 + [Курс usd2] AS [Курс usd2], -- 9 + [Период] AS [Период], -- 10 + [Валюта документа] AS [Валюта документа], -- 11 + [Вид операции] AS [Вид операции], -- 12 + [Статья] AS [Статья], -- 13 + COALESCE([ЗатратыСкладХранение], 0) AS [ЗатратыСкладХранение], -- 14 + COALESCE([Приемка], 0) AS [Приемка], -- 15 + COALESCE([АтсМаркировка], 0) AS [АтсМаркировка], -- 16 + COALESCE([СборкаЗаказа], 0) AS [СборкаЗаказа], -- 17 + COALESCE([Закупка, usd2], 0) AS [Закупка, usd2], -- 18 + COALESCE([Доставка USD2+2], 0) AS [Доставка USD2+2], -- 19 + COALESCE([НДС USD2+2], 0) AS [НДС USD2+2], -- 20 + COALESCE([Таможня USD2+2], 0) AS [Таможня USD2+2], -- 21 + COALESCE([Производство USD2+2], 0) AS [Производство USD2+2], -- 22 + COALESCE([Доп расходы], 0) AS [Доп расходы], -- 23 + COALESCE([Доп расходы USD2+2], 0) AS [Доп расходы USD2+2] -- 24 + FROM + ( + SELECT + id, + artic_id, + COALESCE([Количество], 0) AS [Количество], + [ЗатратыМП], + COALESCE([Закупка], 0) AS [Закупка], + COALESCE([Доставка], 0) AS [Доставка], + [НДС], + COALESCE([Производство], 0) AS [Производство], + COALESCE([Таможня], 0) AS [Таможня], + [Курс usd2], + [Период], + [Валюта документа], + [Вид операции], + [Статья], + [ЗатратыСкладХранение], + [Приемка], + [АтсМаркировка], + [СборкаЗаказа], + COALESCE([Закупка, usd2], 0) AS [Закупка, usd2], + COALESCE([Доставка USD2+2], 0) AS [Доставка USD2+2], + COALESCE([НДС USD2+2], 0) AS [НДС USD2+2], + COALESCE([Таможня USD2+2], 0) AS [Таможня USD2+2], + COALESCE([Производство USD2+2], 0) AS [Производство USD2+2], + COALESCE([Доп расходы], 0) AS [Доп расходы], + COALESCE([Доп расходы USD2+2], 0) AS [Доп расходы USD2+2] + + FROM [mag_pbi].[pbiProd].[СебестоимостьОт2022] + WHERE + 1=1 + --and [artic_id] = 'c4bbfb4b-cf25-11ef-998c-b49691d57efd' + and [artic_id] IN (SELECT + [artic_id] + FROM [mag_pbi].[pbiProd].[GroupsOfNomenclature] + where """ + group + """ = """ + str(counter) + """) + and [Период] >= '2022' + + + UNION ALL + + SELECT + id, + artic_id, + COALESCE([Количество], 0), + [ЗатратыМП], + COALESCE([Закупка], 0), + COALESCE([Доставка], 0), + [НДС], + COALESCE([Сборка], 0), + COALESCE([Таможня], 0), + 0, + '2021', + NULL, + 'Приход', + 'Ввод остатков до 22', + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + FROM [mag_pbi].[pbiProd].[СебестоимостьИтогиДо2022] + where + 1 = 1 + --and [artic_id] = 'c4bbfb4b-cf25-11ef-998c-b49691d57efd' + and [artic_id] IN (SELECT + [artic_id] + FROM [mag_pbi].[pbiProd].[GroupsOfNomenclature] + where """ + group + """ = """ + str(counter) + """) + ) AS tabMain + --WHERE 1=1 + + ORDER BY + [artic_id], [Период] ASC, [Закупка] DESC; + """ + cursor = conn.cursor() + cursor.execute(sql_query) + pbi_totals = cursor.fetchall() + print(time.ctime(), ' Записей к обработке: ', len(pbi_totals)) + return pbi_totals + + + +def get_totalsManufacture(conn, manufactureLevel, start_range, end_range): + sql_query = """ + SELECT --TOP (1000) + id, -- 0 + artic_id, -- 1 + COALESCE([Количество], 0) AS [Количество], -- 2 + COALESCE([ЗатратыМП], 0) AS ЗатратыМП, -- 3 + COALESCE([Закупка], 0) AS [Закупка], -- 4 + COALESCE([Доставка], 0) AS [Доставка], -- 5 + COALESCE([НДС], 0) AS [НДС], -- 6 + COALESCE([Производство], 0) AS [Производство], -- 7 + COALESCE([Таможня], 0) AS [Таможня], -- 8 + [Курс usd2] AS [Курс usd2], -- 9 + [Период] AS [Период], -- 10 + [Валюта документа] AS [Валюта документа], -- 11 + [Вид операции] AS [Вид операции], -- 12 + [Статья] AS [Статья], -- 13 + COALESCE([ЗатратыСкладХранение], 0) AS [ЗатратыСкладХранение], -- 14 + COALESCE([Приемка], 0) AS [Приемка], -- 15 + COALESCE([АтсМаркировка], 0) AS [АтсМаркировка], -- 16 + COALESCE([СборкаЗаказа], 0) AS [СборкаЗаказа], -- 17 + COALESCE([Закупка, usd2], 0) AS [Закупка, usd2], -- 18 + COALESCE([Доставка USD2+2], 0) AS [Доставка USD2+2], -- 19 + COALESCE([НДС USD2+2], 0) AS [НДС USD2+2], -- 20 + COALESCE([Таможня USD2+2], 0) AS [Таможня USD2+2], -- 21 + COALESCE([Производство USD2+2], 0) AS [Производство USD2+2], -- 22 + COALESCE([Доп расходы], 0) AS [Доп расходы], -- 23 + COALESCE([Доп расходы USD2+2], 0) AS [Доп расходы USD2+2] -- 24 + FROM + ( + SELECT + id, + artic_id, + COALESCE([Количество], 0) AS [Количество], + [ЗатратыМП], + COALESCE([Закупка], 0) AS [Закупка], + COALESCE([Доставка], 0) AS [Доставка], + [НДС], + COALESCE([Производство], 0) AS [Производство], + COALESCE([Таможня], 0) AS [Таможня], + [Курс usd2], + [Период], + [Валюта документа], + [Вид операции], + [Статья], + [ЗатратыСкладХранение], + [Приемка], + [АтсМаркировка], + [СборкаЗаказа], + COALESCE([Закупка, usd2], 0) AS [Закупка, usd2], + COALESCE([Доставка USD2+2], 0) AS [Доставка USD2+2], + COALESCE([НДС USD2+2], 0) AS [НДС USD2+2], + COALESCE([Таможня USD2+2], 0) AS [Таможня USD2+2], + COALESCE([Производство USD2+2], 0) AS [Производство USD2+2], + COALESCE([Доп расходы], 0) AS [Доп расходы], + COALESCE([Доп расходы USD2+2], 0) AS [Доп расходы USD2+2] + FROM [mag_pbi].[pbiProd].[СебестоимостьОт2022] + WHERE + 1=1 + --and [artic_id] = '24d0c24b-3a60-11e9-ae9c-b496910dcfd6' + and [1c_id] IN (SELECT + [1c_id] + FROM [mag_pbi].[pbiProd].[НоменклатураВПроизводствеПоУровням] + where [УровеньПроизводства] = """ + str(manufactureLevel) + """ + and [RowNum] BETWEEN """ + str(start_range) + """ AND """ + str(end_range) + """ + --and [1c_id] = 0x9981B49691D57EFD11EDDE7DA97A5E64 + ) + and [Период] >= '2022' + + + UNION ALL + + SELECT + id, + artic_id, + COALESCE([Количество], 0), + [ЗатратыМП], + COALESCE([Закупка], 0), + COALESCE([Доставка], 0), + [НДС], + COALESCE([Сборка], 0), + COALESCE([Таможня], 0), + 0, + '2021', + NULL, + 'Приход', + 'Ввод остатков до 22', + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + FROM [mag_pbi].[pbiProd].[СебестоимостьИтогиДо2022] + where + 1 = 1 + --and [artic_id] = '24d0c24b-3a60-11e9-ae9c-b496910dcfd6' + and [1c_id] IN (SELECT + [1c_id] + FROM [mag_pbi].[pbiProd].[НоменклатураВПроизводствеПоУровням] + where [УровеньПроизводства] = """ + str(manufactureLevel) + """ + and [RowNum] BETWEEN """ + str(start_range) + """ AND """ + str(end_range) + """ + --and [1c_id] = 0x9981B49691D57EFD11EDDE7DA97A5E64 + ) + ) AS tabMain + --WHERE 1=1 + + ORDER BY + [artic_id], [Период] ASC, [Закупка] DESC; + """ + cursor = conn.cursor() + cursor.execute(sql_query) + pbi_totals = cursor.fetchall() + print(time.ctime(), ' Записей к обработке: ', len(pbi_totals)) + return pbi_totals + +def find_sumof_total(sebes_sales, date, current_sales_id, current_params, last_string_values): + quantity = current_params['quantity'] + sumZakupka = current_params['sumZakupka'] + sumZakupkaUSD2 = current_params['sumZakupkaUSD2'] + sum_dostavka = current_params['sum_dostavka'] + sum_dostavkaUSD2 = current_params['sum_dostavkaUSD2'] + sum_NAT = current_params['sum_NAT'] + sum_NATUSD2 = current_params['sum_NATUSD2'] + sum_production = current_params['sum_production'] + sum_productionUSD2 = current_params['sum_productionUSD2'] + sum_zatratiMP = current_params['sum_zatratiMP'] + sum_custom = current_params['sum_custom'] + sum_customUSD2 = current_params['sum_customUSD2'] + sum_skladHranenie = current_params['sum_skladHranenie'] + sum_Priemka = current_params['sum_Priemka'] + sum_AtsMarkirovka = current_params['sum_AtsMarkirovka'] + sum_SborkaZakaza = current_params['sum_SborkaZakaza'] + sum_DopRashod = current_params['sum_DopRashod'] + sum_DopRashodUSD2 = current_params['sum_DopRashodUSD2'] + i = current_params['counter'] + len_sebes_sales = len(sebes_sales) + while i < len_sebes_sales: + try: + curr_str = sebes_sales[i] + except: + print('Ошибка в иттераторе, тек ид =', current_sales_id) + print(i) + print(len_sebes_sales) + break + + if curr_str[10] > date or current_sales_id != curr_str[0]: + break + else: + i += 1 + + if curr_str[12] == 'Приход': + + # кажется что можно и нужно удалить ... + if curr_str[13] == 'Закупка' or curr_str[13] == 'Ввод остатков до 22' or curr_str[13] == 'Производство товара' or curr_str[13] == 'Пересчет товара': + quantity += curr_str[2] + + + if curr_str[9] > 0: + usd2_course = curr_str[9] + else: + if curr_str[13] == 'Ввод остатков до 22': + # для ввода остатков возьём курс на 1 января 2023 года + usd2_course = 75.7785 + else: + usd2_course = 1 + + sumZakupka += curr_str[4] + if curr_str[13] == 'Ввод остатков до 22': + sumZakupkaUSD2 += decimal.Decimal(float(sumZakupka) / usd2_course) + else: + sumZakupkaUSD2 += curr_str[18] + + + #if curr_str[11] == 'руб.': + # sumZakupkaUSD += sumZakupka / usd2_course + + sum_dostavka += curr_str[5] + sum_dostavkaUSD2 += curr_str[19] + sum_NAT += curr_str[6] + sum_NATUSD2 += curr_str[20] + sum_production += curr_str[7] + sum_productionUSD2 += curr_str[22] + sum_zatratiMP += curr_str[3] + sum_custom += curr_str[8] + sum_customUSD2 += curr_str[21] + sum_skladHranenie += curr_str[14] + sum_Priemka += curr_str[15] + sum_AtsMarkirovka += curr_str[16] + sum_SborkaZakaza += curr_str[17] + sum_DopRashod += curr_str[23] + sum_DopRashodUSD2 += curr_str[24] + + if curr_str[12] == 'Расход': + quantity -= last_string_values['quantity'] + sumZakupka -= last_string_values['sumZakupka'] + sumZakupkaUSD2 -= last_string_values['sumZakupkaUSD2'] + sum_dostavka -= last_string_values['sum_dostavka'] + sum_dostavkaUSD2 -= last_string_values['sum_dostavkaUSD2'] + sum_NAT -= last_string_values['sum_NAT'] + sum_NATUSD2 -= last_string_values['sum_NATUSD2'] + sum_production -= last_string_values['sum_production'] + sum_productionUSD2 -= last_string_values['sum_productionUSD2'] + sum_zatratiMP -= last_string_values['sum_zatratiMP'] + sum_custom -= last_string_values['sum_custom'] + sum_customUSD2 -= last_string_values['sum_customUSD2'] + sum_skladHranenie -= last_string_values['sum_skladHranenie'] + sum_Priemka -= last_string_values['sum_Priemka'] + sum_AtsMarkirovka -= last_string_values['sum_AtsMarkirovka'] + sum_SborkaZakaza -= last_string_values['sum_SborkaZakaza'] + sum_DopRashod -= last_string_values['sum_DopRashod'] + sum_DopRashodUSD2 -= last_string_values['sum_DopRashodUSD2'] + + if quantity <= 0: + quantity = 0 + sumZakupka = 0 + sumZakupkaUSD2 = 0 + sum_dostavka = 0 + sum_NAT = 0 + sum_production = 0 + sum_zatratiMP = 0 + sum_custom = 0 + sum_skladHranenie = 0 + sum_Priemka = 0 + sum_AtsMarkirovka = 0 + sum_SborkaZakaza = 0 + sum_dostavkaUSD2 = 0 + sum_NATUSD2 = 0 + sum_productionUSD2 = 0 + sum_customUSD2 = 0 + sum_DopRashod = 0 + sum_DopRashodUSD2 = 0 + + + return {'quantity': quantity, 'sumZakupka': sumZakupka, 'sumZakupkaUSD2': sumZakupkaUSD2, + 'sum_dostavka': sum_dostavka, + 'sum_NAT': sum_NAT, 'sum_production': sum_production, 'sum_zatratiMP': sum_zatratiMP, 'sum_custom': sum_custom, + 'sum_skladHranenie': sum_skladHranenie, 'sum_Priemka': sum_Priemka, 'sum_AtsMarkirovka': sum_AtsMarkirovka, 'sum_SborkaZakaza': sum_SborkaZakaza, + 'sum_dostavkaUSD2': sum_dostavkaUSD2, 'sum_NATUSD2': sum_NATUSD2, 'sum_productionUSD2': sum_productionUSD2, 'sum_customUSD2': sum_customUSD2, + 'sum_DopRashod': sum_DopRashod, 'sum_DopRashodUSD2': sum_DopRashodUSD2, + 'counter': i} + + +def insert_to_DB_Production(arr, conn): + try: + cursor = conn.cursor() + conn.autocommit = False + cursor.fast_executemany = True + table = '[СебестоимостьПроизводствоОт2022]' + + cursor.executemany(""" + INSERT INTO [mag_pbi].[pbiProd].[СебестоимостьПроизводствоОт2022] + ([Период], [artic_id], [Учетная цена], [Учетная цена USD2+2]) + VALUES (?, ?, ?, ?); + """, arr) + + + except pyodbc.DatabaseError as err: + print('ошибка', err) + conn.rollback() + else: + conn.commit() + print(time.ctime(), 'обновлено', len(arr), ': записей') + finally: + conn.autocommit = True + +def update_to_DB_Sales(arr, conn, year): + try: + cursor = conn.cursor() + conn.autocommit = False + cursor.fast_executemany = True + table = '[СебестоимостьОт2022]' + if year == '2022': + table = '[СебестоимостьОт2022]' + elif year == '2023': + table = '[Себестоимость2023]' + elif year == '2024': + table = '[Себестоимость2024]' + + cursor.executemany( + """UPDATE [mag_pbi].[pbiProd].""" + table + """ + SET + [Закупка] = ? -- 0 + , [Закупка, usd2] = ? -- 1 + , [Доставка] = ? -- 2 + , [Производство] = ? -- 3 + , [НДС] = ? -- 4 + , [ЗатратыМП] = ? -- 5 + , [Таможня] = ? -- 6 + , [ЗатратыСкладХранение] = ? -- 7 + , [Учетная стоимость] = ? -- 8 + , [Учетная стоимость USD2+2] = ? -- 9 + , [Учетная цена] = ? -- 10 + , [Учетная цена USD2+2] = ? -- 11 + , [artic_id] = ? -- 12 + , [Приемка] = ? -- 13 + , [АтсМаркировка] = ? -- 14 + , [СборкаЗаказа] = ? -- 15 + , [Доставка USD2+2] = ? -- 16 + , [НДС USD2+2] = ? -- 17 + , [Таможня USD2+2] = ? -- 18 + , [Производство USD2+2] = ? -- 19 + , [Доп расходы] = ? -- 20 + , [Доп расходы USD2+2] = ? -- 21 + WHERE id = ?""", + arr) + + + except pyodbc.DatabaseError as err: + print('ошибка', err) + conn.rollback() + else: + conn.commit() + print(time.ctime(), 'обновлено', len(arr), ': записей') + finally: + conn.autocommit = True + + +def update_to_DB_sebest(arr, conn, year): + try: + cursor = conn.cursor() + conn.autocommit = False + cursor.fast_executemany = True + table = '[СебестоимостьОт2022]' + # if year == '2022': + # table = '[СебестоимостьОт2022]' + # elif year == '2023': + # table = '[Себестоимость2023]' + # elif year == '2024': + # table = '[Себестоимость2024]' + cursor.executemany( + "UPDATE [mag_pbi].[pbiProd]." + table + " SET [Учетная стоимость] = ?, [Учетная стоимость USD2+2] = ?, [Учетная цена] = ?, [Учетная цена USD2+2] = ? WHERE id = ?", + arr) + + + except pyodbc.DatabaseError as err: + print('ошибка', err) + conn.rollback() + else: + conn.commit() + print(time.ctime(), 'обновлено', len(arr), ': записей') + finally: + conn.autocommit = True + + +def exec_procedure(conn, procedure_name): + sql_query = 'EXEC ' + procedure_name + cursor = conn.cursor() + cursor.execute(sql_query).commit() + + +def getMaxCounter(conn, group): + sql_query = "SELECT MAX(" + group + ") FROM [mag_pbi].[pbiProd].[GroupsOfNomenclature]" + + cursor = conn.cursor() + cursor.execute(sql_query) + maxCounter = cursor.fetchall() + return maxCounter[0][0] + + + +def count_sebest(connect, counter = '2k', group = '1', manufactureLevel = 0, manufacture = False, start_range = 0, end_range = 0): + upload = True + ind = 0 + arr_sebes = [] + arr_sales = [] + arr_production = [] + arr_price = [] + last_utid = '' + last_operation = '' + last_state = '' + + if manufacture: + pbi_all = get_totalsManufacture(connect, manufactureLevel, start_range, end_range) + else: + pbi_all = get_totals(connect, counter, group) + + + nparr_all = np.asarray(pbi_all) + + for str in pbi_all: + ind += 1 + date = str[10] + utid = str[1] + id = str[0] + tableGod = str[14] + zakupkaRUB = round(0, 9) + zakupkaUSD2 = round(0, 9) + NAT = round(0, 9) + NATUSD2 = round(0, 9) + zatratiMP = round(0, 9) + production = round(0, 9) + dostavka = round(0, 9) + dostavkaUSD2 = round(0, 9) + custom = round(0, 9) + customUSD2 = round(0, 9) + skladHranenie = round(0, 9) + priemka = round(0, 9) + atsMarkirovka = round(0, 9) + sborkaZakaza = round(0, 9) + uchet_price = round(0, 9) + uchet_price_usd22 = round(0, 9) + dop_rashod = round(0, 9) + dop_rashod_usd22 = round(0, 9) + + + if utid != last_utid: + ## если последняя операция не Реализация Расход, то сделаем фейковую продажу чтобы посчитать цену на сегодня ... + if last_operation != 'Расход' and last_state != 'Реализация' and last_operation != '' and False: + arr_price.append(count_price(all_params, last_utid, connect)) + + + fltr = np.asarray([utid]) + pbi_all_current_utid = nparr_all[np.in1d(nparr_all[:, 1], fltr)] + last_utid = utid + current_params = {'quantity': 0, 'sumZakupka': 0, 'sumZakupkaUSD2': 0, + 'sum_dostavka': 0, 'sum_NAT': 0, 'sum_production': 0, 'sum_zatratiMP': 0, 'sum_custom': 0, 'sum_skladHranenie': 0, 'sum_Priemka': 0, + 'sum_AtsMarkirovka': 0, 'sum_SborkaZakaza': 0, 'sum_dostavkaUSD2': 0, 'sum_NATUSD2': 0, 'sum_productionUSD2': 0, 'sum_customUSD2': 0, + 'sum_zakupkaUSD2': 0, 'sum_DopRashod': 0, 'sum_DopRashodUSD2': 0, + 'counter': 0} + last_string_values = {'quantity': 0, 'sumZakupka': 0, 'sumZakupkaUSD2': 0, + 'sum_dostavka': 0, 'sum_NAT': 0, 'sum_production': 0, 'sum_zatratiMP': 0, 'sum_custom': 0, 'sum_skladHranenie': 0, 'sum_Priemka': 0, + 'sum_AtsMarkirovka': 0, 'sum_SborkaZakaza': 0, 'sum_dostavkaUSD2': 0, 'sum_NATUSD2': 0, 'sum_productionUSD2': 0, 'sum_customUSD2': 0, + 'sum_DopRashod': 0, 'sum_DopRashodUSD2': 0, + 'sum_zakupkaUSD2': 0} + + all_params = find_sumof_total(pbi_all_current_utid, date, str[0], current_params, last_string_values) + current_params = all_params.copy() + + + last_operation = str[12] + last_state = str[13] + sale_quantity = str[2] + + if str[9] > 0: + usd2_course = str[9] + else: + usd2_course = 1 + + sum_quantity = all_params['quantity'] + sum_zakupka = all_params['sumZakupka'] + sum_zakupkaUSD2 = all_params['sumZakupkaUSD2'] + sum_dostavka = all_params['sum_dostavka'] + sum_dostavkaUSD2 = all_params['sum_dostavkaUSD2'] + sum_NAT = all_params['sum_NAT'] + sum_NATUSD2 = all_params['sum_NATUSD2'] + sum_production = all_params['sum_production'] + sum_productionUSD2 = all_params['sum_productionUSD2'] + sum_zatratiMP = all_params['sum_zatratiMP'] + sum_custom = all_params['sum_custom'] + sum_customUSD2 = all_params['sum_customUSD2'] + sum_skladHranenie = all_params['sum_skladHranenie'] + sum_Priemka = all_params['sum_Priemka'] + sum_AtsMarkirovka = all_params['sum_AtsMarkirovka'] + sum_SborkaZakaza = all_params['sum_SborkaZakaza'] + sum_DopRashod = all_params['sum_DopRashod'] + sum_DopRashodUSD2 = all_params['sum_DopRashodUSD2'] + + + if (str[12] == 'Приход') and str[13] != 'Ввод остатков до 22': + + uchet_price = 0 + uchet_price_usd22 = 0 + uchet_stoimost = 0 + uchet_stoimost_usd22 = 0 + + zakupkaRUB = round(sum_zakupka, 9) + zakupkaUSD2 = round(sum_zakupkaUSD2, 9) + + + if sum_quantity != 0: + dostavka = round(sum_dostavka, 9) + dostavkaUSD2 = round(sum_dostavkaUSD2, 9) + NAT = round(sum_NAT, 9) + NATUSD2 = round(sum_NATUSD2, 9) + production = round(sum_production, 9) + productionUSD2 = round(sum_productionUSD2, 9) + zatratiMP = round(sum_zatratiMP, 9) + custom = round(sum_custom, 9) + customUSD2 = round(sum_customUSD2, 9) + skladHranenie = round(sum_skladHranenie, 9) + priemka = round(sum_Priemka, 9) + atsMarkirovka = round(sum_AtsMarkirovka, 9) + sborkaZakaza = round(sum_SborkaZakaza, 9) + dop_rashod = round(sum_DopRashod, 9) + dop_rashod_usd22 = round(sum_DopRashodUSD2, 9) + + uchet_price = round((dostavka + NAT + zakupkaRUB + custom + production) / sum_quantity, 9) + uchet_price_usd22 = round((dostavkaUSD2 + NATUSD2 + zakupkaUSD2 + customUSD2 + productionUSD2) / sum_quantity, 9) + + if sale_quantity != 0: + uchet_stoimost = round(uchet_price * sale_quantity, 9) + uchet_stoimost_usd22 = round(uchet_price_usd22 * sale_quantity, 9) + + + arr_sebes.append((uchet_stoimost, uchet_stoimost_usd22, uchet_price, uchet_price_usd22, id)) + + + elif str[12] == 'Расход': + + if sale_quantity != 0: + + if sum_zakupka < 0: + sum_zakupka = 0 + + if sale_quantity > sum_quantity or sum_quantity == 0: + zakupkaRUB = round(sum_zakupka, 9) + zakupkaUSD2 = round(sum_zakupkaUSD2, 9) + else: + zakupkaRUB = round(decimal.Decimal(sum_zakupka) / sum_quantity * sale_quantity, 9) + zakupkaUSD2 = round(decimal.Decimal(sum_zakupkaUSD2) / sum_quantity * sale_quantity, 9) + + #zakupkaUSD2 = round(sum_zakupkaUSD2 / usd2_course, 15) + + if sale_quantity > sum_quantity or sum_quantity == 0: + dostavka = round(sum_dostavka, 9) + dostavkaUSD2 = round(sum_dostavkaUSD2, 9) + NAT = round(sum_NAT, 9) + NATUSD2 = round(sum_NATUSD2, 9) + production = round(sum_production, 9) + productionUSD2 = round(sum_productionUSD2, 9) + zatratiMP = round(sum_zatratiMP, 9) + custom = round(sum_custom, 9) + customUSD2 = round(sum_customUSD2, 9) + skladHranenie = round(sum_skladHranenie, 9) + priemka = round(sum_Priemka, 9) + atsMarkirovka = round(sum_AtsMarkirovka, 9) + sborkaZakaza = round(sum_SborkaZakaza, 9) + dop_rashod = round(sum_DopRashod, 9) + dop_rashod_usd22 = round(sum_DopRashodUSD2, 9) + else: + dostavka = round(sum_dostavka / sum_quantity * sale_quantity, 9) + dostavkaUSD2 = round(sum_dostavkaUSD2 / sum_quantity * sale_quantity, 9) + NAT = round(sum_NAT / sum_quantity * sale_quantity, 9) + NATUSD2 = round(sum_NATUSD2 / sum_quantity * sale_quantity, 9) + production = round(sum_production / sum_quantity * sale_quantity, 9) + productionUSD2 = round(sum_productionUSD2 / sum_quantity * sale_quantity, 9) + zatratiMP = round(sum_zatratiMP / sum_quantity * sale_quantity, 9) + custom = round(sum_custom / sum_quantity * sale_quantity, 9) + customUSD2 = round(sum_customUSD2 / sum_quantity * sale_quantity, 9) + skladHranenie = round(sum_skladHranenie / sum_quantity * sale_quantity, 9) + priemka = round(sum_Priemka / sum_quantity * sale_quantity, 9) + atsMarkirovka = round(sum_AtsMarkirovka / sum_quantity * sale_quantity, 9) + sborkaZakaza = round(sum_SborkaZakaza / sum_quantity * sale_quantity, 9) + dop_rashod = round(sum_DopRashod / sum_quantity * sale_quantity, 9) + dop_rashod_usd22 = round(sum_DopRashodUSD2 / sum_quantity * sale_quantity, 9) + + + last_string_values = {'quantity': sale_quantity, 'sumZakupka': zakupkaRUB, 'sumZakupkaUSD2': zakupkaUSD2, + 'sum_dostavka': dostavka, + 'sum_NAT': NAT, 'sum_production': production, 'sum_zatratiMP': zatratiMP, + 'sum_custom': custom, 'sum_skladHranenie': skladHranenie, 'sum_Priemka': priemka, + 'sum_AtsMarkirovka': atsMarkirovka, 'sum_SborkaZakaza': sborkaZakaza, + 'sum_dostavkaUSD2': dostavkaUSD2, 'sum_NATUSD2': NATUSD2, 'sum_productionUSD2': productionUSD2, 'sum_customUSD2': customUSD2, + 'sum_DopRashod': dop_rashod, 'sum_DopRashodUSD2': dop_rashod_usd22} + + if zakupkaRUB != 0 or zakupkaUSD2 != 0 or NAT != 0 or production != 0 or dostavka != 0 or custom != 0: + uchet_stoimost = round((dostavka + NAT + zakupkaRUB + custom + production), 9) + uchet_stoimost_usd22 = round((dostavkaUSD2 + NATUSD2 + zakupkaUSD2 + customUSD2 + productionUSD2), 9) + uchet_price = round((dostavka + NAT + zakupkaRUB + custom + production) / sale_quantity, 9) + uchet_price_usd22 = round((dostavkaUSD2 + NATUSD2 + zakupkaUSD2 + customUSD2 + productionUSD2) / sale_quantity, 9) + + arr_sales.append( + (float(-zakupkaRUB), float(-zakupkaUSD2), float(-dostavka), float(-production), float(-NAT), float(-zatratiMP), float(-custom), + float(-skladHranenie), float(uchet_stoimost), + float(uchet_stoimost_usd22), float(uchet_price), float(uchet_price_usd22), utid, float(-priemka), float(-atsMarkirovka), float(-sborkaZakaza), + float(-dostavkaUSD2), float(-NATUSD2), float(-productionUSD2), float(-customUSD2), float(-dop_rashod), float(-dop_rashod_usd22), + id)) + + if str[13] == 'Производство товара': + arr_production.append((str[10], str[1], float(uchet_price), float(uchet_price_usd22))) + + + # break + + if ind % 10000 == 0: + print(time.ctime(), ' ', ind, 'проходов') + + if len(arr_price) > 0 and False: + insert_to_DB_UchetPrice(arr_price, connect) + + if len(arr_production) > 0 and manufacture: + insert_to_DB_Production(arr_production, connect) + + + if upload and manufacture == False: + if len(arr_sales) > 0: + print(time.ctime(), ' записей sales: ', len(arr_sales)) + update_to_DB_Sales(arr_sales, connect, '2022') + + if len(arr_sebes) > 0: + print(time.ctime(), ' записей sebest: ', len(arr_sebes)) + update_to_DB_sebest(arr_sebes, connect, '2022') + + + upload = False + + +def fill_table_sebestoim2022(connect, skip = False): + + if skip: + return + + + #флаг для обработки без заполнения таблиц ... + prepare_table = True + fill_AtsMarkirovka = True + fill_DopRashod = True + fill_Dostavka = True + fill_Zakupka = True + fill_ZatratiMp = False + fill_Pereschet = True + fill_PereschetSklad = True + fill_Priemka = True + fill_Prodaji = True + fill_Proizvodstvo = True + fill_Sborka = True + + if prepare_table: + print('Подготовка таблицы СебестоимостьОт2022 ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Подготовка таблицы СебестоимостьОт2022]') + + # заполним таблицы данными закупки ... + if fill_AtsMarkirovka: + print('Заполнение таблицы данными: АтсМаркировка ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(АтсМаркировка)]') + + if fill_DopRashod: + print('Заполнение таблицы данными: Доп расходы ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(ДопРасходы)]') + + if fill_Dostavka: + print('Заполнение таблицы данными: Доставка ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(Доставка)]') + + if fill_Zakupka: + print('Заполнение таблицы данными: Закупка ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(Закупка)]') + + if fill_ZatratiMp: + print('Заполнение таблицы данными: ЗатратыМП ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(ЗатратыМП)]') + + if fill_Pereschet: + print('Заполнение таблицы данными: Пересчет ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(Перерасчет)]') + + if fill_PereschetSklad: + print('Заполнение таблицы данными: Пересчет ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(ПерерасчетСкладскойКонтур)]') + + if fill_Priemka: + print('Заполнение таблицы данными: Приемка ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(Приемка)]') + + if fill_Prodaji: + print('Заполнение таблицы данными: Продажи ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(Продажи)]') + + if fill_Proizvodstvo: + print('Заполнение таблицы данными: Производство ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(Производство)]') + + if fill_Sborka: + print('Заполнение таблицы данными: Сборка ~ ? мин, ? записей ...') + exec_procedure(connect, '[pbiProd].[Пакетное: Заполнить себестоимостьОт2022(Сборка)]') + +def count_price(all_params, last_utid, conn): + arr_price = [] + uchet_price = 0 + uchet_price_usd22 = 0 + sale_quantity = 1 + sum_quantity = all_params['quantity'] + sum_zakupka = all_params['sumZakupka'] + sum_zakupkaUSD2 = all_params['sumZakupkaUSD2'] + sum_dostavka = all_params['sum_dostavka'] + sum_dostavkaUSD2 = all_params['sum_dostavkaUSD2'] + sum_NAT = all_params['sum_NAT'] + sum_NATUSD2 = all_params['sum_NATUSD2'] + sum_production = all_params['sum_production'] + sum_productionUSD2 = all_params['sum_productionUSD2'] + sum_custom = all_params['sum_custom'] + sum_customUSD2 = all_params['sum_customUSD2'] + + + if sale_quantity != 0: + + + if sale_quantity > sum_quantity or sum_quantity == 0: + zakupkaRUB = round(sum_zakupka, 9) + zakupkaUSD2 = round(sum_zakupkaUSD2, 9) + else: + zakupkaRUB = round(decimal.Decimal(sum_zakupka) / sum_quantity * sale_quantity, 9) + zakupkaUSD2 = round(decimal.Decimal(sum_zakupkaUSD2) / sum_quantity * sale_quantity, 9) + + + if sale_quantity > sum_quantity or sum_quantity == 0: + dostavka = round(sum_dostavka, 9) + dostavkaUSD2 = round(sum_dostavkaUSD2, 9) + NAT = round(sum_NAT, 9) + NATUSD2 = round(sum_NATUSD2, 9) + production = round(sum_production, 9) + productionUSD2 = round(sum_productionUSD2, 9) + custom = round(sum_custom, 9) + customUSD2 = round(sum_customUSD2, 9) + else: + dostavka = round(sum_dostavka / sum_quantity * sale_quantity, 9) + dostavkaUSD2 = round(sum_dostavkaUSD2 / sum_quantity * sale_quantity, 9) + NAT = round(sum_NAT / sum_quantity * sale_quantity, 9) + NATUSD2 = round(sum_NATUSD2 / sum_quantity * sale_quantity, 9) + production = round(sum_production / sum_quantity * sale_quantity, 9) + productionUSD2 = round(sum_productionUSD2 / sum_quantity * sale_quantity, 9) + custom = round(sum_custom / sum_quantity * sale_quantity, 9) + customUSD2 = round(sum_customUSD2 / sum_quantity * sale_quantity, 9) + + + + if zakupkaRUB != 0 or zakupkaUSD2 != 0 or NAT != 0 or production != 0 or dostavka != 0 or custom != 0: + uchet_price = round((dostavka + NAT + zakupkaRUB + custom + production) / sale_quantity, 9) + uchet_price_usd22 = round((dostavkaUSD2 + NATUSD2 + zakupkaUSD2 + customUSD2 + productionUSD2) / sale_quantity, 9) + + + return (last_utid, float(uchet_price), float(uchet_price_usd22)) + #arr_price.append((last_utid, float(uchet_price), float(uchet_price_usd22))) + #if len(arr_price) > 0: + # insert_to_DB_UchetPrice(arr_price, conn) + + + + + + + + +def insert_to_DB_UchetPrice(arr, conn): + try: + cursor = conn.cursor() + conn.autocommit = False + cursor.fast_executemany = True + table = '[pbiProd].[УчетнаяЦенаПоСебестоимости]' + + cursor.executemany(""" + INSERT INTO [mag_pbi].[pbiProd].[УчетнаяЦенаПоСебестоимости] + ( [Период], [artic_id], [Учетная цена], [Учетная цена USD2+2]) + VALUES (CONVERT(date, GETDATE()), ?, ?, ?); + """, arr) + + + except pyodbc.DatabaseError as err: + print('ошибка', err) + conn.rollback() + else: + conn.commit() + print(time.ctime(), 'обновлено', len(arr), ': записей') + finally: + conn.autocommit = True + + + + +union_sebes = True +print('start time', time.ctime()) +connect = sql_connect() +ComputeManufacture = True +maxLvl = 1 + +if ComputeManufacture: + maxLvl = 4 + exec_procedure(connect, '[pbiProd].[Подготовка Производство: единая процедура для подготовки]') + + + +for stRange in range(0, maxLvl): + # Заполнение таблицы + skip = False + fill_table_sebestoim2022(connect, skip) + + if True: + group = '[2k]' + max_counter = getMaxCounter(connect, group) + print('Группа: ', group, ' Всего групп - ', max_counter) + for counter in range(max_counter): + counter += 1 + count_sebest(connect, counter, group) + print(time.ctime(), ' группа ', counter, ' обработана') + + + # Расчитаем товары которые учавствуют в производстве + if ComputeManufacture: + start_range = 0 + for i in range(stRange, stRange + 1): + for i_range in range(2000, 20000, 2000): + end_range = i_range + count_sebest(connect, "", "", i, True, start_range, end_range) + start_range = i_range + + # Нужно добавить 1с_id в таблицу .... + exec_procedure(connect, '[pbiProd].[Производство: Заполнить 1сid для СебестоимостьПроизводствоОт2022]') + + +# заполним сводную таблицу (финальную) для загрузки в пби ... +if union_sebes: + print('Объединение в сводную таблицу ~ 10 мин ...') + exec_procedure(connect, '[pbiProd].[ЗаполнитьСебестоимостьСводныйОт2022]') + + +connect.close() +print('end time ', time.ctime())