Все вопросы
Есть проблема с ботом, что при выполнении команды «leave» (см. ниже) бот не выходит из голосового чата. Первая команда работает стабильно, а вот вторая, при ее выполнении бот отписывает, что .
29 показов
Возник вопрос, как вывести 10 имён рандомно, но чтобы они не повторялись? [дубликат]
введите сюда код static void Main(string[] args) < string[] MassNames = (string[])Enum.GetNames(typeof(Names)); Random random = new Random(); students people = new .
Как получить callback из ответа бота в pyrogram
У меня есть юзербот для работы с обычным ботом. Мне надо чтобы мой юзербот мог нажимать на кнопки в боте, смотрел в документации(https://docs.pyrogram.org/api/bound-methods/Message.click), там говорят .
Unity FPS на Android меняется 29/59
При запуске игры на Android фпс показывается 29, 59 (на протяжении от нескольких секунд до 3-5 минут), после фпс выравнивается и становится стабильными 60 (телефон как раз поддерживает 60 герц). Также .
В чём причина проблемы git fatal: could not create work tree dir ‘jww-standard-lib’: No such file or directory
Я хочу клонировать репозиторий с git hub но получаю ошибку fatal: could not create work tree dir ‘jww-standard-lib’: No such file or directory
Как можно запретить пользователю спамить отправкой писем
У меня есть функция, которая создает токен с данными юзера и отправляет его ему на почту, проблема в том, что эту функцию можно вызывать много раз, а нужно ввести ограничение на отправку писем(не чаще .
65 показов
Как найти определенные слова в строке и вывести их вместе с их индексами?
Нужно сделать следующее: в тексте найти такие слова как «of» «in» «new» «from» «this» «rail» «spliter», вывести их в консоль и .
30 показов
Как собрать ядро с использованием каналов (pipe) вместо временных файлов?
Всем привет. Очень сильно прошу подробно описать, что я должен сделать, чтобы собрать ядро с использованием pipe. Не совсем понимаю, куда я должен запихнуть этот ключ. Если в makefile, то куда.
Как удалить одинаковые названия в переменной?
Есть переменная, в ней список картинок через запятую: $string = ‘site.com/50b/gdh8ec6267b05384/DSC0565615.jpg, site.com/d70/d709cce76a2b82/DSC05660_16.jpg, site.com/81a/81a33d1b802/DSC05662_37.jpg, .
Создание слайдера на HTML, CSS, JS
Подскажите пожалуйста как сделать на HTML, CSS, JS такой слайдер как на этой странице https://www.superlist.com/. Чтобы когда видео заканчиволось, начиналось новое и следущий заголовок менял цвет, а .
35 показов
Как узнать текущий URl а не URL обработчика в PHP
Как можно вывести текущий урл страницы если я использую обработчик? То есть если я нахожусь на странице likes и запрашиваю $_SERVER[‘REQUEST_URI’] при открытии страницы всё в порядке, скрипт выдаёт .
18 показов
Как деактивировать выбор даты при повторном нажатии на дату в библиотеке react calendar?
Подскажите пожалуйста, как деактивировать выбор даты при повторном нажатии на нее в react calendar?
115 показов
Как перенести файлы из vs code в visual studio?
Я писал в vs code и узнал, что на C++ лучше писать в visual studio. Написал я много и хотел бы перенести все свои файлы в visual studio.
Какова сложность (Big O Notation) операции grep текстового файла, если мы проверяем строку по частичному совпадению?
Если я правильно понимаю, то сложность операции команды grep с текстовым файлом будет O(n), если мы ищем строку по полному совпадению. Если мы грепаем файл по частичному совпадению строк, сложность .
106 показов
Unity Непонятные просадки FPS на Android
При запуске игры на Android отображается около 40 фпс, но через некоторое время (от 1-2 секунд до нескольких минут) фпс выравнивается и становится стабильными 60 (телефон как раз поддерживает 60 герц).
15 30 50 на странице
-
Важное на Мете
Связанные метки
Дизайн сайта / логотип © 2023 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2023.10.27.43697
Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.
Описание конструктора отчетов
Конструктор отчетов позволяет делать запросы напрямую к БД. Описание ограничений, возможностей и синтаксиса используемого диалекта SQL Вы можете найти в документации Firebird 2.1.
Конструктор отчетов находится на вкладке «Отчеты» в основном меню биллинга
Отчеты разбиваются на группы. Не относящиеся ни к одной попадают в группу «Не определено». Группы настраиваются в справочниках:
По-умолчанию в биллинге идет более 60 отчетов. Вы так же можете создать свои или воспользоваться одним из примеров из данной статьи. Для добавления отчета нажмите кнопку «Добавить» в конструкторе. Ксли требуется выберите категорию, В поле «SQL запрос» вставьте текст отчета и сохраните.
Результат выполнения отчета можно отобразить браузере или выгрузить:
- В формате DBF
- В CSV с разделением «,» (запятая)
- В Excel (xlsx)
Для выполнения отчета выберите формат отображения и нажмите кнопку «Выполнить запрос»
Фильтры данных (параметры полей формы)
В отчётах можно добавить фильтры — выбор информации, например счетов и актов, только за выбранные даты или период дат, отфильтровать по абонентам и тд.
Фильтры подставляют указанные данные в тело отчёта и потом он выполняется.
Фильтры указываются примерно по такой схеме:
':title|type[params]$'
- : — указывает, что это строка с переменной
- title — заголовок, отображаемый на форме
- | — разделитель заголовка и типа
- type[params] — тип с параметрами
- $ — флаг отмечает обязательную переменную, он обязателен для всех фильтров
Ниже они описаны подробно.
Выбор дат
date — дата, указывается без параметров, отображает на форме календарь выбора даты
BILL_DATE between ':1-Начало|date$' and ':2-Конец|date$ 23:59:59'
Выбор периодов
monthchoice — отобразит список периодов в формате «ММ.ГГГГ месяц_прописью»
-
12 последних месяцев
':Дата Список месяцев|monthchoice|$'
':Дата Список месяцев|monthchoice|3$'
':Дата Список месяцев|monthchoice|period_end_date|select[financeoperations]$'
':Дата Список месяцев|monthchoice|period_end_date|select[financeoperations,op_type=2,storno=0]$'
Список вариантов
choices — список, параметры — это элементы списка
Homes.City = ':Город|choices[Москва^]Москва^[Волгоград^]Волгоград]$' owner_id in (:Администратор|choices[33^]root^[1005^]Василий^[1007,1005^]Василий или Михаил]$) Abonents.Id = ':Абонент|choices[35^]Михаил^[40^]Володя]$'
Список вариантов из сравочников биллинга
select — список, построенный на основе модели, подобно работе API, параметры содержат модель (обязательно) и фильтры
a.parent_id = ':Группа|select[Abonents,is_folder=1]$' h.id = ':Заявка|select[HDSK]$'
Строка для ввода произвольных данных:
Отсутстие параметров предложет ввести произвольные данные.
':Введите число$'
Выполнение отчёта из консоли скриптом make_reports.pyc
Для того, чтобы запустить выполнение отчета из консоли, необходимо:
-
Перейти в контейнер биллинга
chroot /app/asr_billing/
python2.7 /usr/lib/python2.7/site-packages/jobs_worker/jobs_scripts/make_reports.pyc -r 105
У скрипта есть несколько опций и пресетов для выгрузок в СОРМ3
Дополнительные опции запуска
Опция | Полный формат | Пример | Описание |
---|---|---|---|
-c CHARSET | —charset=CHARSET | -c utf8 | Кодировка вывода, по-умолчанию: cp1251 |
-p PRESET | —preset=PRESET | -p norsi-trans | Использовать пресет настроек для конкретного СОРМ Доступные пресеты: mfi-soft, vasexperts, norsi-trans, signaltec |
-s SEPARATOR | —separator=SEPARATOR | -s «|» | Символ разделителя полей, по-умолчанию: точка с запятой «;» |
-f | —safe-separator | — | Удалять символ разделителя из содержимого полей. Если задан этот флаг, то в каждом поле отчета символ разделителя (из опции —separator) будет заменяться на пробел. Это позволяет гарантировать, что разделитель полей встречается только между полями, но не в самих полях. |
-q QUOTE | —quote=QUOTE | -q \» | Символ экранирования полей, по-умолчанию: нет Чтобы задать двойную кавычку в bash её нужно экранировать: make_reports.pyc —quote=\» Все остальные символы можно передать в двойных кавычках, например: make_reports.pyc —quote=»‘» |
-b | —double-quote | — | Дублировать символ экранирования, если он встречается внутри поля |
-w | —wrap | — | Экранировать только поля, внутри которых встречаются символ разделителя или символ экранирования |
Пример запуска make_reports с опциями
- Выгрузить отчет #105 в формате, пригодном для СОРМ от компании «Норси-Транс» и кодировке UTF-8:
python /usr/lib/python2.7/site-packages/jobs_worker/jobs_scripts/make_reports.pyc -r 105 -c utf8 -p norsi-trans
python /usr/lib/python2.7/site-packages/jobs_worker/jobs_scripts/make_reports.pyc -r 105 -s "," -q \" -w
python /usr/lib/python2.7/site-packages/jobs_worker/jobs_scripts/make_reports.pyc -r 105 -s ";" -q \" -f
Выполнение отчёта из консоли утилитой sqlexec
Запрос к базе данных можно выполнить передав его утилите sqlexec, например так:
Команда
sqlexec "select count(*) from abonents"
COUNT ============ 14
Запрос можно написать в несколько строк:
Команда
sqlexec "select count(*) from abonents"
Это удобно, если запрос сложный и объёмный. Вывод будет таким же, как у команды выше.
Выполнение запроса для использования в скриптах
Тут возможны два варианта.
С помощью sqlexec
Если отчёт достаточно простой, его можно выполнить с помощью sqlexec. Но нужно учитвать несколько моментов:
- На самом деле утилита работает в контейнере asr_billing
- Вывод лучше отформатировать для удобства написания скриптов и сохранения данных в переменные
- Частично отформатировать Вывод можно средствами SQL:
- либо «set heading off;» — уберёт заголовки, это удобно если Вы выгружаете, например, список каких-то позиций (абонентов, финансовых операций) для обработки каждой в отдельности
- либо «set list on;» — «перевернёт» данные, отразит их в виде колонок вместо таблицы
Ниже приведён скрипт, в котором показано как работать с выводом в том или ином виде, включая одиночные значения и списки:
#!/bin/bash abonent_count=$(chroot /app/asr_billing/ /usr/local/bin/sqlexec "set list; select count(*) from abonents where is_folder=0" | awk '$2') folder_count=$(chroot /app/asr_billing/ /usr/local/bin/sqlexec "set heading off; select count(*) from abonents where is_folder=1" | sed 's/ *//g; /^$/d') echo "В биллиге сейчас вот столько абонентов, администраторов, и операторов связи: $" echo "В биллиге сейчас вот столько папок: $" echo "Список папок:" chroot /app/asr_billing/ /usr/local/bin/sqlexec "set heading off; select name from abonents where is_folder=1" | sed 's/ *//g; /^$/d' | \ while read folder; do echo "* $" done
Если sqlexec не очень подходит, отчёт слишком сложный
Если отчёт слишком сложный и его удобней сохранить в файл, тогда сделайте следующее:
- Убедитесь что запрос в файле заканчивается символом точки с запятой: «;»
- Положите файл где-нибудь внутри контейнера asr_billing
- Выполните запрос командой isql-fb, ключём -i укажите путь к файлу
Например, можно положить скрипт в папку opt, внутри контейнера, с таким содержимым:
Файл /app/asr_billing/opt/abonents.sql
select count(*) from abonents where is_folder=0 ;
Тогда запрос к БД можно выплнить такой командой:
Команда
chroot /app/asr_billing isql-fb 169.254.30.50:/var/db/billing.gdb -p servicem -u SYSDBA -i /opt/abonents.sql
Заметьте, что для «хост» системы, файл находится по пути /app/asr_billing/opt/abonents.sql, но утилита isql-fb находится в контейнере, и для неё нужно указывать «относительный» путь: /opt/abonents.sql, убрав адрес корневой папки контейнера. Вывод отчёта Вы так же можете форматировать командными утилитами ОС, сохранять в переменные или передавать в циклы для дальнейшей обработки.
Описание полей
К большенсту полей БД существуют описания. Описание всех полей можно получить выполнив команду sqlexeс «show comments», например:
sqlexec "show comments" | head -n 5 COMMENT ON DOMAIN RAD_ATTRIB IS Radius-attribute; COMMENT ON COLUMN ABONENTS.ID IS №; COMMENT ON COLUMN ABONENTS.NAME IS Название/ФИО; COMMENT ON COLUMN ABONENTS.PARENT_ID IS Группа; COMMENT ON COLUMN ABONENTS.CONTRACT_NUMBER IS Номер договора;
Поля, отраженные в веб-интерфейсе (настройки абонента, тарифов, услуг и тд) как правило имею описание согласно названию. На примере настроек тарифа, вкладка «Опции», параметры Обещанного платежа:
sqlexec "show comments" | grep "Разрешать подключение обещанного платежа только один раз в текущий месяц" COMMENT ON COLUMN TARIF.PROMISE_PAY_ONLY_THIS_MONTH IS Разрешать подключение обещанного платежа только один раз в текущий месяц;
Особенности SQL в Firebird
UNION (UNION ALL) и ORDER BY
В Firebird Order By должен быть последним оператором, сортируя всю выборку, например:
select col1, col2, col3 from table1 union all select '', 'Итого', sum(col3) from table1 order by 1
Как поставить «Итого» в конец строки
В примере выше вторая часть запроса выбирает итого по первой, при этом «Итого» окажется первой строкой выборки так как при сортировке пустая строка «выше» любого символа.
Чтобы «Итого» переместить в конец списка, можно использовать «невидимый» символ Юникода подобный пробелу, но стоящий в Юникоде ниже всех Кириллицы:union all select ' '
Список символов можно посмотреть в Википедии, в примере использован символ U+2003 «em space»
Особенность сортировки числовых значений
В примере выше выборка будет отсортирована как текстовая. То есть порядок чисел будет: 1,10,100,2,20,200. Что бы отсортировать выборку как числа нужно убрать строковые константы в полях и заменить их на значение null. Тогда результат будет такой: 1,2,10,20,100,200.
select col1, col2, col3 from table1 union all select null, null, sum(col3) from table1 order by 3
Процедуры Carbon Soft
Для работы с базой мы добавили ряд собственных процедур, которые помогут найти нужные данные и верно их отобразить в отчётах в соответствии с архитектурой биллинга.
Получение списка вложенных групп и абонентов в дереве групп
GLN_RECURSIVE_GROUP_WALK
Принимает: GR_ID — ID группы
Возвращает: GROUP_ID — ID запрошенной группы и всех её подгруппGLN_RECURSIVE_ABONENTS_GET
Принимает: GROUP_ID — ID группы
Возвращает: ABONENT_ID — ID абонентов в указанной группе и всех её подгруппахПримеры запросов
SELECT group_id FROM GLN_RECURSIVE_GROUP_WALK(1) SELECT abonent_id FROM GLN_RECURSIVE_ABONENTS_GET(1)
Полезные функции в Firebird
iif
Функция iif аналогична опратору сравнения if then else.
Если верно то возвращается иначе .
Удобно использовать, если в выборке встречаются пустые поля. В конструкторе отчётов они выводятся как none. Пример:select iif(a.home_id is null, 'НеУказан',h.street || ' ' || h.s_number) from abonents a left join homes h on a.home_id=h.id order by 1
В примере, вместо слова None будет стоять НеУказан.
Также можно заменять числовые значения текстом:
select name, iif(deleted=1,'Удалён','') from abonents
Удалённые абонеты будут выведены с пометкой Удалён, дейсвующие без отметки.
Примеры отчётов
Список абонентов, подключенных к NAS с ip 172.16.0.6 в формате id, фио, номер телефона
select UR.user_id as ID, U.identify as FIO, AV.attribute_value as TELEFON from users_radiusauth UR left join USERS U on U.id=UR.user_id left join ATTRIBUTE_VALUES AV on AV.user_id=UR.user_id and AV.ATTRIBUTE_ID=1 where UF_IP2STRING(UR.NAS_IP_ADDRESS)='172.16.0.6' order by U.identify
Список абонентов, оплативших через платежную систему «Qiwiwallet» в формате логин, ФИО, сумма, дата
select LOGIN_IN as LOGIN, USER_NAME_OUT as FIO, SUMMA_IN as SUMMA, OPERATOR_DATE_IN as DATA from PAY_LOG where MSG_OUT='ACCEPTED' and ACT_IN='PAY' and PAY_OPERATOR='Qiwiwallet' order by USER_NAME_OUT
Список привязки абонентов к порту коммутатора (ФИО, Имя коммутатора, IP коммутатор, Номер порта, Номер vlan) с группировкой по номеру коммутатора
select u.identify as FIO, sw.name as NAME, uf_ip2string(sw.ip) as SWITCH_IP, sp.num as PORT, sp.vlan as VLAN from switch_ports sp join users u on u.id=sp.user_id join switch sw on sw.id=sp.switch_id order by sp.switch_id
Общее количество абонентов по группам
select name as "Группа", (select count(1) from abonents where parent_id=grp.id) as "Количество абонентов" from abonents grp where is_folder=1
Средняя выручка(в расчёте на одного абонента) за предыдущий и текущий месяц или с возможностью выбора периода
select cast(avg(ss) as numeric(18,2)) as "Выручка", year_number as "Год", month_number as "Месяц" from (select sum(summ) as ss,year_number,month_number from counters where (current_date - cast(year_number || '-' || month_number || '-01' as date)
Информация об абонентах с реквизитами и скоростями(CEIL_IN) - Номер договора, Имя абонента, Название тарифа, Паспорт серия, Паспорт номер, Кем выдан, Когда выдан, адрес, номер телефона (сортировка по имени абонента)
select A.CONTRACT_NUMBER, A.NAME, T.NAME, ABSP.CEIL_IN, (select AV.ATTRIBUTE_VALUE from ATTRIBUTE_VALUES AV where AV.ATTRIBUTE_ID = 14 and AV.ABONENT_ID = A.ID), (select AV.ATTRIBUTE_VALUE from ATTRIBUTE_VALUES AV where AV.ATTRIBUTE_ID = 13 and AV.ABONENT_ID = A.ID), (select AV.ATTRIBUTE_VALUE from ATTRIBUTE_VALUES AV where AV.ATTRIBUTE_ID = 16 and AV.ABONENT_ID = A.ID), (select AV.ATTRIBUTE_VALUE from ATTRIBUTE_VALUES AV where AV.ATTRIBUTE_ID = 17 and AV.ABONENT_ID = A.ID), H.CITY, H.STREET, H.S_NUMBER, H.S_LITER, A.A_HOME_NUMBER, A.SMS from ABONENTS A left join TARIF T on T.ID = A.TARIF_ID left join ABONENTS_SPEED ABSP on ABSP.ABONENT_ID = A.ID left join HOMES H on H.ID = A.HOME_ID where A.DELETED != 1 and A.IS_FOLDER != 1 order by A.NAME
Отчет по списаниям по абонентам в формате (число, id группы, название группы, сумма и кол-во абонентов, по которым были списания) и последней строкой сумма за день.
select C.DT, A.PARENT_ID, (select NAME from ABONENTS where sum(C.SUMM), 'Насчитано на ' || count(C.ABONENT_ID) || ' из ' ||(select count(*) from ABONENTS where DELETED = 0 and IS_FOLDER = 0 and PARENT_ID = A.PARENT_ID) from ABONENTS A join(select sum(SUMM) as SUMM, ABONENT_ID, cast(S_DATE as date) as DT from COUNTERS group by 2, 3) as C on C.ABONENT_ID = A.ID where A.DELETED = 0 and C.SUMM > 0 group by 1, 2, 3 union select C.DT, 9999999, 'Сумма', sum(C.SUMM), 'Насчитано на ' || count(C.ABONENT_ID) || ' из ' ||(select count(*) from ABONENTS where DELETED = 0 and IS_FOLDER = 0) from ABONENTS A join(select sum(SUMM) as SUMM, ABONENT_ID, cast(S_DATE as date) as DT from COUNTERS group by 2, 3) as C on C.ABONENT_ID = A.ID where A.DELETED = 0 and C.SUMM > 0 group by 1, 2, 3 order by 1, 2, 3
Отчет по должникам для отключения КТВ (Улица, Дом, Подъезд, Квартира, ФИО, Тариф) игнорируя ручной статус "Отключен"
select h.street as "Улица", h.s_number as "Номер дома", a.home_entrance as "Номер подъезда", a.A_HOME_NUMBER as "Номер квартиры", a.name as "ФИО", t.name as "Тариф" from abonents_block ab left join abonents a on ab.abonent_id=a.id left join homes h on a.home_id=h.id left join tarif t on a.tarif_id=t.id left join objects_status os on a.id=os.object_id where ab.b_negbal=1 and a.tarif_id in (21,22,23,24) and (os.status<>5 or os.status is null) group by 1,2,3,4,5,6 order by 6
Отчет по свободным IP адресам
select uf_ip2string(pc.ip) as "IP адрес", ipp.name as "Pull", (case when ipp.enabled <> 0 THEN 'Да' ELSE 'Нет' END) as "Включен" from pull_cache pc left join ip_pull ipp on ipp.pull_id = pc.pull_id where pc.user_id is null order by pc.pull_id, pc.ip
Кто платит через Юнителлер?
select distinct(pay_id_str_in) as "PAY", CONTRACT_NUMBER_IN as "Договор",Пример USER_NAME_OUT as "ФИО", operator_date_in as "Дата", SUMMA_IN as "Сумма" from pay_log where (operator_src_ip='213.208.182.172' or pay_operator='Uniteller') and act_in='pay' and operator_date_in between ':C_даты|date$' and ':По_дату|date$' order by user_name_out
Количество услуг из ЛК за месяц по абонентам
select A.ID, A.CONTRACT_NUMBER, A.NAME, count(*) from USERS_USLUGA UU left join ABONENTS A on UU.ABONENT_ID = A.ID where UU.USLUGA_ID = ':ID услуги$' and UU.IS_ZAKAZANO = 1 and UU.CREATE_DATE between ':C_даты|date$' and ':По_дату|date$' group by A.ID, A.CONTRACT_NUMBER, A.NAME having count(*)>1 order by A.NAMEe_in between ':C_даты|date$' and ':По_дату|date$'
Прибыль с комиссии за обещанный платеж (все периоды)
select A.NAME as "ФИО", A.CONTRACT_NUMBER as "Номер договора", C.MONTH_NUMBER as "номер месяца", C.SUMM as "Прибыть" from COUNTERS C left join ABONENTS A on C.ABONENT_ID = A.ID where (USLUGA_ID = -5) union select '#ИТОГО', '', '', round(sum(C.SUMM), 2) as "общая сумма" from COUNTERS C where (USLUGA_ID = -5) union select '#ИТОГО КОЛ-ВО РАЗ АКТИВИРОВАННА УСЛУГА', '', '', round(count(A.ID), 0) as "общая сумма" from COUNTERS C left join ABONENTS A on C.ABONENT_ID = A.ID where (USLUGA_ID = -5) order by 1
Прибыль с комиссии за обещанный платеж (по периодам)
select A.NAME as "ФИО", A.CONTRACT_NUMBER as "Номер договора", C.SUMM as "Прибыть" from COUNTERS C left join ABONENTS A on C.ABONENT_ID = A.ID where (USLUGA_ID = -5) and MONTH_NUMBER = ':номер месяца(1-12)$' union select '#ИТОГО', '', round(sum(C.SUMM), 2) as "общая сумма" from COUNTERS C where (USLUGA_ID = -5) and MONTH_NUMBER = ':номер месяца(1-12)$' union select '#ИТОГО КОЛ-ВО РАЗ АКТИВИРОВАННА УСЛУГА', '', round(count(A.ID), 0) as "общая сумма" from COUNTERS C left join ABONENTS A on C.ABONENT_ID = A.ID where (USLUGA_ID = -5) and MONTH_NUMBER = ':номер месяца(1-12)$' order by 1
Просмотр пользователей в онлайне с выводом времени онлайна
select cast(U.LOGIN as varchar(128)) as "логин", cast(H.STREET as varchar(128)) as "Улица", cast(H.S_NUMBER as varchar(128)) as "№ дома", cast(AB.A_HOME_NUMBER as varchar(128)) as "№ квартиры", cast(UF_IP2STRING(U.IP) as varchar(128)) as "IP-адрес", cast((time '00:00:00' + datediff(second, RS.START_TIME, current_timestamp)) as varchar(128)) as "время в онлайне" from USERS_RADIUSAUTH UR left join USERS U on UR.USER_ID = U.ID left join ABONENTS AB on U.ABONENT_ID = AB.ID left join HOMES H on AB.HOME_ID = H.ID left join RADIUS_SESSIONS RS on UR.ACCT_SESSION_ID = RS.ACCT_SESSION_ID where UR.LOGGED = 1 union select cast('#ИТОГО ПОЛЬЗОВАТЕЛЕЙ В ОНЛАЙНЕ' as varchar(128)) as "логин", cast('' as varchar(128)) as "Улица", cast('' as varchar(128)) as "№ дома", cast('' as varchar(128)) as "№ квартиры", cast('' as varchar(128)) as "IP-адрес", cast(count(UR.LOGGED) as varchar(128)) as "время в онлайне" from USERS_RADIUSAUTH UR where UR.LOGGED = 1 order by 1
Абоненты, которые в начале следующего месяца будут заблокированы (при условии что лимит выставлен отричательным числом, в противном случае минус перед ним нужно убрать)
select distinct A.CONTRACT_NUMBER as "номер договора", A.NAME as "ФИО", H.STREET as "Улица", H.S_NUMBER as "Номер дома", A.HOME_ENTRANCE as "Номер подъезда", A.A_HOME_NUMBER as "Номер квартиры", A.SMS as "номер для смс", T.NAME as "Тариф" from ABONENTS A left join ABONENTS_CACHE ACCH on A.ID = ACCH.ID left join ADMIN_ACCOUNTS AC on A.ACCOUNT_ID = AC.ID left join HOMES H on A.HOME_ID = H.ID left join TARIF T on A.TARIF_ID = T.ID where (ACCH.RECOMEND_PAY_SUM_CACHE / (select CONST_VALUE from VPN_CONST where CONST_ID = 1)) > (-(AC.LIMIT) / (select CONST_VALUE from VPN_CONST where CONST_ID = 1)) and A.IS_FOLDER = 0 and (select count(1) from ABONENTS_BLOCK AB where AB.ABONENT_ID = A.ID and (AB.B_NEGBAL != 1 or AB.B_OWN != 1 or AB.B_ADMIN != 1 or AB.B_SYS != 1)) = 0 union select '#ВСЕГО', '', '', '', '', '', '', count(A.ID) from ABONENTS A left join ABONENTS_CACHE ACCH on A.ID = ACCH.ID left join ADMIN_ACCOUNTS AC on A.ACCOUNT_ID = AC.ID where (ACCH.RECOMEND_PAY_SUM_CACHE / (select CONST_VALUE from VPN_CONST where CONST_ID = 1)) > (-(AC.LIMIT) / (select CONST_VALUE from VPN_CONST where CONST_ID = 1)) and A.IS_FOLDER = 0 and (select count(1) from ABONENTS_BLOCK AB where AB.ABONENT_ID = A.ID and (AB.B_NEGBAL != 1 or AB.B_OWN != 1 or AB.B_ADMIN != 1 or AB.B_SYS != 1)) = 0
Список IP адрес и номер договора всех абонентов. у которых в качестве nas_ip указан адрес 192.168.1.2:
select uf_ip2string(u.ip) as "IP", a.CONTRACT_NUMBER as "Номер договора" from users u left join abonents a on u.abonent_id=a.id left join nas n on u.nas_id=n.id where uf_ip2string(n.ip)='192.168.1.2' and a.deleted=0
Список абонентов, взявших больше одного обещанного платежа
select distinct AB.NAME as "ФИО", AB.CONTRACT_NUMBER as "Номер договора", (select count(1) from USERS_USLUGA UUA left join ABONENTS ABA on UUA.ABONENT_ID = ABA.ID where (UUA.USLUGA_ID = 1247 or UUA.USLUGA_ID = 1248 or UUA.USLUGA_ID = 1249) and UUA.DELETED = 0 and ABA.ID = AB.ID) as "Кол-во обещанных платежей" from USERS_USLUGA UU left join ABONENTS AB on UU.ABONENT_ID = AB.ID where UU.USLUGA_ID = 1247 and UU.DELETED = 0 and (select count(1) from USERS_USLUGA UUA left join ABONENTS ABA on UUA.ABONENT_ID = ABA.ID where (UUA.USLUGA_ID = 1247 or UUA.USLUGA_ID = 1248 or UUA.USLUGA_ID = 1249) and UUA.DELETED = 0 and ABA.ID = AB.ID) > 1 order by 3
Отчет по абонентам со статусом "подключен"
select count(distinct ab.id) as "Кол-во абонентов" from abonents ab left join abonents_block abb on ab.id = abb.abonent_id where abb.id is null and ab.deleted = 0 and ab.is_folder = 0 and exists(select 1 from users where nas_id=70 and abonent_id=ab.id and ip is not null)
Отчет по абонентам со статусом "не подключен"
select count(distinct ab.id) as "Кол-во абонентов" from abonents ab inner join abonents_block abb on ab.id = abb.abonent_id where ab.deleted = 0 and ab.is_folder = 0
Отчет по абонентам у которых сегодня списалась абонентская плата
select count(distinct ab.id) as "Кол-во абонентов" from arch_account_stack aas left join abonents ab on aas.abonent_id = ab.id where credit > 0 and cast(bill_date as date) = current_date
Отчет выводящий абонентов должников и в статусе "отключен" по каждому дому в отдельности:
select CITY as "Город", STREET as "Улица", SNUMBER as "Дом", AHOMENUMBER as "Квартира", FIO as "ФИО", PHONE as "Телефон", TNAME as "Тариф", round((AA.OSTATOK + AA.DEBIT - AA.CREDIT) / cast((select CONST_VALUE from VPN_CONST where CONST_ID = 1) as numeric(18,5)), 2) as "Баланс" from (select H.CITY as "CITY", H.STREET as "STREET", H.S_NUMBER as "SNUMBER", CAST(A.A_HOME_NUMBER AS INTEGER) as "AHOMENUMBER", A.NAME as "FIO", A.SMS as "PHONE", T.NAME as "TNAME", A.ACCOUNT_ID as "AAID" from ABONENTS A left join ABONENTS_BLOCK AB on AB.ABONENT_ID = A.ID left join HOMES H on A.HOME_ID = H.ID left join TARIF T on A.TARIF_ID = T.ID where A.DELETED != 1 and H.id=':Дом|select[homes]$' group by 1, 2, 3, 4, 5, 6, 7, 8) left join ADMIN_ACCOUNTS AA on AAID = AA.ID where round((AA.OSTATOK + AA.DEBIT - AA.CREDIT) / 10000000000.00, 2)
Отчет "абоненты с положительным балансом"
select a.contract_number as "Номер договора", a.name "ФИО", (h.street||' '||h.s_number||' '||a.a_home_number) as "Адрес", (aa.ostatok + aa.debit - aa.credit)/10000000000.00 as "Баланс" from abonents a inner join admin_accounts aa on a.account_id = aa.id left join homes h on a.home_id = h.id where (aa.ostatok + aa.debit - aa.credit)/10000000000.00 > 0 order by (aa.ostatok + aa.debit - aa.credit)/10000000000.00 desc
Отчет "Абоненты по услуге"
select contract_number as "Номер договора", name as "ФИО", (h.street||' '||h.s_number||' '||a.a_home_number) as "Адрес", uu.enable_date as "Дата подключения", (aa.ostatok + aa.debit - aa.credit)/10000000000.00 as "Баланс" from abonents a left join admin_accounts aa on aa.id = a.account_id left join homes h on h.id = a.home_id inner join users_usluga uu on uu.abonent_id = a.id where uu.usluga_id = ':Услуга|select[Usluga]$'
Отчет "Абоненты по тарифу"
select a.contract_number as "Номер договора", a.name as "ФИО", (h.street||' '||h.s_number||' '||a.a_home_number) as "Адрес", (aa.ostatok + aa.debit - aa.credit)/10000000000.00 as "Баланс" from abonents a left join admin_accounts aa on aa.id = a.account_id left join homes h on h.id = a.home_id where a.tarif_id = :ID Тарифа$
Отчет "Пресса", цель отчета раздать списки почтальонам, кому из абонентов приносить газету.
select h.s_number as "Дом", list(a.a_home_number) as "Квартиры" from abonents a left join abonents_block ab on a.id = ab.abonent_id inner join homes h on a.home_id = h.id where h.street = ':Улица$' and a.is_folder = 0 and (ab.abonent_id is null or (ab.b_negbal = 1 and (current_timestamp - ab.b_date) < 90)) group by h.s_number
Отчет "Интернет", отчет за период по абонентской плате, по приходам физических и юридических лиц, по приходам через платежные системы, расторгнутым и заключенным договорам.
select first 1 (':Начало|date$') as "Период начало", (':Конец|date$') as "Период окончание", ( select (sum(aas.credit) / (select CONST_VALUE from VPN_CONST where CONST_ID = 1)) from arch_account_stack aas left join abonents ab on aas.abonent_id = ab.id where aas.bill_date between ':Начало|date$' and ':Конец|date$ 23.59.59' and aas.storno=0 and (upper(aas.descr) like 'Абонентская плата' or upper(aas.descr) like 'Трафик') and ab.company = 0 ) as "Абон. плата физ.", ( select (sum(aas.credit_adjust) /(select CONST_VALUE from VPN_CONST where CONST_ID = 1))from arch_account_stack aas left join abonents ab on aas.abonent_id = ab.id where aas.bill_date between ':Начало|date$' and ':Конец|date$ 23.59.59' and (upper(aas.descr) like 'Абонентская плата' or upper(aas.descr) like 'Трафик' ) and ab.company = 1 and aas.storno=0 ) as "Абон. плата юр.", ( select (sum(fo.op_summa) / (select CONST_VALUE from VPN_CONST where CONST_ID = 1)) from finance_operations fo left join abonents ab on fo.abonent_id = ab.id where fo.op_type = 2 and fo.op_date between ':Начало|date$' and ':Конец|date$ 23.59.59' and fo.op_summa > 0 and ab.company = 0 ) as "Приходы физ.", ( select (sum(fo.op_summa) / (select CONST_VALUE from VPN_CONST where CONST_ID = 1)) from finance_operations fo left join abonents ab on fo.abonent_id = ab.id where fo.op_type = 2 and fo.op_date between ':Начало|date$' and ':Конец|date$ 23.59.59' and fo.op_summa > 0 and ab.company = 1 ) as "Приходы юр.", ( select (sum(fo.op_summa) / (select CONST_VALUE from VPN_CONST where CONST_ID = 1)) from finance_operations fo where fo.op_type = 2 and fo.op_date between ':Начало|date$' and ':Конец|date$ 23.59.59' and fo.op_summa > 0 ) as "Итого", ( select count(os.id) from objects_status os left join abonents ab on os.object_id = ab.id where os.status=31 and upper(os.object_name) = 'Abonents' and cast(os.apply_date as date) between cast(':Начало|date$' as date) and cast(':Конец|date$' as date) ) as "Подписанные", ( select count(os.id) from objects_status os left join abonents ab on os.object_id = ab.id where os.status=35 and upper(os.object_name) = 'Abonents' and cast(os.apply_date as date) between cast(':Начало|date$' as date) and cast(':Конец|date$' as date) ) as "Расторженные" from send_type
Отчет по должникам с возможностью выбора тарифа. В отчете: номер договора, ФИО, телефон абонента, адрес, тариф, статус, дата последнего платежа, баланс.
select AB.CONTRACT_NUMBER as "№ договора", AB.NAME as "ФИО", AB.SMS as "Телефон", TP.NAME as "Тариф", H.STREET as "Улица", H.S_NUMBER as "№ дома", H.S_LITER as "Корпус", AB.A_HOME_NUMBER as "№ квартиры", (select max(ffoo.system_date) from finance_operations ffoo where ffoo.abonent_id=ab.id and ffoo.op_type=2 and ffoo.storno=0) as "Посл. платеж", (AA.DEBIT + AA.OSTATOK - AA.CREDIT) / (select CONST_VALUE from VPN_CONST where CONST_ID = 1) as "Баланс", STATUS.NAME as "Статус", av1.attribute_value as "s/n" from USERS U left join ABONENTS AB on U.ABONENT_ID=AB.ID left join ADMIN_ACCOUNTS AA on AB.ACCOUNT_ID = AA.ID left join HOMES H on AB.HOME_ID=H.ID left join TARIF TP on AB.TARIF_ID = TP.ID left join OBJECTS_STATUS OS on OS.OBJECT_ID=AB.ID left join STATUS on OS.STATUS=STATUS.ID left join ATTRIBUTE_VALUES as av1 on ab.id=av1.ABONENT_ID and av1.ATTRIBUTE_ID=1007 left join ABONENTS_BLOCK ABL on ABL.ABONENT_ID = AB.ID where ABL.b_negbal=1 and TP.ID=':Тариф|select[Tarif]$' order by U.CONTRACT_NUMBER
Отчет должники по постоплате с разделением по физическим и юридическим лицам. Отчет содержит: номер договора, ФИО, адрес, дата последнего платежа, сумма долга (рекоммендованный платеж по постоплате)
select first 1 cast('******************************************' as varchar(100) ) as "№ договора", cast('*****ФИЗИЧЕСКИЕ ЛИЦА**********' as varchar(100) ) as "Наименование", cast('******************************************' as varchar(100)) as "Адрес" , cast('******************************************' as varchar(100) ) as "Посл. платеж", cast('*****************************' as varchar(100)) as "Сумма долга" from send_type union all select AB.CONTRACT_NUMBER as "№ договора", AB.NAME as "ФИО", H.STREET || ', д. ' || H.S_NUMBER || ', кв.' || AB.A_HOME_NUMBER as "Адрес", (select max(FO.OP_DATE) from FINANCE_OPERATIONS FO where FO.ABONENT_ID = AB.ID) as "Посл. платеж", (select round( sum( cast( (CNT.SUMM) as float ) ) , 2) from counters cnt left join usluga u on CNT.USLUGA_ID=U.ID where cnt.month_number=extract(month FROM cast('NOW' as date))-1 and cnt.year_number=extract(year FROM cast('NOW' as date)) and u.post_pay=1 and cnt.abonent_id=ab.id) as "Баланс" from ABONENTS AB left join ADMIN_ACCOUNTS AA on AB.ACCOUNT_ID = AA.ID left join ABONENTS_CACHE ACCH on AB.ID = ACCH.ID left join HOMES H on AB.HOME_ID=H.ID where AA.CREDIT_ADJUST!=0 and AB.COMPANY = 0 and (AA.DEBIT + AA.OSTATOK - AA.CREDIT) / (select CONST_VALUE from VPN_CONST where CONST_ID = 1)select first 1 cast('******************************************' as varchar(100) ) as "№ договора", cast('*****ЮРИДИЧЕСКИЕ ЛИЦА**********' as varchar(100) ) as "ФИО", cast('******************************************' as varchar(100)) as "Адрес" , cast('******************************************' as varchar(100) ) as "Посл. платеж", cast('*****************************' as varchar(100)) as "Баланс" from send_type union all select AB.CONTRACT_NUMBER as "№ договора", AB.NAME as "ФИО", H.STREET || ', д. ' || H.S_NUMBER || ', кв.' || AB.A_HOME_NUMBER as "Адрес", (select max(FO.OP_DATE) from FINANCE_OPERATIONS FO where FO.ABONENT_ID = AB.ID) as "Посл. платеж", (select round( sum( cast( (CNT.SUMM) as float ) ) , 2) from counters cnt left join usluga u on CNT.USLUGA_ID=U.ID where cnt.month_number=extract(month FROM cast('NOW' as date))-1 and cnt.year_number=extract(year FROM cast('NOW' as date)) and u.post_pay=1 and cnt.abonent_id=ab.id) as "Баланс" from ABONENTS AB left join ADMIN_ACCOUNTS AA on AB.ACCOUNT_ID = AA.ID left join ABONENTS_CACHE ACCH on AB.ID = ACCH.ID left join HOMES H on AB.HOME_ID=H.ID where AA.CREDIT_ADJUST!=0 and AB.COMPANY = 1 and (AA.DEBIT + AA.OSTATOK - AA.CREDIT) / (select CONST_VALUE from VPN_CONST where CONST_ID = 1)
Отчет по абонентам, у которых должна произойти смена тарифа
select A.ID as "ID абонента", A.NAME as "ФИО", A.TARIF_ID as "ID тарифа", T.NAME as "Тариф", A.TARIF_NEXT_ID as "ID нового тарифа" from ABONENTS A left join TARIF T on A.TARIF_ID=T.ID where A.TARIF_NEXT_DATE between ':День смены тарифа|date$' and ':День смены тарифа|date$ 23:59:59 '
Сумма платежей через платежные системы "Жилищное управление", "Yandex" за каждый день в периоде между Датой1 и Датой2
with PERIOD as (select distinct cast(PLS.DATE_CREATE as date) as DAT from PAY_LOG PLS where PLS.DATE_CREATE between ':Дата1|date$' and ':Дата2|date$ 23:59:59') select PERIOD.DAT as "Date", ( select COALESCE(sum(P.SUMMA_IN),0) from PAY_LOG P where P.MSG_OUT containing 'ACCEPTED' and P.ACT_IN containing 'PAY' and P.PAY_OPERATOR containing upper('Жилищное упр') and P.DATE_CREATE containing DAT ) as "Жилищное упр", ( select COALESCE(sum(P.SUMMA_IN),0) from PAY_LOG P where P.MSG_OUT containing 'ACCEPTED' and P.ACT_IN containing 'PAY' and P.PAY_OPERATOR containing upper('Yandex.Kassa') and P.DATE_CREATE containing DAT ) as "Яндекс" from PAY_LOG PL inner join PERIOD on PL.DATE_CREATE containing DAT where PL.MSG_OUT containing 'ACCEPTED' and PL.ACT_IN containing 'PAY' group by PERIOD.DAT
Отчет "Выставленные счета физическим лицам". В отчете: сумма в счете, ФИО абонента, описание финансовой операции
select ((fo.op_summa)/(select const_value from vpn_const where const_id=1)) as "Сумма", ab.name as "ФИО", ft.op_name || ', ' || ft.op_descr from finance_operations fo left join abonents ab on fo.abonent_id=ab.id left join fin_types ft on fo.op_type=ft.type_id where (fo.op_type=5 or fo.op_type=9 or fo.op_type=1) and fo.abonent_id=ab.id and ab.company=0 and fo.op_date between cast(':Начало|date$' as date) and cast(':Конец|date$' as date)
Отчёт о превышении лимита предоплаченного трафика по юридическим лицам с возможностью выбора месяца - года
SQL запрос
select distinct ab.name, tarif.name, usluga.max_mb_in_m, round(usluga.in_price / cast((select CONST_VALUE from VPN_CONST where CONST_ID = 1) as numeric(18,5)), 2), round(traf_counters.v_in / cast((1048576) as numeric(18,5)), 2), round(traf_counters.v_out / cast((1048576) as numeric(18,5)), 2), usluga.name, usluga.id, tarif.id, ab.id from abonents as ab left join tarif on ab.tarif_id=tarif.id join tarif_users_usluga as tuu on tuu.tarif_id = tarif.id join usluga on tuu.usluga_id=usluga.id join users_usluga as uu on uu.abonent_id = ab.id and uu.usluga_Id = usluga.id and uu.tarif_id = tarif.id join traf_counters on ab.id=traf_counters.abonent_id where traf_counters.MONTH_NUMBER = (':Месяц|choices[1^]Январь^[2^]Февраль^[3^]Март^[4^]Апрель^[5^]Май^[6^]Июнь^[7^]Июль^[8^]Август^[9^]Сентябрь^[10^]Октябрь^[11^]Ноябрь^[12^]Декабрь]$') and traf_counters.year_number LIKE upper(':Год$') and ab.company = 1
Шаблон отчёта
Отчёт о динамике приходов и актов за заданный период времени
SQL запрос
select fo.SYSTEM_DATE as "Дата", u.login as "Логин", a.contract_number as "Номер договора", a.name as "ФИО", round(fo.op_summa / cast((select CONST_VALUE from VPN_CONST where CONST_ID = 1) as numeric(18,5)), 2) as "Сумма прихода", round(fo.balance_buh / cast((select CONST_VALUE from VPN_CONST where CONST_ID = 1) as numeric(18,5)), 2) as "Баланс", a.tarif_id as "ID тарифа", t.name, ft.op_name from abonents as a join users as u on a.id=u.abonent_id join finance_operations as fo on fo.ABONENT_ID=a.id join fin_types as ft on fo.op_type = ft.type_id join tarif as t on t.id = a.tarif_id where fo.SYSTEM_DATE between (':1 Дата|date$') and (':2 Дата|date$') and fo.op_type in (1,2)
Шаблон отчёта
"form_list.html" %> .btn-container