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