Dumped on 2021-05-19
Действия пользователя
F-Key | Name | Type | Description |
---|---|---|---|
id | bigint |
PRIMARY KEY
DEFAULT nextval('core.auto_id_ad_audits'::regclass)
Идентификатор |
|
fn_user | integer |
Пользователь |
|
d_date | timestamp with time zone |
Дата события |
|
c_data | text |
Дополнительные параметры |
|
c_type | text |
Тип события |
|
c_app_name | text |
Имя приложение |
|
dx_created | timestamp with time zone |
DEFAULT now()
Дата создания в БД |
Информация о мобильных устройствах
F-Key | Name | Type | Description |
---|---|---|---|
id | uuid |
PRIMARY KEY
DEFAULT uuid_generate_v4()
Идентификатор |
|
fn_user | integer |
Пользователь |
|
d_date | timestamp with time zone |
Дата возникновения событий |
|
b_debug | boolean |
NOT NULL
DEFAULT false
Режим отладки |
|
c_architecture | text |
Архитектура устройства |
|
c_phone_model | text |
Модель телефона |
|
c_sdk | text |
Версия sdk |
|
c_os | text |
Версия ОС |
|
c_imei | text |
IMEI |
|
c_version | text |
Версия приложения |
|
dx_created | timestamp with time zone |
NOT NULL
DEFAULT now()
Создан в БД |
|
n_version | bigint |
Показатели мобильного устройства
F-Key | Name | Type | Description |
---|---|---|---|
id | uuid |
PRIMARY KEY
DEFAULT uuid_generate_v4()
Идентификатор |
|
fn_user | integer |
NOT NULL
Пользователь |
|
d_date | timestamp with time zone |
NOT NULL
DEFAULT now()
Дата события |
|
c_network_type | text |
Тип сети |
|
b_isonline | boolean |
NOT NULL
DEFAULT false
Состояние подключения к сети интернет |
|
n_ram | bigint |
Размер ОЗУ |
|
n_used_ram | bigint |
Размер используемого ОЗУ |
|
n_phone_memory | bigint |
Размер внутренней памяти |
|
n_used_phone_memory | bigint |
Размер используемой внутренней памяти |
|
n_sd_card_memory | bigint |
Размер внешней памяти |
|
n_used_sd_card_memory | bigint |
Размер используемой внешей памяти |
|
n_battery_level | integer |
Уровень заряда батареи |
|
n_time | integer |
Смещение времени |
|
dx_created | timestamp with time zone |
DEFAULT now()
Создан в БД |
Перемещение исполнителя
F-Key | Name | Type | Description |
---|---|---|---|
id | uuid |
PRIMARY KEY
DEFAULT uuid_generate_v4()
Идентификатор |
|
fn_user | integer |
NOT NULL
Исполнитель |
|
d_date | timestamp with time zone |
NOT NULL
DEFAULT now()
Дата |
|
n_longitude | numeric(20,15) |
NOT NULL
Долгота |
|
n_latitude | numeric(20,15) |
NOT NULL
Широта |
|
c_network_status | text |
Тип сети |
|
dx_created | timestamp with time zone |
DEFAULT now()
Создан в БД |
Логирование действий пользователей с данными. Полная информация
F-Key | Name | Type | Description |
---|---|---|---|
id | uuid | NOT NULL DEFAULT uuid_generate_v4() | |
c_table_name | text |
Имя таблицы в которой произошли изменения |
|
c_operation | text |
Тип операции, INSERT, UPDATE, DELETE |
|
jb_old_value | jsonb |
Предыдущие данные |
|
jb_new_value | jsonb |
Новые данные |
|
c_user | text |
Учетная запись |
|
d_date | timestamp with time zone |
Дата события |
Логирование запросов пользователя
F-Key | Name | Type | Description |
---|---|---|---|
id | uuid | PRIMARY KEY DEFAULT uuid_generate_v4() | |
integer_id | bigint |
Идентификатор |
|
uuid_id | uuid |
Идентификатор |
|
c_action | text |
NOT NULL
Имя таблицы |
|
c_method | text |
Метод |
|
d_date | timestamp with time zone | NOT NULL DEFAULT now() | |
core.pd_users.id | f_user | integer |
NOT NULL
DEFAULT '-1'::integer
Пользователь |
jb_data | jsonb | NOT NULL |
Файлы
F-Key | Name | Type | Description |
---|---|---|---|
id | uuid |
PRIMARY KEY
DEFAULT uuid_generate_v4()
Идентификатор |
|
fn_type | integer |
NOT NULL
Тип изображения |
|
fn_result | uuid |
NOT NULL
Результат |
|
fn_route | uuid |
NOT NULL
Маршрут |
|
n_longitude | numeric(20,15) |
NOT NULL
Долгота |
|
n_latitude | numeric(20,15) |
NOT NULL
Широта |
|
c_notice | text |
Примечание |
|
d_date | timestamp with time zone |
NOT NULL
Дата создания |
|
fn_file | uuid |
NOT NULL
Файл |
|
ba_data | bytea |
Превью |
|
n_size | integer |
Размер превью |
|
jb_data | jsonb |
JSON данные |
|
dx_created | timestamp with time zone |
DEFAULT now()
Дата создания в БД |
|
fn_point | uuid |
Файлы
F-Key | Name | Type | Description |
---|---|---|---|
id | uuid |
PRIMARY KEY
DEFAULT uuid_generate_v4()
Идентификатор |
|
c_name | text |
NOT NULL
Имя файла |
|
d_date | timestamp with time zone |
NOT NULL
Дата создания |
|
c_mime | text |
NOT NULL
MIME-тип |
|
c_extension | text |
NOT NULL
Расширение |
|
ba_data | bytea |
NOT NULL
Байты |
|
n_size | integer |
NOT NULL
Размер файла |
|
jb_data | jsonb |
JSON данные |
|
dx_created | timestamp with time zone |
DEFAULT now()
Дата создания в БД |
Уведомления
F-Key | Name | Type | Description |
---|---|---|---|
fn_user_to | integer |
NOT NULL
Адресат |
|
c_title | text |
Заголовок |
|
c_message | text |
Сообщение |
|
d_date | timestamp with time zone |
NOT NULL
Создан |
|
d_changed | timestamp with time zone |
Изменен |
|
fn_user_from | integer |
NOT NULL
От кого |
|
b_readed | boolean |
NOT NULL
DEFAULT false
Прочитан |
|
b_sended | boolean |
NOT NULL
DEFAULT false
Доставлено |
|
dx_created | timestamp with time zone |
DEFAULT now()
Дата создания в БД |
|
id | uuid | PRIMARY KEY DEFAULT uuid_generate_v4() | |
c_group | text | ||
jb_data | jsonb |
Дополнительные данные в уведомлениях |
Точки
F-Key | Name | Type | Description |
---|---|---|---|
id | uuid |
PRIMARY KEY
DEFAULT uuid_generate_v4()
Идентификатор |
|
dbo.ed_registr_pts.id | f_registr_pts | uuid |
Учетный показатель |
core.cd_routes.id | f_route | uuid |
NOT NULL
Маршрут |
core.cs_point_types.id | f_type | integer |
NOT NULL
Тип точки |
c_notice | text |
Примечание |
|
c_info | text |
Информация |
|
jb_data | jsonb |
JSON данные |
|
dx_created | timestamp with time zone |
DEFAULT now()
Дата создания в БД |
|
n_order | integer |
NOT NULL
Сортировка |
|
b_anomaly | boolean | NOT NULL DEFAULT false | |
sn_delete | boolean | NOT NULL DEFAULT false |
Результат выполнения
F-Key | Name | Type | Description |
---|---|---|---|
id | uuid |
PRIMARY KEY
DEFAULT uuid_generate_v4()
Идентификатор |
|
fn_user_point | uuid |
NOT NULL
Пользовательская точка |
|
fn_point | uuid |
NOT NULL
Точка маршрута |
|
fn_type | integer |
NOT NULL
Тип результат |
|
fn_user | integer |
NOT NULL
Пользователь |
|
fn_route | uuid |
NOT NULL
Маршрут |
|
d_date | timestamp with time zone |
NOT NULL
Дата создания |
|
c_notice | text |
Примечание |
|
b_warning | boolean |
NOT NULL
DEFAULT false
Предупреждение Дост./Недост. |
|
jb_data | jsonb |
JSON данные |
|
dx_created | timestamp with time zone |
DEFAULT now()
Дата создания в БД |
|
b_check | boolean |
Подтверждено |
|
d_date_check | timestamp with time zone |
Дата подтверждения |
|
n_manual_longitude | numeric(20,15) |
Долгота указанная вручную |
|
n_manual_latitude | numeric(20,15) |
Широта указанная вручную |
История изменения статусов заданий
F-Key | Name | Type | Description |
---|---|---|---|
id | uuid |
PRIMARY KEY
DEFAULT uuid_generate_v4()
Идентификатор |
|
fn_route | uuid |
NOT NULL
Задание |
|
fn_status | integer |
NOT NULL
Статус |
|
fn_user | integer |
NOT NULL
Пользователь |
|
d_date | timestamp with time zone |
NOT NULL
Дата изменения |
|
c_notice | text |
Примечание |
|
dx_created | timestamp with time zone |
DEFAULT now()
Дата создания в БД |
Маршруты
F-Key | Name | Type | Description |
---|---|---|---|
id | uuid |
PRIMARY KEY
DEFAULT uuid_generate_v4()
Идентификатор |
|
core.cs_route_types.id | f_type | integer |
NOT NULL
Тип маршрута |
c_number | text |
NOT NULL
Номер маршрута |
|
d_date | timestamp with time zone |
NOT NULL
DEFAULT now()
Дата создания |
|
d_date_start | date |
NOT NULL
Дата начала выполнения |
|
d_date_end | date |
NOT NULL
Дата завершения выполнения |
|
c_notice | text |
Примечание |
|
b_extended | boolean |
NOT NULL
Продлен |
|
d_extended | date |
Продлен до |
|
jb_data | jsonb |
JSON данные |
|
dx_created | timestamp with time zone |
DEFAULT now()
Дата создания в БД |
|
n_order | integer |
NOT NULL
Сортировка |
|
b_draft | boolean |
NOT NULL
DEFAULT false
Является черновиком |
|
core.cs_route_statuses.id | f_status | integer |
Статус маршрута |
Настройки
F-Key | Name | Type | Description |
---|---|---|---|
id | integer |
PRIMARY KEY
DEFAULT nextval('core.auto_id_cd_settings'::regclass)
Идентификатор |
|
c_key | text |
NOT NULL
Ключ |
|
c_value | text |
Значение |
|
core.cs_setting_types.id | f_type | integer |
NOT NULL
Тип |
c_label | text |
Заголовок |
|
c_summary | text |
Краткое описание |
|
core.sd_divisions.id | f_division | integer |
Регион |
core.pd_users.id | f_user | integer |
Пользователь |
sn_delete | boolean |
NOT NULL
DEFAULT false
Удален |
|
f_role | integer |
Логирование job
F-Key | Name | Type | Description |
---|---|---|---|
id | uuid | PRIMARY KEY DEFAULT uuid_generate_v4() | |
n_level_msg | integer |
0 - сообщение 1 - предупрежденние 2 - ошибка |
|
d_timestamp | timestamp with time zone | ||
c_descr | text |
Точки
F-Key | Name | Type | Description |
---|---|---|---|
id | uuid |
PRIMARY KEY
DEFAULT uuid_generate_v4()
Идентификатор |
|
fn_point | uuid |
Точка |
|
fn_user | integer |
NOT NULL
Пользователь |
|
fn_route | uuid |
NOT NULL
Маршрут |
|
fn_type | integer |
NOT NULL
Тип |
|
n_longitude | numeric(20,15) |
NOT NULL
Долгота |
|
n_latitude | numeric(20,15) |
NOT NULL
Широта |
|
c_notice | text |
Примечание |
|
jb_data | jsonb |
JSON данные |
|
b_check | boolean | ||
d_date_check | timestamp with time zone |
Дата подтверждения |
|
dx_created | timestamp with time zone |
DEFAULT now()
Дата записи в БД |
|
d_date | timestamp with time zone |
NOT NULL
Дата создания |
|
c_telephone | text |
Новый номер телефона абонента |
|
b_export | boolean | DEFAULT false |
Исполнители задания
F-Key | Name | Type | Description |
---|---|---|---|
id | uuid |
PRIMARY KEY
DEFAULT uuid_generate_v4()
Идентифиактор |
|
core.cd_routes.id | f_route | uuid |
NOT NULL
Маршрут |
core.pd_users.id | f_user | integer |
NOT NULL
Пользователь |
b_main | boolean |
NOT NULL
DEFAULT false
Является главным |
|
dx_created | timestamp with time zone |
DEFAULT now()
Дата создания в БД |
Тип изображений
F-Key | Name | Type | Description |
---|---|---|---|
id | integer |
PRIMARY KEY
DEFAULT nextval('core.auto_id_cs_attachment_types'::regclass)
Идентификатор |
|
n_code | integer |
Код |
|
c_name | text |
NOT NULL
Наименование |
|
c_short_name | text |
Краткое наименование |
|
c_const | text |
NOT NULL
Константа |
|
n_order | integer |
Сортировка |
|
b_default | boolean |
NOT NULL
DEFAULT false
По умолчанию |
|
b_disabled | boolean |
NOT NULL
DEFAULT false
Отключено |
Тип точки
F-Key | Name | Type | Description |
---|---|---|---|
id | integer |
PRIMARY KEY
DEFAULT nextval('core.auto_id_cs_point_types'::regclass)
Идентификатор |
|
n_code | integer |
Код |
|
c_name | text |
NOT NULL
Наименование |
|
c_short_name | text |
Краткое наименование |
|
c_const | text |
Константа |
|
n_order | integer |
Сортировка |
|
b_default | boolean |
NOT NULL
DEFAULT false
Отключено |
|
b_disabled | boolean |
NOT NULL
DEFAULT false
Отключено |
Tables referencing this one via Foreign Key Constraints:
Тип результат
F-Key | Name | Type | Description |
---|---|---|---|
id | integer |
PRIMARY KEY
DEFAULT nextval('core.auto_id_cs_result_types'::regclass)
Идентификатор |
|
n_code | integer |
Код |
|
c_name | text |
NOT NULL
Наименование |
|
c_short_name | text |
Краткое наименование |
|
c_const | text |
NOT NULL
Константа |
|
n_order | integer |
Отключено |
|
b_default | boolean |
NOT NULL
DEFAULT false
По умолчанию |
|
b_disabled | boolean |
NOT NULL
DEFAULT false
Отключено |
|
c_code_out | text |
Код из внешней системы |
Тип результат
F-Key | Name | Type | Description |
---|---|---|---|
id | integer |
PRIMARY KEY
DEFAULT nextval('core.auto_id_cs_route_statuses'::regclass)
Идентификатор |
|
n_code | integer |
Код |
|
c_name | text |
NOT NULL
Наименование |
|
c_short_name | text |
Краткое наименование |
|
c_const | text |
NOT NULL
Константа |
|
n_order | integer |
Приоритет статуса (чем больше число тем выше статус) |
|
b_disabled | boolean |
NOT NULL
DEFAULT false
Отключено |
Tables referencing this one via Foreign Key Constraints:
Тип маршрута
F-Key | Name | Type | Description |
---|---|---|---|
id | integer |
PRIMARY KEY
DEFAULT nextval('core.auto_id_cs_route_types'::regclass)
Идентификатор |
|
n_code | integer |
Код |
|
c_name | text |
NOT NULL
Наименование |
|
c_short_name | text |
Краткое наименование |
|
c_const | text |
NOT NULL
Константа |
|
n_order | integer |
Сортировка |
|
b_default | boolean |
NOT NULL
DEFAULT false
По умолчанию |
|
b_disabled | boolean |
NOT NULL
DEFAULT false
Отключено |
Тип настройки
F-Key | Name | Type | Description |
---|---|---|---|
id | integer |
PRIMARY KEY
DEFAULT nextval('core.auto_id_cs_setting_types'::regclass)
Идентификатор |
|
n_code | integer |
Код |
|
c_name | text |
NOT NULL
Наименование |
|
c_short_name | text |
Краткое наименование |
|
c_const | text |
NOT NULL
Константа |
|
n_order | integer |
Сортировка |
|
b_default | boolean |
NOT NULL
DEFAULT false
По умолчанию |
|
b_disabled | boolean |
NOT NULL
DEFAULT false
Отключено |
Tables referencing this one via Foreign Key Constraints:
Права доступа
F-Key | Name | Type | Description |
---|---|---|---|
id | integer |
PRIMARY KEY
DEFAULT nextval('core.auto_id_pd_accesses'::regclass)
Идентификатор |
|
core.pd_users.id | f_user | integer |
Пользователь |
core.pd_roles.id | f_role | integer |
Роль |
c_name | text |
Табл./Предст./Функц. |
|
c_criteria | text |
Серверный фильтр |
|
c_path | text |
Путь в файловой системе |
|
c_function | text |
Функция RPC или её часть |
|
c_columns | text |
Запрещенные колонки |
|
b_deletable | boolean |
NOT NULL
DEFAULT false
Разрешено удалени |
|
b_creatable | boolean |
NOT NULL
DEFAULT false
Разрешено создание |
|
b_editable | boolean |
NOT NULL
DEFAULT false
Разрешено редактирование |
|
b_full_control | boolean |
NOT NULL
DEFAULT false
Дополнительный доступ |
|
sn_delete | boolean |
NOT NULL
DEFAULT false
Удален |
Роли
F-Key | Name | Type | Description |
---|---|---|---|
id | integer |
PRIMARY KEY
DEFAULT nextval('core.auto_id_pd_roles'::regclass)
Идентификатор |
|
c_name | text |
UNIQUE
NOT NULL
Наименование |
|
c_description | text |
Описание роли |
|
n_weight | integer |
NOT NULL
Приоритет |
|
sn_delete | boolean |
NOT NULL
DEFAULT false
Удален |
Привязка пользователей к отделению или участку
F-Key | Name | Type | Description |
---|---|---|---|
id | integer |
PRIMARY KEY
DEFAULT nextval('core.auto_id_pd_userindivisions'::regclass)
Идентификатор |
|
core.pd_users.id | f_user | integer |
NOT NULL
Пользователь |
core.sd_divisions.id | f_division | integer |
Отделение |
core.sd_subdivisions.id | f_subdivision | integer |
Участок |
sn_delete | boolean |
NOT NULL
DEFAULT false
Признак удаленной записи |
Пользователи в ролях
F-Key | Name | Type | Description |
---|---|---|---|
id | integer |
PRIMARY KEY
DEFAULT nextval('core.auto_id_pd_userinroles'::regclass)
Идентификатор |
|
core.pd_users.id | f_user | integer |
NOT NULL
Пользователь |
core.pd_roles.id | f_role | integer |
NOT NULL
Роль |
sn_delete | boolean |
NOT NULL
DEFAULT false
Удален |
Пользователи
F-Key | Name | Type | Description |
---|---|---|---|
id | integer |
PRIMARY KEY
DEFAULT nextval('core.auto_id_pd_users'::regclass)
Идентификатор |
|
core.pd_users.id | f_parent | integer |
Родитель |
c_login | text |
UNIQUE
NOT NULL
Логин |
|
c_password | text |
Пароль |
|
fn_file | uuid |
Иконка |
|
s_salt | text |
Salt |
|
s_hash | text |
Hash |
|
c_first_name | text |
Имя |
|
c_imei | text |
IMEI |
|
c_description | text |
Описание |
|
b_disabled | boolean |
NOT NULL
DEFAULT false
Отключен |
|
sn_delete | boolean |
NOT NULL
DEFAULT false
Удален |
|
c_version | text |
Версия мобильного приложения |
|
n_version | bigint |
Версия мобильного приложения - Число |
|
c_last_name | text |
Фамилия |
|
c_middle_name | text |
Отчество |
|
c_phone | text |
Телефон |
|
c_email | text |
Эл. почта |
|
c_post | text |
Должность |
|
c_tab_number | text |
UNIQUE
Табельный номер |
|
b_pgcrypto | boolean | ||
c_post_code | text |
Код должности |
Tables referencing this one via Foreign Key Constraints:
Открытый список пользователей
F-Key | Name | Type | Description |
---|---|---|---|
id | integer | ||
f_parent | integer | ||
c_login | text | ||
c_claims | text | ||
fn_file | uuid | ||
c_description | text | ||
c_first_name | text | ||
c_last_name | text | ||
c_middle_name | text | ||
c_imei | text | ||
c_phone | text | ||
c_email | text | ||
c_version | text | ||
n_version | bigint | ||
b_disabled | boolean | ||
c_main_divisions | text | ||
c_divisions | text | ||
c_subdivisions | text |
SELECT t.id , t.f_parent , t.c_login , t.c_claims , t.fn_file , t.c_description , t.c_first_name , t.c_last_name , t.c_middle_name , t.c_imei , t.c_phone , t.c_email , t.c_version , t.n_version , t.b_disabled , CASE WHEN (t.c_main_divisions = '..'::text) THEN ''::text ELSE t.c_main_divisions END AS c_main_divisions , CASE WHEN (t.c_divisions = '..'::text) THEN ''::text ELSE t.c_divisions END AS c_divisions , CASE WHEN (t.c_subdivisions = '..'::text) THEN ''::text ELSE t.c_subdivisions END AS c_subdivisions FROM ( WITH items AS ( SELECT uid.f_user , COALESCE (d.f_division , uid.f_division ) AS f_main_division , CASE WHEN (d.f_division IS NOT NULL) THEN uid.f_division ELSE NULL::integer END AS f_division , uid.f_subdivision FROM (core.pd_userindivisions uid JOIN core.sd_divisions d ON ( (uid.f_division = d.id) ) ) ORDER BY uid.f_user ) SELECT u.id , u.f_parent , u.c_login , concat ('.' , ( SELECT string_agg (t_1.c_name ,'.'::text ) AS string_agg FROM ( SELECT r.c_name FROM (core.pd_userinroles uir JOIN core.pd_roles r ON ( (uir.f_role = r.id) ) ) WHERE (uir.f_user = u.id) ORDER BY r.n_weight DESC ) t_1 ) ,'.' ) AS c_claims , u.fn_file , u.c_description , u.c_first_name , u.c_last_name , u.c_middle_name , u.c_imei , u.c_phone , u.c_email , u.c_version , u.n_version , u.b_disabled , concat ('.' , ( SELECT string_agg ( (t_1.f_main_division)::text ,'.'::text ) AS string_agg FROM ( SELECT DISTINCT i.f_main_division FROM items i WHERE ( (i.f_user = u.id) AND (i.f_main_division IS NOT NULL) ) ) t_1 ) ,'.' ) AS c_main_divisions , concat ('.' , ( SELECT string_agg ( (t_1.f_division)::text ,'.'::text ) AS string_agg FROM ( SELECT DISTINCT i.f_division FROM items i WHERE ( (i.f_user = u.id) AND (i.f_division IS NOT NULL) ) ) t_1 ) ,'.' ) AS c_divisions , concat ('.' , ( SELECT string_agg ( (t_1.f_subdivision)::text ,'.'::text ) AS string_agg FROM ( SELECT DISTINCT i.f_subdivision FROM items i WHERE ( (i.f_user = u.id) AND (i.f_subdivision IS NOT NULL) ) ) t_1 ) ,'.' ) AS c_subdivisions FROM core.pd_users u WHERE (u.sn_delete = false) ) t;
Клиентские ошибки
F-Key | Name | Type | Description |
---|---|---|---|
id | uuid |
PRIMARY KEY
DEFAULT uuid_generate_v4()
Идентификатор |
|
c_message | text |
Текст ошибки |
|
c_code | text |
Код ошибки |
|
d_created | timestamp with time zone |
Дата возникновения ошибки |
|
fn_user | integer |
Идентификатор пользователя |
|
c_version | text |
Версия приложения |
|
c_platform | text |
Тип платформы |
|
jb_data | jsonb |
Прочии данные |
|
dx_date | timestamp with time zone |
DEFAULT now()
Дата записи на сервере |
Журнал версий
F-Key | Name | Type | Description |
---|---|---|---|
id | integer |
PRIMARY KEY
DEFAULT nextval('core.auto_id_sd_digests'::regclass)
Идентификатор |
|
c_version | text |
NOT NULL
Версия |
|
c_description | text |
Описание |
|
core.sd_divisions.id | f_division | integer |
Отделение |
b_hidden | boolean |
NOT NULL
DEFAULT false
Скрыт |
|
ba_file | bytea |
NOT NULL
Файл для обновления |
|
dx_created | timestamp with time zone | NOT NULL DEFAULT now() | |
n_version | bigint |
Номер версии |
Отделения
F-Key | Name | Type | Description |
---|---|---|---|
id | integer |
PRIMARY KEY
DEFAULT nextval('core.auto_id_sd_divisions'::regclass)
Идентификатор |
|
core.sd_divisions.id | f_division | integer |
Вышестоящее отделение |
c_name | text |
NOT NULL
Наименование |
|
c_dep_code | text |
Код отделения (филиала) |
|
n_code | integer |
Код |
|
b_disabled | boolean |
NOT NULL
DEFAULT false
Отключено |
|
n_longitude | numeric | ||
n_latitude | numeric | ||
c_phone | text |
Для возможности осуществления вызова в экстренной ситуации |
Tables referencing this one via Foreign Key Constraints:
Участки
F-Key | Name | Type | Description |
---|---|---|---|
id | integer |
PRIMARY KEY
DEFAULT nextval('core.auto_id_sd_subdivisions'::regclass)
Идентификатор |
|
core.sd_divisions.id | f_division | integer |
NOT NULL
Отделение |
n_code | integer |
Код |
|
c_name | text |
NOT NULL
Наименование |
|
b_disabled | boolean |
NOT NULL
DEFAULT false
Отключено |
|
c_dep_code | text |
Текстовый код |
Tables referencing this one via Foreign Key Constraints:
Изменение состояния таблицы
F-Key | Name | Type | Description |
---|---|---|---|
c_table_name | text |
UNIQUE#1
NOT NULL
Имя таблицы |
|
n_change | double precision |
NOT NULL
Версия изменения |
|
core.pd_users.id | f_user | integer | UNIQUE#1 |
id | bigserial | PRIMARY KEY |
Зависимость таблиц состояний
F-Key | Name | Type | Description |
---|---|---|---|
id | smallint | PRIMARY KEY DEFAULT nextval('core.sd_table_change_ref_id_seq'::regclass) | |
c_table_name | text |
NOT NULL
Таблица |
|
c_table_name_ref | text |
NOT NULL
Зависимая таблица |
Состояние таблиц
F-Key | Name | Type | Description |
---|---|---|---|
id | bigserial | PRIMARY KEY | |
core.pd_users.id | f_user | integer | NOT NULL |
c_table_name | text | NOT NULL | |
jb_data | jsonb |
F-Key | Name | Type | Description |
---|---|---|---|
table_name | character varying | ||
table_type | character varying | ||
table_title | character varying | ||
primary_key | character varying | ||
table_comment | character varying | ||
table_schema | information_schema.sql_identifier |
SELECT table1.table_name , table1.table_type , table1.table_title , table1.primary_key , table1.table_comment , table1.table_schema FROM ( SELECT (t.table_name)::character varying AS table_name , (t.table_type)::character varying AS table_type , (pgd.description)::character varying AS table_title , (cc.column_name)::character varying AS primary_key , ''::character varying AS table_comment , t.table_schema FROM ( ( ( (information_schema.tables t LEFT JOIN pg_statio_all_tables st ON ( (st.relname = (t.table_name)::name ) ) ) LEFT JOIN pg_description pgd ON ( ( (pgd.objoid = st.relid) AND (pgd.objsubid = 0) ) ) ) LEFT JOIN information_schema.table_constraints tc ON ( ( ( (t.table_name)::text = (tc.table_name)::text ) AND ( (t.table_catalog)::text = (tc.table_catalog)::text ) ) ) ) LEFT JOIN information_schema.constraint_column_usage cc ON ( ( (tc.constraint_name)::text = (cc.constraint_name)::text ) ) ) WHERE ( ( (t.table_catalog)::text = (current_database () )::text ) AND ( (tc.constraint_type)::text = 'PRIMARY KEY'::text ) ) UNION SELECT (t.table_name)::character varying AS table_name , (t.table_type)::character varying AS table_type , (pgd.description)::character varying AS table_title , ''::character varying AS primary_key , ''::character varying AS table_comment , t.table_schema FROM ( (information_schema.tables t LEFT JOIN pg_class pgc ON ( (pgc.relname = (t.table_name)::name ) ) ) LEFT JOIN pg_description pgd ON ( (pgd.objoid = pgc.oid) ) ) WHERE ( ( (t.table_type)::text = 'VIEW'::text ) AND ( (t.table_catalog)::text = (current_database () )::text ) ) UNION SELECT (r.routine_name)::character varying AS table_name , (r.routine_type)::character varying AS table_type , (pgd.description)::character varying AS table_title , ''::character varying AS primary_key , ''::character varying AS table_comment , r.routine_schema AS table_schema FROM ( (information_schema.routines r LEFT JOIN pg_proc pgp ON ( (pgp.proname = (r.routine_name)::name ) ) ) LEFT JOIN pg_description pgd ON ( (pgd.objoid = pgp.oid) ) ) WHERE ( (r.routine_catalog)::text = (current_database () )::text ) ) table1 WHERE ( ( (table1.table_schema)::text <> 'pg_catalog'::text ) AND ( (table1.table_schema)::text <> 'information_schema'::text ) AND ( (table1.table_schema)::text <> 'public'::text ) );
Системный список пользователей
F-Key | Name | Type | Description |
---|---|---|---|
id | integer | ||
f_parent | integer | ||
c_login | text | ||
c_first_name | text | ||
c_last_name | text | ||
c_middle_name | text | ||
c_user_name | text | ||
c_password | text | ||
s_salt | text | ||
s_hash | text | ||
b_pgcrypto | boolean | ||
c_claims | text | ||
c_all_divisions | text | ||
b_disabled | boolean | ||
c_version | text | ||
n_version | bigint |
SELECT u.id , u.f_parent , u.c_login , u.c_first_name , u.c_last_name , u.c_middle_name , concat (u.c_first_name ,' ' , u.c_last_name ,' ' , u.c_middle_name ) AS c_user_name , u.c_password , u.s_salt , u.s_hash , u.b_pgcrypto , concat ('.' , ( SELECT string_agg (t.c_name ,'.'::text ) AS string_agg FROM ( SELECT r.c_name FROM (core.pd_userinroles uir JOIN core.pd_roles r ON ( (uir.f_role = r.id) ) ) WHERE (uir.f_user = u.id) ORDER BY r.n_weight DESC ) t ) ,'.' ) AS c_claims , ( WITH RECURSIVE tab_rec AS ( SELECT sd_divisions.id AS id_parent , sd_divisions.id , sd_divisions.f_division , 1 AS num FROM core.sd_divisions WHERE (sd_divisions.id IN ( SELECT pud.f_division FROM core.pd_userindivisions pud WHERE (pud.f_user = u.id) ) ) UNION ALL SELECT r_2.id_parent , d.id , d.f_division , (r_2.num + 1) AS num FROM core.sd_divisions d , tab_rec r_2 WHERE (r_2.id = d.f_division) ) SELECT string_agg ( (r_1.id)::text ,','::text ) AS string_agg FROM tab_rec r_1 ) AS c_all_divisions , u.b_disabled , u.c_version , u.n_version FROM core.pd_users u WHERE (u.sn_delete = false);
Получение "Вложения" мобильным приложением
/** * @params {integer} _fn_user - идентификатор пользователя * @params {text} _c_version - текущая версия приложения * * @example * [{ "action": "cf_mui_cd_attachments", "method": "Select", "data": [{ "params": [_fn_user, _c_version] }], "type": "rpc", "tid": 0 }] */ BEGIN RETURN QUERY select ad.c_name, f.c_mime, a.d_date, a.n_longitude, a.n_latitude, a.ba_data, f.ba_data as ba_file from core.cd_attachments as a INNER JOIN core.cd_files as f ON f.id = a.fn_file inner join core.cd_results as r ON a.fn_result = r.id inner join core.cd_points as p on r.fn_point = p.id inner join dbo.ed_registr_pts as rp ON rp.id = p.f_registr_pts inner join dbo.ss_address as ad ON ad.id = rp.f_address where a.id = _id; END
Получение списка "Вложений" мобильным приложением
/** * @params {integer} _fn_user - идентификатор пользователя * @params {text} _c_version - текущая версия приложения * * @example * [{ "action": "cf_mui_cd_attachments", "method": "Select", "data": [{ "params": [_fn_user, _c_version] }], "type": "rpc", "tid": 0 }] */ BEGIN IF _fn_user IS NOT NULL THEN RETURN QUERY select a.id, f.c_name, f.c_mime, a.fn_type, a.fn_result, a.fn_route, a.fn_point, a.d_date, a.n_longitude, a.n_latitude, a.fn_file, a.c_notice, a.jb_data::text, a.dx_created, a.ba_data, a.n_size, null::bytea as ba_file, f.n_size as n_file_size from core.cd_userinroutes as uir INNER JOIN core.cd_attachments as a ON a.fn_route = uir.f_route INNER JOIN core.cd_files as f ON f.id = a.fn_file inner join core.cd_results as r ON r.id = a.fn_result where uir.f_user = _fn_user and r.fn_user = _fn_user and core.sf_is_mobile_route(uir.f_route); ELSE RETURN QUERY select a.id, f.c_name, f.c_mime, a.fn_type, a.fn_result, a.fn_route, a.fn_point, a.d_date, a.n_longitude, a.n_latitude, a.fn_file, a.c_notice, a.jb_data::text, a.dx_created, a.ba_data, a.n_size, null::bytea as ba_file, f.n_size as n_file_size from core.cd_attachments as a INNER JOIN core.cd_files as f ON f.id = a.fn_file; END IF; END
Получение списка "Файлов" мобильным приложением
/** * @params {integer} _fn_user - идентификатор пользователя * @params {text} _c_version - текущая версия приложения * * @example * [{ "action": "cf_mui_cd_files", "method": "Select", "data": [{ "params": [_fn_user, _c_version] }], "type": "rpc", "tid": 0 }] */ BEGIN IF _fn_user IS NOT NULL THEN -- для файла специально указываем null, чтобы телефон не обрабатывал данные RETURN QUERY select f.id, f.c_name, f.d_date, f.c_mime, f.c_extension, f.jb_data::text, null::bytea, f.n_size, f.dx_created from core.cd_userinroutes as uir INNER JOIN core.cd_attachments as a ON a.fn_route = uir.f_route INNER JOIN core.cd_files as f ON f.id = a.fn_file inner join core.cd_results as r ON r.id = a.fn_result where uir.f_user = _fn_user and r.fn_user = _fn_user and core.sf_is_mobile_route(uir.f_route); --RETURN QUERY select f.id, f.c_name, f.d_date, f.c_mime, f.c_extension, f.jb_data::text, null::bytea, f.n_size, f.dx_created --from core.cd_files as f --inner join core.cd_attachments as a ON a.fn_file = f.id --inner join core.cd_routes as r ON a.fn_route = r.id --inner join core.cd_results as rr ON rr.id = a.fn_result --where rr.fn_user = _fn_user or core.sf_is_mobile_route(r.id); --UNION --select f.id, f.c_name, f.d_date, f.c_mime, f.c_extension, f.jb_data::text, f.ba_data, f.n_size, f.dx_created --from core.cd_files as f --where f.id in (select u.fn_file from core.pd_users as u where u.id = _fn_user) or --f.id in (select fb.fn_question_file from core.cd_feedbacks as fb where fb.fn_user = _fn_user and fb.fn_question_file is not null) --or f.id in (select fb.fn_answer_file from core.cd_feedbacks as fb where fb.fn_user = _fn_user and fb.fn_answer_file is not null); ELSE RETURN QUERY select f.id, f.c_name, f.d_date, f.c_mime, f.c_extension, f.jb_data::text, null::bytea, f.n_size, f.dx_created from core.cd_files as f; END IF; END
Получение списка "Уведомлений" мобильным приложением
/** * @params {integer} _fn_user - идентификатор пользователя * @params {text} _c_version - текущая версия приложения * * @example * [{ "action": "cf_mui_cd_notifications", "method": "Select", "data": [{ "params": [_fn_user, _c_version] }], "type": "rpc", "tid": 0 }] */ BEGIN RETURN QUERY select n.id, n.c_title, n.c_message, n.d_date from core.cd_notifications as n where n.fn_user_to = _fn_user or n.fn_user_from = _fn_user order by n.d_date desc; END
Получение списка "Точек маршрута" мобильным приложением
/** * @params {integer} _fn_user - идентификатор пользователя * @params {text} _c_version - текущая версия приложения * * @example * [{ "action": "cf_mui_cd_points", "method": "Select", "data": [{ "params": [_fn_user, _c_version] }], "type": "rpc", "tid": 0 }] */ BEGIN RETURN QUERY select p.id, p.f_registr_pts, p.f_route, p.f_type, p.c_notice, p.c_info, p.jb_data::text, p.dx_created, p.n_order, p.b_anomaly, p.sn_delete from core.cd_userinroutes as uir LEFT JOIN core.cd_points as p ON p.f_route = uir.f_route INNER JOIN core.cd_routes as r ON r.id = p.f_route left join core.cs_route_statuses as rs ON r.f_status = rs.id where uir.f_user = _fn_user and core.sf_is_mobile_route(r.id); END
Получение списка "Результаты обхода" мобильным приложением
/** * @params {integer} _fn_user - идентификатор пользователя * @params {text} _c_version - текущая версия приложения * * @example * [{ "action": "cf_mui_cd_results", "method": "Select", "data": [{ "params": [_fn_user, _c_version] }], "type": "rpc", "tid": 0 }] */ BEGIN RETURN QUERY select r.id, r.fn_route, r.fn_point, r.fn_user_point, r.fn_type, r.fn_user, r.d_date, r.c_notice, r.b_warning, r.jb_data::text, r.dx_created, r.b_check, coalesce(r.n_manual_longitude, 0.0), coalesce(r.n_manual_latitude, 0.0) from core.cd_userinroutes as uir LEFT JOIN core.cd_routes as rt ON rt.id = uir.f_route INNER JOIN core.cd_results as r ON r.fn_route = rt.id left join core.cs_route_statuses as rs ON rt.f_status = rs.id where uir.f_user = _fn_user and r.fn_user = _fn_user and core.sf_is_mobile_route(rt.id); END
Получение списка "Истории маршрутов" мобильным приложением
/** * @params {integer} _fn_user - идентификатор пользователя * @params {text} _c_version - текущая версия приложения * * @example * [{ "action": "cf_mui_cd_route_history", "method": "Select", "data": [{ "params": [_fn_user, _c_version] }], "type": "rpc", "tid": 0 }] */ BEGIN RETURN QUERY select rh.id, rh.fn_route, rh.fn_status, rh.fn_user, rh.d_date, rh.c_notice, rh.dx_created from core.cd_userinroutes as uir LEFT JOIN core.cd_route_history as rh ON rh.fn_route = uir.f_route where uir.f_user = _fn_user and core.sf_is_mobile_route(uir.f_route); END
Получение списка "Маршрутов" мобильным приложением
/** * @params {integer} _fn_user - идентификатор пользователя * @params {text} _c_version - текущая версия приложения * * @example * [{ "action": "cf_mui_cd_routes", "method": "Select", "data": [{ "params": [_fn_user, _c_version] }], "type": "rpc", "tid": 0 }] */ BEGIN RETURN QUERY select r.id, r.f_type, r.c_number, r.d_date, r.d_date_start, r.d_date_end, r.c_notice, r.b_extended, r.d_extended, r.jb_data::text, r.dx_created, (select count(*) from core.cd_points as p where p.f_route = r.id) as n_count, r.n_order, r.b_draft from core.cd_userinroutes as uir INNER JOIN core.cd_routes as r ON r.id = uir.f_route left join core.cs_route_statuses as rs ON r.f_status = rs.id where uir.f_user = _fn_user and core.sf_is_mobile_route(r.id); -- не старше текущей даты END
Получение списка "Пользовательских точек" мобильным приложением
/** * @params {integer} _fn_user - идентификатор пользователя * @params {text} _c_version - текущая версия приложения * * @example * [{ "action": "cf_mui_cd_user_points", "method": "Select", "data": [{ "params": [_fn_user, _c_version] }], "type": "rpc", "tid": 0 }] */ BEGIN RETURN QUERY select up.id, up.fn_point, up.fn_user, u.c_login as c_user, up.fn_route, up.fn_type, up.n_longitude, up.n_latitude, up.c_notice, up.jb_data::text, up.d_date_check, up.dx_created, up.d_date, up.c_telephone, false from core.cd_userinroutes as uir LEFT JOIN core.cd_routes as rt ON rt.id = uir.f_route INNER JOIN core.cd_user_points as up ON up.fn_route = rt.id INNER JOIN core.pd_users as u ON up.fn_user = u.id left join core.cs_route_statuses as rs ON rt.f_status = rs.id where uir.f_user = _fn_user and up.fn_user = _fn_user and core.sf_is_mobile_route(rt.id); END
Получение списка "пользователей в маршрутах" мобильным приложением
/** * @params {integer} _fn_user - идентификатор пользователя * @params {text} _c_version - текущая версия приложения * * @example * [{ "action": "cf_mui_cd_userinroutes", "method": "Select", "data": [{ "params": [_fn_user, _c_version] }], "type": "rpc", "tid": 0 }] */ BEGIN RETURN QUERY select * from core.cd_userinroutes as cuir where cuir.f_route in (select DISTINCT r.id from core.cd_userinroutes as uir INNER JOIN core.cd_routes as r ON r.id = uir.f_route left join core.cs_route_statuses as rs ON r.f_status = rs.id where uir.f_user = _fn_user and core.sf_is_mobile_route(r.id)); END
Типы вложений
/** * @params {integer} _fn_user - идентификатор пользователя * @params {text} _c_version - текущая версия приложения * * @example * [{ "action": "cf_mui_cd_attachment_types", "method": "Select", "data": [{ "params": [_fn_user, _c_version] }], "type": "rpc", "tid": 0 }] */ BEGIN RETURN QUERY select at.id, at.c_name, at.c_const, at.n_order, at.b_default from core.cs_attachment_types as at where at.b_disabled = false; END
Тип точки
/** * @params {integer} _fn_user - идентификатор пользователя * @params {text} _c_version - текущая версия приложения * * @example * [{ "action": "cf_mui_cs_point_types", "method": "Select", "data": [{ "params": [_fn_user, _c_version] }], "type": "rpc", "tid": 0 }] */ BEGIN RETURN QUERY select pt.id, pt.c_name, pt.c_const, pt.n_order from core.cs_point_types as pt where pt.b_disabled = false; END
Тип результат
/** * @params {integer} _fn_user - идентификатор пользователя * @params {text} _c_version - текущая версия приложения * * @example * [{ "action": "cf_mui_cs_result_types", "method": "Select", "data": [{ "params": [_fn_user, _c_version] }], "type": "rpc", "tid": 0 }] */ BEGIN RETURN QUERY select rt.id, rt.c_name, rt.c_short_name, rt.c_const, rt.n_order from core.cs_result_types as rt where rt.b_disabled = false; END
Тип результат
/** * @params {integer} _fn_user - идентификатор пользователя * @params {text} _c_version - текущая версия приложения * * @example * [{ "action": "cf_mui_cs_route_statuses", "method": "Select", "data": [{ "params": [_fn_user, _c_version] }], "type": "rpc", "tid": 0 }] */ BEGIN RETURN QUERY select rs.id, rs.c_name, rs.c_const, rs.n_order from core.cs_route_statuses as rs where rs.b_disabled = false; END
Тип маршрута
/** * @params {integer} _fn_user - идентификатор пользователя * @params {text} _c_version - текущая версия приложения * * @example * [{ "action": "cf_mui_cs_route_types", "method": "Select", "data": [{ "params": [_fn_user, _c_version] }], "type": "rpc", "tid": 0 }] */ BEGIN RETURN QUERY select rt.id, rt.c_name, rt.c_const, rt.n_order from core.cs_route_types as rt where rt.b_disabled = false; END
Получение списка пользователей мобильным приложением
/** * @params {integer} _fn_user - идентификатор пользователя * @params {text} _c_version - текущая версия приложения * * @example * [{ "action": "cf_mui_pd_users", "method": "Select", "data": [{ "params": [_fn_user, _c_version] }], "type": "rpc", "tid": 0 }] */ BEGIN RETURN QUERY select u.id, u.f_parent, u.c_login, u.fn_file, concat(u.c_last_name, ' ', u.c_first_name, ' ', u.c_middle_name), u.c_description, u.b_disabled, (select string_agg(d.c_phone, ', ') from core.pd_userindivisions as uid inner join core.sd_divisions as d on uid.f_division = d.id where uid.f_user = _fn_user) from core.pd_users as u where u.id in ( select distinct cuir.f_user from core.cd_userinroutes as cuir where cuir.f_route in ( select r.id from core.cd_userinroutes as uir LEFT JOIN core.cd_routes as r ON r.id = uir.f_route where uir.f_user = _fn_user and core.sf_is_mobile_route(r.id))) OR u.id = _fn_user; END
Получение списка версий мобильным приложением
/** * @params {integer} _fn_user - идентификатор пользователя * @params {text} _c_version - текущая версия приложения * * @example * [{ "action": "cf_mui_sd_digests", "method": "Select", "data": [{ "params": [_fn_user, _c_version] }], "type": "rpc", "tid": 0 }] */ BEGIN RETURN QUERY select d.id, d.c_version, d.c_description, d.dx_created, d.n_version from core.sd_digests as d; END
Получение списка изменений для пользователя
/** * @params {integer} _fn_user - идентификатор пользователя * @params {text} _c_version - текущая версия приложения * * @example * [{ "action": "cf_mui_sd_table_change", "method": "Select", "data": [{ "params": [_fn_user, _c_version] }], "type": "rpc", "tid": 0 }] */ DECLARE _b_change boolean; BEGIN select false into _b_change; -- значение по умолчанию select (case when c_value = 'true' then true else false end) into _b_change from core.cd_settings where c_key = 'MBL_TABLE_CHANGE' limit 1; IF _b_change then return query select tc.c_table_name, max(coalesce(tc.n_change, 0.0)) as n_change, max(tc.f_user) as f_user from core.sd_table_change as tc where tc.f_user is null or tc.f_user = _fn_user group by tc.c_table_name; else return query select null::text, 0.0::double precision, null::integer from core.sd_table_change as tc where tc.c_table_name = 'unknow'; end if; END
Обновление Филиала/Отделения/Участка у пользователя
/** * @params {integer} _user_id - идент. пользователя * @params {json} _divisions - список отделений. Формат строки '[1,2]' * @params {json} _sub_divisions - список участков. Формат строки '[1,2]' * * @returns {integer} * 0 - ОК * * @example * [{ "action": "cf_update_user_divisions", "method": "Query", "data": [{ "params": [_user_id, _divisions, _sub_divisions] }], "type": "rpc", "tid": 0 }] */ BEGIN delete from core.pd_userindivisions where f_user = _user_id; -- проверяем divisions IF (select count(*) from json_array_elements_text(_divisions)) > 0 THEN insert into core.pd_userindivisions(f_user, f_division, f_subdivision) SELECT _user_id, t.value::integer, null FROM json_array_elements_text(_divisions) as t; END IF; -- проверяем sub_divisions IF (select count(*) from json_array_elements_text(_sub_divisions)) > 0 THEN insert into core.pd_userindivisions(f_user, f_division, f_subdivision) SELECT _user_id, (select f_division from core.sd_subdivisions where id = t.value::integer), t.value::integer FROM json_array_elements_text(_sub_divisions) as t; END IF; RETURN 0; END
Триггер. Обновление истории в маршрутах
DECLARE _f_route uuid; _f_status integer; _n_status_weight integer; _f_user integer; BEGIN -- все вычисления производяться после выполнения операций IF (TG_OP = 'INSERT' OR TG_OP = 'UPDATE') THEN select NEW.fn_route into _f_route; select NEW.fn_user into _f_user; ELSE select OLD.fn_route into _f_route; END IF; select rs.id, rs.n_order into _f_status, _n_status_weight from core.cd_route_history as rh inner join core.cs_route_statuses as rs ON rs.id = rh.fn_status where rh.fn_route = _f_route order by rh.d_date desc, rs.n_order desc limit 1; IF ((_n_status_weight <= 1 OR _n_status_weight >= 1000) OR -- если статус меньше чем 1 или больше 1000, то это Диспетчер (select count(*) from core.cd_userinroutes as uir where uir.f_route = _f_route and uir.f_user = _f_user and uir.b_main) >= 1) THEN -- если это главный обходчик update core.cd_routes as r set f_status = _f_status where r.id = _f_route; END IF; RETURN NULL; -- result is ignored since this is an AFTER trigger END
Триггер. Процедура логирования действия пользователя
BEGIN IF (TG_OP = 'UPDATE') THEN INSERT INTO core.cd_action_log(c_table_name, c_operation, jb_old_value, jb_new_value, c_user, d_date) VALUES (TG_TABLE_NAME, TG_OP, row_to_json(OLD), row_to_json(NEW), USER, clock_timestamp()); RETURN NEW; ELSIF (TG_OP = 'DELETE') THEN INSERT INTO core.cd_action_log(c_table_name, c_operation, jb_old_value, c_user, d_date) VALUES (TG_TABLE_NAME, TG_OP, row_to_json(OLD), USER, clock_timestamp()); RETURN OLD; ELSIF (TG_OP = 'INSERT') THEN INSERT INTO core.cd_action_log(c_table_name, c_operation, jb_new_value, c_user, d_date) VALUES (TG_TABLE_NAME, TG_OP, row_to_json(NEW), USER, clock_timestamp()); RETURN NEW; ELSE RETURN OLD; END IF; EXCEPTION WHEN OTHERS THEN INSERT INTO core.cd_sys_log(d_timestamp, c_descr) VALUES(clock_timestamp(), 'Непредвиденная ошибка логирования'); RETURN OLD; END;
Триггер. Обновление версии в пользователях
BEGIN IF (TG_OP = 'INSERT' OR TG_OP = 'UPDATE') THEN UPDATE core.pd_users as u set n_version = core.sf_version_to_number(NEW.c_version), c_version = NEW.c_version where u.id = NEW.fn_user; END IF; RETURN NEW; END
Триггер. Обновления версии приложения
BEGIN IF (TG_OP = 'INSERT' OR TG_OP = 'UPDATE') THEN NEW.n_version = core.sf_version_to_number(NEW.c_version); END IF; RETURN NEW; END
Триггер. Обновление справочной версии
DECLARE _users json; BEGIN if TG_OP = 'DELETE' and to_jsonb(OLD) ? 'fn_user' then select concat('[{"f_user":', OLD.fn_user::text ,'}]')::json into _users; else if TG_OP != 'DELETE' and to_jsonb(NEW) ? 'fn_user' then select concat('[{"f_user":', NEW.fn_user::text ,'}]')::json into _users; else select '[{"f_user":null}]'::json into _users; end if; end if; perform core.sf_table_change_update(t.c_table_name_ref, (u.value#>>'{f_user}')::integer) from json_array_elements(_users) as u left join (select TG_TABLE_NAME as c_table_name_ref UNION select c_table_name_ref from core.sd_table_change_ref where c_table_name = TG_TABLE_NAME) as t on 1=1; RETURN null; END
Системная функция. Получение прав доступа для пользователя. Используется NodeJS
/** * @params {integer} n_user_id - иден. пользователя */ BEGIN RETURN QUERY select * from (select a.c_name, a.c_criteria, a.c_path, a.c_function, a.c_columns, a.b_editable, a.b_deletable, a.b_creatable, a.b_full_control, core.sf_accesses(r.c_name, u.id, u.c_claims, a.f_user) as access from core.pd_accesses as a left join core.sv_users as u on n_user_id = u.id left join core.pd_roles as r on a.f_role = r.id where a.sn_delete = false) as t where t.access > 0; END;
Обновление ролей у пользователя
/** * @params {integer} _user_id - идент. пользователя * @params {json} _claims - роли в виде строки '["manager", "inspector"]' * * @returns {integer} идент. пользователя */ BEGIN delete from core.pd_userinroles where f_user = _user_id; insert into core.pd_userinroles(f_user, f_role, sn_delete) SELECT _user_id, (select id from core.pd_roles where t.value = c_name), false FROM json_array_elements_text(_claims) as t; RETURN _user_id; END
Системная функция для обработки прав. Для внешнего использования не применять
/** * @params {text} c_role_name - имя роли в безопасности * @params {integer} n_currentuser - идент. пользователя в безопасности * @params {text} c_claims - список ролей * @params {integer} n_user_id - иден. пользователя * * @returns * 0 - доступ запрещен */ BEGIN IF c_role_name is null and n_user_id is null then RETURN 1; ELSEIF (c_role_name is not null and c_claims is not null and POSITION(CONCAT('.', c_role_name, '.') IN c_claims) > 0) then RETURN 2; ELSEIF (c_role_name is not null and c_claims is not null and POSITION(CONCAT('.', c_role_name, '.') IN c_claims) > 0) then RETURN 3; ELSEIF (c_role_name is null and n_currentuser = n_user_id) then RETURN 4; ELSEIF (c_role_name = 'anonymous' or n_user_id = -1) then RETURN 5; else RETURN 0; end if; END
Генерация версии БД
var birthday = '2020-11-09'; var newVersion = '1.' + Math.floor(Math.abs(new Date().getTime() - new Date(birthday).getTime()) / (1000 * 3600 * 24)) + '.' + status + '.' + ((new Date().getHours() * 60) + new Date().getMinutes()); return newVersion;
Окончательное удаление маршрута без сохранения истории
/** * @params {uuid} _route_id - идентификатор маршрута * * @returns {integer} 0 - маршрут удален, 1 - ошибка при удалении */ DECLARE _result integer; BEGIN delete from core.cd_files where id IN (select fn_file from core.cd_attachments where fn_route = _route_id); delete from core.cd_attachments where fn_route = _route_id; delete from core.cd_results where fn_route = _route_id; delete from core.cd_user_points where fn_route = _route_id; delete from core.cd_route_history where fn_route = _route_id; delete from core.cd_userinroutes where f_route = _route_id; delete from dbo.ed_output_meter_readings where fn_route = _route_id; delete from core.cd_points where f_route = _route_id; delete from core.cd_routes where id = _route_id; RETURN 0; END
Проверка даты завершения маршрута, true - маршрут активный
/** * @params {date} _d_date - дата * @returns {boolean} false - маршрут завершен */ BEGIN RETURN (_d_date + interval '1 day') >= now(); END
Версия БД
/** * @returns {text} версия базы данных */ DECLARE _ver text; BEGIN SELECT c_value INTO _ver FROM core.cd_settings WHERE lower(c_key) = lower('DB_VERSION'); RETURN _ver; END
Сброс результатов прохождния маршрута. Системная функция, не применять на production
/** * @params {uuid} _route_id - идентификатор маршрута * * @returns {integer} 0 - маршрут очищен */ BEGIN delete from dbo.ed_output_meter_readings where fn_route = _route_id; delete from dbo.ed_output_conn_seals where fn_route = _route_id; delete from core.cd_files where id IN (select fn_file from core.cd_attachments where fn_route = _route_id); delete from core.cd_attachments where fn_route = _route_id; delete from core.cd_results where fn_route = _route_id; delete from core.cd_user_points where fn_route = _route_id; delete from core.cd_route_history where fn_route = _route_id and fn_status not IN (2,3); delete from core.cd_points where f_route = _route_id and b_anomaly = true; RETURN 0; END
Является ли маршрут доступным для мобильного устройства
/** * @params {uuid} _f_route - иден. маршрута * * @returns {boolean} true - маршрут доступен для мобильного устройства */ BEGIN IF (select count(*) from core.cd_routes as r inner join core.cs_route_statuses as rs ON r.f_status = rs.id where r.id = _f_route and rs.n_order > 0 and core.sf_finish_date(CASE WHEN r.b_extended = true THEN r.d_extended ELSE r.d_date_end END)) = 1 THEN RETURN true; ELSE RETURN false; END IF; END
Процедура очистки устаревших данных
/** * системная функция должна выполнять от postgres */ DECLARE _n_val integer = 100; _d_data timestamptz = date_trunc('day', now()) + '1 day'::interval; -- начало следующего дня _dg_cnt integer; --diagnostic _dg_text text = ''; BEGIN -- опрос настройки BEGIN select c_value::integer into _n_val from core.cd_settings where c_key = 'ALL_DEL_AFTER'; --в любых непонятных ситуациях берем 100 дней EXCEPTION WHEN OTHERS THEN _n_val = 100; END; _d_data = _d_data - _n_val * '1 day'::interval; delete from core.ad_audits where d_date < _d_data; get diagnostics _dg_cnt = row_count; _dg_text = _dg_text || ' core.ad_audits: удалено '|| _dg_cnt::text || E'\n'; delete from core.ad_mobile_devices where d_date < _d_data; get diagnostics _dg_cnt = row_count; _dg_text = _dg_text || ' core.ad_mobile_devices: удалено '|| _dg_cnt::text || E'\n'; delete from core.ad_mobile_indicators where d_date < _d_data; get diagnostics _dg_cnt = row_count; _dg_text = _dg_text || ' core.ad_mobile_indicators: удалено '|| _dg_cnt::text || E'\n'; delete from core.cd_notifications where d_date < _d_data; get diagnostics _dg_cnt = row_count; _dg_text = _dg_text || ' core.cd_notifications: удалено '|| _dg_cnt::text || E'\n'; delete from core.cd_action_log where d_date < _d_data; get diagnostics _dg_cnt = row_count; _dg_text = _dg_text || ' core.cd_action_log: удалено '|| _dg_cnt::text || E'\n'; delete from core.cd_action_log_user where d_date < _d_data; get diagnostics _dg_cnt = row_count; _dg_text = _dg_text || ' core.cd_action_log_user: удалено '|| _dg_cnt::text || E'\n'; delete from core.sd_client_errors where d_created < _d_data; get diagnostics _dg_cnt = row_count; _dg_text = _dg_text || ' core.sd_client_errors: удалено '|| _dg_cnt::text || E'\n'; insert into core.cd_sys_log(d_timestamp, c_descr) values(clock_timestamp(), 'Очистка таблиц выполнена. ' || E'\n' || _dg_text); EXCEPTION WHEN OTHERS THEN insert into core.cd_sys_log(d_timestamp, c_descr) values(clock_timestamp(), 'Непредвиденная ошибка очистки таблиц'); END;
/** * @params {text} _c_table_name - имя таблицы * @params {integer} _f_user - иднтификатор пользователя * * @returns {integer} - 0 результат выполнения * * @example * [{ "action": "sf_table_change_update", "method": "Query", "data": [{ "params": [_c_table_name, _f_user] }], "type": "rpc", "tid": 0 }] */ BEGIN IF (select count(*) from core.sd_table_change where c_table_name = _c_table_name and (case when _f_user is null then _f_user is null else f_user = _f_user end)) = 0 then INSERT INTO core.sd_table_change (c_table_name, n_change, f_user) VALUES (_c_table_name, (SELECT EXTRACT(EPOCH FROM now())), _f_user); else update core.sd_table_change set n_change = (SELECT EXTRACT(EPOCH FROM now())) where c_table_name = _c_table_name and (case when _f_user is null then _f_user is null else f_user = _f_user end); end if; RETURN 0; END
Принудительное обновление версии базу данных
/** * принудительное обновление * * @returns {text} новая версия базы данных */ DECLARE _ver text; BEGIN UPDATE core.cd_settings SET c_value = core.sf_build_version(0) WHERE lower(c_key) = lower('DB_VERSION'); SELECT c_value INTO _ver FROM core.cd_settings WHERE lower(c_key) = lower('DB_VERSION'); RETURN _ver; END;
Преобразование версии в число
/** * @params {text} c_version - версия приложения * @returns {bigint} числовой вариант версии */ try { var data = c_version.split('.'); return (parseInt(data[1]) * 24 * 60) + parseInt(data[3]); } catch(e) { return 0; }
F-Key | Name | Type | Description |
---|---|---|---|
f_user | integer | ||
c_name | text | ||
d_date_str | text | ||
d_date | timestamp with time zone | ||
n_longitude | numeric | ||
n_latitude | numeric | ||
c_network_status | text |
SELECT t.f_user , concat (u.c_last_name ,' ' , u.c_first_name ,' ' , u.c_middle_name ) AS c_name , t.d_date_str , t.d_date , t.n_longitude , t.n_latitude , t.c_network_status FROM ( ( SELECT t_1.fn_user AS f_user , to_char (t_1.d_date ,'dd.MM.YYYY HH24:MI'::text ) AS d_date_str , max (t_1.d_date) AS d_date , avg (t_1.n_longitude) AS n_longitude , avg (t_1.n_latitude) AS n_latitude , max (t_1.c_network_status) AS c_network_status FROM core.ad_tracking t_1 GROUP BY t_1.fn_user , (to_char (t_1.d_date ,'dd.MM.YYYY HH24:MI'::text ) ) UNION ALL SELECT t_1.fn_user AS f_user , to_char (t_1.d_date ,'dd.MM.YYYY HH24:MI'::text ) AS d_date_str , t_1.d_date , t_1.n_longitude , t_1.n_latitude , 'online'::text AS c_network_status FROM core.cd_user_points t_1 WHERE (t_1.n_longitude > (1)::numeric ) ) t JOIN core.pd_users u ON ( (t.f_user = u.id) ) ) ORDER BY t.d_date;
Бланки строгой отчетности
F-Key | Name | Type | Description |
---|---|---|---|
id | uuid |
PRIMARY KEY
DEFAULT uuid_generate_v4()
Идентификатор пломбы |
|
core.cs_result_types.id | f_result_type | integer |
NOT NULL
Тип результата к которому привязан бланк |
c_number | text |
NOT NULL
Номер бланка |
|
core.pd_users.id core.pd_users.id | f_user_from | integer |
Кто выдал |
dx_created | timestamp with time zone |
DEFAULT now()
Дата создания |
|
fn_result | uuid |
Видимо это должен быть FK на "результат выполнения" (core.cd_results) |
|
jb_history | json |
История изменения |
|
n_order | integer |
Порядок |
|
c_prefix | text |
Префикс |
|
n_number | bigint |
Номер бланка (числовой) |
|
core.sd_subdivisions.id | f_subdivision | integer |
Подразделение |
core.pd_users.id | f_user_to | integer |
Кто получил |
d_date_to | timestamp with time zone |
Дата выдачи |
|
dbo.es_blank_status.id | f_status | integer | |
c_document_trash | text |
Номер акта списания |
|
dbo.es_notice_trash.id | f_notice_trash | integer | |
c_notice | text | ||
core.pd_users.id | f_user_mol | integer |
Материально ответственное лицо |
Приборы учета
F-Key | Name | Type | Description |
---|---|---|---|
id | uuid |
PRIMARY KEY
DEFAULT uuid_generate_v4()
ID |
|
link | integer |
Идентификтор из Омнис |
|
dbo.es_device_types.id | f_device_type | integer |
Тип прибора учета |
c_serial_number | text |
Серийный номер ПУ |
|
n_rate | numeric(19,6) |
Коэффициент трансформации |
|
n_manufacture_year | integer |
Год выпуска |
|
d_setup_date | date |
Дата установки |
|
d_valid_date | date |
Дата гос. поверки |
|
dbo.es_device_location.id | f_device_location | integer |
Ссылка на Справочник в Омнис Место установки |
f_owner_type | integer |
Ссылка на Справочник в Омнис Эксплуатационная ответственность |
|
n_owner_type | integer |
Эксплуатационная ответственность |
|
c_device_location | text |
временное поле. т.к. в присланных данных более 700 строк по 1 РЭС |
|
imp_int | integer |
временно поле при импорте |
|
dbo.ed_registr_pts.id | f_registr_pts | uuid |
Ссылка на ТУ |
imp_text | text |
временное поле для импорта |
|
b_askue | boolean |
DEFAULT false
ПУ включен в АСКУЭ |
|
d_close_date | date |
Дата снятия ПУ |
|
d_last_check_date | date |
Дата последней инструментальной проверки |
|
c_last_check_doc | text |
Номер акта инструментальной проверки |
|
n_power_disc_speed | numeric |
Активная мощность по оборотам диска |
|
n_power_network_devices | numeric |
Активная мощность по приборам в силовой сети |
Tables referencing this one via Foreign Key Constraints:
Показания ПУ
F-Key | Name | Type | Description |
---|---|---|---|
id | uuid |
PRIMARY KEY
DEFAULT uuid_generate_v4()
Идентификатор |
|
n_value_prev | numeric(19,6) |
Пред. показание |
|
d_date_prev | timestamp with time zone |
Дата пред. показания |
|
n_digit | numeric(2,1) |
Разрядность |
|
dbo.es_scales.id | f_scale | integer |
NOT NULL
Шкала показания |
dx_created | timestamp with time zone |
DEFAULT now()
Дата создания записи |
|
dbo.ed_registr_pts.id | f_registr_pts | uuid |
NOT NULL
Ссылка на точку учета |
dbo.es_tariff_zones.id | f_tariff_zone | integer |
NOT NULL
Тарифная зона |
dbo.es_energy_types.id | f_energy_type | integer |
Ссылка на измеряемый показатель |
dbo.es_delivery_methods.id | f_delivery_method | integer |
Ссылка на источик показаний |
d_replace_date | timestamp with time zone |
Дата снятия/замены |
|
dbo.es_reading_statuses.id | f_reading_status | integer |
NOT NULL
DEFAULT 1
Статус показания |
dbo.ed_devices.id | f_device | uuid |
Прибор учета |
jb_sources | jsonb |
Привязка новых пломб к точке учета
F-Key | Name | Type | Description |
---|---|---|---|
id | uuid |
PRIMARY KEY
DEFAULT uuid_generate_v4()
[e110] Идентификатор |
|
fn_seal | uuid |
Ссылка на пред. пломбу |
|
fn_point | uuid |
NOT NULL
[e90] Точка маршрута |
|
fn_route | uuid |
NOT NULL
[e80] Маршрута |
|
fn_user_point | uuid |
NOT NULL
[e70] Пользовательская точка |
|
fn_seal_new | uuid |
NOT NULL
[e50|d] Новая пломба |
|
fn_type | integer |
[e40] Тип пломбы |
|
fn_place | integer |
[e30] Место установки |
|
d_date | timestamp with time zone |
NOT NULL
[e20] Дата |
|
dx_created | timestamp with time zone |
DEFAULT now()
[e10] Дата создания записи |
|
fn_result | uuid |
NOT NULL
Результат |
|
b_export | boolean |
DEFAULT false
Экспортировано |
Tables referencing this one via Foreign Key Constraints:
Показания ПУ
F-Key | Name | Type | Description |
---|---|---|---|
id | uuid |
PRIMARY KEY
DEFAULT uuid_generate_v4()
Идентификатор |
|
fn_meter_reading | uuid |
NOT NULL
Показание ПУ |
|
fn_point | uuid |
Точка маршрута |
|
fn_route | uuid |
Маршрута |
|
fn_user_point | uuid |
Пользовательская точка |
|
n_value | numeric(19,6) |
Показание |
|
d_date | timestamp with time zone |
NOT NULL
Дата показания |
|
dx_created | timestamp with time zone |
DEFAULT now()
Дата создания записи |
|
b_export | boolean |
DEFAULT false
Экспортировано |
|
fn_result | uuid |
Идентификатор результата (акта) |
Исходящая информация о трансформаторах
F-Key | Name | Type | Description |
---|---|---|---|
id | uuid |
PRIMARY KEY
DEFAULT uuid_generate_v4()
Идентификатор |
|
fn_route | uuid |
Маршрута |
|
fn_point | uuid |
Точка маршрута |
|
fn_user_point | uuid |
Пользовательский результат |
|
fn_result | uuid |
Результат |
|
fn_transformer | uuid |
Пред. трансформатор |
|
c_number | text |
Номер трансформатора |
|
n_year | integer |
Год выпуска |
|
d_date | timestamp with time zone |
Дата установки?? |
|
n_rate | numeric |
Коэффициент трансформации |
|
fn_phase | integer |
Фаза |
|
dx_created | timestamp with time zone |
DEFAULT now()
Дата создания записи |
|
d_date_check | timestamp with time zone |
Дата поверки |
|
b_voltage | boolean |
Является трансформатором напряжения |
|
fn_device_type | integer |
Тип |
|
b_export | boolean |
DEFAULT false
Экспортировано |
|
n_check_cycle | integer |
Межповерочный интервал, лет |
|
n_tt1 | numeric(19,6) |
Величина на первичнй обмотке |
|
n_tt2 | numeric(19,6) |
Величина на вторичной обмотке |
Учетный показатель
F-Key | Name | Type | Description |
---|---|---|---|
id | uuid |
PRIMARY KEY
DEFAULT uuid_generate_v4()
ID |
|
core.sd_divisions.id | f_division | integer |
NOT NULL
Филиал/Отделение |
core.sd_subdivisions.id | f_subdivision | integer |
NOT NULL
Участок |
b_disabled | boolean |
NOT NULL
DEFAULT false
Отлючено |
|
dx_created | timestamp with time zone |
DEFAULT now()
Дата создания |
|
sn_delete | boolean |
NOT NULL
DEFAULT false
Признак что запись удалена |
|
c_registr_pts | text |
Наименование точки учета |
|
dbo.es_status_consume.id | f_status_consume | integer |
Статус точки учета |
b_technical_metering | boolean |
Признак Тех. Учета |
|
c_substation | text |
Подстанция |
|
c_line_substation | text |
Фидер 6-10/35кВ |
|
c_rp | text |
РП |
|
c_line_rp | text |
Фидер 6-10/35кВ |
|
c_tp | text |
Трансформаторная подстанция |
|
c_line_tp | text |
Фидер 0,4кВ |
|
c_line_segment | text |
№ опоры ВЛ-0,4кВ |
|
f_violation | integer |
Ссылка на Тип нарушения |
|
d_violation_date | date |
Дата нарушения |
|
d_date_before | date |
Срок устранения нарушения |
|
dbo.sd_subscr.id | f_subscr | uuid |
Ссылка на абонента |
dbo.ss_address.id | f_address | uuid |
Ссылка на адресную витрину |
f_subscr_int | integer |
Наверно для импорта |
|
f_device_int | integer |
Наверно для импорта |
|
imp_int | integer |
временно поле при импорте |
|
c_line_tp_1 | text |
Линия 0,4 кВ |
|
c_line_segment_1 | text |
Участок линии 0,4 кВ |
|
imp_text | text |
Код УП |
|
d_close_date | date |
Дата закрытия ТУ |
|
c_status_registr_pts | text |
Статус ТУ |
|
c_status | text |
Внеплановые работы |
|
c_predictr | text |
Показатель из системы ПредиктР |
|
n_geo_lat | numeric(19,6) | ||
n_geo_lon | numeric(19,6) | ||
d_restriction_date | date |
Дата введения ограничения |
|
c_restriction_method | text |
Способ ограничения |
|
c_network_pts_code | text |
Номер точки поставки |
|
n_max_cap | integer |
Величина максимальной мощности |
|
b_sub | boolean |
NOT NULL
DEFAULT false
Признак: точка учета является субабонентом |
|
b_transit | boolean |
NOT NULL
DEFAULT false
Признак: транзитер |
|
dbo.es_registr_pts_status.id | f_registr_pts_status | integer |
Tables referencing this one via Foreign Key Constraints:
История точек учета
F-Key | Name | Type | Description |
---|---|---|---|
id | uuid | PRIMARY KEY DEFAULT uuid_generate_v4() | |
dbo.ed_registr_pts.id | f_registr_pts | uuid |
UNIQUE#1
NOT NULL
Идентификатор точки учета |
b_plan | boolean |
NOT NULL
Является плановым точкой |
|
dbo.es_no_plan_works.id | f_no_plan_work | smallint |
UNIQUE#1
Тип внеплановой работы |
d_date_period | date |
UNIQUE#1
NOT NULL
Период работ |
|
core.cs_point_types.id | f_point_type | integer |
UNIQUE#1
Тип работ по точке |
b_no_plan | boolean |
NOT NULL
признак что точка является внеплановой |
|
d_no_plan_date | date |
планируемая дата выполнения работ по внеплановой точке. Будет заполняться при импорте внеплановых работ/ручном указании внеплановых работ по точке учета через АРМ Диспетчера. |
Плобмы
F-Key | Name | Type | Description |
---|---|---|---|
id | uuid |
PRIMARY KEY
DEFAULT uuid_generate_v4()
Идентификатор |
|
c_number | text |
NOT NULL
Номер пломбы |
|
core.pd_users.id | f_user_from | integer |
Кто выдал |
dx_created | timestamp with time zone |
DEFAULT now()
Дата создания |
|
dbo.ed_registr_pts.id | f_registr_pts | uuid |
Точка |
c_prefix | text |
Префикс |
|
c_type | text |
Типы пломб (скорее всего избыточно, так как есть FK f_type) |
|
c_location | text |
Место установки пломбы (скорее всего избыточно, так как есть FK f_place) |
|
imp_int | integer |
временно для импорта |
|
d_replace_date | timestamp with time zone |
Дата замены |
|
n_order | integer |
Порядок |
|
jb_history | json |
История изменений |
|
dbo.es_seal_types.id | f_type | integer |
Типы пломб |
dbo.es_seal_places.id | f_place | integer |
Место установки пломбы |
dbo.ed_output_conn_seals.id | f_output_conn_seal | uuid |
Ссылка на результат из мобильного приложения |
n_number | bigint |
Номер сквозной |
|
core.pd_users.id | f_user_to | integer |
Кто получил |
d_date_to | timestamp without time zone |
Дата выдачи - заполняется при указании поля f_user_to |
|
core.sd_subdivisions.id | f_subdivision | integer |
Подразделение |
dbo.es_seal_status.id | f_status | integer | NOT NULL |
c_document_trash | text |
Номер акта списания |
|
dbo.es_notice_trash.id | f_notice_trash | smallint |
Причина забраковки пломбы |
core.pd_users.id | f_user_mol | integer |
Материально ответственное лицо за получение пломб в РЭС |
c_notice | text |
Поле для списания пломб, установленных без использования мобильного приложения. Ввод вручную |
Трансформаторы
F-Key | Name | Type | Description |
---|---|---|---|
id | uuid |
PRIMARY KEY
DEFAULT uuid_generate_v4()
ID |
|
dbo.ed_registr_pts.id | f_registr_pts | uuid |
Ссылка на идентификатор ТУ |
b_voltage | boolean |
Признак, что это ТН |
|
c_serial_number | text |
Серийниый номер |
|
d_replace_before | date |
Дата следующей госповерки |
|
c_phase | text |
Фаза ТТ/ТН |
|
imp_int | integer |
Ссылка на идентификатор ТТ/ТН из сторонней системы |
|
n_manufacture_year | integer |
Год выпуска |
|
d_check_date | date |
Дата гос.поверки |
|
d_replace_date | date |
Дата сняти прибора (признак отключения) |
|
imp_text | text |
временно для импорта |
|
dx_created | timestamp with time zone |
DEFAULT now()
Дата создания записи |
|
f_device_type | integer |
Ссылка на тип документа |
|
n_rate | numeric(10,2) |
Коэффициент трансформации |
Нарушения
F-Key | Name | Type | Description |
---|---|---|---|
id | uuid |
PRIMARY KEY
DEFAULT uuid_generate_v4()
Идентификатор нарушения |
|
c_violation_type | text |
Тип нарушения |
|
d_violation_date | date |
Дата нарушения |
|
d_date_elimination | date |
Срок устранения нарушения |
|
f_registr_pts | text |
Идентификатор точки учета |
Статусы бланков
F-Key | Name | Type | Description |
---|---|---|---|
id | smallint | PRIMARY KEY DEFAULT nextval('dbo.es_blank_status_id_seq'::regclass) | |
c_name | text | NOT NULL | |
n_code | smallint | NOT NULL | |
c_const | text | NOT NULL |
Tables referencing this one via Foreign Key Constraints:
Источник показаний
F-Key | Name | Type | Description |
---|---|---|---|
id | serial |
PRIMARY KEY
Идентификатор |
|
n_code | integer |
Код |
|
c_name | text |
Наименование |
|
c_const | text |
Константа |
|
b_default | boolean |
Признак значения по-умолчанию |
Tables referencing this one via Foreign Key Constraints:
Категории приборов
F-Key | Name | Type | Description |
---|---|---|---|
id | serial |
PRIMARY KEY
Идентификатор |
|
n_code | integer |
Код |
|
c_name | text |
Наименование |
|
b_meter | boolean |
NOT NULL
Признак: Наличие показаний |
|
b_tranf | boolean |
NOT NULL
Признак: Является трансформатором |
|
b_default | boolean |
NOT NULL
Категория по-умолчанию |
|
b_disabled | boolean |
NOT NULL
Признак: Категория не используется |
Tables referencing this one via Foreign Key Constraints:
Место установки
F-Key | Name | Type | Description |
---|---|---|---|
id | serial |
PRIMARY KEY
Идентификатор |
|
n_code | integer |
Код |
|
c_name | text |
NOT NULL
Наименование места установки |
|
c_const | text |
Константа |
|
b_default | boolean |
NOT NULL
Признак значения по-умолчанию |
|
core.sd_divisions.id | f_division | integer |
Ссылка на филиал/отделение ЦиП |
core.sd_subdivisions.id | f_subdivision | integer |
Ссылка на участок/РЭС ЦиП |
Tables referencing this one via Foreign Key Constraints:
Типы прибора
F-Key | Name | Type | Description |
---|---|---|---|
id | serial |
PRIMARY KEY
Идентификатор |
|
dbo.es_device_categories.id | f_device_categories | integer |
NOT NULL
Категория |
c_name | text |
Наименование |
|
c_modification | text |
Модификация |
|
n_check_cycle | integer |
Межповерочный интервал, лет |
|
dbo.es_tariff_zones.id | f_tariff_zone | integer |
Количество временных зон |
b_phase3 | boolean |
Признак: Трехфазный |
|
b_disabled | boolean |
NOT NULL
Признак: Тип прибора не используется |
|
f_device_types | integer |
Наверно это идентификатор из внешней системы |
|
n_tariff | integer |
Количество тарифных зон |
|
n_digits | numeric(2,1) |
Разрядность |
|
n_tt1 | numeric(19,6) |
Величина на первичнй обмотке |
|
n_tt2 | numeric(19,6) |
Величина на вторичной обмотке |
|
n_rate | numeric(10,2) |
Коэффициент трансформации |
|
f_main_division | integer |
Филиал |
|
f_division | integer |
Отделение |
|
f_subdivision | integer |
Участок |
Tables referencing this one via Foreign Key Constraints:
Виды измерения
F-Key | Name | Type | Description |
---|---|---|---|
id | serial |
PRIMARY KEY
Идентификатор |
|
n_code | integer |
Код |
|
c_name | text |
NOT NULL
Наименование |
|
c_const | text |
Константа |
|
b_default | boolean |
NOT NULL
Признак значения по-умолчанию |
|
c_code_out | text |
Код из внешней системы |
Tables referencing this one via Foreign Key Constraints:
Причины недопуска
F-Key | Name | Type | Description |
---|---|---|---|
id | serial |
PRIMARY KEY
Идентификатор |
|
n_code | integer |
Код |
|
c_name | text |
NOT NULL
Наименование |
|
c_short_name | text |
Краткое наименование |
|
c_const | text |
Константа |
|
n_order | integer |
Сортировка |
|
b_default | boolean |
NOT NULL
DEFAULT false
По умолчанию |
|
b_disabled | boolean |
NOT NULL
DEFAULT false
Отключено |
Справочник внеплановых работ
F-Key | Name | Type | Description |
---|---|---|---|
id | smallint | PRIMARY KEY DEFAULT nextval('dbo.es_no_plan_work_id_seq'::regclass) | |
c_name | text |
NOT NULL
Наименование |
|
c_const | text |
NOT NULL
Константа |
|
b_disabled | boolean |
NOT NULL
Отключено |
|
n_order | smallint |
NOT NULL
Сортировка |
|
n_code | smallint |
Код |
|
c_short_name | text |
Сокращенное наименование |
Tables referencing this one via Foreign Key Constraints:
Причина списания пломбы/бланка
F-Key | Name | Type | Description |
---|---|---|---|
id | smallint | PRIMARY KEY DEFAULT nextval('dbo.es_notice_trash_id_seq'::regclass) | |
c_name | text | NOT NULL | |
c_const | text | NOT NULL | |
b_default | boolean | NOT NULL | |
b_disabled | boolean | NOT NULL | |
b_seal | boolean |
NOT NULL
Применяется для пломб |
Фазы
F-Key | Name | Type | Description |
---|---|---|---|
id | serial |
PRIMARY KEY
Идентификатор |
|
n_code | integer |
Код |
|
c_name | text |
NOT NULL
Наименование |
|
c_const | text |
Константа |
Классы точности прибора
F-Key | Name | Type | Description |
---|---|---|---|
id | serial |
PRIMARY KEY
Идентификатор |
|
n_code | integer |
Код |
|
c_name | text |
Наименование |
|
c_const | text |
Константа |
Статусы показаний
F-Key | Name | Type | Description |
---|---|---|---|
id | serial |
PRIMARY KEY
Идентификатор |
|
n_code | integer |
Код |
|
c_name | text |
Наименование |
|
c_const | text |
Константа |
Tables referencing this one via Foreign Key Constraints:
Статус активности ТУ
F-Key | Name | Type | Description |
---|---|---|---|
id | serial | PRIMARY KEY | |
c_name | text | NOT NULL | |
c_const | text | NOT NULL | |
b_disabled | boolean | NOT NULL |
Tables referencing this one via Foreign Key Constraints:
Типы ограничений
F-Key | Name | Type | Description |
---|---|---|---|
id | serial |
PRIMARY KEY
Идентификатор |
|
n_code | integer |
Код |
|
c_name | text |
NOT NULL
Наименование |
|
c_short_name | text |
Краткое наименование |
|
c_const | text |
Константа |
|
n_order | integer |
Сортировка |
|
b_default | boolean |
NOT NULL
DEFAULT false
По умолчанию |
|
b_disabled | boolean |
NOT NULL
DEFAULT false
Отключено |
Шкалы прибора учета
F-Key | Name | Type | Description |
---|---|---|---|
id | integer |
PRIMARY KEY
DEFAULT nextval('dbo.auto_id_es_scales'::regclass)
Идентификатор |
|
n_code | integer |
Код |
|
c_name | text |
NOT NULL
Наименование |
|
c_short_name | text |
Краткое наименование |
|
c_const | text |
NOT NULL
Константа |
|
n_order | integer |
Сортировка |
|
b_default | boolean |
NOT NULL
DEFAULT false
По умолчанию |
|
b_disabled | boolean |
NOT NULL
DEFAULT false
Отключено |
|
c_code_out | text |
Код из внешней системы |
Tables referencing this one via Foreign Key Constraints:
Справочник мест установки пломб
F-Key | Name | Type | Description |
---|---|---|---|
id | integer |
PRIMARY KEY
DEFAULT nextval('dbo.auto_id_es_seal_places'::regclass)
[e80] Идентификатор |
|
n_code | integer |
[e70] Код |
|
c_name | text |
NOT NULL
[e60|d] Наименование |
|
c_short_name | text |
[e50] Краткое наименование |
|
c_const | text |
[e40] Константа |
|
n_order | integer |
[e30] Сортировка |
|
b_default | boolean |
NOT NULL
DEFAULT false
[e20] Отключено |
|
b_disabled | boolean |
NOT NULL
DEFAULT false
[e10] Отключено |
Tables referencing this one via Foreign Key Constraints:
Статусы пломб
F-Key | Name | Type | Description |
---|---|---|---|
id | smallint | PRIMARY KEY DEFAULT nextval('dbo.es_seal_status_id_seq'::regclass) | |
c_name | text | NOT NULL | |
n_code | smallint | NOT NULL | |
c_const | text | NOT NULL |
Tables referencing this one via Foreign Key Constraints:
тип пломбы
F-Key | Name | Type | Description |
---|---|---|---|
id | integer |
PRIMARY KEY
DEFAULT nextval('dbo.auto_id_es_seal_types'::regclass)
[e80] Идентификатор |
|
n_code | integer |
[e70] Код |
|
c_name | text |
NOT NULL
[e60|d] Наименование |
|
c_short_name | text |
[e50] Краткое наименование |
|
c_const | text |
[e40] Константа |
|
n_order | integer |
[e30] Сортировка |
|
b_default | boolean |
NOT NULL
DEFAULT false
[e20] Отключено |
|
b_disabled | boolean |
NOT NULL
DEFAULT false
[e10] Отключено |
Tables referencing this one via Foreign Key Constraints:
Статус потребления ТУ
F-Key | Name | Type | Description |
---|---|---|---|
id | serial | PRIMARY KEY | |
n_code | integer | ||
c_name | text | NOT NULL | |
c_const | text | ||
n_order | integer | ||
b_default | boolean | NOT NULL DEFAULT false | |
b_disabled | boolean | NOT NULL DEFAULT false |
Tables referencing this one via Foreign Key Constraints:
Тарифные зоны
F-Key | Name | Type | Description |
---|---|---|---|
id | integer |
PRIMARY KEY
DEFAULT nextval('dbo.auto_id_es_tariff_zones'::regclass)
Идентификатор |
|
n_count_scale | integer |
NOT NULL
Код |
|
c_name | text |
NOT NULL
Наименование |
|
c_short_name | text |
Краткое наименование |
|
c_const | text |
NOT NULL
Константа |
|
n_order | integer |
Сортировка |
|
b_default | boolean |
NOT NULL
DEFAULT false
По умолчанию |
|
b_disabled | boolean |
NOT NULL
DEFAULT false
Отключено |
Tables referencing this one via Foreign Key Constraints:
Причина проверки
F-Key | Name | Type | Description |
---|---|---|---|
id | serial |
PRIMARY KEY
Идентификатор |
|
c_name | text |
NOT NULL
Наименование |
|
c_const | text |
Константа |
|
n_order | integer |
Сортировка |
|
b_disabled | boolean |
NOT NULL
DEFAULT false
Отключено |
Типы нарушений
F-Key | Name | Type | Description |
---|---|---|---|
id | serial |
PRIMARY KEY
Идентификатор |
|
n_code | integer |
Код |
|
c_name | text |
NOT NULL
Наименование |
|
c_short_name | text |
Краткое наименование |
|
c_const | text |
Константа |
|
n_order | integer |
Сортировка |
|
b_default | boolean |
NOT NULL
DEFAULT false
По умолчанию |
|
b_disabled | boolean |
NOT NULL
DEFAULT false
Отключено |
|
c_code_out | text |
Код из внешней системы |
Сопоставление видов работ
F-Key | Name | Type | Description |
---|---|---|---|
id | serial |
PRIMARY KEY
Идентификатор |
|
core.cs_route_types.id | f_route_type | integer |
NOT NULL
Тип маршрута |
core.cs_point_types.id | f_point_type | integer |
NOT NULL
Тип точки |
core.cs_result_types.id | f_result_type | integer |
NOT NULL
Тип результата |
b_disabled | boolean |
NOT NULL
DEFAULT false
Признак: не используется |
|
dx_created | timestamp with time zone |
NOT NULL
DEFAULT now()
Дата создания записи |
Сотрудники
F-Key | Name | Type | Description |
---|---|---|---|
id | uuid |
PRIMARY KEY
DEFAULT uuid_generate_v4()
Идентификатор |
|
f_maindivision_int | integer |
Целочисленная ссылка на филиал |
|
f_division_int | integer |
Целочисленная ссылка на отделение |
|
f_subfivision_int | integer |
Целочисленная ссылка на участок |
|
c_name1 | text |
Фамилия |
|
c_name2 | text |
Имя |
|
c_name3 | text |
Отчество |
|
d_date_begin | date |
Дата трудоустройства |
|
d_date_end | date |
Дата увольнения |
|
c_login | text |
Логин (первичный) |
|
s_password | text |
Пароль (первичный) |
|
c_tab_number | text |
Табельный номер |
|
f_roles | integer |
Ссылка на Справочник Роли |
|
c_telephone | text |
Номер телефона |
|
c_email | text |
|
|
b_skill1 | boolean |
Квалификация_1: Контрольное снятие показаний |
|
b_skill2 | boolean |
Квалификация_2: Инструментальная проверка |
|
b_skill3 | boolean |
Квалификация_3: Замена (снятие) прибора, Установка прибора |
|
b_skill4 | boolean |
Квалификация_4: Ввод ограничения энергоснабжения, Возобновление энергоснабжения |
|
b_gpx | boolean |
Договор ГПХ |
Абонент
F-Key | Name | Type | Description |
---|---|---|---|
id | uuid |
PRIMARY KEY
DEFAULT uuid_generate_v4()
Идентификатор |
|
f_division | integer |
Идентификатор отделения (ПО) |
|
f_subdivision | integer |
Идентификатор участка (РЭС) |
|
c_code | text |
Код абонента |
|
c_name1 | text |
Наименование ЮЛ:c_name_consumer | Фамилия ФЛ |
|
c_name2 | text |
Имя ФЛ |
|
c_name3 | text |
Отчество ФЛ |
|
c_telephone | text |
Номер телефона |
|
b_problem_person | boolean |
NOT NULL
DEFAULT false
Проблемный абонент |
|
b_person | boolean |
Признак ФЛ |
|
n_check_date | integer |
интервал проверок?? |
|
f_subscr | integer |
Наверно это Идентификатор ЛС из внешней системы |
|
imp_int | integer |
временное поле для импорта |
|
jb_history | json |
История изменений номеров телефона |
|
f_partners | text |
Идентификатор абонента из внешней системы |
Tables referencing this one via Foreign Key Constraints:
Адреса
F-Key | Name | Type | Description |
---|---|---|---|
id | uuid |
PRIMARY KEY
DEFAULT uuid_generate_v4()
ID |
|
c_name | text |
Полный адрес |
|
c_index | text |
Индекс |
|
c_region | text |
Наименование области |
|
code_fias_region | uuid |
Код ФИАС региона |
|
c_raion | text |
Наименование района |
|
data_area_fias_id | uuid | ||
c_city_name | text |
Наименование города |
|
data_city_fias_id | uuid |
Код ФИАС города |
|
c_settlement_name | text |
Наименование населенного пункта |
|
settlement_fias_id | uuid |
Код ФИАС населенного пункта |
|
c_street_name | text |
Наименование улицы |
|
data_street_fias_id | uuid |
Код ФИАС улицы |
|
c_house_name | text |
Номер дома |
|
data_house_fias_id | uuid |
Код ФИАС дома |
|
c_block_name | text |
Корпус |
|
c_flat_name | text |
Квартира |
|
n_fias_level | integer |
Уровень ФИАС |
|
n_geo_lat | numeric(19,6) |
Широта |
|
n_geo_lon | numeric(19,6) |
Долгота |
|
qc_geo | integer |
Точность координат |
|
imp_int | integer |
временное поле для импорта |
|
c_comment_address | text |
Комментарий к адресу |
|
imp_text | text |
временное поле для импорта |
|
f_conn_points | text |
Идентификатор объекта с внешней системы |
|
c_name_obj | text |
Наименование объекта |
|
b_dadata | boolean |
NOT NULL
DEFAULT false
Признак: адрес обработан сервисом DaData |
Tables referencing this one via Foreign Key Constraints:
Справочник адресов ФИАС
F-Key | Name | Type | Description |
---|---|---|---|
id | uuid | ||
c_region | text |
наименование региона |
|
f_region | uuid |
идентификатор региона ФИАС |
|
c_province | text |
наименование района |
|
f_province | uuid |
идентификатор района ФИАС |
|
c_town | text |
наименование города |
|
f_town | uuid |
идентификатор города ФИАС |
|
c_municipality | text |
наименование нас. пункта |
|
f_municipality | uuid |
идентификатор нас. пункта ФИАС |
|
c_street | text |
наименование улицы |
|
f_street | uuid |
идентификатор улицы ФИАС |
|
c_house_number | text |
номер дома |
|
f_house | uuid |
идентификатор дома ФИАС |
|
n_object_type_level | integer |
регион |
SELECT sa.f_house AS id , sa.c_region , sa.f_region , sa.c_province , sa.f_province , sa.c_town , sa.f_town , sa.c_municipality , sa.f_municipality , sa.c_street , sa.f_street , sa.c_house_number , sa.f_house , sa.n_object_type_level FROM dbo.ss_fias_address sa;
Получение дерева подразделений для пользователя
/** * @params {integer} _f_user - пользователь * * @example * [{ "action": "cf_arm_all_subdivisions", "method": "Select", "data": [{ "params": [_f_user] }], "type": "rpc", "tid": 0 }] */ BEGIN RETURN QUERY -- поиск subdivisions select sd.id, sd.f_division, sd.n_code, sd.c_name, true as b_subdivision from core.pd_userindivisions as ud inner join core.sd_subdivisions as sd ON ud.f_subdivision = sd.id where ud.f_user = _f_user and ud.f_subdivision is not null and b_disabled = false UNION -- поиск через divisions select sd.id, sd.f_division, sd.n_code, sd.c_name, false as b_subdivision from core.sd_subdivisions as sd where sd.b_disabled = false and sd.f_division IN (WITH RECURSIVE tree AS ( SELECT d.id, d.f_division FROM core.sd_divisions as d where d.id IN (select ud.f_division from core.pd_userindivisions as ud where ud.f_user = _f_user and ud.f_division is not null and ud.f_subdivision is null) UNION SELECT d.id, d.f_division FROM core.sd_divisions as d JOIN tree ON d.id = tree.f_division) select t.id from tree as t); END
Функция предназначена для назначения или переназначения исполнителей в маршруте
/** * @params {integer} _f_current_user - текущий пользователь * @params {json} _users - массив пользователей. В функцияю должно передаваться как строка, например: '[{ "id":4, "b_main": true }, { "id": 13, "b_main": false }]' * @params {uuid} _f_route - иден. маршрута * @params {boolean} _b_plan - true - применяется в пранировании * * @returns {integer} * 0 - ОК * 1 - маршрут не найден * 2 - пользователь не найден * * @example * [{ "action": "cf_arm_assign_route", "method": "Query", "data": [{ "params": [_f_current_user, _users, _f_route, _b_plan] }], "type": "rpc", "tid": 1 }] */ DECLARE _status_id integer; -- иден. статус передан (назначен) _transfered_status_id integer; -- иден. статуса передан _re_assign boolean; -- переназначенение BEGIN select false into _re_assign; IF (select count(*) from core.cd_routes as r where r.id = _f_route) = 1 THEN IF (select count(*) from core.pd_users as u where u.id = _f_current_user) = 1 THEN select rs.id into _status_id from core.cs_route_statuses as rs where rs.c_const = CASE WHEN _b_plan = true THEN 'CREATED' ELSE 'ASSINGNED' END; -- находим информацию о статусе IF (select count(*) from core.cd_routes as r where r.id = _f_route and r.f_status = _status_id) = 1 THEN select true into _re_assign; -- удаляем информацию из истории delete from core.cd_route_history as rh where rh.fn_route = _f_route and rh.fn_status = _status_id; -- удаляем привязку к пользователю delete from core.cd_userinroutes as uir where uir.f_route = _f_route; END IF; -- статус не меняется если вес положительный IF(select rs.n_order from core.cd_routes as r inner join core.cs_route_statuses as rs ON r.f_status = rs.id where r.id = _f_route) < 0 THEN -- создаем новый статус insert into core.cd_route_history (fn_route, fn_status, fn_user, d_date, c_notice) values (_f_route, _status_id, _f_current_user, now(), (CASE WHEN _re_assign THEN 'Переназначен' ELSE 'Назначен' END)); ELSE select rs.id into _transfered_status_id from core.cs_route_statuses as rs where rs.c_const = 'TRANSFERRED'; -- создаем новый статус "Передан" insert into core.cd_route_history (fn_route, fn_status, fn_user, d_date, c_notice) values (_f_route, _transfered_status_id, _f_current_user, now(), 'Назначен(ы) новый(е) пользователь(и)'); END IF; IF _users is not null and (select count(*) from json_array_elements(_users::json)) > 0 THEN -- создаем привязку insert into core.cd_userinroutes(f_route, f_user, b_main) select _f_route, (t.value #>> '{id}')::integer, (t.value #>> '{b_main}')::boolean from json_array_elements(_users::json) as t where (t.value #>> '{id}')::integer NOT IN (select uir.f_user from core.cd_userinroutes as uir where uir.f_route = _f_route); END IF; RETURN 0; ELSE RETURN 2; -- нет пользователя END IF; ELSE RETURN 1; -- нет маршрута END IF; END
Массовое обновление типа работ по точкам маршрута
/** * * @params {json} _items - список идентификаторов cd_points, требуется передать в виде строки '["e7ded0cd-12dd-47f5-a75b-192376291e83"]' * @params {integer} _f_point_type - тип работ * * @returns {integer} * 0 - ОК * * @example * [{ "action": "cf_arm_cd_point_update", "method": "Query", "data": [{ "params": [_items, _f_point_type] }], "type": "rpc", "tid": 0}] */ BEGIN update core.cd_points as p set f_type = _f_point_type where p.id in (select t.value::uuid from json_array_elements_text(_items) as t); RETURN 0; END
Получение всех точек заданий, по значениям, выбранным в фильтре за текущий день
/** * @params {integer} _f_main_division - иден. филиал. Обязателен при передаче * @params {integer} _f_division - иден. отделение. Обязателен при передаче * @params {integer} _f_subdivision - иден. участок. Обязателен при передаче * @params {integer} _f_manager - иден. диспетчер. Может быть null * @params {integer} _f_user - иден. обходчика. Может быть null * @params {date} _d_date - дата для фильтрации * * @example * [{ "action": "cf_arm_cd_points", "method": "Select", "data": [{ "params": [_f_main_division, _f_division, _f_subdivision, _f_manager, _f_user] }], "type": "rpc", "tid": 0}] */ DECLARE _routes json; BEGIN IF _d_date is null THEN select now()::date into _d_date; END IF; -- обходчики выбраны и находим все маршруты за текущую дату select array_to_json(array_agg(t.id)) into _routes from (select r.id from core.cd_userinroutes as uir INNER JOIN core.cd_routes as r ON r.id = uir.f_route where uir.b_main = true and uir.f_user IN ( select u.id from dbo.cf_arm_pd_users(_f_main_division, _f_division, _f_subdivision, _f_manager, _f_user) as u ) and _d_date >= r.d_date_start and _d_date <= (CASE WHEN r.b_extended THEN r.d_extended ELSE r.d_date_end END)) as t; RETURN QUERY select * from dbo.cf_arm_cd_points(_routes, _d_date); END
Получить список заданий по маршруту
/** * @params {json} _routes - массив маршрутов, требуется передать в виде строки '["e7ded0cd-12dd-47f5-a75b-192376291e83"]' * @params {date} _d_date - дата фильтрации, например 2020-10-01 * @example * [{ "action": "cf_arm_cd_points", "method": "Select", "data": [{ "params": [_routes, _d_date] }], "type": "rpc", "tid": 0}] */ BEGIN RETURN QUERY WITH user_points as ( select up.fn_point, up.fn_user, up.d_date from core.cd_user_points as up where up.fn_route IN (select t.value::uuid from json_array_elements_text(_routes) as t) --and up.d_date::date = _d_date::date ) select p.id, (select count(*) from user_points as up where up.fn_point = p.id) > 0 as b_done, ad.c_name as c_address, coalesce(rp.n_geo_lon, ad.n_geo_lon) as n_geo_lon, coalesce(rp.n_geo_lat, ad.n_geo_lat) as n_geo_lat, d.c_serial_number as c_device_number, s.c_code as c_subscr, (CASE WHEN s.b_person THEN concat(s.c_name1, ' ', s.c_name2, ' ', s.c_name3) ELSE s.c_name1 END) as c_owner, (select array_to_json(array_agg(row_to_json(t))) from ( select r.id as f_result, rt.c_const as c_type_const, rt.c_short_name as c_type_name, r.fn_user as f_user, u.c_first_name, u.c_last_name, u.c_middle_name, r.d_date from core.cd_results as r inner join core.cs_result_types as rt ON r.fn_type = rt.id inner join core.pd_users as u ON u.id = r.fn_user where r.fn_route IN (select t.value::uuid from json_array_elements_text(_routes) as t) and r.fn_point = p.id ) as t) as j_results, (select r.d_date from core.cd_results as r where r.fn_route IN (select t.value::uuid from json_array_elements_text(_routes) as t) and r.fn_point = p.id order by r.d_date desc limit 1) as d_date_result -- дата выполнения from core.cd_points as p left join dbo.ed_registr_pts as rp ON p.f_registr_pts = rp.id left join dbo.ss_address as ad ON ad.id = rp.f_address left join dbo.sd_subscr as s ON s.id = rp.f_subscr left join dbo.ed_devices as d ON d.f_registr_pts = rp.id where d.d_close_date is null and p.f_route IN (select t.value::uuid from json_array_elements_text(_routes) as t) order by p.n_order; END
Подсветка дат с выполненными заданиями
/** * @params {json} _f_users - массив пользователей, например [1, 2, 3] * @params {date} _d_start_date - дата месяца для просмотра. По умолчанию нужно указать первый день месяца * @params {date} _d_end_date - дата месяца для просмотра. По умолчанию нужно указать последний день месяца * * @returns - список дат с количеством выполненных заданий * * @example * [{ "action": "cf_arm_cd_results", "method": "Query", "data": [{ "params": [_f_users, _d_start_date, _d_end_date] }], "type": "rpc", "tid": 0}] */ DECLARE _status_weight integer; BEGIN select rs.n_order into _status_weight from core.cs_route_statuses as rs where rs.c_const = 'ASSINGNED'; -- не ниже этого статуса RETURN QUERY select stat.d_date, sum(stat.n_count)::bigint, sum(stat.n_count_route)::bigint, stat.fn_user from ( -- результаты select max(rr.d_date)::date as d_date, count(*) as n_count, null::bigint as n_count_route, rr.fn_user as fn_user from core.cd_results as rr where rr.fn_user IN (select t.value::integer from json_array_elements_text(_f_users) as t) and rr.d_date between _d_start_date and _d_end_date group by rr.fn_user, date_part('year', rr.d_date), date_part('month', rr.d_date), date_part('day', rr.d_date) union -- активные маршруты на дату select max(dy.d_date)::date as d_date, null::bigint as n_count, count(*) as n_count_route, uir.f_user as fn_user from core.cd_userinroutes as uir inner join core.cd_routes as r ON r.id = uir.f_route inner join lateral generate_series(r.d_date_start::date, r.d_date_end::date, '1 day') as dy(d_date) on dy.d_date between _d_start_date and _d_end_date left join core.cs_route_statuses as rs ON rs.id = r.f_status where 1=1 and uir.f_user IN (select t.value::integer from json_array_elements_text(_f_users) as t) and _d_end_date::date >= r.d_date_start and _d_start_date::date <= CASE WHEN r.b_extended THEN r.d_extended ELSE r.d_date_end END and rs.n_order >= _status_weight group by uir.f_user, date_part('year', dy.d_date), date_part('month', dy.d_date), date_part('day', dy.d_date) ) as stat group by stat.fn_user, stat.d_date order by stat.d_date ; END
Этап "Планирование": получение списка маршрутов
/** * @params {integer} _f_author - автор маршрута * @example * [{ "action": "cf_arm_cd_route", "method": "Select", "data": [{ "params":[_f_author] }], "type": "rpc", "tid": 0 }] */ DECLARE _status_weight integer; -- вес статуса Сформирован _create_status_id integer; -- идентификатор Формируется _routes json; -- список маршрутов для выборки BEGIN select rs.n_order into _status_weight from core.cs_route_statuses as rs where rs.c_const = 'CREATED'; -- только до этого состояния select rs.id into _create_status_id from core.cs_route_statuses as rs where rs.c_const = 'CREATE'; -- только до этого состояния -- получаем список маршрутов которые были созданы указанным пользователем IF _f_author is not null THEN select array_to_json(array_agg(row_to_json(t))) into _routes from ( select DISTINCT rh.fn_route from core.cd_route_history as rh where rh.fn_user = _f_author and rh.fn_status = _create_status_id ) as t; ELSE select array_to_json(array_agg(row_to_json(t))) into _routes from ( select DISTINCT rh.fn_route from core.cd_route_history as rh where rh.fn_status = _create_status_id ) as t; END IF; -- обходчики выбраны и находим все маршруты за текущую дату RETURN QUERY select r.id, r.c_number, r.d_date_start, r.d_date_end, rs.c_const, rs.c_name, r.f_type, rt.c_name as c_type, (select array_to_json(array_agg(row_to_json(t))) from ( select u.id, u.c_first_name, u.c_last_name, u.c_middle_name, uir.b_main from core.cd_userinroutes as uir inner join core.pd_users as u ON u.id = uir.f_user where uir.f_route = r.id order by u.c_first_name, u.c_last_name ) as t) as j_users, (select count(*) from core.cd_points as p where r.id = p.f_route) as n_points from (select (t.value #>> '{fn_route}')::uuid as fn_route from json_array_elements(_routes) as t) as uir INNER JOIN core.cd_routes as r ON r.id = uir.fn_route inner join core.cs_route_types as rt ON rt.id = r.f_type left join core.cs_route_statuses as rs ON rs.id = r.f_status where _status_weight >= rs.n_order order by r.d_date_start; END
Список маршрутов в разделе "Маршруты" - для отчетности
/** * @params {integer} _f_main_division - иден. филиал. Обязателен при передаче * @params {integer} _f_division - иден. отделение. Обязателен при передаче * @params {integer} _f_subdivision - иден. участок. Обязателен при передаче * @params {integer} _f_manager - иден. диспетчер. Может быть null * @params {integer} _f_user - иден. обходчика. Может быть null * @params {date} _d_date_start - дата начала * @params {date} _d_date_end - дата завершения * * @example * [{ "action": "cf_arm_cd_routes", "method": "Select", "data": [{ "params": [_f_main_division, _f_division, _f_subdivision, _f_manager, _f_user, _d_date_start, _d_date_end] }], "type": "rpc", "tid": 0}] */ DECLARE _users json; -- обходчики --_d_date date; --_status_weight integer; BEGIN --select now()::date into _d_date; -- закомментировал по требованию аналитика --select rs.n_order into _status_weight --from core.cs_route_statuses as rs --where rs.c_const = 'ASSINGNED'; -- не ниже этого статуса -- обходчики выбраны и находим все маршруты за текущую дату RETURN QUERY select t.id, t.c_number, t.d_date_start, t.d_date_end, t.c_const, t.c_name, t.f_type, t.c_type, t.j_users, t.n_points, t.n_done_points, t.n_done_today_points from ( with userinroutes as ( select uir.f_route, uir.f_user, uir.b_main from core.cd_userinroutes as uir UNION ALL select rh.fn_route, rh.fn_user, true from core.cd_route_history as rh inner join core.cs_route_statuses as rs ON rh.fn_status = rs.id where rs.c_const = 'CREATE' ) select r.id, r.c_number, r.d_date_start, r.d_date_end, rs.c_const, rs.c_name, r.f_type, rt.c_name as c_type, (select array_to_json(array_agg(row_to_json(t))) from ( select u.id, u.c_first_name, u.c_last_name, u.c_middle_name, uir.b_main from core.cd_userinroutes as uir inner join core.pd_users as u ON u.id = uir.f_user where uir.f_route = r.id order by u.c_first_name, u.c_last_name ) as t) as j_users, (select count(*) from core.cd_points as p where r.id = p.f_route) as n_points, (select count(DISTINCT fn_point) from core.cd_user_points as up where r.id = up.fn_route and up.fn_user = _f_user) as n_done_points, (select count(DISTINCT fn_point) from core.cd_user_points as up where r.id = up.fn_route and up.fn_user = _f_user and up.d_date::date = now()::date) as n_done_today_points, row_number() over(partition by r.id) as n_row from userinroutes as uir INNER JOIN core.cd_routes as r ON r.id = uir.f_route inner join core.cs_route_types as rt ON rt.id = r.f_type left join core.cs_route_statuses as rs ON rs.id = r.f_status where (case when _f_user is not null then uir.f_user = _f_user else (uir.b_main and uir.f_user IN (select u.id from dbo.cf_arm_pd_users(_f_main_division, _f_division, _f_subdivision, _f_manager, _f_user) as u) ) end) and r.d_date_start >= _d_date_start and _d_date_end >= (CASE WHEN r.b_extended THEN r.d_extended ELSE r.d_date_end END) order by r.d_date_start) as t where t.n_row = 1; END
Этап "Назначение": получить список маршрутов по заданным параметрам фильтров "Обходчик" и "Дата"
/** * @params {integer} _f_user - обходчик * @params {date} _d_date - дата для фильтрации маршрутов * * @example * [{ "action": "cf_arm_cd_routes", "method": "Select", "data": [{ "params": [_f_user, _d_date] }], "type": "rpc", "tid": 0 }] */ DECLARE _status_weight integer; _result_types_oov integer; BEGIN select rs.n_order into _status_weight from core.cs_route_statuses as rs where rs.c_const = 'ASSINGNED'; -- не ниже этого статуса --тип документа "отказ от выполнения" select rt.id into _result_types_oov from core.cs_result_types as rt where rt.c_const = 'OOV'; RETURN QUERY WITH routes as ( select r.id, r.c_number, r.d_date_start, r.d_date_end, rs.c_const, rs.c_name, r.f_type, rt.c_name as c_type from core.cd_userinroutes as uir INNER JOIN core.cd_routes as r ON r.id = uir.f_route inner join core.cs_route_types as rt ON rt.id = r.f_type left join core.cs_route_statuses as rs ON rs.id = r.f_status where 1=1 --and uir.b_main = true and uir.f_user = _f_user and _d_date::date >= r.d_date_start and _d_date::date <= CASE WHEN r.b_extended THEN r.d_extended ELSE r.d_date_end END and rs.n_order >= _status_weight ) select r.*, (select array_to_json(array_agg(row_to_json(t))) from ( select u.id, u.c_first_name, u.c_last_name, u.c_middle_name, uir.b_main from core.cd_userinroutes as uir inner join core.pd_users as u ON u.id = uir.f_user where uir.f_route = r.id order by u.c_first_name, u.c_last_name ) as t) as j_users, (select count(*) from core.cd_points as p where r.id = p.f_route) as n_points, (select count(DISTINCT fn_point) from core.cd_user_points as up where r.id = up.fn_route and up.fn_user = _f_user) as n_done_points, (select count(DISTINCT cr.fn_point) from ( select case when max(cr.fn_type) = _result_types_oov and count(distinct cr.fn_type) = 1 then cr.fn_point end as fn_point from core.cd_results as cr where r.id = cr.fn_route and cr.fn_user = _f_user group by cr.fn_point) as cr) as n_refuse_points, (select count(DISTINCT fn_point) from core.cd_user_points as up where r.id = up.fn_route and up.fn_user = _f_user and up.d_date::date = _d_date::date) as n_done_today_points, t.n_cnt_fl::int, t.n_cnt_ul::int, t.n_cnt_tu::int from routes as r left join lateral (select sum(case when ss.b_person then 1 else 0 end) as n_cnt_fl, sum(case when not ss.b_person then 1 else 0 end) as n_cnt_ul, sum(case when rp.b_technical_metering then 1 else 0 end) as n_cnt_tu -- техучет from core.cd_points cp inner join dbo.ed_registr_pts rp on rp.id = cp.f_registr_pts inner join dbo.sd_subscr ss on ss.id = rp.f_subscr where cp.f_route = r.id ) t on true order by r.d_date_start; END
Отмена маршрута на исполнение
/** * @params {integer} _f_current_user - текущий пользователь * @params {uuid} _route_id - идентификатор маршрута * * @returns {integer} * 0 - ОК * 1 - маршрут не найден * 2 - пользователь не найден * 3 - статус документ отличается от "Выполняется" * * @example * [{ "action": "cf_arm_transfer_close", "method": "Query", "data": [{ "params": [_f_current_user, _route_id] }], "type": "rpc", "tid": 0}] */ DECLARE _c_status text; -- текущий статус маршрута _f_next_status_id integer; -- статус - передан BEGIN IF(select count(*) from core.cd_routes as r where r.id = _route_id) = 1 THEN IF(select count(*) from core.pd_users as u where u.id = _f_current_user) = 1 THEN -- текущий статус select rs.c_const into _c_status from core.cd_routes as r left join core.cs_route_statuses as rs ON rs.id = r.f_status where r.id = _route_id; -- 488125 Операция должна быть доступна для маршрутов в статусе "Выполняется", при этом должен быть доступен множественный выбор маршрутов для выполнения операции. IF _c_status = 'PROCCESS' THEN -- новый статус select rs.id into _f_next_status_id from core.cs_route_statuses as rs where rs.c_const = 'CANCEL'; -- создаем новый статус "Выполняется" insert into core.cd_route_history (fn_route, fn_status, fn_user, d_date) values (_route_id, _f_next_status_id, _f_current_user, now()); update core.cd_routes set b_extended = true, d_extended = now() - interval '1 day' where id = _route_id; RETURN 0; ELSE RETURN 3; -- статус документ отличается от "назначен" END IF; ELSE RETURN 2; -- нет пользователя END IF; ELSE RETURN 1; -- нет маршрута END IF; END
Отмена нескольких маршрутов
/** * @params {integer} _f_current_user - текущий пользователь * @params {json} _routes - массив маршрутов, требуется передать в виде строки '["e7ded0cd-12dd-47f5-a75b-192376291e83"]' * * @returns * возвращается таблица с двумя колонками route_id:uuid и status_id: integer, где статус может содержать значение 0 - ОК, 1 - пользователь не найден. * дополнительные статусы можно узнать в функции dbo.cf_arm_transfer_route * * @example * [{ "action": "cf_arm_transfer_close", "method": "Query", "data": [{ "params": [_f_current_user, routes] }], "type": "rpc", "tid": 0}] */ BEGIN IF (select count(*) from core.pd_users as u where u.id = _f_current_user) = 1 THEN RETURN QUERY select t.value::uuid, dbo.cf_arm_close_route(_f_current_user, t.value::uuid) from json_array_elements_text(_routes) as t; ELSE RETURN QUERY select null, 1; END IF; END
Создание маршрута на основе точек учета
/** * @params {integer} _f_current_user - текущий пользователь * @params {json} _registr_pts - идент-ры точек учета, передавать в виде строку иден-ров, например '[{"id": "40170afe-498d-4ff0-a1e7-9f29d470cf0a", "f_type": 1}, {"id": "16dc8d78-04db-45ac-ab02-2112000478c2", "f_type": 2}]' * @params {date} _d_start - дата начала, например 2020-10-07 * @params {date} _d_end - дата завершения, например 2020-10-30 * @params {text} _c_number - номер маршрута * @params {json} _users - список исполнителей, передается в виде строки '[{"id": 4, "b_main": true}, {"id": 23, "b_main": false}]' * @params {integer} _f_route_type - тип маршрута * @params {boolean} _b_draft - является черновиком, предназначена для указания демонстрационного маршрута. По умолчанию передать false * * @returns * 0 - OK * 1 - нет пользователя * 2 - точки учета не переданы * * @example * [{ "action": "cf_arm_create_route", "method": "Query", "data": [{ "params": [_f_current_user, _registr_pts, _d_start, _d_end, _c_number, _users, _f_route_type, _b_draft] }], "type": "rpc", "tid": 0}] */ DECLARE _status_id integer; -- статус "Сформирован" _route_id uuid; _status_create_id integer; BEGIN IF (select count(*) from core.pd_users as u where u.id = _f_current_user) = 1 THEN IF (select count(*) from json_array_elements(_registr_pts)) > 0 THEN select uuid_generate_v4() into _route_id; insert into core.cd_routes (id, f_type, c_number, d_date, d_date_start, d_date_end, c_notice, b_extended, d_extended, n_order, b_draft) values (_route_id, _f_route_type, _c_number, now(), _d_start, _d_end, '', false, null, 1, _b_draft); select rs.id into _status_create_id from core.cs_route_statuses as rs where rs.c_const = 'CREATE'; insert into core.cd_route_history (fn_route, fn_status, fn_user, d_date, c_notice) values (_route_id, _status_create_id, _f_current_user, now(), ''); IF _users is not null and (select count(*) from json_array_elements(_users::json)) > 0 THEN -- ищем статус "Сформирован" select rs.id into _status_id from core.cs_route_statuses as rs where rs.c_const = 'CREATED'; -- создаем привязку insert into core.cd_userinroutes(f_route, f_user, b_main) select _route_id, (t.value #>> '{id}')::integer, (t.value #>> '{b_main}')::boolean from json_array_elements(_users::json) as t; -- создаем новый статус insert into core.cd_route_history (fn_route, fn_status, fn_user, d_date, c_notice) values (_route_id, _status_id, _f_current_user, now(), ''); END IF; -- f_type = 1 задание для снятия показаний insert into core.cd_points (f_registr_pts, f_route, f_type, c_notice, c_info, jb_data, n_order, sn_delete) select (t.value #>> '{id}')::uuid, _route_id, (t.value #>> '{f_type}')::integer, null, dbo.sf_generate_point_info(rp.id), dbo.sf_generate_point_jb_data(rp.id), 1, false from json_array_elements(_registr_pts) as t inner join dbo.ed_registr_pts as rp ON rp.id = (t.value #>> '{id}')::uuid left join dbo.ss_address as ad ON ad.id = rp.f_address order by ad.c_name; RETURN QUERY select _route_id, 0; ELSE RETURN QUERY select null::uuid, 2; -- точки не переданы END IF; ELSE RETURN QUERY select null::uuid, 1; -- нет пользователя END IF; END
Создание бланк
/** * @params {integer} _f_subdivision - подразделение, брать из справочника. По умолчанию установить из пользователя * @params {text} _c_prefix - префикс, можно не указывать * @params {bigint} _start - начальное заначение * @params {bigint} _end - конечное значение * @params {integer} _f_type - тип документа * @params {integer} _f_user_from - текущий пользователь, который работает с бланками * @params {integer} _f_user_to - кому передается бланк * @params {integer} _f_user_mol - Материально ответственное лицо за получение бланков в РЭС * @params {text} _c_notice - примечание * Все поля должны быть обязательными, кроме префикса * * @returns {integer} * 0 - ОК * 1 - нет подразделения * 2 - текущий пользователь не найден * 3 - МОЛ не указан * 4 - доступны бланки с указанными комбинациями * 5 - запрещено создавать больше, чем 100000 * * @example * [{ "action": "cf_arm_ed_blank_create", "method": "Query", "data": [{ "params": [_f_subdivision, _c_prefix, _start, _end, _f_type, _f_user_from, _f_user_to, _f_user_mol, _c_notice] }], "type": "rpc", "tid": 0}] */ BEGIN IF (select count(*) from core.sd_subdivisions as d where d.id = _f_subdivision) = 1 THEN IF (select count(*) from core.pd_users as u where u.id = _f_user_from) = 1 THEN IF (select count(*) from core.pd_users as u where u.id = _f_user_mol) = 1 THEN IF (select count(*) from dbo.ed_blanks as b where b.c_prefix = _c_prefix and b.n_number between _start and _end) > 0 THEN RETURN 4; ELSE IF ABS(_end - _start) > 100000 THEN RETURN 5; ELSE insert into dbo.ed_blanks(id, n_number, f_result_type, c_prefix, c_number, f_user_from, f_user_to, f_subdivision, jb_history, f_status, n_order, dx_created, f_user_mol, c_notice) select uuid_generate_v4(), generate_series, _f_type, _c_prefix, concat(coalesce(_c_prefix, ''), generate_series::text), _f_user_from, _f_user_to, --now(), -- d_date_to сказали не заполнять _f_subdivision, -- таким образом сохраняем историю dbo.sf_update_jb_history('[]'::json, json_build_object('f_user_to', _f_user_to, --'d_date_to', now(), 'f_status', 1)), 1, -- По умолчания статус пломбы "Зарегистрировано" generate_series / 2147483647, now(), _f_user_mol, _c_notice from generate_series(_start, _end, 1); END IF; END IF; RETURN 0; ELSE RETURN 3; END IF; ELSE RETURN 2; END IF; ELSE RETURN 1; END IF; END
Обновление бланков
/** * При списание указать поле f_user_to и поле d_date_to, которое потом будет являться датой списания * * @params {integer} _f_subdivision - подразделение * @params {json} _blanks - список бланков, требуется передать в виде строки '["e7ded0cd-12dd-47f5-a75b-192376291e83"]' * @params {integer} _f_user_from - текущий пользователь, который работает с пломбами * @params {integer} _f_user_to - кому передаются пломбы * @params {integer} _f_status - статус пломбы * @params {text} _c_document_trash - номер акта списания пломбы. Указывается при статусе "Списано" * @params {integer} _f_notice_trash - причина забраковки. Указывается при статусе "Списано". Получать из es_notice_trash * @params {integer} _f_user_mol - Материально ответственное лицо за получение бланков в РЭС * @params {text} _c_notice - примечание * * @returns {integer} * 0 - ОК * 1 - пользователь не найден * * @example * [{ "action": "cf_arm_ed_seals_update", "method": "Query", "data": [{ "params": [_f_subdivision, _blanks, _f_user_from, _f_user_to, _f_status, _c_document_trash, _f_notice_trash, _f_user_mol, _c_notice] }], "type": "rpc", "tid": 0}] */ BEGIN IF _f_user_to is null or (select count(*) from core.pd_users as u where u.id = _f_user_to) = 1 THEN update dbo.ed_blanks as b set f_status = _f_status, f_subdivision = _f_subdivision, f_user_from = _f_user_from, f_user_to = _f_user_to, d_date_to = now(), c_document_trash = _c_document_trash, f_notice_trash = _f_notice_trash, c_notice = _c_notice, f_user_mol = case when _f_user_mol is null then b.f_user_mol else _f_user_mol end where b.id IN (select t.value::uuid from json_array_elements_text(_blanks) as t); RETURN 0; ELSE RETURN 1; -- пользователь не найден END IF; END
Поиск бланков
/** * @params {uuid} _id - иден. пломбы * @params {integer} _f_subdivision - подразделение * @params {integer} _f_user_from - выдал * @params {integer} _f_user_to - получил * @params {text} _c_prefix - префикс * @params {integer} _n_start_number - номер с * @params {integer} _n_end_number - номер по * @params {date} _d_start_send - дата выдачи с * @params {date} _d_end_send - дата выдачи по * @params {date} _d_start_setup - дата установки с * @params {date} _d_end_setup - дата установки по * @params {date} _d_start_trash - дата списания с * @params {date} _d_end_trash - дата списания по * @params {integer} _f_type - Тип документа * @params {text} _c_owner - ФИО/наименование * @params {integer} _f_status - статус * @params {integer} _f_user_mol - Материально ответственное лицо за получение бланков в РЭС * * @example * [{ "action": "cf_arm_ed_blanks", "method": "Query", "data": [{ "params": [_id, _f_subdivision, _f_user_from, _f_user_to, _c_prefix, _n_start_number, _n_end_number, _d_start_send, _d_end_send, _d_start_setup, _d_end_setup, _d_start_trash, _d_end_trash, _f_type, _f_user_mol, _c_owner, _f_status] }], "type": "rpc", "tid": 0}] */ BEGIN return query select t.*, nt.c_name as c_notice_trash from (select b.id, -- иден. пломбы b.f_subdivision, -- иден. подразделение sd.c_name as c_subdivision, -- подразделение rtb.id as f_result_type, -- иден.типа документа rtb.c_name as c_result_type, -- наимен. типа документа b.c_prefix, -- префикс b.c_number, -- номер бланков b.n_number, -- номер бланков uf.c_first_name as c_first_name_from, -- кто выдал uf.c_last_name as c_last_name_from, -- кто выдал uf.c_middle_name as c_middle_name_from, -- кто выдал uf.id as f_user_from, -- иден. кто выдал ut.c_first_name as c_first_name_to, -- кто получил ut.c_last_name as c_last_name_to, -- кто получил ut.c_middle_name as c_middle_name_to, -- кто получил ut.id as f_user_to, -- иден. кто получил b.d_date_to::date, -- дата выдачи bs.c_name as c_blank_status, -- статус бланков bs.id as f_blank_status, -- иден. статуса бланков b.dx_created, -- дата создания r.d_date::date as d_date_setup, -- дата установки r.id as f_result, -- иден. документа rt.c_name as c_result_name, -- наименование документа (case when bs.c_const = 'TRASH' then ut.id else null end) as f_user_trashed, -- кто списал, тот же кто и получил ранее (case when bs.c_const = 'TRASH' then b.d_date_to::date else null end) as d_date_trashed, -- дата списания (case when bs.c_const = 'TRASH' then b.c_document_trash else null end) as c_document_trash, -- Номер акта списания (case when bs.c_const = 'TRASH' then b.f_notice_trash else null end) as f_notice_trash, -- Причина списания case when sub.b_person then concat(sub.c_name1, ' ', sub.c_name2, ' ', sub.c_name3) else sub.c_name1 end as c_owner, -- потребитель b.f_user_mol, -- Материально ответственное лицо за получение бланков в РЭС b.c_notice -- Примечание from dbo.ed_blanks as b inner join core.cs_result_types as rtb ON b.f_result_type = rtb.id inner join dbo.es_blank_status as bs ON b.f_status = bs.id left join core.sd_subdivisions as sd ON sd.id = b.f_subdivision left join core.cd_results as r ON r.jb_data#>>'{f_act_number}' = b.id::text left join core.cs_result_types as rt ON rt.id = r.fn_type left join core.cd_points as p ON p.id = r.fn_point left join dbo.ed_registr_pts as rp ON rp.id = p.f_registr_pts left join dbo.sd_subscr as sub ON sub.id = rp.f_subscr left join core.pd_users as uf ON b.f_user_from = uf.id left join core.pd_users as ut ON b.f_user_to = ut.id) as t left join dbo.es_notice_trash as nt ON nt.id = t.f_notice_trash where (case when _id is null then 1=1 else t.id = _id end) and (case when _f_subdivision is null then 1=1 else t.f_subdivision = _f_subdivision end) and (case when _f_user_from is null then 1=1 else t.f_user_from = _f_user_from end) and (case when _f_user_to is null then 1=1 else t.f_user_to = _f_user_to end) and (case when _c_prefix is null then 1=1 else t.c_prefix = _c_prefix end) and (case when _n_start_number is null then 1=1 when _n_start_number is not null and _n_end_number is null then t.n_number = _n_start_number else t.n_number between _n_start_number and _n_end_number + 1 end) and (case when _d_start_send is null then 1=1 when _d_start_send is not null and _d_end_send is null then t.d_date_to = _d_start_send else t.d_date_to between _d_start_send and _d_end_send + interval '1 day' end) and (case when _d_start_setup is null then 1=1 when _d_start_setup is not null and _d_end_setup is null then t.d_date_setup = _d_start_setup else t.d_date_setup between _d_start_setup and _d_end_setup + interval '1 day' end) and (case when _d_start_trash is null then 1=1 when _d_start_trash is not null and _d_end_trash is null then t.d_date_trashed = _d_start_trash else t.d_date_trashed between _d_start_trash and _d_end_trash + interval '1 day' end) and (case when _f_type is null then 1=1 else t.f_result_type = _f_type end) and (case when _f_status is null then 1=1 else t.f_blank_status = _f_status end) and (case when _f_user_mol is null then 1=1 else t.f_user_mol = _f_user_mol end); END
Удление бланков
/** * Внимание! Удаление бланков может привести к потере данных * * @params {json} _blanks - список пломб, требуется передать в виде строки '["e7ded0cd-12dd-47f5-a75b-192376291e83"]' * * @returns {integer} * 0 - ОК * * @example * [{ "action": "cf_arm_ed_blanks_remove", "method": "Query", "data": [{ "params": [_blanks] }], "type": "rpc", "tid": 0}] */ BEGIN delete from dbo.ed_blanks as b where b.f_status = 1 and -- статус "Зарегистрировано" b.id in (select t.value::uuid from json_array_elements_text(_blanks) as t); RETURN 0; END
Этап "Планирование": получение списка точек учета
/** * @example * [{ "action": "cf_arm_ed_registr_pts", "method": "Select", "data": [{ }], "type": "rpc", "tid": 0 }] * * @todo * колонка b_meter_exists - возвращается доступность показания, для снятия показаний точка валидна */ BEGIN RETURN QUERY select rp.id, rp.c_address, ad.n_geo_lon, ad.n_geo_lat, rp.f_division, d.c_name, rp.f_subdivision, sd.c_name, rp.c_device_number, rp.c_subscr, rp.c_owner, rp.d_meter_date, rp.c_network_item, rp.c_network_type, rp.f_device_type, dt.c_name, (select count(*) from dbo.ed_output_meter_readings as omr inner join dbo.ed_input_meter_readings as imr ON imr.id = omr.fn_meter_reading where imr.f_registr_pts = rp.id) > 0, rp.b_disabled from dbo.ed_registr_pts as rp left join dbo.ss_address as ad ON ad.id = rp.f_address inner join core.sd_divisions as d ON rp.f_division = d.id inner join core.sd_subdivisions as sd ON rp.f_subdivision = sd.id inner join dbo.es_device_types as dt ON rp.f_device_type = dt.id; END
Поиск пломбы
/** * @params {uuid} _id - иден. пломбы * @params {integer} _f_subdivision - подразделение * @params {integer} _f_user_from - выдал * @params {integer} _f_user_to - получил * @params {text} _c_prefix - префикс * @params {bigint} _n_start_number - номер с * @params {bigint} _n_end_number - номер по * @params {date} _d_start_send - дата выдачи с * @params {date} _d_end_send - дата выдачи по * @params {date} _d_start_setup - дата установки с * @params {date} _d_end_setup - дата установки по * @params {date} _d_start_trash - дата списания с * @params {date} _d_end_trash - дата списания по * @params {integer} _f_type - Тип пломбы * @params {integer} _f_place - Место установки * @params {uuid} _f_registr_pts - потребитель * @params {text} _c_device_number - Номер ПУ * @params {integer} _f_status - статус * @params {integer} _f_user_mol - Материально ответственное лицо за получение пломб в РЭС * * @example * [{ "action": "cf_arm_ed_seals", "method": "Query", "data": [{ "params": [_id, _f_subdivision, _f_user_from, _f_user_to, _c_prefix, _n_start_number, _n_end_number, _d_start_send, _d_end_send, _d_start_setup, _d_end_setup, _d_start_trash, _d_end_trash, _f_type, _f_place, _f_registr_pts, _c_device_number, _f_status, _f_user_mol] }], "type": "rpc", "tid": 0}] */ BEGIN return query select t.*, nt.c_name as c_notice_trash from (select s.id, -- иден. пломбы s.f_subdivision, -- иден. подразделение sd.c_name as c_subdivision, -- подразделение st.id as f_seal_type, -- иден. типа пломбы st.c_name as c_seal_type, -- тип пломбы s.c_prefix, -- префикс s.c_number, -- номер пломбы s.n_number, -- номер пломбы uf.c_first_name as c_first_name_from, -- кто выдал uf.c_last_name as c_last_name_from, -- кто выдал uf.c_middle_name as c_middle_name_from, -- кто выдал uf.id as f_user_from, -- иден. кто выдал ut.c_first_name as c_first_name_to, -- кто получил ut.c_last_name as c_last_name_to, -- кто получил ut.c_middle_name as c_middle_name_to, -- кто получил ut.id as f_user_to, -- иден. кто получил s.d_date_to::date, -- дата выдачи ss.c_name as c_seal_status, -- статус пломбы ss.id as f_seal_status, -- иден. статуса пломбы s.dx_created, -- дата создания ocs.d_date::date as d_date_setup, -- дата установки coalesce(sp.id, sp1.id) as f_seal_place, -- иден. место установки coalesce(sp.c_name, sp1.c_name) as c_seal_place, -- место установки d.c_serial_number, -- Номер ПУ rp.id as f_registr_pts, -- иден. точки учета case when sub.b_person then concat(sub.c_name1, ' ', sub.c_name2, ' ', sub.c_name3) else sub.c_name1 end as c_owner, -- потребитель r.id as f_result, -- иден. документа rt.c_name as c_result_name, -- наименование документа (case when ss.c_const = 'TRASH' then ut.id else null end) as f_user_trashed, -- кто списал, тот же кто и получил ранее (case when ss.c_const = 'TRASH' then s.d_date_to::date else null end) as d_date_trashed, -- дата списания (case when ss.c_const = 'TAKE_OFF' then s.d_date_to::date else null end) as d_date_take_off, -- дата снятия (case when ss.c_const = 'TRASH' then s.c_document_trash else null end) as c_document_trash, -- Номер акта списания (case when ss.c_const = 'TRASH' then s.f_notice_trash else null end) as f_notice_trash, -- Причина забраковки s.f_user_mol, -- Материально ответственное лицо за получение пломб в РЭС s.c_notice -- Примечание from dbo.ed_seals as s inner join dbo.es_seal_status as ss ON s.f_status = ss.id left join core.sd_subdivisions as sd ON sd.id = s.f_subdivision left join dbo.ed_output_conn_seals as ocs ON s.id = ocs.fn_seal_new left join core.cd_results as r ON ocs.fn_result = r.id left join core.cs_result_types as rt ON rt.id = r.fn_type left join dbo.ed_registr_pts as rp ON rp.id = s.f_registr_pts left join dbo.sd_subscr as sub ON sub.id = rp.f_subscr left join dbo.es_seal_places as sp ON s.f_place = sp.id left join dbo.es_seal_types as st ON s.f_type = st.id left join dbo.es_seal_places as sp1 ON ocs.fn_place = sp1.id left join dbo.es_seal_types as st1 ON ocs.fn_type = st1.id left join dbo.ed_devices as d ON s.f_registr_pts = d.f_registr_pts left join core.pd_users as uf ON s.f_user_from = uf.id left join core.pd_users as ut ON s.f_user_to = ut.id) as t left join dbo.es_notice_trash as nt ON nt.id = t.f_notice_trash where (case when _id is null then 1=1 else t.id = _id end) and (case when _f_subdivision is null then 1=1 else t.f_subdivision = _f_subdivision end) and (case when _f_user_from is null then 1=1 else t.f_user_from = _f_user_from end) and (case when _f_user_to is null then 1=1 else t.f_user_to = _f_user_to end) and (case when _c_prefix is null then 1=1 else t.c_prefix = _c_prefix end) and (case when _n_start_number is null then 1=1 when _n_start_number is not null and _n_end_number is null then t.n_number = _n_start_number else t.n_number between _n_start_number and _n_end_number + 1 end) and (case when _d_start_send is null then 1=1 when _d_start_send is not null and _d_end_send is null then t.d_date_to = _d_start_send else t.d_date_to between _d_start_send and _d_end_send + interval '1 day' end) and (case when _d_start_setup is null then 1=1 when _d_start_setup is not null and _d_end_setup is null then t.d_date_setup = _d_start_setup else t.d_date_setup between _d_start_setup and _d_end_setup + interval '1 day' end) and (case when _d_start_trash is null then 1=1 when _d_start_trash is not null and _d_end_trash is null then t.d_date_trashed = _d_start_trash else t.d_date_trashed between _d_start_trash and _d_end_trash + interval '1 day' end) and (case when _f_type is null then 1=1 else t.f_seal_type = _f_type end) and (case when _f_place is null then 1=1 else t.f_seal_place = _f_place end) and (case when _c_device_number is null then 1=1 else t.c_serial_number = _c_device_number end) and (case when _f_registr_pts is null then 1=1 else t.f_registr_pts = _f_registr_pts end) and (case when _f_status is null then 1=1 else t.f_seal_status = _f_status end) and (case when _f_user_mol is null then 1=1 else t.f_user_mol = _f_user_mol end); END
Создание пломбы
/** * @params {integer} _f_subdivision - подразделение, брать из справочника. По умолчанию установить из пользователя * @params {text} _c_prefix - префикс, можно не указывать * @params {bigint} _start - начальное заначение * @params {bigint} _end - конечное значение * @params {integer} _f_type - тип пломбы * @params {integer} _f_user_from - текущий пользователь, который работает с пломбами * @params {integer} _f_user_to - кому передается пломба * @params {integer} _f_user_mol - Материально ответственное лицо за получение пломб в РЭС * @params {text} _c_notice - примечание * Все поля должны быть обязательными, кроме префикса * * @returns {integer} * 0 - ОК * 1 - нет подразделения * 2 - текущий пользователь не найден * 3 - кому передается пломба не найдена * 4 - доступны пломбы с указанными комбинациями * 5 - запрещено создавать больше, чем 100000 * * @example * [{ "action": "cf_arm_ed_seals_create", "method": "Query", "data": [{ "params": [_f_subdivision, _c_prefix, _start, _end, _f_type, _f_user_from, _f_user_to, _f_user_mol, _c_notice] }], "type": "rpc", "tid": 0}] */ BEGIN IF (select count(*) from core.sd_subdivisions as d where d.id = _f_subdivision) = 1 THEN IF (select count(*) from core.pd_users as u where u.id = _f_user_from) = 1 THEN --IF (select count(*) from core.pd_users as u where u.id = _f_user_to) = 1 THEN IF (select count(*) from dbo.ed_seals as b where b.c_prefix = _c_prefix and b.n_number between _start and _end) > 0 THEN RETURN 4; ELSE IF ABS(_end - _start) > 100000 THEN RETURN 5; ELSE insert into dbo.ed_seals(id, n_number, f_type, c_prefix, c_number, f_user_from, f_user_to, f_subdivision, jb_history, f_status, n_order, dx_created, f_user_mol, c_notice) select uuid_generate_v4(), generate_series, _f_type, _c_prefix, generate_series::text, _f_user_from, _f_user_to, --now(), -- d_date_to сказали не заполнять _f_subdivision, -- таким образом сохраняем историю dbo.sf_update_jb_history('[]'::json, json_build_object('f_user_to', _f_user_to, --'d_date_to', now(), 'f_status', 1)), 1, -- По умолчания статус пломбы "Зарегистрировано" generate_series / 2147483647, now(), _f_user_mol, _c_notice from generate_series(_start, _end, 1); END IF; END IF; RETURN 0; --ELSE --RETURN 3; --END IF; ELSE RETURN 2; END IF; ELSE RETURN 1; END IF; END
Удление пломб
/** * Внимание! Удаление пломб может привести к потере данных * * @params {json} _seals - список пломб, требуется передать в виде строки '["e7ded0cd-12dd-47f5-a75b-192376291e83"]' * * @returns {integer} * 0 - ОК * * @example * [{ "action": "cf_arm_ed_seals_remove", "method": "Query", "data": [{ "params": [_seals] }], "type": "rpc", "tid": 0}] */ BEGIN delete from dbo.ed_seals as s where s.f_status = 1 and -- статус "Зарегистрировано" s.id in (select t.value::uuid from json_array_elements_text(_seals) as t); RETURN 0; END
Обновление пломб
/** * При списание указать поле f_user_to и поле d_date_to, которое потом будет являться датой списания * * @params {integer} _f_subdivision - подразделение * @params {json} _seals - список пломб, требуется передать в виде строки '["e7ded0cd-12dd-47f5-a75b-192376291e83"]' * @params {integer} _f_user_from - текущий пользователь, который работает с пломбами * @params {integer} _f_user_to - кому передаются пломбы * @params {integer} _f_status - статус пломбы * @params {text} _c_document_trash - номер акта списания пломбы. Указывается при статусе "Списано" * @params {integer} _f_notice_trash - причина забраковки. Указывается при статусе "Списано". Получать из es_notice_trash * @params {integer} _f_user_mol - Материально ответственное лицо за получение пломб в РЭС * @params {text} _c_notice - примечание * * @returns {integer} * 0 - ОК * 1 - пользователь не найден * * @example * [{ "action": "cf_arm_ed_seals_update", "method": "Query", "data": [{ "params": [_f_subdivision, _seals, _f_user_from, _f_user_to, _f_status, _c_document_trash, _f_notice_trash, _f_user_mol, _c_notice] }], "type": "rpc", "tid": 0}] */ BEGIN IF _f_user_to is null or (select count(*) from core.pd_users as u where u.id = _f_user_to) = 1 THEN update dbo.ed_seals as s set f_status = _f_status, f_subdivision = _f_subdivision, f_user_from = _f_user_from, f_user_to = _f_user_to, d_date_to = now(), c_document_trash = _c_document_trash, f_notice_trash = _f_notice_trash, c_notice = _c_notice, f_user_mol = case when _f_user_mol is null then s.f_user_mol else _f_user_mol end where s.id IN (select t.value::uuid from json_array_elements_text(_seals) as t); RETURN 0; ELSE RETURN 1; -- пользователь не найден END IF; END
/* Список возможных параметров: _c_ps text default null, -- ПС _c_line_ps text default null, -- фидер от ПС _c_rp text default null, -- РП _c_line_rp text default null, -- фидер от РП _c_tp text default null, --ТП _c_line_tp text default null, -- фидер от ТП -- адрес _c_raion text default null, -- район _c_city text default null, -- город _c_settle text default null, -- населенный пункт _c_street text default null, -- улица _c_house text default null, -- дом _c_house_build text default null, -- корпус _f_fias uuid default null, -- идентификатор адреса в ФИАС -- ПУ _c_device_location text default null, _b_ASKUE bool default null, _c_ASKUE text default null, _n_mpi smallint default null, -- ТУ _f_div int default null, -- ссылка на отделение 37. Обязательно к заполнению _f_subdiv int default null, -- ссылка на участок 66. Обязательно к заполнению _n_registr_pts_type int default null, -- ЮЛ\ТУ\ФЛ _с_registr_pts_name text default null, -- наименование ТУ _f_consume_status int default null, -- сссылка на статус потребления _b_problem bool default null, -- признак проблемного абонента _b_violation bool default null, --наличие неисполненного предписания _n_check_date int default null, -- дата (день) обхода _b_person boolean default null -- признак ФЛ/ЮЛ -- показания _f_delivery int default null, -- источник показаний _d_date_begin date default null, -- начало периода даты показаний _d_date_end date default null, -- окончание периода даты показаний _n_absent_period int default null, -- период (количество месяцев) с отсутствующими показаниями _b_strong_check bool default null, -- ищем строго заданное количество месяцев с отсутствующими показаниями (true) или более (false) _f_event int default null -- вид работ -- планирование _d_date_period date DEFAULT NULL::date -- период просмотра данных, если это поле не передавать, то фильтрации в истории ТУ не будет см. ed_registr_pts_history _b_plan boolean DEFAULT NULL::boolean -- является плановым или нет _f_no_plan_work smallint DEFAULT NULL::smallint -- тип внеплановой работы. см. es_no_plan_works _b_no_plan boolean DEFAULT NULL::boolean, -- признак что точка является внеплановой _d_no_plan_date date DEFAULT NULL::date, -- планируемая дата выполнения работ по внеплановой точке. Будет заполняться при импорте внеплановых работ/ручном указании внеплановых работ по точке учета через АРМ Диспетчера _f_registr_pts_status integer DEFAULT NULL::integer -- Статус активности ТУ _n_month_last_check_date integer DEFAULT NULL::integer -- Последняя инструментальная проверка была проведена более чем n месяцев Пример запроса: select * from dbo.cf_arm_filtration( _f_div => 37, _f_subdiv => 66, _c_ps => 'руд') */ DECLARE _d_start_period date; _p_date_begin date = (now() - interval'3 year')::date; -- начало периода даты показаний. По умолчанию начальная дата годь назад _p_date_end date = now()::date; -- окончание периода даты показаний. По умолчанию текущая дата _n_object_type_level int4; -- уровень адреса ФИАС _f_fias_nil uuid = uuid_nil(); -- пустой идентификатор фиас BEGIN -- проверка обязательных параметров if _f_div is null and _f_subdiv is null then raise exception 'Не заданы Филиал/РЭС'; end if; if _d_date_begin is not null then _p_date_begin = _d_date_begin; end if; if _d_date_end is not null then _p_date_end = _d_date_end; end if; select n_object_type_level into _n_object_type_level from dbo.ss_fias_address as sfa where sfa.id = _f_fias; -- список ТУ заданной РЭС create temp table t_registr_pts ( id uuid, c_registr_pts text, f_status_consume int, b_technical_metering bool, f_subscr uuid, f_address uuid, c_ps text, c_line_ps text, c_rp text, c_line_rp text, c_tp text, c_line_tp text, c_line_segment_1 text, c_raion text, c_city_name text, c_settlement_name text, c_street_name text, c_house text, c_house_build text, b_person boolean, f_registr_pts_status integer ) on commit drop; /* if _c_ps is not null then create index trgm_c_ps_idx ON t_registr_pts USING GIN (c_ps gin_trgm_ops); end if; if _c_line_ps is not null then create index trgm_c_line_ps_idx ON t_registr_pts USING GIN (c_line_ps gin_trgm_ops); end if; if _c_rp is not null then create index trgm_c_rp_idx ON t_registr_pts USING GIN (c_rp gin_trgm_ops); end if; if _c_line_rp is not null then create index trgm_c_line_rp_idx ON t_registr_pts USING GIN (c_line_rp gin_trgm_ops); end if; if _c_tp is not null then create index trgm_c_tp_idx ON t_registr_pts USING GIN (c_tp gin_trgm_ops); end if; if _c_line_tp is not null then create index trgm_c_line_tp_idx ON t_registr_pts USING GIN (c_line_tp gin_trgm_ops); end if; if _c_raion is not null then create index trgm_c_raion_idx ON t_registr_pts USING GIN (c_raion gin_trgm_ops); end if; if _c_city is not null then create index trgm_c_city_name_idx ON t_registr_pts USING GIN (c_city_name gin_trgm_ops); end if; if _c_settle is not null then create index trgm_c_settlement_name_idx ON t_registr_pts USING GIN (c_settlement_name gin_trgm_ops); end if; if _c_street is not null then create index trgm_c_street_name_idx ON t_registr_pts USING GIN (c_street_name gin_trgm_ops); end if; */ insert into t_registr_pts( id, c_registr_pts, f_status_consume, b_technical_metering, f_subscr, f_address, c_ps, c_line_ps, c_rp, c_line_rp, c_tp, c_line_tp, c_line_segment_1, c_raion, c_city_name, c_settlement_name, c_street_name, c_house, c_house_build, b_person, f_registr_pts_status ) select t.id, t.c_registr_pts, t.f_status_consume, t.b_technical_metering, t.f_subscr, t.f_address, t.c_substation as c_ps, t.c_line_substation as c_line_ps, t.c_rp, t.c_line_rp, t.c_tp, t.c_line_tp, t.c_line_segment_1, sa.c_raion, sa.c_city_name, sa.c_settlement_name, sa.c_street_name, sa.c_house_name, sa.c_block_name, sub.b_person, t.f_registr_pts_status from dbo.ed_registr_pts as t left join dbo.ss_address as sa on sa.id = t.f_address left join dbo.sd_subscr as sub ON sub.id = t.f_subscr where t.f_division = _f_div and t.f_subdivision = _f_subdiv and (case when _f_registr_pts_status is null then 1=1 else _f_registr_pts_status = t.f_registr_pts_status end) and (case when _f_consume_status is null then 1=1 else _f_consume_status = t.f_status_consume end) and (case when _f_fias is null or _n_object_type_level is null then true else case _n_object_type_level when 1 then sa.code_fias_region = _f_fias when 3 then sa.data_area_fias_id = _f_fias when 4 then sa.data_city_fias_id = _f_fias when 6 then sa.settlement_fias_id = _f_fias when 7 then sa.data_street_fias_id = _f_fias when 8 then sa.data_house_fias_id = _f_fias end end); --/* -- далее отсекать все фильтры -- СЕТЬ if _c_ps is not null then delete from t_registr_pts t where coalesce(lower(t.c_ps), '') not like '%'||lower(_c_ps)||'%'; end if; if _c_line_ps is not null then delete from t_registr_pts t where coalesce(lower(t.c_line_ps), '') not like '%'||lower(_c_line_ps)||'%'; end if; if _c_rp is not null then delete from t_registr_pts t where coalesce(lower(t.c_rp), '') not like '%'||lower(_c_rp)||'%'; end if; if _c_line_rp is not null then delete from t_registr_pts t where coalesce(lower(t.c_line_rp), '') not like '%'||lower(_c_rp)||'%'; end if; if _c_tp is not null then delete from t_registr_pts t where coalesce(lower(t.c_tp), '') not like '%'||lower(_c_tp)||'%'; end if; if _c_line_tp is not null then delete from t_registr_pts t where coalesce(lower(t.c_line_tp), '') not like '%'||lower(_c_line_tp)||'%'; end if; -- АДРЕСА if _c_raion is not null then delete from t_registr_pts t where coalesce(lower(t.c_raion), '') not like '%'||lower(_c_raion)||'%'; end if; if _c_city is not null then delete from t_registr_pts t where coalesce(lower(t.c_city_name), '') not like '%'||lower(_c_city)||'%'; end if; if _c_settle is not null then delete from t_registr_pts t where coalesce(lower(t.c_settlement_name), '') not like '%'||lower(_c_settle)||'%'; end if; if _c_street is not null then delete from t_registr_pts t where coalesce(lower(t.c_street_name), '') not like '%'||lower(_c_street)||'%'; end if; if _c_house is not null then delete from t_registr_pts t where coalesce(lower(t.c_house), '') != lower(_c_house); end if; if _c_house_build is not null then delete from t_registr_pts t where coalesce(lower(t.c_house_build), '') != lower(_c_house_build); end if; if _b_person is not null then delete from t_registr_pts t where t.b_person != _b_person; end if; if _c_line_segment_1 is not null then delete from t_registr_pts t where coalesce(lower(t.c_line_segment_1), '') not like '%'||lower(_c_line_segment_1)||'%'; end if; -- ПОКАЗАНИЯ if _f_delivery is not null then delete from t_registr_pts t where not exists ( select 1 from dbo.ed_input_meter_readings eimr where eimr.f_registr_pts = t.id and eimr.f_delivery_method = _f_delivery); end if; --*/ --select count(*) into _n_cnt from t_registr_pts; --raise notice '%', _n_cnt; -- убираем ТУ, где нет показаний за указанный период --/* if _d_date_begin is not null then delete from t_registr_pts t where not exists ( select 1 from dbo.ed_input_meter_readings eimr where eimr.f_registr_pts = t.id and eimr.d_date_prev between _p_date_begin and coalesce(_p_date_end, now()::date) ); end if; --*/ if _n_absent_period is not null then select now() - (_n_absent_period + case when _b_strong_check then 0 else 1 end) * interval'1 month' into _d_start_period; -- убираем ТУ, где есть показания после даты _d_start_period delete from t_registr_pts t where exists ( select 1 from dbo.ed_input_meter_readings eimr where eimr.f_registr_pts = t.id and eimr.d_date_prev > _d_start_period); end if; --select count(*) into _n_cnt from t_registr_pts; --raise notice '%', _n_cnt; RETURN QUERY with history as ( select rpth.id, rpth.f_registr_pts, rpth.b_plan, rpth.f_no_plan_work, npw.c_name as c_no_plan_work, rt.c_const as c_route_const, pt.id as f_point_type, pt.c_name as c_point_type, rpth.b_no_plan, rpth.d_no_plan_date from dbo.ed_registr_pts_history as rpth left join dbo.es_no_plan_works as npw ON npw.id = rpth.f_no_plan_work left join (select p.f_registr_pts, p.f_route, r.b_extended, r.d_extended, r.d_date_end, p.f_type from core.cd_points as p inner join core.cd_routes as r ON p.f_route = r.id where date_trunc('MONTH',(case when r.b_extended then r.d_extended else r.d_date_end end))::date = _d_date_period) as t ON rpth.f_registr_pts = t.f_registr_pts and t.f_type = rpth.f_point_type left join core.cd_routes as r ON r.id = t.f_route and date_trunc('MONTH',(case when r.b_extended then r.d_extended else r.d_date_end end))::date = _d_date_period left join core.cs_route_types as rt ON rt.id = r.f_type left join core.cs_point_types as pt ON pt.id = rpth.f_point_type where (case when _d_no_plan_date is not null then rpth.d_no_plan_date = _d_no_plan_date else 1=1 end) and (case when _d_date_period is not null then rpth.d_date_period = _d_date_period else rpth.d_date_period is null end) and (case when _b_plan is not null then rpth.b_plan = _b_plan else 1=1 end) and (case when _b_no_plan is not null then rpth.b_no_plan = _b_no_plan else 1=1 end) and (case when _f_no_plan_work is not null then rpth.f_no_plan_work = _f_no_plan_work else 1=1 end) and (case when _f_point_type is not null then rpth.f_point_type = _f_point_type else 1=1 end) ) select t.id, sd2.c_name as c_filial, sd.c_name as c_pes, ss2.c_name as c_res, ss.f_partners as c_partners_code, case when ss.b_person then ss.c_name1 || ' ' || ss.c_name2 || ' ' || ss.c_name3 else ss.c_name1 end as c_subscr_name, ss.c_code as c_subscr_code, erp.imp_text as c_registr_pts_code, t.c_registr_pts, erp.c_status_registr_pts, erp.d_close_date as d_tu_close_date, ss.n_check_date, ss.b_problem_person, t.f_status_consume, -- привести справочник esc.c_name as c_status_consume, t.b_technical_metering, erp.c_status, erp.c_predictr, ed.c_serial_number, edt.c_name as c_device_type, coalesce(ed.b_askue, false) as b_askue, edt.b_phase3, ed.d_setup_date, ed.d_close_date as d_pu_close_date, ed.d_valid_date, t.c_ps, t.c_line_ps, t.c_rp, t.c_line_rp, t.c_tp, t.c_line_tp, t.c_raion, t.c_city_name, t.c_settlement_name, t.c_street_name, erp.c_line_segment_1, sa.c_house_name, sa.c_block_name, sa.c_flat_name, sa.n_geo_lat, sa.n_geo_lon, case when sa.c_name is not null then '(Оригинальный адрес: '||sa.c_name ||') ' else '' end || coalesce(sa.c_comment_address, '') as c_comment_address, t.b_person, _d_date_period as d_date_period, hst.b_plan as b_plan, hst.f_no_plan_work as f_no_plan_work, hst.c_no_plan_work as c_no_plan_work, hst.c_route_const as c_route_const, hst.f_point_type as f_point_type, hst.c_point_type as c_point_type, hst.id as f_registr_pts_history, hst.b_no_plan, hst.d_no_plan_date, t.f_registr_pts_status, rps.c_name, de.d_last_check_date, erp.b_sub, erp.b_transit from t_registr_pts as t left join dbo.es_registr_pts_status as rps ON t.f_registr_pts_status = rps.id inner join dbo.ed_registr_pts as erp on erp.id = t.id inner join dbo.sd_subscr as ss on ss.id = erp.f_subscr left join dbo.ss_address as sa on sa.id = t.f_address left join dbo.ed_devices as ed left join dbo.es_device_types as edt on edt.id = ed.f_device_type on ed.f_registr_pts = t.id and ed.d_close_date is null left join core.sd_divisions sd left join core.sd_divisions as sd2 on sd2.id = sd.f_division on sd.id = erp.f_division left join core.sd_subdivisions as ss2 on ss2.id = erp.f_subdivision left join dbo.es_status_consume as esc on esc.id = coalesce(erp.f_status_consume, 2) left join dbo.ed_devices as de ON de.f_registr_pts = t.id and de.d_close_date is null left join history as hst on hst.f_registr_pts = t.id where case when _d_date_period is not null then hst.id is not null else 1=1 end and (case when _n_month_last_check_date is null then 1=1 else de.d_last_check_date < (now() - (_n_month_last_check_date::text || ' month')::interval) end); END
Общая статистика обходов по дням
begin RETURN QUERY SELECT r.d_date::date as d_date, sum(r.n_count_plan)::integer as n_count_plan, sum(r.n_count)::integer as n_count from dbo.cf_arm_get_users_statistics_by_hour(_f_div,_f_subdiv, null, _d_date_begin, _d_date_end) as stat -- по ЭСУ inner join lateral json_to_recordset(stat.j_results) as r(d_date date, n_count_plan integer, n_count integer) on true group by r.d_date::date order by r.d_date::date ; end
Статистика количества обходов за месяц
begin RETURN QUERY SELECT r.d_date, avg(case when r.f_div = _f_div and r.f_subdiv = coalesce(_f_subdiv,r.f_subdiv) then r.n_count::real end)::integer as n_count_avg_div, avg(r.n_count::real)::integer as n_count_abg_all, max(case when r.f_div = _f_div and r.f_subdiv = coalesce(_f_subdiv,r.f_subdiv) then r.n_count::real end)::integer as n_count_max FROM ( SELECT stat.f_div, stat.f_subdiv, stat.f_user, r.d_date::date as d_date, sum(r.n_count) as n_count from dbo.cf_arm_get_users_statistics_by_hour(null,null, null, _d_date_begin, _d_date_end) as stat inner join lateral json_to_recordset(stat.j_results) as r(d_date date, n_count integer) on true group by stat.f_div,stat.f_subdiv,stat.f_user,r.d_date order by stat.f_div,stat.f_subdiv,stat.f_user,r.d_date ) as r group by r.d_date order by r.d_date ; end
Статистика обходов в разрезе контролеров по часам
begin -- буфер для пользователей и часов create temp table t_userdivisions ( f_div int4, f_subdiv int4, f_user int4, c_user text, d_date date, n_hour integer ) on commit drop; insert into t_userdivisions(f_div, f_subdiv, f_user, c_user, d_date, n_hour) select max(sd.f_division) as f_div, max(ssd.id) as f_subdiv, pu.id, concat(pu.c_last_name || ' ', pu.c_first_name || ' ', pu.c_middle_name)::text as c_user, dy.d_date::date, date_part('hour', dy.d_date)::integer from generate_series(_d_date_begin::date, _d_date_end::date + INTERVAL '23 hours', '1 hours') as dy(d_date) inner join core.pd_userindivisions as pud on true -- отделение inner join core.sd_divisions as sd on sd.id = pud.f_division -- участок left join core.sd_subdivisions as ssd on ssd.id = pud.f_subdivision inner join core.pd_users as pu on pu.id = pud.f_user and ( pu.id = _fn_user or _fn_user is null) where 1=1 --and date_part('hour', dy.d_date) between 6 and 23 and ( sd.id = _f_div or sd.f_division = _f_div or _f_div is null) and ( ssd.id = _f_subdiv or _f_subdiv is null) group by pu.id, concat(pu.c_last_name || ' ', pu.c_first_name || ' ', pu.c_middle_name), dy.d_date, date_part('hour', dy.d_date); RETURN QUERY select t.f_div, t.f_subdiv, t.f_user, t.c_user, sum(rres.n_count_plan)::integer as n_count_plan, array_to_json(array_agg(row_to_json(rres) order by t.d_date, t.n_hour)) from t_userdivisions as t -- руз-ты left join ( select tt.f_user, tt.d_date as d_date, tt.n_hour as n_hour, coalesce(rr.n_count_plan,0) as n_count_plan, coalesce(rr.n_count, 0) as n_count, sum(coalesce(rr.n_count, 0)) over(partition by tt.f_user, tt.d_date) as n_count_all, -- всего за день max(coalesce(rr.n_count, 0)) over(partition by tt.d_date, tt.n_hour) as n_max, -- максимум по предприятию за час avg(coalesce(rr.n_count::real, 0)) over(partition by tt.d_date, tt.n_hour)::integer as n_avg, -- среднее по предприятию за час coalesce(rr.n_count_ABDP, 0) as n_count_ABDP from t_userdivisions as tt left join ( select uir.f_user, coalesce(rr.d_date, cr.d_date)::date as d_date, date_part('hour', coalesce(rr.d_date, cr.d_date)) as n_hour, count(distinct cp.id) as n_count_plan, count(distinct rr.fn_point) as n_count, count(distinct case when b_ABDP then rr.fn_point end) as n_count_ABDP from core.cd_routes as cr inner join core.cd_userinroutes as uir on uir.f_route = cr.id inner join core.cd_points as cp on cp.f_route = cr.id left join ( select rr.fn_point, rr.fn_user, case when crt.c_const = 'ABDP' then true else false end as b_ABDP, max(rr.d_date) as d_date from core.cd_results as rr left join core.cs_result_types as crt on crt.id = rr.fn_type group by rr.fn_point, rr.fn_user, case when crt.c_const = 'ABDP' then true else false end ) as rr on rr.fn_point = cp.id and rr.fn_user = uir.f_user group by uir.f_user, coalesce(rr.d_date, cr.d_date)::date, date_part('hour', coalesce(rr.d_date, cr.d_date)) ) as rr on 1=1 and rr.f_user = tt.f_user and rr.d_date = tt.d_date and rr.n_hour = tt.n_hour where 1=1 order by tt.f_user, tt.d_date, tt.n_hour, rr.n_count_plan ) as rres on 1=1 and rres.f_user = t.f_user and rres.d_date = t.d_date and rres.n_hour = t.n_hour group by t.f_div,t.f_subdiv,t.c_user,t.f_user order by sum(rres.n_count) desc, t.f_div,t.f_subdiv,t.c_user,t.f_user ; end
Получение диспетчеров по заданному фильтру
/** * @params {integer} _f_current_user - иден. текущего пользователя * @params {integer} _f_main_division - иден. филиал * @params {integer} _f_division - иден. отделение * @params {integer} _f_subdivision - иден. участок * * @example * [{ "action": "cf_arm_pd_user_managers", "method": "Select", "data": [{ "params": [_f_current_user, _f_main_division, _f_division, _f_subdivision] }], "type": "rpc", "tid": 0}] */ DECLARE _f_role integer; BEGIN select r.id into _f_role from core.pd_roles as r where r.c_name = 'manager'; IF _f_current_user is not null AND _f_main_division is not null THEN CASE WHEN _f_division is null AND _f_subdivision is null THEN -- пользователь и Филиал выбраны RETURN QUERY select u.id, u.c_login, u.c_first_name, u.c_last_name, u.c_middle_name from core.pd_userindivisions as uid inner join core.pd_users as u ON uid.f_user = u.id inner join core.pd_userinroles as uir ON uir.f_user = u.id inner join dbo.cf_arm_sd_main_divisions(_f_current_user) as smd ON smd.id = uid.f_division where uir.f_role = _f_role and smd.id = _f_main_division; WHEN _f_division is not null AND _f_subdivision is null THEN -- пользователь, Филиал и Отделение выбраны RETURN QUERY select u.id, u.c_login, u.c_first_name, u.c_last_name, u.c_middle_name from core.pd_userindivisions as uid inner join core.pd_users as u ON uid.f_user = u.id inner join core.pd_userinroles as uir ON uir.f_user = u.id inner join dbo.cf_arm_sd_divisions(_f_current_user, _f_main_division) as smd ON smd.id = uid.f_division where uir.f_role = _f_role and smd.id = _f_division; WHEN _f_division is not null AND _f_subdivision is not null THEN -- пользователь, Филиал, Отделение и Участок выбраны RETURN QUERY select u.id, u.c_login, u.c_first_name, u.c_last_name, u.c_middle_name from dbo.cf_arm_sd_subdivisions(_f_current_user, _f_division) as smd inner join core.pd_userindivisions as uid ON smd.f_division = uid.f_division OR smd.id = uid.f_subdivision inner join core.pd_users as u ON uid.f_user = u.id inner join core.pd_userinroles as uir ON uir.f_user = u.id where uir.f_role = _f_role and smd.id = _f_subdivision; END CASE; END IF; END
Получение статистик по обходчику
/** * @params {integer} _fn_user - иден. обходчика * @params {date} _d_date - дата * * @example * [{ "action": "cf_arm_pd_user_stat", "method": "Select", "data": [{ "params": [_fn_user, _d_date] }], "type": "rpc", "tid": 0}] */ DECLARE _status_weight integer; _result_types_oov integer; BEGIN select rs.n_order into _status_weight from core.cs_route_statuses as rs where rs.c_const = 'ASSINGNED'; -- не ниже этого статуса --тип документа "отказ от выполнения" select rt.id into _result_types_oov from core.cs_result_types as rt where rt.c_const = 'OOV'; RETURN QUERY with points as ( -- все задания для контролера select (CASE WHEN s.b_person THEN 1 ELSE 0 END) as b_person from core.cd_routes as r inner join core.cd_userinroutes as uir ON r.id = uir.f_route INNER join core.cs_route_statuses as rs ON rs.id = r.f_status INNER JOIN core.cd_points as p ON p.f_route = r.id left join dbo.ed_registr_pts as rp ON rp.id = p.f_registr_pts left join dbo.sd_subscr as s ON s.id = rp.f_subscr where uir.f_user = _fn_user and _d_date::date >= r.d_date_start and _d_date::date <= CASE WHEN r.b_extended THEN r.d_extended ELSE r.d_date_end END and rs.n_order >= _status_weight ), userpoints as ( -- выполненные контролером задания select max(CASE WHEN s.b_person THEN 1 ELSE 0 END) as b_person, CASE WHEN max(cr.fn_type) = _result_types_oov and count(distinct cr.fn_type) = 1 then 1 else 0 end as b_refuse, max(up.d_date) as d_date from core.cd_userinroutes as uir INNER JOIN core.cd_routes as rt ON rt.id = uir.f_route INNER join core.cs_route_statuses as rs ON rs.id = rt.f_status INNER JOIN core.cd_points as p ON p.f_route = uir.f_route left join dbo.ed_registr_pts as rp ON rp.id = p.f_registr_pts left join dbo.sd_subscr as s ON s.id = rp.f_subscr inner JOIN core.cd_user_points as up ON up.fn_point = p.id left join core.cd_results as cr on cr.fn_user_point = up.id where uir.f_user = _fn_user and _d_date::date >= rt.d_date_start and _d_date::date <= CASE WHEN rt.b_extended THEN rt.d_extended ELSE rt.d_date_end END and rs.n_order >= _status_weight group by p.id ) select u.id, u.c_login, u.c_first_name, u.c_last_name, u.c_middle_name, u.c_email, u.c_phone, u.fn_file, (select a.d_date from core.ad_tracking as a where a.fn_user = u.id order by a.d_date desc limit 1) as d_tracking_date, -- время последнего получения геокординаты (select count(*) from userpoints where b_person = 1 and d_date::date = _d_date) as n_today_done_person, -- Выполнено сегодня ФЛ (select count(*) from userpoints where b_person = 1) as n_all_done_person, -- Выполнено ФЛ (select count(*) from userpoints where b_person = 1 and b_refuse = 1) as n_refuse_person, -- Отказ от выполнения ФЛ ((select count(*) from points where b_person = 1) - (select count(*) from userpoints where b_person = 1)) as n_lost_person, -- Осталось ФЛ (select count(*) from points where b_person = 1) as n_all_person, -- Общее кол-во ФЛ (select count(*) from userpoints where b_person = 0 and d_date::date = _d_date) as n_today_done, -- Выполнено сегодня ЮЛ (select count(*) from userpoints where b_person = 0) as n_all_done, -- Выполнено ЮЛ (select count(*) from userpoints where b_person = 0 and b_refuse = 1) as n_refuse, -- Отказ от выполнения ЮЛ ((select count(*) from points where b_person = 0) - (select count(*) from userpoints where b_person = 0)) as n_lost, -- Осталось ЮЛ (select count(*) from points where b_person = 0) as n_all -- Общее кол-во ЮЛ from core.pd_users as u where u.id = _fn_user; END
Получение обходчиков по заданному фильтру
/** * @params {integer} _f_main_division - иден. филиал. Обязателен при передаче * @params {integer} _f_division - иден. отделение. Может быть null * @params {integer} _f_subdivision - иден. участок. Может быть null * @params {integer} _f_manager - иден. диспетчер. Может быть null * @params {integer} _f_user - иден. обходчика. Может быть null * * @example * [{ "action": "cf_arm_pd_users", "method": "Select", "data": [{ "params": [_f_main_division, _f_division, _f_subdivision, _f_manager, _f_user] }], "type": "rpc", "tid": 0}] */ DECLARE _users json; -- обходчики BEGIN RETURN QUERY select u.id, max(u.c_login), max(u.c_first_name), max(u.c_last_name), max(u.c_middle_name), max(u.fn_file), concat('.', string_agg(distinct r.c_name, '.'), '.') from core.pd_userindivisions as uid inner join core.pd_users as u ON uid.f_user = u.id inner join core.pd_userinroles as uir ON uir.f_user = uid.f_user inner join core.pd_roles as r ON r.id = uir.f_role left join core.sd_divisions as dd on dd.id = uid.f_division where --r.c_name = 'inspector' and (case when _f_main_division is null then 1=1 else _f_main_division = dd.f_division end) and (case when _f_division is null then 1=1 else _f_division = dd.id end) and (case when _f_subdivision is null then 1=1 else _f_subdivision = uid.f_subdivision end) and (case when _f_manager is null then 1=1 else _f_manager = u.f_parent end) and (case when _f_user is null then 1=1 else _f_user = u.id end) group by u.id; END
Получение статистика для обходчиков по заданному фильтру
/** * @params {integer} _f_main_division - иден. филиал. Обязателен при передаче * @params {integer} _f_division - иден. отделение. Обязателен при передаче * @params {integer} _f_subdivision - иден. участок. Обязателен при передаче * @params {integer} _f_manager - иден. диспетчер. Может быть null * @params {integer} _f_user - иден. обходчика. Может быть null * * @example * [{ "action": "cf_arm_pd_users_stat", "method": "Select", "data": [{ "params": [_f_main_division, _f_division, _f_subdivision, _f_manager, _f_user] }], "type": "rpc", "tid": 0}] */ BEGIN RETURN QUERY select u.id, -- общая информация о пользователе u.c_login, u.c_first_name, u.c_last_name, u.c_middle_name, u.fn_file, (select count(*) from dbo.cf_arm_cd_routes(u.id, now()::date)) as n_route_active, -- кол-во активных маршрутов (select a.d_date from core.ad_tracking as a where a.fn_user = u.id order by a.d_date desc limit 1) as d_tracking_date, -- время последнего получения геокординаты coalesce(s.n_today_done_person, 0) + coalesce(s.n_today_done, 0) as n_today_done, -- выполнено сегодня coalesce(s.n_all_done_person, 0) + coalesce(s.n_all_done, 0) as n_all_done, -- выполнено всего coalesce(s.n_refuse_person, 0) + coalesce(s.n_refuse, 0) as n_refuse, -- отказ от выполнения coalesce(s.n_lost_person, 0) + coalesce(s.n_lost, 0) as n_lost, -- осталось coalesce(s.n_all_person, 0) + coalesce(s.n_all, 0) as n_all -- Общее количество from dbo.cf_arm_pd_users(_f_main_division, _f_division, _f_subdivision, _f_manager, _f_user) as u left join lateral dbo.cf_arm_pd_user_stat(u.id, _d_date::date) s on true where u.c_claims ilike '%.inspector.%'; END
Удаление маршрута со статусом "Сформирован"
/** * @params {uuid} _route_id - идентификатор маршрута * * @returns {integer} * 0 - ОК * 1 - статус документ отличается от "сформирован" и "формируется" * * @example * [{ "action": "cf_arm_remove_route", "method": "Query", "data": [{ "params": [_route_id] }], "type": "rpc", "tid": 0}] */ DECLARE _c_status text; BEGIN select rs.c_const into _c_status from core.cd_routes as r inner join core.cs_route_statuses as rs ON rs.id = r.f_status where r.id = _route_id; -- лучше статус не менять иначе при синхронизации может быть потеря данных IF _c_status = 'CREATE' OR _c_status = 'CREATED' THEN RETURN core.sf_del_route(_route_id); ELSE RETURN 1; -- статус документ отличается от "сформирован" и "формируется" END IF; END
Массовое удаление маршрутов со статусом "Сформирован" или "Формируется"
/** * @params {json} _routes - массив маршрутов, требуется передать в виде строки '["e7ded0cd-12dd-47f5-a75b-192376291e83"]' * * @returns возвращается таблица с двумя колонками id:uuid и n_status: integer, дополнительно о статусах можно узнать в функции dbo.cf_arm_remove_route * * @example * [{ "action": "cf_arm_remove_routes", "method": "Query", "data": [{ "params": [_f_current_user, routes] }], "type": "rpc", "tid": 0}] */ BEGIN RETURN QUERY select t.value::uuid as id, dbo.cf_arm_remove_route(t.value::uuid) as n_status from json_array_elements_text(_routes) as t; END
DECLARE _d_date_period date; BEGIN -- период вычисляется на основе даты завершения маршрута select date_trunc('MONTH',(case when r.b_extended then r.d_extended else r.d_date_end end))::date into _d_date_period from core.cd_routes as r where r.id = _f_route; create temp table t_keys ( id uuid, f_registr_pts uuid, f_point_type int, c_point_name text ) on commit drop; insert into t_keys( id, f_registr_pts, f_point_type, c_point_name ) select cp.id, rp.id as f_registr_pts, cp.f_type as f_point_type, cpt.c_name as c_point_name from core.cd_points as cp inner join dbo.ed_registr_pts as rp on rp.id = cp.f_registr_pts left join core.cs_point_types as cpt on cpt.id = cp.f_type where cp.f_route = _f_route; --'a499211a-2714-4552-a45c-45ac8959c7a1' RETURN QUERY with history as ( select distinct rpth.id, t.id as f_point, rpth.f_point_type, rpth.f_registr_pts, rpth.b_plan, rpth.f_no_plan_work, npw.c_name as c_no_plan_work, row_number() over(partition by rpth.f_registr_pts, rpth.f_point_type, rpth.b_plan, rpth.f_no_plan_work order by rpth.d_date_period desc, rpth.id) as n_row from t_keys as t inner join dbo.ed_registr_pts_history as rpth ON t.f_registr_pts = rpth.f_registr_pts and rpth.f_point_type = t.f_point_type left join dbo.es_no_plan_works as npw ON npw.id = rpth.f_no_plan_work where case when _d_date_period is not null then rpth.d_date_period = _d_date_period else rpth.d_date_period is null end ) select t.id, t.f_registr_pts, t.f_point_type, t.c_point_name, sd2.c_name as c_filial, sd.c_name as c_pes, ss2.c_name as c_res, case when ss.b_person then ss.c_name1 || ' ' || ss.c_name2 || ' ' || ss.c_name3 else ss.c_name1 end as c_subscr_name, ss.c_code as c_subscr_code, erp.c_registr_pts, erp.c_status_registr_pts, erp.d_close_date as d_tu_close_date, ss.n_check_date, ss.b_problem_person, erp.f_status_consume::text, -- привести справочник esc.c_name as c_status_consume, erp.b_technical_metering, erp.c_status, erp.c_predictr, ed.c_serial_number, edt.c_name as c_device_type, coalesce(ed.b_askue, false) as b_askue, edt.b_phase3, ed.d_setup_date, ed.d_close_date as d_pu_close_date, ed.d_valid_date, erp.c_substation , erp.c_line_substation , erp.c_rp, erp.c_line_rp, erp.c_tp, erp.c_line_tp, sa.c_raion, sa.c_city_name, sa.c_settlement_name, sa.c_street_name, sa.c_house_name, sa.c_block_name, sa.c_flat_name, sa.n_geo_lat, sa.n_geo_lon, sa.c_comment_address, _d_date_period as d_date_period, hst.b_plan as b_plan, hst.f_no_plan_work as f_no_plan_work, hst.c_no_plan_work as c_no_plan_work from t_keys as t inner join dbo.ed_registr_pts as erp on erp.id = t.f_registr_pts inner join dbo.sd_subscr as ss on ss.id = erp.f_subscr left join dbo.ss_address as sa on sa.id = erp.f_address inner join dbo.ed_devices as ed left join dbo.es_device_types as edt on edt.id = ed.f_device_type on ed.f_registr_pts = t.f_registr_pts and ed.d_close_date is null left join core.sd_divisions sd left join core.sd_divisions as sd2 on sd2.id = sd.f_division on sd.id = erp.f_division left join core.sd_subdivisions as ss2 on ss2.id = erp.f_subdivision left join dbo.es_status_consume as esc on esc.id = coalesce(erp.f_status_consume, 2) left join history as hst on hst.f_point = t.id and hst.f_point_type = t.f_point_type and hst.n_row = 1 ; END
Список отделений доступных для пользователя
/** * @params {integer} _f_current_user - текущий пользователь * @params {integer} _f_main_division - филиал * * @example * [{ "action": "cf_arm_sd_divisions", "method": "Select", "data": [{ "params": [_f_current_user, _f_main_division] }], "type": "rpc", "tid": 0}] */ BEGIN -- список разрешеннных отделений см. core.pd_userindivisions -> f_division RETURN QUERY WITH RECURSIVE tree AS ( SELECT d.id, d.f_division, d.c_name, d.c_dep_code, d.n_code, d.b_disabled FROM core.sd_divisions as d where d.id IN (select ud.f_division from core.pd_userindivisions as ud where ud.f_user = _f_current_user) UNION SELECT d.id, d.f_division, d.c_name, d.c_dep_code, d.n_code, d.b_disabled FROM core.sd_divisions as d JOIN tree ON d.id = tree.f_division) select t.id, t.f_division, t.c_name, t.c_dep_code, t.n_code from tree as t where t.b_disabled = false and t.f_division = _f_main_division; END
Список филиалов доступных для пользователя
/** * @params {integer} _f_current_user - текущий пользователь * * @example * [{ "action": "cf_arm_sd_main_divisions", "method": "Select", "data": [{ "params": [_f_current_user] }], "type": "rpc", "tid": 0}] */ BEGIN -- список разрешеннных отделений см. core.pd_userindivisions -> f_division RETURN QUERY WITH RECURSIVE tree AS ( SELECT d.id, d.f_division, d.c_name, d.c_dep_code, d.n_code, d.b_disabled FROM core.sd_divisions as d where d.id IN (select ud.f_division from core.pd_userindivisions as ud where ud.f_user = _f_current_user) UNION SELECT d.id, d.f_division, d.c_name, d.c_dep_code, d.n_code, d.b_disabled FROM core.sd_divisions as d JOIN tree ON d.id = tree.f_division) select t.id, t.c_name, t.c_dep_code, t.n_code from tree as t where t.b_disabled = false and t.f_division is null; END
Список участков доступных для пользователя
/** * @params {integer} _f_current_user - текущий пользователь * @params {integer} _f_division - отделение * * @example * [{ "action": "cf_arm_sd_subdivisions", "method": "Select", "data": [{ "params": [_f_current_user, _f_division] }], "type": "rpc", "tid": 0}] */ BEGIN -- список разрешеннных отделений см. core.pd_userindivisions -> f_subdivision RETURN QUERY -- поиск subdivisions select sd.id, sd.f_division, sd.c_name, sd.n_code, true as b_subdivision -- b_subdivision прямой доступ к участку from core.pd_userindivisions as ud inner join core.sd_subdivisions as sd ON ud.f_subdivision = sd.id where ud.f_user = _f_current_user and ud.f_subdivision is not null and b_disabled = false UNION -- поиск через divisions select sd.id, sd.f_division, sd.c_name, sd.n_code, false as b_subdivision from core.sd_subdivisions as sd where sd.b_disabled = false and sd.f_division IN (WITH RECURSIVE tree AS ( SELECT d.id, d.f_division FROM core.sd_divisions as d where d.id IN (select ud.f_division from core.pd_userindivisions as ud where ud.f_user = _f_current_user and ud.f_division is not null and ud.f_subdivision is null) UNION SELECT d.id, d.f_division FROM core.sd_divisions as d JOIN tree ON d.id = tree.f_division) select t.id from tree as t); END
Передача маршрута на исполнение
/** * @params {integer} _f_current_user - текущий пользователь * @params {uuid} _route_id - идентификатор маршрута * * @returns {integer} * 0 - ОК * 1 - маршрут не найден * 2 - пользователь не найден * 3 - статус документ отличается от "назначен" * * @example * [{ "action": "cf_arm_transfer_route", "method": "Query", "data": [{ "params": [_f_current_user, _route_id] }], "type": "rpc", "tid": 0}] */ DECLARE _c_status text; -- текущий статус маршрута _f_next_status_id integer; -- статус - передан BEGIN IF(select count(*) from core.cd_routes as r where r.id = _route_id) = 1 THEN IF(select count(*) from core.pd_users as u where u.id = _f_current_user) = 1 THEN -- текущий статус select rs.c_const into _c_status from core.cd_routes as r left join core.cs_route_statuses as rs ON rs.id = r.f_status where r.id = _route_id; -- Передаем только после назначен IF _c_status = 'ASSINGNED' THEN -- новый статус select rs.id into _f_next_status_id from core.cs_route_statuses as rs where rs.c_const = 'TRANSFERRED'; -- создаем новый статус "передан" insert into core.cd_route_history (fn_route, fn_status, fn_user, d_date) values (_route_id, _f_next_status_id, _f_current_user, now()); RETURN 0; ELSE RETURN 3; -- статус документ отличается от "назначен" END IF; ELSE RETURN 2; -- нет пользователя END IF; ELSE RETURN 1; -- нет маршрута END IF; END
Передача нескольких маршрутов на исполнение
/** * @params {integer} _f_current_user - текущий пользователь * @params {json} _routes - массив маршрутов, требуется передать в виде строки '["e7ded0cd-12dd-47f5-a75b-192376291e83"]' * * @returns * возвращается таблица с двумя колонками route_id:uuid и status_id: integer, где статус может содержать значение 0 - ОК, 1 - пользователь не найден. * дополнительные статусы можно узнать в функции dbo.cf_arm_transfer_route * * @example * [{ "action": "cf_arm_transfer_routes", "method": "Query", "data": [{ "params": [_f_current_user, routes] }], "type": "rpc", "tid": 0}] */ BEGIN IF (select count(*) from core.pd_users as u where u.id = _f_current_user) = 1 THEN RETURN QUERY select t.value::uuid, dbo.cf_arm_transfer_route(_f_current_user, t.value::uuid) from json_array_elements_text(_routes) as t; ELSE RETURN QUERY select null, 1; END IF; END
Обновление точек маршрута на основе точек учета
/** * @params {uuid} _f_route - маршрут * @params {json} _registr_pts - идент-ры точек учета, передавать в виде строку иден-ров, например '[{"id": "40170afe-498d-4ff0-a1e7-9f29d470cf0a", "f_type": 1}, {"id": "16dc8d78-04db-45ac-ab02-2112000478c2", "f_type": 2}]' * @params {boolean} _b_delete - нужно ли удалить указанные точки учета. true - да * * @returns * 0 - OK * 1 - нет маршрута * 2 - точки учета не переданы * * @example * [{ "action": "cf_arm_update_route", "method": "Query", "data": [{ "params": [_f_route, _registr_pts, _b_delete] }], "type": "rpc", "tid": 0}] */ BEGIN IF (select count(*) from core.cd_routes as r where r.id = _f_route) = 1 THEN IF (select count(*) from json_array_elements(_registr_pts)) > 0 THEN IF _b_delete THEN delete from core.cd_points as p where p.f_route = _f_route and p.f_registr_pts in (select (t.value #>> '{id}')::uuid from json_array_elements(_registr_pts) as t); RETURN 0; ELSE insert into core.cd_points (f_registr_pts, f_route, f_type, c_notice, c_info, jb_data, n_order, sn_delete) select (t.value #>> '{id}')::uuid, _f_route, (t.value #>> '{f_type}')::integer, null, dbo.sf_generate_point_info(rp.id), dbo.sf_generate_point_jb_data(rp.id), 1, false from json_array_elements(_registr_pts) as t inner join dbo.ed_registr_pts as rp ON rp.id = (t.value #>> '{id}')::uuid left join dbo.ss_address as ad ON ad.id = rp.f_address order by ad.c_name; RETURN 0; END IF; ELSE RETURN 2; -- точки не переданы END IF; ELSE RETURN 1; -- нет маршрута END IF; END
Обновление точек маршрута для раздела планирования
/** * @params {uuid} _f_route - маршрут * @params {json} _registr_pts_history - идент-ры точек, передавать в виде строку иден-ров, например '[{"f_registr_pts_history": "40170afe-498d-4ff0-a1e7-9f29d470cf0a", "f_type": 1}, {"f_registr_pts_history": "16dc8d78-04db-45ac-ab02-2112000478c2", "f_type": 2}]' * * @returns * 0 - OK * 1 - нет маршрута * 2 - точки учета не переданы * * @example * [{ "action": "cf_arm_update_route", "method": "Query", "data": [{ "params": [_f_route, _registr_pts_history] }], "type": "rpc", "tid": 0}] */ BEGIN IF (select count(*) from core.cd_routes as r where r.id = _f_route) = 1 THEN IF (select count(*) from json_array_elements(_registr_pts_history)) > 0 THEN insert into core.cd_points (f_registr_pts, f_route, f_type, c_notice, c_info, jb_data, n_order, sn_delete) select rph.f_registr_pts, _f_route, (t.value #>> '{f_type}')::integer, null, dbo.sf_generate_point_info(rp.id), dbo.sf_generate_point_jb_data(rp.id), 1, false from json_array_elements(_registr_pts_history) as t inner join dbo.ed_registr_pts_history as rph ON rph.id = (t.value #>> '{f_registr_pts_history}')::uuid inner join dbo.ed_registr_pts as rp ON rp.id = rph.f_registr_pts left join dbo.ss_address as ad ON ad.id = rp.f_address order by ad.c_name; -- 476674: далее нужно проставить b_plan update dbo.ed_registr_pts_history as rph set b_plan = true where rph.id in (select (t.value #>> '{f_registr_pts_history}')::uuid from json_array_elements(_registr_pts_history) as t); RETURN 0; ELSE RETURN 2; -- точки не переданы END IF; ELSE RETURN 1; -- нет маршрута END IF; END
Создание пользователя с ролями
BEGIN -- не переданы обязательные атрибуты if _c_last_name is null or _c_first_name is null or _f_maindivision is null or _f_division is null or _f_subdivision is null or nullif(trim(_c_login), '') is null or nullif(trim(_c_tab_number), '') is null or nullif(trim(_c_password), '') is null then return 1; end if; -- пользователь с таким табельным номером уже существует if exists(select 1 from core.pd_users where c_tab_number = _c_tab_number) then return 2; end if; -- пользователь с таким логином уже существует if exists(select 1 from core.pd_users where c_login = _c_login) then return 3; end if; -- удостовериться что переданные рэс есть в справочнике select id into _f_maindivision from core.sd_divisions where id = _f_maindivision and f_division is null; select id into _f_division from core.sd_divisions where id = _f_division and f_division = _f_maindivision; select id into _f_subdivision from core.sd_subdivisions where id = _f_subdivision and f_division = _f_division; with ins_users as ( -- создание пользователя insert into core.pd_users (c_last_name, c_first_name, c_middle_name, c_login, c_tab_number, c_post_code, c_post, c_phone, c_email, s_hash, b_pgcrypto) select _c_last_name, _c_first_name, _c_middle_name, _c_login, _c_tab_number, _c_post_code, _c_post, _c_phone, _c_email, crypt(_c_password, gen_salt('bf', 8)), true returning id ) -- привязка к участку insert into core.pd_userindivisions (f_user, f_division, f_subdivision) select pu.id as f_user, _f_division, _f_subdivision from ins_users as pu where _f_division is not null and _f_subdivision is not null union -- привязка к отделению select pu.id as f_user, _f_division, null from ins_users as pu where _f_division is not null union -- привязка к филиалу select pu.id as f_user, _f_maindivision, null from ins_users as pu where _f_maindivision is not null ; RETURN 0; END
Получение карточки пользователя (детальная информация о пользователе)
BEGIN RETURN QUERY select pd.id, pd.c_last_name, pd.c_first_name, pd.c_middle_name, pd.c_login, pd.c_tab_number, pd.c_post_code, pd.c_post, ( select string_agg(distinct coalesce(sdd.c_name, sd.c_name), ',') from core.pd_userindivisions as pud inner join core.sd_divisions as sd on sd.id = pud.f_division left join core.sd_divisions as sdd on sdd.id = sd.f_division where pud.f_user = pd.id ) as c_maindivision, ( select string_agg(distinct sd.c_name, ',') from core.pd_userindivisions as pud inner join core.sd_divisions as sd on sd.id = pud.f_division where pud.f_user = pd.id and sd.f_division is null ) as c_division, ( select string_agg(distinct ss.c_name, ',') from core.pd_userindivisions as pud inner join core.sd_subdivisions as ss on ss.id = pud.f_subdivision where pud.f_user = pd.id ) as c_subdivision, pd.c_phone, ( SELECT string_agg(t_1.c_description, ',') AS string_agg FROM ( SELECT r.c_description FROM core.pd_userinroles uir JOIN core.pd_roles r ON uir.f_role = r.id WHERE uir.f_user = pd.id ORDER BY r.n_weight DESC ) t_1 ) as c_claims, pd.c_email, case when pd.b_disabled then 'Отключен' else 'Действующий' end as c_status, null::date as d_date_work, null::date as d_date_dismiss from core.pd_users as pd where 1=1 and pd.c_tab_number = _c_tab_number ; END
Получение списка ролей
BEGIN RETURN QUERY select pd.id, pd.c_name, pd.c_description from core.pd_roles as pd where 1=1 and not sn_delete; END
Получение списка пользователей
BEGIN RETURN QUERY select pd.id, pd.c_last_name, pd.c_first_name, pd.c_login, pd.c_tab_number, pd.c_post_code, ( select string_agg(distinct coalesce(sdd.c_name, sd.c_name), ',') as string_agg from core.pd_userindivisions as pud inner join core.sd_divisions as sd on sd.id = pud.f_division left join core.sd_divisions as sdd on sdd.id = sd.f_division where pud.f_user = pd.id ) as c_maindivision, ( SELECT string_agg(t_1.c_name, ',') AS string_agg FROM ( SELECT r.c_name FROM core.pd_userinroles uir JOIN core.pd_roles r ON uir.f_role = r.id WHERE uir.f_user = pd.id ORDER BY r.n_weight DESC ) t_1 ) AS c_claims from core.pd_users as pd where 1=1 and not pd.sn_delete -- не удаленные and case when _f_maindivision is null then true else _f_maindivision in (select pud.f_division from core.pd_userindivisions as pud where pud.f_user = pd.id) end -- фильтр по филиалу and pd.b_disabled = coalesce(_b_disabled, pd.b_disabled) -- фильтр по статусу and case when _c_post_code is null then true else pd.c_post_code = _c_post_code end -- фильтр по коду должности order by pd.id ; END
Изменение профиля пользователя
DECLARE _f_user int4; -- идентификатор пользователя BEGIN -- не передан табельный номер if nullif(trim(_c_tab_number), '') is null then return 1; end if; -- идентификатор пользователя по табельному номеру select id into _f_user from core.pd_users where c_tab_number = _c_tab_number; -- пользователя с таким табельным номером не существует if _f_user is null then return 2; end if; -- модификация атрибутов update core.pd_users set _c_last_name = _c_last_name, _c_first_name = _c_first_name, _c_middle_name = _c_middle_name, _c_login = _c_login, _c_post_code = _c_post_code, _c_post = _c_post, _c_phone = _c_phone, _c_email = _c_email where id = _f_user; -- изменение подразделения пользователя (подумать) /* select id into _f_maindivision from core.sd_divisions where id = _f_maindivision and f_division is null; select id into _f_division from core.sd_divisions where id = _f_division and f_division = _f_maindivision; select id into _f_subdivision from core.sd_subdivisions where id = _f_subdivision and f_division = _f_division; if _f_maindivision is not null and _f_division is not null and _f_subdivision is not null then insert into core.pd_userindivisions(f_user, f_division, f_subdivision) select _f_division, _f_subdivision end if; */ RETURN 0; END
Назначение пользователю роли
DECLARE _f_user int4; BEGIN if nullif(trim(_c_tab_number), '') is null or _f_role is null then return 1; end if; select id into _f_user from core.pd_users where c_tab_number = _c_tab_number; -- пользователя с таким табельным номером не существует if _f_user is null then return 2; end if; -- переданной роли нет в справочнике ролей if not exists(select 1 from core.pd_roles where id = _f_role) then return 3; end if; -- у пользователя уже есть такая роль if exists ( select 1 from core.pd_userinroles as pur where pur.f_role = _f_role and pur.f_user = _f_user) then return 4; end if; insert into core.pd_userinroles (f_user, f_role) select _f_user, _f_role; RETURN 0; END
Блокировка/Разблокировка пользователя
BEGIN -- если табельный номер не передан - то выход if nullif(trim(_c_tab_number), '') is null then RETURN 1; end if; -- пользователя с таким табельным номером не существует if not exists(select 1 from core.pd_users where c_tab_number = _c_tab_number) then return 2; end if; -- если есть что менять - то необходимо выполнить изменение if exists (select 1 from core.pd_users where c_tab_number = _c_tab_number and (b_disabled::int4 # _b_disabled::int4)::bool) then update core.pd_users set b_disabled = _b_disabled where c_tab_number = _c_tab_number; end if; RETURN 0; END
Изменение пароля
BEGIN if nullif(trim(_c_tab_number), '') is null or _c_new_pwd is null then return 1; end if; -- пользователя с таким табельным номером не существует if not exists(select 1 from core.pd_users where c_tab_number = _c_tab_number) then return 2; end if; -- изменение пароля update core.pd_users set s_salt = null, s_hash = crypt(_c_new_pwd, gen_salt('bf', 8)), b_pgcrypto = true where c_tab_number = _c_tab_number; -- успешный выход RETURN 0; END
Список бланков для обходчика
DECLARE _day text; BEGIN select coalesce(s.c_value, '30') into _day from core.cd_settings as s where s.c_key = 'DB_SEAL_DAY'; RETURN QUERY select b.id, b.f_result_type, coalesce(b.c_number, concat(b.c_prefix, b.n_number::text)) as c_number, b.f_user_to, b.f_status, b.dx_created from dbo.ed_blanks as b where b.f_user_to = _fn_user and b.f_status != 4 and b.f_status != 1 and (b.dx_created + (_day || ' day')::interval)::date >= now()::date; END
Список входных пломб для обходчика
BEGIN RETURN QUERY select t.uuid_id, t.id, t.f_registr_pts, t.f_point, t.c_number, t.c_name, t.c_location, t.dx_created, t.d_replace_date, t.n_row from (select t.*, row_number() over(partition by t.id, t.f_point order by t.dx_created desc) as n_row from (select uuid_generate_v4() as uuid_id, s.id, s.f_registr_pts, p.id as f_point, concat(coalesce(s.c_prefix, ''), s.c_number) as c_number, st.c_name, s.c_location, s.dx_created, s.d_replace_date from core.cd_userinroutes as uir inner JOIN core.cd_points as p ON p.f_route = uir.f_route inner JOIN core.cd_routes as rt ON rt.id = uir.f_route inner JOIN dbo.ed_seals as s ON s.f_registr_pts = p.f_registr_pts inner join dbo.es_seal_types as st ON st.id = s.f_type left join dbo.ed_output_conn_seals as ocs ON ocs.fn_point = p.id where uir.f_user = _fn_user and (s.d_replace_date is null or ocs.fn_seal = s.id) and CASE WHEN _f_point is null THEN core.sf_is_mobile_route(rt.id) ELSE p.id = _f_point END) as t ) as t where t.n_row = 1 ; END
Получение входящих показаний мобильным устройством
/** * @params {integer} _fn_user - идентификатор пользователя * @params {text} _c_version - текущая версия приложения * * @example * [{ "action": "cf_mui_ed_input_meter_readings", "method": "Select", "data": [{ "params": [_fn_user, _c_version] }], "type": "rpc", "tid": 0 }] */ BEGIN RETURN QUERY select uuid_generate_v4() as uuid_id, imp.id, p.id as f_point, imp.n_value_prev, imp.d_date_prev, imp.n_digit, imp.f_scale, s.n_order, s.c_name, et.c_const, imp.d_replace_date, imp.jb_sources::text from core.cd_userinroutes as uir inner JOIN core.cd_points as p ON p.f_route = uir.f_route inner JOIN core.cd_routes as rt ON rt.id = uir.f_route inner JOIN dbo.ed_input_meter_readings as imp ON imp.f_registr_pts = p.f_registr_pts inner join dbo.es_energy_types as et ON et.id = imp.f_energy_type inner join dbo.es_scales as s on imp.f_scale = s.id left join dbo.ed_output_meter_readings as omr ON omr.fn_point = p.id left join core.cd_user_points as up ON up.id = omr.fn_user_point where uir.f_user = _fn_user and (case when up.id is not null then up.fn_user = _fn_user else 1=1 end) and (imp.d_replace_date is null or omr.fn_meter_reading = imp.id) and CASE WHEN _f_point is null THEN core.sf_is_mobile_route(rt.id) ELSE p.id = _f_point END; END
Список входных трансформаторов для обходчика
BEGIN RETURN QUERY select uuid_generate_v4(), tf.id, p.id, dt.c_name, tf.b_voltage, tf.c_serial_number, tf.n_manufacture_year, coalesce(dt.n_rate, tf.n_rate), tf.c_phase, tf.f_registr_pts, tf.d_check_date, tf.dx_created, tf.d_replace_date from core.cd_userinroutes as uir inner JOIN core.cd_points as p ON p.f_route = uir.f_route inner JOIN core.cd_routes as rt ON rt.id = uir.f_route inner JOIN dbo.ed_transformers as tf ON tf.f_registr_pts = p.f_registr_pts inner join dbo.es_device_types as dt ON dt.id = tf.f_device_type where uir.f_user = _fn_user and (tf.d_replace_date is null or tf.id in (select et.fn_transformer from dbo.ed_output_transformers as et where et.fn_point = p.id)) and CASE WHEN _f_point is null THEN core.sf_is_mobile_route(rt.id) ELSE p.id = _f_point END; END
Выходные пломбы для обходчика
BEGIN RETURN QUERY select s.id, s.fn_seal, s.fn_point, s.fn_route, s.fn_user_point, s.fn_result, s.fn_seal_new, concat(coalesce(ss.c_prefix, ''), ss.c_number), s.fn_type, st.c_name, s.fn_place, sp.c_name, s.d_date, s.dx_created, ss.d_replace_date from core.cd_userinroutes as uir LEFT JOIN core.cd_routes as r ON r.id = uir.f_route INNER JOIN dbo.ed_output_conn_seals as s ON s.fn_route = r.id inner join dbo.es_seal_places as sp ON sp.id = s.fn_place inner join dbo.es_seal_types as st ON st.id = s.fn_type inner join dbo.ed_seals as ss ON ss.id = s.fn_seal_new where uir.f_user = _fn_user and CASE WHEN _f_point is null THEN core.sf_is_mobile_route(r.id) ELSE s.fn_point = _f_point END; END
Получение исходящих показаний мобильным устройством
/** * @params {integer} _fn_user - идентификатор пользователя * @params {text} _c_version - текущая версия приложения * * @example * [{ "action": "cf_mui_ed_output_meter_readings", "method": "Select", "data": [{ "params": [_fn_user, _c_version] }], "type": "rpc", "tid": 0 }] */ BEGIN RETURN QUERY select omr.id, omr.fn_meter_reading, omr.fn_route, omr.fn_point, omr.fn_user_point, omr.fn_result, omr.n_value, omr.d_date from core.cd_userinroutes as uir LEFT JOIN core.cd_routes as r ON r.id = uir.f_route INNER JOIN dbo.ed_output_meter_readings as omr ON omr.fn_route = r.id left join core.cd_user_points as up ON up.id = omr.fn_user_point inner join dbo.ed_input_meter_readings as imr ON imr.id = omr.fn_meter_reading where uir.f_user = _fn_user and up.fn_user = _fn_user and (CASE WHEN _f_result is null THEN core.sf_is_mobile_route(r.id) ELSE omr.fn_result = _f_result END); END
Исходящая информация о трансформаторах для обходчика
BEGIN RETURN QUERY select t.id, t.fn_route, t.fn_point, t.fn_user_point, t.fn_result, t.fn_transformer, t.fn_device_type, dt.c_name, t.c_number, t.n_year, t.d_date, t.n_rate, t.fn_phase, ph.c_name, t.b_voltage, t.d_date_check, t.n_check_cycle, t.n_tt1, t.n_tt2 from core.cd_userinroutes as uir LEFT JOIN core.cd_routes as r ON r.id = uir.f_route inner JOIN dbo.ed_output_transformers as t ON t.fn_route = r.id left join dbo.es_device_types as dt ON dt.id = t.fn_device_type left join dbo.es_phase as ph ON t.fn_phase = ph.id where uir.f_user = _fn_user and CASE WHEN _f_point is null THEN core.sf_is_mobile_route(r.id) ELSE t.fn_point = _f_point END; END
Список пломб для обходчика
DECLARE _day text; BEGIN select coalesce(s.c_value, '30') into _day from core.cd_settings as s where s.c_key = 'DB_SEAL_DAY'; RETURN QUERY select s.id, concat(coalesce(s.c_prefix, ''), s.c_number), s.f_user_to, s.f_type, st.c_name, s.f_status, s.dx_created from dbo.ed_seals as s inner join dbo.es_seal_types as st ON st.id = s.f_type left join dbo.ed_output_conn_seals as ocs ON ocs.fn_seal_new = s.id where (s.f_user_to = _fn_user and s.f_status != 5 and s.f_status != 1 and (s.dx_created + (_day || ' day')::interval)::date >= now()::date) or s.id in (select s.id from core.cd_userinroutes as uir inner JOIN core.cd_points as p ON p.f_route = uir.f_route inner JOIN core.cd_routes as rt ON rt.id = uir.f_route inner JOIN dbo.ed_seals as s ON s.f_registr_pts = p.f_registr_pts left join dbo.ed_output_conn_seals as ocs ON ocs.fn_point = p.id where uir.f_user = _fn_user and (s.d_replace_date is null or ocs.fn_seal = s.id) and core.sf_is_mobile_route(rt.id)); END
Место установки
/** * @params {integer} _fn_user - идентификатор пользователя * @params {text} _c_version - текущая версия приложения * * @example * [{ "action": "cf_mui_es_device_location", "method": "Select", "data": [{ "params": [_fn_user, _c_version] }], "type": "rpc", "tid": 0 }] */ BEGIN RETURN QUERY select dl.id, dl.c_name, dl.c_const from dbo.es_device_location as dl; END
Типы устройств
BEGIN return query with divisions as (select coalesce(sd.f_division, uid.f_division) as f_main_division, (case when sd.f_division is null then null else uid.f_division end) as f_division, uid.f_subdivision from core.pd_userindivisions as uid inner join core.sd_divisions as sd on sd.id = uid.f_division where uid.f_user = _fn_user) select dt.id, dc.b_meter, dt.c_name, dt.n_check_cycle, dt.f_main_division, dt.f_division, dt.f_subdivision, dt.n_tt1, dt.n_tt2 from dbo.es_device_types as dt inner join dbo.es_device_categories as dc ON dc.id = dt.f_device_categories where dt.b_disabled = false and (dt.f_main_division is null and dt.f_division is null and dt.f_subdivision is null); END
Тип энергии
/** * @params {integer} _fn_user - идентификатор пользователя * @params {text} _c_version - текущая версия приложения * * @example * [{ "action": "cf_mui_es_energy_types", "method": "Select", "data": [{ "params": [_fn_user, _c_version] }], "type": "rpc", "tid": 0 }] */ BEGIN RETURN QUERY select et.id, et.c_name, et.c_const, et.n_code, et.b_default from dbo.es_energy_types as et; END
Причины недопуска
/** * @params {integer} _fn_user - идентификатор пользователя * @params {text} _c_version - текущая версия приложения * * @example * [{ "action": "cf_mui_es_restrictions", "method": "Select", "data": [{ "params": [_fn_user, _c_version] }], "type": "rpc", "tid": 0 }] */ BEGIN RETURN QUERY select fr.id, fr.c_name, fr.c_const, fr.n_order from dbo.es_failure_reason as fr where fr.b_disabled = false; END
Фазы
/** * @params {integer} _fn_user - идентификатор пользователя * @params {text} _c_version - текущая версия приложения * * @example * [{ "action": "cf_mui_es_phase", "method": "Select", "data": [{ "params": [_fn_user, _c_version] }], "type": "rpc", "tid": 0 }] */ BEGIN RETURN QUERY select p.id, p.c_name from dbo.es_phase as p; END
Типы ограничений
/** * @params {integer} _fn_user - идентификатор пользователя * @params {text} _c_version - текущая версия приложения * * @example * [{ "action": "cf_mui_es_restrictions", "method": "Select", "data": [{ "params": [_fn_user, _c_version] }], "type": "rpc", "tid": 0 }] */ BEGIN RETURN QUERY select r.id, r.c_name, r.c_const, r.n_order from dbo.es_restrictions as r where r.b_disabled = false; END
Шкалы прибора учета
/** * @params {integer} _fn_user - идентификатор пользователя * @params {text} _c_version - текущая версия приложения * * @example * [{ "action": "cf_mui_es_scales", "method": "Select", "data": [{ "params": [_fn_user, _c_version] }], "type": "rpc", "tid": 0 }] */ BEGIN RETURN QUERY select s.id, s.c_name, s.c_const, s.n_order from dbo.es_scales as s where s.b_disabled = false; END
Справочник мест установки пломб
/** * @params {integer} _fn_user - идентификатор пользователя * @params {text} _c_version - текущая версия приложения * * @example * [{ "action": "cf_mui_es_seal_places", "method": "Select", "data": [{ "params": [_fn_user, _c_version] }], "type": "rpc", "tid": 0 }] */ BEGIN RETURN QUERY select sp.id, sp.c_name, sp.c_const, sp.n_order from dbo.es_seal_places as sp where sp.b_disabled = false; END
тип пломбы
/** * @params {integer} _fn_user - идентификатор пользователя * @params {text} _c_version - текущая версия приложения * * @example * [{ "action": "cf_mui_es_seal_types", "method": "Select", "data": [{ "params": [_fn_user, _c_version] }], "type": "rpc", "tid": 0 }] */ BEGIN RETURN QUERY select st.id, st.c_name, st.c_const, st.n_order from dbo.es_seal_types as st where st.b_disabled = false; END
Тарифные зоны
/** * @params {integer} _fn_user - идентификатор пользователя * @params {text} _c_version - текущая версия приложения * * @example * [{ "action": "cf_mui_es_work_links", "method": "Select", "data": [{ "params": [_fn_user, _c_version] }], "type": "rpc", "tid": 0 }] */ BEGIN RETURN QUERY select tz.id, tz.c_name, tz.c_const, tz.n_order from dbo.es_tariff_zones as tz where tz.b_disabled = false; END
Причина проверки
/** * @params {integer} _fn_user - идентификатор пользователя * @params {text} _c_version - текущая версия приложения * * @example * [{ "action": "cf_mui_es_verification_reason", "method": "Select", "data": [{ "params": [_fn_user, _c_version] }], "type": "rpc", "tid": 0 }] */ BEGIN RETURN QUERY select vr.id, vr.c_name, vr.c_const, vr.n_order from dbo.es_verification_reason as vr where vr.b_disabled = false; END
Типы нарушений
/** * @params {integer} _fn_user - идентификатор пользователя * @params {text} _c_version - текущая версия приложения * * @example * [{ "action": "cf_mui_es_violations", "method": "Select", "data": [{ "params": [_fn_user, _c_version] }], "type": "rpc", "tid": 0 }] */ BEGIN RETURN QUERY select v.id, v.c_name, v.c_const, v.n_order from dbo.es_violations as v where v.b_disabled = false; END
Сопоставление видов работ
/** * @params {integer} _fn_user - идентификатор пользователя * @params {text} _c_version - текущая версия приложения * * @example * [{ "action": "cf_mui_es_work_links", "method": "Select", "data": [{ "params": [_fn_user, _c_version] }], "type": "rpc", "tid": 0 }] */ BEGIN RETURN QUERY select el.id, el.f_route_type, el.f_point_type, el.f_result_type from dbo.es_work_links as el where el.b_disabled = false; END
DECLARE _updates_geo int = 0; -- кол-во вставленных ЛС begin insert into core.cd_sys_log(d_timestamp, c_descr) values(clock_timestamp(), 'Запущено обновление пустых координат в справочнике адресов.'); update dbo.ed_registr_pts AS erp set n_geo_lat = geeo.n_geo_lat, n_geo_lon = geeo.n_geo_lon from ( select cp.f_registr_pts, -- точка учета row_number() over(partition by cp.f_registr_pts order by cup.d_date asc, cp.id desc) as n_row, -- координат может быть несколько, берется самая первая по дате cup.n_latitude as n_geo_lat, -- широта cup.n_longitude as n_geo_lon -- долгота from core.cd_points as cp inner join core.cd_user_points AS cup on cup.fn_point = cp.id where cup.n_latitude > 0 and cup.n_longitude > 0 --координаты только из тех строк где они есть ) as geeo where 1=1 and ( coalesce(erp.n_geo_lat, 0) <> round(geeo.n_geo_lat, 6) or coalesce(erp.n_geo_lon, 0) <> round(geeo.n_geo_lon, 6)) and geeo.f_registr_pts = erp.id and geeo.n_row = 1; GET DIAGNOSTICS _updates_geo = ROW_COUNT; insert into core.cd_sys_log(d_timestamp, c_descr) values(clock_timestamp(), 'Обновление пустых координат в справочнике адресов выполнено. Обновлено ' || _updates_geo::text); EXCEPTION WHEN OTHERS THEN insert into core.cd_sys_log(d_timestamp, c_descr) values(clock_timestamp(), 'Непредвиденная ошибка обновления пустых координат в справочнике адресов'); end;
Заполнение буферов экспорта
DECLARE _message_text text; _status_weight integer; BEGIN _session_id = coalesce(_session_id, uuid_generate_v4()); select rs.n_order into _status_weight from core.cs_route_statuses as rs where rs.c_const = 'ASSINGNED'; -- выгружаются маршруты не ниже этого статуса insert into imp.i_integration_sessions( sessionId , startTime , status , parameters ) select _session_id as sessionId, now() as startTime, 'Операция запущена' as status, concat( 'Экспорт результатов. Параметры', ': Отделения: ', coalesce(_f_div, 'все отделения'), ', Участки: ', coalesce(_f_subdiv, 'все участки'), ', Интервал с: ', _d_date_begin, ', Интервал по: ', _d_date_end ) as parameters on conflict on CONSTRAINT i_integration_sessions_pkey do update set parameters = concat(imp.i_integration_sessions.parameters, excluded.parameters) ; begin -- маршруты begin insert into imp.e_routes ( f_maindivision , --Код Филиала f_subdivision , --Код участка f_doc , --Идентификатор (Первичный ключ) маршрута c_doc_name , --Номер (наименование) маршрута d_begin_date , --Дата начала маршрута d_end_date , --Дата окончания маршрута c_doc_type , --Тип маршрута c_doc_status , --Статус маршрута g_session_id --идентификатор сессии экспорта ) select max(coalesce(sdf.c_dep_code, sdf.n_code::text, sd.c_dep_code, sd.n_code::text)) as f_maindivision, max(coalesce(ssd.c_dep_code, ssd.n_code::text)) as f_subdivision, cr.id as f_doc, cr.c_number as c_doc_name, cr.d_date_start as d_begin_date, cr.d_date_end as d_end_date, --rt.c_name as c_doc_type, rt.id as c_doc_type, --rs.c_name as c_doc_status, rs.id as c_doc_status, _session_id as g_session_id from core.cd_routes as cr -- статус маршрута inner join core.cs_route_statuses as rs on rs.id = cr.f_status -- исполнитель маршрута inner join core.cd_userinroutes as uir on uir.f_route = cr.id and uir.b_main = true inner join core.pd_userindivisions as ud on ud.f_user = uir.f_user and ud.sn_delete = false -- отделение inner join core.sd_divisions as sd on sd.id = ud.f_division -- филиал left join core.sd_divisions as sdf on sdf.id = sd.f_division -- участок inner join core.sd_subdivisions as ssd on ssd.id = ud.f_subdivision -- тип маршрута inner join core.cs_route_types as rt on rt.id = cr.f_type where 1=1 and rs.n_order >= _status_weight and _d_date_end::date >= cr.d_date_start and _d_date_begin::date <= CASE WHEN cr.b_extended THEN cr.d_extended ELSE cr.d_date_end END and case when _f_div is null or _f_div = '' then true else coalesce(sdf.c_dep_code, sdf.n_code::text, sd.c_dep_code) in (select a.elem from unnest(string_to_array(_f_div, ',')) as a(elem) ) end and case when _f_subdiv is null or _f_subdiv = '' then true else ssd.c_dep_code in (select a.elem from unnest(string_to_array(_f_subdiv, ',')) as a(elem) ) end group by cr.id , cr.c_number , cr.d_date_start , cr.d_date_end , rt.id , rs.id; end; -- Строки заданий begin insert into imp.e_points ( f_maindivision , f_doc_detail , --идентификатор строки f_doc , --идентификатор (первичный ключ) маршрута f_registr_pts , --ссылка на идентификатор ту (код ту) c_fias_town , --код фиас города c_fias_municipality , --код фиас населенного пункта c_fias_street , --код фиас улицы c_fias_building , --код фиас дома n_latitude , --широта n_longitude , --долгота g_session_id ) select r.f_maindivision as f_maindivision, cp.id as f_doc_detail, cp.f_route as f_doc, erp.imp_text as f_registr_pts, sa.data_city_fias_id::text as c_fias_town, sa.settlement_fias_id::text as c_fias_municipality, sa.data_street_fias_id::text as c_fias_street, sa.data_house_fias_id::text as c_fias_building, coalesce(erp.n_geo_lat, sa.n_geo_lat) as n_latitude, coalesce(erp.n_geo_lon, sa.n_geo_lon) as n_latitude, _session_id as g_session_id from imp.e_routes as r inner join core.cd_points as cp on cp.f_route = r.f_doc inner join dbo.ed_registr_pts as erp on erp.id = cp.f_registr_pts left join dbo.ss_address as sa on sa.id = erp.f_address where 1=1 and r.g_session_id = _session_id; end; -- результаты begin insert into imp.e_results ( f_maindivision , -- код филиала f_docout , -- идентификатор документа f_doc_detail , -- идентификатор строки задания f_registr_pts , f_registr_pts_mk , f_device_guid , f_device , -- идентификатор ПУ d_docout_date , -- дата документа c_docout_number , -- номер документа (системный или номер бланка) f_docout_type , -- c_docout_name , -- наименование документа c_user_fio , -- фио исполнителя c_note , -- поле "примечание" карточки акта c_type_violation , -- тип нарушения d_violation_date_before , -- срок устранения нарушения c_note_violation , -- характеристика нарушения d_violation_date_begin , -- нарушение с d_violation_date_end , -- нарушение по c_reason_fail , -- причина невыполнения d_restrict_date , -- дата ограничения c_restrict , -- тип ограничения d_ranewal_date , -- дата возобновления f_check_reason , -- причина проверки c_voltage_a , -- напряжение фазное A c_voltage_b , -- напряжение фазное B c_voltage_c , -- напряжение фазное C c_power_disk , -- активная мощность по оборотам диска в силовой цепи c_power_meters , -- активная мощность по приборам в силовой цепи c_reactive_disk , -- реактивная мощность по оборотам диска в силовой цепи c_reactive_meters , -- реактивная мощность по приборам в силовой цепи c_user_tab_number , -- табельный номер пользователя, который составил акт g_session_id -- идентификатор сессии экспорта ) select p.f_maindivision as f_maindivision, cr.id as f_docout, cr.fn_point as f_doc_detail, p.f_registr_pts as f_registr_pts, cp.f_registr_pts as f_registr_pts_mk, ed.f_device_guid as f_device_guid, ed.f_device as f_device, cr.d_date::date as d_docout_date, coalesce(cr.jb_data ->> 'c_act_number', concat(rt.c_short_name, '-', u.id::text,'-',ed.c_serial_number)) as c_docout_number, coalesce(rt.c_code_out, rt.n_code::text, rt.id::text) as f_docout_type, coalesce(rt.c_code_out, rt.n_code::text, rt.c_name) as c_docout_name, concat(u.c_last_name || ' ', u.c_first_name || ' ', u.c_middle_name) as c_user_fio, cr.c_notice as c_note, coalesce(ev.c_code_out, ev.n_code::text) as c_type_violation, (cr.jb_data ->> 'd_violation_date_end')::date as d_violation_date_before, cr.jb_data ->> 'c_violation_notice' as c_note_violation, (cr.jb_data ->> 'd_violation_date_start')::date as d_violation_date_begin, (cr.jb_data ->> 'd_violation_date_end')::date as d_violation_date_end, coalesce(efr.id::text, cr.jb_data ->> 'c_failure', efr.c_name) as c_reason_fail, case when rt.c_const = 'AVOE' then cr.d_date::date end as d_restrict_date, coalesce(er.id::text, cr.jb_data ->> 'c_restriction', er.c_name) as c_restrict, case when rt.c_const = 'AVE' then cr.d_date::date end as d_ranewal_date, cp.f_type::text as f_check_reason, cr.jb_data ->> 'c_voltage_a' as c_voltage_a , cr.jb_data ->> 'c_voltage_b' as c_voltage_b , cr.jb_data ->> 'c_voltage_c' as c_voltage_c , cr.jb_data ->> 'c_power_disk' as c_power_disk , cr.jb_data ->> 'c_power_meters' as c_power_meters , cr.jb_data ->> 'c_reactive_disk' as c_reactive_disk , cr.jb_data ->> 'c_reactive_meters' as c_reactive_meters, u.c_tab_number as c_user_tab_number, _session_id as g_session_id from imp.e_points as p -- результат inner join core.cd_results as cr on cr.fn_point = p.f_doc_detail -- строки inner join core.cd_points as cp on cp.id = p.f_doc_detail -- исполнитель inner join core.pd_users as u on u.id = cr.fn_user -- тип документа inner join core.cs_result_types as rt on rt.id = cr.fn_type --and rt.c_const = 'CMR' -- типы нарушений left join dbo.es_violations as ev on ev.id = (cr.jb_data ->> 'f_violation')::integer -- причины недопуска left join dbo.es_failure_reason as efr on efr.id = (cr.jb_data ->> 'f_failure')::integer -- тип ограничения left join dbo.es_restrictions as er on er.id = (cr.jb_data ->> 'f_restriction')::integer -- последний прибор на дату left join lateral ( select ed.f_registr_pts, ed.c_serial_number, nullif(ed.imp_text, '') as f_device, ed.id as f_device_guid, row_number() over(partition by ed.f_registr_pts order by ed.d_setup_date desc, ed.d_close_date desc) as n_row from dbo.ed_devices as ed where 1=1 and ed.f_registr_pts = cp.f_registr_pts and (ed.d_setup_date is null or ed.d_setup_date < cr.d_date) and (ed.d_close_date is null or ed.d_close_date >= cr.d_date) ) as ed on 1=1 and ed.n_row = 1 where 1=1 and cr.b_check and p.g_session_id = _session_id; end; -- приборы begin insert into imp.e_devices( f_docout , --идентификатор документа f_device , --код/идентификатор пу c_serial_number , --заводской номер d_close_date , --дата снятия существующего пу f_device_tn , --код/идентификатор тн c_serial_number_tn , --заводской номер тн d_close_date_tn , --дата снятия существующего тн f_device_tt , --код/идентификатор тт c_serial_number_tt , --заводской номер тт d_close_date_tt , --дата снятия существующего тт --f_device_new , --код/идентификатор нового пу d_setup_date , --дата установки нового пу c_serial_number_new , --заводской номер f_device_type , c_device_type , --наименование модели c_device_location_type , --место установки b_phase3 , --фазность трехфазный прибор 0 - нет 1 - да f_time_zone , --тариф f_energy_type , --f_scale , --шкала n_device_mpi , --мпи (число лет) d_release_date , --год выпуска d_verification_date , --дата поверки пу f_device_tn_new , --код/идентификатор нового тн d_setup_date_tn , --дата установки нового тн c_serial_number_tn_new , --заводской номер тн f_device_type_tn , c_device_type_tn , --наименование модели тн c_phase_tn_new , --фаза n_device_mpi_tn , --мпи (число лет) d_release_date_tn , --год выпуска d_verification_date_tn , --дата поверки пу n_tt1_tn , --номинальное напряжение первичной обмотки, в n_tt2_tn , --номинальное напряжение вторичной обмотки, в f_device_tt_new , --код/идентификатор тт d_setup_date_tt , --дата установки тт (новый) c_serial_number_tt_new , --заводской номер тт f_device_type_tt , c_device_type_tt , --наименование типа c_phase_tt_new , --фаза n_device_mpi_tt , --мпи (число лет) d_release_date_tt , --год выпуска d_verification_date_tt , --дата поверки пу n_tt1_tt , --номинальный ток первичной обмотки, а n_tt2_tt , --номинальный ток вторичной обмотки, а g_session_id --идентификатор сессии экспорта ) select DISTINCT cr.id as f_docout, er.f_device as f_device, coalesce(ed.c_serial_number, cp.jb_data ->> 'c_device_number') as c_serial_number, case when rt.c_const = 'AZPU' then cr.d_date else ed.d_close_date end as d_close_date, -- будем считать что дата акта и есть дата снятия старого ПУ tn.f_device_tn as f_device_tn, tn.c_serial_number_tn as c_serial_number_tn, tn.d_close_date_tn as d_close_date_tn, tt.f_device_tt as f_device_tt, tt.c_serial_number_tt as c_serial_number_tt, tt.d_close_date_tt as d_close_date_tt, --case when rt.c_const in ('ADEPU', 'AZPU') then edn.id end -- as f_device_new, case when rt.c_const in ('AM', 'ADEPU', 'AZPU') then cr.d_date end as d_setup_date, --будем считать что дата акта и есть дата установки нового ПУ cr.jb_data ->> 'c_device_number' as c_serial_number_new, edn.f_device_type as f_device_type, cr.jb_data ->> 'c_device_model' as c_device_type, --cr.jb_data ->> 'c_device_location' as c_device_location_type, edl.id as c_device_location_type, edt.b_phase3::int4 as b_phase3, (cr.jb_data ->> 'f_tariff_zone')::int4 as f_time_zone, null::text as f_energy_type, --cr.jb_data ->> 'c_tariff_zone' as f_scale, edt.n_check_cycle as n_device_mpi, (cr.jb_data ->> 'n_year')::int4 as d_release_date, (cr.jb_data ->> 'd_check_date')::date as d_verification_date, tn.f_device_tn_new as f_device_tn_new , tn.d_setup_date_tn as d_setup_date_tn , tn.c_serial_number_tn_new as c_serial_number_tn_new , tn.f_device_type_tn as f_device_type_tn , tn.c_device_type_tn as c_device_type_tn , tn.c_phase_tn_new as c_phase_tn_new , tn.n_device_mpi_tn as n_device_mpi_tn , tn.d_release_date_tn as d_release_date_tn , tn.d_verification_date_tn as d_verification_date_tn , tn.n_tt1_tn as n_tt1_tn , tn.n_tt2_tn as n_tt2_tn , tt.f_device_tt_new as f_device_tt_new , tt.d_setup_date_tt as d_setup_date_tt , tt.c_serial_number_tt_new as c_serial_number_tt_new , tt.f_device_type_tt as f_device_type_tt , tt.c_device_type_tt as c_device_type_tt , tt.c_phase_tt_new as c_phase_tt_new , tt.n_device_mpi_tt as n_device_mpi_tt , tt.d_release_date_tt as d_release_date_tt , tt.d_verification_date_tt as d_verification_date_tt , tt.n_tt1_tt as n_tt1_tt , tt.n_tt2_tt as n_tt2_tt , _session_id as g_session_id from imp.e_points as p -- точки inner join core.cd_points as cp on cp.id = p.f_doc_detail -- результат inner join core.cd_results as cr on cr.fn_point = p.f_doc_detail inner join imp.e_results as er on er.g_session_id = p.g_session_id and er.f_doc_detail = p.f_doc_detail and er.f_docout = cr.id -- тип документа inner join core.cs_result_types as rt on rt.id = cr.fn_type -- трансформатор тока left join ( select tnew.fn_result, -- док tnew.fn_phase, tnew.id::text as f_device_tt_new, tnew.d_date as d_setup_date_tt, tnew.c_number as c_serial_number_tt_new, edt.id as f_device_type_tt, edt.c_name as c_device_type_tt, ep.id::text as c_phase_tt_new, edt.n_check_cycle as n_device_mpi_tt, tnew.n_year as d_release_date_tt, tnew.d_date_check as d_verification_date_tt, edt.n_tt1 as n_tt1_tt, edt.n_tt2 as n_tt2_tt, told.c_serial_number as c_serial_number_tt, told.d_replace_date as d_close_date_tt, coalesce(told.imp_text, told.id::text) as f_device_tt from dbo.ed_output_transformers as tnew inner join dbo.es_device_types as edt on edt.id = tnew.fn_device_type -- предыдущий трансформер left join dbo.ed_transformers as told on told.id = tnew.fn_transformer -- фаза left join dbo.es_phase as ep on ep.id = tnew.fn_phase where tnew.b_voltage = false -- трансформатор тока ) as tt on tt.fn_result = cr.id -- трансформатор напряжения left join ( select tnew.fn_result, -- док tnew.fn_phase, tnew.id::text as f_device_tn_new, tnew.d_date as d_setup_date_tn, tnew.c_number as c_serial_number_tn_new, edt.id as f_device_type_tn, edt.c_name as c_device_type_tn, ep.id::text as c_phase_tn_new, edt.n_check_cycle as n_device_mpi_tn, tnew.n_year as d_release_date_tn, tnew.d_date_check as d_verification_date_tn, edt.n_tt1 as n_tt1_tn, edt.n_tt2 as n_tt2_tn, told.c_serial_number as c_serial_number_tn, told.d_replace_date as d_close_date_tn, coalesce(told.imp_text, told.id::text) as f_device_tn from dbo.ed_output_transformers as tnew inner join dbo.es_device_types as edt on edt.id = tnew.fn_device_type -- предыдущий трансформер left join dbo.ed_transformers as told on told.id = tnew.fn_transformer -- фаза left join dbo.es_phase as ep on ep.id = tnew.fn_phase where tnew.b_voltage = true -- трансформатор напряжения ) as tn on tn.fn_result = cr.id and tn.fn_phase = tt.fn_phase -- тип устанавливаемого ПУ left join dbo.es_device_types as edt on edt.id = (cr.jb_data ->> 'f_device_model')::int4 -- последний прибор, если вдруг не заполнено в результатах left join dbo.ed_devices as ed on ed.id = er.f_device_guid -- новый прибор left join dbo.ed_devices as edn on 1=1 and edn.f_registr_pts = cp.f_registr_pts and edn.d_setup_date = cr.d_date left join dbo.es_device_location as edl on edl.id = (cr.jb_data ->> 'f_device_location')::integer where 1=1 and p.g_session_id = _session_id and coalesce(edn.id, ed.id) is not null; --and rt.c_const in ('ADEPU', 'AZPU'); end; -- показания begin insert into imp.e_readings ( id , f_doc_detail , -- идентификатор строки f_device , -- ид ПУ из внешней УС f_device_new , -- ид ПУ из МК c_serial_number , -- заводской номер f_energy_type , -- вид измерения c_time_zone , -- тариф --c_scale , -- шкала d_date , -- дата показания n_value , -- значение показания f_delivery_method , b_cross_null , f_docout , g_session_id -- идентификатор сессии экспорта ) select r.id as id , max(f_doc_detail ) as f_doc_detail , max(f_device ) as f_device , max(f_device_new ) as f_device_new , max(c_serial_number ) as c_serial_number , max(f_energy_type ) as f_energy_type , max(c_time_zone ) as c_time_zone , max(d_date ) as d_date , max(n_value ) as n_value , max(f_delivery_method ) as f_delivery_method , max(b_cross_null ) as b_cross_null , max(f_docout ) as f_docout , _session_id as g_session_id from ( select imr.id as id , r.f_doc_detail as f_doc_detail , r.f_device as f_device , imr.f_device as f_device_new , coalesce(ed.c_serial_number, cr.jb_data ->> 'c_device_number') as c_serial_number , coalesce(et.c_code_out, es.c_code_out, et.c_name) as f_energy_type , coalesce(es.c_code_out, tz.c_name) as c_time_zone , --coalesce(es.c_code_out, es.c_name) as c_scale , emr.d_date::date as d_date , emr.n_value as n_value , 2 as f_delivery_method , 0 as b_cross_null , r.f_docout from imp.e_results as r --показания inner join dbo.ed_output_meter_readings as emr on emr.fn_point = r.f_doc_detail inner join dbo.ed_input_meter_readings as imr on imr.id = emr.fn_meter_reading -- результат inner join core.cd_results as cr --on cr.fn_point = r.f_doc_detail on cr.id = r.f_docout -- тарифная зона left join dbo.es_tariff_zones as tz on tz.id = imr.f_tariff_zone -- врем зона left join dbo.es_scales as es on es.id = imr.f_scale -- вид энергии left join dbo.es_energy_types as et on et.id = imr.f_energy_type -- последний прибор left join dbo.ed_devices as ed on ed.id = r.f_device_guid where 1=1 and r.g_session_id = _session_id and abs(emr.n_value) > 0 ) as r group by r.id; end; begin insert into imp.e_seals ( id , f_doc_detail , -- идентификатор строки f_docout , -- идентификатор документа f_seal , -- код/идентификатор пломбы f_registr_pts , f_seal_mk , f_device , -- код/идентификатор пу c_seal_number_prefix , -- Номер установленной пломбы (префикс) c_seal_number , -- № пломбы состоит из префикса и номера f_seal_type , -- тип пломбы c_seal_location , -- место установки пломбы d_seal_close_date , -- дата снятия пломбы d_seal_setup_date , -- дата установки пломбы g_session_id ) select id , MAX(f_doc_detail ) AS f_doc_detail , MAX(f_docout ) AS f_docout , MAX(f_seal ) AS f_seal , MAX(f_registr_pts ) AS f_registr_pts , MAX(f_seal_mk ) AS f_seal_mk , MAX(f_device ) AS f_device , MAX(c_seal_number_prefix) AS c_seal_number_prefix, MAX(c_seal_number ) AS c_seal_number , MAX(f_seal_type ) AS f_seal_type , MAX(c_seal_location ) AS c_seal_location , MAX(d_seal_close_date ) AS d_seal_close_date , MAX(d_seal_setup_date ) AS d_seal_setup_date , _session_id as g_session_id from ( select coalesce(esn.id, es.id) as id, r.f_doc_detail as f_doc_detail , r.f_docout as f_docout , es.imp_int::text as f_seal , r.f_registr_pts as f_registr_pts , esn.id::text as f_seal_mk , r.f_device as f_device , esn.c_prefix as c_seal_number_prefix , -- сделать настраиваемо esn.c_number as c_seal_number , coalesce(est.c_const, est.id::text, est.c_name) as f_seal_type , coalesce(esp.c_const, espD.c_const, esp.id::text, esp.c_name) as c_seal_location , esn.d_replace_date as d_seal_close_date , ocs.d_date as d_seal_setup_date from imp.e_results as r --пломбы inner join dbo.ed_output_conn_seals as ocs on ocs.fn_point = r.f_doc_detail -- старая пломба left join dbo.ed_seals as es on es.id = ocs.fn_seal -- новая пломба left join dbo.ed_seals as esn on esn.id = ocs.fn_seal_new -- тип пломбы left join dbo.es_seal_types as est on est.id = esn.f_type -- место установки пломбы left join dbo.es_seal_places as esp on esp.id = esn.f_place -- место по-умолчанию left join dbo.es_seal_places as espD on espD.c_const = 'ZISU_PLOMB_20' where 1=1 and r.g_session_id = _session_id and coalesce(es.id, esn.id) is not null ) as r group by r.id; end; -- фотокарточки begin insert into imp.e_photos ( id , f_docout , -- идентификатор документа f_device , c_photo , -- ссылка на фотографию c_type_photo , -- тип фотографии c_note_photo , -- комментарий к фотографии g_session_id ) select cf.id as id, r.f_docout as f_docout, r.f_device as f_device, concat(cs.c_value, '/file?id=', cf.id::text) as c_photo, coalesce(cat.n_code::text, cat.c_name) as c_type_photo, ca.c_notice as c_note_photo, _session_id as g_session_id from imp.e_results as r -- вложение inner join core.cd_attachments as ca on ca.fn_result = r.f_docout -- тип вложения inner join core.cs_attachment_types as cat on cat.id = ca.fn_type -- файл inner join core.cd_files as cf on cf.id = ca.fn_file inner join core.cd_settings as cs on cs.c_key = 'ALL_URL' where 1=1 and r.g_session_id = _session_id ; end; -- сообщение об успешности update imp.i_integration_sessions set status = 'Success', finishdate = now() where sessionid = _session_id; -- обработка ошибок exception when others then GET STACKED DIAGNOSTICS _message_text = MESSAGE_TEXT; end; if _message_text is not null then update imp.i_integration_sessions set status = 'Fail', finishdate = now(), parameters = concat(parameters, '. Текст ошибки: ', _message_text) where sessionid = _session_id; end if; END;
Обработка буферов импорта
DECLARE _f_division int; _f_subdivision int; _rec record; _count_subscr int = 0; -- кол-во вставленных ЛС _count_tu int = 0; -- кол-во вставленных ТУ _count_pu int = 0; -- кол-во вставленных ПУ _count_tr int = 0; -- кол-во вставленных Трансформаторов _count_seals int = 0; -- кол-во вставленных Пломб _count_readings int = 0; -- кол-во вставленных Показаний _count_address int = 0; -- кол-во адресов _startTime timestamptz; -- время начала _endTime timestamptz; _delta double precision; _message_text text; BEGIN -- Филиал - Общий ПЭС - РЭС create temp table t_div ( f_maindivision text, f_maindivision_code text, f_division text, f_division_code text, f_subdivision text, f_subdivision_code text ) on commit drop; insert into t_div ( f_maindivision, f_maindivision_code, f_division, f_division_code, f_subdivision, f_subdivision_code ) select MAX(f_maindivision), f_maindivision_code, MAX(f_division), f_division_code, MAX(f_subdivision), f_subndivision_code from ( select f_maindivision, f_maindivision_code, f_division, f_division_code, f_subdivision, f_subndivision_code from imp.i_tu_ul itu where 1=1 and ( itu.g_session_id = _session_id or _session_id is null) and itu.f_subndivision_code is not NULL and itu.f_subdivision is not NULL union select f_maindivision, f_maindivision_code, f_division, f_division_code, f_subdivision, f_subndivision_code from imp.i_tu_fl itu where 1=1 and ( itu.g_session_id = _session_id or _session_id is null) and itu.f_subndivision_code is not NULL and itu.f_subdivision is not NULL ) as d --where f_subndivision_code = '4400R022' group by f_maindivision_code, f_division_code, f_subndivision_code ; -- логирование insert into imp.i_integration_sessions( sessionId , startTime , status , parameters ) select _session_id as sessionId, now() as startTime, 'Операция запущена' as status, 'Перенос НСИ из ВБ в таблицы.' as parameters on conflict on CONSTRAINT i_integration_sessions_pkey do update set parameters = concat(imp.i_integration_sessions.parameters, ' ', excluded.parameters) ; -- витрины для буферов -- ТУ create temp table t_tu( id uuid primary key, f_div int, f_maindivision text, f_maindivision_code text, f_division text, f_division_code text, f_subdiv int, f_subdivision text, f_subndivision_code text, f_partners text, c_name_consumer text, c_code text, f_check_date int4, c_telephone text, b_person bool, b_problem_person int4, f_registr_pts text, c_registr_pts text, c_substation text, c_line_substation text, c_tp text, c_line_tp text, c_line_tp_1 text, c_line_segment text, c_status_registr_pts text, d_close_date date, c_status_consume text, b_technical_metering int4, c_status text, c_status_value text, c_predictr text, d_restriction_date date NULL, c_restriction_method text NULL, c_network_pts_code text NULL, n_max_cap integer NULL, b_sub bool not null default false, b_transit bool not null default false, row_num int ) on commit drop; -- КА create temp table if not exists t_subscr ( id uuid, f_division int, f_subdivision int, f_registr_pts_text text, f_registr_pts uuid, f_partners text, c_name1 text, c_name2 text , c_name3 text , c_telephone text , c_code text , b_person bool , f_check_date int, dense_rnk int, f_subscr uuid ) on commit drop; -- ПУ create temp table t_pu( id uuid, f_device text, f_registr_pts uuid, f_registr_pts_text text, c_serial_number text, c_device_type text, b_phase3 bool, f_device_location_type text, f_time_zone text, f_energy_type text, c_digits numeric(5,2), d_replace_before text, c_askue text, b_askue bool, d_setup_date date, d_close_date date, f_device_type int, row_num int ) on commit drop; -- трансформаторы create temp table t_tr( id uuid, f_maindivision_code text, f_registr_pts uuid, f_registr_pts_text text, f_device_t text, b_voltage bool, c_serial_number_t text, d_replace_before date, c_device_type_t text, c_phase text, n_tt1_t numeric(9,3), n_tt2_t numeric(9,3), d_setup_date_t date, d_close_date_t date, f_device_type int, row_num int ) on commit drop; -- пломюы create temp table t_seals( id uuid, f_registr_pts_text text, f_seal text, c_seal_number text, c_seal_prefix text, f_seal_type text, f_seal_location text, f_registr_pts uuid, f_type int, f_place int ) on commit drop; -- показания create temp table t_readings( id uuid, f_registr_pts uuid, f_registr_pts_text text, f_energy_type text, f_time_zone text, f_scale text, d_date date, n_value numeric(19,6), f_delivery_methods text ) on commit drop; -- определяем типы ПУ и соханяем при необхолимости новые create temp table if not exists t_pu_type ( id uuid default uuid_generate_v4(), f_device_categories int, c_device_type text, b_phase3 bool, f_tariff_zone int, n_tariff int, n_digits numeric(5, 2), type_id int ) on commit drop; create temp table if not exists t_address ( id uuid, dns_rnk int, row_num int, f_registr_pts text, f_kladr text, c_name text, c_index text, c_region text, code_fias_region text, c_raion text, data_area_fias_id text, c_сity_name text, data_city_fias_id text, c_settlement_name text, settlement_fias_id text, c_street_name text, data_street_fias_id text, c_house_name text, data_house_fias_id text, c_block_name text, c_flat_name text, n_fias_level int, n_geo_lat numeric(19, 6), n_geo_lon numeric(19, 6), qc_geo int, f_address uuid, f_conn_points text, c_name_obj text ) on commit drop; for _rec in select d.f_maindivision_code, d.f_maindivision, sd.id as f_main_id, sd1.id as f_div_id, d.f_division_code, d.f_division, d.f_subdivision_code, d.f_subdivision, ss.id as f_sub_id from t_div as d left join core.sd_divisions sd on sd.c_dep_code = d.f_maindivision_code left join core.sd_divisions sd1 on sd1.f_division = sd.id and ( sd1.c_dep_code = d.f_division_code or d.f_division_code is null) left join core.sd_subdivisions ss on ss.c_dep_code = d.f_subdivision_code loop -- id отделения if _rec.f_main_id is not null then if _rec.f_div_id is not null then _f_division = _rec.f_div_id; else insert into core.sd_divisions (f_division, c_name, c_dep_code) values(_rec.f_main_id, coalesce(_rec.f_division, 'Общий'), _rec.f_division_code) returning id into _f_division; end if; else if not exists (select 1 from core.sd_divisions where c_dep_code = _rec.f_maindivision_code) then -- филиал insert into core.sd_divisions (c_name, c_dep_code) values(_rec.f_maindivision, _rec.f_maindivision_code) returning id into _f_division; -- общий ПЭС insert into core.sd_divisions (f_division, c_name, c_dep_code) values(_f_division, coalesce(_rec.f_division, 'Общий'), _rec.f_division_code) returning id into _f_division; end if; end if; -- id участка if _rec.f_sub_id is not null then _f_subdivision = _rec.f_sub_id; else insert into core.sd_subdivisions (f_division, c_name, c_dep_code) values(_f_division, _rec.f_subdivision, _rec.f_subdivision_code) returning id into _f_subdivision; end if; -- теперь по каждому РЭС обрабатываем буферные таблицы begin raise notice 'Зона: %, %, %, %, %, %', _f_division, _rec.f_maindivision_code, _rec.f_maindivision, _f_subdivision, _rec.f_subdivision_code, _rec.f_subdivision; --- /*1. ТУ */ --- _starttime := clock_timestamp(); insert into t_tu( id, f_div, f_maindivision, f_maindivision_code, f_division, f_division_code, f_subdiv, f_subdivision, f_subndivision_code, f_partners, c_name_consumer, c_code, f_check_date, c_telephone, b_person, b_problem_person, f_registr_pts, c_registr_pts, c_substation, c_line_substation, c_tp, c_line_tp, c_line_tp_1, c_line_segment, c_status_registr_pts, d_close_date, c_status_consume, b_technical_metering, c_status, c_status_value, c_predictr, d_restriction_date, c_restriction_method, c_network_pts_code, n_max_cap, b_sub, b_transit ) select uuid_generate_v4(), _f_division, ul.f_maindivision, ul.f_maindivision_code, ul.f_division, ul.f_division_code, _f_subdivision, ul.f_subdivision, ul.f_subndivision_code, ul.f_partners, ul.c_name_consumer, ul.c_code, ul.f_check_date, ul.c_telephone, false, ul.b_problem_person, ul.f_registr_pts, ul.c_registr_pts, ul.c_substation, ul.c_line_substation, ul.c_tp, ul.c_line_tp, ul.c_line_tp_1, ul.c_line_segment, ul.c_status_registr_pts, ul.d_close_date, ul.c_status_consume, ul.b_technical_metering, ul.c_status, ul.c_status_value, ul.c_predictr, ul.d_restriction_date, ul.c_restriction_method, ul.c_network_pts_code, ul.n_max_cap, coalesce(ul.b_sub, False), coalesce(ul.b_transit, False) from imp.i_tu_ul ul where ul.f_maindivision_code = _rec.f_maindivision_code and ul.f_subndivision_code = _rec.f_subdivision_code and ( ul.g_session_id = _session_id or _session_id is null) ; insert into t_tu( id, f_div, f_maindivision, f_maindivision_code, f_division, f_division_code, f_subdiv, f_subdivision, f_subndivision_code, f_partners, c_name_consumer, c_code, c_telephone, b_person, b_problem_person, f_registr_pts, c_registr_pts, c_substation, c_line_substation, c_tp, c_line_tp, c_line_tp_1, c_line_segment, c_status_registr_pts, d_close_date, c_status_consume, b_technical_metering, c_status, c_status_value, c_predictr, d_restriction_date, c_restriction_method, c_network_pts_code, n_max_cap, b_sub, b_transit ) select uuid_generate_v4(), _f_division, fl.f_maindivision, fl.f_maindivision_code, fl.f_division, fl.f_division_code, _f_subdivision, fl.f_subdivision, fl.f_subndivision_code, fl.f_partners, fl.c_name_consumer, fl.c_code, fl.c_telephone, true, fl.b_problem_person, fl.f_registr_pts, fl.c_registr_pts, fl.c_substation, fl.c_line_substation, fl.c_tp, fl.c_line_tp, fl.c_line_tp_1, fl.c_line_segment, fl.c_status_registr_pts, fl.d_close_date, fl.c_status_consume, fl.b_technical_metering, fl.c_status, fl.c_status_value, fl.c_predictr, fl.d_restriction_date, fl.c_restriction_method, fl.c_network_pts_code, fl.n_max_cap, coalesce(fl.b_sub, False), coalesce(fl.b_transit, False) from imp.i_tu_fl fl where fl.f_maindivision_code = _rec.f_maindivision_code and fl.f_subndivision_code = _rec.f_subdivision_code and ( fl.g_session_id = _session_id or _session_id is null); update t_tu as t0 set row_num = t.row_num from ( select t.id, row_number() over (partition by t.f_registr_pts order by t.id) as row_num from t_tu as t ) as t where t0.id = t.id; delete from t_tu where row_num > 1; update t_tu as t set id = erp.id from dbo.ed_registr_pts erp where erp.f_division = _f_division and erp.f_subdivision = _f_subdivision and LPAD(erp.imp_text, 36, '0') = LPAD(t.f_registr_pts, 36, '0'); -- справочник статусов update t_tu as t0 set c_status_consume = ( select esc.id from dbo.es_status_consume as esc where esc.n_code = case when t0.c_status_consume ~ '^[0-9\.]+$' = true then t0.c_status_consume::float::integer end order by esc.id desc limit 1 ) where c_status_consume is not null; -- справочник статусов update t_tu as t0 set c_status_registr_pts = ( select esc.id from dbo.es_registr_pts_status as esc where esc.id = case when t0.c_status_registr_pts ~ '^[0-9\.]+$' = true then t0.c_status_registr_pts::float::integer end or esc.c_name = t0.c_status_registr_pts order by esc.id desc limit 1 ) where c_status_registr_pts is not null; --- /*2. КА */ --- insert into t_subscr ( id, f_division, f_subdivision, f_registr_pts_text, f_registr_pts, f_partners, c_name1, c_name2 , c_name3 , c_telephone , c_code , b_person , f_check_date, dense_rnk ) select coalesce(erp.f_subscr, uuid_generate_v4()) as id, _f_division as f_division, _f_subdivision as f_subdivision, s.f_registr_pts as f_registr_pts_text, s.id as f_registr_pts, s.f_partners, case when s.b_person then split_part(s.c_name_consumer, ' ', 1) else s.c_name_consumer end c_name1, case when s.b_person then split_part(s.c_name_consumer, ' ', 2) end c_name2, case when s.b_person then split_part(s.c_name_consumer, ' ', 3) end c_name3, s.c_telephone, s.c_code, s.b_person, s.f_check_date, dense_rank () over (order by c_code, c_name_consumer) from t_tu as s left join dbo.ed_registr_pts as erp on erp.id = s.id; --- /*3. ПУ */ --- insert into t_pu( id, f_device, f_registr_pts_text, c_serial_number, c_device_type, b_phase3, f_device_location_type, f_time_zone, f_energy_type, c_digits, d_replace_before, c_askue, b_askue, d_setup_date, d_close_date, row_num ) select coalesce(ed.id, uuid_generate_v4()) as id, p.f_device, p.f_registr_pts as f_registr_pts_text, p.c_serial_number as c_serial_number, p.c_device_type, case p.b_phase3 when 3 then true else false end b_phase3, p.c_device_location_type, p.f_time_zone_1_1, p.f_energy_type_1, trunc(case when p.c_digits = 10 then 9.0 when ceil(log(nullif(p.c_digits, 0))) >= 1 then p.c_digits / (power(10, ceil(log(nullif(p.c_digits, 0)))-1)) else p.c_digits end, 1) as c_digits, p.d_replace_before, p.c_askue, p.b_askue::bool, p.d_setup_date, p.d_close_date, row_number() over(partition by p.f_registr_pts, p.f_device, p.f_energy_type_1, p.f_time_zone_1_1) AS row_num from imp.i_pu p inner join t_tu as t on t.f_div = _f_division and t.f_subdiv = _f_subdivision and t.f_registr_pts = p.f_registr_pts and t.f_maindivision_code = p.f_maindivision_code left join dbo.ed_devices ed on LPAD(ed.imp_text, 36, '0') = LPAD(p.f_device::text, 36, '0') and ed.f_registr_pts = t.id where p.g_session_id = g_session_id or _session_id is null; delete from t_pu where row_num > 1; -- Привязка ПУ к ТУ update t_pu p0 set f_registr_pts = t.id from t_tu t where p0.f_registr_pts_text = t.f_registr_pts; -- по каждому виду энергии ожидается отдельная строка, поэтому итоговый результат надо группировать без вида энергии -- так же надо отобрать уникальные тарифы в разрезе ПУ для определения типа ПУ (тарифность, временные зоны) -- СТРУКТУРА может измениться, нужно будет актуализировать insert into t_pu_type ( f_device_categories, c_device_type, b_phase3, f_tariff_zone, n_tariff, n_digits) select distinct 1 as f_device_categories, t.c_device_type, t.b_phase3 , t.n_tariff as f_tariff_zone, t.n_tariff as n_tariff, t.c_digits as n_digits from ( select id, count(*) over (partition by f_registr_pts, f_device, f_energy_type) as n_tariff, c_device_type, c_digits, b_phase3 from t_pu t ) as t; update t_pu_type set f_tariff_zone = 3 where f_tariff_zone > 3; -- Сопоставление с существующими справочниками update t_pu_type t0 set type_id = edt.id from t_pu_type t inner join dbo.es_device_types edt on coalesce(edt.c_name, '-') = coalesce(c_device_type, '-') and coalesce(edt.n_digits, -1) = coalesce(t.n_digits, -1) and edt.b_phase3 = t.b_phase3 and edt.f_tariff_zone = t.f_tariff_zone and not edt.b_disabled and edt.f_device_categories = 1 where t0.id = t.id; --Добавление новых записей и привязка with t_new_type as ( insert into dbo.es_device_types( f_device_categories, c_name, b_phase3, f_tariff_zone, n_tariff, n_digits, b_disabled) select 1, pt.c_device_type, pt.b_phase3, pt.f_tariff_zone, pt.n_tariff, pt.n_digits, false from t_pu_type as pt where type_id is null returning id, c_name, n_digits, b_phase3, f_tariff_zone ) update t_pu_type t set type_id = n.id from t_new_type n where t.type_id is null and coalesce(n.c_name, '-') = coalesce(c_device_type, '-') and coalesce(n.n_digits, -1) = coalesce(t.n_digits, -1) and coalesce(n.b_phase3, false) = coalesce(t.b_phase3, false) and n.f_tariff_zone = t.f_tariff_zone; -- простановка типов ПУ в витрине update t_pu p set f_device_type = pt.type_id from ( select id, count(*) over (partition by f_device, f_energy_type) as n_tariff, c_device_type, c_digits, b_phase3 from t_pu t ) as pp inner join t_pu_type pt on coalesce(pt.c_device_type, '-') = coalesce(pp.c_device_type, '-') and coalesce(pt.n_digits, -1) = coalesce(pp.c_digits, -1) and coalesce(pt.b_phase3, false) = coalesce(pp.b_phase3, false) and pt.f_tariff_zone = pp.n_tariff where pp.id = p.id; delete from t_pu where id in ( select id from ( select t.id, row_number() over(partition by f_registr_pts, f_device_type, c_serial_number , d_setup_date order by id ) as n_row from t_pu as t ) as t where n_row > 1 ); delete from t_pu where id in ( select t.id from ( select t.id, row_number() over(partition by t.id order by t.d_setup_date desc) as n_row from t_pu as t ) as t where t.n_row > 1 ); --- /*4. Трансформаторы */ --- insert into t_tr( id, f_device_t, f_registr_pts, f_registr_pts_text, b_voltage, c_serial_number_t, d_replace_before, c_device_type_t, c_phase, n_tt1_t, n_tt2_t, d_setup_date_t, d_close_date_t, row_num ) select coalesce(et.id, uuid_generate_v4()) as id, itt.f_device_tt as f_device_t, null::uuid as f_registr_pts, itt.f_registr_pts as f_registr_pts_text, false as b_voltage, itt.c_serial_number_tt as c_serial_number_t, itt.d_replace_before, itt.c_device_type_tt as c_device_type_text, itt.c_phase, itt.n_tt1_tt as n_tt1_t, itt.n_tt2_tt as n_tt2_t, itt.d_setup_date_tt as d_setup_date_t, itt.d_close_date_tt as d_close_date_t, row_number() over(partition by itt.f_registr_pts, coalesce(et.id::text, itt.f_device_tt) order by itt.id) as row_num from imp.i_tt itt inner join t_tu as t on t.f_div = _f_division and t.f_subdiv = _f_subdivision and t.f_registr_pts = itt.f_registr_pts and t.f_maindivision_code = itt.f_maindivision_code left join dbo.ed_transformers as et on LPAD(et.imp_text, 36, '0') = LPAD(itt.f_device_tt, 36, '0') and et.f_registr_pts = t.id where 1=1 and length(trim(itt.c_serial_number_tt)) > 0 and ( itt.g_session_id = _session_id or _session_id is null) union all select coalesce(et.id, uuid_generate_v4()) as id, itn.f_device_tn as f_device_t, null::uuid as f_registr_pts, itn.f_registr_pts as f_registr_pts_text, true as b_voltage, itn.c_serial_number_tn as c_serial_number_t, itn.d_replace_before, itn.c_device_type_tn as c_device_type_text, itn.c_phase, itn.n_tt1_tn as n_tt1_t, itn.n_tt2_tn as n_tt2_t, itn.d_setup_date_tn as d_setup_date_t, itn.d_close_date_tn as d_close_date_t, row_number() over(partition by itn.f_registr_pts, coalesce(et.id::text, itn.f_device_tn) order by itn.id) as row_num from imp.i_tn itn inner join t_tu as t on t.f_div = _f_division and t.f_subdiv = _f_subdivision and t.f_registr_pts = itn.f_registr_pts and t.f_maindivision_code = itn.f_maindivision_code left join dbo.ed_transformers as et on LPAD(et.imp_text, 36, '0') = LPAD(itn.f_device_tn, 36, '0') and et.f_registr_pts = t.id where 1=1 and length(trim(itn.c_serial_number_tn)) > 0 and ( itn.g_session_id = _session_id or _session_id is null); delete from t_tr where row_num > 1; -- привязка к ТУ update t_tr tr set f_registr_pts = t.id from t_tu t where t.f_registr_pts = tr.f_registr_pts_text; -- Существующие типы трансформаторов update t_tr t set f_device_type = edt.id from dbo.es_device_types edt where edt.c_name = t.c_device_type_t and (edt.n_tt1 = t.n_tt1_t or edt.n_tt1 is null and t.n_tt1_t is null) and (edt.n_tt2 = t.n_tt2_t or edt.n_tt2 is null and t.n_tt2_t is null); -- Определение новых типов транформаторов (5 - ТТ, 6 - ТН) with t_tr_types as ( insert into dbo.es_device_types (f_device_categories, c_name, n_tt1, n_tt2, b_disabled) select distinct case t.b_voltage when false then 5 else 6 end as f_device_categories, c_device_type_t, n_tt1_t, n_tt2_t, false from t_tr t where not exists (select 1 from dbo.es_device_types edt where edt.c_name = t.c_device_type_t and edt.n_tt1 = t.n_tt1_t and edt.n_tt2 = t.n_tt2_t) returning id, f_device_categories, c_name, n_tt1, n_tt2 ) update t_tr t set f_device_type = trt.id from t_tr_types trt where t.f_device_type is null and (trt.c_name = t.c_device_type_t or trt.c_name is null and t.c_device_type_t is null) and (trt.n_tt1 = t.n_tt1_t or trt.n_tt1 is null and t.n_tt1_t is null) and (trt.n_tt2 = t.n_tt2_t or trt.n_tt2 is null and t.n_tt2_t is null) and trt.f_device_categories = case t.b_voltage when false then 5 else 6 end ; --- /*5. Пломбы */ --- -- могут приходить в одной строке несколько пломб, разделенных черезх ; -- сохранение одиночных пломб + доп. обработка строк с перечисленными пломбами в одной строке (резделенных через ;) -- т.к. пломбы, типы и расположение могут перечисляться через ; , то раскладываем каждый элемент с номером пломбы, типом и расположением на отдельную строчку insert into t_seals( id, f_registr_pts_text, c_seal_number, f_seal_type, f_seal_location ) select case when a.nr = 1 then es.id else uuid_generate_v4() end as new_id, es.f_registr_pts as f_registr_pts_text, trim(a.elem) c_seal_number, coalesce(trim(b.elem) , split_part(es.f_seal_type , ';', 1)) as f_seal_type, -- если типов перечислено меньше, чем номеров пломб, то берем по-умолчанию первое значение coalesce(trim(c.elem) , split_part(es.f_seal_location , ';', 1)) as f_seal_location -- если местоположений перечислено меньше, чем номеров пломб, то берем по-умолчанию первое значение --row_number() over(partition by es.f_registr_pts, es.c_seal_number, es.c_seal_prefix, es.f_seal_type, es.f_seal_location order by es.id) AS dns_rnk from imp.i_seal es inner join t_tu as t on t.f_div = _f_division and t.f_subdiv = _f_subdivision and t.f_registr_pts = es.f_registr_pts and t.f_maindivision_code = es.f_maindivision_code left join lateral unnest(string_to_array(es.c_seal_number, ';')) with ordinality as a(elem, nr) on true left join lateral unnest(string_to_array(es.f_seal_type, ';')) with ordinality as b(elem, nr) on b.nr = a.nr left join lateral unnest(string_to_array(es.f_seal_location, ';')) with ordinality as c(elem, nr) on c.nr = a.nr where length(c_seal_number) > 0 and ( es.g_session_id = _session_id or _session_id is null); -- только для ЦиП -- типы пломб --/* with cte as ( select distinct f_seal_type as c_type from t_seals where f_seal_type is not NULL ) insert into dbo.es_seal_types (c_name, b_default, b_disabled) select c_type, false, false from cte cd where not exists ( select 1 from dbo.es_seal_types st where st.c_name = cd.c_type OR st.n_code = case when cd.c_type ~ '^[0-9\.]+$' = true then cd.c_type::float::integer end ); --*/ -- привязка типов пломб update t_seals es0 set f_type = ( select t.id from dbo.es_seal_types t where ( t.n_code = case when es0.f_seal_type ~ '^[0-9\.]+$' = true then es0.f_seal_type::float::integer end or t.c_const = es0.f_seal_type or t.c_name = es0.f_seal_type) and not t.b_disabled order by t.id desc limit 1 ) where es0.f_seal_type is not null; -- только для ЦиП пока -- типы расположения пломб --/* with cte as ( select distinct f_seal_location as c_place from t_seals where f_seal_location is not NULL ) insert into dbo.es_seal_places (c_name, b_default, b_disabled) select c_place, false, false from cte cd where not exists ( select 1 from dbo.es_seal_places st where st.c_name = cd.c_place or st.n_code = case when cd.c_place ~ '^[0-9\.]+$' = true then cd.c_place::float::integer end ); --*/ -- привязка расположения пломб update t_seals es0 set f_place = ( select t.id from dbo.es_seal_places t where (t.n_code = case when es0.f_seal_location ~ '^[0-9\.]+$' = true then es0.f_seal_location::float::integer end or t.c_const = es0.f_seal_location or t.c_name = es0.f_seal_location) and not t.b_disabled order by t.id desc limit 1 ) where es0.f_seal_location is not null; -- привязка к ТУ update t_seals t set f_registr_pts = tu.id from t_tu tu where tu.f_registr_pts = f_registr_pts_text ; -- привязка к существующим пломбам update t_seals t set id = ess.id from dbo.ed_seals as ess left join dbo.es_seal_types as est on est.b_default left join dbo.es_seal_places as esp on esp.b_default where 1=1 and ess.f_registr_pts = t.f_registr_pts and ess.c_number = t.c_seal_number and coalesce(ess.f_type, est.id) = coalesce(t.f_type, est.id) and coalesce(ess.f_place, esp.id) = coalesce(t.f_place, esp.id); delete from t_seals where id in ( select id from ( select t.id, row_number() over(partition by t.id) as n_row from t_seals as t ) as t where n_row > 1 ); --- /*6. Показания */ --- insert into t_readings( id, f_registr_pts_text, f_energy_type, f_time_zone, f_scale, d_date, n_value, f_delivery_methods ) select uuid_generate_v4(), ir.f_registr_pts as f_registr_pts_text, ir.f_energy_type, ir.f_time_zone, ir.f_scale, ir.d_date, ir.n_value, ir.f_delivery_methods from imp.i_readings ir inner join t_tu as t on t.f_div = _f_division and t.f_subdiv = _f_subdivision and t.f_registr_pts = ir.f_registr_pts and t.f_maindivision_code = ir.f_maindivision_code where 1=1 and ( ir.g_session_id = _session_id or _session_id is null); -- контрольные показания insert into t_readings( id, f_registr_pts_text, f_energy_type, f_time_zone, f_scale, d_date, n_value, f_delivery_methods ) select uuid_generate_v4(), ir.f_registr_pts as f_registr_pts_text, ir.f_energy_type, ir.f_time_zone, ir.f_scale, ir.d_date2, ir.n_value2, 2 from imp.i_readings ir inner join t_tu as t on t.f_div = _f_division and t.f_subdiv = _f_subdivision and t.f_registr_pts = ir.f_registr_pts and t.f_maindivision_code = ir.f_maindivision_code where 1=1 and ( ir.g_session_id = _session_id or _session_id is null) and ir.d_date2 is not null and ir.n_value2 is not null; -- TODO: переделать, дичь какая-то update t_readings t set f_scale = coalesce(es.id, esC.id, esS.id, esD.id) from t_readings tt -- по названию left join dbo.es_scales as es on lower(trim(tt.f_time_zone)) = lower(trim(es.c_name)) -- по коду left join dbo.es_scales as esC on esC.id = case when tt.f_time_zone ~ '^[0-9\.]+$' = true then tt.f_time_zone::float::integer end -- по коду САП left join dbo.es_scales as esS on esS.c_code_out = tt.f_time_zone inner join dbo.es_scales as esD on esD.b_default = true where tt.id = t.id; update t_readings t set f_time_zone = coalesce(etz.id, 1) from t_readings tt left join dbo.es_tariff_zones as etz on etz.id = case when tt.f_time_zone ~ '^[0-9\.]+$' = true then tt.f_time_zone::float::integer else 1 end where tt.id = t.id; update t_readings t set f_energy_type = coalesce(eet.id, eetC.id, eetD.id) from t_readings tt -- по названию left join dbo.es_energy_types as eet on eet.c_name = tt.f_energy_type -- по константе left join dbo.es_energy_types as eetC on eetC.c_const = tt.f_energy_type inner join dbo.es_energy_types as eetD on eetD.b_default = true where tt.id = t.id; update t_readings t set f_delivery_methods = coalesce(edm.id, edmm.id, edmD.id) from t_readings tt left join dbo.es_delivery_methods as edm on lower(tt.f_delivery_methods) like '%' || lower(edm.c_name) || '%' left join dbo.es_delivery_methods as edmm on edmm.id = case when tt.f_delivery_methods ~ '^[0-9\.]+$' = true then tt.f_delivery_methods::float::integer end inner join dbo.es_delivery_methods as edmD on edmD.b_default = true where tt.id = t.id; update t_readings r set f_registr_pts = t.id from t_tu t where t.f_registr_pts = r.f_registr_pts_text; update t_readings r set id = imr.id from dbo.ed_input_meter_readings AS imr where 1=1 and imr.f_registr_pts = r.f_registr_pts and imr.d_date_prev = r.d_date and imr.f_scale::text = r.f_scale and imr.f_energy_type::text = r.f_energy_type; delete from t_readings where id in ( select id from ( select t.id, row_number() over(partition by t.id) as n_row from t_readings as t ) as t where n_row > 1 ); -- типы энергий -- типы методов доставки -- шкалы? -- адреса begin -- Отбор адресов и генерация уидентификаторов для уникальных строк insert into t_address( id, f_address, row_num, f_registr_pts, f_kladr, c_name, c_index, --c_region, c_raion, c_сity_name, c_settlement_name, c_street_name, c_house_name, c_block_name, c_flat_name, n_geo_lat, n_geo_lon, f_conn_points, c_name_obj ) select uuid_generate_v4() as id, erp.f_address as f_address, row_number() over (partition by iau.c_address, iau.c_building_corp , iau.c_premise_number order by iau.f_registr_pts) as row_num, iau.f_registr_pts, coalesce(nullif(trim(iau.f_kladr), ''), iau.f_conn_points, iau.f_registr_pts) as f_kladr, coalesce(nullif(trim(iau.c_address), ''), iau.c_premise_name) as c_name, iau.c_index, iau.c_province, --iau.f_region, iau.c_town, iau.c_municipality, iau.c_street, iau.c_building_num, iau.c_building_corp, iau.c_premise_number, iau.c_latitude, iau.c_longitude, iau.f_conn_points, iau.c_name_obj from imp.i_addr_ul iau inner join t_tu as t on t.f_div = _f_division and t.f_subdiv = _f_subdivision and t.f_registr_pts = iau.f_registr_pts and t.f_maindivision_code = iau.f_maindivision_code left join dbo.ed_registr_pts as erp on erp.id = t.id where 1=1 --and length(c_address) > 0 and (iau.g_session_id = _session_id or _session_id is null); insert into t_address( id, f_address, row_num, f_registr_pts, f_kladr, c_name, c_index, --c_region, c_raion, c_сity_name, c_settlement_name, c_street_name, c_house_name, c_block_name, c_flat_name, n_geo_lat, n_geo_lon, f_conn_points, c_name_obj ) select uuid_generate_v4() as id, erp.f_address as f_address, row_number() over (partition by iau.c_address, iau.c_building_corp , iau.c_premise_number order by iau.f_registr_pts) as row_num, iau.f_registr_pts, coalesce(nullif(trim(iau.f_kladr), ''), iau.f_conn_points, iau.f_registr_pts) as f_kladr, coalesce(nullif(trim(iau.c_address), ''), iau.c_premise_name) as c_name, iau.c_index, iau.c_province, --iau.f_region, iau.c_town, iau.c_municipality, iau.c_street, iau.c_building_num, iau.c_building_corp, iau.c_premise_number, iau.c_latitude, iau.c_longitude, iau.f_conn_points, iau.c_name_obj from imp.i_addr_fl as iau inner join t_tu as t on t.f_div = _f_division and t.f_subdiv = _f_subdivision and t.f_registr_pts = iau.f_registr_pts and t.f_maindivision_code = iau.f_maindivision_code left join dbo.ed_registr_pts as erp on erp.id = t.id where 1=1 --and length(c_address) > 0 and ( iau.g_session_id = _session_id or _session_id is null); delete from t_address where coalesce(c_name, '') = ''; -- ранжирование update t_address as t0 set dns_rnk = tt.dns_rnk from t_address as t inner join ( select t.id, dense_rank() over (order by t.c_name, t.c_block_name , t.c_flat_name, f_kladr) as dns_rnk from t_address as t ) as tt on tt.id = t.id where t.id = t0.id ; with f_addr_uniq as ( select dns_rnk, uuid_generate_v4() as f_address -- уникальный адрес from ( select distinct dns_rnk from t_address t where t.f_address is null ) as t ) update t_address ta set f_address = t.f_address from f_addr_uniq t where ta.dns_rnk = t.dns_rnk and ta.f_address is null; --delete from t_address where row_num > 1; end; --- /*ФИНАЛ. Вставка/апдейт в реальные таблицы */ --- -- 1. select * from t_subscr -- КА -- 2. select * from t_tu -- ТУ -- 3. select * from t_pu -- ПУ -- 4. select * from t_tr -- Трансформаторы -- 5. select * from t_seals -- Пломбы -- 6. select * from t_readings -- Показания _count_subscr := _count_subscr + (SELECT COUNT(*) from t_subscr); _count_tu := _count_tu + (SELECT COUNT(*) from t_tu); _count_pu := _count_pu + (SELECT COUNT(*) from t_pu); _count_tr := _count_tr + (SELECT COUNT(*) from t_tr); _count_seals := _count_seals + (SELECT COUNT(*) from t_seals); _count_readings := _count_readings + (SELECT COUNT(*) from t_readings); _count_address := _count_address + (SELECT COUNT(*) from t_address); -- 2. select * from t_tu -- ТУ -- 3. select * from t_pu -- ПУ -- 4. select * from t_tr -- Трансформаторы -- 5. select * from t_seals -- Пломбы -- 6. select * from t_readings -- Показания -- вставка данных в реальные таблицы perform dbo.cf_process_imp_insert(); -- обработка ошибок exception when others then GET STACKED DIAGNOSTICS _message_text = MESSAGE_TEXT; end; _endTime := clock_timestamp(); _delta := 1000 * ( extract(epoch from _endTime) - extract(epoch from _startTime) ); RAISE NOTICE 'время=%', _delta; -- и по завершению очищаем truncate table t_tu; truncate table t_subscr; truncate table t_pu; truncate table t_pu_type; truncate table t_tr; truncate table t_seals; truncate table t_readings; truncate table t_address; end loop; if _message_text is not null then update imp.i_integration_sessions set status = concat(status || ',', 'TransferFail'), parameters = concat(parameters, '. Текст ошибки: ', _message_text) where sessionid = _session_id; RAISE NOTICE '%', _message_text; end if; raise notice 'подготовлено ЛС %, подготовлено ТУ %, подготовлено ПУ %, подготовлено трансформаторов %, подготовлено пломб %, подготовлено показаний %, подготовлено адресов %', _count_subscr, _count_tu, _count_pu, _count_tr, _count_seals, _count_readings, _count_address; return 0; -- ОК END;
Вставка результатов обработки буферов импорта
DECLARE _inserted_subscr int = 0; -- кол-во вставленных ЛС _inserted_tu int = 0; -- кол-во вставленных ТУ _inserted_pu int = 0; -- кол-во вставленных ПУ _inserted_tr int = 0; -- кол-во вставленных Трансформаторов _inserted_seals int = 0; -- кол-во вставленных Пломб _inserted_readings int = 0; -- кол-во вставленных Показаний _inserted_address int = 0; -- кол-во адресов BEGIN INSERT INTO dbo.sd_subscr ( id, f_division, f_subdivision, c_code, c_name1, c_name2, c_name3, c_telephone, b_problem_person, b_person, n_check_date, f_partners ) select ts.id, ts.f_division, ts.f_subdivision, max(ts.c_code), max(ts.c_name1), max(ts.c_name2), max(ts.c_name3), max(ts.c_telephone), false as b_problem_person, max(ts.b_person::int4)::bool, max(ts.f_check_date), max(ts.f_partners) from t_subscr as ts group by ts.id, ts.f_division, ts.f_subdivision on conflict on CONSTRAINT sd_subscr_pkey do update set c_code = excluded.c_code, c_name1 = excluded.c_name1, c_name2 = excluded.c_name2, c_name3 = excluded.c_name3, c_telephone = excluded.c_telephone, b_problem_person = false, b_person = excluded.b_person, n_check_date= excluded.n_check_date, f_partners = excluded.f_partners ; GET DIAGNOSTICS _inserted_subscr = ROW_COUNT; INSERT INTO dbo.ed_registr_pts ( id, f_division, f_subdivision, b_disabled, c_registr_pts, f_status_consume, b_technical_metering, c_substation, c_line_substation, --c_rp, --c_line_rp, c_tp, c_line_tp, c_line_segment, --f_violation, --d_violation_date, --d_date_before, f_subscr, --f_address, --f_subscr_int, --f_device_int, --imp_int, c_line_tp_1, --c_line_segment_1, imp_text, d_close_date, c_status_registr_pts, f_registr_pts_status, c_status, c_predictr, d_restriction_date, c_restriction_method, c_network_pts_code, n_max_cap, b_sub, b_transit ) SELECT tt.id, tt.f_div, tt.f_subdiv, false as b_disabled, tt.c_registr_pts, tt.c_status_consume::integer as f_status_consume, tt.b_technical_metering::bool, tt.c_substation, tt.c_line_substation, tt.c_tp, tt.c_line_tp, tt.c_line_segment, ts.id as f_subscr, tt.c_line_tp_1, tt.f_registr_pts, tt.d_close_date, tt.c_status_registr_pts, case when tt.c_status_registr_pts ~ '^[0-9\.]+$' = true then tt.c_status_registr_pts::float::integer end as f_registr_pts_status, tt.c_status, tt.c_predictr, tt.d_restriction_date, tt.c_restriction_method, tt.c_network_pts_code, tt.n_max_cap, tt.b_sub, tt.b_transit FROM t_tu as tt inner join t_subscr AS ts on ts.f_registr_pts = tt.id on conflict on CONSTRAINT ed_registr_pts_pkey do update set c_registr_pts = excluded.c_registr_pts, f_status_consume = excluded.f_status_consume, b_technical_metering = excluded.b_technical_metering, c_substation = excluded.c_substation, c_line_substation = excluded.c_line_substation, c_tp = excluded.c_tp, c_line_tp = excluded.c_line_tp, c_line_segment = excluded.c_line_segment, c_line_tp_1 = excluded.c_line_tp_1, d_close_date = excluded.d_close_date, c_status_registr_pts = excluded.c_status_registr_pts, f_registr_pts_status = excluded.f_registr_pts_status, c_status = excluded.c_status, c_predictr = excluded.c_predictr, d_restriction_date = excluded.d_restriction_date, c_restriction_method = excluded.c_restriction_method, c_network_pts_code = excluded.c_network_pts_code, n_max_cap = excluded.n_max_cap, b_sub = excluded.b_sub, b_transit = excluded.b_transit ; GET DIAGNOSTICS _inserted_tu = ROW_COUNT; INSERT INTO dbo.ed_devices ( id, --link, f_device_type, c_serial_number, --n_rate, --n_manufacture_year, d_setup_date, --d_valid_date, --f_device_location, --f_owner_type, --n_owner_type, c_device_location, --imp_int, f_registr_pts, imp_text, b_askue, d_close_date ) select distinct tp.id, tp.f_device_type, tp.c_serial_number, tp.d_setup_date, tp.f_device_location_type, tp.f_registr_pts, tp.f_device, tp.b_askue, tp.d_close_date from t_pu as tp on conflict on CONSTRAINT imp_ed_devices_pkey do update set f_device_type = excluded.f_device_type, c_serial_number = excluded.c_serial_number, d_setup_date = excluded.d_setup_date, c_device_location = excluded.c_device_location, b_askue = excluded.b_askue, d_close_date = excluded.d_close_date ; GET DIAGNOSTICS _inserted_pu = ROW_COUNT; update dbo.ed_devices set d_close_date = now() where id in ( select ed.id from dbo.ed_devices ed -- по точке учета есть прибор inner join (select f_registr_pts from t_pu group by f_registr_pts) as tt on tt.f_registr_pts = ed.f_registr_pts -- все приборы которые не вставляются сейчас left join t_pu as t on t.f_registr_pts = ed.f_registr_pts and t.id = ed.id where ed.d_close_date is NULL and t.id is NULL ); INSERT INTO dbo.ed_transformers ( id, f_registr_pts, b_voltage, c_serial_number, d_replace_before, c_phase, --imp_int, --n_manufacture_year, --d_check_date, d_replace_date, imp_text, f_device_type ) SELECT distinct tt.id, tt.f_registr_pts, tt.b_voltage, tt.c_serial_number_t, tt.d_replace_before, tt.c_phase, tt.d_close_date_t, tt.f_device_t, tt.f_device_type from t_tr as tt on conflict on CONSTRAINT ed_transformers_pkey do update set b_voltage = excluded.b_voltage, c_serial_number = excluded.c_serial_number, d_replace_before= excluded.d_replace_before, c_phase = excluded.c_phase, d_replace_date = excluded.d_replace_date, f_device_type = excluded.f_device_type ; GET DIAGNOSTICS _inserted_tr = ROW_COUNT; INSERT INTO dbo.ed_seals ( id, c_number, f_status, --f_user, f_registr_pts, c_prefix, --imp_int, --d_replace_date, --b_draft, --n_order, --jb_history, f_type, f_place ) select ts.id, ts.c_seal_number, est.id as f_status, ts.f_registr_pts, ts.c_seal_prefix, --ts.f_seal, ts.f_type, ts.f_place from t_seals AS ts inner join dbo.es_seal_status as est on est.c_const = 'REG' on conflict on constraint ed_seals_pkey do update set c_prefix = excluded.c_prefix, f_place = excluded.f_place ; GET DIAGNOSTICS _inserted_seals = ROW_COUNT; -- показания insert into dbo.ed_input_meter_readings ( id, n_value_prev, d_date_prev, --n_digit, f_scale, f_registr_pts, f_tariff_zone, f_energy_type, f_delivery_method ) SELECT tr.id, tr.n_value, tr.d_date, case when tr.f_scale ~ '^[0-9\.]+$' = true then tr.f_scale::integer else 2 end, tr.f_registr_pts, case when tr.f_time_zone ~ '^[0-9\.]+$' = true then tr.f_time_zone::integer else 1 end, case when tr.f_energy_type ~ '^[0-9\.]+$' = true then tr.f_energy_type::integer else 2 end, case when tr.f_delivery_methods ~ '^[0-9\.]+$' = true then tr.f_delivery_methods::integer else 1 end from t_readings AS tr on conflict on constraint ed_input_meter_readings_pkey do update set n_value_prev = excluded.n_value_prev, f_delivery_method = excluded.f_delivery_method; GET DIAGNOSTICS _inserted_readings = ROW_COUNT; --модификация старых показаний update dbo.ed_input_meter_readings as emr0 set jb_sources = json_build_object( 'f_delivery_method' , emrSubscr.f_delivery_method, 'c_delivery_method_name' , emrSubscr.c_delivery_method_name, 'n_value' , emrSubscr.n_value, 'd_date' , emrSubscr.d_date, 'f_scale' , emrSubscr.f_scale, 'c_scale' , emrSubscr.c_scale ) from t_tu as t inner join ( -- последнее контрольное показание select emr.id, emr.f_registr_pts, emr.f_energy_type, emr.f_scale, row_number () over (partition by emr.f_registr_pts, emr.f_energy_type, emr.f_scale order by emr.d_date_prev desc, emr.id) as n_row from dbo.ed_input_meter_readings as emr inner join t_tu as tt on tt.id = emr.f_registr_pts inner join dbo.es_delivery_methods as edm on edm.id = emr.f_delivery_method and edm.c_const = 'EDM_Check' -- контрольное показание where emr.d_replace_date is null ) as emrCheck on emrCheck.f_registr_pts = t.id -- последнее потребительское показание inner join ( select emr.id, emr.f_registr_pts, emr.f_energy_type, edm.id as f_delivery_method, edm.c_name as c_delivery_method_name, emr.n_value_prev as n_value, emr.d_date_prev as d_date, emr.f_scale as f_scale, es.c_name as c_scale, row_number () over (partition by emr.f_registr_pts, emr.f_energy_type, emr.f_scale order by emr.d_date_prev desc, emr.id) as n_row from dbo.ed_input_meter_readings as emr inner join t_tu as tt on tt.id = emr.f_registr_pts inner join dbo.es_scales as es on es.id = emr.f_scale left join dbo.es_delivery_methods as edm on edm.id = emr.f_delivery_method where 1=1 and coalesce(edm.c_const, 'EDM_Subscr') = 'EDM_Subscr' -- потребительское показание ) as emrSubscr on emrSubscr.f_registr_pts = emrCheck.f_registr_pts and emrSubscr.f_energy_type = emrCheck.f_energy_type and emrSubscr.f_scale = emrCheck.f_scale where 1=1 and emrSubscr.n_row = 1 and emrCheck.n_row = 1 and emrCheck.id = emr0.id; -- все непоследние показания перевести в замененные update dbo.ed_input_meter_readings as emr0 set d_replace_date = coalesce(emr.d_date_prev, now()::date) from t_tu as t inner join ( -- последнее контрольное показание select emr.id, emr.f_registr_pts, emr.d_replace_date, lag(emr.d_date_prev) over( partition by emr.f_registr_pts, emr.f_energy_type, emr.f_scale order by emr.d_date_prev desc ) as d_date_prev, -- дата следующего показания row_number () over ( partition by emr.f_registr_pts, emr.f_energy_type, emr.f_scale order by coalesce(edm.id, 1) desc, emr.d_date_prev desc, emr.id ) as n_row -- вычисление последнего показания from dbo.ed_input_meter_readings as emr inner join t_tu as tt on tt.id = emr.f_registr_pts left join dbo.es_delivery_methods as edm on edm.id = emr.f_delivery_method ) as emr on emr.f_registr_pts = t.id where emr.n_row > 1 -- все кроме последнего and emr.d_replace_date is null -- с незаполненной датой замены and emr.id = emr0.id ; -- адреса insert into dbo.ss_address ( id, c_name, c_index, c_region, c_raion, c_city_name, c_settlement_name, c_street_name, c_house_name, c_block_name, c_flat_name, n_geo_lat, n_geo_lon, imp_text, f_conn_points, c_name_obj ) select distinct f_address, c_name, c_index, c_region, c_raion, c_сity_name, c_settlement_name, c_street_name, c_house_name, c_block_name, c_flat_name, n_geo_lat, n_geo_lon, f_kladr, f_conn_points, c_name_obj from ( select row_number() over(partition by ta.f_address) as n_row, * from t_address AS ta )as ta where ta.n_row = 1 on conflict on constraint ss_address_pkey do update set c_index = COALESCE(NULLIF(dbo.ss_address.c_index , ''), excluded.c_index ) , c_region = COALESCE(NULLIF(dbo.ss_address.c_region , ''), excluded.c_region ) , c_raion = COALESCE(NULLIF(dbo.ss_address.c_raion , ''), excluded.c_raion ) , c_city_name = COALESCE(NULLIF(dbo.ss_address.c_city_name , ''), excluded.c_city_name ) , c_settlement_name = COALESCE(NULLIF(dbo.ss_address.c_settlement_name , ''), excluded.c_settlement_name ) , c_street_name = COALESCE(NULLIF(dbo.ss_address.c_street_name , ''), excluded.c_street_name ) , c_house_name = COALESCE(NULLIF(dbo.ss_address.c_house_name , ''), excluded.c_house_name ) , c_block_name = COALESCE(NULLIF(dbo.ss_address.c_block_name , ''), excluded.c_block_name ) , c_flat_name = COALESCE(NULLIF(dbo.ss_address.c_flat_name , ''), excluded.c_flat_name ) , n_geo_lat = COALESCE(NULLIF(dbo.ss_address.n_geo_lat , 0 ), excluded.n_geo_lat ) , n_geo_lon = COALESCE(NULLIF(dbo.ss_address.n_geo_lon , 0 ), excluded.n_geo_lon ) , f_conn_points = COALESCE(NULLIF(dbo.ss_address.f_conn_points , ''), excluded.f_conn_points ) , c_name_obj = COALESCE(NULLIF(dbo.ss_address.c_name_obj , ''), excluded.c_name_obj ) , b_dadata = false where dbo.ss_address.c_name != excluded.c_name; GET DIAGNOSTICS _inserted_address = ROW_COUNT; -- указание на адрес в ТУ update dbo.ed_registr_pts rp set f_address = ta.f_address from t_tu as rpp inner join t_address as ta on rpp.f_registr_pts = ta.f_registr_pts where rpp.id = rp.id and (rp.f_address <> ta.f_address or rp.f_address is null); raise notice 'вставлено ЛС %, вставлено ТУ %, вставлено ПУ %, вставлено трансформаторов %, вставлено пломб %, вставлено показаний %, вставлено адресов %', _inserted_subscr, _inserted_tu, _inserted_pu, _inserted_tr, _inserted_seals, _inserted_readings, _inserted_address; return 0; -- ОК END;
Триггер. Обновление истории бланков
BEGIN IF (TG_OP = 'UPDATE') THEN UPDATE dbo.ed_blanks as b set jb_history = dbo.sf_update_jb_history(jb_history, json_build_object('f_user_to', b.f_user_to, 'd_date_to', now(), 'f_status', b.f_status)) where b.id = NEW.id; END IF; RETURN NEW; END
Триггер. Обновление истории пломбы
BEGIN IF (TG_OP = 'UPDATE' or TG_OP = 'INSERT') THEN UPDATE dbo.ed_seals as s set jb_history = dbo.sf_update_jb_history(s.jb_history, json_build_object('f_user_to', s.f_user_to, 'f_user_from', s.f_user_from, 'd_date_to', now(), 'f_status', s.f_status)) where s.id = NEW.id; END IF; RETURN NEW; END
Получение статистики по маршруту
/** * @param {uuid} _f_route - иден. маршрута * * @example * [{ "action": "rpt_arm_cd_route_stat", "method": "Select", "data": [{ "params": [_f_route] }], "type": "rpc", "tid": 0 }] */ DECLARE _n_all_points bigint; -- общее количество точек _n_done_points bigint; -- количество пройденных точек BEGIN select DISTINCT count(fn_point) into _n_done_points from core.cd_user_points as p where p.fn_route = _f_route; select count(*) into _n_all_points from core.cd_points as p where p.f_route = _f_route; RETURN QUERY select u.id, u.c_login, u.c_first_name, u.c_last_name, u.c_middle_name, uir.b_main, _n_all_points as n_all_points, (select DISTINCT count(fn_point) from core.cd_user_points as p where p.fn_route = _f_route and p.fn_user = u.id) as n_done_points, _n_all_points - _n_done_points as n_need_points from core.cd_userinroutes as uir inner join core.pd_users as u ON u.id = uir.f_user where uir.f_route = _f_route order by uir.b_main DESC; END
Создание показаний для акта замены ПУ
/** * Выполняется только после установки предыдущих показаний в d_replace_date * * @params {uuid} _f_result - результат с актом замены ПУ * * @returns {integer} 0 - запись создана * * @example * [{ "action": "sf_generate_meter_reading", "method": "Query", "data": [{ "params": [_f_result] }], "type": "rpc", "tid": 0}] */ DECLARE _n_count_scale integer; -- количество шкал по тарифу _c_result_type text; -- тип создаваемого результата _f_registr_pts uuid; -- точка учета _meters json; -- показания BEGIN -- нужно определить количество шкал для обработки select tz.n_count_scale, rt.c_const, p.f_registr_pts into _n_count_scale, _c_result_type, _f_registr_pts from core.cd_results as r inner join core.cd_points as p ON p.id = r.fn_point inner join core.cs_result_types as rt ON rt.id = r.fn_type inner join dbo.es_tariff_zones as tz ON tz.id = (r.jb_data #>> '{f_tariff_zone}')::integer where r.id = _f_result; IF _c_result_type = 'AZPU' OR _c_result_type = 'ADEPU' THEN IF _n_count_scale = 1 THEN -- Сутки select array_to_json(array_agg(row_to_json(t))) into _meters from ( select (r.jb_data #>> '{n_scale1}')::numeric as n_scale, r.d_date, dt.n_digits, (select id from dbo.es_scales where c_const = 'TFZ_Day') as f_scale, _f_registr_pts as f_registr_pts, (r.jb_data #>> '{f_tariff_zone}')::integer as f_tariff_zone, 1 as f_energy_type, 2 as f_delivery_method from core.cd_results as r inner join core.cs_result_types as rt ON rt.id = r.fn_type inner join dbo.es_device_types as dt ON dt.id = (r.jb_data #>> '{f_device_model}')::integer where r.id = _f_result ) as t; ELSIF _n_count_scale = 2 THEN -- День, Ночь select array_to_json(array_agg(row_to_json(t))) into _meters from ( select (r.jb_data #>> '{n_scale1}')::numeric as n_scale, r.d_date, dt.n_digits, (select id from dbo.es_scales where c_const = 'TFZ_DayTime') as f_scale, _f_registr_pts as f_registr_pts, (r.jb_data #>> '{f_tariff_zone}')::integer as f_tariff_zone, 1 as f_energy_type, 2 as f_delivery_method from core.cd_results as r inner join core.cs_result_types as rt ON rt.id = r.fn_type inner join dbo.es_device_types as dt ON dt.id = (r.jb_data #>> '{f_device_model}')::integer where r.id = _f_result UNION ALL select (r.jb_data #>> '{n_scale2}')::numeric as n_scale, r.d_date, dt.n_digits, (select id from dbo.es_scales where c_const = 'TFZ_Nigth') as f_scale, _f_registr_pts as f_registr_pts, (r.jb_data #>> '{f_tariff_zone}')::integer as f_tariff_zone, 1 as f_energy_type, 2 as f_delivery_method from core.cd_results as r inner join core.cs_result_types as rt ON rt.id = r.fn_type inner join dbo.es_device_types as dt ON dt.id = (r.jb_data #>> '{f_device_model}')::integer where r.id = _f_result ) as t; ELSIF _n_count_scale = 3 THEN -- Ночь, Пик, Полупик select array_to_json(array_agg(row_to_json(t))) into _meters from ( select (r.jb_data #>> '{n_scale1}')::numeric as n_scale, r.d_date, dt.n_digits, (select id from dbo.es_scales where c_const = 'TFZ_Nigth') as f_scale, _f_registr_pts as f_registr_pts, (r.jb_data #>> '{f_tariff_zone}')::integer as f_tariff_zone, 1 as f_energy_type, 2 as f_delivery_method from core.cd_results as r inner join core.cs_result_types as rt ON rt.id = r.fn_type inner join dbo.es_device_types as dt ON dt.id = (r.jb_data #>> '{f_device_model}')::integer where r.id = _f_result UNION ALL select (r.jb_data #>> '{n_scale2}')::numeric as n_scale, r.d_date, dt.n_digits, (select id from dbo.es_scales where c_const = 'TFZ_Peak') as f_scale, _f_registr_pts as f_registr_pts, (r.jb_data #>> '{f_tariff_zone}')::integer as f_tariff_zone, 1 as f_energy_type, 2 as f_delivery_method from core.cd_results as r inner join core.cs_result_types as rt ON rt.id = r.fn_type inner join dbo.es_device_types as dt ON dt.id = (r.jb_data #>> '{f_device_model}')::integer where r.id = _f_result UNION ALL select (r.jb_data #>> '{n_scale3}')::numeric as n_scale, r.d_date, dt.n_digits, (select id from dbo.es_scales where c_const = 'TFZ_SemiPeak') as f_scale, _f_registr_pts as f_registr_pts, (r.jb_data #>> '{f_tariff_zone}')::integer as f_tariff_zone, 1 as f_energy_type, 2 as f_delivery_method from core.cd_results as r inner join core.cs_result_types as rt ON rt.id = r.fn_type inner join dbo.es_device_types as dt ON dt.id = (r.jb_data #>> '{f_device_model}')::integer where r.id = _f_result ) as t; ELSE RETURN 2; -- не удалось определить количество шкал END IF; --raise notice '%', _meters; -- добавляем показания INSERT INTO dbo.ed_input_meter_readings(n_value_prev, d_date_prev, n_digit, f_scale, f_registr_pts, f_tariff_zone, f_energy_type, f_delivery_method) select (t.value #>> '{n_scale}')::numeric, (t.value #>> '{d_date}')::timestamp with time zone, (t.value #>> '{n_digits}')::numeric, (t.value #>> '{f_scale}')::integer, (t.value #>> '{f_registr_pts}')::uuid, (t.value #>> '{f_tariff_zone}')::integer, (t.value #>> '{f_energy_type}')::integer, (t.value #>> '{f_delivery_method}')::integer from json_array_elements(_meters::json) as t; ELSE RETURN 1; -- результат не является актом замены ПУ END IF; RETURN 0; END
Генерация информации для точки учета
/** * @params {uuid} _f_registr_pts - идентификатор точки учета * * @returns {jsonb} * * @example * [{ "action": "sf_generate_point_info", "method": "Query", "data": [{ "params": [_f_registr_pts] }], "type": "rpc", "tid": 0}] */ DECLARE _c_seals_info text; _c_transformers_info text; _c_meter_readings text; BEGIN IF (select count(*) from dbo.ed_registr_pts as rp where rp.id = _f_registr_pts) = 1 THEN select string_agg(concat( '<div><b>Тип</b>: ', st.c_name, '<br />', '<b>Номер</b>: ', coalesce(s.c_number, concat(s.c_prefix, s.n_number::text)), '<br />', '<b>Место установки</b>: ', s.c_location, '</div>'), '' order by s.c_type, s.c_location) into _c_seals_info from dbo.ed_seals as s left join dbo.es_seal_types as st ON s.f_type = st.id where s.f_registr_pts = _f_registr_pts and s.d_replace_date is null; select string_agg(concat( '<div><b>Дата</b>: ', to_char((imp.jb_sources->>'d_date')::date, 'DD.MM.YYYY'), '<br />', '<b>Источник</b>: ', imp.jb_sources->>'c_delivery_method_name', '<br />', '<b>Шкала</b>: ', imp.jb_sources->>'c_scale', '<br />', '<b>Показание</b>: ', (imp.jb_sources->>'n_value')::numeric , '</div>'), '' order by imp.f_scale) into _c_meter_readings from dbo.ed_input_meter_readings as imp where imp.f_registr_pts = _f_registr_pts and imp.d_replace_date is null and imp.jb_sources is not null; select string_agg(concat( '<div><b>Тип трансформатора</b>: ', CASE WHEN t.b_voltage THEN 'напряжение' ELSE 'ток' END, '<br />', '<b>Номер</b>: ', t.c_serial_number, '<br />', '<b>Тип</b>: ', dt.c_name, '<br />', '<b>Год выпуска</b>: ', t.n_manufacture_year::text, '<br />', '<b>Коэффициент трансформации</b>: ', dt.n_rate::text, '<br />', '<b>Фаза</b>: ', t.c_phase, '<br />', '<b>Дата поверки</b>: ', to_char(t.d_check_date, 'DD.MM.YYYY'), '<br />', '<b>Дата след. поверки</b>: ', to_char(t.d_replace_before, 'DD.MM.YYYY'), '<br />', '<b>Межповерочный интервал</b>: ', dt.n_check_cycle::text, '</div>'), '' order by t.b_voltage, t.c_phase) into _c_transformers_info from dbo.ed_transformers as t inner join dbo.es_device_types as dt ON dt.id = t.f_device_type where t.f_registr_pts = _f_registr_pts and t.d_replace_date is null; RETURN concat('<p style="text-align: center">Показания</p>', CASE WHEN _c_meter_readings is null THEN '<div>информация отсутствует</div>' ELSE _c_meter_readings END, '<p style="text-align: center">Пломбы</p>', CASE WHEN _c_seals_info is null THEN '<div>информация отсутствует</div>' ELSE _c_seals_info END, '<p style="text-align: center">Трансформаторы</p>', CASE WHEN _c_transformers_info is null THEN '<div>информация отсутствует</div>' ELSE _c_transformers_info END); ELSE RETURN ''; END IF; END
Генерация JSON информации для точки учета
/** * @params {uuid} _f_registr_pts - идентификатор точки учета * * @returns {jsonb} * * @example * [{ "action": "sf_generate_point_data", "method": "Query", "data": [{ "params": [_f_registr_pts] }], "type": "rpc", "tid": 0}] */ DECLARE _jb_data jsonb; BEGIN IF (select count(*) from dbo.ed_registr_pts as rp where rp.id = _f_registr_pts) = 1 THEN select json_build_object( 'c_address', ad.c_name, -- Адрес 'b_person', s.b_person, -- true - Фил. лицо 'b_technical_metering', rp.b_technical_metering, -- Признак технического учета 'c_device_model', dt.c_name, -- Модель ПУ 'c_device_number', d.c_serial_number, -- № ПУ 'c_owner', CASE WHEN s.b_person THEN concat(s.c_name1, ' ', s.c_name2, ' ', s.c_name3) ELSE s.c_name1 END, -- ФИО 'c_device_interval', '', 'n_longitude', ad.n_geo_lon, 'n_latitude', ad.n_geo_lat, 'c_subscr', s.c_code, 'c_telephone', s.c_telephone, 'c_path', case when rp.c_substation is null then '' else concat(rp.c_substation, '/', rp.c_line_substation, '/', rp.c_rp, '/', rp.c_line_rp, '/', rp.c_tp, '/', rp.c_line_tp, '/', rp.c_line_segment) end )::jsonb into _jb_data from dbo.ed_registr_pts as rp left join dbo.sd_subscr as s ON s.id = rp.f_subscr left join dbo.ss_address as ad ON ad.id = rp.f_address left join dbo.ed_devices as d ON d.f_registr_pts = rp.id left join dbo.es_device_types as dt ON dt.id = d.f_device_type where d.d_close_date is null and rp.id = _f_registr_pts; RETURN _jb_data; ELSE RETURN null::jsonb; END IF; END
Обработка выходных данных
/** * @returns {integer} * 0 - ОК * * @example * [{ "action": "sf_transfer_output_data", "method": "Query", "data": [{ "params": [] }], "type": "rpc", "tid": 0}] */ BEGIN -- обработка показаний (просили закомментировать - Аня К.) /*IF (select count(*) from dbo.ed_output_meter_readings where b_export = false) > 0 THEN -- нужно перенести новые показаний в input INSERT INTO dbo.ed_input_meter_readings(id, n_value_prev, d_date_prev, n_digit, f_scale, dx_created, f_registr_pts, f_tariff_zone, f_energy_type, f_delivery_method, d_replace_date) select t.id, t.n_value, t.d_date, t.n_digit, t.f_scale, t.dx_created, t.f_registr_pts, t.f_tariff_zone, t.f_energy_type, t.f_delivery_method, t.d_replace_date::timestamp with time zone from (select omr.id, omr.n_value, omr.d_date, imr.n_digit, imr.f_scale, now() as dx_created, imr.f_registr_pts, imr.f_tariff_zone, imr.f_energy_type, imr.f_delivery_method, null as d_replace_date, row_number() over(partition by imr.id, imr.f_registr_pts order by omr.d_date desc) as n_row from dbo.ed_output_meter_readings as omr inner join dbo.ed_input_meter_readings as imr ON omr.fn_meter_reading = imr.id where omr.b_export = false) as t where t.n_row = 1; -- устанавливаем признак замены показания update dbo.ed_input_meter_readings as imr set d_replace_date = t1.d_date from ( select t.id, t.d_date from (select imr.id, omr.d_date, row_number() over(partition by imr.id, imr.f_registr_pts order by omr.d_date desc) as n_row from dbo.ed_output_meter_readings as omr inner join dbo.ed_input_meter_readings as imr ON omr.fn_meter_reading = imr.id where omr.b_export = false) as t where t.n_row = 1 ) as t1 where imr.id = t1.id; -- указываем, что данные обработали update dbo.ed_output_meter_readings set b_export = true where b_export = false; END IF;*/ -- обработка пломб IF (select count(*) from dbo.ed_output_conn_seals where b_export = false) > 0 OR (select count(*) from dbo.ed_seals as s where s.d_replace_date is null and s.f_status = 4) > 0 THEN -- нужно обновить информацию по пломбам, которые ранее были выданы и использованы update dbo.ed_seals as s set f_registr_pts = t1.f_registr_pts, c_type = t1.c_type, c_location = t1.c_location, f_type = t1.f_type, f_place = t1.f_place, f_output_conn_seal = t1.f_output_conn_seal from ( select ocs.fn_seal_new, p.f_registr_pts, st.c_name as c_type, st.id as f_type, sp.c_name as c_location, sp.id as f_place, ocs.id as f_output_conn_seal from dbo.ed_output_conn_seals as ocs inner join dbo.es_seal_types as st ON st.id = ocs.fn_type inner join dbo.es_seal_places as sp ON sp.id = ocs.fn_place inner join dbo.ed_seals as es ON es.id = ocs.fn_seal_new inner join core.cd_points as p ON p.id = ocs.fn_point where ocs.b_export = false ) as t1 where s.id = t1.fn_seal_new; -- отключаем пломбы, которые были заменены update dbo.ed_seals as s set d_replace_date = t1.d_date from ( select es.id, ocs.d_date from dbo.ed_output_conn_seals as ocs inner join dbo.ed_seals as es ON es.id = ocs.fn_seal where ocs.b_export = false ) as t1 where s.id = t1.id; -- отключаем пломбы, которые были снята update dbo.ed_seals as s set d_replace_date = now() where s.d_replace_date is null and s.f_status = 4; -- указываем, что данные обработали update dbo.ed_output_conn_seals set b_export = true where b_export = false; END IF; /*-- обработка трансформаторов IF (select count(*) from dbo.ed_output_transformers where b_export = false) > 0 THEN -- находим созданные трансформаторы и добавляем их общий список INSERT INTO dbo.ed_transformers(id, f_registr_pts, b_voltage, c_serial_number, d_replace_before, f_device_type, c_phase, imp_int, n_manufacture_year, d_check_date, d_replace_date, imp_text, n_rate) select ot.id, p.f_registr_pts, ot.b_voltage, ot.c_number, ot.d_date + (dt.n_check_cycle || ' year')::interval, dt.id, ph.c_name, null, ot.n_year, ot.d_date_check, null, null, ot.n_rate FROM dbo.ed_output_transformers as ot inner join dbo.es_phase as ph ON ph.id = ot.fn_phase inner join core.cd_points as p ON p.id = ot.fn_point inner join dbo.es_device_types as dt ON dt.id = ot.fn_device_type where ot.b_export = false; -- отключаем трансформаторы, которые были заменены update dbo.ed_transformers as t set d_replace_date = t1.d_date from ( select tr.id, ot.d_date from dbo.ed_output_transformers as ot inner join dbo.ed_transformers as tr ON tr.id = ot.fn_transformer where ot.b_export = false ) as t1 where t.id = t1.id; -- указываем, что данные обработали update dbo.ed_output_transformers set b_export = true where b_export = false; END IF; -- обновление номера телефона IF (select count(*) from core.cd_user_points where b_export = false) > 0 THEN -- обновляем номера update dbo.sd_subscr as s set c_telephone = t1.c_telephone, jb_history = dbo.sf_update_jb_history(CASE WHEN jb_history is null THEN '[]'::json ELSE jb_history END, json_build_object('c_telephone', s.c_telephone, 'fn_user_point', t1.fn_user_point, 'dx_created', now())) from ( select up.c_telephone, rp.f_subscr, up.id as fn_user_point from core.cd_user_points as up inner join core.cd_points as p ON p.id = up.fn_point inner join dbo.ed_registr_pts as rp ON rp.id = p.f_registr_pts inner join dbo.sd_subscr as s ON s.id = rp.f_subscr where up.b_export = false and (up.c_telephone != s.c_telephone or s.c_telephone is null) ) as t1 where s.id = t1.f_subscr; -- проверяем есть ли задания по замене ПУ и отключаем старое ПУ update dbo.ed_devices as d set d_close_date = now()::date from ( select p.f_registr_pts, r.jb_data from core.cd_user_points as up inner join core.cd_points as p ON p.id = up.fn_point inner join core.cd_results as r ON r.fn_user_point = up.id inner join core.cs_result_types as rt ON rt.id = r.fn_type where up.b_export = false and (rt.c_const = 'AZPU' or rt.c_const = 'ADEPU') ) as t where d.f_registr_pts = t.f_registr_pts and d.d_close_date is null; -- устанавливаем новый ПУ insert into dbo.ed_devices(f_device_type, c_serial_number, n_rate, n_manufacture_year, d_setup_date, d_valid_date, f_device_location, f_registr_pts) select (r.jb_data #>> '{f_device_model}')::integer, (r.jb_data #>> '{c_device_number}'), (r.jb_data #>> '{n_rate}')::numeric, (r.jb_data #>> '{n_year}')::integer, up.d_date::date, (r.jb_data #>> '{d_check_date}')::date, (r.jb_data #>> '{f_device_location}')::integer, p.f_registr_pts from core.cd_user_points as up inner join core.cd_points as p ON p.id = up.fn_point inner join core.cd_results as r ON r.fn_user_point = up.id inner join core.cs_result_types as rt ON rt.id = r.fn_type where up.b_export = false and (rt.c_const = 'AZPU' or rt.c_const = 'ADEPU'); -- отключаем старые показания update dbo.ed_input_meter_readings as imr set d_replace_date = t.d_date from ( select p.f_registr_pts, up.d_date from core.cd_user_points as up inner join core.cd_points as p ON p.id = up.fn_point inner join core.cd_results as r ON r.fn_user_point = up.id inner join core.cs_result_types as rt ON rt.id = r.fn_type where up.b_export = false and (rt.c_const = 'AZPU' or rt.c_const = 'ADEPU') ) as t where imr.f_registr_pts = t.f_registr_pts and imr.d_replace_date is null; -- создаем показания perform dbo.sf_generate_meter_reading(r.id) from core.cd_user_points as up inner join core.cd_results as r ON r.fn_user_point = up.id inner join core.cs_result_types as rt ON rt.id = r.fn_type where up.b_export = false and (rt.c_const = 'AZPU' or rt.c_const = 'ADEPU'); -- указываем, что данные обработали update core.cd_user_points set b_export = true where b_export = false; END IF;*/ RETURN 0; END
Обновление истории для специального поля jb_history
items.push(old_json); return items;
Обновление JSON и общей информации у точки маршрута
/** * @params {uuid} _f_point - идентификатор точки маршрута * * @returns * 0 - OK * 1 - нет точки маршрута * * @example * [{ "action": "sf_update_point_jb_data", "method": "Query", "data": [{ "params": [_f_point] }], "type": "rpc", "tid": 0}] */ DECLARE _f_registr_pts uuid; BEGIN IF (select count(*) from core.cd_points as p where p.id = _f_point) = 1 THEN select p.f_registr_pts into _f_registr_pts from core.cd_points as p where p.id = _f_point; update core.cd_points as p set jb_data = dbo.sf_generate_point_jb_data(_f_registr_pts), c_info = dbo.sf_generate_point_info(_f_registr_pts) where p.id = _f_point; RETURN 0; ELSE RETURN 1; -- нет точки маршрута END IF; END
Преобразует текст в uuid, при неудаче вернет null
BEGIN RETURN str::uuid; EXCEPTION WHEN invalid_text_representation THEN RETURN NULL; END;
Схема отчетов
Отчет по выполненным работам
/** * @params {date} _d_date_start - дата начала периода * @params {date} _d_date_end - дата окончания периода * @params {text} _f_main_division - филиал, можно передать -1, тогда выборка будет по всем * @params {text} _f_division - отделение, можно передать -1, тогда выборка будет по всем в рамках филиала * @params {text} _f_subdivisions - список участоков через запятую, например 55,56. Можно передать -1, тогда все участки в рамках отделения * @params {text} _c_substation - Наименование ПС * @params {text} _c_line_substation - Наименование фидера 6-10 кВ * @params {text} _c_tp - Наименование ТП 6-10/0,4 кВ * * @example * [{ "action": "cf_doned_work", "method": "Select", "data": [{ "params": [_d_date_start, _d_date_end, _f_main_division, _f_division, _f_subdivisions] }], "type": "rpc", "tid": 0 }] */ DECLARE _d_period_start date; _d_period_end date; BEGIN select _d_date_start, _d_date_end into _d_period_start, _d_period_end; RETURN QUERY with results as ( select main_div.id as f_main_division, div.id as f_division, rp.f_subdivision as f_subdivision, main_div.c_name as c_main_division, -- Филиал div.c_name as c_division, -- Отделение sub_div.c_name as c_subdivision, -- Участок r.c_number as c_route_number, -- номер маршрута -- Исполнители маршрута (select string_agg(concat(u.c_last_name, ' ', u.c_first_name, ' ', u.c_middle_name), ', ') from core.cd_userinroutes as uir inner join core.pd_users as u ON uir.f_user = u.id where uir.f_route = r.id and uir.b_main) as c_main_users, -- исполнитель (select string_agg(concat(u.c_last_name, ' ', u.c_first_name, ' ', u.c_middle_name), ', ') from core.cd_userinroutes as uir inner join core.pd_users as u ON uir.f_user = u.id where uir.f_route = r.id and uir.b_main = false) as c_second_users, -- соисполнитель rrt.c_name as c_result_type, -- тип акта rr.d_date as d_result_date, -- дата акта case when s.b_person then concat(s.c_name1, ' ', s.c_name2, ' ', s.c_name3) else s.c_name1 end as c_owner, -- Наименование абонента ad.c_name as c_address, -- адрес rp.imp_text as c_registr_pts_code, -- код ТУ d.c_serial_number as n_device_code, -- Номер ПУ sc.c_name as c_scale_name, -- Тариф round(omr.n_value, ((coalesce(dt.n_digits, 9.2) % floor(coalesce(dt.n_digits, 9.2))) * 10)::integer)::text as c_value_current, -- Текущие показаний concat(u.c_last_name, ' ', u.c_first_name, ' ', u.c_middle_name) as c_doned_user_name, -- Выполнил rr.fn_user_point, rr.fn_type, p.n_order, rp.c_substation as c_substation, rp.c_line_substation as c_line_substation, rp.c_tp as c_tp --, --row_number() over(partition by rr.fn_point order by rr.d_date desc) as n_row нужно выводить все - 486785 from core.cd_results as rr inner join core.pd_users as u ON u.id = rr.fn_user inner join core.cs_result_types as rrt ON rrt.id = rr.fn_type inner join core.cd_points as p ON rr.fn_point = p.id inner join core.cd_routes as r ON p.f_route = r.id left join dbo.ed_output_meter_readings as omr ON omr.fn_result = rr.id left join dbo.ed_input_meter_readings as imp ON imp.id = omr.fn_meter_reading inner join dbo.ed_devices as d ON d.f_registr_pts = p.f_registr_pts inner join dbo.es_device_types as dt ON d.f_device_type = dt.id inner join dbo.ed_registr_pts as rp ON p.f_registr_pts = rp.id inner join core.sd_subdivisions as sub_div ON rp.f_subdivision = sub_div.id inner join core.sd_divisions as div ON rp.f_division = div.id left join core.sd_divisions as main_div ON div.f_division = main_div.id inner join dbo.sd_subscr as s ON rp.f_subscr = s.id inner join dbo.ss_address as ad ON rp.f_address = ad.id left join dbo.es_scales as sc on imp.f_scale = sc.id where omr.d_date between _d_date_start and _d_date_end + interval '1 day' ) select row_number() over(order by max(t.n_order) desc) AS n_num, -- номер п/п to_char(_d_period_start, 'dd.MM.YYYY') as d_period_start, to_char(_d_period_end, 'dd.MM.YYYY') as d_period_end, max(t.f_main_division) as f_maindivision, max(t.f_division) as f_division, max(t.f_subdivision) as f_subdivision, max(t.c_main_division) as c_main_division, max(t.c_division) as c_division, max(t.c_subdivision) as c_subdivision, max(t.c_route_number) as c_route_number, max(t.c_main_users) as c_main_users, max(t.c_second_users) as c_second_users, max(t.c_result_type) as c_result_type, max(t.d_result_date) as d_result_date, max(t.c_owner) as c_owner, max(t.c_address) as c_address, max(t.c_registr_pts_code) as c_registr_pts_code, max(t.n_device_code) as n_device_code, string_agg(t.c_scale_name, ', ') as c_scale_name, string_agg(t.c_value_current, ', ') as c_value_current, max(t.c_doned_user_name) as c_doned_user_name, max(t.c_substation) as c_substation, max(t.c_line_substation) as c_line_substation, max(t.c_tp) as c_tp from (select * from results as rr where rr.d_result_date between _d_date_start and _d_date_end + interval '1 day' and (case when _f_main_division is null or _f_main_division = '' or _f_main_division = '-1' then 1=1 else _f_main_division::integer = rr.f_main_division end) and (case when _f_division is null or _f_division = '' or _f_division = '-1' then 1=1 else _f_division::integer = rr.f_division end) and (case when _f_subdivisions is null or _f_subdivisions = '' or _f_subdivisions = '-1' then 1=1 else rr.f_subdivision in (select t.value::integer from json_array_elements_text(rpt.sf_rpt_csv_to_json(_f_subdivisions)) as t) end) and (case when _c_substation is null or _c_substation = '' or _c_substation = '-1' then 1=1 else rr.c_substation ilike '%'||_c_substation||'%' end) and (case when _c_line_substation is null or _c_line_substation = '' or _c_line_substation = '-1' then 1=1 else rr.c_line_substation ilike '%'||_c_line_substation||'%' end) and (case when _c_tp is null or _c_tp = '' or _c_tp = '-1' then 1=1 else rr.c_tp ilike '%'||_c_tp||'%' end) ) as t --where t.n_row = 1 (486785 убрал в рамках вот этого река - нужно выводить все) group by t.fn_user_point, t.fn_type order by max(t.n_order) desc; END
Журнал регистрации бланков актов проверки состояния схемы измерений э/э и работы/замены/допуска в эксплуатацию приборов учета
BEGIN RETURN QUERY /*with items as ( select -- тут делаем сортировки по истории row_number() over(partition by s.id order by s.d_date_to asc) as n_row, s.id, -- иден. пломбы ss.c_const as c_status_const, -- иден. типа пломбы s.f_user_to as f_user_to, -- кому выдан s.f_user_from as f_user_from, -- кем выдан coalesce(s.d_date_to, s.dx_created) as d_date_to, -- дата выдачи s.f_status as f_status -- статус from (select -- отсюда получаем информацию об истории s.id,s.dx_created, (json_array_elements(s.jb_history)->>'f_user_to')::integer as f_user_to, (json_array_elements(s.jb_history)->>'f_user_from')::integer as f_user_from, (json_array_elements(s.jb_history)->>'d_date_to')::timestamp with time zone as d_date_to, (json_array_elements(s.jb_history)->>'f_status')::integer as f_status from dbo.ed_blanks as s where s.f_status is not null) as s inner join dbo.es_blank_status as ss ON s.f_status = ss.id where 1=1 )*/ select s.id, -- иден. пломбы 1::bigint as n_row, -- позиция ssd.id as f_subdivision, -- иден. участок ssd.c_name as c_subdivision, -- участок concat(coalesce(s.c_prefix, ''), s.n_number) as c_blank_number, -- Номер пломбировочного материала s.dx_created as d_date_create, -- дата создания пломбы concat(um.c_last_name || ' ', LEFT(um.c_first_name, 1) || '. ', LEFT(um.c_middle_name, 1) || '.') as c_user_mol, -- Фамилия и инициалы МОЛ s.d_date_to, -- Дата выдачи бланка акта concat(ut.c_last_name || ' ', LEFT(ut.c_first_name, 1) || '. ', LEFT(ut.c_middle_name, 1) || '.') as c_user_to, -- кто получил ut.c_post as c_post_to, -- Должность получателя пломбировочного материала concat(uf.c_last_name || ' ', LEFT(uf.c_first_name, 1) || '. ', LEFT(uf.c_middle_name, 1) || '.') as c_user_from, -- кто выдал uf.c_post as c_post_from, -- Должность ответственного за ведение и хранение журнала case when ss.c_const in ('SETUP','TRASH') then to_char(s.d_date_to, 'dd.MM.YYYY'::text) end as d_date_setup_trash, -- Дата составления (возврата) акта (бланка) concat( case when sub.b_person then concat(sub.c_name1, ' ', sub.c_name2, ' ', sub.c_name3) else sub.c_name1 end, -- Наименование потребителя ' ', sa.c_name, -- Адрес ' ', sa.c_name_obj -- Наименование объекта ) as c_owner, -- потребитель coalesce(s.c_document_trash, rt.c_name) as c_document_number, -- Дата акта (документ о списании пломбировочного материала) case when s.c_document_trash is null or s.c_document_trash = '' then to_char(r.d_date, 'dd.MM.YYYY'::text) else to_char(s.d_date_to, 'dd.MM.YYYY'::text) end as c_document_date -- Номер акта (документ о списании пломбировочного материала) from dbo.ed_blanks as s inner join dbo.es_blank_status as ss ON s.f_status = ss.id left join core.sd_subdivisions as ssd ON ssd.id = s.f_subdivision left join core.sd_divisions as sd ON sd.id = ssd.f_division left join core.sd_divisions as sdd ON sdd.id = sd.f_division left join core.cd_results as r ON s .fn_result = r.id inner join core.cs_result_types as rt ON rt.id = s.f_result_type left join core.cd_points as cp on cp.id = r.fn_point left join dbo.ed_registr_pts as rp ON rp.id = cp.f_registr_pts left join dbo.sd_subscr as sub ON sub.id = rp.f_subscr left join dbo.ss_address as sa ON sa.id = rp.f_address left join core.pd_users as uf ON s.f_user_from = uf.id left join core.pd_users as ut ON s.f_user_to = ut.id left join core.pd_users as um ON s.f_user_mol = um.id where s.d_date_to between _d_date_start and _d_date_end + interval '1 day' and ss.c_const in ('REG', 'SEND', 'SETUP', 'TRASH') and rt.c_const in ('AIP', 'AZPU', 'ADEPU') and case when _f_maindivisions is null or _f_maindivisions = '' or _f_maindivisions = '-1' then 1=1 else sdd.id in (select t.value::integer from json_array_elements_text(rpt.sf_rpt_csv_to_json(_f_maindivisions)) as t) end and case when _f_divisions is null or _f_divisions = '' or _f_divisions = '-1' then 1=1 else sd.id in (select t.value::integer from json_array_elements_text(rpt.sf_rpt_csv_to_json(_f_divisions)) as t) end and case when _f_subdivisions is null or _f_subdivisions = '' or _f_subdivisions = '-1' then 1=1 else ssd.id in (select t.value::integer from json_array_elements_text(rpt.sf_rpt_csv_to_json(_f_subdivisions)) as t) end and (case when _f_user_to is null or _f_user_to = '' or _f_user_to = '-1' then 1=1 else s.f_user_to in (select t.value::integer from json_array_elements_text(rpt.sf_rpt_csv_to_json(_f_user_to)) as t) end) and (case when _f_statuses is null or _f_statuses = '' or _f_statuses = '-1' then 1=1 else ss.id in (select t.value::integer from json_array_elements_text(rpt.sf_rpt_csv_to_json(_f_statuses)) as t) end) order by s.d_date_to, s.id; END
Журнал регистрации актов о неучтенном потреблении э/э
BEGIN RETURN QUERY /*with items as ( select -- тут делаем сортировки по истории row_number() over(partition by s.id order by s.d_date_to asc) as n_row, s.id, -- иден. пломбы ss.c_const as c_status_const, -- иден. типа пломбы s.f_user_to as f_user_to, -- кому выдан s.f_user_from as f_user_from, -- кем выдан coalesce(s.d_date_to, s.dx_created) as d_date_to, -- дата выдачи s.f_status as f_status -- статус from (select -- отсюда получаем информацию об истории s.id,s.dx_created, (json_array_elements(s.jb_history)->>'f_user_to')::integer as f_user_to, (json_array_elements(s.jb_history)->>'f_user_from')::integer as f_user_from, (json_array_elements(s.jb_history)->>'d_date_to')::timestamp with time zone as d_date_to, (json_array_elements(s.jb_history)->>'f_status')::integer as f_status from dbo.ed_blanks as s where s.f_status is not null) as s inner join dbo.es_blank_status as ss ON s.f_status = ss.id where 1=1 ) */ select s.id, -- иден. пломбы 1::bigint as n_row, -- позиция ssd.id as f_subdivision, -- иден. участок ssd.c_name as c_subdivision, -- участок concat(coalesce(s.c_prefix, ''), s.n_number) as c_blank_number, -- Номер пломбировочного материала s.dx_created as d_date_create, -- дата создания пломбы concat(um.c_last_name || ' ', LEFT(um.c_first_name, 1) || '. ', LEFT(um.c_middle_name, 1) || '.') as c_user_mol, -- Фамилия и инициалы МОЛ s.d_date_to, -- Дата выдачи бланка акта concat(ut.c_last_name || ' ', LEFT(ut.c_first_name, 1) || '. ', LEFT(ut.c_middle_name, 1) || '.') as c_user_to, -- кто получил ut.c_post as c_post_to, -- Должность получателя пломбировочного материала concat(uf.c_last_name || ' ', LEFT(uf.c_first_name, 1) || '. ', LEFT(uf.c_middle_name, 1) || '.') as c_user_from, -- кто выдал uf.c_post as c_post_from, -- Должность ответственного за ведение и хранение журнала case when ss.c_const in ('SETUP','TRASH') then to_char(s.d_date_to, 'dd.MM.YYYY'::text) end as d_date_setup_trash, -- Дата составления (возврата) акта (бланка) case when rt.c_const = 'ABUP' then concat( case when sub.b_person then concat(sub.c_name1, ' ', sub.c_name2, ' ', sub.c_name3) else sub.c_name1 end, ' ', sa.c_name) when rt.c_const = 'ABDP' then concat(r.jb_data->>'c_address', ' ', r.jb_data->>'c_consumer') end as c_owner, -- потребитель case when rt.c_const = 'ABUP' then 'безучетное потребление' when rt.c_const = 'ABDP' then 'бездоговорное потреблене' end as c_status, coalesce(s.c_document_trash, rt.c_name) as c_document_number, -- Дата акта (документ о списании пломбировочного материала) case when s.c_document_trash is null or s.c_document_trash = '' then to_char(r.d_date, 'dd.MM.YYYY'::text) else to_char(s.d_date_to, 'dd.MM.YYYY'::text) end as c_document_date -- Номер акта (документ о списании пломбировочного материала) --concat((case when s.c_document_trash is null or s.c_document_trash = '' then to_char(r.d_date, 'dd.MM.YYYY'::text) else to_char(i.d_date_to, 'dd.MM.YYYY'::text) end), ' ', coalesce(s.c_document_trash, rt.c_name)) as c_document -- наименование документа from dbo.ed_blanks as s inner join dbo.es_blank_status as ss ON s.f_status = ss.id left join core.sd_subdivisions as ssd ON ssd.id = s.f_subdivision left join core.sd_divisions as sd ON sd.id = ssd.f_division left join core.sd_divisions as sdd ON sdd.id = sd.f_division left join core.cd_results as r ON s .fn_result = r.id inner join core.cs_result_types as rt ON rt.id = s.f_result_type left join core.cd_points as cp on cp.id = r.fn_point left join dbo.ed_registr_pts as rp ON rp.id = cp.f_registr_pts left join dbo.sd_subscr as sub ON sub.id = rp.f_subscr left join dbo.ss_address as sa ON sa.id = rp.f_address left join core.pd_users as uf ON s.f_user_from = uf.id left join core.pd_users as ut ON s.f_user_to = ut.id left join core.pd_users as um ON s.f_user_mol = um.id where s.d_date_to between _d_date_start and _d_date_end + interval '1 day' and ss.c_const in ('REG', 'SEND', 'SETUP', 'TRASH') and rt.c_const in ('ABUP', 'ABDP') and case when _f_maindivisions is null or _f_maindivisions = '' or _f_maindivisions = '-1' then 1=1 else sdd.id in (select t.value::integer from json_array_elements_text(rpt.sf_rpt_csv_to_json(_f_maindivisions)) as t) end and case when _f_divisions is null or _f_divisions = '' or _f_divisions = '-1' then 1=1 else sd.id in (select t.value::integer from json_array_elements_text(rpt.sf_rpt_csv_to_json(_f_divisions)) as t) end and case when _f_subdivisions is null or _f_subdivisions = '' or _f_subdivisions = '-1' then 1=1 else ssd.id in (select t.value::integer from json_array_elements_text(rpt.sf_rpt_csv_to_json(_f_subdivisions)) as t) end and (case when _f_user_to is null or _f_user_to = '' or _f_user_to = '-1' then 1=1 else s.f_user_to in (select t.value::integer from json_array_elements_text(rpt.sf_rpt_csv_to_json(_f_user_to)) as t) end) and (case when _f_statuses is null or _f_statuses = '' or _f_statuses = '-1' then 1=1 else ss.id in (select t.value::integer from json_array_elements_text(rpt.sf_rpt_csv_to_json(_f_statuses)) as t) end) order by s.d_date_to, s.id; END
Отчет "Реестр показаний для ГП"
/** * @params {date} _d_date_start - дата начала периода * @params {date} _d_date_end - дата окончания периода * @params {text} _f_subdivisions - список участок * @params {text} _f_user_to - иден. пользователя * @params {text} _f_statuses - список статусов * * @example * [{ "action": "cf_ed_seals", "method": "Select", "data": [{ "params": [_d_date_start, _d_date_end, _f_main_division, _f_division, _f_subdivisions, _f_user] }], "type": "rpc", "tid": 0 }] */ DECLARE _CMR int4; _ATO int4; _CREATED int4; _METER int4; BEGIN select c.id into _CMR from core.cs_result_types as c where c.c_const = 'CMR'; select c.id into _ATO from core.cs_result_types as c where c.c_const = 'ATO'; select c.id into _CREATED from core.cs_route_statuses as c where c.c_const = 'CREATED'; select c.id into _METER from core.cs_attachment_types as c where c.c_const = 'METER'; RETURN QUERY select omr.id, sdd.id as f_maindivision , -- Филиал sdd.c_name as c_maindivision , -- Филиал sd.id as f_division , -- ПЭС sd.c_name as c_division , -- ПЭС ssd.id as f_subdivision , -- РЭС ssd.c_name as c_subdivision , -- РЭС case when ss.b_person then concat(ss.c_name1, ' ', ss.c_name2, ' ', ss.c_name3) else ss.c_name1 end as c_owner , -- Наименование потребителя/ФИО потребителя ss.c_code as c_code , -- Номер договора энергоснабжения/номер лицевого счета erp.imp_text as c_registr_pts_code, -- Код ТУ erp.c_registr_pts as c_registr_pts_name, -- Наименование ТУ coalesce(sa.c_city_name, sa.c_settlement_name) as c_settlement , -- Населенный пункт sa.c_street_name as c_street , -- Улица sa.c_house_name as c_house , -- Дом sa.c_flat_name as c_flat_name , -- Квартира ed.c_serial_number as c_serial_number , -- Заводской №ПУ edt.c_name as c_device_type , -- Тип ПУ coalesce(ed.n_rate, 1) as n_rate , -- Расчетный коэффициент ed.f_device as f_device , -- Единица оборудования concat(r.c_number, ' от ' || to_char(r.d_date, 'dd.MM.YYYY'::text)) as c_doc_number , -- Номер и дата документа es.c_name as c_time_zone , -- Тариф emr.n_value_prev as n_value_prev , -- Предыдущие контрольные показания emr.d_date_prev as d_date_prev , -- Дата предыдущих контрольных показаний concat(puResult.c_last_name || ' ', puResult.c_first_name || ' ', puResult.c_middle_name) as c_result_user, -- ФИО сотрудника снявшего показание concat(puRoute.c_last_name || ' ', puRoute.c_first_name || ' ', puRoute.c_middle_name) as c_route_user , -- ФИО сотрудника сформировавшего задание omr.n_value as n_value , -- Текущие контрольные показания omr.d_date as d_date , -- Дата текущих показаний null::timestamptz as d_export_date , -- Дата загрузки в расчетную систему true as b_attachment_exist, -- Наличие приложения ca.c_photo_links as c_photo_links , -- Ссылки на фотографии ca.f_files as f_files -- идентификаторы файлов фотографий from core.cd_results as cr -- точка inner join core.cd_points as cp on cp.id = cr.fn_point -- маршрут inner join core.cd_routes as r on r.id = cp.f_route -- точка учета inner join dbo.ed_registr_pts as erp on erp.id = cp.f_registr_pts -- ЛС inner join dbo.sd_subscr as ss on ss.id = erp.f_subscr -- РЭС inner join core.sd_subdivisions as ssd on ssd.id = erp.f_subdivision -- ПЭС inner join core.sd_divisions as sd on sd.id = erp.f_division -- Филиал inner join core.sd_divisions as sdd on sdd.id = sd.f_division -- Адрес inner join dbo.ss_address as sa on sa.id = erp.f_address -- Снятое показание inner join dbo.ed_output_meter_readings as omr on omr.fn_point = cp.id and omr.fn_user_point = cr.fn_user_point and omr.fn_result = cr.id -- предыдущее показание inner join dbo.ed_input_meter_readings as emr on emr.id = omr.fn_meter_reading inner join dbo.es_scales as es on es.id = emr.f_scale -- последний прибор на дату left join lateral( select ed.f_registr_pts, ed.c_serial_number, ed.f_device_type, ed.n_rate, nullif(ed.imp_text, '') as f_device, ed.id as f_device_guid, row_number() over(partition by ed.f_registr_pts order by ed.d_setup_date desc, ed.d_close_date desc) as n_row from dbo.ed_devices as ed where 1=1 and ed.f_registr_pts = cp.f_registr_pts and (ed.d_setup_date is null or ed.d_setup_date < cr.d_date) and (ed.d_close_date is null or ed.d_close_date >= cr.d_date) ) as ed on 1=1 and ed.n_row = 1 -- тип прибора учета left join dbo.es_device_types as edt on edt.id = ed.f_device_type -- сотрудник снявший показание left join core.pd_users as puResult on puResult.id = cr.fn_user -- сотрудник создавший маршрут left join ( select crh.fn_route, crh.fn_user, row_number() over(partition by crh.fn_route order by crh.d_date asc, crh.id) as n_row from core.cd_route_history as crh where crh.fn_status = _CREATED ) as crh on crh.fn_route = r.id and crh.n_row = 1 left join core.pd_users as puRoute on puRoute.id = crh.fn_user -- сылки на фотографии left join ( select ca.fn_result, string_agg(cf.id::text,';') as f_files, string_agg(concat(cs.c_value, '/file?id=', cf.id::text), ';') as c_photo_links from core.cd_attachments as ca -- файл inner join core.cd_files as cf on cf.id = ca.fn_file inner join core.cd_settings as cs on cs.c_key = 'ALL_URL' where ca.fn_type = _METER group by ca.fn_result ) as ca on ca.fn_result = cr.id where cr.fn_type in (_CMR, _ATO) and cr.d_date::date between _d_date_start and _d_date_end and case when _f_maindivisions is null or _f_maindivisions = '' or _f_maindivisions = '-1' then 1=1 else sdd.id in (select t.value::integer from json_array_elements_text(rpt.sf_rpt_csv_to_json(_f_maindivisions)) as t) end and case when _f_divisions is null or _f_divisions = '' or _f_divisions = '-1' then 1=1 else sd.id in (select t.value::integer from json_array_elements_text(rpt.sf_rpt_csv_to_json(_f_divisions)) as t) end and case when _f_subdivisions is null or _f_subdivisions = '' or _f_subdivisions = '-1' then 1=1 else erp.f_subdivision in (select t.value::integer from json_array_elements_text(rpt.sf_rpt_csv_to_json(_f_subdivisions)) as t) end and case when _subject = 'fl' then ss.b_person when _subject = 'ul' then not ss.b_person else true end ; END
Журнал регистрации выдачи пломбировочного материала
/** * @params {date} _d_date_start - дата начала периода * @params {date} _d_date_end - дата окончания периода * @params {text} _f_subdivisions - список участок * @params {text} _f_user_to - иден. пользователя * @params {text} _f_statuses - список статусов * * @example * [{ "action": "cf_ed_seals", "method": "Select", "data": [{ "params": [_d_date_start, _d_date_end, _f_main_division, _f_division, _f_subdivisions, _f_user] }], "type": "rpc", "tid": 0 }] */ BEGIN RETURN QUERY /* with items as ( select -- тут делаем сортировки по истории row_number() over(partition by s.id order by s.d_date_to asc) as n_row, s.id, -- иден. пломбы ss.c_const as c_status_const, -- иден. типа пломбы s.f_user_to as f_user_to, -- кому выдан s.f_user_from as f_user_from, -- кем выдан s.dx_created as d_date_create, -- дата создания coalesce(s.d_date_to, s.dx_created) as d_date_to, -- дата выдачи s.f_status as f_status -- статус from (select -- отсюда получаем информацию об истории s.id,s.dx_created, (json_array_elements(s.jb_history)->>'f_user_to')::integer as f_user_to, (json_array_elements(s.jb_history)->>'f_user_from')::integer as f_user_from, (json_array_elements(s.jb_history)->>'d_date_to')::timestamp with time zone as d_date_to, (json_array_elements(s.jb_history)->>'f_status')::integer as f_status from dbo.ed_seals as s where s.f_status is not null) as s inner join dbo.es_seal_status as ss ON s.f_status = ss.id where 1=1 ) */ select s.id, -- иден. пломбы 1::bigint as n_row, -- позиция ssd.id as f_subdivision, -- иден. участок ssd.c_name as c_subdivision, -- участок st.c_name as c_seal_type, -- Тип (наименование) пломбировочного материала concat(coalesce(s.c_prefix, ''), s.c_number) as c_seal_number, -- Номер пломбировочного материала concat(um.c_last_name || ' ', LEFT(um.c_first_name, 1) || '. ', LEFT(um.c_middle_name, 1) || '.') as c_user_mol, -- Фамилия и инициалы МОЛ ss.c_name as c_status_name, -- название статуса ss.c_const as c_status_const, -- иден. типа пломбы s.dx_created::timestamptz as d_date_create, -- дата создания пломбы s.d_date_to::timestamptz, -- дата выдачи/установка/снятия concat(ut.c_last_name || ' ', LEFT(ut.c_first_name, 1) || '. ', LEFT(ut.c_middle_name, 1) || '.') as c_user_to, -- кто получил ut.c_post as c_post_to, -- Должность получателя пломбировочного материала concat(uf.c_last_name || ' ', LEFT(uf.c_first_name, 1) || '. ', LEFT(uf.c_middle_name, 1) || '.') as c_user_from, -- кто выдал uf.c_post as c_post_from, -- Должность ответственного за ведение и хранение журнала case when ss.c_const in ('SETUP','TRASH') then to_char(s.d_date_to, 'dd.MM.YYYY'::text) end as d_date_setup_trash, -- Дата установки (возврата) пломбировочного материала rp.id as f_registr_pts, -- иден. точки учета case when sub.b_person then concat(sub.c_name1, ' ', sub.c_name2, ' ', sub.c_name3) else sub.c_name1 end as c_owner, -- потребитель r.id as f_result, -- иден. документа coalesce(s.c_document_trash, rt.c_name) as c_document_number, -- Дата акта (документ о списании пломбировочного материала) case when s.c_document_trash is null or s.c_document_trash = '' then to_char(r.d_date, 'dd.MM.YYYY'::text) else to_char(s.d_date_to, 'dd.MM.YYYY'::text) end as c_document_date -- Номер акта (документ о списании пломбировочного материала) --concat((case when s.c_document_trash is null or s.c_document_trash = '' then to_char(r.d_date, 'dd.MM.YYYY'::text) else to_char(i.d_date_to, 'dd.MM.YYYY'::text) end), ' ', coalesce(s.c_document_trash, rt.c_name)) as c_document -- наименование документа from dbo.ed_seals as s inner join dbo.es_seal_status as ss ON s.f_status = ss.id left join core.sd_subdivisions as ssd ON ssd.id = s.f_subdivision left join core.sd_divisions as sd ON sd.id = ssd.f_division left join core.sd_divisions as sdd ON sdd.id = sd.f_division left join dbo.ed_output_conn_seals as ocs ON s.id = ocs.fn_seal_new left join core.cd_results as r ON ocs.fn_result = r.id left join core.cs_result_types as rt ON rt.id = r.fn_type left join dbo.ed_registr_pts as rp ON rp.id = s.f_registr_pts left join dbo.sd_subscr as sub ON sub.id = rp.f_subscr left join dbo.es_seal_places as sp ON s.f_place = sp.id left join dbo.es_seal_types as st ON s.f_type = st.id left join core.pd_users as uf ON s.f_user_from = uf.id left join core.pd_users as ut ON s.f_user_to = ut.id left join core.pd_users as um ON s.f_user_mol = um.id where s.d_date_to between _d_date_start and _d_date_end + interval '1 day' and case when _f_maindivisions is null or _f_maindivisions = '' or _f_maindivisions = '-1' then 1=1 else sdd.id in (select t.value::integer from json_array_elements_text(rpt.sf_rpt_csv_to_json(_f_maindivisions)) as t) end and case when _f_divisions is null or _f_divisions = '' or _f_divisions = '-1' then 1=1 else sd.id in (select t.value::integer from json_array_elements_text(rpt.sf_rpt_csv_to_json(_f_divisions)) as t) end and case when _f_subdivisions is null or _f_subdivisions = '' or _f_subdivisions = '-1' then 1=1 else ssd.id in (select t.value::integer from json_array_elements_text(rpt.sf_rpt_csv_to_json(_f_subdivisions)) as t) end and (case when _f_user_to is null or _f_user_to = '' or _f_user_to = '-1' then 1=1 else s.f_user_to in (select t.value::integer from json_array_elements_text(rpt.sf_rpt_csv_to_json(_f_user_to)) as t) end) and (case when _f_statuses is null or _f_statuses = '' or _f_statuses = '-1' then 1=1 else ss.id in (select t.value::integer from json_array_elements_text(rpt.sf_rpt_csv_to_json(_f_statuses)) as t) end) order by s.d_date_to, s.id; END
Выгрузка показаний по ЮЛ за период
/** * @params {date} _d_date_start - дата начала периода * @params {date} _d_date_end - дата окончания периода * @params {text} _f_main_division - филиал * @params {text} _f_division - отделение * @params {text} _f_subdivisions - список участок * * @example * [{ "action": "cf_meters", "method": "Select", "data": [{ "params": [_d_date_start, _d_date_end, _f_main_division, _f_division, _f_subdivisions] }], "type": "rpc", "tid": 0 }] */ DECLARE _d_period_start date; _d_period_end date; BEGIN select _d_date_start, _d_date_end into _d_period_start, _d_period_end; RETURN QUERY select row_number() over(order by max(p.n_order) desc) AS n_num, -- номер п/п to_char(_d_period_start, 'dd.MM.YYYY') as d_period_start, to_char(_d_period_end, 'dd.MM.YYYY') as d_period_end, max(main_div.id) as f_maindivision, max(div.id) as f_division, max(rp.f_subdivision) as f_subdivision, max(sub_div.c_dep_code) as c_dep_code, -- Код участка(РЭС) max(s.f_partners) as f_partners, -- Код/идентификатор абонента max(s.c_name1) as c_owner, -- Наименование абонента max(ad.f_conn_points) as f_conn_points, -- Код/идентификатор объекта учета ЮЛ max(ad.c_name_obj) as c_name_obj, -- Наименование объекта max(s.c_code) as c_subscr, -- Код абонента max(rp.imp_text) as c_registr_pts_code, -- код ТУ max(d.link) as c_device_code, -- Код/идентификатор ПУ max(d.c_serial_number) as c_device_number, -- Заводской номер max(dt.c_name) as c_device_model, -- Наименование модели string_agg(sc.c_name, ', ') as c_scale_name, -- Тариф string_agg(to_char(imp.d_date_prev, 'dd.MM.YYYY'), ', ') as c_date_prev, -- Дата показания string_agg(round(imp.n_value_prev, ((dt.n_digits % floor(dt.n_digits)) * 10)::integer)::text, ', ') as c_value_prev, -- Значение показания string_agg(to_char(omr.d_date, 'dd.MM.YYYY'), ', ') as c_date_current, -- Дата текущих показаний string_agg(round(omr.n_value, ((dt.n_digits % floor(dt.n_digits)) * 10)::integer)::text, ', ') as c_value_current -- Текущие показаний from dbo.ed_output_meter_readings as omr inner join dbo.ed_input_meter_readings as imp ON imp.id = omr.fn_meter_reading inner join core.cd_points as p ON omr.fn_point = p.id inner join core.cd_results as rr ON rr.id = omr.fn_result inner join dbo.ed_devices as d ON d.f_registr_pts = p.f_registr_pts inner join dbo.es_device_types as dt ON d.f_device_type = dt.id inner join dbo.ed_registr_pts as rp ON p.f_registr_pts = rp.id inner join core.sd_subdivisions as sub_div ON rp.f_subdivision = sub_div.id inner join core.sd_divisions as div ON rp.f_division = div.id left join core.sd_divisions as main_div ON div.f_division = main_div.id inner join dbo.sd_subscr as s ON rp.f_subscr = s.id inner join dbo.ss_address as ad ON rp.f_address = ad.id inner join dbo.es_scales as sc on imp.f_scale = sc.id where s.b_person = false and omr.d_date between _d_date_start and _d_date_end + interval '1 day' and (case when _f_main_division is null or _f_main_division = '' or _f_main_division = '-1' then 1=1 else _f_main_division::integer = main_div.id end) and (case when _f_division is null or _f_division = '' or _f_division = '-1' then 1=1 else _f_division::integer = div.id end) and (case when _f_subdivisions is null or _f_subdivisions = '' or _f_subdivisions = '-1' then 1=1 else rp.f_subdivision in (select t.value::integer from json_array_elements_text(rpt.sf_rpt_csv_to_json(_f_subdivisions)) as t) end) group by p.id order by p.n_order desc; END
Выгрузка показаний по ФЛ за период
/** * @params {date} _d_date_start - дата начала периода * @params {date} _d_date_end - дата окончания периода * @params {integer} _f_main_division - филиал * @params {integer} _f_division - отделение * @params {text} _f_subdivisions - список участок * * @example * [{ "action": "cf_meters_by_person", "method": "Select", "data": [{ "params": [_d_date_start, _d_date_end, _f_main_division, _f_division, _f_subdivisions] }], "type": "rpc", "tid": 0 }] */ DECLARE _d_period_start date; _d_period_end date; BEGIN select _d_date_start, _d_date_end into _d_period_start, _d_period_end; RETURN QUERY select row_number() over(order by t.n_order desc) AS n_num, -- номер п/п * from (select to_char(_d_period_start, 'dd.MM.YYYY') as d_period_start, to_char(_d_period_end, 'dd.MM.YYYY') as d_period_end, main_div.id as f_maindivision, div.id as f_division, rp.f_subdivision as f_subdivision, s.c_code as c_subscr, -- № л/сч (ККС) rp.imp_text as c_document_code, -- Код Договора d.link as c_sap_code, --Код ЕО SAP concat(coalesce(ad.c_region || ', ', ''), coalesce(ad.c_raion || ', ', ''), coalesce(ad.c_city_name || ', ', ''), coalesce(ad.c_settlement_name, '')) as c_area_name, -- Нас. пункт ad.c_street_name as c_street_name, -- Улица ad.c_house_name as c_house_number, -- № дома ad.c_flat_name as c_appartament_number, -- № квартиры concat(s.c_name1, ' ', s.c_name2, ' ', s.c_name3) as c_owner, -- ФИО потребителя d.c_serial_number as c_device_number, -- Заводской № счетчика dt.c_name as c_device_model, -- Тип счетчика dt.n_digits as n_digits, -- Разрядность sc.c_name as c_scale_name, -- Вид тарифа to_char(imp.d_date_prev, 'dd.MM.YYYY') as c_date_prev, -- Дата предыдущих контрольных показаний REPLACE(round(imp.n_value_prev, ((dt.n_digits % floor(dt.n_digits)) * 10)::integer)::text, '.', ',') as c_value_prev, -- Предыдущие контролные показания to_char(omr.d_date, 'dd.MM.YYYY') as c_date_current, -- Фактическая дата снятия показаний REPLACE(round(omr.n_value, ((dt.n_digits % floor(dt.n_digits)) * 10)::integer)::text, '.', ',') as c_value_current, -- Показания прибора учета на дату снятия nullif(rr.c_notice,'') as c_notice, -- Примечание row_number() over(partition by rr.fn_point, imp.id order by rr.d_date desc) as n_row, rr.fn_user, p.n_order from dbo.ed_output_meter_readings as omr inner join dbo.ed_input_meter_readings as imp ON imp.id = omr.fn_meter_reading inner join core.cd_points as p ON omr.fn_point = p.id inner join core.cd_results as rr ON rr.id = omr.fn_result inner join dbo.ed_devices as d ON d.f_registr_pts = p.f_registr_pts inner join dbo.es_device_types as dt ON d.f_device_type = dt.id inner join dbo.ed_registr_pts as rp ON p.f_registr_pts = rp.id inner join core.sd_divisions as div ON rp.f_division = div.id left join core.sd_divisions as main_div ON div.f_division = main_div.id inner join dbo.sd_subscr as s ON rp.f_subscr = s.id inner join dbo.ss_address as ad ON rp.f_address = ad.id inner join dbo.es_scales as sc on imp.f_scale = sc.id where s.b_person and omr.d_date between _d_date_start and _d_date_end + interval '1 day' and (case when _f_main_division is null or _f_main_division = '' or _f_main_division = '-1' then 1=1 else _f_main_division::integer = main_div.id end) and (case when _f_division is null or _f_division = '' or _f_division = '-1' then 1=1 else _f_division::integer = div.id end) and (case when _f_subdivisions is null or _f_subdivisions = '' or _f_subdivisions = '-1' then 1=1 else rp.f_subdivision in (select t.value::integer from json_array_elements_text(rpt.sf_rpt_csv_to_json(_f_subdivisions)) as t) end) --group by p.id ) as t where t.n_row = 1 order by t.n_order desc; END
Отчет "Статистика отработки маршрутов"
DECLARE _METER_REDINGS int4; -- Снятие показаний _CHECK int4; -- Проверка _LIMIT int4; -- Ограничение _RENEW int4; -- Возобновление _SETUP int4; -- Установка _REPLACE int4; -- Замена _CMR int4; -- Акт снятия контрольного показания _OOV int4; -- Отказ от выполнения _AIP int4; -- Акт инструментальной проверки _AVE int4; -- Акт возобновления энергоснабжения _AVOE int4; -- Акт о введении ограничения режима потребления _ABUP int4; -- Акт о безучетном потреблении BEGIN select c.id into _METER_REDINGS from core.cs_point_types as c where c.c_const = 'METER_REDINGS'; select c.id into _CHECK from core.cs_point_types as c where c.c_const = 'CHECK'; select c.id into _LIMIT from core.cs_point_types as c where c.c_const = 'LIMIT'; select c.id into _RENEW from core.cs_point_types as c where c.c_const = 'RENEW'; select c.id into _SETUP from core.cs_point_types as c where c.c_const = 'SETUP'; select c.id into _REPLACE from core.cs_point_types as c where c.c_const = 'REPLACE'; select c.id into _CMR from core.cs_result_types as c where c.c_const = 'CMR' ; select c.id into _OOV from core.cs_result_types as c where c.c_const = 'OOV' ; select c.id into _AIP from core.cs_result_types as c where c.c_const = 'AIP' ; select c.id into _AVE from core.cs_result_types as c where c.c_const = 'AVE' ; select c.id into _AVOE from core.cs_result_types as c where c.c_const = 'AVOE'; select c.id into _ABUP from core.cs_result_types as c where c.c_const = 'ABUP'; RETURN QUERY -- отделения with subdivisions as ( select sdd.id as f_maindivision , sdd.c_name as c_maindivision , sd.id as f_division , sd.c_name as c_division , ssd.id as f_subdivision , ssd.c_name as c_subdivision from core.sd_subdivisions as ssd -- отделение inner join core.sd_divisions as sd on sd.id = ssd.f_division -- филиал inner join core.sd_divisions as sdd on sdd.id = sd.f_division where 1=1 and case when _f_maindivisions is null or _f_maindivisions = '' or _f_maindivisions = '-1' then true else sdd.id in (select t.value::integer from json_array_elements_text(rpt.sf_rpt_csv_to_json(_f_maindivisions)) as t) end and case when _f_divisions is null or _f_divisions = '' or _f_divisions = '-1' then true else sd.id in (select t.value::integer from json_array_elements_text(rpt.sf_rpt_csv_to_json(_f_divisions)) as t) end and case when _f_subdivisions is null or _f_subdivisions = '' or _f_subdivisions = '-1' then true else ssd.id in (select t.value::integer from json_array_elements_text(rpt.sf_rpt_csv_to_json(_f_subdivisions)) as t) end ), -- маршруты routes as ( select cr.id as f_route, cur.c_inspectors, case when crs.c_const = 'TRANSFERRED' then true else false end as b_plan from core.cd_routes as cr inner join core.cd_userinroutes as uir on uir.f_route = cr.id -- только определенные статусы маршрутов inner join core.cs_route_statuses as crs on crs.id = cr.f_status and crs.c_const in ('TRANSFERRED', 'RECEIVED', 'PROCCESS', 'DONED', 'NOT_CONFIRMED', 'CONFIRMED', 'EXPIRED', 'CANCEL', 'EXPORT') -- вся бригада inner join ( select cur.f_route, string_agg(concat(pu.c_last_name, ' ', left(pu.c_first_name,1) || '.', left(pu.c_middle_name, 1) || '.'), ',') as c_inspectors from core.cd_userinroutes as cur inner join core.pd_users as pu on pu.id = cur.f_user group by cur.f_route ) as cur on cur.f_route = cr.id where 1=1 and case when _f_user is null or _f_user = '' or _f_user = '-1' then true else uir.f_user in (select t.value::integer from json_array_elements_text(rpt.sf_rpt_csv_to_json(_f_user)) as t) end and cr.d_date_start >= _d_date_start and _d_date_end <= (CASE WHEN cr.b_extended THEN cr.d_extended ELSE cr.d_date_end END) group by cr.id, cur.c_inspectors, case when crs.c_const = 'TRANSFERRED' then true else false end ), -- точки учета registr_pts as ( select cp.id as f_point, cp.f_route as f_route, cp.f_registr_pts as f_registr_pts, cp.f_type as f_type, ssd.f_maindivision , ssd.c_maindivision , ssd.f_division , ssd.c_division , ssd.f_subdivision , ssd.c_subdivision , erp.c_substation , erp.c_line_substation , erp.c_tp from routes as r -- точки inner join core.cd_points as cp on cp.f_route = r.f_route and cp.f_type in (_METER_REDINGS, _CHECK, _LIMIT, _RENEW, _SETUP, _REPLACE) -- только определенные виды работ -- учетные показатели inner join dbo.ed_registr_pts as erp on erp.id = cp.f_registr_pts -- фильтр по участкам inner join subdivisions as ssd on ssd.f_subdivision = erp.f_subdivision and ssd.f_division = erp.f_division where 1=1 -- фильтр по типам работ and case when nullif(trim(_f_route_types), '') is null or _f_route_types = '-1' then true else cp.f_type in (select t.value::integer from json_array_elements_text(rpt.sf_rpt_csv_to_json(_f_route_types)) as t) end -- фильтр по подстанции and case when nullif(trim(_c_substation), '') is null or _c_substation = '-1' then true else lower(erp.c_substation) like '%'|| lower(trim(_c_substation)) ||'%' end -- фильтр по фидеру 6-10кВ and case when nullif(trim(_c_line_substation), '') is null or _c_line_substation = '-1' then true else lower(erp.c_line_substation) like '%' || lower(trim(_c_line_substation)) || '%' end -- фильтр по ТП and case when nullif(trim(_c_tp), '') is null or _c_tp = '-1' then true else lower(erp.c_tp) like '%' || lower(trim(_c_tp)) || '%' end ), results as ( select erp.f_point, --наличие актов определенного типа по строке задания max(case when cr.fn_type = _CMR then 1 else 0 end) AS n_cmr, max(case when cr.fn_type = _OOV then 1 else 0 end) AS n_oov, max(case when cr.fn_type = _AIP then 1 else 0 end) AS n_aip, max(case when cr.fn_type = _AVE then 1 else 0 end) AS n_ave, max(case when cr.fn_type = _AVOE then 1 else 0 end) AS n_avoe, max(case when cr.fn_type = _ABUP then 1 else 0 end) AS n_abup from registr_pts as erp inner join core.cd_results as cr on cr.fn_point = erp.f_point group by erp.f_point ) -- итоговый вывод select to_char(_d_date_start, 'dd.MM.YYYY'::text) as d_date_start, to_char(_d_date_end, 'dd.MM.YYYY'::text) as d_date_end, erp.f_maindivision , erp.c_maindivision , erp.f_division , erp.c_division , erp.f_subdivision , erp.c_subdivision , r.c_inspectors , erp.c_substation , erp.c_line_substation , erp.c_tp , -- Снятие показаний count(case when erp.f_type = _METER_REDINGS and r.b_plan then erp.f_registr_pts end) as n_meter_redings_plan, count(case when erp.f_type = _METER_REDINGS and cr.n_cmr = 1 then erp.f_registr_pts end) as n_meter_redings_cmr, count(case when erp.f_type = _METER_REDINGS and cr.n_oov = 1 then erp.f_registr_pts end) as n_meter_redings_oov, count(case when erp.f_type = _METER_REDINGS and cr.f_point is not null then erp.f_registr_pts end) as n_meter_redings_done, -- Проверки count(case when erp.f_type = _CHECK and r.b_plan then erp.f_registr_pts end) as n_check_plan, count(case when erp.f_type = _CHECK and cr.n_aip = 1 then erp.f_registr_pts end) as n_check_aip, count(case when erp.f_type = _CHECK and cr.n_abup = 1 then erp.f_registr_pts end) as n_check_abup, count(case when erp.f_type = _CHECK and cr.n_oov = 1 then erp.f_registr_pts end) as n_check_oov, count(case when erp.f_type = _CHECK and cr.f_point is not null then erp.f_registr_pts end) as n_check_done, -- Допуск в эксплуатацию count(case when erp.f_type =_SETUP and r.b_plan then erp.f_registr_pts end) n_permission_setup_plan , count(case when erp.f_type = _REPLACE and r.b_plan then erp.f_registr_pts end) n_permission_replace_plan , count(case when erp.f_type = _REPLACE and cr.n_aip = 1 then erp.f_registr_pts end) n_permission_aip , count(case when erp.f_type = _REPLACE and cr.n_abup = 1 then erp.f_registr_pts end) n_permission_abup , count(case when erp.f_type in (_SETUP, _REPLACE) and cr.n_oov = 1 then erp.f_registr_pts end) n_permission_oov , count(case when erp.f_type in (_SETUP, _REPLACE) and cr.f_point is not null then erp.f_registr_pts end) n_permission_done , -- Ограничение и возобновление count(case when erp.f_type =_LIMIT and r.b_plan then erp.f_registr_pts end) n_limit_limit_plan, count(case when erp.f_type =_RENEW and r.b_plan then erp.f_registr_pts end) n_limit_renew_plan, count(case when erp.f_type =_LIMIT and cr.n_avoe = 1 then erp.f_registr_pts end) n_limit_limit, count(case when erp.f_type =_RENEW and cr.n_ave = 1 then erp.f_registr_pts end) n_limit_renew, count(case when erp.f_type =_LIMIT and cr.n_oov = 1 then erp.f_registr_pts end) n_limit_oov, count(case when erp.f_type in (_LIMIT, _RENEW) and cr.f_point is not null then erp.f_registr_pts end) n_limit_done from registr_pts as erp inner join routes as r on r.f_route = erp.f_route -- результаты работ left join results as cr on cr.f_point = erp.f_point group by erp.f_maindivision , erp.c_maindivision , erp.f_division , erp.c_division , erp.f_subdivision , erp.c_subdivision , erp.c_substation , erp.c_line_substation , erp.c_tp , r.c_inspectors ; END
Преобразование csv в json
/** * @params {text} _csv - входная csv строка * @returns {json} JSON */ try { var data = _csv.split(','); return JSON.stringify(data); } catch(e) { return JSON.stringify([]); }
Generated by PostgreSQL Autodoc