commit 529334d03b7778cfcce5cc64dfc40849d6e0e999 Author: msyu Date: Mon Jun 2 16:16:51 2025 +0300 initial draft diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d356eab --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +etc/info/ \ No newline at end of file diff --git a/Application.cfc b/Application.cfc new file mode 100644 index 0000000..dd2ed21 --- /dev/null +++ b/Application.cfc @@ -0,0 +1,285 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ), + DE( "https://" ), + DE( "http://" ) + ) & + cgi.http_host & + reReplace( + getDirectoryFromPath( arguments.template ), + "([^\\/]+[\\/]){#local.requestDepth#}$", + "", + "one" + ) + ) /> + + + + + + + + + + + + + + + + + + + + + + + + + #login# + + + select usr_id from usr where login='#login#' + + + + + + + #cfcatch.message# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select 1; + + + + + + + + + + + + + \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..eb7208f --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# Svc + +Каталог услуг \ No newline at end of file diff --git a/_doc_ls.cfm b/_doc_ls.cfm new file mode 100644 index 0000000..03b1b85 --- /dev/null +++ b/_doc_ls.cfm @@ -0,0 +1,21 @@ + + + + + +select +d.abstract_service_id as entity_id, d.abstract_service_doc_id as doc_id, d.abstract_service_doc as title, datalength(d.doc) as doc_size, d.contenttype, d.fname, +a.login as creator, a.shortname as creator_name, u.login as modifier, u.shortname as modifier_name + from abstract_service_doc d + left outer join usr a on (d.creator_id=a.usr_id) + left outer join usr u on (d.modifier_id=u.usr_id) + + + + + + + +#title# +
+
\ No newline at end of file diff --git a/abstract_service.cfm b/abstract_service.cfm new file mode 100644 index 0000000..9f89a55 --- /dev/null +++ b/abstract_service.cfm @@ -0,0 +1,575 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + pageInfo=#pageInfo# + id="#d.abstract_service_id#" + status=#pageInfo.status# + trackOut="tr" + idAttributesOut="id" +/> + + + + + + + select a.analytic_code, a.area_code, a.area + from area a + where area_id= + + + select + a.login as creator, a.shortname as creator_shortname, m.login as updater, m.shortname as updater_shortname + from #pageInfo.entity# e + left outer join usr a on (e.creator_id=a.usr_id) + left outer join usr m on (e.updater_id=m.usr_id) + where e.#pageInfo.key#= + + + + + + Абстрактная услуга + + #d.abstract_service# + [#d.abstract_service_id#] + + + + + + + + + + + +
+ +
+
Номенклатура (RUS)
+
+ +
+
+ +
+
Номенклатура (ENG)
+
+ +
+
+ +
+
Группа услуг
+
+ + select area_id, area_code, analytic_code, area + from area + order by 3 + + + /> +
+
+ +
+
Код услуги
+
+ #qArea.area_code#. +
+
+ +
+
Единица измерения
+
+ + select measure_id, measure + from measure + order by 2 + + + /> + для композитных услуг (состоящих из компонентов) указывать штуки. Часто композитные услуги попадают в спецификацию в количестве 1 шт. +
+
+ +
+
Точность
+
+ + Количество знаков после запятой, 0 - целое число +
+
+ +
+
Класс характеристики
+
+ + select modifier_class_id, modifier_class + from modifier_class + order by 2 + + + /> + + + + + + + + + + + + Список, из которого выбирается значение характеристики-модификатора, определяющее конкретную услугу (вариант).
+ Если варианты не предусмотрены, нужно оставить поле пустым. +
+
+
+ +
+
Ответственный
+
+ + select usr_id, firstname, middlename, lastname + from usr + order by 4,2,3 + + +
+
+ + +
+
Версия
+
+ +
+
+ +
+
Статус
+
+ + select status_id, status + from status + order by 1 + + + /> + с + +
+
+ +
+
Описание
+
+ +
+
+ +
+
Коммерческие примечания
+
+ +
+
+ +
+
Создано
+
+ #dateFormat(d.dt_created,'DD.MM.YYYY')# #timeFormat(d.dt_created,'HH:MM')# + #qDecoration.creator# (#qDecoration.creator_shortname#) +       + Изменено + #dateFormat(d.dt_updated,'DD.MM.YYYY')# #timeFormat(d.dt_updated,'HH:MM')# + #qDecoration.updater# (#qDecoration.updater_shortname#) +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + select + ac.abstract_service_param_class_id + ,ac.param_class_id + ,ac.is_multiple + ,ac.sort + ,c.param_class + ,c.measure_id + ,m.measure_id + ,m.measure + ,m.measure_short + + ,(select count(*) from param p where p.param_class_id=ac.param_class_id) as param_cnt + from abstract_service_param_class ac + left outer join param_class c on (ac.param_class_id=c.param_class_id) + left outer join measure m on (c.measure_id=m.measure_id) + where ac.abstract_service_id= + order by ac.sort + + + +

+ Компоненты (#qAbstractServiceParamClass.recordCount#) + + + + + + +

+
+ + + + + + + + + + + + + + + + + + + + + + + + +
КомпонентЕдиница измеренияВариантовМножественныйСортировка
+ + + #param_class# + + #measure# (#measure_short#) + + #param_cnt# + + + Да + + + #sort# + + +
+ + + + + + + select + s.service_id + ,m.modifier_id + ,m.modifier + + ,c.modifier_class_id + ,c.modifier_class + ,m.code as modifier_code + ,(select count(*) from service_param sp where sp.service_id=s.service_id) as param_count + ,(select count(*) from service_param sp join service_param_price spp on (sp.service_param_id=spp.service_param_id) where sp.service_id=s.service_id) as service_param_price_count + + ,(select sp.price from service_price sp where sp.service_id=s.service_id AND sp.pricing_model_id=1 order by service_price_id desc limit 1) as prc_inst + ,(select count(*) from service_price sp where sp.service_id=s.service_id AND sp.pricing_model_id=1) as prc_inst_cnt + ,(select sp.service_price_id from service_price sp where sp.service_id=s.service_id AND sp.pricing_model_id=1 order by service_price_id desc limit 1) as prc_inst_id + + ,(select sp.price from service_price sp where sp.service_id=s.service_id AND sp.pricing_model_id=2 order by service_price_id desc limit 1)as prc_fix + ,(select count(*) from service_price sp where sp.service_id=s.service_id AND sp.pricing_model_id=2) as prc_fix_cnt + ,(select sp.service_price_id from service_price sp where sp.service_id=s.service_id AND sp.pricing_model_id=2 order by service_price_id desc limit 1)as prc_fix_id + + ,(select sp.price from service_price sp where sp.service_id=s.service_id AND sp.pricing_model_id=3 order by service_price_id desc limit 1) as prc_payg + ,(select count(*) from service_price sp where sp.service_id=s.service_id AND sp.pricing_model_id=3) as prc_payg_cnt + ,(select sp.service_price_id from service_price sp where sp.service_id=s.service_id AND sp.pricing_model_id=3 order by service_price_id desc limit 1) as prc_payg_id + + from service s + left outer join modifier m on (s.modifier_id=m.modifier_id) + left outer join modifier_class c on (m.modifier_class_id=c.modifier_class_id) + where s.abstract_service_id= + order by m.sort, m.code, m.modifier + + + + + + + + + + +

+ Варианты услуги (#qService.recordCount#) + + + + + + +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
КодНазваниеЦена усл. инст.Цена усл. фикс.Цена усл. paygКомпонентовЦен комп-в
+ + +
+ + + +
+
#request.skuCode(qArea.area_code,d.code,modifier_code)##d.abstract_service# - #modifier# + + #formatPrice(prc_inst)# + + + + #formatPrice(prc_fix)# + + + + #formatPrice(prc_payg)# + + #param_count##service_param_price_count# + +
+ + + + + select + ac.abstract_service_complementary_id + ,ac.abstract_service_id + ,ac.complementary_id + ,ac.quantity + ,ac.sort + ,c.code + ,c.abstract_service + ,c.area_id + ,g.area_code + from abstract_service_complementary ac + left outer join abstract_service c on (ac.complementary_id=c.abstract_service_id) + left outer join area g on (c.area_id=g.area_id) + where ac.abstract_service_id= + order by ac.sort + + + +

+ Дополнительные услуги (#qAbstractServiceComplementary.recordCount#) + + + + + + +

+
+ + + + + + + + + + + + + + + + + + + + + + +
КодАбстрактная услугаКол-воСортировка
+ + + #request.skuCode(area_code,code)# + + #abstract_service# + + #quantity# + + #sort# + + +
+ + +
+ + + diff --git a/abstract_service_complementary.cfm b/abstract_service_complementary.cfm new file mode 100644 index 0000000..f7827e7 --- /dev/null +++ b/abstract_service_complementary.cfm @@ -0,0 +1,200 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + pageInfo=#pageInfo# + id="#d.abstract_service_complementary_id#" + status=#pageInfo.status# + trackOut="tr" + idAttributesOut="id" +/> + + + select + a.abstract_service + ,a.abstract_service_id + ,a.code + ,g.area_code + from abstract_service a + left outer join area g on (a.area_id=g.area_id) + where a.abstract_service_id= + + + + + select + a.abstract_service + ,a.abstract_service_id + ,a.code + ,g.area_code + from abstract_service a + left outer join area g on (a.area_id=g.area_id) + where a.abstract_service_id= + + + + select + a.login as creator, a.shortname as creator_shortname, m.login as updater, m.shortname as updater_shortname + from #pageInfo.entity# e + left outer join usr a on (e.creator_id=a.usr_id) + left outer join usr m on (e.updater_id=m.usr_id) + where e.#pageInfo.key#= + + + + + + + Дополнительная абстрактная услуга + + #qComplementary.abstract_service# + #request.skuCode(qComplementary.area_code,qComplementary.code)# + [#d.complementary_id#] + + для абстрактной услуги + + #qAbstractService.abstract_service# + #request.skuCode(qAbstractService.area_code,qAbstractService.code)# + [#d.abstract_service_id#] + + + + + + + +
#status.errorMessage#
+
+ + + + + + + +
+ +
+
Абстрактная услуга
+ +
+ + +
+
Дополнительная услуга
+
+ + select + a.abstract_service + ,a.abstract_service_id + ,a.code + ,g.area_code + from abstract_service a + left outer join area g on (a.area_id=g.area_id) + where a.abstract_service_id <> + + order by g.analytic_code, a.code + + + + + + + + + Эта услуга предлагается дополнительно к основной при формировании спецификации +
+
+ +
+
Кол-во по умолчанию
+
+ + В каком количестве предлагать на каждый экземпляр основной услуги +
+
+ +
+
Сортировка
+
+ + Целое число - порядок, в котором Компонент будет выводиться в составе данной услуги. Рекомендуется ставить через 100, чтобы потом удобнее было тасовать +
+
+ +
+
Описание
+
+ +
+
+ +
+
Создано
+
+ #dateFormat(d.dt_created,'DD.MM.YYYY')# #timeFormat(d.dt_created,'HH:MM')# + #qDecoration.creator# (#qDecoration.creator_shortname#) +       + Изменено + #dateFormat(d.dt_updated,'DD.MM.YYYY')# #timeFormat(d.dt_updated,'HH:MM')# + #qDecoration.updater# (#qDecoration.updater_shortname#) +
+
+ +
+
+ + diff --git a/abstract_service_complementary_del.cfm b/abstract_service_complementary_del.cfm new file mode 100644 index 0000000..d072cbe --- /dev/null +++ b/abstract_service_complementary_del.cfm @@ -0,0 +1,72 @@ + + + + + + + + +/***use case: составное имя неоднозначно читается*/ + + + + + + + + + + select + a.abstract_service + ,c.abstract_service as complementary_service + ,a.abstract_service_id + ,c.abstract_service_id as complementary_id + ,a.code + ,c.code as complementary_code + ,g.area_code + ,gc.area_code as complementary_area_code + from abstract_service_complementary cs + left outer join abstract_service a on (cs.abstract_service_id=a.abstract_service_id) + left outer join area g on (a.area_id=g.area_id) + left outer join abstract_service c on (cs.complementary_id=c.abstract_service_id) + left outer join area gc on (c.area_id=gc.area_id) + where cs.abstract_service_complementary_id= + + + + + + + Удаление дополнительной абстрактной услуги + #qDecoration.complementary_service# + #request.skuCode(qDecoration.complementary_area_code, qDecoration.complementary_code)# + [#abstract_service_complementary_id#] + для абстрактной услуги + #qDecoration.complementary_service# + #request.skuCode(qDecoration.area_code, qDecoration.code)# + + +   + + + + +#markup# + + diff --git a/abstract_service_del.cfm b/abstract_service_del.cfm new file mode 100644 index 0000000..d5299cc --- /dev/null +++ b/abstract_service_del.cfm @@ -0,0 +1,69 @@ + + + + + + + + + + + + + s.service_id + m.modifier + + service s + left outer join modifier m on (s.modifier_id=m.modifier_id) + + s.abstract_service_id + 2 desc + + + + + + + + + + select a.code, a.abstract_service + FROM abstract_service a + where a.abstract_service_id= + + + + + + + Удаление абстрактной услуги (номенклатурной позиции, строки каталога услуг) + #qDecoration.abstract_service# + + [#abstract_service_id#] + + + +   + + + + +#markup# + + \ No newline at end of file diff --git a/abstract_service_filter.cfm b/abstract_service_filter.cfm new file mode 100644 index 0000000..533b258 --- /dev/null +++ b/abstract_service_filter.cfm @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Каталог услуг - фильтр + + + + + +
+ +
+
+
+ +
+
+ +
+
#i18("Номенклатура","Service")#
+
+ + #i18("по вхождению подстроки","by substring")# +
+
+ +
+
#i18("Код услуги","Service Code")#
+
+ + #i18("по вхождению подстроки","by substring")# +
+
+ +
+
#i18("Статус","Status")#
+
+ + select status_id, status + from status + order by status_id + + + +
+
+ +
+
#i18("Группа каталога","Catalog Group")#
+
+ + select g.area_id, g.area, g.area_code + from area g + order by g.area_code + + + + +
+ #i18("Код","Code")# + +
+ #i18("Группа","Group")# + +
+ #i18("по вхождению подстроки","by substring")# +
+
+
+ + + +
+ +
+ + + \ No newline at end of file diff --git a/abstract_service_ls.cfm b/abstract_service_ls.cfm new file mode 100644 index 0000000..ea92ddd --- /dev/null +++ b/abstract_service_ls.cfm @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + select + + a.abstract_service_id + g.area_code + g.analytic_code + g.area + a.area_id + a.abstract_service + a.abstract_service_en + a.code/***use case: составное поле. А как сортировать*/ + a.status_id + s.status + m.measure + m.measure_short + + a.manager_id + u.login + u.firstname + u.middlename + u.lastname + u.email + a.descr + a.commercial_note + + + + + + (select count(*) from abstract_service_param_class ac where ac.abstract_service_id=a.abstract_service_id) as param_count + c.modifier_class + a.modifier_class_id + (select count(*) from service s where s.abstract_service_id=a.abstract_service_id) as service_count + (select count(*) from abstract_service_complementary ac where ac.abstract_service_id=a.abstract_service_id) as complementary_count + (select count(*) from abstract_service_doc d where d.abstract_service_id=a.abstract_service_id) as doc_count + + from abstract_service a + left outer join modifier_class c on (a.modifier_class_id=c.modifier_class_id) + left outer join area g on (a.area_id=g.area_id) + left outer join measure m on (a.measure_id=m.measure_id) + left outer join status s on (a.status_id=s.status_id) + left outer join usr u on (a.manager_id=u.usr_id) + + where 1=1 + order by + + + + + + + + + +select count(*) as cnt from abstract_service where 1=1 + + + + + + + + + + + + + Абстрактные услуги + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + #analytic_code# #area##request.skuCode(area_code,code)##abstract_service##measure_short##param_count##modifier_class##service_count##complementary_count##lastname# #firstname# #middlename##status# + +
+ + #gridFooter# + +
+ \ No newline at end of file diff --git a/abstract_service_param_class.cfm b/abstract_service_param_class.cfm new file mode 100644 index 0000000..c29b030 --- /dev/null +++ b/abstract_service_param_class.cfm @@ -0,0 +1,277 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + pageInfo=#pageInfo# + id="#d.abstract_service_param_class_id#" + status=#pageInfo.status# + trackOut="tr" + idAttributesOut="id" +/> + + + select + a.abstract_service + ,a.abstract_service_id + ,a.code + from abstract_service a + where a.abstract_service_id= + + + + + select p.param_class, m.measure_id, m.measure + from param_class p + left outer join measure m on m.measure_id=p.measure_id + where param_class_id= + + + + select + a.login as creator, a.shortname as creator_shortname, m.login as updater, m.shortname as updater_shortname + from #pageInfo.entity# e + left outer join usr a on (e.creator_id=a.usr_id) + left outer join usr m on (e.updater_id=m.usr_id) + where e.#pageInfo.key#= + + + + + + + Компонент [#d.abstract_service_param_class_id#] + + #qParamClass.param_class# [#d.param_class_id#] + + абстрактной услуги + + #qAbstractService.abstract_service# [#d.abstract_service_id#] + + + + + + + +
#status.errorMessage#
+
+ + + + + + + + +
+ +
+
Абстрактная услуга
+ +
+ + +
+
Компонент
+
+ + select c.param_class_id, c.param_class, m.measure_short + from param_class c + left outer join measure m on (c.measure_id=m.measure_id) + order by 2 + + + + + + + + + + + + + Единица измерения: + #qParamClass.measure#(нет) + + Вариант компонента либо фиксируется в варианте услуги, либо выбирается при формировании спецификации +
+
+ +
+
Множественный
+
+ checked /> + Если отметка стоит, то для экземпляра услуги можно выбирать несколько вариантов компонента, например, несколько типов диска +
+
+ +
+
Сортировка
+
+ + Целое число - порядок, в котором Компонент будет выводиться в составе данной услуги. Рекомендуется ставить через 100, чтобы потом удобнее было тасовать +
+
+ + +
+
Описание
+
+ +
+
+ +
+
Создано
+
+ #dateFormat(d.dt_created,'DD.MM.YYYY')# #timeFormat(d.dt_created,'HH:MM')# + #qDecoration.creator# (#qDecoration.creator_shortname#) +       + Изменено + #dateFormat(d.dt_updated,'DD.MM.YYYY')# #timeFormat(d.dt_updated,'HH:MM')# + #qDecoration.updater# (#qDecoration.updater_shortname#) +
+
+ +
+Это шаблон для компонента экземпляра услуги (строки спецификации). Если в компонентах услуги определен Компонент, а не конкретный вариант компонента, то нужно присвоить цены всем компонентам этого класса, которые актуальны для данной услуги. Это требуется не только для назначения цен, но и для ограничения списка возможных вариантов выбора компонента для данной услуги. *** Может быть, вместо "компонент" нужно ввести термин "тип компонента", потому что это не экземпляр. Например, Компонент - дисковое пространство, а компонент - дисковое пространство SSD, это уточнение класса компонента, но не конкретный объем на конкретном СХД, и даже не конкретная дисковая квота в рамках контракта (спецификации) +
+
+ + + + +

Реализации (конкретные параметры вариантов услуг), использующих данный компонент

+ + + select + ac.abstract_service_param_class_id + ,g.area_code + ,s.abstract_service_id + ,s.service_id + ,a.abstract_service + ,a.code + ,sp.service_param_id + ,ac.param_class_id + ,pc.param_class + ,p.param_id + ,p.param + ,p.code as param_code + ,p.sort + ,s.modifier_id /*всегда берем ключ от той таблицы, к которой присоединяем - если нарушена ссылка, останется больше информации*/ + ,m.modifier + ,a.modifier_class_id + ,mc.modifier_class + ,m.code as modifier_code + ,u.measure_short + from abstract_service_param_class ac + left outer join param_class pc on (ac.param_class_id=pc.param_class_id) + left outer join service_param sp on (ac.abstract_service_param_class_id=sp.abstract_service_param_class_id) + left outer join param p on (ac.param_class_id=p.param_class_id AND sp.param_id=p.param_id)/***условие выглядит избыточно жестким, сразу из класса и экземпляра, а зачем*/ + left outer join service s on (sp.service_id=s.service_id) + left outer join abstract_service a on (s.abstract_service_id=a.abstract_service_id) /*** тут снова развилка, можно взять из шаблона, а можно из экземпляра... нельзя ли устранить неоднозначность*/ + left outer join area g on (a.area_id=g.area_id) + left outer join modifier m on (s.modifier_id=m.modifier_id) + /*** тут еще можно присоединить класс модификатора, и тоже варианты - из шаблона или экземпляра... но экземпляр бывает пустым*/ + left outer join modifier_class mc on (mc.modifier_class_id=m.modifier_class_id) /*кажется, в данном случае правильно по шаблону*/ + left outer join measure u on (pc.measure_id=u.measure_id)/***единица измерения из класса может быть переопределена - может, здесь вообще без нее обойтись... цены-то нет. А в цене единица должна быть зафиксирована*/ + where ac.abstract_service_param_class_id= + order by p.sort, ac.abstract_service_param_class_id + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IDВариант услугиКодКомпонентЕд.изм.Сортировка
+ + #service_param_id##abstract_service# #modifier# + #request.skuCode(area_code, code, modifier_code, param_code)# + + #param_class#: #param# + #measure_short##sort#
+ + +
+ + + diff --git a/abstract_service_param_class_del.cfm b/abstract_service_param_class_del.cfm new file mode 100644 index 0000000..f714b86 --- /dev/null +++ b/abstract_service_param_class_del.cfm @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + service_param_id + a.code + a.abstract_service + c.modifier_class + m.modifier + pc.param_class + p.param + + service_param sp + left outer join service s on (sp.service_id=s.service_id) + left outer join abstract_service a on (s.abstract_service_id=a.abstract_service_id) + left outer join modifier m on (s.modifier_id=m.modifier_id) + left outer join modifier_class c on (m.modifier_class_id=c.modifier_class_id) + left outer join param p on (sp.param_id=p.param_id) + left outer join param_class pc on (p.param_class_id=pc.param_class_id) + + sp.abstract_service_param_class_id + 1 desc + + + + + + + + + +select + ac.abstract_service_id, a.abstract_service, a.code + ,g.area, g.area_code, g.analytic_code + ,ac.param_class_id, c.param_class + FROM abstract_service_param_class ac + left outer join abstract_service a on (ac.abstract_service_id=a.abstract_service_id) + left outer join area g on (ac.abstract_service_id=a.abstract_service_id) + left outer join param_class c on (ac.param_class_id=c.param_class_id) + where ac.abstract_service_param_class_id= + + + + + + + Удаление компонента абстрактной услуги + #qDecoration.abstract_service# + (#qDecoration.code#) + #qDecoration.param_class# + + [#abstract_service_param_class_id#] + + + +   + + + + + +#markup# + + diff --git a/abstract_service_rpt.cfm b/abstract_service_rpt.cfm new file mode 100644 index 0000000..2ab2434 --- /dev/null +++ b/abstract_service_rpt.cfm @@ -0,0 +1,270 @@ + + + + + + + + + + + + + + + + + select + + a.abstract_service_id + + g.area_code + g.area + g.area_en + + u.status + u.status_en + + a.code + a.abstract_service + a.abstract_service_en + + m.measure_short + m.measure_short_en + + (select count(*) from abstract_service_provider sp where sp.abstract_service_id=a.abstract_service_id) as provider_count + + CAST( + ( + select coalesce(p.provider,'') as provider /*null does not produce an attribute*/ + from abstract_service_provider sp + join provider p on (sp.provider_id=p.provider_id) + where sp.abstract_service_id=a.abstract_service_id + FOR XML AUTO, TYPE, ROOT('providers') + ) + AS VARCHAR(MAX)) + as providers + + + CAST( + ( + select coalesce(p.provider_en, '') as provider /*NB!*/ + from abstract_service_provider sp + join provider p on (sp.provider_id=p.provider_id) + where sp.abstract_service_id=a.abstract_service_id + FOR XML AUTO, TYPE, ROOT('providers') + ) + AS VARCHAR(MAX)) + as providers_en + + + p.payment_periodicity + p.payment_periodicity_en + + b.budget_code + + b.budget + b.budget_en + + st.service_type + st.service_type_en + + mc.modifier_class + + (select count(*) from service s where s.abstract_service_id=a.abstract_service_id) as service_count + + (select count(*) from abstract_service_doc d where d.abstract_service_id=a.abstract_service_id) as doc_count + + CAST( + ( + select abstract_service_doc_id, abstract_service_doc, fname, contenttype, dt_created + from abstract_service_doc d + where d.abstract_service_id=a.abstract_service_id + FOR XML AUTO, TYPE, ROOT('docs') + ) + AS VARCHAR(MAX)) + as docs + + + from abstract_service a + join service_type st on (a.service_type_id=st.service_type_id) + join status u on (a.status_id=u.status_id) + left outer join modifier_class mc on (a.modifier_class_id=mc.modifier_class_id) + left outer join area g on (a.area_id=g.area_id) + left outer join budget b on (a.budget_id=b.budget_id) + left outer join measure m on (a.measure_id=m.measure_id) + left outer join payment_periodicity p on (b.payment_periodicity_id=p.payment_periodicity_id) + where 1=1 + order by + + + + + + + + +select count(*) as cnt from abstract_service where 1=1 + + + + + + + + + + + + + #i18("Каталог","Catalog")# + + + + + + + + + + + + + +

+ #d.XmlAttributes.provider# +

+
+ #cfcatch.message# #cfcatch.detail# +
+
+
+ + + + + + + + + +

+ + + + #d.XmlAttributes.abstract_service_doc##d.XmlAttributes.abstract_fname# (#dateFormat(d.XmlAttributes.dt_created,'DD.MM.YYYY')#) +

+
+ #cfcatch.message# #cfcatch.detail# +
+
+
+ + + + + + + + + + + + #abstract_service# + #abstract_service_en# + + #code# + + + + + Провайдеры + #request.formatProviders(providers)# + + + Providers + #request.formatProviders(providers_en)# + + + + #request.formatDocs(docs)# + + + + + + #gridFooter# + +
+ \ No newline at end of file diff --git a/area.cfm b/area.cfm new file mode 100644 index 0000000..3c09d8f --- /dev/null +++ b/area.cfm @@ -0,0 +1,200 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + pageInfo=#pageInfo# + id="#d.area_id#" + status=#pageInfo.status# + trackOut="tr" + idAttributesOut="id" +/> + + + + select + a.login as creator, a.shortname as creator_shortname, m.login as updater, m.shortname as updater_shortname + from area g + left outer join usr a on (g.creator_id=a.usr_id) + left outer join usr m on (g.updater_id=m.usr_id) + where g.area_id= + + + + + + + Группа каталога + + #d.area# + [#d.area_id#] + + + + + + +
#status.errorMessage#
+
+ + + + + + +
+ + +
+
ID
+
+ #d.area_id# +
+
+ +
+
Код
+
+ + используется для формирования кода услуги и кода sku +
+
+ +
+
Аналитический код
+
+ +
+
+ +
+
Группа (RUS)
+
+ +
+
+ +
+
Группа (ENG)
+
+ +
+
+ + +
+
Описание
+
+ +
+
+ +
+
Создано
+
+ #dateFormat(d.dt_created,'DD.MM.YYYY')# #timeFormat(d.dt_created,'HH:MM')# + #qDecoration.creator# (#qDecoration.creator_shortname#) +       + Изменено + #dateFormat(d.dt_updated,'DD.MM.YYYY')# #timeFormat(d.dt_updated,'HH:MM')# + #qDecoration.updater# (#qDecoration.updater_shortname#) +
+
+ +
+ +
+ + + + + + + select distinct + a.abstract_service_id + ,a.code + ,a.abstract_service + ,(select count(*) from service s where s.abstract_service_id=a.abstract_service_id) as svc_cnt + ,(select count(*) from abstract_service_param_class ac where ac.abstract_service_id=a.abstract_service_id) as param_cnt + from abstract_service a + where a.area_id= + order by a.code, a.abstract_service + + + +

Абстрактные услуги (#qAbstractService.recordCount#)

+
+ + + + + + + + + + + + + + + + + + + + + + +
Код услугиАбстрактная услугаВариантовКомпонентов
+ + + #code# + + #abstract_service# + + #svc_cnt# + + #param_cnt# + + +
+
+ + \ No newline at end of file diff --git a/area_del.cfm b/area_del.cfm new file mode 100644 index 0000000..3af754c --- /dev/null +++ b/area_del.cfm @@ -0,0 +1,67 @@ + + + + + + + + + + + + + a.abstract_service_id + a.code + a.abstract_service + + abstract_service a + left outer join area g on (a.area_id=g.area_id) + + g.area_id + 2 + + + + + + + + + + select + m.area + from area m + where m.area_id= + + + + + + + Удаление группы услуг + #qDecoration.area# + [#area_id#] + + +   + + +#markup# + + \ No newline at end of file diff --git a/area_ls.cfm b/area_ls.cfm new file mode 100644 index 0000000..9c67952 --- /dev/null +++ b/area_ls.cfm @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + + + select + + m.area_id + m.area_code + m.analytic_code + m.area + m.area_en + (select count(*) from abstract_service a where a.area_id=m.area_id) as as_cnt + (select count(*) from abstract_service a join service s on (a.abstract_service_id=s.abstract_service_id) where a.area_id=m.area_id) as svc_cnt + + from area m + where 1=1 + order by + + + + + + + + + +select count(*) as cnt from area where 1=1 + + + + + + + + + + + + Группы услуг + + + + + + + + + + + + + + + + + + + + + + title="редактировать" class="edit"title="просмотр" class="view"> + + + + + + + + + + + + + + + + + + + + + + + + + #gridFooter# + + + + + + + \ No newline at end of file diff --git a/area_ls1.cfm b/area_ls1.cfm new file mode 100644 index 0000000..4fa40c7 --- /dev/null +++ b/area_ls1.cfm @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + select + + m.area_id + m.area_code + m.analytic_code + m.area + + from area m + where 1=1 + order by + + + + + + + + + +select count(*) as cnt from area where 1=1 + + + + + + + + + + + + Группы каталога + + + + + + + + + function uc(x) {return UCase(x);} + + + + + + + + title="редактировать" class="edit"title="просмотр" class="view"> + + + + rrrrrrr + (#area_id#) + + _#area_code#_ + + + + + + + + + #gridFooter# + + + + + \ No newline at end of file diff --git a/builder.cfm b/builder.cfm new file mode 100644 index 0000000..a4221f2 --- /dev/null +++ b/builder.cfm @@ -0,0 +1,200 @@ + + + + + + + + + + + + +select o.type, o.name from sys.objects o where o.type in ('U','V') order by o.type, o.name + + + + +select c.name, c.system_type_id, c.max_length, c.is_nullable, c.is_identity from sys.columns c join sys.objects o on (c.object_id=o.object_id) where o.name= + + + +
+ + + + + + + + + checked/> + + + + + +
+ + + + + + +
+select 
+<d:field_set titleMapOut="titleMap" lengthOut="fieldCount">
+	<d:field title="#name#">#name#</d:field>
+</d:field_set>
+from #obj#
+
+
+ + + +
+select 
+	,#name#
+from #obj#
+
+
+ + +
+insert into #obj# (	
+	,#name#
+) values (
+	,<cfqueryparam cfsqltype="cf_sql_#fieldType(system_type_id)#" value="###name###"/>
+)
+
+
+ + + +
+update #obj# set 
+	,#name#=<cfqueryparam cfsqltype="cf_sql_#fieldType(system_type_id)#" value="###name###"/>
+where #obj#_id=<cfqueryparam cfsqltype="cf_sql_integer" value="###obj#_id##" null=##!isNumeric(#obj#_id)##/>
+
+
+ + +
+<d:bean readonly=#!pageInfo.writePermitted()# table="#obj#" datasource="#request.DS#" output="d" status="status">
+	
+		<d:param field="creator_id" type="integer" value="##request.usr_id##" skipUpdate/>
+		<d:param field="updater_id" type="integer" value="##request.usr_id##"/>
+		<d:param field="dt_created" type="timestamp" value="##Now()##" skipUpdate/>
+		<d:param field="dt_updated" type="timestamp" value="##Now()##"/>
+		<d:param field="#name#" type="#fieldType(system_type_id)#" size="#max_length#" preprocessor=##cleanInput## preprocessor=##plain2HtmClean## key autoincrement forNull="" default="0" init="0"/>
+	
+</d:bean>
+
+
+ + +
+<table class="worktable">	
+	<thead>	
+		<layout:grid_head titleMap=#titleMap# sortArray=#pageInfo.settings.sort.sortArray#>		
+			<th><layout:column_head name="#name#"/></th>
+			
+		</layout:grid_head>
+	</thead>
+	
+	<cfoutput query="qRead" maxrows="#pageInfo.recordsPerPage#" startrow="#pageInfo.nStart#">
+		<tr>
+			<td class="c">##dateFormat(#name#,'DD.MM.YYYY')#name###</td>
+			
+		</tr>
+	</cfoutput>		
+</table>
+
+
+ + +
+<div class="detail">	
+	
+	<div class="tr">
+		<div class="th">#name#</div>
+		<div class="td"><input type="text" name="#name#" id="#name#" value="<textarea rows="5" cols="70" name="#name#" id="#name#"><input type="checkbox" name="#name#" id="name" value="1"<cfif (##dateFormat(d.#name#,'DD.MM.YYYY')d.#name###"/></textarea> GT 0)> checked</cfif>/></div>
+	</div>
+	
+</div>
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/catalog_tree.cfm b/catalog_tree.cfm new file mode 100644 index 0000000..15187c0 --- /dev/null +++ b/catalog_tree.cfm @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + select + + + g.area_id + g.area + g.area_code + g.analytic_code + + a.abstract_service_id + a.abstract_service + a.code as abstract_service_code + + s.service_id + m.modifier + m.code as modifier_code + + ac.abstract_service_param_class_id + pc.param_class_id + pc.param_class + ac.is_multiple + + sp.service_param_id + p.param_id + p.param + p.param_short + p.code as param_code + + + + from area g + left outer join abstract_service a on (g.area_id=a.area_id) + left outer join service s on (a.abstract_service_id=s.abstract_service_id) + left outer join modifier m on (s.modifier_id=m.modifier_id) + left outer join abstract_service_param_class ac on (a.abstract_service_id=ac.abstract_service_id) + left outer join param_class pc on (ac.param_class_id=pc.param_class_id) + left outer join service_param sp on (s.service_id=sp.service_id AND ac.abstract_service_param_class_id=sp.abstract_service_param_class_id) + left outer join param p on (sp.param_id=p.param_id) + where 1=1 + order by g.analytic_code, a.code, m.code, s.service_id, ac.abstract_service_param_class_id, p.sort, p.code, p.param_id + + + + + + + + + + + + +select count(*) as cnt from param where 1=1 + + + + + + + + + + + + Дерево каталога + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/contract.cfm b/contract.cfm new file mode 100644 index 0000000..a1b3fdd --- /dev/null +++ b/contract.cfm @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + pageInfo=#pageInfo# + id="#d.contract_id#" + status=#pageInfo.status# + trackOut="tr" + idAttributesOut="id" +/> + + + + select + a.login as creator, a.shortname as creator_shortname, m.login as updater, m.shortname as updater_shortname + from contract g + left outer join usr a on (g.creator_id=a.usr_id) + left outer join usr m on (g.updater_id=m.usr_id) + where g.contract_id= + + + + + + + Договор + + #d.contract# + [#d.contract_id#] + + + + + + + + + + + + +
+ + +
+
ID
+
+ #d.contract_id# +
+
+ +
+
Номер договора
+
+ +
+
+ +
+
Дата договора
+
+ + +
+
+ +
+
Контрагент
+
+ + select c.contragent_id, c.contragent + from contragent c + order by 2 + + +
+
+ +
+
Создано
+
+ #dateFormat(d.dt_created,'YYYY-MM-DD')# #timeFormat(d.dt_created,'HH:MM')# + #qDecoration.creator# (#qDecoration.creator_shortname#) +       + Изменено + #dateFormat(d.dt_updated,'YYYY-MM-DD')# #timeFormat(d.dt_updated,'HH:MM')# + #qDecoration.updater# (#qDecoration.updater_shortname#) +
+
+ +
+ +
+ + + + + + + + select + s.specification_id + ,s.specification + ,(select count(*) from specification_item i where i.specification_id=s.specification_id) as item_cnt + from specification s + where s.contract_id= + order by 1 + + + +

Спецификации (#qSpecification.recordCount#)

+
+ + + + + + + + + + + + + + + + + + + + + + + + +
Номер спецификацииСтрок
+ + #specification# + #item_cnt# + + +
+
+ + + \ No newline at end of file diff --git a/contract_ls.cfm b/contract_ls.cfm new file mode 100644 index 0000000..8edaf11 --- /dev/null +++ b/contract_ls.cfm @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + select + + d.contract_id + c.contragent + d.contract + d.dt_contract + d.descr + (select count(*) from agreement s where s.contract_id=d.contract_id) as spec_cnt + + from contract d + join contragent c on (d.contragent_id=c.contragent_id) + where 1=1 + order by + + + + + + + + + +select count(*) as cnt from contract where 1=1 + + + + + + + + + + + + Договоры + + + + + + + + + + + + + + + + + + + + + + title="редактировать" class="edit"title="просмотр" class="view"> + + + + + + + + + + + + + + + + + + + + + + + + #gridFooter# + + + diff --git a/contragent.cfm b/contragent.cfm new file mode 100644 index 0000000..1641fb1 --- /dev/null +++ b/contragent.cfm @@ -0,0 +1,243 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + pageInfo=#pageInfo# + id="#d.contragent_id#" + status=#pageInfo.status# + trackOut="tr" + idAttributesOut="id" +/> + + + + select + a.login as creator, a.shortname as creator_shortname, m.login as updater, m.shortname as updater_shortname + from contragent g + left outer join usr a on (g.creator_id=a.usr_id) + left outer join usr m on (g.updater_id=m.usr_id) + where g.contragent_id= + + + + + + + Контрагент + + #d.contragent# + [#d.contragent_id#] + + + + + + + + + + + +
+ + +
+
ID
+
+ #d.contragent_id# +
+
+ +
+
Наименование
+
+ +
+
+ +
+
Провайдер
+
+ checked/> +
+
+ +
+
Внешний UID
+
+ Company UID из Элмы +
+
+ +
+
WZ
+
+ +
+
+ +
+
Описание
+
+ +
+
+ +
+
Создано
+
+ #dateFormat(d.dt_created,'YYYY-MM-DD')# #timeFormat(d.dt_created,'HH:MM')# + #qDecoration.creator# (#qDecoration.creator_shortname#) +       + Изменено + #dateFormat(d.dt_updated,'YYYY-MM-DD')# #timeFormat(d.dt_updated,'HH:MM')# + #qDecoration.updater# (#qDecoration.updater_shortname#) +
+
+ +
+ +
+ + + + + + select + d.contract_id + ,d.contract + ,d.dt_contract + ,(select count(*) from specification s where s.contract_id=d.contract_id) as spec_cnt + ,(select count(distinct resource_realm_id) from resource_realm_access a where a.contract_id=d.contract_id) as res_realm_cnt + from contract d + where d.contragent_id= + order by 1 + + + +

Договоры (#qContract.recordCount#)

+
+ + + + + + + + + + + + + + + + + + + + + + +
Номер договораДата договораСпецификацийРесурсных платформ
+ + #contract# + #dateFormat(dt_contract,'YYYY-MM-DD')# + + #spec_cnt# + + + #res_realm_cnt# + + +
+
+ Доступ к ресурсным платформам предоставляется на уровне договора + + + + select + u.usr_id + ,u.login + ,u.firstname + ,u.lastname + ,u.middlename + ,u.email + ,u.idp_usr_uid + from usr u + where u.contragent_id= + order by 1 + + + +

Пользователи (#qContract.recordCount#)

+
+ + + + + + + + + + + + + + + + + + + + + + +
ЛогинФ.И.О.e-mailIDP user UID
+ + #login##lastname# #firstname# #middlename##email##idp_usr_uid# + +
+
+ \ No newline at end of file diff --git a/contragent_ls.cfm b/contragent_ls.cfm new file mode 100644 index 0000000..465781a --- /dev/null +++ b/contragent_ls.cfm @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + select + + c.contragent_id + c.contragent + c.descr + c.external_uid + c.external_code + c.is_provider + (select count(*) from contract d where d.contragent_id=c.contragent_id) as contract_cnt + (select count(*) from specification s join contract d on (s.contract_id=d.contract_id) where d.contragent_id=c.contragent_id) as spec_cnt + (select count(*) from usr u where u.contragent_id=c.contragent_id) as usr_cnt + + from contragent c + where 1=1 + order by + + + + + + + + + +select count(*) as cnt from contragent where 1=1 + + + + + + + + + + + + Контрагенты + + + + + + + + + + + + + + + + + + + + + + title="редактировать" class="edit"title="просмотр" class="view"> + + + + + + + + + + + + + + + + + + + + + + + + + + + #gridFooter# + + + diff --git a/doc.cfm b/doc.cfm new file mode 100644 index 0000000..933348e --- /dev/null +++ b/doc.cfm @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +select +d.#entity#_id as entity_id, d.#entity#_doc as title, datalength(d.doc) as doc_size, d.contenttype, d.fname, +a.login as creator, a.shortname as creator_name, u.login as modifier, u.shortname as modifier_name + from #entity#_doc d + left outer join usr a on (d.creator_id=a.usr_id) + left outer join usr u on (d.updater_id=u.usr_id) + where d.#entity#_doc_id= + + + +#entitySpec.selectHead# +where d.#entity#_id= + + + + + Документ + + #title##fname# + (#contenttype#) + + + + + + + + + + + + + + + + +
+ + +
+
Название документа
+
+ +
+
+ + +
+
Имя файла
+
+ #qAttributes.fname# + + +
+
+ +
+
Content Type
+
+ #qAttributes.contenttype# + +
+
+ +
+
Размер
+
+ #qAttributes.doc_size# байт +
+
+
+ + +
+
Заменить файл
+
+ +
+
+
+ +
+
Создано
+
+ #dateFormat(d.dt_created,'DD.MM.YYYY')# #timeFormat(d.dt_created,'HH:MM')# + #qAttributes.creator# (#qAttributes.creator_name#) + Дата и время первоначальной загрузки +
+
+ +
+
Изменен
+
+ #dateFormat(d.dt_updated,'DD.MM.YYYY')# #timeFormat(d.dt_updated,'HH:MM')# + #qAttributes.modifier# (#qAttributes.modifier_name#) +
+
+ +
+
+ + + + + + + + + diff --git a/doc_del.cfm b/doc_del.cfm new file mode 100644 index 0000000..e26ae36 --- /dev/null +++ b/doc_del.cfm @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + select d.#entity#_doc as doc_name, d.fname, a.abstract_service, a.code + from #entity#_doc d + join #entity# a on (d.abstract_service_id=a.abstract_service_id) + where d.#entity#_doc_id= + + + + + + + Удаление документа + #qDecoration.doc_name#(#qDecoration.fname#) [#doc_id#] + абстрактной услуги + + #qDecoration.code# + #qDecoration.abstract_service# + + + + +   + + + + + +#markup# + + \ No newline at end of file diff --git a/doc_get.cfm b/doc_get.cfm new file mode 100644 index 0000000..6edd2ab --- /dev/null +++ b/doc_get.cfm @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + select d.doc, d.fname, d.contenttype + from #entity#_doc d + where #entity#_doc_id= + + + + + + + +#errMsg# + \ No newline at end of file diff --git a/etc/db/postgres.txt b/etc/db/postgres.txt new file mode 100644 index 0000000..29d3866 --- /dev/null +++ b/etc/db/postgres.txt @@ -0,0 +1,37 @@ +create table if not exists: не заменяет декларацию... затупил, не догадался +drop table if exists; + +14:04 17.04.2023 +ERROR: operator does not exist: uuid = character varying +Использовать для POSTGRESQL UUID: CF GUID+CF_SQL_OTHER + +Ошибка при записи в базу данных. ERROR: column "is_payg" is of type bit but expression is of type boolean Подсказка: You will need to rewrite or cast the expression. Позиция: 723 То же самое работает для abstract_service_param_class.cfm ??? +Очень странная разница: в abstract_service_param_class.cfm числа в d возвращаются как числа, а в tariff как строки +Ошибка: в БД нужно boolean, а в форме bit (транслируется в cf_sql_bit) +Теперь проблема с датой - добавил формат, ок. timestamp для Postgre работает + +Message ERROR: invalid input syntax for type uuid: "" +Где: unnamed portal parameter $1 = '' +SQL select count(*) as cnt +from service_tariff +where 1=1 +AND service_tariff_guid= +DatabaseName PostgreSQL +DatabaseVersion 15.1 +DriverName PostgreSQL JDBC Driver +DriverVersion 42.6.0 +Datasource svc +Stacktrace The Error Occurred in +D:\wwwroot\svc3\lib\data\bean.cfm: line 94 +- и как это работает для INT? ответ: (а у нас other... когда был idstam, все было однозначно, но с Postgre почему-то idstamp не работает - "Использовать для POSTGRESQL UUID: CF GUID+CF_SQL_OTHER" - вероятно, надо сделать свои типы и маппинг чуть сложнее, чем cf_sql_#type#) + +ошибка в dispatch_detail.cfm, рассчитанном на целочисленный id + +для idstamp + ERROR: operator does not exist: uuid = character + Подсказка: No operator matches the given name and argument types. You might need to add explicit type casts. + Позиция: 96 +для other + ERROR: invalid input syntax for type uuid: "" + Где: unnamed portal parameter $1 = '' +Но! в соседнем шаблоне tariff.cfm "other" работает, и в этом раньше работало - разница была в вызове, в одном случае было пустая строка, в другом отсутствовал параметр \ No newline at end of file diff --git a/etc/db/service_catalog.sql b/etc/db/service_catalog.sql new file mode 100644 index 0000000..9244f93 --- /dev/null +++ b/etc/db/service_catalog.sql @@ -0,0 +1,238 @@ +/* + + + +- +*/ + +-- +if exists (select * from sysobjects where name='measure') drop table measure +create table measure ( + measure_id int identity PRIMARY KEY NOT NULL + ,measure varchar(255) NOT NULL + ,measure_short varchar(9) NOT NULL + ,measure_short_en varchar(9) NULL + ,descr varchar(MAX) NULL +) +go + +insert into measure (measure, measure_short) values ('','.') +insert into measure (measure, measure_short) values ('','') +insert into measure (measure, measure_short) values ('-','-') +insert into measure (measure, measure_short) values ('','') +insert into measure (measure, measure_short) values ('','') +insert into measure (measure, measure_short) values ('10000 .','10..') + +go + +if exists (select * from sysobjects where name='service_type') drop table service_type +create table service_type ( + service_type_id int PRIMARY KEY NOT NULL + ,service_type varchar(255) NOT NULL +) +go + +insert into service_type (service_type_id, service_type) values (1,'') +insert into service_type (service_type_id, service_type) values (2,'') -- , +insert into service_type (service_type_id, service_type) values (3,'') +go + +-- . , , , +-- , +if exists (select * from sysobjects where name='modifier_class') drop table modifier_class +create table modifier_class ( + modifier_class_id int identity PRIMARY KEY NOT NULL + ,modifier_class varchar(255) NOT NULL + ,descr varchar(MAX) NULL +) +go + +-- +if exists (select * from sysobjects where name='modifier') drop table modifier +create table modifier ( + modifier_id int identity PRIMARY KEY NOT NULL + ,modifier_class_id int NOT NULL + ,modifier varchar(255) NOT NULL + ,modifier_en varchar(255) NULL + ,descr varchar(MAX) NULL +) +go +--alter table modifier add modifier_en varchar(255) NULL + +-- 1 + +if exists (select * from sysobjects where name='abstract_service') drop table abstract_service +create table abstract_service ( + abstract_service_id int identity PRIMARY KEY NOT NULL + ,abstract_service varchar(255) NOT NULL + ,service_type_id INT NOT NULL + ,modifier_class_id INT NULL -- migrated from service (no support for multiple modifier classes) + ,code varchar(31) NOT NULL + ,version int NOT NULL + ,descr varchar(MAX) NULL +) +go + +/* +-- +-- , ( ), +-- modifier_class_id abstract_service +if exists (select * from sysobjects where name='service_class') drop table service_class +create table service_class ( + service_class_id int identity PRIMARY KEY NOT NULL + ,abstract_service_id int NOT NULL + ,modifier_class_id INT NULL + --,service_class varchar(255) NOT NULL -- + ,descr varchar(MAX) NULL +) +go +*/ + +-- +-- 1 , +-- +-- () , +-- , +if exists (select * from sysobjects where name='service') drop table service +create table service ( + service_id int identity PRIMARY KEY NOT NULL + ,abstract_service_id int NOT NULL + ,modifier_id INT NULL + --,service varchar(255) NOT NULL -- + ,descr varchar(MAX) NULL + ,measure_id int NULL --*** ? + ,precision int NULL + ,base_price decimal(15,4) NULL + ,CONSTRAINT UK_abstract_service_modifier UNIQUE(abstract_service_id, modifier_id) +) +go +--alter table service add measure_id int NULL +--alter table service add precision int NULL +--alter table service add base_price decimal(15,4) NULL +--alter table service add CONSTRAINT UK_abstract_service_modifier UNIQUE(abstract_service_id, modifier_id) + +-- , , +-- +if exists (select * from sysobjects where name='param_class') drop table param_class +create table param_class ( + param_class_id int identity PRIMARY KEY NOT NULL + ,param_class varchar(255) NOT NULL + ,measure_id int NULL + /*,precision int NULL + ,show_in_spec bit NOT NULL*/ + ,descr varchar(MAX) NULL +) +go + +if exists (select * from sysobjects where name='param') drop table param +create table param ( + param_id int identity PRIMARY KEY NOT NULL + ,param_class_id int NULL--NOT NULL + ,param varchar(255) NOT NULL + ,measure_id int NULL -- overrides param_class.measure + ,precision int NULL -- *** , , , param_class.precision + --,show_in_spec bit NOT NULL default 1 + ,base_price decimal(15,4) NULL -- , - + ,descr varchar(MAX) NULL +) + +--alter table param add base_price decimal(15,4) NULL +--alter table param add measure_id int NULL +go +-- , +-- +-- , + +-- 2 : +-- 1:1, 1:n +if exists (select * from sysobjects where name='service_param') drop table service_param +create table service_param ( + service_param_id int identity PRIMARY KEY NOT NULL + ,service_id int NOT NULL -- FK + --,modifier_id int NULL -- FK + ,param_class_id int NULL -- . 1 : , + ,param_id int NULL + --,base_price decimal(15,4) NULL -- . , - + ,descr varchar(MAX) NULL + ,CONSTRAINT CK_param_xor_class CHECK (((param_class_id IS NULL) AND NOT (param_id IS NULL)) OR ((param_id IS NULL) AND NOT (param_class_id IS NULL))) + -- , + -- alter table service_param drop CONSTRAINT CK_param_xor_class +) +go + +-- service_param , 1:1, - 1:n +-- +-- , +if exists (select * from sysobjects where name='service_param_price') drop table service_param_price +create table service_param_price ( + service_param_price_id int identity PRIMARY KEY NOT NULL + ,service_param_id int NOT NULL -- FK, 1:1. , + --,param_class_id int NOT NULL + ,param_id int NOT NULL + ,base_price decimal(15,4) NULL -- , . , - + CONSTRAINT UK_service_param_price UNIQUE (service_param_id, param_id) +) +go + + + +if exists (select * from sysobjects where name='specification') drop table specification +create table specification ( + specification_id int identity PRIMARY KEY NOT NULL + ,specification varchar(255) NOT NULL + ,descr varchar(MAX) NULL +) +go + + +if exists (select * from sysobjects where name='specification_item') drop table specification_item +create table specification_item ( + specification_item_id int identity PRIMARY KEY NOT NULL + ,specification_id int NOT NULL + ,service_id int NOT NULL + --,modifier_id int NULL + ,specification_item varchar(1023) NOT NULL -- + ,quantity decimal(15,4) NULL + ,price decimal(15,4) NULL -- +) +go +--alter table specification_item alter column specification_item varchar (1023) NOT NULL + +if exists (select * from sysobjects where name='specification_item_param') drop table specification_item_param +create table specification_item_param ( + specification_item_param_id int identity PRIMARY KEY NOT NULL + ,specification_item_id int NOT NULL + ,service_param_id int NOT NULL -- , param_id + ,param_id int NULL -- , *** , + ,quantity decimal(15,4) NULL + ,price decimal(15,4) NULL +) +go + +---------------------------------------- +--9:00 24.09.2020 +-- , +if exists (select * from sysobjects where name='site') drop table site +create table site ( + site_id int identity PRIMARY KEY NOT NULL + ,site varchar(255) NOT NULL + ,descr varchar(MAX) NULL +) +go + +insert into site(site) values(' -9') +insert into site(site) values(' -10') +insert into site(site) values(' ') +insert into site(site) values(' ') +insert into site(site) values(' ') +insert into site(site) values(' ') +insert into site(site) values(' ') +insert into site(site) values(' NORD') +insert into site(site) values(' OST') +go + + + + + + diff --git a/etc/db/set_env.cmd b/etc/db/set_env.cmd new file mode 100644 index 0000000..34f4fc0 --- /dev/null +++ b/etc/db/set_env.cmd @@ -0,0 +1,8 @@ +REM set Windows env +setx datasource_svc_class org.postgresql.Driver /M +setx datasource_svc_connectionString jdbc:postgresql://localhost:5432/svc /M +setx datasource_svc_username postgres /M +setx datasource_svc_password encrypted:8ea2101f286dfcf2947cb2162e927cb769b3f845b6d4c57ef2ae89463d72d97842a2228c7ba562a24ee8eaf728350ab6 /M +setx datasource_svc_connectionLimit 5 /M + +pause diff --git a/etc/db/spec.sql b/etc/db/spec.sql new file mode 100644 index 0000000..959ab30 --- /dev/null +++ b/etc/db/spec.sql @@ -0,0 +1,409 @@ +/* + +*/ + +-- +drop table if exists measure CASCADE; +create table measure ( + measure_id int GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY NOT NULL + ,measure varchar(255) NOT NULL + ,measure_short varchar(9) NOT NULL + + ,creator_id int NULL + ,updater_id int NULL + ,dt_created timestamp NOT NULL default CURRENT_TIMESTAMP -- + ,dt_updated timestamp NOT NULL default CURRENT_TIMESTAMP -- +); +insert into measure (measure, measure_short) values ('','.'); +insert into measure (measure, measure_short) values ('',''); +insert into measure (measure, measure_short) values ('-','-'); +insert into measure (measure, measure_short) values ('',''); +insert into measure (measure, measure_short) values ('',''); +insert into measure (measure, measure_short) values ('10000 .','10..'); + + +drop table if exists contragent CASCADE; +create table contragent ( + contragent_id int GENERATED BY DEFAULT AS IDENTITY NOT NULL PRIMARY KEY + ,contragent varchar(255) NULL + ,descr text NULL -- comments + ,is_provider bool NOT NULL DEFAULT false + ,external_uid uuid NULL + ,external_code varchar(255) NULL --WZ + ,dt_created timestamptz NOT NULL default CURRENT_TIMESTAMP -- + ,creator_id int NULL -- , + ,dt_updated timestamptz NOT NULL default CURRENT_TIMESTAMP + ,updater_id int NULL -- , +); +ALTER TABLE contragent OWNER TO dbo; +-- +insert into contragent (contragent, is_provider) values ('NUBES', true); -- , , +insert into contragent (contragent) values + (' ') +,(' ') +; + + +drop table if exists contract CASCADE; +create table contract ( + contract_id int GENERATED BY DEFAULT AS IDENTITY NOT NULL PRIMARY KEY + ,contragent_id int NOT NULL + ,contract varchar(255) NULL -- + ,dt_contract timestamptz NOT NULL + ,is_closed bool NOT NULL default false + ,dt_closed timestamptz NULL -- + + ,descr text NULL -- comments + ,dt_created timestamptz NOT NULL default CURRENT_TIMESTAMP -- + ,creator_id int NULL -- , + ,dt_updated timestamptz NOT NULL default CURRENT_TIMESTAMP -- + ,updater_id int NULL -- , +); +ALTER TABLE contract OWNER TO dbo; +insert into contract (contragent_id,contract,dt_contract) values (2,'test',CURRENT_TIMESTAMP); + +-- +drop table if exists agreement CASCADE; +create table agreement ( + --agreement_id int GENERATED BY DEFAULT AS IDENTITY NOT NULL PRIMARY KEY + --, + contract_id int NOT NULL + ,agreement_version int NOT NULL + ,agreement varchar(255) NULL -- + ,dt_agreement timestamptz NOT NULL -- , ( , ) + ,is_actual boolean NOT NULL -- , 1 - , , , + + ,descr text NULL + ,dt_created timestamptz NOT NULL default CURRENT_TIMESTAMP -- + ,creator_id int NULL -- , + ,dt_updated timestamptz NOT NULL default CURRENT_TIMESTAMP -- + ,updater_id int NULL -- , + ,CONSTRAINT PK_agreement PRIMARY KEY (contract_id, agreement_version) +); +ALTER TABLE agreement OWNER TO dbo; +insert into agreement (contract_id,agreement_version,dt_agreement,is_actual) values (1,0,CURRENT_TIMESTAMP,true); + +-- , ( ) +drop table if exists specification CASCADE; +create table specification ( + specification_id int GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY NOT NULL + ,specification varchar(255) NOT NULL + ,contract_id int NOT NULL + + ,descr text NULL + ,creator_id int NULL + ,updater_id int NULL + ,dt_created timestamp NOT NULL default CURRENT_TIMESTAMP -- + ,dt_updated timestamp NOT NULL default CURRENT_TIMESTAMP -- +); +ALTER TABLE specification OWNER TO dbo; +insert into specification (specification,contract_id) values ('first spec',1); + + +-- +drop table if exists specification_version CASCADE; +create table specification_version ( + specification_id int + ,agreement_version int NOT NULL -- FK agreement + + ,descr text NULL + ,creator_id int NULL + ,updater_id int NULL + ,dt_created timestamp NOT NULL default CURRENT_TIMESTAMP -- + ,dt_updated timestamp NOT NULL default CURRENT_TIMESTAMP -- + ,CONSTRAINT PK_specification_version PRIMARY KEY (specification_id, agreement_version) +); +ALTER TABLE specification_version OWNER TO dbo; + +-- +drop table if exists specification_item CASCADE; +create table specification_item ( + specification_item_uid uuid NOT NULL PRIMARY KEY DEFAULT gen_random_uuid() -- + ,specification_id int NOT NULL --FK + ,svc_id int NOT NULL --immutable + + ,creator_id int NULL + ,updater_id int NULL + ,dt_created timestamp NOT NULL default CURRENT_TIMESTAMP -- + ,dt_updated timestamp NOT NULL default CURRENT_TIMESTAMP -- +); +ALTER TABLE specification_item OWNER TO dbo; + +-- ( ) +drop table if exists specification_item_version CASCADE; +create table specification_item_version ( + specification_item_uid uuid NOT NULL -- + ,agreement_version int NOT NULL -- : - ( , *** , ) + ,dt_from timestamptz NULL + ,dt_to timestamptz NULL + + ,specification_item_version varchar(1023) NOT NULL -- + ,quantity decimal(15,4) NULL + ,price decimal(15,4) NULL + + ,creator_id int NULL + ,updater_id int NULL + ,dt_created timestamp NOT NULL default CURRENT_TIMESTAMP -- + ,dt_updated timestamp NOT NULL default CURRENT_TIMESTAMP -- + ,CONSTRAINT PK_specification_item_version PRIMARY KEY (specification_item_uid, agreement_version) +); +ALTER TABLE specification_item OWNER TO dbo; + +-- () , +drop table if exists specification_item_param CASCADE; +create table specification_item_param ( + specification_item_param_id int GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY NOT NULL + ,specification_item_uid uuid NOT NULL + ,agreement_version int NOT NULL + + ,service_param_id int NOT NULL + ,quantity decimal(15,4) NULL + ,price decimal(15,4) NULL + + ,creator_id int NULL + ,updater_id int NULL + ,dt_created timestamp NOT NULL default CURRENT_TIMESTAMP -- + ,dt_updated timestamp NOT NULL default CURRENT_TIMESTAMP -- +); +ALTER TABLE specification_item_param OWNER TO dbo; + + +drop table if exists svc CASCADE; +CREATE TABLE svc ( + svc_id integer NOT NULL, + svc character varying(255), + descr text, + dt_created timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + creator_id integer, + dt_updated timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, + updater_id integer, + is_production_ready boolean DEFAULT false NOT NULL, + code character varying(255), + man text, + svc_short character varying(255), + resource_realm_type_id integer, + version character varying(255), + orchestrator_name character varying(255), + sort integer +); +ALTER TABLE svc OWNER TO dbo; + +INSERT INTO svc VALUES (92, 'k8s_mongodb', '', '2024-09-09 12:53:00.022+03', 3, '2024-09-09 12:53:00.022+03', 3, false, NULL, NULL, NULL, NULL, NULL, NULL, NULL); +INSERT INTO svc VALUES (95, 'NodeJS - ', ': node:16', '2024-12-10 17:57:41.06+03', 3, '2025-03-07 18:12:53.508+03', 3, true, '', ': node:16', 'nodejs', 3, '0.0.6', 'Node', NULL); +INSERT INTO svc VALUES (50, 'Nextcloud - ', ' : k8s. : helm chart', '2024-09-09 12:51:27.551+03', 3, '2025-02-28 18:11:26.017+03', 3, true, '', ' : k8s. : helm chart', 'nextcloud', 3, '0.0.3', 'Nextcloud', NULL); +INSERT INTO svc VALUES (21, ' VM (vc_vdc)', ' Cloud Director. ', '2024-04-08 10:59:07.350806+03', NULL, '2025-02-12 15:42:07.821+03', 10, false, '', ' Cloud Director. ', '', NULL, NULL, NULL, NULL); +INSERT INTO svc VALUES (26, 'vApp VM (vc_vapp)', ' . vc_nsxt', '2024-12-23 14:54:46.277+03', 3, '2025-02-12 15:42:46.017+03', 10, false, '', ' . vc_nsxt', '', NULL, NULL, NULL, NULL); +INSERT INTO svc VALUES (111, 'DNS-', '', '2024-09-17 14:22:05.028+03', 11, '2025-02-28 16:45:10.351+03', 3, true, '', '', 'dnsrecord', 4, '0.0.4', 'Records', NULL); +INSERT INTO svc VALUES (13, 'S3 (s3_bucket)', ' S3
: Ceph', '2024-12-11 23:19:43.469+03', 3, '2025-02-28 16:43:49.758+03', 3, true, '', ' S3
: Ceph', 's3bucket', 1, '0.0.3', 'Bucket', NULL); +INSERT INTO svc VALUES (20, ' VM Cloud Director (vc_organization)', ' ', '2024-04-08 10:59:07.350806+03', NULL, '2025-02-12 15:41:57.046+03', 10, false, '', ' ', '', NULL, NULL, NULL, NULL); +INSERT INTO svc VALUES (12, 'S3 - ', 'S3 account, CEPH (S3 CEPH). , ', '2024-04-08 10:59:07.350806+03', NULL, '2025-02-28 16:42:41.829+03', 3, true, '', 'S3 account, CEPH (S3 CEPH). , ', 's3', 1, '1.0.0', 'Ceph', NULL); +INSERT INTO svc VALUES (32, 'PostgreSQL (vc_vm_postgresql_std)', ' PostgreSQL .


Postgre - 17', '2024-08-05 12:47:46.275+03', 3, '2025-02-12 15:42:55.441+03', 10, false, '', ' PostgreSQL .


Postgre - 17', '', NULL, NULL, NULL, NULL); +INSERT INTO svc VALUES (100, 'tenantOpenwhisk', ' Openwhisk', '2024-09-12 13:43:55.166+03', 3, '2024-12-26 13:06:02.166+03', 3, false, '', ' Openwhisk', NULL, NULL, NULL, NULL, NULL); +INSERT INTO svc VALUES (25, ' IP VM (vc_external_ip)', ' external Ip Cloud Director.
', '2024-12-12 16:32:45.488+03', 3, '2025-02-28 16:47:42.541+03', 3, true, '', ' external Ip Cloud Director.
', 'vcexternalip', 2, '0.0.2', 'Ip', NULL); +INSERT INTO svc VALUES (96, 'pgAdmin - PostgreSQL', '', '2024-12-10 18:28:43.874+03', 3, '2025-02-28 17:48:10.242+03', 3, true, '', '', 'pgadmin', 3, '0.0.2', 'Pgadmin', NULL); +INSERT INTO svc VALUES (110, 'DNS-', '', '2024-09-16 18:52:52.357+03', 11, '2025-02-28 16:45:17.753+03', 3, true, '', '', 'dnszone', 4, '0.0.3', 'Zones', NULL); +INSERT INTO svc VALUES (99, 'k8s_gitea', '', '2025-02-28 17:18:32.548+03', 3, '2025-02-28 17:43:41.652+03', 3, true, '', '', '', 3, '0.0.1', 'Gitea', NULL); +INSERT INTO svc VALUES (82, 'Harbor Registry (registry_k8s)', 'Harbor Registry. : k8s. : helm chart. : keycloak', '2024-09-09 12:52:04.345+03', 3, '2025-02-28 18:09:50.071+03', 3, true, '', 'Harbor Registry. : k8s. : helm chart. : keycloak', 'harbor', 3, '0.0.2', 'Registry', NULL); +INSERT INTO svc VALUES (2, 'k8sTemplate', '', '2025-02-28 17:06:21.371+03', 3, '2025-02-28 17:06:48.617+03', 3, false, '', '', '', 3, '0.0.1', 'Template', NULL); +INSERT INTO svc VALUES (23, 'VM Cloud Director (vc_vm)', ' - .
vc_ip ', '2024-08-02 12:53:13.869+03', 3, '2025-02-12 15:42:20.771+03', 10, false, '', ' - .
vc_ip ', '', NULL, NULL, NULL, NULL); +INSERT INTO svc VALUES (91, 'Redis In-Memory DB Cluster on k8s', 'Redis . .
: k8s.
: k8s operator
port 6379', '2024-09-09 12:52:49.473+03', 3, '2025-03-07 11:39:36.69+03', 3, true, '', '', 'redis', 3, '0.0.3', 'Redis', NULL); +INSERT INTO svc VALUES (81, 'Apache Superset - (superset_k8s)', 'Apache Superset .
: k8s.
: k8s operator.
: 2FA keycloak ( @mgmt.nubes.ru)', '2024-09-09 12:51:49.122+03', 3, '2025-02-28 18:09:54.127+03', 3, true, '', 'Apache Superset .
: k8s.
: k8s operator.
: 2FA keycloak ( @mgmt.nubes.ru)', 'superset', 3, '0.0.1', 'Superset', NULL); +INSERT INTO svc VALUES (22, ' VM (vc_nsxt)', '', '2024-04-08 10:59:07.350806+03', NULL, '2025-02-28 17:19:33.266+03', 3, false, '', '', '', NULL, '', '', NULL); +INSERT INTO svc VALUES (93, 'RabbitMQ - (rabbitmq_k8s)', 'RabbitMQ', '2024-09-09 12:53:09.059+03', 3, '2025-03-07 11:39:29.483+03', 3, true, '', '', 'rabbitmq', 3, '0.0.3', 'Rabbitmq', NULL); +INSERT INTO svc VALUES (90, 'PostgreSQL RDBMS Cluster', 'PostgreSQL . : k8s. : k8s operator.
, .', '2024-09-09 12:52:34.457+03', 3, '2025-03-12 10:36:06.529+03', 3, true, '', 'PostgreSQL . : k8s. : k8s operator.
, .', 'postgres', 3, '0.0.5', 'Pgsql', NULL); +INSERT INTO svc VALUES (98, 'k8s_simple_http_container', '', '2025-02-28 17:18:40.813+03', 3, '2025-02-28 17:43:48.248+03', 3, true, '', '', 'http', 3, '0.0.3', 'SimpleHttpContainer', NULL); +INSERT INTO svc VALUES (94, 'Lucee - ', ': lucee/lucee:latest', '2024-12-10 16:53:24.068+03', 3, '2025-03-10 10:13:04.713+03', 3, true, '', ': lucee/lucee:latest', 'lucee', 3, '0.0.9', 'Lucee', NULL); +INSERT INTO svc VALUES (1, 'dummy service', ' ', '2024-04-19 19:10:30.206+03', 3, '2025-04-30 19:00:08.473+03', 10, true, '', '', 'dummy', 7, '', 'dummy', NULL); +INSERT INTO svc VALUES (112, 'grafana_tenant', '', '2025-03-12 12:30:15.669+03', 3, '2025-04-28 18:40:23.781+03', 10, false, '', '', 'tenant', 6, '0.0.2', 'Tenant', NULL); + +ALTER TABLE ONLY svc + ADD CONSTRAINT PK_svc PRIMARY KEY (svc_id); + + + + + + + + + +------------------------------------------------------------------------- +-- IAM +------------------------------------------------------------------------- +-- usr is normally shared view +drop table if exists usr; +create table usr( + usr_id int GENERATED BY DEFAULT AS IDENTITY(START WITH 11) PRIMARY KEY NOT NULL + ,firstname varchar(255) NULL + ,middlename varchar(255) NULL + ,lastname varchar(255) NOT NULL + ,login varchar(255) NOT NULL + ,password varchar(255) NULL -- changed from varbinary for postgre and Argon2 + ,email varchar(255) NOT NULL + ,phone_cell varchar(50) NULL + ,descr text NULL + ,settings text NULL + ,locked boolean NOT NULL CONSTRAINT DF_usr_locked DEFAULT(false) + + ,creator_id int NULL + ,updater_id int NULL + ,dt_created timestamp NOT NULL default CURRENT_TIMESTAMP -- + ,dt_updated timestamp NOT NULL default CURRENT_TIMESTAMP -- + + ,fullname varchar GENERATED ALWAYS AS ((lastname||rtrim(' '||coalesce(firstname,'')))||rtrim(' '||coalesce(middlename,''))) STORED + ,shortname varchar GENERATED ALWAYS AS (replace((lastname||rtrim(' '||coalesce(left(firstname,(1))||'.','')))||rtrim(' '||coalesce(left(middlename,(1))||'.','')),' .','')) STORED +); +create unique index UX_login on usr(login); +insert into usr (usr_id,firstname,middlename,lastname,login,password,email,phone_cell) + values (2,'','',' ','anonymous',null,'',null); +insert into usr (usr_id,firstname,middlename,lastname,login,password,email,phone_cell) + values (10,'','','','smishchuk','$argon2id$v=19$m=500,t=3,p=4$d37RBdizC3rwQfINGSoQmg$Bwvr1f+RQf9hpXwV58sgUYzYpupp7iUzfUBACGApT80','msyu@mail.ru',null); + +------------------------------ + +drop table if exists obj; +create table obj ( -- + obj varchar(63) NOT NULL PRIMARY KEY + ,descr text NULL -- + + ,creator_id int NULL + ,updater_id int NULL + ,dt_created timestamp NOT NULL default CURRENT_TIMESTAMP -- + ,dt_updated timestamp NOT NULL default CURRENT_TIMESTAMP -- +); + +drop table if exists role; +create table role ( -- + role_id int /*identity*/ NOT NULL PRIMARY KEY + ,role varchar(255) NOT NULL + ,descr text NULL -- + + ,creator_id int NULL + ,updater_id int NULL + ,dt_created timestamp NOT NULL default CURRENT_TIMESTAMP -- + ,dt_updated timestamp NOT NULL default CURRENT_TIMESTAMP -- +); +insert into role (role_id,role) values (1,''); +insert into role (role_id,role) values (2,''); -- + + +drop table if exists usr_role; +create table usr_role ( -- + role_id int NOT NULL + ,usr_id int NOT NULL + ,CONSTRAINT PK_usr_role primary key (usr_id, role_id) + + ,creator_id int NULL + ,dt_created timestamp NOT NULL default CURRENT_TIMESTAMP -- +); +insert into usr_role (role_id,usr_id) values (2,2); +insert into usr_role (role_id,usr_id) values (1,10); + + +drop table if exists acl; +create table acl( + obj varchar(63) NOT NULL + ,role_id int NOT NULL + ,permission int NOT NULL -- 1=READ 2=WRITE + + ,creator_id int NULL + ,modifier_id int NULL + ,dt_created timestamp NOT NULL default CURRENT_TIMESTAMP -- + ,dt_modified timestamp NOT NULL default CURRENT_TIMESTAMP -- + ,CONSTRAINT PK_acl PRIMARY KEY (obj, role_id) +); + + +/* insert into obj (obj,descr) values ('abstract_service',' '); +insert into obj (obj,descr) values ('price','- '); + +insert into obj (obj,descr) values ('service',' ( )'); +insert into obj (obj,descr) values ('abstract_service_rpt',''); +insert into obj (obj,descr) values ('price_rpt','-: '); +insert into obj (obj,descr) values ('export',' '); + +insert into obj (obj,descr) values ('modifier_class',' '); +insert into obj (obj,descr) values ('modifier',''); +insert into obj (obj,descr) values ('param_class',' '); +insert into obj (obj,descr) values ('param',''); +insert into obj (obj,descr) values ('measure',' '); +insert into obj (obj,descr) values ('site',' '); +insert into obj (obj,descr) values ('provider',' ()'); +insert into obj (obj,descr) values ('area',' '); + +insert into obj (obj,descr) values ('service_param',' '); + +insert into obj (obj,descr) values ('specification',''); +insert into obj (obj,descr) values ('specification_item',' '); +insert into obj (obj,descr) values ('specification_item_param',' ( )'); + +insert into obj (obj,descr) values ('usr',''); +insert into obj (obj,descr) values ('acl',' '); + +insert into obj (obj,descr) values ('service_param_price',' '); +insert into obj (obj,descr) values ('service_price',' '); + +insert into obj (obj,descr) values ('abstract_service_complementary',' '); */ + + +/* -- +insert into acl(obj,role_id,permission) values ('abstract_service',2,1); +insert into acl(obj,role_id,permission) values ('price',2,1); +insert into acl(obj,role_id,permission) values ('service',2,1); +insert into acl(obj,role_id,permission) values ('abstract_service_rpt',2,1); +insert into acl(obj,role_id,permission) values ('abstract_service_doc',2,1); +insert into acl(obj,role_id,permission) values ('price_rpt',2,1); + +insert into acl(obj,role_id,permission) values ('modifier_class',2,1); +insert into acl(obj,role_id,permission) values ('modifier',2,1); +insert into acl(obj,role_id,permission) values ('param_class',2,1); +insert into acl(obj,role_id,permission) values ('param',2,1); +insert into acl(obj,role_id,permission) values ('measure',2,1); +insert into acl(obj,role_id,permission) values ('site',2,1); +insert into acl(obj,role_id,permission) values ('provider',2,1); +insert into acl(obj,role_id,permission) values ('area',2,1); + +insert into acl(obj,role_id,permission) values ('specification',2,1); +insert into acl(obj,role_id,permission) values ('specification_item',2,1); +insert into acl(obj,role_id,permission) values ('specification_item_param',2,1); + +insert into acl(obj,role_id,permission) values ('service_param',2,1); +insert into acl(obj,role_id,permission) values ('abstract_service_param_class',2,1); +insert into acl(obj,role_id,permission) values ('service_param_price',2,1); +insert into acl(obj,role_id,permission) values ('service_price',2,1); +insert into acl(obj,role_id,permission) values ('abstract_service_complementary',2,1); + +-- +insert into acl(obj,role_id,permission) values ('abstract_service',1,2); +insert into acl(obj,role_id,permission) values ('price',1,2); +insert into acl(obj,role_id,permission) values ('service',1,2); +insert into acl(obj,role_id,permission) values ('abstract_service_rpt',1,2); +insert into acl(obj,role_id,permission) values ('abstract_service_doc',1,2); +insert into acl(obj,role_id,permission) values ('price_rpt',1,2); +insert into acl(obj,role_id,permission) values ('export',1,2); + +insert into acl(obj,role_id,permission) values ('modifier_class',1,2); +insert into acl(obj,role_id,permission) values ('modifier',1,2); +insert into acl(obj,role_id,permission) values ('param_class',1,2); +insert into acl(obj,role_id,permission) values ('param',1,2); +insert into acl(obj,role_id,permission) values ('measure',1,2); +insert into acl(obj,role_id,permission) values ('site',1,2); +insert into acl(obj,role_id,permission) values ('provider',1,2); +insert into acl(obj,role_id,permission) values ('area',1,2); + +insert into acl(obj,role_id,permission) values ('specification',1,2); +insert into acl(obj,role_id,permission) values ('specification_item',1,2); +insert into acl(obj,role_id,permission) values ('specification_item_param',1,2); + + +insert into acl(obj,role_id,permission) values ('usr',1,2); +insert into acl(obj,role_id,permission) values ('acl',1,2); + +insert into acl(obj,role_id,permission) values ('service_param',1,2); +insert into acl(obj,role_id,permission) values ('abstract_service_param_class',1,2); +insert into acl(obj,role_id,permission) values ('service_param_price',1,2); +insert into acl(obj,role_id,permission) values ('service_price',1,2); +insert into acl(obj,role_id,permission) values ('abstract_service_complementary',1,2); */ + + + \ No newline at end of file diff --git a/etc/spec.txt b/etc/spec.txt new file mode 100644 index 0000000..9ec0768 --- /dev/null +++ b/etc/spec.txt @@ -0,0 +1,30 @@ +2025-06-02 +можно отметить, что тут смешаны версионность допника и темпоральность строки +Можно сделать таблицу, собирающую версии строк, чтобы не искать каждый раз (а может, нам не нужен снапшот на произвольную дату? или версию допника - вот, я уже запутался) +в сервисе нет единиц измерения у меня +31.05.2025 +Спецификация относится к договору. В принципе, в договоре может быть несколько спецификаций, но поддерживать это не кажется безусловно нужным. Каждая новая действующая версия спецификации относится к доп соглашению (возможно для договора ввести нулевой допник). Возможно, для редактирования захочется ввести редакторскую версионность, эту мы не рассматриваем. + +Для обсуждения версионности важно, что мы имеем дело с услугами, которые длятся (в отличие от них, для продажи товаров, видимо, имеет смысл только тривиальная редакторская версионность, не имеющая отношения к учету). +Спецификация состоит из номенклатурных позиций с ценой, количеством, датой начала и окончания действия, уникальным ключом строки. Ключ строки может соотноситься 1 к 1 с объектом биллинга для индивидуальных объектов (облачный пул) или 1 ко многим для счетных объектов (ip адрес). Включение разнородных объектов, отличающихся модификаторами (соответственно, кодами) или значениями параметров, не поддерживается. +Версионность спецификации поддерживает: добавление, удаление, изменение строки (почти тоже самое, что услуги) . При добавлении или удалении услуги обязательный атрибут - дата начала или завершения оказания услуги (обе даты имеют смысл "включительно": первый и последний день оказания услуги). Дата начала/завершения может быть какой угодно (хоть через 5 лет, мы не реализуем проверок), но с одним ограничением: даты в цепочке версий строки должны быть последовательными (монотонными), дата завершения не меньше даты начала, дата начала следующей версии не меньше даты завершения предыдущей версии. + +Добавленная услуга получает уникальный ключ строки. Ключ удаленной услуги (строки) дискардится. Видимо, есть разные похожие сценарии: удалить услугу (вместе со строкой) с некоторой даты, обнулить количество с некоторой даты, завершить обслуживание с некоторой даты. Разница будет видна, когда дойдем до модификации. + +Разница между строкой и инстансом услуги, возможно, нуждается в пояснении. Когда мы редактируем строку, мы подразумеваем, что за ней могут стоять индивидуальные инстансы. Например, при расширении вычислительного пула мы говорим про конкретный пул (в том числе имеющий уникальный идентификатор) , а не просто докидываем куда-то гигабайт или рублей. В случае со счетными объектами обычно подразумевается, что при увеличении количества объекты добавляются к множеству, при уменьшении - убираются из него (строго говоря, это не так - увеличение просто значит, что добавили больше, чем убрали, причем поменяться могли все элементы). Счетные объекты (те же стойки) обычно имеют индивидуальность: у каждого стойко-места свой номер, но это обычно отражается не в спецификации, а в ТУ (возможно, это связано с тем, что индивидуальность элемента не влияет на взаиморасчеты, только количество). Может быть, это не важно. + +При изменении строки не может меняться номенклатура. Может меняться количество, параметры (компоненты) композитной услуги, цена (или частные цены компонентов). Чтобы не путаться: дата начала/окончания меняться не может, это не обычный прикладной атрибут, а "драйвер" версионности. Иначе говоря, при изменении строки меняются только числовые значения (можно, наверно, менять примечания и пользовательские названия – они на учет не влияют) +Модификация строки нетривиальна по сравнению с созданием и удалением. Когда мы меняем строку, мы создаем новую версию, завершая действие прежней версии некоторым числом и создавая новую версию (непременно) более поздним числом (чаще всего следующим днем, пропуск мы, скорее всего, не захотим поддерживать: это может несколько усложнить формирование счетов... но паузу можно оформить периодом с нулевым количеством). +Таким образом, спецификация содержит версии строк, которые на любую дату составляют актуальную картину, причем на любую дату актуально не более одной версии каждой строки. За расчетный период могут быть актуальными несколько вариантов строки, логических препятствий для этого нет (может быть, этого придется избегать, чтобы исключить противоречия при формировании счетов). Строки не удаляются, а закрываются некоторой датой. + +Редактирование (включая возможность двигать даты начала/окончания) в некоторый момент замораживается, и строку нельзя уже поменять задним числом (условия уточнить). Может быть, необходим будет механизм компенсирующих проводок для корректировки задним числом. + +Таким образом, мы семантически объединяем даты начала/окончания оказания услуги и даты актуальности версий строк (чтобы не усложнять, и они кажутся очень близкими по смыслу). +Возобновления оказания услуги, наверное, предусматривать не надо: достаточно создать новую строку спецификации с теми же реквизитами и новым уникальным ключом строки - тогда можно рассчитывать на непрерывность цепочек версий (это ограничение выглядит успокаивающим, но непонятно, так ли оно полезно или необходимо). ВременнАя монотонность цепочек версий, напротив, кажется совершенно обязательной. +Номера версий строк монотонны (реализация может позволить наличие пропусков – оно логически ничему не противоречит) + +Теперь что такое версия спецификации и откуда берется номер версии спецификации. Предлагается считать версией спецификации снапшот версий строк, последовательность таких снапшотов соответствует истории спецификации. +Каждая версия спецификации вносит изменения: строка добавилась, строка удалилась, строка изменилась. Строки, которые не менялись, просто остаются в кумулятивном представлении, и отсутствуют в дифференциальном представлении. Измененная строка в кумулятивном представлении выглядит как «стало вот так с такой даты», а в дифференциальном «изменилось на столько с такой даты». +Если нам нужно 2 раза поменять некоторую строку (скажем, с 15 и 20 числа месяца) – нам придется выпустить 2 версии спецификации: формат не предусматривает замножение строк. Вероятно, 2 версии спецификации, в свою очередь, потребуют 2 дополнительных соглашений (кажется, в структуре доп соглашения, даже если предусмотрено несколько спецификаций, то это не версии одной спецификации). Впрочем, не припомню практической необходимости в таких изысках. + +Может быть, тут не хватает вопросов, на которые должна отвечать модель, но мне она пока кажется информационно полной и не сильно противоречивой. diff --git a/export.cfm b/export.cfm new file mode 100644 index 0000000..edbca7a --- /dev/null +++ b/export.cfm @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #i18("Экспорт","Export")# + + + + + + + + + + + +
+ ---> +
+ С фильтром по услугам + +
+ +
+
Коды услуг
+
+ + select + abstract_service_id, abstract_service, code + from abstract_service a + where 1=1 + order by a.code + + + + (множественное выделение) +
+
+ +
+
С
+
+ + + по дате присвоения статуса "Проект" или "Активна" +
+
+ +
+
По
+
+ + + по дате присвоения статуса "Проект" или "Активна" +
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+
+ +
+
+
+
+ +
+ Без фильтра + + + SC_service_param_price
+ SC_Rcode
+ + +
+ +
+ \ No newline at end of file diff --git a/export1.cfm b/export1.cfm new file mode 100644 index 0000000..9c89550 --- /dev/null +++ b/export1.cfm @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + #i18("Экспорт","Export")# + + + + + + + + + + + + + + \ No newline at end of file diff --git a/img/Arrow-Left-icon.png b/img/Arrow-Left-icon.png new file mode 100644 index 0000000..d7821a4 Binary files /dev/null and b/img/Arrow-Left-icon.png differ diff --git a/img/Arrow-left-icon (1).png b/img/Arrow-left-icon (1).png new file mode 100644 index 0000000..fcd2dd5 Binary files /dev/null and b/img/Arrow-left-icon (1).png differ diff --git a/img/DataLime.svg b/img/DataLime.svg new file mode 100644 index 0000000..8686414 --- /dev/null +++ b/img/DataLime.svg @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/img/Knob-Left-icon.png b/img/Knob-Left-icon.png new file mode 100644 index 0000000..5b6129f Binary files /dev/null and b/img/Knob-Left-icon.png differ diff --git a/img/a-piece.png b/img/a-piece.png new file mode 100644 index 0000000..029bd20 Binary files /dev/null and b/img/a-piece.png differ diff --git a/img/add.gif b/img/add.gif new file mode 100644 index 0000000..d8c5d3f Binary files /dev/null and b/img/add.gif differ diff --git a/img/alarm-arrow-left-icon.png b/img/alarm-arrow-left-icon.png new file mode 100644 index 0000000..61a0d04 Binary files /dev/null and b/img/alarm-arrow-left-icon.png differ diff --git a/img/alarm-arrow-up-icon.png b/img/alarm-arrow-up-icon.png new file mode 100644 index 0000000..76702f1 Binary files /dev/null and b/img/alarm-arrow-up-icon.png differ diff --git a/img/arr_dn.png b/img/arr_dn.png new file mode 100644 index 0000000..e7a4ca5 Binary files /dev/null and b/img/arr_dn.png differ diff --git a/img/arr_dn1.png b/img/arr_dn1.png new file mode 100644 index 0000000..75389bb Binary files /dev/null and b/img/arr_dn1.png differ diff --git a/img/arr_dn2.png b/img/arr_dn2.png new file mode 100644 index 0000000..2cf29e7 Binary files /dev/null and b/img/arr_dn2.png differ diff --git a/img/arr_up.png b/img/arr_up.png new file mode 100644 index 0000000..44d92f2 Binary files /dev/null and b/img/arr_up.png differ diff --git a/img/arr_up1.png b/img/arr_up1.png new file mode 100644 index 0000000..cfa15b8 Binary files /dev/null and b/img/arr_up1.png differ diff --git a/img/arr_up2.png b/img/arr_up2.png new file mode 100644 index 0000000..56989ed Binary files /dev/null and b/img/arr_up2.png differ diff --git a/img/arrow-left-icon (2).png b/img/arrow-left-icon (2).png new file mode 100644 index 0000000..2442d24 Binary files /dev/null and b/img/arrow-left-icon (2).png differ diff --git a/img/asvc.jpg b/img/asvc.jpg new file mode 100644 index 0000000..a3902d1 Binary files /dev/null and b/img/asvc.jpg differ diff --git a/img/complex.png b/img/complex.png new file mode 100644 index 0000000..0a256cd Binary files /dev/null and b/img/complex.png differ diff --git a/img/component.png b/img/component.png new file mode 100644 index 0000000..49b6926 Binary files /dev/null and b/img/component.png differ diff --git a/img/component.svg b/img/component.svg new file mode 100644 index 0000000..d8bfe46 --- /dev/null +++ b/img/component.svg @@ -0,0 +1,16 @@ + + + + + + + + diff --git a/img/deer.bk.png b/img/deer.bk.png new file mode 100644 index 0000000..85ddfae Binary files /dev/null and b/img/deer.bk.png differ diff --git a/img/deer.png b/img/deer.png new file mode 100644 index 0000000..5605a88 Binary files /dev/null and b/img/deer.png differ diff --git a/img/del.gif b/img/del.gif new file mode 100644 index 0000000..543da40 Binary files /dev/null and b/img/del.gif differ diff --git a/img/del16.png b/img/del16.png new file mode 100644 index 0000000..05dbaf8 Binary files /dev/null and b/img/del16.png differ diff --git a/img/del2.png b/img/del2.png new file mode 100644 index 0000000..cf9a957 Binary files /dev/null and b/img/del2.png differ diff --git a/img/dit.png b/img/dit.png new file mode 100644 index 0000000..807090d Binary files /dev/null and b/img/dit.png differ diff --git a/img/dit_m.png b/img/dit_m.png new file mode 100644 index 0000000..8efd316 Binary files /dev/null and b/img/dit_m.png differ diff --git a/img/dit_m1.png b/img/dit_m1.png new file mode 100644 index 0000000..1038c94 Binary files /dev/null and b/img/dit_m1.png differ diff --git a/img/download.png b/img/download.png new file mode 100644 index 0000000..cafb566 Binary files /dev/null and b/img/download.png differ diff --git a/img/edit.gif b/img/edit.gif new file mode 100644 index 0000000..8c0d109 Binary files /dev/null and b/img/edit.gif differ diff --git a/img/edit.gif.bk b/img/edit.gif.bk new file mode 100644 index 0000000..d87da1a Binary files /dev/null and b/img/edit.gif.bk differ diff --git a/img/json.svg b/img/json.svg new file mode 100644 index 0000000..a4ade48 --- /dev/null +++ b/img/json.svg @@ -0,0 +1,16 @@ + + + + + + diff --git a/img/logo.png b/img/logo.png new file mode 100644 index 0000000..687e1a9 Binary files /dev/null and b/img/logo.png differ diff --git a/img/logo0.png b/img/logo0.png new file mode 100644 index 0000000..ecc0019 Binary files /dev/null and b/img/logo0.png differ diff --git a/img/mimetype/document.png b/img/mimetype/document.png new file mode 100644 index 0000000..cee58b4 Binary files /dev/null and b/img/mimetype/document.png differ diff --git a/img/mimetype/excel.png b/img/mimetype/excel.png new file mode 100644 index 0000000..3cf3f34 Binary files /dev/null and b/img/mimetype/excel.png differ diff --git a/img/mimetype/ficon_pptx.gif b/img/mimetype/ficon_pptx.gif new file mode 100644 index 0000000..4d19e2a Binary files /dev/null and b/img/mimetype/ficon_pptx.gif differ diff --git a/img/mimetype/html.png b/img/mimetype/html.png new file mode 100644 index 0000000..00f4818 Binary files /dev/null and b/img/mimetype/html.png differ diff --git a/img/mimetype/image.png b/img/mimetype/image.png new file mode 100644 index 0000000..7b594f2 Binary files /dev/null and b/img/mimetype/image.png differ diff --git a/img/mimetype/image_.png b/img/mimetype/image_.png new file mode 100644 index 0000000..94fe85e Binary files /dev/null and b/img/mimetype/image_.png differ diff --git a/img/mimetype/pdf.png b/img/mimetype/pdf.png new file mode 100644 index 0000000..c68ab66 Binary files /dev/null and b/img/mimetype/pdf.png differ diff --git a/img/mimetype/powerpoint.png b/img/mimetype/powerpoint.png new file mode 100644 index 0000000..134a007 Binary files /dev/null and b/img/mimetype/powerpoint.png differ diff --git a/img/mimetype/text.png b/img/mimetype/text.png new file mode 100644 index 0000000..746afd9 Binary files /dev/null and b/img/mimetype/text.png differ diff --git a/img/mimetype/word.png b/img/mimetype/word.png new file mode 100644 index 0000000..c28b829 Binary files /dev/null and b/img/mimetype/word.png differ diff --git a/img/minus.gif b/img/minus.gif new file mode 100644 index 0000000..f4b28bd Binary files /dev/null and b/img/minus.gif differ diff --git a/img/new.gif b/img/new.gif new file mode 100644 index 0000000..754b627 Binary files /dev/null and b/img/new.gif differ diff --git a/img/ok.png b/img/ok.png new file mode 100644 index 0000000..a9925a0 Binary files /dev/null and b/img/ok.png differ diff --git a/img/paperclip.gif b/img/paperclip.gif new file mode 100644 index 0000000..2ab56be Binary files /dev/null and b/img/paperclip.gif differ diff --git a/img/piece.png b/img/piece.png new file mode 100644 index 0000000..8802d33 Binary files /dev/null and b/img/piece.png differ diff --git a/img/portlet_dot.gif b/img/portlet_dot.gif new file mode 100644 index 0000000..7e2f4cb Binary files /dev/null and b/img/portlet_dot.gif differ diff --git a/img/redmult.png b/img/redmult.png new file mode 100644 index 0000000..877be7d Binary files /dev/null and b/img/redmult.png differ diff --git a/img/redmult16.png b/img/redmult16.png new file mode 100644 index 0000000..fe83b81 Binary files /dev/null and b/img/redmult16.png differ diff --git a/img/sarrow.bk.gif b/img/sarrow.bk.gif new file mode 100644 index 0000000..bafbb1d Binary files /dev/null and b/img/sarrow.bk.gif differ diff --git a/img/sarrow.gif b/img/sarrow.gif new file mode 100644 index 0000000..bafbb1d Binary files /dev/null and b/img/sarrow.gif differ diff --git a/img/save.gif b/img/save.gif new file mode 100644 index 0000000..d70866b Binary files /dev/null and b/img/save.gif differ diff --git a/img/search.gif b/img/search.gif new file mode 100644 index 0000000..42aa6e0 Binary files /dev/null and b/img/search.gif differ diff --git a/img/search_icon.png b/img/search_icon.png new file mode 100644 index 0000000..2d1efbd Binary files /dev/null and b/img/search_icon.png differ diff --git a/img/simple.png b/img/simple.png new file mode 100644 index 0000000..3965009 Binary files /dev/null and b/img/simple.png differ diff --git a/img/svc.jpg b/img/svc.jpg new file mode 100644 index 0000000..db5ec30 Binary files /dev/null and b/img/svc.jpg differ diff --git a/img/up.gif b/img/up.gif new file mode 100644 index 0000000..2dbd4e3 Binary files /dev/null and b/img/up.gif differ diff --git a/img/view.gif b/img/view.gif new file mode 100644 index 0000000..e3ddd95 Binary files /dev/null and b/img/view.gif differ diff --git a/img/xls.gif b/img/xls.gif new file mode 100644 index 0000000..d35e1e4 Binary files /dev/null and b/img/xls.gif differ diff --git a/inc/functions.cfm b/inc/functions.cfm new file mode 100644 index 0000000..f751234 --- /dev/null +++ b/inc/functions.cfm @@ -0,0 +1,174 @@ + +/* Все глобальные функции экспортированы в request scope */ +function plain2htm(s) { + return replace(replace(s, chr(13),'',"ALL"),chr(10),'
', "ALL"); +} +request.plain2htm = plain2htm; + +function htm2plain(s) { + return replaceNoCase(s, '
', '#chr(13)##chr(10)#', "ALL"); +} +request.htm2plain = htm2plain; + +function cleanHtm(s) { + return replaceList(s, '<,>,"', '<,>,"'); +} +request.cleanHtm = cleanHtm; + +function clean4CDATA(s) { + LF = chr(10); + return replaceNoCase(replaceList(s, '[,]', '&91;,&93;'),"
",LF,"ALL"); +} +request.clean4CDATA = clean4CDATA; + +function numFmt(num, decimalPlaces = 0){ + var sFormat = ","; + if (decimalPlaces GT 0) {sFormat = sFormat & "." & repeatString("0", decimalPlaces);} + return replace(NumberFormat(num, sFormat), ",", " ", "ALL"); +} +request.numFmt = numFmt; + +function nFmt(num, decimalPlaces = 2){ + if (num EQ 0) return ""; + return numFmt(num, decimalPlaces); +} +request.nFmt = nFmt; + +function dateFmt(date, sFormat = 'DD.MM.YYYY'){ + return dateFormat(date, sFormat); +} +request.dateFmt = dateFmt; + +function dateTimeFmt(date, sDateFormat = 'DD.MM.YYYY', sTimeFormat='HH:MM'){ + return dateFormat(date, sDateFormat) & ' ' & timeFormat(date, sTimeFormat); +} +request.dateTimeFmt = dateTimeFmt; + +function timeFmt(date, sFormat = 'HH:MM'){ + return timeFormat(date, sFormat); +} +request.timeFmt = timeFmt; + +function usrAuthenticated() { + return request.usr_id GT 0 AND NOT (request.usr_id EQ request.ANONYMOUS_USR_ID); +} +request.usrAuthenticated = usrAuthenticated; + +function filterOn(filter) { + return (isStruct(filter) AND NOT structIsEmpty(filter)); +} +request.filterOn = filterOn; + +function stripWhiteSpace(sNumber) { + return reReplace(sNumber, "[[:space:]]", "", "ALL"); +} +request.stripWhiteSpace = stripWhiteSpace; +/* +// never used +function cleanNumber(sNumber) { + var s = reReplace(sNumber, "[[:space:]]", "", "ALL"); + if ( find(",", s) ) { //watch argument order!!! + // assume Russian format with decimal comma and spaces for thousand separator + return replace(s, ",", "."); + } else { + // assume English format with decimal point and commas for thousand separator + return replace(s, ",", "", "ALL"); + } +} +request.cleanNumber = cleanNumber; +*/ + +/*https://cflib.org/udf/queryColumnToArray*/ +/** + * Takes a selected column of data from a query and converts it into an array. + * + * @param query The query to scan. (Required) + * @param column The name of the column to return data from. (Required) + * @return Returns an array. + * @author Peter J. Farrell (pjf@maestropublishing.com) + * @version 1, July 22, 2005 + */ +function queryColumnToArray(qry, column) { + var arr = arrayNew(1); + var ii = ""; + var loop_len = arguments.qry.recordcount; + for (ii=1; ii lte loop_len; ii=ii+1) { + arrayAppend(arr, arguments.qry[arguments.column][ii]); + } + return arr; +} +request.queryColumnToArray = queryColumnToArray; + +/* ************************************* */ + +function loginPasswordPolicyCheck(usr_id, login, passwd, passwd2) { + msg = ""; + // для старого логина длина не проверяется, все равно ничего не поделаешь + if (NOT(usr_id GT 0) AND len(login) LE 3) { + msg="Слишком короткий логин (минимальная длина логина 3 символа)"; + } else { + if (passwd NEQ passwd2) { + msg="Пароль и подтверждение не совпадают"; + } else { + if (len(passwd) LT "8") msg="Слишком короткий пароль (минимальная длина пароля 8 символов)"; + } + } + return msg; +} +request.loginPasswordPolicyCheck = loginPasswordPolicyCheck; + +function i18(label,label_en=label) { + //примитивная 2-язычная версия + if (request.language EQ 'en') { + return label_en; + } else { + return label; + }; +} +request.i18 = i18; + +function passwordHashCreate(password) { + return GenerateArgon2Hash('#ARGUMENTS.password#', 'argon2id', 1, 16000, 2); +} +request.passwordHashCreate = passwordHashCreate; + +function passwordHashCheck(password, passwordHash) { + /*dirty hack for Lucee 6*/ + try { + return evaluate("Argon2CheckHash('#ARGUMENTS.password#', ARGUMENTS.passwordHash, 'argon2id')"); + } catch(e) {} // for lucee 5 compatibility + return evaluate("Argon2CheckHash('#ARGUMENTS.password#', ARGUMENTS.passwordHash)"); //lucee 6 +} +request.passwordHashCheck = passwordHashCheck; + +function skuCode(area_code="", abstract_service_code="") { + var s="#arguments[1]#.#arguments[2]#"; + if (arrayLen(arguments) GE 3) { + if (len(arguments[3]) GT 0) { + s="#s#.#arguments[3]#"; + } else { + s="#s#.0"; + }; + }; + if (arrayLen(arguments) GE 4) { + if (len(arguments[4]) GT 0) { + s="#s#.#arguments[4]#" + } + }; + if (arrayLen(arguments) GE 5) { + var pricingModelSuffix=arguments[5]; + s="#s#-#pricingModelSuffix#"; + } + return s; +} +request.skuCode = skuCode; + +function roundSafe(a, precision) { + return (isNumeric(a) AND isNumeric(precision)) ? round(a,precision) : a; +} +request.roundSafe = roundSafe; + +
+ + + diff --git a/inc/menu.cfm b/inc/menu.cfm new file mode 100644 index 0000000..66f1283 --- /dev/null +++ b/inc/menu.cfm @@ -0,0 +1,51 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/index.cfm b/index.cfm new file mode 100644 index 0000000..f6279e9 --- /dev/null +++ b/index.cfm @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/js/jquery.min.js b/js/jquery.min.js new file mode 100644 index 0000000..ee02337 --- /dev/null +++ b/js/jquery.min.js @@ -0,0 +1,4 @@ +/*! jQuery v1.7.1 jquery.com | jquery.org/license */ +(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!ck[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cl||(cl=c.createElement("iframe"),cl.frameBorder=cl.width=cl.height=0),b.appendChild(cl);if(!cm||!cl.createElement)cm=(cl.contentWindow||cl.contentDocument).document,cm.write((c.compatMode==="CSS1Compat"?"":"")+""),cm.close();d=cm.createElement(a),cm.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cl)}ck[a]=e}return ck[a]}function cu(a,b){var c={};f.each(cq.concat.apply([],cq.slice(0,b)),function(){c[this]=a});return c}function ct(){cr=b}function cs(){setTimeout(ct,0);return cr=f.now()}function cj(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ci(){try{return new a.XMLHttpRequest}catch(b){}}function cc(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){if(c!=="border")for(;g=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c
a",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:q.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendChild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o="
"+""+"
",a=c.createElement("div"),a.style.cssText=m+"width:0;height:0;position:static;top:0;margin-top:"+j+"px",r.insertBefore(a,r.firstChild),q=c.createElement("div"),a.appendChild(q),q.innerHTML="
t
",l=q.getElementsByTagName("td"),p=l[0].offsetHeight===0,l[0].style.display="",l[1].style.display="none",b.reliableHiddenOffsets=p&&l[0].offsetHeight===0,q.innerHTML="",q.style.width=q.style.paddingLeft="1px",f.boxModel=b.boxModel=q.offsetWidth===2,typeof q.style.zoom!="undefined"&&(q.style.display="inline",q.style.zoom=1,b.inlineBlockNeedsLayout=q.offsetWidth===2,q.style.display="",q.innerHTML="
",b.shrinkWrapBlocks=q.offsetWidth!==2),q.style.cssText=k+m,q.innerHTML=o,d=q.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,i={doesNotAddBorder:e.offsetTop!==5,doesAddBorderForTableAndCells:h.offsetTop===5},e.style.position="fixed",e.style.top="20px",i.fixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",i.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,i.doesNotIncludeMarginInBodyOffset=r.offsetTop!==j,r.removeChild(a),q=a=null,f.extend(b,i))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;h=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/\bhover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")}; +f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;le&&i.push({elem:this,matches:d.slice(e)});for(j=0;j0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h0)for(h=g;h=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div
","
"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function() +{for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||!bc.test("<"+a.nodeName)?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");b===c?bh.appendChild(o):U(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return br.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bq,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bq.test(g)?g.replace(bq,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,b){var c,d,e;b=b.replace(bs,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b)));return c}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bt.test(f)&&bu.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bD=/%20/g,bE=/\[\]$/,bF=/\r?\n/g,bG=/#.*$/,bH=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bI=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bJ=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bK=/^(?:GET|HEAD)$/,bL=/^\/\//,bM=/\?/,bN=/)<[^<]*)*<\/script>/gi,bO=/^(?:select|textarea)/i,bP=/\s+/,bQ=/([?&])_=[^&]*/,bR=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bS=f.fn.load,bT={},bU={},bV,bW,bX=["*/"]+["*"];try{bV=e.href}catch(bY){bV=c.createElement("a"),bV.href="",bV=bV.href}bW=bR.exec(bV.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bS)return bS.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
").append(c.replace(bN,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bO.test(this.nodeName)||bI.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bF,"\r\n")}}):{name:b.name,value:c.replace(bF,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b_(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b_(a,b);return a},ajaxSettings:{url:bV,isLocal:bJ.test(bW[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bX},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bZ(bT),ajaxTransport:bZ(bU),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cb(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cc(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bH.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bG,"").replace(bL,bW[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bP),d.crossDomain==null&&(r=bR.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bW[1]&&r[2]==bW[2]&&(r[3]||(r[1]==="http:"?80:443))==(bW[3]||(bW[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bT,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bK.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bM.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bQ,"$1_="+x);d.url=y+(y===d.url?(bM.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bX+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bU,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)ca(g,a[g],c,e);return d.join("&").replace(bD,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cd=f.now(),ce=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cd++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ce.test(b.url)||e&&ce.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ce,l),b.url===j&&(e&&(k=k.replace(ce,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cf=a.ActiveXObject?function(){for(var a in ch)ch[a](0,1)}:!1,cg=0,ch;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ci()||cj()}:ci,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cf&&delete ch[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cg,cf&&(ch||(ch={},f(a).unload(cf)),ch[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ck={},cl,cm,cn=/^(?:toggle|show|hide)$/,co=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cp,cq=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cr;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window); \ No newline at end of file diff --git a/js/jquery.searchabledropdown.js b/js/jquery.searchabledropdown.js new file mode 100644 index 0000000..0ffa594 --- /dev/null +++ b/js/jquery.searchabledropdown.js @@ -0,0 +1,3 @@ +/* JQuery Searchable DropDown Plugin | Copyright (c) 2012 xhaggi */ +/*modidfed 14.11.2016|18.01.2018 by msyu - display:inline-block, padding-top: 0 for chrome; BUG: maxListSize IS IGNORED, use instead maxMultiMatch; chrome highlighted position correction;*/ +(function($){var B=register("searchable");B.defaults={maxListSize:100,maxMultiMatch:50,exactMatch:false,wildcards:true,ignoreCase:true,warnMultiMatch:"top {0} matches ...",warnNoMatch:"no matches ...",latency:200,zIndex:"auto"};B.execute=function(g,h){var j=null;var k=null;var l=null;if($.browser.msie&&parseInt(jQuery.browser.version)<7)return this;if(this.nodeName!="SELECT"||this.size>1)return this;var m=$(this);var n={index:-1,options:null};var o="lang";var p=false;$.browser.chrome=/chrome/.test(navigator.userAgent.toLowerCase());if($.browser.chrome)$.browser.safari=false;if($.meta){g=$.extend({},options,m.data())}var q=$("
");var r=$("
");var t=$("");var u=$("
\ No newline at end of file diff --git a/layout/grid_summary.cfm b/layout/grid_summary.cfm new file mode 100644 index 0000000..cc56219 --- /dev/null +++ b/layout/grid_summary.cfm @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + +
 
+
+ + + Выбрано #ATTRIBUTES.recordCount# + + из #ATTRIBUTES.totalCount# + + + + + + + + + + +
+
+ #paginator.links# +
+
+
+
+ + + + +
+ #paginator.links# +
+
+
+
+ + diff --git a/layout/json.cfm b/layout/json.cfm new file mode 100644 index 0000000..47ebf3b --- /dev/null +++ b/layout/json.cfm @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + ---> + + + + + + + + + + + + + [{"#listGetAt(#columnsOut#,i)#":"#qry[listGetAt(#columnsIn#,i)]#",},] + ---> + + + + + + + + + + + + + + + //copy fields to structure, renaming fields, this preserves data type + + + + + + + + + + + + + + + + + + + +#query2json(ATTRIBUTES.qRead,ATTRIBUTES.convertSnakeToCamel)# + \ No newline at end of file diff --git a/layout/language_switch.cfm b/layout/language_switch.cfm new file mode 100644 index 0000000..6533051 --- /dev/null +++ b/layout/language_switch.cfm @@ -0,0 +1,9 @@ + + +   +   +   + style="font-weight:bold;">Ru + style="font-weight:bold;">En + + \ No newline at end of file diff --git a/layout/page.cfm b/layout/page.cfm new file mode 100644 index 0000000..3812f8c --- /dev/null +++ b/layout/page.cfm @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +---> + + + + + + + + + + + + +<cfoutput>#pageTitle#</cfoutput> + + + + + + + + ---> + + + + + + + + + + +
+
+ + +
+ + + +
enctype="#ATTRIBUTES.pageInfo.formEncType#"> +
+
+ +
+
+ + + + +
+ #title# +
+
+ #controls# +
+
+
+ +
+ + + + #ATTRIBUTES.pageInfo.status.errorMessage# + + + + + + + + + + +
+ + +
+ + + +
+ + + + + +
diff --git a/layout/xls.cfm b/layout/xls.cfm new file mode 100644 index 0000000..5d8a964 --- /dev/null +++ b/layout/xls.cfm @@ -0,0 +1,55 @@ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
#title##fieldArray[i]#
#dateFormat(data,'YYYY-MM-DD')# #timeFormat(data,'HH:mm')##Replace(data, '.', ',')##data##data#
+ + + + + + + + \ No newline at end of file diff --git a/layout/xlshtm.cfm b/layout/xlshtm.cfm new file mode 100644 index 0000000..b74ad64 --- /dev/null +++ b/layout/xlshtm.cfm @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#structFind(ATTRIBUTES.titleMap,field).title#
+ #ATTRIBUTES.qRead[field]# +
+ + +
+
+ + + + \ No newline at end of file diff --git a/layout/xml.cfm b/layout/xml.cfm new file mode 100644 index 0000000..65e7e41 --- /dev/null +++ b/layout/xml.cfm @@ -0,0 +1,239 @@ + + + + + + + + + + + + + + + + + + + + + + + xls-generator + + + + + + + + + + + + + + + ss:ExpandedColumnCount="#ListLen(qRead.ColumnList)#" + + ss:ExpandedRowCount="#(qRead.RecordCount + 1)#" + x:FullColumns="1" + x:FullRows="1"> + + + + + + + + + + + + + + + + + + select coalesce(max(length(#field#)),0) as maxlen from qRead + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #columns[i].title# + + + + + + + ss:StyleID="DateTime">#dateFormat(qRead[field],"YYYY-MM-DD")#T#timeFormat(qRead[field],"HH:mm:ss.l")##qRead[field]#
+ +
+ +
+ +
+ + + + + + + + \ No newline at end of file diff --git a/lib/ac.cfm b/lib/ac.cfm new file mode 100644 index 0000000..823d1cb --- /dev/null +++ b/lib/ac.cfm @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select coalesce(max(permission),0) as permission + from usr_role ur + join acl on acl.role_id=ur.role_id + where ur.usr_id= + and acl.obj in () + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/contenttype_icon.cfm b/lib/contenttype_icon.cfm new file mode 100644 index 0000000..1f8f3b1 --- /dev/null +++ b/lib/contenttype_icon.cfm @@ -0,0 +1,12 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/lib/controls/checkbox.cfm b/lib/controls/checkbox.cfm new file mode 100644 index 0000000..38ec2e2 --- /dev/null +++ b/lib/controls/checkbox.cfm @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + id=#ATTRIBUTES.id# value="#ATTRIBUTES.value#" checked="checked" disabled="disabled" #attr#="#structFind(ATTRIBUTES,attr)#"/> \ No newline at end of file diff --git a/lib/controls/column.cfm b/lib/controls/column.cfm new file mode 100644 index 0000000..47cf2d8 --- /dev/null +++ b/lib/controls/column.cfm @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/controls/column_head.cfm b/lib/controls/column_head.cfm new file mode 100644 index 0000000..f189b06 --- /dev/null +++ b/lib/controls/column_head.cfm @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +#ATTRIBUTES.title# + \ No newline at end of file diff --git a/lib/controls/combo.cfm b/lib/controls/combo.cfm new file mode 100644 index 0000000..13e2832 --- /dev/null +++ b/lib/controls/combo.cfm @@ -0,0 +1,178 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + if (isArray(sel)) { + for(i=1; i <= ArrayLen(sel); i++){ + if (sel[i]==key) {return true;} + } + return false; + } else { //считаем, что из сложных типов тут бывает только массив + if (!isSimpleValue(sel)) {return false;} + /*return (sel == key);*/ + return listFind(sel,key); + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #preserveSingleQuotes(ATTRIBUTES.queryString)# + + + + + + + + + + + + + + + + + + + + + + select * from qSel where #ATTRIBUTES.key# in (#selectedList#)1=0 + + + +
#attr#="#structFind(ATTRIBUTES,attr)#"> + +
#Evaluate(ATTRIBUTES.display)#
+
+ + +     + +     +
+
+
+ + + + + +
+ +
+ + + diff --git a/lib/controls/date.cfm b/lib/controls/date.cfm new file mode 100644 index 0000000..b6a3f6f --- /dev/null +++ b/lib/controls/date.cfm @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + id=#ATTRIBUTES.id#
value="#dateFormat(value, ATTRIBUTES.format)#" size="#ATTRIBUTES.size#" disabled="disabled" #attr#="#structFind(ATTRIBUTES,attr)#"/> \ No newline at end of file diff --git a/lib/controls/datetime.cfm b/lib/controls/datetime.cfm new file mode 100644 index 0000000..5b1f4fa --- /dev/null +++ b/lib/controls/datetime.cfm @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + id=#ATTRIBUTES.id# value="#value#" size="#ATTRIBUTES.size#" disabled="disabled" #attr#="#structFind(ATTRIBUTES,attr)#"/> \ No newline at end of file diff --git a/lib/controls/detail_buttons.cfm b/lib/controls/detail_buttons.cfm new file mode 100644 index 0000000..1484050 --- /dev/null +++ b/lib/controls/detail_buttons.cfm @@ -0,0 +1,18 @@ + + \ No newline at end of file diff --git a/lib/controls/grid_head.cfm b/lib/controls/grid_head.cfm new file mode 100644 index 0000000..55090e8 --- /dev/null +++ b/lib/controls/grid_head.cfm @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/controls/link_add.cfm b/lib/controls/link_add.cfm new file mode 100644 index 0000000..b6fbf5b --- /dev/null +++ b/lib/controls/link_add.cfm @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/lib/controls/link_del.cfm b/lib/controls/link_del.cfm new file mode 100644 index 0000000..bd911e9 --- /dev/null +++ b/lib/controls/link_del.cfm @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/lib/controls/link_edit.cfm b/lib/controls/link_edit.cfm new file mode 100644 index 0000000..eccea83 --- /dev/null +++ b/lib/controls/link_edit.cfm @@ -0,0 +1,9 @@ + + + + + + + + +title="#ATTRIBUTES.title_edit#" class="edit"title="#ATTRIBUTES.title_view#" class="view"> \ No newline at end of file diff --git a/lib/controls/link_view.cfm b/lib/controls/link_view.cfm new file mode 100644 index 0000000..4cf9e70 --- /dev/null +++ b/lib/controls/link_view.cfm @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/lib/controls/link_view_edit.cfm b/lib/controls/link_view_edit.cfm new file mode 100644 index 0000000..e676a5a --- /dev/null +++ b/lib/controls/link_view_edit.cfm @@ -0,0 +1,9 @@ + + + + + + + + +title="#ATTRIBUTES.title_edit#" class="edit"title="#ATTRIBUTES.title_view#" class="view"> \ No newline at end of file diff --git a/lib/controls/menu_item.cfm b/lib/controls/menu_item.cfm new file mode 100644 index 0000000..6c4a45d --- /dev/null +++ b/lib/controls/menu_item.cfm @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + +
  • #ATTRIBUTES.label#
  • +
  • #ATTRIBUTES.label#
  • \ No newline at end of file diff --git a/lib/controls/nowbutton.cfm b/lib/controls/nowbutton.cfm new file mode 100644 index 0000000..a142ece --- /dev/null +++ b/lib/controls/nowbutton.cfm @@ -0,0 +1,6 @@ + + + + + + + + + + + + + + + + + + + + + + + #markup# + + + + \ No newline at end of file diff --git a/lib/data/del_condition.cfm b/lib/data/del_condition.cfm new file mode 100644 index 0000000..5cae40c --- /dev/null +++ b/lib/data/del_condition.cfm @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/data/dep_field.cfm b/lib/data/dep_field.cfm new file mode 100644 index 0000000..0d065da --- /dev/null +++ b/lib/data/dep_field.cfm @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/data/dep_param.cfm b/lib/data/dep_param.cfm new file mode 100644 index 0000000..7084ec2 --- /dev/null +++ b/lib/data/dep_param.cfm @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/lib/data/dependency.cfm b/lib/data/dependency.cfm new file mode 100644 index 0000000..19322dc --- /dev/null +++ b/lib/data/dependency.cfm @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select + + + , #field.expression# + + from + + #from.expression# + + where + + + AND + #condition.expression#= + + order by + + + , #order.expression# + + + + + + diff --git a/lib/data/dependency_condition.cfm b/lib/data/dependency_condition.cfm new file mode 100644 index 0000000..1b668ba --- /dev/null +++ b/lib/data/dependency_condition.cfm @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/lib/data/dependency_field.cfm b/lib/data/dependency_field.cfm new file mode 100644 index 0000000..4a3c282 --- /dev/null +++ b/lib/data/dependency_field.cfm @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/data/dependency_from.cfm b/lib/data/dependency_from.cfm new file mode 100644 index 0000000..83fbd4f --- /dev/null +++ b/lib/data/dependency_from.cfm @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/lib/data/dependency_order_by.cfm b/lib/data/dependency_order_by.cfm new file mode 100644 index 0000000..48b990d --- /dev/null +++ b/lib/data/dependency_order_by.cfm @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/lib/data/field.cfm b/lib/data/field.cfm new file mode 100644 index 0000000..8fa07da --- /dev/null +++ b/lib/data/field.cfm @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/data/field_set.cfm b/lib/data/field_set.cfm new file mode 100644 index 0000000..b990b40 --- /dev/null +++ b/lib/data/field_set.cfm @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/data/param.cfm b/lib/data/param.cfm new file mode 100644 index 0000000..2433014 --- /dev/null +++ b/lib/data/param.cfm @@ -0,0 +1,354 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/data/status.cfc b/lib/data/status.cfc new file mode 100644 index 0000000..6e956c5 --- /dev/null +++ b/lib/data/status.cfc @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/data/submit_collection.cfm b/lib/data/submit_collection.cfm new file mode 100644 index 0000000..bc1c10b --- /dev/null +++ b/lib/data/submit_collection.cfm @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/data/submit_param.cfm b/lib/data/submit_param.cfm new file mode 100644 index 0000000..799a3ec --- /dev/null +++ b/lib/data/submit_param.cfm @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/detail_page_info.cfc b/lib/detail_page_info.cfc new file mode 100644 index 0000000..1a0d1e8 --- /dev/null +++ b/lib/detail_page_info.cfc @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/dispatch_detail.cfm b/lib/dispatch_detail.cfm new file mode 100644 index 0000000..30bffcd --- /dev/null +++ b/lib/dispatch_detail.cfm @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/filter_build.cf_ b/lib/filter_build.cf_ new file mode 100644 index 0000000..146c197 --- /dev/null +++ b/lib/filter_build.cf_ @@ -0,0 +1,131 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #item# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/filter_build.cfm b/lib/filter_build.cfm new file mode 100644 index 0000000..ccd55fb --- /dev/null +++ b/lib/filter_build.cfm @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + AND #listGetAt(fltr.expression,i,"?")##fltr.field# = <> <= < >= > LIKE NOT LIKE LIKE NOT LIKE IN () = #fltr.field# + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/filter_page_info.cfc b/lib/filter_page_info.cfc new file mode 100644 index 0000000..ea82758 --- /dev/null +++ b/lib/filter_page_info.cfc @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/lib/filter_rebuild.cfm b/lib/filter_rebuild.cfm new file mode 100644 index 0000000..e69de29 diff --git a/lib/filter_settings.cfm b/lib/filter_settings.cfm new file mode 100644 index 0000000..4d6089d --- /dev/null +++ b/lib/filter_settings.cfm @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/filterparam.cfm b/lib/filterparam.cfm new file mode 100644 index 0000000..8fe4962 --- /dev/null +++ b/lib/filterparam.cfm @@ -0,0 +1,173 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + if (!IsSimpleValue(val)){ + if (isArray(val)) { + return (arrayLen(val) == 0); + } + return false; + } + return ((val==def) OR (val=="")); + + + + + + ", ",,,")/> + + diff --git a/lib/form_page_info.cfc b/lib/form_page_info.cfc new file mode 100644 index 0000000..5d0d6ac --- /dev/null +++ b/lib/form_page_info.cfc @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/generic_page_info.cfc b/lib/generic_page_info.cfc new file mode 100644 index 0000000..08c50d3 --- /dev/null +++ b/lib/generic_page_info.cfc @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/init_settings.cfm b/lib/init_settings.cfm new file mode 100644 index 0000000..f51c235 --- /dev/null +++ b/lib/init_settings.cfm @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/location.cfm b/lib/location.cfm new file mode 100644 index 0000000..06ceafe --- /dev/null +++ b/lib/location.cfm @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/lib/ls_catch.cfm b/lib/ls_catch.cfm new file mode 100644 index 0000000..918f958 --- /dev/null +++ b/lib/ls_catch.cfm @@ -0,0 +1,24 @@ + + + + + + + Ошибка при обращении к базе данных. Возможно, программа некорректно сформировала условия фильтра или сортировки. В качестве временной меры попробуйте сбросить условия фильтра и сортировки. Просьба сообщить об ошибке администратору.
    + #ATTRIBUTES.catch.message#
    + #ATTRIBUTES.catch.detail#
    +
    +
    + + + + + + + + + + + + +
    \ No newline at end of file diff --git a/lib/ls_page_info.cfc b/lib/ls_page_info.cfc new file mode 100644 index 0000000..32e352c --- /dev/null +++ b/lib/ls_page_info.cfc @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/lib/menu_item.cfm b/lib/menu_item.cfm new file mode 100644 index 0000000..632e78a --- /dev/null +++ b/lib/menu_item.cfm @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/mimetype_icon.cfm b/lib/mimetype_icon.cfm new file mode 100644 index 0000000..6128b1a --- /dev/null +++ b/lib/mimetype_icon.cfm @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/lib/order_build.cfm b/lib/order_build.cfm new file mode 100644 index 0000000..bda0f97 --- /dev/null +++ b/lib/order_build.cfm @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/prepare_detail.cfm b/lib/prepare_detail.cfm new file mode 100644 index 0000000..c98e9bc --- /dev/null +++ b/lib/prepare_detail.cfm @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/prepare_filter.cfm b/lib/prepare_filter.cfm new file mode 100644 index 0000000..07eb829 --- /dev/null +++ b/lib/prepare_filter.cfm @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/prepare_form.cfm b/lib/prepare_form.cfm new file mode 100644 index 0000000..baccc32 --- /dev/null +++ b/lib/prepare_form.cfm @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/prepare_ls.cfm b/lib/prepare_ls.cfm new file mode 100644 index 0000000..a621461 --- /dev/null +++ b/lib/prepare_ls.cfm @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/settings.cfm b/lib/settings.cfm new file mode 100644 index 0000000..c7e5784 --- /dev/null +++ b/lib/settings.cfm @@ -0,0 +1,216 @@ + + + + + + +Разрешение конфликта версий при обновлении софта +Конфликт версий: код требует параметр, отсутствующий в сохраненной версии. Например, одна версия фильтра сохранила свои настройки, +а другая, более новая, пытается прочесть несуществующий ключ. +Другой вариант - несуществующее поле (убранное в очередной версии) - этот конфликт проявится только при запросе к БД. +Варианты решения +- создание параметра с дефолтными значениями при запросе (во все запросы добавить значения по умолчанию). Недостаток - возможно создание помойки +- контроль номера версии. Выглядит сложным в сопровождении +*** Возможно, это была плохая идея - разрешить доступ по длинному ключу. Когда доставали и записывали целиком объект, было меньше возможностей для ошибок +---> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select settings from usr where usr_id='#request.usr_id#' + + + + + + Err: + #cfcatch.message# + + + + + + + + + + + + + + + + + + select count(*) as cnt from usr_serrings where usr_id= + + + + + + + insert int usr_settings (usr_id, settings) + values(, ) + + + + update usr_settings + set settings= + where usr_id= + + + + + + + diff --git a/lib/silent.cfm b/lib/silent.cfm new file mode 100644 index 0000000..7f2f6f2 --- /dev/null +++ b/lib/silent.cfm @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/lib/sortparam.cfm b/lib/sortparam.cfm new file mode 100644 index 0000000..1648d2b --- /dev/null +++ b/lib/sortparam.cfm @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/track.cfm b/lib/track.cfm new file mode 100644 index 0000000..169d97d --- /dev/null +++ b/lib/track.cfm @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/upload.cfm b/lib/upload.cfm new file mode 100644 index 0000000..7d9c22e --- /dev/null +++ b/lib/upload.cfm @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/login.cfm b/login.cfm new file mode 100644 index 0000000..e0c2ea4 --- /dev/null +++ b/login.cfm @@ -0,0 +1,166 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #request.APP_NAME# (Версия #request.APP_VERSION#) + + + + + + + + + + +
    +
    +
    + Вход в систему +
    + + +
    +
    + +
    +
    + +
    +
    Логин
    +
    + Без доменного префикса и суффикса +
    +
    + +
    +
    Пароль
    +
    + + Пароль в локальной базе данных (для редакторов) +
    +
    + +
    +
    Запомнить пароль
    +
    + checked/> + Только для локальной базы данных +
    +
    + +
    +
    Очистить настройки
    +
    checked/>
    +
    + +
    +
    +
    + + + +
    +
    +
    +
    +
    +
    + +
    #msg# 
    #alert#
    +











    + +
    +
    + + + + + + + + + + +
    + \ No newline at end of file diff --git a/logout.cfm b/logout.cfm new file mode 100644 index 0000000..937f8d6 --- /dev/null +++ b/logout.cfm @@ -0,0 +1,35 @@ + + +---> + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/measure.cfm b/measure.cfm new file mode 100644 index 0000000..ab628da --- /dev/null +++ b/measure.cfm @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + pageInfo=#pageInfo# + id="#d.measure_id#" + status=#pageInfo.status# + trackOut="tr" + idAttributesOut="id" +/> + + + select + a.login as creator, a.shortname as creator_shortname, m.login as updater, m.shortname as updater_shortname + from #pageInfo.entity# e + left outer join usr a on (e.creator_id=a.usr_id) + left outer join usr m on (e.updater_id=m.usr_id) + where e.#pageInfo.key#= + + + + + + + Единица измерения + + #d.measure# + [#d.measure_id#] + + + + + + +
    #status.errorMessage#
    +
    + + + + + + +
    + + +
    +
    Единица измерения
    +
    + +
    +
    + +
    +
    Сокращение
    +
    + +
    +
    + +
    +
    Сокращение английское
    +
    + +
    +
    + +
    +
    Описание
    +
    + +
    +
    + +
    +
    Создано
    +
    + #dateFormat(d.dt_created,'DD.MM.YYYY')# #timeFormat(d.dt_created,'HH:MM')# + #qDecoration.creator# (#qDecoration.creator_shortname#) +       + Изменено + #dateFormat(d.dt_updated,'DD.MM.YYYY')# #timeFormat(d.dt_updated,'HH:MM')# + #qDecoration.updater# (#qDecoration.updater_shortname#) +
    +
    + +
    + +
    + + + + \ No newline at end of file diff --git a/measure_json.cfm b/measure_json.cfm new file mode 100644 index 0000000..5ae9aaf --- /dev/null +++ b/measure_json.cfm @@ -0,0 +1,44 @@ + + + + + + + + + + select + + measure_id + measure + measure_short + + from measure + where 1=1 + order by measure_id + + + + + + + + + + + + + + + + + + + +#serializeJSON(temp.out)# \ No newline at end of file diff --git a/measure_ls.cfm b/measure_ls.cfm new file mode 100644 index 0000000..1be8748 --- /dev/null +++ b/measure_ls.cfm @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + select + + m.measure_id + m.measure + m.measure_short + m.measure_short_en + + from measure m + where 1=1 + order by + + + + + + + + + +select count(*) as cnt from measure where 1=1 + + + + + + + + + + + + Единицы измерения + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + #measure##measure_short##measure_short_en#
    + + #gridFooter# + +
    + \ No newline at end of file diff --git a/mod/abstract_service_param_class.cfm b/mod/abstract_service_param_class.cfm new file mode 100644 index 0000000..4371689 --- /dev/null +++ b/mod/abstract_service_param_class.cfm @@ -0,0 +1,106 @@ + + + + + + + + + + + + + + + + + + + + + + + + delete from abstract_service_param_class + where abstract_service_id= + AND param_class_id= + + + + + select + x.abstract_service_id + ,x.param_class_id + ,p.param_class + from abstract_service_param_class x + join param_class p on (x.param_class_id=p.param_class_id) + where x.abstract_service_id= + order by 2 + + + +Классы компонентов (#qRead.recordCount#): + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Компонент
    #param_class# + +
    + + + + +
    +
    +
    +
    + + + + + select c.param_class_id, c.param_class + from param_class c + order by c.param_class + + + + /> + + +
    + \ No newline at end of file diff --git a/mod/abstract_service_provider.cfm b/mod/abstract_service_provider.cfm new file mode 100644 index 0000000..f5ff90c --- /dev/null +++ b/mod/abstract_service_provider.cfm @@ -0,0 +1,106 @@ + + + + + + + + + + + + + + + + + + + + + + + + delete from abstract_service_provider + where abstract_service_id= + AND provider_id= + + + + + select + x.abstract_service_id + ,x.provider_id + ,p.provider + from abstract_service_provider x + join provider p on (x.provider_id=p.provider_id) + where x.abstract_service_id= + order by 2 + + + +Провайдеры услуги (#qRead.recordCount#): + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Провайдер
    #provider# + +
    + + + + +
    +
    +
    +
    + + + + + select c.provider_id, c.provider + from provider c + order by c.provider + + + + /> + + +
    + \ No newline at end of file diff --git a/mod/attach_support.cfm b/mod/attach_support.cfm new file mode 100644 index 0000000..2586751 --- /dev/null +++ b/mod/attach_support.cfm @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/mod/auth.cfm b/mod/auth.cfm new file mode 100644 index 0000000..21e403a --- /dev/null +++ b/mod/auth.cfm @@ -0,0 +1,100 @@ + + + + + + + + + + + + select usr_id, locked, + + password as pwdhash + from usr + where login= + + + + + + + + + + + > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mod/documents.cfm b/mod/documents.cfm new file mode 100644 index 0000000..c7a11e1 --- /dev/null +++ b/mod/documents.cfm @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + insert into #ATTRIBUTES.entity#_doc ( + #ATTRIBUTES.entity#_id, #ATTRIBUTES.entity#_doc, doc, contenttype, fname, + dt_created, creator_id, dt_updated, updater_id + ) values ( + , + , + , + , + , + , + , + , + + ) + + + + + + + + + + + + + + +
    + Документы: + + + select d.#ATTRIBUTES.entity#_doc_id as doc_id, d.#ATTRIBUTES.entity#_doc as doc_title, d.fname, d.contenttype, + d.dt_created, a.shortname as creator, d.dt_updated, m.shortname as modifier + from #ATTRIBUTES.entity#_doc d + left outer join usr a on (d.creator_id=a.usr_id) + left outer join usr m on (d.updater_id=m.usr_id) + where #ATTRIBUTES.entity#_id= + + + + + + + #doc_title##fname# + + + #doc_title##fname# + + +     + + + + +
    + + + Добавить: + + Название документа: + + +
    +
    +
    +
    +
    + + + documents: there is no such section "#ATTRIBUTES.section#" + +
    + \ No newline at end of file diff --git a/mod/param_class_param.cfm b/mod/param_class_param.cfm new file mode 100644 index 0000000..69a2161 --- /dev/null +++ b/mod/param_class_param.cfm @@ -0,0 +1,64 @@ + + + + + + + + + + + + select p.param_id, p.param, p.precision + from param p + where p.param_class_id= + order by 2 + + + + + +

    + #ATTRIBUTES.estatus.errorMessage# +

    +
    + + + + + + + + + + + + + + + + + + + +
    + + + + +
    + + + + + + + +
    Вариант компонентаТочность
    #param##precision#
    + + + + +
    + \ No newline at end of file diff --git a/mod/usr_role.cfm b/mod/usr_role.cfm new file mode 100644 index 0000000..4426b2d --- /dev/null +++ b/mod/usr_role.cfm @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + + + delete from usr_role + where usr_id= + AND role_id= + + + + + select + x.usr_id + ,x.role_id + ,p.role + from usr_role x + join role p on (x.role_id=p.role_id) + where x.usr_id= + order by 2 + + + +Роли пользователя (#qRead.recordCount#): + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Роль
    #role# + +
    + + + + +
    +
    +
    +
    + + + + + select c.role_id, c.role + from role c + order by c.role + + + + /> + + +
    + \ No newline at end of file diff --git a/modifier.cfm b/modifier.cfm new file mode 100644 index 0000000..478b4fa --- /dev/null +++ b/modifier.cfm @@ -0,0 +1,237 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + pageInfo=#pageInfo# + id="#d.modifier_id#" + status=#pageInfo.status# + trackOut="tr" + idAttributesOut="id" +/> + + + select + a.login as creator, a.shortname as creator_shortname, m.login as updater, m.shortname as updater_shortname + from #pageInfo.entity# e + left outer join usr a on (e.creator_id=a.usr_id) + left outer join usr m on (e.updater_id=m.usr_id) + where e.#pageInfo.key#= + + + + select + m.modifier_id, c.modifier_class + from modifier m + left outer join modifier_class c on (m.modifier_class_id=c.modifier_class_id) + where m.modifier_id= + + + + + + + Характеристика (модификатор) + + #qDecoration.modifier_class# + [#d.modifier_class_id#]: + #d.modifier# + [#d.modifier_id#] + + + + + + +
    #status.errorMessage#
    +
    + + + + + + +
    + + +
    +
    Класс характеристики
    +
    + + select modifier_class_id, modifier_class + from modifier_class + order by 2 + + + /> + + + + + + + + + + +
    +
    + +
    +
    Характеристика (RUS)
    +
    + +
    +
    + +
    +
    Характеристика (ENG)
    +
    + +
    +
    + +
    +
    Код
    +
    + +
    +
    + +
    +
    Сортировка
    +
    + + Целое число - порядок, в котором Характеристика будет выводиться в списке (или соответствующий Вариант услуги в списке вариантов). Рекомендуется ставить через 100, чтобы потом удобнее было тасовать +
    +
    + +
    +
    Описание
    +
    + +
    +
    + +
    +
    Создано
    +
    + #dateFormat(d.dt_created,'DD.MM.YYYY')# #timeFormat(d.dt_created,'HH:MM')# + #qUsr.creator# (#qUsr.creator_shortname#) +       + Изменено + #dateFormat(d.dt_updated,'DD.MM.YYYY')# #timeFormat(d.dt_updated,'HH:MM')# + #qUsr.updater# (#qUsr.updater_shortname#) +
    +
    + +
    + +
    + + + + + + + select distinct + s.service_id + ,a.abstract_service_id + ,a.code as abstract_service_code + ,a.abstract_service + ,m.modifier + from service s + left outer join modifier m on (s.modifier_id=m.modifier_id) + left outer join abstract_service a on (s.abstract_service_id=a.abstract_service_id) + where s.modifier_id= + order by a.code, a.abstract_service + + + +

    Используется услугами (#qService.recordCount#)

    +
    + + + + + + + + + + + + + + + + + + + + + +
    Код услугиАбстрактная услугаХарактеристика
    + + + #abstract_service_code#.#d.code# + + #abstract_service# + + #modifier# + + +
    +
    + +

    Конкретные услуги (варианты услуги) определяются значением характеристики-модификатора. В тривиальном случае услуга может иметь только один вариант. Разные варианты услуги могут иметь различный состав компонентов (более того, этот состав определяется именно для конкретной услуги), например, в разных кластерах виртуализации может быть доступен разный набор типов дисков.

    +

    Один и тот же класс модификатора может применяться к разным абстрактным услугам.

    +

    Модификатор может состоять из нескольких переменных, например, система виртуализации + частота процессора. В этом случае в справочник нужно включить все актуальные комбинации

    + + diff --git a/modifier_class.cfm b/modifier_class.cfm new file mode 100644 index 0000000..aaa81c5 --- /dev/null +++ b/modifier_class.cfm @@ -0,0 +1,205 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + pageInfo=#pageInfo# + id="#d.modifier_class_id#" + status=#pageInfo.status# + trackOut="tr" + idAttributesOut="id" +/> + + + select + a.login as creator, a.shortname as creator_shortname, m.login as updater, m.shortname as updater_shortname + from #pageInfo.entity# e + left outer join usr a on (e.creator_id=a.usr_id) + left outer join usr m on (e.updater_id=m.usr_id) + where e.#pageInfo.key#= + + + + + + Класс характеристики (модификатора) + + #d.modifier_class# + [#d.modifier_class_id#] + + + + + + +
    #status.errorMessage#
    +
    + + + + + + +
    + +
    +
    Класс характеристики (RUS)
    +
    + +
    +
    + +
    +
    Класс характеристики (ENG)
    +
    + +
    +
    + +
    +
    Описание
    +
    + +
    +
    + +
    +
    Создано
    +
    + #dateFormat(d.dt_created,'DD.MM.YYYY')# #timeFormat(d.dt_created,'HH:MM')# + #qDecoration.creator# (#qDecoration.creator_shortname#) +       + Изменено + #dateFormat(d.dt_updated,'DD.MM.YYYY')# #timeFormat(d.dt_updated,'HH:MM')# + #qDecoration.updater# (#qDecoration.updater_shortname#) +
    +
    + +
    + +
    + + + + + + select + p.modifier_id + ,p.modifier + ,p.code + ,p.sort + from modifier p + where p.modifier_class_id= + order by p.sort, p.code, p.modifier + + + +

    Характеристики (#qModifier.recordCount#) + + + + + + +

    +
    + + + + + + + + + + + + + + + + + + + +
    ХарактеристикаКодСортировка
    + + + #modifier# + #code##sort# + +
    + + + select + a.abstract_service_id + ,a.code + ,a.abstract_service + ,a.abstract_service_en + from modifier_class c + join abstract_service a on (c.modifier_class_id = a.modifier_class_id) + where c.modifier_class_id= + order by 2 + + + +

    Используется абстрактными услугами (#qAbstractService.recordCount#)

    +
    + + + + + + + + + + + + + + + +
    Код услугиНоменклатура (RUS)Номенклатура (ENG)
    #code##abstract_service##abstract_service_en#
    + +
    + + + + diff --git a/modifier_class_del.cfm b/modifier_class_del.cfm new file mode 100644 index 0000000..f499b68 --- /dev/null +++ b/modifier_class_del.cfm @@ -0,0 +1,70 @@ + + + + + + + + + + + + + m.modifier_id + m.modifier_ID + m.modifier + + modifier m + + m.modifier_class_id + 2 + + + + + + + + + + select + c.modifier_class + from modifier_class c + where c.modifier_class_id= + + + + + + + Удаление класса характеристики + #qDecoration.modifier_class# + + [#modifier_class_id#] + + + +   + + + + +#markup# + + \ No newline at end of file diff --git a/modifier_class_ls.cfm b/modifier_class_ls.cfm new file mode 100644 index 0000000..5b10a6d --- /dev/null +++ b/modifier_class_ls.cfm @@ -0,0 +1,111 @@ + + + + + + + + + + + + + + + + + select + + c.modifier_class_id + c.modifier_class + c.modifier_class_en + + (select count(*) from abstract_service a where a.modifier_class_id=c.modifier_class_id) as abstract_service_cnt + + + (select count(*) from modifier a where a.modifier_class_id=c.modifier_class_id) as modifier_cnt + + + from modifier_class c + where 1=1 + order by + + + + + + + + + +select count(*) as cnt from modifier_class where 1=1 + + + + + + + + + + + + Классы характеристик (модификаторов) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + #modifier_class##modifier_class_en##abstract_service_cnt##modifier_cnt# + +
    + + #gridFooter# + +
    + \ No newline at end of file diff --git a/modifier_del.cfm b/modifier_del.cfm new file mode 100644 index 0000000..d28e95e --- /dev/null +++ b/modifier_del.cfm @@ -0,0 +1,69 @@ + + + + + + + + + + + + + s.service_id + a.code + a.abstract_service + m.modifier + + service s + left outer join abstract_service a on (s.abstract_service_id=a.abstract_service_id) + left outer join modifier m on (s.modifier_id=m.modifier_id) + + m.modifier_id + 2 + + + + + + + + + + select + m.modifier + from modifier m + where m.modifier_id= + + + + + + + Удаление характеристики + #qDecoration.modifier# + [#modifier_id#] + + +   + + +#markup# + + \ No newline at end of file diff --git a/modifier_ls.cfm b/modifier_ls.cfm new file mode 100644 index 0000000..454e8c8 --- /dev/null +++ b/modifier_ls.cfm @@ -0,0 +1,112 @@ + + + + + + + + + + + + + + + + + select + + m.modifier_id + m.code as modifier_code + c.modifier_class + m.modifier + m.modifier_en + m.sort + + from modifier m + join modifier_class c on (m.modifier_class_id=c.modifier_class_id) + where 1=1 + order by + + + + + + + + +select count(*) as cnt from modifier where 1=1 + + + + + + + + + + + + Характеристики (модификаторы услуг) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + #modifier_id##modifier_class##modifier##modifier_en##modifier_code##sort# + +
    + + #gridFooter# + +
    + \ No newline at end of file diff --git a/param.cfm b/param.cfm new file mode 100644 index 0000000..47f0f8e --- /dev/null +++ b/param.cfm @@ -0,0 +1,336 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + pageInfo=#pageInfo# + id="#d.param_id#" + status=#pageInfo.status# + trackOut="tr" + idAttributesOut="id" +/> + + + select p.param_class, p.param_class_en, p.measure_id, p.precision, m.measure, m.measure_short + from param_class p + left outer join measure m on (p.measure_id=m.measure_id) + where param_class_id= + + + + + + + + select + a.login as creator, a.shortname as creator_shortname, m.login as updater, m.shortname as updater_shortname + from #pageInfo.entity# e + left outer join usr a on (e.creator_id=a.usr_id) + left outer join usr m on (e.updater_id=m.usr_id) + where e.#pageInfo.key#= + + + + + + Вариант компонента + + #qParamClass.param_class# + [#d.param_class_id#] + + + #d.param#(пустое наименование) + [#d.param_id#] + + + + + + +
    #status.errorMessage#
    +
    + + + + + + +
    + + +
    +
    Компонент
    +
    + + select param_class_id, param_class + from param_class + order by 2 + + + + + + + + + + + + + Единица измерения: #qParamClass.measure# (#qParamClass.measure_short#) + Точность: #qParamClass.precision# + +
    +
    + +
    +
    Вариант компонента
    +
    + > + + ---> + + Уточнение к имени компонента. Если в у компонента единственный вариант - оставить пустым +
    +
    + +
    +
    Сокращение
    +
    + + > + + + + Используется при формировании полного названия услуги в спецификации.
    + Если у компонента единственный вариант - заполнить именем компонента, но со строчной буквы
    +
    +
    + +
    +
    Код
    +
    + +
    +
    + +
    +
    Полное наименование
    +
    + #qParamClass.param_class# #d.param# + Формируется из имени класса и имени компонента (уточненного, если есть варианты) +
    +
    + +
    +
    Единица измерения
    +
    + + select measure_id, measure_short + from measure + order by 2 + + + Переопределяет единицу измерения компонента +
    +
    + +
    +
    Точность
    +
    + + Количество знаков после запятой, 0 - целое число. Переопределяет точность из компонента +
    +
    + +
    +
    Сортировка
    +
    + + Целое число - порядок, в котором вариант компонента будет выводиться в списках. Рекомендуется ставить через 100, чтобы потом удобнее было тасовать +
    +
    + + + + + +
    +
    Описание
    +
    + +
    +
    + +
    +
    Создано
    +
    + #dateFormat(d.dt_created,'DD.MM.YYYY')# #timeFormat(d.dt_created,'HH:MM')# + #qUsr.creator# (#qUsr.creator_shortname#) +       + Изменено + #dateFormat(d.dt_updated,'DD.MM.YYYY')# #timeFormat(d.dt_updated,'HH:MM')# + #qUsr.updater# (#qUsr.updater_shortname#) +
    +
    + +
    + +
    + + + + + + + + + select distinct + s.service_id + ,sp.service_param_id + ,a.abstract_service_id + ,a.code + ,g.area_code + ,a.abstract_service + ,m.modifier + ,m.code as modifier_code + ,p.param_id + ,p.param + ,p.code as param_code + ,(select count (*) from service_param_price spp where sp.service_param_id=spp.service_param_id) as prc_cnt + from service_param sp + left outer join service s on (sp.service_id=s.service_id) + left outer join param p on (sp.param_id=p.param_id) + left outer join modifier m on (s.modifier_id=m.modifier_id) + left outer join abstract_service a on (s.abstract_service_id=a.abstract_service_id) + left outer join area g on (a.area_id=g.area_id) + where sp.param_id= + order by a.code, a.abstract_service + + + + +

    Используется услугами (#qService.recordCount#)

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    Код услугиАбстрактная услугаВариант услугиКод компонента услугиЦен
    + + + #request.skuCode(area_code,code,modifier_code)# + + #abstract_service# + + + + #abstract_service# #modifier# + + + #request.skuCode(area_code,code,modifier_code,param_code)# [#service_param_id#] + + #prc_cnt# + + +
    + +
    + + + + + + + + \ No newline at end of file diff --git a/param_class.cfm b/param_class.cfm new file mode 100644 index 0000000..8080793 --- /dev/null +++ b/param_class.cfm @@ -0,0 +1,378 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + pageInfo=#pageInfo# + id="#d.param_class_id#" + status=#pageInfo.status# + trackOut="tr" + idAttributesOut="id" +/> + + + select + a.login as creator, a.shortname as creator_shortname, m.login as updater, m.shortname as updater_shortname + from #pageInfo.entity# e + left outer join usr a on (e.creator_id=a.usr_id) + left outer join usr m on (e.updater_id=m.usr_id) + where e.#pageInfo.key#= + + + + + + Компонент + + #d.param_class# + [#d.param_class_id#] + + + + + + +
    #status.errorMessage#
    +
    + + + + + + +
    + +
    +
    Компонент (RUS)
    +
    + +
    +
    + +
    +
    Компонент (ENG)
    +
    + +
    +
    + +
    +
    Единица измерения
    +
    + + select measure_id, measure_short + from measure + order by 2 + + /> + служит шаблоном для единицы измерения варианта компонента, ***может быть переопределена +
    +
    + +
    +
    Точность
    +
    + + количество знаков после запятой. 0 - целое число +
    +
    + +
    +
    Описание
    +
    + +
    +
    + +
    +
    Создано
    +
    + #dateFormat(d.dt_created,'DD.MM.YYYY')# #timeFormat(d.dt_created,'HH:MM')# + #qDecoration.creator# (#qDecoration.creator_shortname#) +       + Изменено + #dateFormat(d.dt_updated,'DD.MM.YYYY')# #timeFormat(d.dt_updated,'HH:MM')# + #qDecoration.updater# (#qDecoration.updater_shortname#) +
    +
    + +
    + +
    + + + + + + + select + p.param_id + ,p.param + ,c.param_class + ,p.code + ,p.precision + ,p.sort + ,m.measure_id + ,m.measure + ,m.measure_short + ,(select count(distinct service_id) from service_param sp where sp.param_id=p.param_id) as svc_cnt + from param p + join param_class c on (p.param_class_id=c.param_class_id) + left outer join measure m on (p.measure_id=m.measure_id) + where p.param_class_id= + order by p.sort + + + +

    Варианты компонента (#qParam.recordCount#) + + + + + + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    КомпонентВариант компонентаКодЕдиница измеренияТочностьСортировкаИспользуется услугами
    + + #param_class# + + + + + #param# + + (основной вариант) + + + (не выбран) + + + #code##measure# (#measure_short#)(нет)#precision##sort##svc_cnt#
    + +
    + + + + + + + select distinct + ac.abstract_service_id + ,a.code + ,a.abstract_service + ,ac.abstract_service_param_class_id + ,ac.is_multiple + ,g.area_code + from abstract_service a + join area g on (a.area_id=g.area_id) + right outer join abstract_service_param_class ac on (a.abstract_service_id=ac.abstract_service_id) + where ac.param_class_id= + order by a.code, a.abstract_service + + + + +

    Используется абстрактными услугами (#qAbstractService.recordCount#)

    +
    + + + + + + + + + + + + + + + + + + + + + + +
    КодАбстрактная услугаКомпонентМножественный
    + + + #request.skuCode(area_code,code)# + + #abstract_service# + + #d.param_class# + + + Да + + + +
    + + + + + + + select distinct + s.service_id + ,sp.service_param_id + ,a.abstract_service_id + ,a.code + ,a.abstract_service + ,g.area_code + ,m.modifier_id + ,m.modifier + ,m.code as modifier_code + ,p.param_id + ,p.param + ,p.code as param_code + from service s + join service_param sp on (s.service_id=sp.service_id) + join abstract_service_param_class ac on (sp.abstract_service_param_class_id=ac.abstract_service_param_class_id) + left outer join param p on (sp.param_id=p.param_id) + left outer join modifier m on (s.modifier_id=m.modifier_id) + left outer join abstract_service a on (s.abstract_service_id=a.abstract_service_id) + left join area g on (a.area_id=g.area_id) + where ac.param_class_id= + order by a.code, a.abstract_service + + + +

    Используется конкретными услугами (#qService.recordCount#)

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Абстрактная услугаВариант услугиКод вар. усл. КомпонентВариант компонентаКод вар. комп.
    + + + #abstract_service# + + #abstract_service# #modifier# + + #request.skuCode(area_code,code,modifier_code)# + + #d.param_class# + + + + + #param# + + (основной вариант) + + + (не выбран) + + + + #request.skuCode(area_code,code,modifier_code,param_code)# + + +
    + +
    + + \ No newline at end of file diff --git a/param_class_del.cfm b/param_class_del.cfm new file mode 100644 index 0000000..094de72 --- /dev/null +++ b/param_class_del.cfm @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + p.param_id + p.param_id + p.param + p.param_short + p.code + + param p + + p.param_class_id + 2 desc + + + + sp.service_param_id + a.code + a.abstract_service + m.modifier + c.param_class + p.param + + service_param sp + left outer join param p on sp.param_id=p.param_id + left outer join abstract_service_param_class ac on (sp.abstract_service_param_class_id=ac.abstract_service_param_class_id) + left outer join param_class c on ac.param_class_id=c.param_class_id + left outer join service s on sp.service_id=s.service_id + left outer join modifier m on s.modifier_id=m.modifier_id + left outer join abstract_service a on s.abstract_service_id=a.abstract_service_id + + ac.param_class_id + 2 desc + + + + + + + + + +select + c.param_class + FROM param_class c + where c.param_class_id= + + + + + + + Удаление компонента + #qDecoration.param_class# + + [#param_class_id#] + + + +   + + + + +#markup# + + \ No newline at end of file diff --git a/param_class_ls.cfm b/param_class_ls.cfm new file mode 100644 index 0000000..267835a --- /dev/null +++ b/param_class_ls.cfm @@ -0,0 +1,112 @@ + + + + + + + + + + + + + + + + + select + + c.param_class_id + c.param_class + c.param_class_en + m.measure_short + (select count(*) from param p where p.param_class_id=c.param_class_id) as param_count + (select count(*) from abstract_service_param_class ac where ac.param_class_id=c.param_class_id) as abstract_service_param_class_count + + from param_class c + left outer join measure m on (c.measure_id=m.measure_id) + where 1=1 + order by + + + + + + + + + + +select count(*) as cnt from param_class where 1=1 + + + + + + + + + + + + Компоненты (компоненты услуг) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + #param_class##param_class_en##measure_short##param_count##abstract_service_param_class_count# + +
    + + #gridFooter# + +
    + \ No newline at end of file diff --git a/param_clone.cfm b/param_clone.cfm new file mode 100644 index 0000000..b7bd7f5 --- /dev/null +++ b/param_clone.cfm @@ -0,0 +1,294 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + insert into service_param ( + service_id,param_id,abstract_service_param_class_id,min_value,max_value,incr,descr + ) select + service_id + , + ,abstract_service_param_class_id + ,min_value + ,max_value + ,incr + ,descr + from service_param sp + where service_param_id= + AND NOT exists(select * from service_param sp1 where sp1.service_id=sp.service_id AND sp1.param_id=); + + + + + + pageInfo=#pageInfo# + id="#d.param_id#" + status=#pageInfo.status# + trackOut="tr" + idAttributesOut="id" +/> + + + select p.param_class, p.param_class_en, p.measure_id, p.precision + from param_class p + where param_class_id= + + + + + + + + select + a.login as creator, a.shortname as creator_shortname, m.login as updater, m.shortname as updater_shortname + from #pageInfo.entity# e + left outer join usr a on (e.creator_id=a.usr_id) + left outer join usr m on (e.updater_id=m.usr_id) + where e.#pageInfo.key#= + + + + + + Клонирование варианта (реализации) компонента + + #qParamClass.param_class# + + + #d.param# + [#d.param_id#] + + + + + + + + + + + + + + +
    #status.errorMessage#
    +
    + + + + + + + + +
    +
    +
    Компонент
    +
    + + select param_class_id, param_class + from param_class + order by 2 + + + +
    +
    + +
    +
    Вариант компонента
    +
    + + > + + + + Имя компонента - должно быть уникальным *** Контроль! +
    +
    + +
    +
    Сокращение
    +
    + + > + + + + Используется при формировании полного названия услуги в спецификации +
    +
    + +
    +
    Код
    +
    + + Должен быть уникальным в пределах компонента (класса компонента) +
    +
    + +
    +
    Полное наименование
    +
    + #qParamClass.param_class# #d.param# + Формируется из имени класса и имени компонента (уточненного, если есть варианты) +
    +
    + +
    +
    Единица измерения
    +
    + + select measure_id, measure_short + from measure + order by 2 + + +
    +
    + +
    +
    Точность
    +
    + + Количество знаков после запятой, 0 - целое число +
    +
    + +
    +
    Сортировка
    +
    + + Целое число - порядок, в котором вариант компонента будет выводиться в списках. Рекомендуется ставить через 100, чтобы потом удобнее было тасовать +
    +
    + +
    +
    Описание
    +
    + +
    +
    + +
    +
    Создано
    +
    + #dateFormat(d.dt_created,'DD.MM.YYYY')# #timeFormat(d.dt_created,'HH:MM')# + #qDecoration.creator# (#qDecoration.creator_shortname#) +       + Изменено + #dateFormat(d.dt_updated,'DD.MM.YYYY')# #timeFormat(d.dt_updated,'HH:MM')# + #qDecoration.updater# (#qDecoration.updater_shortname#) +
    +
    +
    + +
    + + +Просьба следить за отсутствием дублирования и поменять значения всех полей, которые нужно. + + + + \ No newline at end of file diff --git a/param_del.cfm b/param_del.cfm new file mode 100644 index 0000000..26da030 --- /dev/null +++ b/param_del.cfm @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + sp.service_param_id + a.code + a.abstract_service + m.modifier + c.param_class + p.param + + service_param sp + left outer join param p on sp.param_id=p.param_id + left outer join param_class c on p.param_class_id=c.param_class_id + left outer join service s on sp.service_id=s.service_id + left outer join modifier m on s.modifier_id=m.modifier_id + left outer join abstract_service a on s.abstract_service_id=a.abstract_service_id + + sp.param_id + 2 desc + + + + sip.specification_item_param_id + spec.specification + a.code + a.abstract_service + m.modifier + c.param_class + p.param + sip.quantity + sip.price + + specification_item_param sip + join service_param sp on (sip.service_param_id=sp.service_param_id) + left outer join abstract_service_param_class ac on (sp.abstract_service_param_class_id=ac.abstract_service_param_class_id) + left outer join param p on sp.param_id=p.param_id + left outer join param_class c on p.param_class_id=c.param_class_id + left outer join param p1 on sp.param_id=p1.param_id + left outer join service s on sp.service_id=s.service_id + left outer join modifier m on s.modifier_id=m.modifier_id + left outer join abstract_service a on s.abstract_service_id=a.abstract_service_id + left outer join specification_item si on sip.specification_item_id=si.specification_item_id + left outer join specification spec on si.specification_id=spec.specification_id + + sp.param_id + 2 desc + + + + spp.service_param_price_id + a.code + a.abstract_service + m.modifier + c.param_class + coalesce(p.param, p1.param) as param + spp.price + + service_param_price spp + left outer join service_param sp on (spp.service_param_id=sp.service_param_id) + left outer join param p on sp.param_id=p.param_id + left outer join param_class c on p.param_class_id=c.param_class_id + left outer join param p1 on sp.param_id=p1.param_id + left outer join service s on sp.service_id=s.service_id + left outer join modifier m on s.modifier_id=m.modifier_id + left outer join abstract_service a on s.abstract_service_id=a.abstract_service_id + + sp.param_id + 2 desc + + + + + + + + + +select + p.param, c.param_class + FROM param p + left outer join param_class c on (p.param_class_id=c.param_class_id) + where p.param_id= + + + + + + + Удаление варианта компонента + + #qDecoration.param_class# + + #qDecoration.param# + + [#param_id#] + + + +   + + + + +#markup# + + \ No newline at end of file diff --git a/param_ls.cfm b/param_ls.cfm new file mode 100644 index 0000000..e466865 --- /dev/null +++ b/param_ls.cfm @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + + + select + + p.param_id + c.param_class_id + p.param + p.param_short + c.param_class + m.measure_short + p.code + p.sort + + p.precision + (select count(*) from service_param sp where sp.param_id=p.param_id) as svc_count + + from param p + left outer join param_class c on (p.param_class_id=c.param_class_id) + left outer join measure m on (p.measure_id=m.measure_id) + where 1=1 + order by + + + + + + + + + +select count(*) as cnt from param where 1=1 + + + + + + + + + + + + Варианты компонентов + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + #param_class##param##param_short##code##measure_short##precision##sort##svc_count# + +
    + + #gridFooter# + +
    + \ No newline at end of file diff --git a/password.cfm b/password.cfm new file mode 100644 index 0000000..7ddd7fd --- /dev/null +++ b/password.cfm @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + + select usr_id, password as pwdhash from usr + where usr_id='#request.usr_id#' + limit 1 + /* AND pwdcompare('#old_password#',password,0) >0 */ + + + + + + + + + + + + + update usr set password='#newHash#' + where usr_id='#request.usr_id#' + + + + + + + + + + + + Смена пароля + + + + + + + + + +Смена пароля в локальной базе данных. + +
    +
    +
    +
    +
    +
    Старый пароль
    +
    +
    + +
    +
    Новый пароль
    +
    +
    + +
    +
    Подтверждение
    +
    +
    + +
    +
    +
    +
    +
    +
    + +

    +
    #msg# 
    +











    + +
    +
    + + + +
    + \ No newline at end of file diff --git a/price_filter.cfm b/price_filter.cfm new file mode 100644 index 0000000..3825f3a --- /dev/null +++ b/price_filter.cfm @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + #i18("Прайс лист - фильтр","Plice List - filter")# + + + + + +
    + +
    +
    +
    + +
    +
    + +
    +
    #i18("Модель ценообразования","Pricing Model")#
    +
    + + select pricing_model_id, pricing_model from pricing_model order by pricing_model_id + + +
    +
    + +
    +
    #i18("Номенклатура","Service")#
    +
    + + #i18("по вхождению подстроки","by substring")# +
    +
    + +
    +
    #i18("Код услуги","Service Code")#
    +
    + + #i18("по вхождению подстроки","by substring")# +
    +
    + +
    +
    #i18("Статус абстр. услуги","Abstract Service Status")#
    +
    + + select status_id, status + from status + order by status_id + + + +
    +
    + +
    +
    #i18("Группа каталога","Catalog Group")#
    +
    + + select g.area_id, g.area, g.area_code + from area g + order by g.area_id + + + + +
    + #i18("Код","Code")# + +
    + #i18("Группа","Group")# + +
    + #i18("по вхождению подстроки","by substring")# +
    +
    +
    + +
    + +
    + + + \ No newline at end of file diff --git a/price_json.cfm b/price_json.cfm new file mode 100644 index 0000000..4f477e2 --- /dev/null +++ b/price_json.cfm @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + select + + prc.service_price_id + prc.service_param_price_id + prm.pricing_model_id + prm.pricing_model + prm.pricing_model_short + prm.pricing_model_code + prc.pricing_period + prc.rating_period + prc.dt_from + prc.dt_to + s.vat_perc + s.vat_free + case when s.vat_free then 0. else vat_perc/100. end as vat_rate + prc.price + case when price*.95 > coalesce(min_price,0) then price*.95 else min_price end as discount_price/***/ + min_price + + a.abstract_service_id + s.service_id + + g.area_code + g.area + g.area_id + g.analytic_code + + a.status_id as abstract_service_status_id + u.status as abstract_service_status + s.status_id as service_status_id + t.status as service_status + prc.status as price_status + + a.code + m.code as modifier_code + p.code as param_code + + a.abstract_service + + m.modifier_id + + mc.modifier_class + mc.modifier_class_id + m.modifier + m.sort + + sp.service_param_id + sp.min_value + sp.max_value + sp.incr + pc.param_class_id + pc.param_class + ac.sort as param_class_sort + ac.is_multiple + p.sort as param_sort + p.param + p.param_id + case when p.param_id IS NULL then se.measure_short else e.measure_short end as measure_short + case when p.param_id IS NULL then s.measure_id else p.measure_id end as measure_id + s.commercial_note + + from ( + select + t.service_param_price_id, t.price, t.min_price, t.service_param_id, t.pricing_model_id + , null as service_price_id, sp.service_id, t.pricing_period, t.rating_period, t.dt_from, t.dt_to, t.status + from service_param_price t join service_param sp on (t.service_param_id=sp.service_param_id) + union all + select + null, st.price, st.min_price, null, st.pricing_model_id, st.service_price_id, st.service_id, st.pricing_period, st.rating_period, st.dt_from, st.dt_to, st.status + from service_price st + ) prc /*кажется, union в данном отчете бесполезен - все равно эти данные попадают в разные группировки*/ + left outer join service s on (prc.service_id=s.service_id) + left outer join service_param sp on (prc.service_param_id=sp.service_param_id) + left outer join abstract_service a on (s.abstract_service_id=a.abstract_service_id) + left outer join modifier m on (s.modifier_id=m.modifier_id) + left outer join modifier_class mc on (m.modifier_class_id=mc.modifier_class_id) + left outer join abstract_service_param_class ac on (sp.abstract_service_param_class_id=ac.abstract_service_param_class_id) + left outer join param_class pc on (ac.param_class_id=pc.param_class_id) + left outer join param p on (sp.param_id=p.param_id) + left outer join measure e on (p.measure_id=e.measure_id) + left outer join measure se on (s.measure_id=se.measure_id) + left outer join area g on (a.area_id=g.area_id) + left outer join status u on (a.status_id=u.status_id) + left outer join status t on (s.status_id=t.status_id) + left outer join pricing_model prm on (prc.pricing_model_id=prm.pricing_model_id) + where 1=1 + + order by g.analytic_code + , a.abstract_service + , s.service_id + , coalesce(m.sort,0) + , m.modifier_id + , coalesce(ac.sort,0) + , coalesce(p.sort,0) + , p.param_id + --, prc.pricing_model_id + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +#serializeJSON(temp.out)# \ No newline at end of file diff --git a/price_ls.cfm b/price_ls.cfm new file mode 100644 index 0000000..5109066 --- /dev/null +++ b/price_ls.cfm @@ -0,0 +1,367 @@ + + + + + + + + + + + + + + + + + select + + prc.service_price_id + prc.service_param_price_id + prm.pricing_model + prm.pricing_model_short + prm.pricing_model_code + prc.pricing_period + prc.rating_period + + s.vat_perc + s.vat_free + case when s.vat_free then 0. else vat_perc/100. end as vat_rate + + prc.price + case when price*.95 > min_price then price*.95 else min_price end as discount_price/***/ + min_price + prc.status as price_status + prc.dt_from + prc.dt_to + + case when prc.price >0 then (prc.price-prc.min_price)/prc.price else NULL end as max_discount + + a.abstract_service_id + s.service_id + + g.area_code + g.area + g.analytic_code + g.area_en + + u.status + u.status_en + + g.area_code||'.'||a.code||'.'||m.code||'.'||p.code as code + a.code as abstract_service_code + m.code as modifier_code + p.code as param_code + + a.status_id + a.abstract_service + a.abstract_service_en + + m.modifier_id + + mc.modifier_class + m.modifier + mc.modifier_class_en + m.modifier_en + + sp.service_param_id + pc.param_class_id + pc.param_class + ac.sort as param_class_sort + p.sort as param_sort + p.param + p.param_en + p.param_id + case when p.param_id IS NULL then se.measure_short else e.measure_short end as measure_short + case when p.param_id IS NULL then se.measure_short_en else e.measure_short_en end as measure_short_en + + + from ( + select + t.service_param_price_id, t.price, t.min_price, t.service_param_id, t.pricing_model_id + , null as service_price_id, sp.service_id, t.pricing_period, t.rating_period + ,t.status, t.dt_from, t.dt_to + from service_param_price t join service_param sp on (t.service_param_id=sp.service_param_id) + union all + select + null, st.price, st.min_price, null, st.pricing_model_id, st.service_price_id, st.service_id, st.pricing_period, st.rating_period + ,st.status, st.dt_from, st.dt_to + from service_price st + ) prc + left outer join service s on (prc.service_id=s.service_id) + left outer join service_param sp on (prc.service_param_id=sp.service_param_id) + left outer join abstract_service a on (s.abstract_service_id=a.abstract_service_id) + left outer join modifier m on (s.modifier_id=m.modifier_id) + left outer join modifier_class mc on (m.modifier_class_id=mc.modifier_class_id) + left outer join abstract_service_param_class ac on (sp.abstract_service_param_class_id=ac.abstract_service_param_class_id) + left outer join param_class pc on (ac.param_class_id=pc.param_class_id) + left outer join param p on (sp.param_id=p.param_id) + left outer join measure e on (p.measure_id=e.measure_id) + left outer join measure se on (s.measure_id=se.measure_id) + left outer join area g on (a.area_id=g.area_id) + left outer join status u on (a.status_id=u.status_id) + left outer join pricing_model prm on (prc.pricing_model_id=prm.pricing_model_id) + where 1=1 + order by + + + + + + +select (select count(*) from service_param_price) + (select count(*) from service_price) as cnt; + + + + + + + + + + + + #i18("Прайс-лист базовый","General Price List")# + + + + + + + + + jsonLink="YES" + /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + title="редактировать" + title="просмотр"> + + title="редактировать" + title="просмотр"> + + + + + + + + + + + + + #analytic_code# #area_code# + + + + + #abstract_service# #modifier# + + + + + + #param_class# + #param# + + + + #pricing_model# + + + #request.skuCode(area_code,abstract_service_code,modifier_code,param_code,pricing_model_code)# + + + #analytic_code# #area# + + + + + + + #numberFormat(price,'.00')# + + + + #numberFormat(price,'.00')# + + + + по запросу + + + + + + #numberFormat(discount_price,'.00')# + + по запросу + + + + + + #numberFormat(min_price,'.00')# + + по запросу + + + + + #numberFormat(f_max_discount,'.0')# + + + + #f_param_class_sort# + + + + #f_param_sort# + + + + Не облагается + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #gridFooter# + + + + + + + + \ No newline at end of file diff --git a/price_rpt.cfm b/price_rpt.cfm new file mode 100644 index 0000000..4f2eb85 --- /dev/null +++ b/price_rpt.cfm @@ -0,0 +1,365 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select + + prc.service_price_id + prc.service_param_price_id + prm.pricing_model_id + prm.pricing_model + prm.pricing_model_short + prm.pricing_model_code + prc.pricing_period + prc.rating_period + prc.price + case when price*.95 > coalesce(min_price,0) then price*.95 else min_price end as discount_price/***/ + min_price + prc.status as price_status + prc.dt_from + prc.dt_to + + a.abstract_service_id + s.service_id + + g.area_code + g.area + g.analytic_code + g.area_en + + a.status_id + u.status + u.status_en + + a.code + m.code as modifier_code + p.code as param_code + + a.abstract_service + a.abstract_service_en + + case when (prc.service_price_id > 0) then s.descr else '' end as service_descr + s.commercial_note + + m.modifier_id + + mc.modifier_class + m.modifier + mc.modifier_class_en + m.modifier_en + + sp.service_param_id + pc.param_class_id + pc.param_class + ac.sort as param_class_sort + p.sort as param_sort + p.param + p.param_id + case when p.param_id IS NULL then se.measure_short else e.measure_short end as measure_short + case when p.param_id IS NULL then se.measure_short_en else e.measure_short_en end as measure_short_en + + s.vat_perc + s.vat_free + case when s.vat_free then 0. else vat_perc/100. end as vat_rate + + + + + from ( + select + t.service_param_price_id, t.price, t.min_price, t.service_param_id, t.pricing_model_id + , null as service_price_id, sp.service_id, t.pricing_period, t.rating_period + ,t.status, t.dt_from, t.dt_to + from service_param_price t join service_param sp on (t.service_param_id=sp.service_param_id) + union all + select + null, st.price, st.min_price, null, st.pricing_model_id, st.service_price_id, st.service_id, st.pricing_period, st.rating_period + ,st.status, st.dt_from, st.dt_to + from service_price st + ) prc + left outer join service s on (prc.service_id=s.service_id) + left outer join service_param sp on (prc.service_param_id=sp.service_param_id) + left outer join abstract_service a on (s.abstract_service_id=a.abstract_service_id) + left outer join modifier m on (s.modifier_id=m.modifier_id) + left outer join modifier_class mc on (m.modifier_class_id=mc.modifier_class_id) + left outer join abstract_service_param_class ac on (sp.abstract_service_param_class_id=ac.abstract_service_param_class_id) + left outer join param_class pc on (ac.param_class_id=pc.param_class_id) + left outer join param p on (sp.param_id=p.param_id) + left outer join measure e on (p.measure_id=e.measure_id) + left outer join measure se on (s.measure_id=se.measure_id) + left outer join area g on (a.area_id=g.area_id) + left outer join status u on (a.status_id=u.status_id) + left outer join pricing_model prm on (prc.pricing_model_id=prm.pricing_model_id) + where 1=1 + order by g.analytic_code + , a.abstract_service, s.service_id, m.sort, m.modifier_id + , prc.pricing_model_id + , coalesce(ac.sort,0) -- service_price should be before service_param_price, but null can be after 0 + , p.sort, p.param_id + + + + + + +select (select count(*) from service_param_price) + (select count(*) from service_price) as cnt; + + + + + + + + + + + + + + + + + + + + + + + + #i18("Прайс-лист на компоненты","Resource Price List")# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Группа услугКодУслугаКомпонентЕдиница измеренияМодель ц-обр.Период ценыПериод замераЦена GPL, ₽ с НДСGPL-5%, ₽ с НДСНДС не обл.НДС%
    #analytic_code# #area# + #request.skuCode(area_code,code,modifier_code)# + + #abstract_service# #modifier# +
    #analytic_code# #area# + + #request.skuCode(area_code,code,modifier_code,param_code,pricing_model_code)# + + #request.skuCode(area_code,code,modifier_code,param_code,pricing_model_code)# + + #abstract_service# #modifier##param_class#: #param# + #abstract_service# #modifier# + #measure_short##pricing_model_short##pricing_period##rating_period# + + + + + #request.numFmt(priceWithVAT(price,vat_rate),2)# + + по запросу + + + + + + #request.numFmt(priceWithVAT(price,vat_rate),2)# + + по запросу + + + + ? + + + + + + #request.numFmt(priceWithVAT(discount_price,vat_rate),2)# + + по запросу + + + + #request.numFmt(priceWithVAT(discount_price,vat_rate),2)# + + по запросу + + + ? + + Не облагается#vat_perc#
    + + #gridFooter# + +
    + \ No newline at end of file diff --git a/price_rpt1.cfm b/price_rpt1.cfm new file mode 100644 index 0000000..95e0b26 --- /dev/null +++ b/price_rpt1.cfm @@ -0,0 +1,239 @@ + + + + + + + + + + + + + + + + + + select + + prc.service_price_id + prc.service_param_price_id + prm.pricing_model + prm.pricing_model_short + prm.pricing_model_code + prm.pricing_model_id + prc.pricing_period + prc.rating_period + prc.price + case when price*.95 > coalesce(min_price,0) then price*.95 else min_price end as discount_price/***/ + min_price + + a.abstract_service_id + s.service_id + + g.area_code + g.area + g.analytic_code + g.area_en + + u.status + u.status_en + + + a.code + m.code as modifier_code + p.code as param_code + + a.abstract_service + a.abstract_service_en + + m.modifier_id + + mc.modifier_class + m.modifier + mc.modifier_class_en + m.modifier_en + + sp.service_param_id + pc.param_class_id + pc.param_class + + p.param + + p.param_id + + case when p.param_id IS NULL then se.measure_short else e.measure_short end as measure_short + case when p.param_id IS NULL then se.measure_short_en else e.measure_short_en end as measure_short_en + + + from ( + select + t.service_param_price_id, t.price, t.min_price, t.service_param_id, t.pricing_model_id + , null as service_price_id, sp.service_id, t.pricing_period, t.rating_period + from service_param_price t join service_param sp on (t.service_param_id=sp.service_param_id) + union all + select + null, st.price, st.min_price, null, st.pricing_model_id, st.service_price_id, st.service_id, st.pricing_period, st.rating_period + from service_price st + ) prc + left outer join service s on (prc.service_id=s.service_id) + left outer join service_param sp on (prc.service_param_id=sp.service_param_id) + left outer join abstract_service a on (s.abstract_service_id=a.abstract_service_id) + left outer join modifier m on (s.modifier_id=m.modifier_id) + left outer join modifier_class mc on (m.modifier_class_id=mc.modifier_class_id) + left outer join abstract_service_param_class ac on (sp.abstract_service_param_class_id=ac.abstract_service_param_class_id) + left outer join param_class pc on (ac.param_class_id=pc.param_class_id) + left outer join param p on (sp.param_id=p.param_id) + left outer join measure e on (p.measure_id=e.measure_id) + left outer join measure se on (s.measure_id=se.measure_id) + left outer join area g on (a.area_id=g.area_id) + left outer join status u on (a.status_id=u.status_id) + left outer join pricing_model prm on (prc.pricing_model_id=prm.pricing_model_id) + where 1=1 + order by g.analytic_code,a.abstract_service, s.service_id, m.sort, m.modifier_id, prc.pricing_model_id, ac.sort, coalesce(p.sort,0), p.param_id + + + + + +select (select count(*) from service_param_price) + (select count(*) from service_price) as cnt; + + + + + + + + + + + + #i18("Прайс-лист на компоненты","Resource Price List")# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Группа услугКодУслугаКомпонентЕдиница измеренияМодель ц-обр.Период ценыПериод опросаЦена GPL, ₽ с НДСGPL-5%, ₽ с НДС
    #analytic_code# #area##request.skuCode(area_code,code,modifier_code)##abstract_service# #modifier#
    #analytic_code# #area##request.skuCode(area_code,code,modifier_code,param_code,pricing_model_code)##param_class#: #param##measure_short##pricing_model_short##pricing_period##rating_period# + + + + #request.numFmt(price*(1+request.VAT),2)# + + по запросу + + + ? + + + + + #request.numFmt(discount_price*(1+request.VAT),2)# + + по запросу + + ? + +
    + + #gridFooter# + +
    + \ No newline at end of file diff --git a/provider.cfm b/provider.cfm new file mode 100644 index 0000000..f72d460 --- /dev/null +++ b/provider.cfm @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + pageInfo=#pageInfo# + id="#d.provider_id#" + status=#pageInfo.status# + trackOut="tr" + idAttributesOut="id" +/> + + + select + a.login as creator, a.shortname as creator_shortname, m.login as updater, m.shortname as updater_shortname + from #pageInfo.entity# e + left outer join usr a on (e.creator_id=a.usr_id) + left outer join usr m on (e.updater_id=m.usr_id) + where e.#pageInfo.key#= + + + + + + Провайдер услуг + + #d.provider# + [#d.provider_id#] + + + + + + +
    #status.errorMessage#
    +
    + + + + + + +
    + + +
    +
    ID
    +
    + #d.provider_id# +
    +
    + +
    +
    Наименование провайдера услуг (RUS)
    +
    + +
    +
    + +
    +
    Наименование провайдера услуг (ENG)
    +
    + +
    +
    + + +
    +
    Описание
    +
    + +
    +
    + +
    +
    Создано
    +
    + #dateFormat(d.dt_created,'DD.MM.YYYY')# #timeFormat(d.dt_created,'HH:MM')# + #qDecoration.creator# (#qDecoration.creator_shortname#) +       + Изменено + #dateFormat(d.dt_updated,'DD.MM.YYYY')# #timeFormat(d.dt_updated,'HH:MM')# + #qDecoration.updater# (#qDecoration.updater_shortname#) +
    +
    + +
    + +
    + + + +*** вывести список услуг провайдера + + \ No newline at end of file diff --git a/provider_ls.cfm b/provider_ls.cfm new file mode 100644 index 0000000..8a093f1 --- /dev/null +++ b/provider_ls.cfm @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + select + + m.provider_id + m.provider + m.provider_en + + from provider m + where 1=1 + order by + + + + + + + + + +select count(*) as cnt from provider where 1=1 + + + + + + + + + + + + Провайдеры услуг + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + #provider_id##provider##provider_en#
    + + #gridFooter# + +
    + \ No newline at end of file diff --git a/saml/app_saml_config.cfm b/saml/app_saml_config.cfm new file mode 100644 index 0000000..e10c081 --- /dev/null +++ b/saml/app_saml_config.cfm @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + prod... + prod + + + stage... + stage + dev + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/saml/cmd/1.txt b/saml/cmd/1.txt new file mode 100644 index 0000000..e69de29 diff --git a/saml/cmd/LUCEE_SAML.pem b/saml/cmd/LUCEE_SAML.pem new file mode 100644 index 0000000..e69de29 diff --git a/saml/cmd/delcert.cmd b/saml/cmd/delcert.cmd new file mode 100644 index 0000000..7223d72 --- /dev/null +++ b/saml/cmd/delcert.cmd @@ -0,0 +1,2 @@ +D:\lucee\jre\bin\keytool.exe -delete -v -alias OFFICE02_SAML -keystore D:\lucee\tomcat\lucee-server\context\security\cacerts -storepass changeit +pause \ No newline at end of file diff --git a/saml/cmd/delcert.cmd.txt b/saml/cmd/delcert.cmd.txt new file mode 100644 index 0000000..1497aea --- /dev/null +++ b/saml/cmd/delcert.cmd.txt @@ -0,0 +1,2 @@ +D:\lucee\jre\bin\keytool.exe -delete -v -alias LUCEE_SAML -keystore D:\lucee\jre\lib\security\cacerts -storepass changeit +pause \ No newline at end of file diff --git a/saml/cmd/delcert.txt b/saml/cmd/delcert.txt new file mode 100644 index 0000000..2d1add1 --- /dev/null +++ b/saml/cmd/delcert.txt @@ -0,0 +1,2 @@ +D:\railo\jre\bin\keytool.exe -delete -v -alias OFFICE02_SAML -keystore D:\railo\jre\lib\security\cacerts -storepass changeit +pause \ No newline at end of file diff --git a/saml/cmd/import.cmd b/saml/cmd/import.cmd new file mode 100644 index 0000000..b3631a2 --- /dev/null +++ b/saml/cmd/import.cmd @@ -0,0 +1,23 @@ +REM maybe should run as admin +cd /D "%~dp0" + +SET keytool=D:\lucee\jre\bin\keytool.exe +SET keystore=D:\lucee\tomcat\lucee-server\context\security\cacerts +REM SET dname=CN=office02.ad.nubes.ru SAML key pair, OU=office02.ad.nubes.ru, O=NUBES, L=Moscow, C=RU +SET alias=OFFICE02_SAML +SET passwd=changeit + + +%keytool% -importkeystore ^ + -deststorepass %passwd% -destkeypass %passwd% -destkeystore %keystore% ^ + -srckeystore office02.ad.nubes.ru.pfx -srcstoretype PKCS12 -srcstorepass ZbUswE9T ^ + -srcalias "te-webserver2k-6c5a79ec-75b1-403e-8a44-31f694e74ea3" -destalias OFFICE02_SAML +pause + +%keytool% -list ^ + -keypass %passwd% ^ + -storepass %passwd% ^ + -keystore %keystore% ^ + -alias %alias% ^ + -v +pause \ No newline at end of file diff --git a/saml/cmd/keystore.p12 b/saml/cmd/keystore.p12 new file mode 100644 index 0000000..63e145d Binary files /dev/null and b/saml/cmd/keystore.p12 differ diff --git a/saml/cmd/lscert.cmd b/saml/cmd/lscert.cmd new file mode 100644 index 0000000..5e5b1c7 --- /dev/null +++ b/saml/cmd/lscert.cmd @@ -0,0 +1,2 @@ +D:\lucee\jre\bin\keytool.exe -list -keystore D:/lucee/tomcat/lucee-server/context/security/cacerts -storepass changeit +pause \ No newline at end of file diff --git a/saml/cmd/lscert.cmd.txt b/saml/cmd/lscert.cmd.txt new file mode 100644 index 0000000..dd4b17f --- /dev/null +++ b/saml/cmd/lscert.cmd.txt @@ -0,0 +1,2 @@ +D:\lucee\jre\bin\keytool.exe -list -v -keystore D:/lucee/tomcat/lucee-server/context/security/cacerts -storepass changeit +pause \ No newline at end of file diff --git a/saml/cmd/lscert.txt b/saml/cmd/lscert.txt new file mode 100644 index 0000000..15719f4 --- /dev/null +++ b/saml/cmd/lscert.txt @@ -0,0 +1,2 @@ +"%JAVA_HOME%\bin\keytool.exe" -list -v -keystore C:\lucee\tomcat\lucee-server\context\security\cacerts -storepass changeit +pause \ No newline at end of file diff --git a/saml/cmd/mkcert.cmd b/saml/cmd/mkcert.cmd new file mode 100644 index 0000000..d49df3a --- /dev/null +++ b/saml/cmd/mkcert.cmd @@ -0,0 +1,62 @@ +REM maybe should run as admin + +cd /D "%~dp0" + +SET keytool="%JAVA_HOME%\bin\keytool.exe" +SET keystore=D:/lucee/tomcat/lucee-server/context/security/cacerts +SET dname=CN=dat-n-smishch1 SSL key pair, OU=dat-n-smishch1, O=NUBES, L=Moscow, C=RU +SET alias=LUCEE_SAML +SET passwd=changeit + +REM it is important for Lucee to see cert + +REM SET keytool=D:\railo\jdk\bin\keytool.exe +REM SET keystore=D:\railo\lib\railo-server\context\security\cacerts +REM SET dname=CN=office02 SAML key pair, OU=offiec02, O=NUBES, L=Moscow, C=RU +REM SET alias=OFFICE02_SAML + + +REM generate cert + key +%keytool% -v -genkeypair ^ + -dname "%dname%" ^ + -alias %alias% ^ + -keyalg RSA ^ + -keysize 2048 ^ + -validity 3653 ^ + -keypass %passwd% ^ + -storepass %passwd% ^ + -keystore %keystore% +pause + +%keytool% -list ^ + -alias %alias% ^ + -keypass %passwd% ^ + -storepass %passwd% ^ + -keystore %keystore% ^ + -v +pause + + +%cd% +REM export cert + key to p12 keystore +%keytool% -importkeystore ^ +-alias %alias% ^ +-srckeystore %keystore% ^ +-destkeystore keystore.p12 ^ +-deststoretype PKCS12 ^ +-srckeypass %passwd% ^ +-srcstorepass %passwd% ^ +-deststorepass %passwd% ^ +-destkeypass %passwd% +pause + +:export +REM U should convert .p12 keystore to .pem format for sending your cert and key to adfs administrator, 'openssl pkcs12 -in keystore.p12 -out saml.pem' +%keytool% -exportcert ^ +-alias %alias% ^ +-keypass %passwd% ^ +-keystore %keystore% ^ +-storepass %passwd% ^ +-rfc ^ +-file LUCEE_SAML.pem +pause \ No newline at end of file diff --git a/saml/cmd/mkcert.cmd.txt b/saml/cmd/mkcert.cmd.txt new file mode 100644 index 0000000..48d95b8 --- /dev/null +++ b/saml/cmd/mkcert.cmd.txt @@ -0,0 +1,62 @@ +REM maybe should run as admin + +cd /D "%~dp0" + +SET keytool="%JAVA_HOME%\bin\keytool.exe" +SET keystore=C:/lucee/tomcat/lucee-server/context/security/cacerts +SET dname=CN=dat-n-smishch1 SAML key pair, OU=dat-n-smishch1, O=NUBES, L=Moscow, C=RU +SET alias=LUCEE_SAML +SET passwd=changeit + +REM it is important for Lucee to see cert + +REM SET keytool=D:\railo\jdk\bin\keytool.exe +REM SET keystore=D:\railo\lib\railo-server\context\security\cacerts +REM SET dname=CN=office02 SAML key pair, OU=offiec02, O=NUBES, L=Moscow, C=RU +REM SET alias=OFFICE02_SAML + +goto export +REM generate cert + key +%keytool% -v -genkeypair ^ + -dname "%dname%" ^ + -alias %alias% ^ + -keyalg RSA ^ + -keysize 2048 ^ + -validity 3653 ^ + -keypass %passwd% ^ + -storepass %passwd% ^ + -keystore %keystore% +pause + +%keytool% -list ^ + -alias %alias% ^ + -keypass %passwd% ^ + -storepass %passwd% ^ + -keystore %keystore% ^ + -v +pause + + +%cd% +REM export cert + key to p12 keystore +%keytool% -importkeystore ^ +-alias %alias% ^ +-srckeystore %keystore% ^ +-destkeystore keystore.p12 ^ +-deststoretype PKCS12 ^ +-srckeypass %passwd% ^ +-srcstorepass %passwd% ^ +-deststorepass %passwd% ^ +-destkeypass %passwd% +pause + +:export +REM U should convert .p12 keystore to .pem format for sending your cert and key to adfs administrator, 'openssl pkcs12 -in keystore.p12 -out saml.pem' +%keytool% -exportcert ^ +-alias %alias% ^ +-keypass %passwd% ^ +-keystore %keystore% ^ +-storepass %passwd% ^ +-rfc ^ +-file LUCEE_SAML.pem +pause \ No newline at end of file diff --git a/saml/cmd/mkcert.txt b/saml/cmd/mkcert.txt new file mode 100644 index 0000000..f704223 --- /dev/null +++ b/saml/cmd/mkcert.txt @@ -0,0 +1,47 @@ +REM maybe should run as admin + +CD /d . +SET keytool="%JAVA_HOME%\bin\keytool.exe" +SET keystore=C:/lucee/tomcat/lucee-server/context/security/cacerts +SET dname=CN=dat-n-smishch1 SAML key pair, OU=dat-n-smishch1, O=NUBES, L=Moscow, C=RU +SET alias=LUCEE_SAML +SET passwd=changeit + +REM SET keytool=D:\railo\jdk\bin\keytool.exe +REM SET keystore=D:\railo\lib\railo-server\context\security\cacerts +REM SET dname=CN=office02 SAML key pair, OU=offiec02, O=NUBES, L=Moscow, C=RU +REM SET alias=OFFICE02_SAML + + +REM generate cert + key +%keytool% -v -genkeypair ^ + -dname "%dname%" ^ + -alias %alias% ^ + -keyalg RSA ^ + -keysize 2048 ^ + -validity 3653 ^ + -keypass %passwd% ^ + -storepass %passwd% ^ + -keystore %keystore% +pause + +%keytool% -v -list ^ + -alias %alias% ^ + -keypass %passwd% ^ + -storepass %passwd% ^ + -keystore %keystore% +pause + +REM export cert + key to p12 keystore +%keytool% -importkeystore ^ +-alias %alias% ^ +-srckeystore %keystore% ^ +-destkeystore keystore.p12 ^ +-deststoretype PKCS12 ^ +-srckeypass %passwd% ^ +-srcstorepass %passwd% ^ +-deststorepass %passwd% ^ +-destkeypass %passwd% +pause + +REM U should convert .p12 keystore to .pem format for sending your cert and key to adfs administrator, 'openssl pkcs12 -in keystore.p12 -out saml.pem' \ No newline at end of file diff --git a/saml/cmd/office02.ad.nubes.ru.pfx b/saml/cmd/office02.ad.nubes.ru.pfx new file mode 100644 index 0000000..a82df63 Binary files /dev/null and b/saml/cmd/office02.ad.nubes.ru.pfx differ diff --git a/saml/cmd/temp.keystore b/saml/cmd/temp.keystore new file mode 100644 index 0000000..1506cef Binary files /dev/null and b/saml/cmd/temp.keystore differ diff --git a/saml/cmd/viewsrc.cmd b/saml/cmd/viewsrc.cmd new file mode 100644 index 0000000..a945e52 --- /dev/null +++ b/saml/cmd/viewsrc.cmd @@ -0,0 +1,6 @@ +D:\lucee\jre\bin\keytool.exe -importkeystore ^ + -deststorepass changeit -destkeypass changeit -destkeystore temp.keystore ^ + -srckeystore office02.ad.nubes.ru.pfx -srcstoretype PKCS12 -srcstorepass ZbUswE9T +pause +D:\lucee\jre\bin\keytool.exe -list -keystore temp.keystore -storepass changeit -v +pause \ No newline at end of file diff --git a/saml/conf/prod_sample.cfm b/saml/conf/prod_sample.cfm new file mode 100644 index 0000000..27ea2a2 --- /dev/null +++ b/saml/conf/prod_sample.cfm @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/saml/conf/stage_sample.cfm b/saml/conf/stage_sample.cfm new file mode 100644 index 0000000..babb907 --- /dev/null +++ b/saml/conf/stage_sample.cfm @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/saml/hist.txt b/saml/hist.txt new file mode 100644 index 0000000..9f09b67 --- /dev/null +++ b/saml/hist.txt @@ -0,0 +1,239 @@ +18:32 11.05.2018 +Метаданные: + + + + + + +MIIDszCCApugAwIBAgIEZ+Y5QzANBgkqhkiG9w0BAQsFADCBiTELMAkGA1UEBhMCUlUxDzANBgNVBAcTBk1vc2NvdzEVMBMGA1UEChMMRGF0YWxpbmUgTExDMSEwHwYDVQQLExh2ZGktc21pc2hjaHVrLmR0bG4ubG9jYWwxLzAtBgNVBAMTJnZkaS1zbWlzaGNodWsuZHRsbi5sb2NhbCBTQU1MIGtleSBwYWlyMB4XDTE4MDUxMTEwMzc1NloXDTI4MDUxMTEwMzc1NlowgYkxCzAJBgNVBAYTAlJVMQ8wDQYDVQQHEwZNb3Njb3cxFTATBgNVBAoTDERhdGFsaW5lIExMQzEhMB8GA1UECxMYdmRpLXNtaXNoY2h1ay5kdGxuLmxvY2FsMS8wLQYDVQQDEyZ2ZGktc21pc2hjaHVrLmR0bG4ubG9jYWwgU0FNTCBrZXkgcGFpcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAIi2IftGa1xi6KmhojTi/gSbRFfZpFyQw1V9YhMo4PgzsJz5tKKPlK/TPJX+P8Gu2OOYlkH2zjjYM9rCmNrdnViVqnlKk0E6cUBeQoKZxGN9GmjHvCONsScLxGMpho+YdNbFAga/OiK3myJeNSGc+tKkyQGUTrXQAK4ZvR0bUy/SkfFjjRA9RJLdBZlA6l1DSht1c6HMV3/tRdWxfwszQ+MK45eFHs6NmSjb6VESFXE6fIsa+JKLSOyjPVaNJeYp2fHSEvA6/mxQYl4AxzGilV7acaFgP8JWdBGuOM+ruyuAH3eAXqVvV/9HiYNPflL5VxKT0/rG50+qpKxTACwgX/kCAwEAAaMhMB8wHQYDVR0OBBYEFLF3U+R9xuCkVjkBpLZO+evGgjS+MA0GCSqGSIb3DQEBCwUAA4IBAQAnTSgsmf1JdT3TVZcCODMkj0UgvhNt9tFTCcBsdYnuMmATZ1ktGaGc3iDd5qynopC55u7VzkyH8S+RXqf5rw6OSTmEWgoNYoKXQXkE0U/LUI0Zurc/OciT6KqOprgqr0JEtV+htaJpAhL1iQ0q+Yi6dmlwRD1c8LOFy5dEwwho4acrDjI6WUNN/eedO9/SJWqpC5ZbzreeUUfcO3vJcRHNY++o8TmK6trJU/DR18G8pBzVPRpjJw9YvzOlw106gk1Vyp0J5OIHB0jpFCHzGYBwBB2XgAso6VgTIiJ2Gd08jSuq+UjvClB9mgA2+vG8jiHFaf8DKSqWjOfxie96S9Ff + + + + + + + + +MIIDszCCApugAwIBAgIEZ+Y5QzANBgkqhkiG9w0BAQsFADCBiTELMAkGA1UEBhMCUlUxDzANBgNVBAcTBk1vc2NvdzEVMBMGA1UEChMMRGF0YWxpbmUgTExDMSEwHwYDVQQLExh2ZGktc21pc2hjaHVrLmR0bG4ubG9jYWwxLzAtBgNVBAMTJnZkaS1zbWlzaGNodWsuZHRsbi5sb2NhbCBTQU1MIGtleSBwYWlyMB4XDTE4MDUxMTEwMzc1NloXDTI4MDUxMTEwMzc1NlowgYkxCzAJBgNVBAYTAlJVMQ8wDQYDVQQHEwZNb3Njb3cxFTATBgNVBAoTDERhdGFsaW5lIExMQzEhMB8GA1UECxMYdmRpLXNtaXNoY2h1ay5kdGxuLmxvY2FsMS8wLQYDVQQDEyZ2ZGktc21pc2hjaHVrLmR0bG4ubG9jYWwgU0FNTCBrZXkgcGFpcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAIi2IftGa1xi6KmhojTi/gSbRFfZpFyQw1V9YhMo4PgzsJz5tKKPlK/TPJX+P8Gu2OOYlkH2zjjYM9rCmNrdnViVqnlKk0E6cUBeQoKZxGN9GmjHvCONsScLxGMpho+YdNbFAga/OiK3myJeNSGc+tKkyQGUTrXQAK4ZvR0bUy/SkfFjjRA9RJLdBZlA6l1DSht1c6HMV3/tRdWxfwszQ+MK45eFHs6NmSjb6VESFXE6fIsa+JKLSOyjPVaNJeYp2fHSEvA6/mxQYl4AxzGilV7acaFgP8JWdBGuOM+ruyuAH3eAXqVvV/9HiYNPflL5VxKT0/rG50+qpKxTACwgX/kCAwEAAaMhMB8wHQYDVR0OBBYEFLF3U+R9xuCkVjkBpLZO+evGgjS+MA0GCSqGSIb3DQEBCwUAA4IBAQAnTSgsmf1JdT3TVZcCODMkj0UgvhNt9tFTCcBsdYnuMmATZ1ktGaGc3iDd5qynopC55u7VzkyH8S+RXqf5rw6OSTmEWgoNYoKXQXkE0U/LUI0Zurc/OciT6KqOprgqr0JEtV+htaJpAhL1iQ0q+Yi6dmlwRD1c8LOFy5dEwwho4acrDjI6WUNN/eedO9/SJWqpC5ZbzreeUUfcO3vJcRHNY++o8TmK6trJU/DR18G8pBzVPRpjJw9YvzOlw106gk1Vyp0J5OIHB0jpFCHzGYBwBB2XgAso6VgTIiJ2Gd08jSuq+UjvClB9mgA2+vG8jiHFaf8DKSqWjOfxie96S9Ff + + + + + + + +urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress + + +urn:oasis:names:tc:SAML:2.0:nameid-format:transient + + +urn:oasis:names:tc:SAML:2.0:nameid-format:persistent + + +urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified + + +urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName + + + + + + +Респонс: + + http://adfs.dtln.local/adfs/services/trust + + + + + + + + + + + pMECHm07laxWFPMkrmXUlWmNa8NJcoVtq6pNxqLOOHk= + + + eDuI0bjq0iii5nm0lj8hUrAOm+4Vnkm5a6PlK1crdFYz5bf6TpQlqnCUbXVDByDvBwdJRvaGYg2MDhRcgOcjADRS4vLdzZN3lDBfVEZ8YGwkiK0lrVjsh8EdkEUl+3mHWbGgLhCNRg0auJEXwlvp7goBqeTtJ9/jcNg9T6RWspUZ6b8De07B02KNi54NpdeFRlZ3JUSRODepgDwO6eLnCw/tGGFpOwKL4CrbT2E+UTDygIylAYyoh1YdkIZQm+My3tWDI7LQh2uwaFU9lZk+t/KqoIQwngnoCnOlmPijXLFZ8vSsdcd62PTy8DTIGsziiochZ+Fb3bOsf6mLF5b0BQ== + + + MIIC2jCCAcKgAwIBAgIQRkugSLS1sq1JtGCxzdsvDTANBgkqhkiG9w0BAQsFADApMScwJQYDVQQDEx5BREZTIFNpZ25pbmcgLSBhZGZzLmR0bG4ubG9jYWwwHhcNMTgwNDIyMDk1MzIzWhcNMTkwNDIyMDk1MzIzWjApMScwJQYDVQQDEx5BREZTIFNpZ25pbmcgLSBhZGZzLmR0bG4ubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtVjQVaHUIurxJQVZYze5ERKvVrGoTc+5qZZ7a72IAgw2WVU/KxLGQXn2Yxk1f2Gs4nsG/4iwLeLyIZUPLWqCylURGzQLqv0jy+G0HxXE0kDkMO97s8n7K0vzd58cY6nQofq8kN/IujXzV++KpDRD1hpX3znBegCVgb6RCuozeG8u5eT3LctYQWv/8y5VZuY8pKsGWT3X/LM8f//XBVgYfzMvCrx+7muHC09MHPfrcZ6zacXZaTyT7urVVqQ5uTjiFaQDirRSVeBfGsRpqAMuTTHSDoVVGyNHtqMeIAHbOYyBnOQRaFNY9yHnkJVIN2FMgZ8oCs6LwYxbWUkyNvA53AgMBAAEwDQYJKoZIhvcNAQELBQADggEBAIQm2zh/73Dba69c+07vbhIDbnBuM1QBjcrTFC4m5NbPvLD/yh8mW6pipYsj5b9SZReJxjlCrvAwqNReafN44BUARD0GzUv2x5sRuAoFpx8MbUzYEdf2HJe+OOPwfeNZ8fUa6v986kslYHFXfEfS1/rB54EFNcTU0LOwG/FR6kfV0PvpzAg4KEl3BDv9rQVOGMu6cPvHFm66HpTnfwKXRe1qMiQlaeeATjeiDzdTBFBhZoLvUPymM22iSKRT4u3YQIIEXT3OiuXuJM9h66CYNvCTkQF0vRSnEpCjNZfsNjknimNIX2dz6IeXpzYQCPV4PdNM94jTInZ+JWwFzFWANjo= + + + + + + + + +Потому что обращался к себе по локалхосту или короткому имени, а надо по полному имени vdi-smishchuk.dtln.local (делать, что ли, редирект? или пробивать имя своего хоста в настройках) +13:22 14.05.2018 +С полным именем работает, но Ассершен не возвращает +Логаут полный не отработал, простой отработал, но ассершен все равно не. + +Ругается на отсутствие подписи, хотя в метаданных декларирует, что подпись будет AuthnRequestsSigned="true" +Теперь алгоритм подписи не тот. У меня SHA1, а он ожидает SHA256 +ADFS metadata: https://adfs.dtln.local/FederationMetadata/2007-06/FederationMetadata.xml +там есть упоминание sha256, но только про себя, про SP не говорит + + + +Не в первый раз возникает: +file or directory }R�j�0���,yw�ch�� 9�RYnDm�x��ϯ +�G�7o��n`�i�}�0 ��������OI�/m��8�2|�i�C��0�D�yg9�2z�B�"o��^���NO4�1Mp�����?��w�����.̫�0Bn���+������i�3�w���>I���E�#����*n��pP�4�%0+�����&CL� �4 R�V�f2��������zG+�3�)h��J�U���p������4���ǒ�h��Ce��1���$ ǹ T�mLe𦅿�3�@7%$;:�Y�b=��r��~�L#�3�|l4;:1�䑲 �[�?�� not exist + +Очевидно, райло думает, что я даю ему имя файла +Говорят - потому что не может распарсить. Его можно понять +Теперь новая измена при логине + + + +*** наверно, неплохо проверять статус? + + + + в незашифрованной части документа +На Logout приходит то SAML_request, то SAML_Request, то SAML_Response +Оказывается, она присылает то постом, то гетом. Вероятно, от этого зависит и кодирование! +Эта прекрасная тулза https://rnd.feide.no/simplesaml/module.php/saml2debug/debug.php прекрасно декодирует (ссылка с https://www.experts-exchange.com/questions/28521347/Decipher-SAML-Response-From-ADFS-Server-using-ColdFusion.html) + +Попробовал без успеха: https://gist.github.com/guillaumemolter/3e210855881ec5f09294 +18:19 14.05.2018 +Думаю, что надо на Редирект давать Ассершен логаута +17:14 15.05.2018 +SAML:2.0:status:Responder +Теперь не могу законнектиться. Такое чувство, что зря поменял на SHA256 +https://social.technet.microsoft.com/Forums/en-US/4acc04b7-aac7-43e9-ba50-9570503045f9/msis0038-saml-message-has-wrong-signature?forum=windowsazureaditpro +Попробовал SHA1 то же самое ADFS:MSIS0038: SAML Message has wrong signature + +10:24 16.05.2018 +Если не подписывать запрос (обратное было отражено в метаданных AuthnRequestsSigned="true") то вроде все работает +Вот, теперь не могу отлогиниться + +Трассирую хромом +Оказывается, при простом логауте получаю такую телегу +SAMLRequest: + + + http://adfs.dtln.local/adfs/services/trust + smishchuk + _0a607a2f-c124-4b0f-9245-c476a24a9344 + _e79a1300-00c3-4426-a64f-879c43de5a94 + _7f1dc8d5-9b0c-4f8b-b59c-1a1905609cd3 + + + Потом сбросилось. + Похоже, при каждом логине ИдП дает новый индекс сессии, даже не справшивая пароля + + 13:40 06.06.2018 + System.NotSupportedException: MSIS0023: SAML signature type 'http://www.w3.org/2000/09/xmldsig#rsa-sha256' is not supported by the HTTP Redirect binding serializer at this time. + Сделать постом? + 12:15 07.06.2018 + был неправильный урл криптоалгоритма правильно: http://www.w3.org/2001/04/xmldsig-more#rsa-sha256 + Почти хорошо, только возвращает в первый раз + + Если повторить запрос - редиректит куда надо и присылает группы + Попробуем трассировать https://addons.mozilla.org/en-US/firefox/addon/saml-tracer/ + 11:04 08.06.2018 + ошибка в метаданных + исправил + 11:07 08.06.2018 + +Saml +https://vdi-smishchuk.dtln.local/mms/saml/metadata.cfm +Microsoft.IdentityModel.Protocols.XmlSignature.SignatureVerificationFailedException: MSIS0038: SAML Message has wrong signature. Issuer: 'https://vdi-smishchuk.dtln.local/mms/saml/metadata.cfm'. + +Нашел еще 1 параметр в урле, которого у меня нет RelayState: https://infong-dev.dtln.local/sso/login +10:43 09.06.2018 +&client-request-id=18ee542a-04ee-4fb7-ba19-0080000000f9 + +Вижу разночтение +https://adfs.dtln.local/adfs/ls/?SAMLRequest=nVNdb9MwFH3upP0Hy%2B%2F5ateus9ZOWUpFpQFRm%2FHAm3FcauGP4Ot03b%2FHcShECCpEXqL4nnvuuec49w8nJdGRWxBGL3AWpxhxzUwt9JcFfq7W0Rw%2FLK%2BvUPfcA1Vy3JC8dQe95d9aDu76aoQ8hQbSFxe4tZoYCgKIpooDcYzs8ndPZBynpLHGGWYk%2Fq3tchcF4NZ5gRh1fZvVAos6zWZFPh5n0Twv7qKb2U0RPb6Z3k1ui9ntJFuvZ%2Bt5D%2F94Xs5ThbmlNUdRc%2FveD1rgXYmc3yNUNgAt32hwVDuPT7N5lM6idF5lUzKekkn6KcBWHi80dYH14FwDJElovYe4dlLH0jAqw3ciITmPDHs%2FCt07e2ndzz0IyNuqKqPyw64KHPnZhcJoaBW3O26PgvHn7dMvFcdaRKAEHNih%2FTqUoxQkndUJgInZXmE0Qt6eLtmO3Ec8GvX5kuCC%2FZ94lv8uQ3FHa%2Bpop%2BU%2BGQ4eSGlIl9FmVRop2CtaG6uo%2B7uYLM7CiaijfYCSVkPDmdgLXmOUS2leCsup87E723KcLNFw2I8rzetwwb3Njp8cKoxqqBXQhc1PlDncd53tGoIL6c3Y8v3yol%2BMsA7nj0v%2FejG27u4HZ35yZamXbKw7e%2FJH9iA6uaS6g6CfkOEP6yvfAQAAAAAAAAAAAAA%3D&SigAlg=http%3A%2F%2Fwww%2Ew3%2Eorg%2F2001%2F04%2Fxmldsig%2Dmore%23rsa%2Dsha256&RelayState=https%3A%2F%2Fvdi%2Dsmishchuk%2Edtln%2Elocal%2Fmms%2Fsaml%2Fsso%2Ecfm&Signature=OKVrDbguCzLO0qzFmzNnGpWymCcu97nMyiYe7r1rhQVRgofNYOA3d0bPpjwMGn%2Bcz1WefeX7s%2BvZABXwunwJEC99Tqy9iYhqDpiNYze8rwFbYGnRJUOJVBCtCX2NUYthOlOzVlb%2B1B31NvW70jhBonr3i7syD5Lg4aJpHqaTfAh7ayPdABTlI%2FKjZd2BsHxKH%2F3gh7zQ%2B3VS2tJ2NEUGDwNeJwauG7mxDL4WNZvBIb%2FBQ4UvllfZ3A5rQNwh5c%2BB7qu16%2FAy3j27LpC12xrOPITJuFueoZEa%2BjAs5QjU2Pj%2BndhlT0MH5Az2dqKPI6if%2FTTFYBZleycgRzIwMOkD8g%3D%3D + +https://adfs.dtln.local/adfs/ls/?SAMLRequest=nVNdb9MwFH3upP0Hy%2B%2F5ateus9ZOWUpFpQFRm%2FHAm3FcauGP4Ot03b%2FHcShECCpEXqL4nnvuuec49w8nJdGRWxBGL3AWpxhxzUwt9JcFfq7W0Rw%2FLK%2BvUPfcA1Vy3JC8dQe95d9aDu76aoQ8hQbSFxe4tZoYCgKIpooDcYzs8ndPZBynpLHGGWYk%2Fq3tchcF4NZ5gRh1fZvVAos6zWZFPh5n0Twv7qKb2U0RPb6Z3k1ui9ntJFuvZ%2Bt5D%2F94Xs5ThbmlNUdRc%2FveD1rgXYmc3yNUNgAt32hwVDuPT7N5lM6idF5lUzKekkn6KcBWHi80dYH14FwDJElovYe4dlLH0jAqw3ciITmPDHs%2FCt07e2ndzz0IyNuqKqPyw64KHPnZhcJoaBW3O26PgvHn7dMvFcdaRKAEHNih%2FTqUoxQkndUJgInZXmE0Qt6eLtmO3Ec8GvX5kuCC%2FZ94lv8uQ3FHa%2Bpop%2BU%2BGQ4eSGlIl9FmVRop2CtaG6uo%2B7uYLM7CiaijfYCSVkPDmdgLXmOUS2leCsup87E723KcLNFw2I8rzetwwb3Njp8cKoxqqBXQhc1PlDncd53tGoIL6c3Y8v3yol%2BMsA7nj0v%2FejG27u4HZ35yZamXbKw7e%2FJH9iA6uaS6g6CfkOEP6yvfAQAAAAAAAAAAAAA%3D&SigAlg=http:%2F%2Fwww.w3.org%2F2001%2F04%2Fxmldsig-more%23rsa-sha256&RelayState=https:%2F%2Fvdi-smishchuk.dtln.local%2Fmms%2Fsaml%2Fsso.cfm&Signature=OKVrDbguCzLO0qzFmzNnGpWymCcu97nMyiYe7r1rhQVRgofNYOA3d0bPpjwMGn%2Bcz1WefeX7s%2BvZABXwunwJEC99Tqy9iYhqDpiNYze8rwFbYGnRJUOJVBCtCX2NUYthOlOzVlb%2B1B31NvW70jhBonr3i7syD5Lg4aJpHqaTfAh7ayPdABTlI%2FKjZd2BsHxKH%2F3gh7zQ%2B3VS2tJ2NEUGDwNeJwauG7mxDL4WNZvBIb%2FBQ4UvllfZ3A5rQNwh5c%2BB7qu16%2FAy3j27LpC12xrOPITJuFueoZEa%2BjAs5QjU2Pj%2BndhlT0MH5Az2dqKPI6if%2FTTFYBZleycgRzIwMOkD8g%3D%3D&client-request-id=bdb01962-e04c-4505-6006-0080000000c6 + +А как в работающем варианте +https://adfs.dtln.local/adfs/ls/?SAMLRequest=fVNNj9owEL3vr4hyD0mgQNaCSBT6gUQhgrSHXipjT1hLjp16HJb997WzbGGlNrlYnnnvzbzxZIa0lg1ZtPZJ7eF3C2gfguBSS4WkS83D1iiiKQokitaAxDJyWHzbkOEgIY3RVjMtw3ekfg5FBGOFVp60Xs3D3fbTZvdlvf2VJSw78nSYTbLx5DgdfoAxJFM%2BrhJ49AlGj%2BPpaJR64g8w6DTmoZP09yAojD4LDmbrKs7DQxFYZ6argdjCWqGlyjp8kmZRMomSrEymZJSR9PGnR60cWihqO9EnaxskcUx5hQNupRpIzajs7rHE2BOKq%2FePQnGhTv2mj68gJF%2FLsoiK3aH0Eou3USy1wrYGcwBzFgy%2B7ze3HoSqtDpFHM73nSDqWOrTCXiYd%2FZnfvKk82ryXu4svofeyA3xo1uvCi0Fe%2Bni%2FvusTU3t%2F%2B2lg7SLCB5VHZS0ChtgohKuub8yCyn189IAte51rGkhDOJ3xa%2FrB7xbRjcRCxcbLHXdUCPQvwpcKLNXuzfL9%2FCldNu1hyrvXUBGmMe5cOGOZ224f0tgrnZpqGteG3sd0j%2FFX7uOe9rOH97S939W%2Fgc%3D&RelayState=https%3A%2F%2Finfong-dev.dtln.local%2Fsso%2Flogin&Signature=AMgdc0Doiznf7v5240ZHq6pqw5ms1C%2FFb2cxRv%2Ft%2F85HgzhsShy3F4H15%2BvT0kbscrLF%2B6EEVqHY0tVI%2BYZH1IOfryHU4b7e9DdsKRKUusJ9b3GK%2BiQeyt5lIB3VPZyWQ6bndMJ353R4AhBkYF4%2B0Ilk3fHYsOhATPl8yGNtMn9PrBQ9N5Dh320fcrPO19v3Qv%2B8Hbu1Z2kw2qRyI4E9rPuTnn1n3q0ybBHl1OtW23EMlnW7Grp5Gfvf3EcLd68FdAT6SPlaBIeFVZmtQ92eugYxXEgMFD241d8P1iVDyeJI3SBUX%2FcuyaBVQ%2BT1Y4G6dLIh7MfUDh2V55xAHijZBg%3D%3D&SigAlg=http%3A%2F%2Fwww.w3.org%2F2001%2F04%2Fxmldsig-more%23rsa-sha256 + +https://adfs.dtln.local/adfs/ls/?SAMLRequest=fVNNj9owEL3vr4hyD0mgQNaCSBT6gUQhgrSHXipjT1hLjp16HJb997WzbGGlNrlYnnnvzbzxZIa0lg1ZtPZJ7eF3C2gfguBSS4WkS83D1iiiKQokitaAxDJyWHzbkOEgIY3RVjMtw3ekfg5FBGOFVp60Xs3D3fbTZvdlvf2VJSw78nSYTbLx5DgdfoAxJFM%2BrhJ49AlGj%2BPpaJR64g8w6DTmoZP09yAojD4LDmbrKs7DQxFYZ6argdjCWqGlyjp8kmZRMomSrEymZJSR9PGnR60cWihqO9EnaxskcUx5hQNupRpIzajs7rHE2BOKq%2FePQnGhTv2mj68gJF%2FLsoiK3aH0Eou3USy1wrYGcwBzFgy%2B7ze3HoSqtDpFHM73nSDqWOrTCXiYd%2FZnfvKk82ryXu4svofeyA3xo1uvCi0Fe%2Bni%2FvusTU3t%2F%2B2lg7SLCB5VHZS0ChtgohKuub8yCyn189IAte51rGkhDOJ3xa%2FrB7xbRjcRCxcbLHXdUCPQvwpcKLNXuzfL9%2FCldNu1hyrvXUBGmMe5cOGOZ224f0tgrnZpqGteG3sd0j%2FFX7uOe9rOH97S939W%2Fgc%3D&RelayState=https%3A%2F%2Finfong-dev.dtln.local%2Fsso%2Flogin&Signature=AMgdc0Doiznf7v5240ZHq6pqw5ms1C%2FFb2cxRv%2Ft%2F85HgzhsShy3F4H15%2BvT0kbscrLF%2B6EEVqHY0tVI%2BYZH1IOfryHU4b7e9DdsKRKUusJ9b3GK%2BiQeyt5lIB3VPZyWQ6bndMJ353R4AhBkYF4%2B0Ilk3fHYsOhATPl8yGNtMn9PrBQ9N5Dh320fcrPO19v3Qv%2B8Hbu1Z2kw2qRyI4E9rPuTnn1n3q0ybBHl1OtW23EMlnW7Grp5Gfvf3EcLd68FdAT6SPlaBIeFVZmtQ92eugYxXEgMFD241d8P1iVDyeJI3SBUX%2FcuyaBVQ%2BT1Y4G6dLIh7MfUDh2V55xAHijZBg%3D%3D&SigAlg=http%3A%2F%2Fwww.w3.org%2F2001%2F04%2Fxmldsig-more%23rsa-sha256&client-request-id=18ee542a-04ee-4fb7-ba19-0080000000f9 + +Теперь мы видим удивительную вещь, у меня дефис кодируется UrlEncodedFormat, а у них нет. После раундтрипа мои параметры имеют уже другие значения, %2D преобразовался обратно в минус. То ли это стандарт, то ли сервер это делает, то ли клиент. +А когда у меня SHA1, то в урле нету дефисов, и этот баг не проявляется +Полагаю, то же самое будет, когда я буду пользоваться сразу постом + +Sic! https://www.bennadel.com/blog/2656-url-encoding-amazon-s3-resource-keys-for-pre-signed-urls-in-coldfusion.htm +reserved=;/?:@&=+$, + +http://localhost/mms/saml/sso.cfm?mark=-_.!~*'() +http://localhost/mms/saml/sso.cfm?mark=%2D%5F%2E%21%7E%2A%27%28%29&mark=-_.!~*'() +14:56 09.06.2018 +fixed... +А зачем мы используем HTTP POST binding? Чем редирект нас не радует? +А вот чем: HTTP 413, он ответ отправляет редиректом и он не помещается в урлу +Хочется понять, как пост попадает на мой сервер SP + +Теперь не могу отлогиниться + + +13:08 13.06.2018 +NotOnOrAfter не означает истечения сессии +adfs sessionNotOnOrAfter not supported? +https://aws.amazon.com/ru/blogs/security/enable-your-federated-users-to-work-in-the-aws-management-console-for-up-to-12-hours/ +https://www.owasp.org/index.php/SAML_Security_Cheat_Sheet + +13:20 19.06.2018 +проверка подписи оказалась сложнее, чем я думал http://blog.tagworldwide.com/?p=19 +https://stackoverflow.com/questions/26265727/unable-to-validate-saml-assertion-with-coldfusion +The Reference for URI #_abc42efe-bcaa-43dc-b1c3-3ac2d3c99d5e has no XMLSignatureInput +получилось + assertionArray = XMLSearch(SAMLResponseXml, "/*[name()='samlp:Response']/*[name()='EncryptedAssertion']/*[name()='Assertion']"); + assertionElement = assertionArray[1]; + assertionElement.setIdAttribute("ID",true); //sic! + + 16:22 27.03.2019 + Добавил xmlsec-2.1.1.jar в railo/lib + Error + illegal key size + //see https://backstage.forgerock.com/knowledge/kb/article/a17171105 + see https://myshittycode.com/2016/02/18/java-saml-illegal-key-size/ + put local_policy.jar, US_export_policy.jar to railo\jdk\jre\lib\security, reboot railo + OK works + на Railo + +10:08 02.04.2019 проблемы на Lucee Could not initialize class org.apache.xml.security.Init +Возможно, библиотека xmlsec конфликтует? +Caused by: java.lang.NoClassDefFoundError: Could not initialize class org.apache.xml.security.Init +Переименовать файл D:\lucee\tomcat\lib\xmlsec-2.1.1.jar при этом не дает + +//Init = CreateObject("Java", "org.apache.xml.security.Init").Init().init(); + ref = createObject("java", "org.apache.xml.security.Init"); + // initialize if needed + if (!ref.isInitialized()) { + // find static method named "init" with no parameters + method = ref.getClass().getDeclaredMethod("init", []); + // invoke it via reflection + method.invoke(ref, javacast("null", "")); + } +- сложный способ инициализации оказался ничем не лучше простого +Если изменить имя класса +cannot load class through its string name, because no definition for the class with the specified name [org.apache.xml.security.Init1] could be found caused by (java.lang.ClassNotFoundException:org.apache.xml.security.Init1 not found by lucee.core [64];java.lang.ClassNotFoundException:org.apache.xml.security.Init1;) + +https://stackoverflow.com/questions/30887240/exception-noclassdeffounderror-org-apache-xml-security-init ссылаются на логирование. И у меня при первом вызове ругань на slf4j + java.lang.ClassNotFoundException: org.slf4j.LoggerFactory + В D:\lucee\tomcat\lucee-server\bundles имеются slf4j.api-1.7.12.jar, slf4j.nop-1.7.12.jar, + но в райло slf4j-nop.jar slf4j-api-1.7.22.jar slf4j-api.jar + причем slf4j-api-1.7.22.jar новее (2016 год) + Попробовать обновиться? Current version: 5.2.9.31 + 5.3.1.102 +не помогло +для опыта вовсе дизейблил +Кстати. Log4J not loaded (может, потому что slf4j дизейблил, никто и не грузит) +Ни фига, jar пересоздались +подложил в верхнюю либу файлы от Райло, перезапустил Люси - и вот, все взлетело. Теперь надо + + + \ No newline at end of file diff --git a/saml/login.cfm b/saml/login.cfm new file mode 100644 index 0000000..532a017 --- /dev/null +++ b/saml/login.cfm @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + #request.SAML.baseUrl#metadata.cfm + + + + + + login64 = binaryEncode(deflate(authnRequestXml),"base64"); + loginUrlEnc = urlEncodeRfc2396(login64); + loginSigAlgUrl = urlEncodeRfc2396('http://www.w3.org/2001/04/xmldsig-more##rsa-sha256'); + relayState = urlEncodeRfc2396(target_page); + if (len(target_page)) { //empty RelayState would not be accepted + relayStateX = "&RelayState=#urlEncodeRfc2396(target_page)#"; + } else { + relayStateX = ""; + } + loginRequest2Sign = "SAMLRequest=#loginUrlEnc##relayStateX#&SigAlg=#loginSigAlgUrl#"; //parameter order matters + signature = sign(loginRequest2Sign, privateKey, 'SHA256withRSA'); + signature64 = binaryEncode(signature,"base64"); + signatureForUrl = urlEncodeRfc2396(signature64); + loginRequest = "#loginRequest2Sign#&Signature=#signatureForUrl#"; + + + diff --git a/saml/logout.cfm b/saml/logout.cfm new file mode 100644 index 0000000..932aa36 --- /dev/null +++ b/saml/logout.cfm @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #request.SAML.baseUrl#metadata.cfm + + + + + + + + logout64 = (deflate2base64(logoutResponseXml)); + logoutUrl = urlEncodeRfc2396(logout64); + logoutSigAlgUrl= urlEncodeRfc2396('http://www.w3.org/2001/04/xmldsig-more##rsa-sha256'); + if (len(target_page)) { //empty RelayState would not be accepted + relayStateX = "&RelayState=#urlEncodeRfc2396(target_page)#"; + } else { + relayStateX = ""; + } + logoutRequest2Sign="SAMLRequest=#logoutUrl##relayStateX#&SigAlg=#logoutSigAlgUrl#"; //order matters + signedBytesUrl = urlEncodeRfc2396(sign2base64(logoutRequest2Sign, privateKey, 'SHA256withRSA')); + logoutRequest="#logoutRequest2Sign#&Signature=#signedBytesUrl#"; + + + + + + + + + + + #request.SAML.baseUrl#metadata.cfm + #SAML_NameID# + #SAML_SessionIndex# + + + + + logout64 = (deflate2base64(logoutRequestXml)); + logoutUrl = urlEncodeRfc2396(logout64); + logoutSigAlgUrl= urlEncodeRfc2396('http://www.w3.org/2001/04/xmldsig-more##rsa-sha256'); + if (len(target_page)) { //empty RelayState would not be accepted + relayStateX = "&RelayState=#urlEncodeRfc2396(target_page)#"; + } else { + relayStateX = ""; + } + logoutRequest2Sign="SAMLRequest=#logoutUrl##relayStateX#&SigAlg=#logoutSigAlgUrl#"; //order matters + signedBytesUrl = urlEncodeRfc2396(sign2base64(logoutRequest2Sign,privateKey,'SHA256withRSA')); + logoutRequest="#logoutRequest2Sign#&Signature=#signedBytesUrl#"; + + + + + diff --git a/saml/metadata.cfm b/saml/metadata.cfm new file mode 100644 index 0000000..2742104 --- /dev/null +++ b/saml/metadata.cfm @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #signingCertString# + + + + + + + #encryptionCertString# + + + + + + + urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified + + + + + \ No newline at end of file diff --git a/saml/req.cfm b/saml/req.cfm new file mode 100644 index 0000000..149793e --- /dev/null +++ b/saml/req.cfm @@ -0,0 +1,131 @@ + + + + + + + + + + + + + + + + + + + + + + + + #baseUrl#metadata.cfm + + + + + + + + + + + + + + + #baseUrl#metadata.cfm + #SAML_NameID# + #SAML_SessionIndex# + + + + + + login64 = binaryEncode(deflate(authnRequestXml),"base64"); + loginUrlEnc = urlEncodeRfc2396(login64); + loginSigAlgUrl= urlEncodeRfc2396('http://www.w3.org/2001/04/xmldsig-more##rsa-sha256'); + loginRequest2Sign="SAMLRequest=#loginUrlEnc#&SigAlg=#loginSigAlgUrl#"; + + signedLoginUrlEnc = urlEncodeRfc2396(sign2base64(loginRequest2Sign,privateKey,'SHA256withRSA')); + loginRequest="#loginRequest2Sign#&Signature=#signedLoginUrlEnc#"; + + + + + logout64 = binaryEncode(deflate(logoutRequestXml),"base64"); + logoutUrl = urlEncodeRfc2396(logout64); + logoutSigAlgUrl= urlEncodeRfc2396('http://www.w3.org/2001/04/xmldsig-more##rsa-sha256'); + logoutRequest2Sign="SAMLRequest=#logoutUrl#&SigAlg=#logoutSigAlgUrl#"; + + signedLogoutUrl = urlEncodeRfc2396(sign2base64(logoutRequest2Sign,privateKey,'SHA256withRSA')); + logoutRequest="#logoutRequest2Sign#&Signature=#signedLogoutUrl#"; + + + + + +При обращении к этой странице используйте корректное имя хоста, которое зарегистрировано в ADFS! +
    +Logged in #SAML_SessionIndex#Not logged in +Текущий URL #currentPageUrl# +
    +SAML2 LOGIN: +Click Here to login +#loginRequest# + + + +
    +SAML2 LOGOUT: +Click Here to logout +
    +ADFS URL: +adfs url +
    +
    +ADFS (IdP) metadata +
    +Own metadata + + + +
    +authnRequestXml:
    +-----------------
    + +
    #xmlformat(authnRequestXml)#
    +
    +-----------------
    +
    +logoutRequestXml:
    +-----------------
    + +
    #xmlformat(logoutRequestXml)#
    +
    +-----------------
    +
    + + + +
    +form: +url: +session: +cookie: \ No newline at end of file diff --git a/saml/saml.cfm b/saml/saml.cfm new file mode 100644 index 0000000..8cb592f --- /dev/null +++ b/saml/saml.cfm @@ -0,0 +1,146 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + var emptyByteArray = createObject("java", "java.io.ByteArrayOutputStream").init().toByteArray(); + var byteClass = emptyByteArray.getClass().getComponentType(); + var output = createObject("java","java.lang.reflect.Array").newInstance(byteClass, 500); + var deflater = createObject("java", "java.util.zip.Deflater"); + + deflater.init(9,true); + deflater.setInput(ARGUMENTS.s.getBytes("UTF-8")); + deflater.finish(); + var compressedDataLength = deflater.deflate(output); + + return output; + + + + + + + + + + var emptyByteArray = createObject("java", "java.io.ByteArrayOutputStream").init().toByteArray(); + var byteClass = emptyByteArray.getClass().getComponentType(); + var output = createObject("java","java.lang.reflect.Array").newInstance(byteClass, 500); + var deflater = createObject("java", "java.util.zip.Deflater"); + + deflater.init(9,true); + deflater.setInput(ARGUMENTS.s.getBytes("UTF-8")); + deflater.finish(); + compressedDataLength = deflater.deflate(output); + + return toBase64(output, 'UTF-8'); + + + + + + + + + + + + var signer = createObject("java", "java.security.Signature").getInstance(ARGUMENTS.algorithm);; + var signer.initSign(ARGUMENTS.pk); + var signer.update(ARGUMENTS.s.getBytes("us-ASCII")); + + return signer.sign(); + + + + + + + + + + + + var signer = createObject("java", "java.security.Signature").getInstance(ARGUMENTS.algorithm);; + var signer.initSign(ARGUMENTS.pk); + var signer.update(ARGUMENTS.s.getBytes("us-ASCII")); + + return binaryEncode(signer.sign(), "base64"); + + + + + + + + + + + + + \ No newline at end of file diff --git a/saml/sso.cfm b/saml/sso.cfm new file mode 100644 index 0000000..869a128 --- /dev/null +++ b/saml/sso.cfm @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + /* + On Lucee + Error "Could not initialize class org.apache.xml.security.Init" is possibly caused by incompatible slf4j(api?) + Solution: put slf4j-api-1.7.22.jar to D:\lucee\tomcat\lib + */ + Init = CreateObject("Java", "org.apache.xml.security.Init").Init().init(); + /* + // more complex way to initialize xmlsec + ref = createObject("java", "org.apache.xml.security.Init"); + // writeDump(ref); + // initialize if needed + if (!ref.isInitialized()) { + // find static method named "init" with no parameters + method = ref.getClass().getDeclaredMethod("init", []); + // invoke it via reflection + method.invoke(ref, javacast("null", "")); + } + */ + dataArray=XMLSearch(SAMLResponseXml, "//*[name()='EncryptedAssertion']"); + try { + dataElement=dataArray[1]; + DECRYPT_MODE=CreateObject( "Java", "org.apache.xml.security.encryption.XMLCipher").DECRYPT_MODE; + cipher=CreateObject( "Java", "org.apache.xml.security.encryption.XMLCipher").getInstance(); + cipher.init(DECRYPT_MODE, javacast("null", "")); + cipher.setKEK(privateKey); + cipher.doFinal(dataElement.getOwnerDocument(), dataElement, true); + } catch (any e) { + err = "Ошибка авторизации. Статус запроса: " & SAMLStatus; + } + + +// + if (NOT len(err)) { + assertionArray = XMLSearch(SAMLResponseXml, "/*[name()='samlp:Response']/*[name()='EncryptedAssertion']/*[name()='Assertion']"); + try { + assertionElement = assertionArray[1]; + assertionElement.setIdAttribute("ID",true); //sic! + //WriteDump(assertionElement); + Init = CreateObject("Java", "org.apache.xml.security.Init").Init().init(); + SignatureConstants = CreateObject("Java", "org.apache.xml.security.utils.Constants"); + SignatureSpecNS = SignatureConstants.SignatureSpecNS; //writeDump(SignatureSpecNS); + xmlSignatureClass = CreateObject("Java", "org.apache.xml.security.signature.XMLSignature"); + signatureElement=SAMLResponseXml.getElementsByTagNameNS(SignatureSpecNS,"Signature").item(0); + xmlSignature = xmlSignatureClass.init(signatureElement,""); + keyInfo = xmlSignature.getKeyInfo(); + X509CertificateResolverCN = "org.apache.xml.security.keys.keyresolver.implementations.X509CertificateResolver"; + keyResolver = CreateObject("Java", X509CertificateResolverCN).init(); + keyInfo.registerInternalKeyResolver(keyResolver); + x509cert = keyInfo.getX509Certificate(); + isValid = xmlSignature.checkSignatureValue(x509cert); + } catch (any e) { + err = "Ошибка при проверке подписи. Статус запроса: " & SAMLStatus; + } + } + + + + + + + + + + + + + + + + + select usr_id, locked, shortname + from usr + where login= + + + + + + + + + + + + + + + + + + + + #err# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/service.cfm b/service.cfm new file mode 100644 index 0000000..a98350c --- /dev/null +++ b/service.cfm @@ -0,0 +1,671 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + pageInfo=#pageInfo# + id="#d.service_id#" + status=#pageInfo.status# + trackOut="tr" + idAttributesOut="id" +/> + + + select a.abstract_service, m.modifier, m.modifier_id, c.modifier_class, + m.code as modifier_code, a.code, g.area_code, a.manager_id, + a.measure_id, u.measure, u.measure_short, a.precision + ,au.login as creator, au.shortname as creator_shortname, mu.login as updater, mu.shortname as updater_shortname + from service s + left outer join abstract_service a on (s.abstract_service_id=a.abstract_service_id) + left outer join area g on a.area_id=g.area_id + left outer join modifier m on (s.modifier_id=m.modifier_id) + left outer join modifier_class c on (m.modifier_class_id=c.modifier_class_id) + left outer join measure u on (a.measure_id=u.measure_id) + left outer join usr au on (s.creator_id=au.usr_id) + left outer join usr mu on (s.updater_id=mu.usr_id) + where s.service_id= + + + + + select a.modifier_class_id, mc.modifier_class, a.measure_id, a.precision + from abstract_service a + left outer join modifier_class mc on (a.modifier_class_id=mc.modifier_class_id) + where a.abstract_service_id= + + + + + + + + + + + + + + + + Вариант услуги (конкретная услуга) + + #qDecoration.abstract_service# + + - #qDecoration.modifier# + + [#d.service_id#] + + + + + + +
    #status.errorMessage#
    +
    + + + + + + +
    + + +
    +
    Абстрактная услуга
    +
    + + select abstract_service_id, abstract_service, code + from abstract_service + order by 3,2 + + + /> + + + Единица измерения: #qDecoration.measure# (#qDecoration.measure_short#) + Точность: #qDecoration.precision#(нет) + +
    +
    + +
    +
    Характеристика
    +
    + + select m.modifier_id, m.modifier + from modifier m + join abstract_service a on (m.modifier_class_id=a.modifier_class_id) + where a.abstract_service_id= + order by m.sort, m.code, m.modifier + + + #qAbstractService.modifier_class# + + + + + + (нет) + +
    +
    + +
    +
    Код варианта услуги
    +
    + #request.skuCode(qDecoration.area_code, qDecoration.code, qDecoration.modifier_code)# +
    +
    + + + + +
    +
    Единица измерения
    +
    + + select measure_id, measure + from measure + order by 2 + + + /> + для композитных услуг (состоящих из компонентов) указывать штуки. Обычно композитные услуги попадают в спецификацию в количестве 1 шт. +
    +
    + +
    +
    Точность
    +
    + + Количество знаков после запятой, 0 - целое число. Переопределяет точность из абстрактной услуги +
    +
    + + + +
    +
    Ответственный
    +
    + + select usr_id, firstname, middlename, lastname + from usr + order by 4,2,3 + + + + + + + + Переопределяет ответственного за абстрактную услугу +
    +
    + +
    +
    Внутренняя
    +
    + checked /> + Предоставляется только внутри компании. Не должна попадать в списки, публикуемые наружу. Не предполагается наличия цены. При снятии отметки станет обычной услугой. +
    +
    + +
    +
    Статус
    +
    + + select status_id, status + from status + order by 1 + + + /> + с + +
    +
    + +
    +
    Ставка НДС
    +
    + % +
    +
    + +
    +
    НДС не облагается
    +
    + checked /> + Если флаг установлен, ставка НДС игнорируется +
    +
    + + +
    +
    Описание
    +
    + +
    +
    + +
    +
    Коммерческие примечания
    +
    + +
    +
    + +
    +
    Создано
    +
    + #dateFormat(d.dt_created,'DD.MM.YYYY')# #timeFormat(d.dt_created,'HH:MM')# + #qDecoration.creator# (#qDecoration.creator_shortname#) +       + Изменено + #dateFormat(d.dt_updated,'DD.MM.YYYY')# #timeFormat(d.dt_updated,'HH:MM')# + #qDecoration.updater# (#qDecoration.updater_shortname#) +
    +
    + +
    + +
    + + + + + + + + + select + sp.service_param_id + ,ac.param_class_id + ,ac.abstract_service_param_class_id + ,ac.is_multiple + ,sp.param_id + ,sp.min_value + ,sp.max_value + ,p.param + ,p.code as param_code + ,p.precision + ,m.measure + ,m.measure_short + ,c.param_class + + ,(select count(*) from service_param_price t where t.service_param_id=sp.service_param_id AND t.pricing_model_id=1) as inst_cnt + ,(select price from service_param_price t where t.service_param_id=sp.service_param_id AND t.pricing_model_id=1 order by service_param_price_id desc limit 1) as prc_inst + ,(select service_param_price_id from service_param_price t where t.service_param_id=sp.service_param_id AND t.pricing_model_id=1 order by service_param_price_id desc limit 1) as prc_inst_id + ,(select status from service_param_price t where t.service_param_id=sp.service_param_id AND t.pricing_model_id=1 order by service_param_price_id desc limit 1) as prc_inst_stat + + ,(select count(*) from service_param_price t where t.service_param_id=sp.service_param_id AND t.pricing_model_id=2) as fix_cnt + ,(select price from service_param_price t where t.service_param_id=sp.service_param_id AND t.pricing_model_id=2 order by service_param_price_id desc limit 1) as prc_fix + ,(select service_param_price_id from service_param_price t where t.service_param_id=sp.service_param_id AND t.pricing_model_id=2 order by service_param_price_id desc limit 1) as prc_fix_id + ,(select status from service_param_price t where t.service_param_id=sp.service_param_id AND t.pricing_model_id=2 order by service_param_price_id desc limit 1) as prc_fix_stat + + ,(select count(*) from service_param_price t where t.service_param_id=sp.service_param_id AND t.pricing_model_id=3) as payg_cnt + ,(select price from service_param_price t where t.service_param_id=sp.service_param_id AND t.pricing_model_id=3 order by service_param_price_id desc limit 1) as prc_payg + ,(select service_param_price_id from service_param_price t where t.service_param_id=sp.service_param_id AND t.pricing_model_id=3 order by service_param_price_id desc limit 1) as prc_payg_id + ,(select status from service_param_price t where t.service_param_id=sp.service_param_id AND t.pricing_model_id=3 order by service_param_price_id desc limit 1) as prc_payg_stat + + from abstract_service_param_class ac + left outer join service_param sp on (ac.abstract_service_param_class_id=sp.abstract_service_param_class_id + AND sp.service_id=) + left outer join param_class c on (ac.param_class_id=c.param_class_id) + left outer join param p on (sp.param_id=p.param_id) + left outer join measure m on (p.measure_id=m.measure_id) + where ac.abstract_service_id= + order by ac.sort, ac.abstract_service_param_class_id, p.sort, p.param + + + + +

    + Компоненты варианта услуги (#qServiceParam.recordCount#), цены без НДС + + + + + + + + + + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    КомпонентВариант компонентаКодЕд.изм.MinMaxЦена инстЦена фиксЦена payg
    + + + + + + + + + + + + + +
    + + + + + +
    +
    +
    + #param_class# + + + + + + + + + + #param# + (основной вариант) + + + (не выбран) + + + + + #request.skuCode(qDecoration.area_code,qDecoration.code,qDecoration.modifier_code,param_code)# + + #measure_short##request.roundSafe(min_value,precision)##request.roundSafe(max_value,precision)# + + (#prc_inst_stat#) + + + #prc_inst# + + по запросу + + + + (#inst_cnt#) + + + (prc_fiх_stat) + + + #prc_fix# + + по запросу + + + + + + + + #prc_payg# + + по запросу + + + + + + + +
    +
    + + + + + + + + + + + + + + select + t.service_price_id + ,t.service_id + ,t.pricing_model_id + ,m.pricing_model + ,m.pricing_model_short + ,t.pricing_period + ,t.rating_period + ,t.price + + ,t.dt_from + ,t.dt_to + ,t.status + ,t.descr + from service_price t + left outer join pricing_model m on (t.pricing_model_id=m.pricing_model_id) + where t.service_id= + order by 1 + + + +

    + Цены услуги без НДС (#qServicePrice.recordCount#) + + + + + цена услуги - это то, что остается, если все компоненты обнулить, или их нет (для атомарной услуги). Если компоненты есть, обычно цена услуги не нужна, стоимость складывается из компонентов +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    IDЦ-обр.Период ценыПериод опросаСтатусСПоЦена GPL без НДС
    + + #service_price_id##pricing_model_short##pricing_period##rating_period##status##dateFormat(dt_from,'DD.MM.YYYY')##dateFormat(dt_to,'DD.MM.YYYY')##request.formatPrice(price)# + +
    + + + + + select f.specification_id, f.specification, + (select count(*) from specification_item_param sip where sip.specification_item_id=si.specification_item_id) as item_param_cnt + from specification_item si + left outer join specification f on (si.specification_id=f.specification_id) + where si.service_id= + + + +

    Используется спецификациями (#qSpecification.recordCount#)

    +
    + + + + + + + + + + + + + + + + + + +
    СпецификацияКомпонентовСумма, ₽
    + + + #specification# + + + #item_param_cnt# + + + under construction +
    + + + + Компоненты доступны после сохранения услуги + +
    + + + + diff --git a/service_clone.cfm b/service_clone.cfm new file mode 100644 index 0000000..4c50665 --- /dev/null +++ b/service_clone.cfm @@ -0,0 +1,347 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + insert into service ( + abstract_service_id,modifier_id,descr,measure_id,precision + --,base_price + ) + select + abstract_service_id + , + ,descr + ,measure_id + ,precision + --,base_price + from service + where service_id=; + + + + select LASTVAL() as new_service_id; + + + + + insert into service_param ( + service_id,abstract_service_param_class_id,param_id,descr + ) + select + + ,abstract_service_param_class_id + ,param_id + ,descr + from service_param + where service_id=; + + + + + + + + + + + + + + + + + + + + + + pageInfo=#pageInfo# + id="#new_service_id#" + status=#pageInfo.status# + trackOut="tr" + idAttributesOut="id" +/> + + + select + a.login as creator, a.shortname as creator_shortname, m.login as updater, m.shortname as updater_shortname + from #pageInfo.entity# e + left outer join usr a on (e.creator_id=a.usr_id) + left outer join usr m on (e.updater_id=m.usr_id) + where e.#pageInfo.key#= + + + + + + Клонирование варианта услуги (конкретной услуги) + + [#d.service_id#] + + + + + + + + + + + + + +
    #status.errorMessage#
    +
    + + + + + + +
    + + +
    +
    Услуга по каталогу (абстрактная)
    +
    + + select abstract_service_id, abstract_service, code + from abstract_service + order by 3,2 + + + /> + +
    +
    + +
    +
    Класс характеристики
    +
    + + select mc.modifier_class_id, mc.modifier_class + from abstract_service a + left outer join modifier_class mc on (a.modifier_class_id=mc.modifier_class_id) + where a.abstract_service_id= + + #qAbstractService.modifier_class# + +
    +
    + +
    +
    Характеристика
    +
    + + select m.modifier_id, m.modifier + from modifier m + join abstract_service a on (m.modifier_class_id=a.modifier_class_id) + where a.abstract_service_id= + order by 2 + + + select m.modifier_id, m.modifier + from modifier m + join abstract_service a on (m.modifier_class_id=a.modifier_class_id) + where a.abstract_service_id= + AND NOT exists (select * from service s where s.modifier_id=m.modifier_id AND s.abstract_service_id=a.abstract_service_id) + order by 2 + limit 1 + + + + Необходимо выбрать новое уникальное значение характеристики, иначе будет ошибка +
    +
    + + + + + + +
    +
    Описание
    +
    + +
    +
    + +
    +
    Создано
    +
    + #dateFormat(d.dt_created,'DD.MM.YYYY')# #timeFormat(d.dt_created,'HH:MM')# + #qDecoration.creator# (#qDecoration.creator_shortname#) +       + Изменено + #dateFormat(d.dt_updated,'DD.MM.YYYY')# #timeFormat(d.dt_updated,'HH:MM')# + #qDecoration.updater# (#qDecoration.updater_shortname#) +
    +
    + +
    + +
    + + + + + + + + + select + sp.service_param_id + ,ac.param_class_id + ,sp.param_id + ,p.param + ,c.param_class + ,(select count(*) from service_param_price spp where spp.service_param_id=sp.service_param_id) as price_count + from service_param sp + left outer join abstract_service_param_class ac on (sp.abstract_service_param_class_id=ac.abstract_service_param_class_id) + left outer join param_class c on (ac.param_class_id=c.param_class_id) + left outer join param p on (sp.param_id=p.param_id) + where sp.service_id= + order by p.param, c.param_class + + + + +

    Компоненты (#qServiceParam.recordCount#) + + + + + + +

    +
    + + + + + + + + + + + + + + + + + + + + + +
    КомпонентВариант компонентаЦен для прайс-листа (вариантов)
    + + + #param_class# + + #param_class# / #param# + + #price_count# + + +
    + +
    + + + + \ No newline at end of file diff --git a/service_del.cfm b/service_del.cfm new file mode 100644 index 0000000..506b3e9 --- /dev/null +++ b/service_del.cfm @@ -0,0 +1,95 @@ + + + + + + + + + + + + + sp.service_param_id + c.param_class + p.param + + service_param sp + left outer join param p on (sp.param_id=p.param_id) + left outer join param_class c on (p.param_class_id=c.param_class_id) + + sp.service_id + 2 + + + + t.service_price_id + + service_price t + + t.service_id + 1 + + + + si.specification_item_id + n.specification + si.specification_item + si.quantity + + specification_item si + left outer join specification n on (si.specification_id=n.specification_id) + + si.service_id + 2,3 + + + + + + + + + + select a.code, a.abstract_service, m.modifier + from service s + join abstract_service a on (s.abstract_service_id=a.abstract_service_id) + left outer join modifier m on (s.modifier_id=m.modifier_id) + where s.service_id= + + + + + + + Удаление конкретной услуги + #qDecoration.code# + #qDecoration.abstract_service# + / #qDecoration.modifier# + [#service_id#] + + +   + + + + +#markup# + + \ No newline at end of file diff --git a/service_filter.cfm b/service_filter.cfm new file mode 100644 index 0000000..623d921 --- /dev/null +++ b/service_filter.cfm @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Развернутый каталог услуг - фильтр + + + + + +
    + +
    +
    +
    + +
    +
    + +
    +
    #i18("Номенклатура","Service")#
    +
    + + #i18("по вхождению подстроки","by substring")# +
    +
    + +
    +
    #i18("Код услуги","Service Code")#
    +
    + + #i18("по вхождению подстроки","by substring")# +
    +
    + +
    +
    #i18("Статус","Status")#
    +
    + + select status_id, status + from status + order by status_id + + + +
    +
    + +
    +
    #i18("Группа каталога","Catalog Group")#
    +
    + + select g.area_id, g.area, g.area_code + from area g + order by g.area_code + + + + +
    + #i18("Код","Code")# + +
    + #i18("Группа","Group")# + +
    + #i18("по вхождению подстроки","by substring")# +
    +
    +
    + +
    + +
    + + + \ No newline at end of file diff --git a/service_ls.cfm b/service_ls.cfm new file mode 100644 index 0000000..bb30b99 --- /dev/null +++ b/service_ls.cfm @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + select + + s.service_id + s.abstract_service_id + a.abstract_service + CONCAT_WS(' - ', a.abstract_service, m.modifier) as service + g.analytic_code + g.area + g.area_code + a.code as abstract_service_code + m.code as modifier_code + c.modifier_class + c.modifier_class_id + m.modifier + m.modifier_id + s.manager_id + u.login + u.firstname + u.middlename + u.lastname + u.email + s.descr + s.commercial_note + s.is_internal + a.status_id + st.status + s.measure_id + n.measure + s.vat_perc + s.vat_free + + (select count(*) from service_param sp where sp.service_id=s.service_id) as param_count + (select count(*) from abstract_service_param_class ac where ac.abstract_service_id=a.abstract_service_id) as abstract_param_count + + from service s + join abstract_service a on (s.abstract_service_id=a.abstract_service_id) + left outer join modifier m on (s.modifier_id=m.modifier_id) + left outer join modifier_class c on (a.modifier_class_id=c.modifier_class_id) + left outer join area g on (a.area_id=g.area_id) + left outer join status st on (s.status_id=st.status_id) + left outer join measure n on (s.measure_id=n.measure_id) + left outer join usr u on (s.manager_id=u.usr_id) + where 1=1 + order by + + + + + + + + +select count(*) as cnt from service where 1=1 + + + + + + + + + + + + + Варианты услуг (список конкретных услуг с характеристиками) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + #analytic_code# #area##request.skuCode(area_code,abstract_service_code,modifier_code)##service##abstract_service##modifier_class##modifier##abstract_param_count##param_count##lastname# #firstname# #middlename##status##measure#Не облагается#vat_perc# + +
    + + #gridFooter# + +
    + \ No newline at end of file diff --git a/service_param.cfm b/service_param.cfm new file mode 100644 index 0000000..e9b56f4 --- /dev/null +++ b/service_param.cfm @@ -0,0 +1,497 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select abstract_service_param_class_id + from param p + join param_class pc on (p.param_class_id=pc.param_class_id) + join abstract_service_param_class ac on (pc.param_class_id=ac.param_class_id) + join abstract_service a on (ac.abstract_service_id=a.abstract_service_id) + join service s on (a.abstract_service_id=s.abstract_service_id) + where param_id= + AND service_id= + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + pageInfo=#pageInfo# + id="#d.service_param_id#" + status=#pageInfo.status# + + idAttributesOut="id" +/> + + + + select + s.service_id + ,a.abstract_service + ,s.abstract_service_id + ,a.code as abstract_service_code + ,a.area_id + ,g.area_code + ,s.modifier_id + ,m.modifier + ,m.code as modifier_code + ,c.modifier_class_id + ,c.modifier_class + from service s + join abstract_service a on (s.abstract_service_id=a.abstract_service_id) + join area g on (a.area_id=g.area_id) + left outer join modifier m on (s.modifier_id=m.modifier_id) + left outer join modifier_class c on (m.modifier_class_id=c.modifier_class_id) + where service_id= + + + + + select p.param_id, p.param, m.measure_id, m.measure, m.measure_short, p.param_class_id, c.param_class, p.code, p.precision + from param p + left outer join measure m on m.measure_id=p.measure_id + left outer join param_class c on p.param_class_id=c.param_class_id + where param_id= + + + + select p.param_class_id, p.param_class, p.precision, m.measure_id, m.measure, m.measure_short, ac.sort + from param_class p + join abstract_service_param_class ac on (p.param_class_id=ac.param_class_id) + left outer join measure m on m.measure_id=p.measure_id + where ac.abstract_service_param_class_id= + + + + select + a.login as creator, a.shortname as creator_shortname, m.login as updater, m.shortname as updater_shortname + from #pageInfo.entity# e + left outer join usr a on (e.creator_id=a.usr_id) + left outer join usr m on (e.updater_id=m.usr_id) + where e.#pageInfo.key#= + + + + + + Вариант компонента + + #qParam.param# [#d.param_id#] + + + #qParamClass.param_class# [#qParamClass.param_class_id#] + + + варианта услуги + + #qService.abstract_service# + + - #qService.modifier# + + + [#qService.service_id#] + + + + + +
    #status.errorMessage#
    +
    + + + + + + + + + + + +
    + + + +
    +
    Характеристика
    + +
    + + + +
    +
    Вариант компонента
    +
    + + + #qParamClass.param_class# + + + + + + + + select p.param_id, p.param, p.param_short, c.param_class, p.code, + (select count(*) from service_param sp where sp.param_id=p.param_id AND sp.service_id= AND sp.param_id<>) as usage_cnt + from param p + join param_class c on (p.param_class_id=c.param_class_id) + join abstract_service_param_class ac on (c.param_class_id=ac.param_class_id) + where 1=1 + AND ac.abstract_service_id= + + AND p.param_class_id= + + + AND p.param_class_id IN (select param_class_id from abstract_service_param_class where abstract_service_param_class_id=) + + order by c.param_class, p.sort, p.param + + + + class="" + + /> + + + + + + + + + + + + + + + + Ед. изм.: + #qParam.measure# (#qParam.measure_short#)(нет) + Точность: + #qParam.precision#(нет). +   + +
    + Варианты компонента, которые уже использованы, недоступны для выбора. + Если вариант компонента не выбран здесь, он выбирается при формировании экземпляра (в спецификации/заявке) +
    +
    + + +
    +
    Полный код
    +
    + + #request.skuCode(qService.area_code,qService.abstract_service_code,qService.modifier_code,qParam.code)# + + (состоит из кодов + группы #qService.area_code#, + абстрактной услуги #qService.abstract_service_code#, + характеристики #qService.modifier_code#0, + варианта компонента #qParam.code#) + +
    +
    + +
    +
    Сортировка
    +
    + #qParamClass.sort# + (определяется для компонента абстрактной услуги) +
    +
    + + + + + + + + + + + + + + + + + + +
    +
    Min
    +
    + + минимальное количество при формировании спецификации/заявки +
    +
    + +
    +
    Max
    +
    + + максимальное количество при формировании спецификации/заявки +
    +
    + +
    +
    Шаг
    +
    + + шаг изменения в интерфейсе пользователя при формировании спецификации/заявки +
    +
    + +
    +
    Описание
    +
    + +
    +
    + +
    +
    Создано
    +
    + #dateFormat(d.dt_created,'DD.MM.YYYY')# #timeFormat(d.dt_created,'HH:MM')# + #qDecoration.creator# (#qDecoration.creator_shortname#) +       + Изменено + #dateFormat(d.dt_updated,'DD.MM.YYYY')# #timeFormat(d.dt_updated,'HH:MM')# + #qDecoration.updater# (#qDecoration.updater_shortname#) +
    +
    + +
    + +
    +
    + + + + + + + + + + + + + + + select + t.service_param_price_id + ,t.service_param_id + ,t.pricing_model_id + ,m.pricing_model + ,m.pricing_model_short + ,t.pricing_period + ,t.rating_period + ,t.price + + ,t.dt_from + ,t.dt_to + ,t.status + ,t.descr + from service_param_price t + left outer join pricing_model m on (t.pricing_model_id=m.pricing_model_id) + where t.service_param_id= + order by 1 + + + +

    + Цены компонента услуги (без НДС) +

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    IDЦ-обр.Период ценыПериод опросаСтатусСПоЦена GPL без НДС
    + + #service_param_price_id##pricing_model_short##pricing_period##rating_period##status##dateFormat(dt_from,'DD.MM.YYYY')##dateFormat(dt_to,'DD.MM.YYYY')##request.formatPrice(price)# + +
    + +
    + + diff --git a/service_param_del.cfm b/service_param_del.cfm new file mode 100644 index 0000000..3988279 --- /dev/null +++ b/service_param_del.cfm @@ -0,0 +1,98 @@ + + + + + + + + + + + + + service_param_price_id + a.code + a.abstract_service + c.modifier_class + m.modifier + pc.param_class + p.param + prm.pricing_model_short + + service_param_price spp + left outer join service_param sp on (spp.service_param_id=sp.service_param_id) + left outer join service s on (sp.service_id=s.service_id) + left outer join abstract_service a on (s.abstract_service_id=a.abstract_service_id) + left outer join area g on (a.area_id=g.area_id) + left outer join modifier m on (s.modifier_id=m.modifier_id) + left outer join modifier_class c on (m.modifier_class_id=c.modifier_class_id) + left outer join param p on (sp.param_id=p.param_id) + left outer join param_class pc on (p.param_class_id=pc.param_class_id) + left outer join pricing_model prm on (spp.pricing_model_id=prm.pricing_model_id) + + spp.service_param_id + 1 desc + + + + + + + + + +select + sp.service_param_id + ,p.code as param_code, p.param + ,a.code, a.abstract_service + ,g.area_code + ,m.code as modifier_code, m.modifier + ,mc.modifier_class + from service_param sp + left outer join param p on (sp.param_id=p.param_id) + left outer join param_class c on (p.param_class_id=c.param_class_id) + left outer join service s on (sp.service_id=s.service_id) + left outer join modifier m on (s.modifier_id=m.modifier_id) + left outer join modifier_class mc on (m.modifier_class_id=mc.modifier_class_id) + left outer join abstract_service a on (s.abstract_service_id=a.abstract_service_id) + left outer join area g on (a.area_id=g.area_id) + where sp.service_param_id= + + + + + + Удаление компонента услуги + + #abstract_service# #modifier# + #param# + #request.skuCode(area_code,code,modifier_code,param_code)# + + [#service_param_id#] + + + +   + + + + +#markup# + + \ No newline at end of file diff --git a/service_param_price.cfm b/service_param_price.cfm new file mode 100644 index 0000000..f173ea8 --- /dev/null +++ b/service_param_price.cfm @@ -0,0 +1,313 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + pageInfo=#pageInfo# + id="#d.service_param_price_id#" + status=#pageInfo.status# + trackOut="tr" + idAttributesOut="id" +/> + + + + + + select + sp.service_param_id, sp.service_id, sp.param_id, ac.abstract_service_param_class_id + ,p.param_id, p.param_class_id, p.param, p.param_short, p.code as param_code + ,pc.param_class + ,m.measure_id, m.measure , m.measure_short + ,s.service_id + ,a.abstract_service_id, a.abstract_service, a.code as abstract_service_code + ,g.area_code + ,sm.modifier_id, sm.modifier, sm.code as modifier_code + from service_param sp + left outer join abstract_service_param_class ac on sp.abstract_service_param_class_id=ac.abstract_service_param_class_id + left outer join param p on sp.param_id=p.param_id + --left outer join param_class pc on ac.param_class_id=pc.param_class_id + left outer join param_class pc on p.param_class_id=pc.param_class_id + left outer join service s on sp.service_id=s.service_id + left outer join abstract_service a on s.abstract_service_id=a.abstract_service_id /*** can be obtained also from abstract_service_param_class*/ + left outer join area g on a.area_id=g.area_id + left outer join modifier sm on s.modifier_id=sm.modifier_id + left outer join measure m on pc.measure_id=m.measure_id /*** we can override measure from param_class in param*/ + where sp.service_param_id= + + + + select + a.login as creator, a.shortname as creator_shortname, m.login as updater, m.shortname as updater_shortname + from #pageInfo.entity# e + left outer join usr a on (e.creator_id=a.usr_id) + left outer join usr m on (e.updater_id=m.usr_id) + where e.#pageInfo.key#= + + + + + + Цена компонента + #qServiceParam.abstract_service# + [#qServiceParam.abstract_service_id#] + #qServiceParam.modifier#(основной вариант) + [#qServiceParam.service_id#] + : + #qServiceParam.param_class# + [#qServiceParam.param_class_id#] + #qServiceParam.param#(основной вариант) + [#qServiceParam.param_id#] + #request.skuCode(qServiceParam.area_code,qServiceParam.abstract_service_code, + qServiceParam.modifier_code,qServiceParam.param_code)# + + [#d.service_param_price_id#] + + + + + + +
    #status.errorMessage#
    +
    + + + + + + + +
    + + + + + +
    +
    Единица измерения
    +
    + #qServiceParam.measure# (#qServiceParam.measure_short#) +
    +
    + +
    +
    Модель ценообразования
    +
    + +
    +
    + +
    +
    Период цены
    +
    + + за какое время указана цена +
    +
    + +
    +
    Период опроса
    +
    + + с какой периодичностью собирается тарифицируемая метрика +
    +
    + +
    +
    Цена GPL
    +
    + + публичная цена без скидки, без НДС +
    +
    + +
    +
    Минимальная цена
    +
    + + ценовое дно, предел скидки - как правило, равна себестоимости, но может быть и ниже. Без НДС +
    +
    + +
    +
    Себестоимость
    +
    + + ведется для справки и для контроля. Без НДС +
    +
    + + + +
    +
    Статус
    +
    + + *** правила переходов +
    +
    + +
    +
    Действует с
    +
    + + +
    +
    + +
    +
    Действует по
    +
    + + +
    +
    + +
    +
    Описание
    +
    + +
    +
    + +
    +
    Создано
    +
    + #dateFormat(d.dt_created,'DD.MM.YYYY')# #timeFormat(d.dt_created,'HH:MM')# + #qDecoration.creator# (#qDecoration.creator_shortname#) +       + Изменено + #dateFormat(d.dt_updated,'DD.MM.YYYY')# #timeFormat(d.dt_updated,'HH:MM')# + #qDecoration.updater# (#qDecoration.updater_shortname#) +
    +
    + +
    + +
    + + + + + \ No newline at end of file diff --git a/service_param_price_del.cfm b/service_param_price_del.cfm new file mode 100644 index 0000000..97b6703 --- /dev/null +++ b/service_param_price_del.cfm @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + select t.service_param_price_id, t.price, t.cost, t.min_price, t.status, t.dt_from, t.dt_to + ,g.area_code, a.code, a.abstract_service + ,m.modifier, m.code as modifier_code, mc.modifier_class + ,p.param, p.code as param_code + from service_param_price t + left outer join service_param sp on (t.service_param_id=sp.service_param_id) + left outer join service s on (sp.service_id=s.service_id) + left outer join abstract_service a on (s.abstract_service_id=a.abstract_service_id) + left outer join area g on (a.area_id=g.area_id) + left outer join modifier m on (s.modifier_id=m.modifier_id) + left outer join modifier_class mc on (m.modifier_class_id=mc.modifier_class_id) + left outer join param p on (sp.param_id=p.param_id) + + where t.service_param_price_id= + + + + + + + Удаление цены компонента + #request.skuCode(area_code,code,modifier_code,param_code)# + #abstract_service# + #modifier# + #param# + с #dateFormat(dt_from,"DD.MM.YYYY")# + по #dateFormat(dt_to,"DD.MM.YYYY")# + #price# + [#service_param_price_id#] + + +   + + + + +#markup# + + \ No newline at end of file diff --git a/service_price.cfm b/service_price.cfm new file mode 100644 index 0000000..3f8924c --- /dev/null +++ b/service_price.cfm @@ -0,0 +1,279 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + pageInfo=#pageInfo# + id="#d.service_price_id#" + status=#pageInfo.status# + trackOut="tr" + idAttributesOut="id" +/> + + + + + + + + + + + select + s.service_id + ,a.abstract_service_id, a.abstract_service, a.code as abstract_service_code + ,g.area_code + ,m.modifier, m.code as modifier_code + ,u.measure_id, u.measure, u.measure_short + from service s + left outer join abstract_service a on s.abstract_service_id=a.abstract_service_id + left outer join area g on a.area_id=g.area_id + left outer join modifier m on s.modifier_id=m.modifier_id + left outer join measure u on u.measure_id=s.measure_id + where s.service_id= + + + + select + a.login as creator, a.shortname as creator_shortname, m.login as updater, m.shortname as updater_shortname + from #pageInfo.entity# e + left outer join usr a on (e.creator_id=a.usr_id) + left outer join usr m on (e.updater_id=m.usr_id) + where e.#pageInfo.key#= + + + + + + Цена услуги + #request.skuCode(qService.area_code, qService.abstract_service_code, qService.modifier_code)# + #qService.abstract_service# #qService.modifier# + [#d.service_price_id#] + + + + + +
    #status.errorMessage#
    +
    + + + + + + + +
    + + + +
    +
    Модель ценообразования
    +
    + +
    +
    + +
    +
    Период цены
    +
    + + за какое время указана цена. Для фиксированной оплаты обычно месяц +
    +
    + +
    +
    Период опроса
    +
    + + с какой периодичностью собирается тарифицируемая метрика. Для фиксированной оплаты не указывать +
    +
    + +
    +
    Единица измерения
    +
    + #qService.measure# (#qService.measure_short#) +
    +
    + +
    +
    Цена GPL
    +
    + + публичная цена без скидки, без НДС +
    +
    + +
    +
    Минимальная цена
    +
    + + ценовое дно, предел скидки - как правило, равна себестоимости, но может быть и ниже. Без НДС +
    +
    + +
    +
    Себестоимость
    +
    + + ведется для справки и для контроля. Без НДС +
    +
    + + + +
    +
    Статус
    +
    + + *** реализовать правила переходов +
    +
    + +
    +
    Действует с
    +
    + + +
    +
    + +
    +
    Действует по
    +
    + + +
    +
    + +
    +
    Описание
    +
    + +
    +
    + +
    +
    Создано
    +
    + #dateFormat(d.dt_created,'DD.MM.YYYY')# #timeFormat(d.dt_created,'HH:MM')# + #qDecoration.creator# (#qDecoration.creator_shortname#) +       + Изменено + #dateFormat(d.dt_updated,'DD.MM.YYYY')# #timeFormat(d.dt_updated,'HH:MM')# + #qDecoration.updater# (#qDecoration.updater_shortname#) +
    +
    +
    + +
    + + +Это цена услуги, не включая компоненты. Если компоненты есть, их суммарная стоимость (количество по каждому компоненту, умноженное на цену этого компонента) добавляется к цене услуги. Если для всех компонентов количество 0, то останется только цена услуги. Если в спецификации количество для данной услуги больше 1, то полученная сумма будет умножена на количество по данной услуге. Если стоимость, как для большинства композитных услуг, формируется только из компонентов, цена самой услуги равна нулю или (что правильнее) отсутствует в прайс-листе. + + \ No newline at end of file diff --git a/service_price_del.cfm b/service_price_del.cfm new file mode 100644 index 0000000..9504f24 --- /dev/null +++ b/service_price_del.cfm @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + select t.service_price_id, t.price, t.cost, t.min_price, t.status, t.dt_from, t.dt_to + ,g.area_code, a.code, a.abstract_service + ,m.modifier, m.code as modifier_code, mc.modifier_class + from service_price t + left outer join service s on (t.service_id=s.service_id) + left outer join abstract_service a on (s.abstract_service_id=a.abstract_service_id) + left outer join area g on (a.area_id=g.area_id) + left outer join modifier m on (s.modifier_id=m.modifier_id) + left outer join modifier_class mc on (m.modifier_class_id=mc.modifier_class_id) + + where t.service_price_id= + + + + + + + + Удаление цены услуги + #request.skuCode(area_code,code,modifier_code)# + #abstract_service# + #modifier# + с #dateFormat(dt_from,"DD.MM.YYYY")# + по #dateFormat(dt_to,"DD.MM.YYYY")# + #price# + [#service_price_id#] + + +   + + + + +#markup# + + \ No newline at end of file diff --git a/site.cfm b/site.cfm new file mode 100644 index 0000000..aa618d7 --- /dev/null +++ b/site.cfm @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + pageInfo=#pageInfo# + id="#d.site_id#" + status=#pageInfo.status# + trackOut="tr" + idAttributesOut="id" +/> + + + + select + a.login as creator, a.shortname as creator_shortname, m.login as updater, m.shortname as updater_shortname + from #pageInfo.entity# e + left outer join usr a on (e.creator_id=a.usr_id) + left outer join usr m on (e.updater_id=m.usr_id) + where e.#pageInfo.key#= + + + + + + + Площадка + + #d.site# + [#d.site_id#] + + + + + + +
    #status.errorMessage#
    +
    + + + + + + +
    + + +
    +
    ID
    +
    + #d.site_id# +
    +
    + +
    +
    Площадка (RUS)
    +
    + +
    +
    + +
    +
    Площадка (ENG)
    +
    + +
    +
    + + +
    +
    Описание
    +
    + +
    +
    + +
    +
    Создано
    +
    + #dateFormat(d.dt_created,'DD.MM.YYYY')# #timeFormat(d.dt_created,'HH:MM')# + #qDecoration.creator# (#qDecoration.creator_shortname#) +       + Изменено + #dateFormat(d.dt_updated,'DD.MM.YYYY')# #timeFormat(d.dt_updated,'HH:MM')# + #qDecoration.updater# (#qDecoration.updater_shortname#) +
    +
    + +
    + +
    + + + + \ No newline at end of file diff --git a/site_ls.cfm b/site_ls.cfm new file mode 100644 index 0000000..a548557 --- /dev/null +++ b/site_ls.cfm @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + select + + m.site_id + m.site + m.site_en + + from site m + where 1=1 + order by + + + + + + + + + +select count(*) as cnt from site where 1=1 + + + + + + + + + + + + Площадки + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + #site_id##site##site_en#
    + + #gridFooter# + +
    + \ No newline at end of file diff --git a/specification.cfm b/specification.cfm new file mode 100644 index 0000000..7d2d518 --- /dev/null +++ b/specification.cfm @@ -0,0 +1,207 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + pageInfo=#pageInfo# + id="#d.specification_id#" + status=#pageInfo.status# + trackOut="tr" + idAttributesOut="id" +/> + + + + select + a.login as creator, a.shortname as creator_shortname, m.login as updater, m.shortname as updater_shortname + from #pageInfo.entity# e + left outer join usr a on (e.creator_id=a.usr_id) + left outer join usr m on (e.updater_id=m.usr_id) + where e.#pageInfo.key#= + + + + select d.contract_id, d.contract, d.dt_contract, c.contragent_id, c.contragent + from contract d + left outer join contragent c on (d.contragent_id=c.contragent_id) + where d.contract_id= + + + + + + Спецификация + + #d.specification# + [#d.specification_id#] + + + + + + +
    #status.errorMessage#
    +
    + + + + + + +
    + + +
    +
    Спецификация (номер)
    +
    + +
    +
    + +
    +
    Договор
    +
    + + select c.contract_id, c.contract, c.dt_contract + from contract c + order by 1 + + + /> + + + +
    +
    + + +
    +
    Описание
    +
    + +
    +
    + +
    +
    Создано
    +
    + #dateFormat(d.dt_created,'DD.MM.YYYY')# #timeFormat(d.dt_created,'HH:MM')# + #qDecoration.creator# (#qDecoration.creator_shortname#) +       + Изменено + #dateFormat(d.dt_updated,'DD.MM.YYYY')# #timeFormat(d.dt_updated,'HH:MM')# + #qDecoration.updater# (#qDecoration.updater_shortname#) +
    +
    + +
    + +
    + + + + + + select + i.specification_item_uid + ,s.svc_id + ,s.svc + ,s.code + + + ,(select count(*) from specification_item_version siv where siv.specification_item_uid=i.specification_item_uid) as item_version_count + from specification_item i + left outer join svc s on (i.svc_id=s.svc_id) + where i.specification_id= + order by 1 + + + +

    + Строки спецификации (#qItem.recordCount#) + + + + + + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + +
    Ключ строкиУслугаКод услуги
    + + #specification_item_uid##svc##quantity##price##item_version_count# + +
    + +
    + + + diff --git a/specification_del.cfm b/specification_del.cfm new file mode 100644 index 0000000..c3b3953 --- /dev/null +++ b/specification_del.cfm @@ -0,0 +1,68 @@ + + + + + + + + + + + + + si.specification_item_id + n.specification + si.specification_item + si.quantity + + specification_item si + left outer join specification n on (si.specification_id=n.specification_id) + + si.specification_id + 2,3 + + + + + + + + + + select + n.specification + from specification n + where n.specification_id= + + + + + + + Удаление спецификации + #qDecoration.specification# + [#specification_id#] + + +   + + +#markup# + + \ No newline at end of file diff --git a/specification_filter.cfm b/specification_filter.cfm new file mode 100644 index 0000000..6c24189 --- /dev/null +++ b/specification_filter.cfm @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + Спецификации - фильтр + +
    +
    +
    +
    +
    +
    +
    +
    +Under Construction +
    + + diff --git a/specification_item.cfm b/specification_item.cfm new file mode 100644 index 0000000..acbc142 --- /dev/null +++ b/specification_item.cfm @@ -0,0 +1,219 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + pageInfo=#pageInfo# + id="#d.specification_item_uid#" + status=#pageInfo.status# + trackOut="tr" + idAttributesOut="id" +/> + + + select s.specification_id, s.specification + from specification s + where s.specification_id= + + + + select s.svc, s.code + from svc s + where s.svc_id= + + + + + + select + a.login as creator, a.shortname as creator_shortname, m.login as updater, m.shortname as updater_shortname + from specification_item e + left outer join usr a on (e.creator_id=a.usr_id) + left outer join usr m on (e.updater_id=m.usr_id) + where e.specification_item_uid= + + + + + + Строка спецификации (экземпляр услуги) + + [#d.specification_item_uid#] + + + + + + +
    #status.errorMessage#
    +
    + + + + + + + +
    + + +
    +
    Спецификация (номер)
    + +
    + +
    +
    Услуга
    +
    + + select s.svc_id, s.svc, s.code + from svc s + order by 2 + + + + + + +
    +
    + + + +
    +
    Создано
    +
    + #dateFormat(d.dt_created,'DD.MM.YYYY')# #timeFormat(d.dt_created,'HH:MM')# + #qDecoration.creator# (#qDecoration.creator_shortname#) +       + Изменено + #dateFormat(d.dt_updated,'DD.MM.YYYY')# #timeFormat(d.dt_updated,'HH:MM')# + #qDecoration.updater# (#qDecoration.updater_shortname#) +
    +
    +
    + +
    + + + + + + select + siv.price + ,siv.quantity + ,siv.specification_item_version + ,siv.agreement_version + ,siv.dt_from + ,siv.dt_to + ,a.contract_id + ,a.agreement + ,a.dt_agreement + ,a.is_actual + from specification_item_version siv + join specification_item i on (siv.specification_item_uid=i.specification_item_uid) + join specification s on (i.specification_id=s.specification_id) + join contract d on (s.contract_id=d.contract_id) + join agreement a on (siv.agreement_version=a.agreement_version AND s.contract_id=a.contract_id) + where siv.specification_item_uid= + order by siv.agreement_version desc + + + +

    + Версии (#qSpecificationItemVersion.recordCount#) + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    ВерсияДопникДата сДата поУслуга (для печати)КоличествоЦена
    + + + + #agreement_version##agreement#< + #quantity# + #price# + + + +
    + +
    + + diff --git a/specification_item_del.cfm b/specification_item_del.cfm new file mode 100644 index 0000000..3b07e21 --- /dev/null +++ b/specification_item_del.cfm @@ -0,0 +1,77 @@ + + + + + + + + + + + + + specification_item_param_id + c.param_class + coalesce(p.param, p1.param) as param + sip.quantity + + specification_item_param sip + left outer join service_param sp on (sip.service_param_id=sp.service_param_id) + left outer join param p on sp.param_id=p.param_id + left outer join param_class c on p.param_class_id=c.param_class_id + left outer join param p1 on sp.param_id=p1.param_id + + specification_item_id + 1 + + + + + + + + + + select + si.specification_item, + n.specification + from specification_item si + join specification n on (si.specification_id=n.specification_id) + where si.specification_item_id= + + + + + + + Удаление строки спецификации + #qDecoration.specification# + #qDecoration.specification_item# + [#specification_item_id#] + + + +   + + + + +#markup# + + \ No newline at end of file diff --git a/specification_item_param.cfm b/specification_item_param.cfm new file mode 100644 index 0000000..8a94dd9 --- /dev/null +++ b/specification_item_param.cfm @@ -0,0 +1,350 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + pageInfo=#pageInfo# + id="#d.specification_item_param_id#" + status=#pageInfo.status# + trackOut="tr" + idAttributesOut="id" +/> + + + + + select sp.param_id, sp.service_id, sp.service_param_id, ac.param_class_id + ,p.param, p.param_short, p.precision, spp.min_price, c.param_class, u.measure_short + ,g.area_code, a.code as abstract_service_code, m.code as modifier_code, p.code as param_code + from service_param sp + left outer join service s on (sp.service_id=s.service_id) + left outer join abstract_service a on (s.abstract_service_id=a.abstract_service_id) + left outer join abstract_service_param_class ac on (sp.abstract_service_param_class_id=ac.abstract_service_param_class_id) + left outer join area g on a.area_id=g.area_id + left outer join modifier m on (s.modifier_id=m.modifier_id) + left outer join param p on (sp.param_id=p.param_id) + left outer join measure u on (p.measure_id=u.measure_id) + left outer join param_class c on (ac.param_class_id=c.param_class_id) + left outer join service_param_price spp on (sp.service_param_id=spp.service_param_id) + where sp.service_param_id= + + + + + select f.specification_id, f.specification, + a.code as abstract_service_code, a.abstract_service_id, a.abstract_service, + s.service_id, + m.modifier_id, m.modifier, m.code as modifier_code + from specification_item si + left outer join service s on (si.service_id=s.service_id) + left outer join abstract_service a on (s.abstract_service_id=a.abstract_service_id) + left outer join specification f on (si.specification_id=f.specification_id) + left outer join modifier m on (s.modifier_id=m.modifier_id) + where si.specification_item_id= + + + + + + + + select sp.param_id, c.param_class, p.param, p.param_short, p.precision, + spp.min_price, spp.service_param_price_id, + a.code as abstract_service_code, a.abstract_service, m.modifier, n.specification, + g.area_code, + m.code as modifier_code, p.code as param_code + ,au.login as creator, au.shortname as creator_shortname, mu.login as updater, mu.shortname as updater_shortname + from specification_item_param sip + left outer join service_param sp on (sip.service_param_id=sp.service_param_id) + left outer join abstract_service_param_class ac on (sp.abstract_service_param_class_id=ac.abstract_service_param_class_id) + -- варианты + -- вариант компонента задан в шаблоне, тогда он не должен быть задан в экземпляре, и в шаблоне не должен быть задан класс (компонент) + -- в шалоне задан компонент, тогда в экземпляре должен быть задан его вариант + -- запрещенные комбинации: + -- в шаблоне задан класс, но в экземпляре не задан вариант компонента + -- в шаблоне задан класс, но в экземпляре задан член другого класса + -- в шаблоне задан вариант компонента (не задан класс, это контролируется ограничением), но в экземпляре тоже задан компонент + -- ... + left outer join param p on (sp.param_id=p.param_id) -- *** выглядит неэффективно. Также создаст ошибку при -1 в sip.param_id + left outer join param_class c on (ac.param_class_id=c.param_class_id) -- это конкретная запись экземпляра, + -- поэтому вариант компонента всегда известен, и класс берем от него, + -- не нужно задумываться, какой класс определен в шаблоне + left outer join service_param_price spp on /***/ + (sp.service_param_id=spp.service_param_id) -- параллельные сущности со specification_item_param + left outer join service s on (sp.service_id=s.service_id) + left outer join abstract_service a on (s.abstract_service_id=a.abstract_service_id) + left outer join area g on (a.area_id=g.area_id) + + left outer join specification_item si on (sip.specification_item_id=si.specification_item_id) + left outer join specification n on (si.specification_id=n.specification_id) + + left outer join modifier m on (s.modifier_id=m.modifier_id) + + left outer join usr au on (sip.creator_id=au.usr_id) + left outer join usr mu on (sip.updater_id=mu.usr_id) + + where sip.specification_item_param_id= + + + + + + + + + + Вариант компонента #qDecoration.param_class#/#qDecoration.param# + экземпляра услуги + + #qDecoration.abstract_service_code# #qDecoration.abstract_service# + / #qDecoration.modifier# + + (#qDecoration.specification#) + + + [#d.specification_item_param_id#] + + + + + + +
    #status.errorMessage#
    +
    + + + + + + + + +
    + + + + + + + + + *** + + +
    +
    Спецификация
    + +
    + + + + +
    +
    Компонент
    + +
    + + + + + + *** + + + + select p.param, p.precision, m.measure_short + from param p + left outer join param_class c on (p.param_class_id=c.param_class_id) + left outer join measure m on (coalesce(p.measure_id,c.measure_id)=m.measure_id) + where p.param_id= + + + #qParam.param# + + + + +++ + + + select p.param_id, p.param, c.param_class, m.measure_short + from param p + join param_class c on (p.param_class_id=c.param_class_id) + left outer join measure m on (coalesce(p.measure_id, c.measure_id)=m.measure_id) + where p.param_class_id= + order by 3,2 + + + + + + + + + здесь выбирается вариант компонента. Если вариантов нет, создавать единственный вариант не нужно + + + + + + (из шаблона - варианта услуги) + +
    + ---> + +
    +
    Количество
    +
    + + #qServiceParam.measure_short# + (для оплаты по потреблению заполняется при биллинге) +
    +
    + +
    +
    Цена без НДС
    +
    + ₽ +   +   +   + + Базовая цена без НДС: + + #qDecoration.min_price# ₽не задана + + +
    +
    + +
    +
    Создано
    +
    + #dateFormat(d.dt_created,'DD.MM.YYYY')# #timeFormat(d.dt_created,'HH:MM')# + #qDecoration.creator# (#qDecoration.creator_shortname#) +       + Изменено + #dateFormat(d.dt_updated,'DD.MM.YYYY')# #timeFormat(d.dt_updated,'HH:MM')# + #qDecoration.updater# (#qDecoration.updater_shortname#) +
    +
    + + + +
    + + + + + diff --git a/specification_item_param_del.cfm b/specification_item_param_del.cfm new file mode 100644 index 0000000..47f0c67 --- /dev/null +++ b/specification_item_param_del.cfm @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + select + a.login as creator, a.shortname as creator_shortname, m.login as updater, m.shortname as updater_shortname + from #pageInfo.entity# e + left outer join usr a on (e.creator_id=a.usr_id) + left outer join usr m on (e.updater_id=m.usr_id) + where e.#pageInfo.key#= + + + + + + Удаление варианта компонента экземпляра услуги + + [#specification_item_param_id#] + + + +   + + + + +#markup# + + \ No newline at end of file diff --git a/specification_item_version.cfm b/specification_item_version.cfm new file mode 100644 index 0000000..7768d66 --- /dev/null +++ b/specification_item_version.cfm @@ -0,0 +1,292 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + pageInfo=#pageInfo# + id="#d.specification_item_uid#" + status=#pageInfo.status# + trackOut="tr" + idAttributesOut="id" +/> + + + select s.specification_id, s.specification + from specification s + where s.specification_id= + + + + select s.svc, s.code, s.measure_id + from svc s + where s.svc_id= + + + + + + + + + + + select + a.login as creator, a.shortname as creator_shortname, m.login as updater, m.shortname as updater_shortname + from specification_item e + left outer join usr a on (e.creator_id=a.usr_id) + left outer join usr m on (e.updater_id=m.usr_id) + where e.specification_item_uid= + + + + + + Строка спецификации (экземпляр услуги) + + [#d.specification_item_uid#] + + + + + + +
    #status.errorMessage#
    +
    + + + + + + + +
    + + +
    +
    Спецификация (номер)
    + +
    + +
    +
    Услуга
    +
    + + select s.svc_id, s.code + from svc s + order by 2 + + + + + + +
    +
    + + + + + + + + + + + +
    + ---> + +
    +
    Количество
    +
    + +
    +
    + +
    +
    Стоимость
    +
    + + подставить сумму по позициям: + #qCost.cost# +
    +
    + +
    +
    Создано
    +
    + #dateFormat(d.dt_created,'DD.MM.YYYY')# #timeFormat(d.dt_created,'HH:MM')# + #qDecoration.creator# (#qDecoration.creator_shortname#) +       + Изменено + #dateFormat(d.dt_updated,'DD.MM.YYYY')# #timeFormat(d.dt_updated,'HH:MM')# + #qDecoration.updater# (#qDecoration.updater_shortname#) +
    +
    + + +
    + + + + + +

    + Компоненты (#qSpecificationItemParam.recordCount#) + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    Вариант компонентаКодКоличествоЕд.изм.Базовая ценаЦена
    + + + + + + + + + + + + #param_class# #param# + + #qService.abstract_service_code#.#qService.modifier_code#.#code# + #round(quantity,precision)# + #measure_short##min_price##price# + + + +
    + +
    +*** Можно переделать на прямой ввод в форму. Можно однородные позиции выбирать из списка, но тогда вариант выбрать 2 разных интерфейсно непонятно как реализовывать. +поскольку спека только для демонстрации, может этого и не делать? +Цену базовую показать + + + diff --git a/specification_ls.cfm b/specification_ls.cfm new file mode 100644 index 0000000..cb1633b --- /dev/null +++ b/specification_ls.cfm @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + select + + s.specification_id + s.specification + (select count(*) from specification_item i where i.specification_id=s.specification_id) as item_count + + from specification s + where 1=1 + order by + + + + +select count(*) as cnt from specification where 1=1 + + + + + + + + + + + + Спецификации + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + #specification##item_count# + +
    + + #gridFooter# + + + + \ No newline at end of file diff --git a/style/web.css b/style/web.css new file mode 100644 index 0000000..3463337 --- /dev/null +++ b/style/web.css @@ -0,0 +1,321 @@ +/*common elements*/ +html, body { + margin: 0; + padding: 0; + border: none; + height: 100%; +} +body, table, tr, td, th, input, select, textarea, button, form, ul, li, p { + font-size: 11px; + font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; + color:black; +} +form {margin: 0;padding:0;} +p {margin: 0.5em;} +table {border-collapse: collapse;} +img {border: none; margin: 0; vertical-align: middle;} +a, a:link, a:visited {color: #111111; text-decoration: underline;} +a:hover {color: #ff7600; text-decoration: underline;} + + +/* form elements */ +input {color: black; padding: 0 0.3em; } +input:read-only {color:#555; background-color:#f0f0f0;} +input:disabled {color:#555; background-color:#f0f0f0;} +select:disabled {color:#555;} +select option[disabled] { color:#ddd;} + +.detail .td input[type="text"]:disabled {border:1px solid #aaa; color:#555;} +.textbox-disabled {display:inline-block; border: 1px solid #aaa; color:#555; background-color:#f0f0f0; padding:.1em;} + +/*layout*/ + +div.vspacer {height:5px;} + +ul#mainmenu { + list-style-type:none; + padding:0; + margin:0; + display:block; + width:100%; +} +ul#mainmenu li { + text-align:right; + vertical-align:baseline; + padding:.2em 15px .2em 0 ; + margin:.3em 0; + background: url('../img/sarrow.gif') center right no-repeat; + font-size:120%; + font-weight:normal; + font-family: Verdana, Tahoma, Arial, Helvetica, sans-serif; + line-height: 1.1em; +} +ul#mainmenu li a{/*display:block;*/color:#cde;text-decoration:none;} +ul#mainmenu li a:hover{text-decoration:underline;} +ul#mainmenu li.selected {color: /*#4682b4;*/ #fa6 /*#00f*/;} +ul#mainmenu li.menu-item-ext {background: url('../img/external.gif') center right no-repeat;} +ul#mainmenu li.menu-item-noaction {background: none; color: #777;} +ul#mainmenu li.menu-title { + color: #111; + background:none white; + margin:.5em 0 0 0; + /*font-weight: bold;*/ + /*border:1px solid #ccc;*/ +} + +.page {display:table; table-layout: fixed; width:100%; height:100%;} + +.page-main {display:table-row; height:100%;} + +.page-footer {display:table-row; height:1px;} + +.menu {display:table-cell; width:150px; padding:0 0 0 .5em; background-color: #012; -border:1px solid red;} + +.content {display:table-cell; height:100%; vertical-align:top; padding: 3px;} + +.header {display:block; /*background:url('../img/portlet_dot.gif') center left no-repeat; padding-left:33px;*/ line-height: 21px; font-family: Verdana, Tahoma, sans-serif;} + +.control-bar {display:table; width:100%; color:/*#559*/white; /*border:1px solid #ccc;*/ height:19px; } +.header .control-bar a:link, .header .control-bar a:visited {color:white; padding: .2em .5em;} +.header .control-bar a:hover {background:white;color:#f90; padding: .2em .5em;} + +.title {display:table-cell; padding:1px 12px; vertical-align:middle; font-size:110%; background-color:#aaa/*#ccc*//*rgb(117,147,156)*/; /*color:#fa6;*/ border: 1px solid #bbb; border-right:none;} +.title b {color:#026;} + +.main-controls {display:table-cell; padding:0 7px; text-align:right; vertical-align: middle; background-color:#aaa/*rgb(117,147,156)*/; border: 1px solid #bbb; border-left:none;} + +.footer {height:21px; line-height: 21px; background-color:#e0e0e0; border:1px solid #bbb; text-align: right; vertical-align: middle; padding:0 3px;} + + +.table {display:table;} +.tr {display:table-row;} +.td, .th {display:table-cell; padding: 0 0.5em; vertical-align:top;} + + +.detail { + display:table; + width:100%; + margin: 3px 0; + border:1px solid #ddd; + border-collapse: collapse; +} +.detail .tr{ + line-height: 1.5em; +} +.detail .th { + display:table-cell; + text-align:right; + background-color:#e0e0e0; + padding:0.35em 0.5em; + border:none; + /*color: #5f5f5f;*/ + font-weight:normal; + vertical-align:top; + /*border:1px solid red;*/ +} +.detail .td { + display:table-cell; + background-color:#e7e7e7; + padding:0.2em 0.5em; + border:1px solid #ddd; + vertical-align:baseline; +} +.detail .td input, .detail .td select, .detail .td img, .detail .td button, .detail .td div, .detail .td span { + vertical-align: baseline; + margin: 0 0.3em; +} + +.detail .td label { + vertical-align: baseline; + margin: 0 0.3em 0 0; + line-height:normal; +} + +.detail .td input[type="checkbox"] { + vertical-align: top; margin: 0 0 0 0.3em; +} + +/*.detail .td input[type="text"] { + width: 97%; +}*/ + +.detail .td textarea { + color: black; + width: 97%; + margin-left: 0.2em; + padding: 0.2em 0.5em; +} +/***hack*/ +.detail .td a img {vertical-align:text-bottom;} + +.filter {background-color: #f7f7f7;} +.disabled, tr.disabled td, tr.disabled th {color: #888;} +.plate {background-color:#f0f0f0; padding:.1em; border:1px solid #ddd;} + +button, .button, .content a.button:link { + background: #fafafa; + -background: -webkit-linear-gradient(top, #fafafa 0%, #f4f4f4 40%,#e5e5e5 100%); + background:-webkit-linear-gradient(top, #dde 0%, #cde 40%,#bcd 100%); + border: 1px solid #aad; + padding: 1px 10px; + color: #black; + border-radius: 3px; + box-shadow: 0 1px 1px #ddd; + } + +button:disabled, .button:disabled, .maincontrol:disabled { + background: #fafafa; + background: -webkit-linear-gradient(top, #fafafa 0%,#f4f4f4 40%,#e5e5e5 100%); + border-color: #aaa; + color: #999; + box-shadow: none; +} + +button:not(:disabled):hover, +.button:not(:disabled):hover, +.maincontrol:not(:disabled):hover +{ + background: #fefefe; + background: -webkit-linear-gradient(top, #fefefe 0%,#f8f8f8 40%,#e9e9e9 100%); + box-shadow: 0 1px 3px rgba(7, 7, 7, 0.35); + border: 1px solid #aaa; + color: #ff7600; +} + +button:not(:disabled):active, .button:not(:disabled):active { + background: #f4f4f4; + background: -webkit-linear-gradient(top, #f4f4f4 0%,#efefef 40%,#dcdcdc 100%); + box-shadow: inset 0 1px 3px rgba(7, 7, 7, 0.35); +} + +button.maincontrol { + /*background-color:#c3c82f; + background:-webkit-linear-gradient(top, #cd6 0%, #cd6 40%,#bc5 100%);*/ + -background-color:#6fa0f0; + background-color:#6fa0f0; + background:-webkit-linear-gradient(top, #dde 0%, #cde 40%,#bcd 100%); + color: black; +} + +button.maincontrol:hover { + +} + + +/*не совсем аккуратно, при нажатии выглядит чуть иначе, чем кнопка*/ +.content button a, .content button a:link, .content button a:visited {color: #790; text-decoration:none; cursor:default;} +.content button:hover a, .content button:active {color: #ff7600; text-decoration:none; cursor:default;} +.content button.maincontrol a, .content button.maincontrol a:link,.content button.maincontrol a:visited {color: black;} +.content button.maincontrol:hover a, .content button.maincontrol:active a {color: #ff7600;} + +.submitnew { + background-image:url('../img/new.gif'); + width:13px; height:13px; border:none; padding:0; color:transparent; cursor:pointer; +} +.submitsave { + background-image:url('../img/save.gif'); + width:14px; height:14px; border:none; padding:0; color:transparent; cursor:pointer; +} +.submitdel { + background-image:url('../img/del.gif'); + width:13px; height:13px; border:none; padding:0; color:transparent; cursor:pointer; +} +.submitminus { + background-image:url('../img/minus.gif'); + width:13px; height:13px; border:none; padding:0; color:transparent; cursor:pointer; +} + +.content a, .content a:link, .content a:visited {color: #1111ee; text-decoration: none;} +.content a:hover {color: #ff7600; text-decoration: underline;} +.content h4 {margin-block-end: .5em;} +.content i {color:#555;} + +.cell {border: 1px solid #ddd; width:100%; padding: 0.2em;} + +.l, td.l, th.l{text-align: left;} +.r, td.r, th.r{text-align: right;} +.c, td.c, th.c{text-align: center;} +.nw {white-space: nowrap;} +.b {font-weight:bold;} +.i {font-style:italic;} +.wide {min-width:100%} +.wh100 {width:100%; height:100%;} +.table {display:table} +.tcell {display:table-cell} +.mid {vertical-align:middle} /*используется для заполнения ячейки таблицы якорем a href*/ + +.err {color: red;} +.warn {color: #f80;} + +a.up {background: url('../img/up.gif') center right no-repeat; padding-right: 7px;} +a.add {background: url('../img/add.gif') center right no-repeat; width:13px; height:13px; display:inline-block;} +a.edit {background: url('../img/edit.gif') center right no-repeat; width:13px; height:13px; display:inline-block;} +a.view {background: url('../img/view.gif') center right no-repeat; width:13px; height:13px; display:inline-block;} +a.del {background: url('../img/del.gif') center right no-repeat; width:13px; height:13px; display:inline-block;} + + +/* worktable classes */ + +table.worktable {border-collapse:separate; border-spacing:0; border-left:1px solid #ddd;} + +table.worktable th, +table.worktable td { + border-bottom: thin solid #ddd; + border-right: thin solid #ddd; +} +table.worktable thead th, +table.worktable thead td { + box-shadow: 0 -1px 0 0 #ddd; +} +table.worktable thead { + top: 0; + left: 0; + position: sticky; + z-index: 1; +} + +table.worktable td p {margin:0;} + +table.worktable thead tr td, table.worktable tr th{padding: 3px; background-color: #999;} + +table.worktable tr {height: 1.7em; background-color: white;} + +table.worktable tr td {padding:0.1em 0.3em; height:2em;} + +table.worktable tr:hover, table.worktable tr td:hover {background-color:#e5e5e5;} + +table.worktable th {font-weight:500; color:white;} + +/*double borders - not tested with border-collapse:separate*/ +table.worktable tbody tr td.lbd, +table.worktable thead tr td.lbd + {border-left: double #ccc;} + +table.worktable tbody tr td.rbd, +table.worktable thead tr td.rbd + {border-right: double #ccc;} + +table.worktable tbody tr td.tbd, +table.worktable thead tr td.tbd, +table.worktable tbody tr.tbd td, +table.worktable thead tr.tbd td + {border-top: double #ccc;} + +table.worktable tbody tr td.bbd, +table.worktable thead tr td.bbd, +table.worktable tbody tr.bbd td, +table.worktable thead tr.bbd td + {border-bottom: double #ccc;} + +table.worktable tr.hist {background-color: #f6f6f6;} +table.worktable tr.hist:hover, table.worktable tr.hist:hover td, table.worktable tr.comment:hover{background-color:#efefef;} +table.worktable tr.hist td.marked {background: #ddf5c0;} +table.worktable tr.hist:hover td.marked{background-color:#d0f0b9;} + + +@media print { + #mainmenu, .menu, .page-footer, .control-bar, .noprint {display:none;} +} + + + diff --git a/svc_json.cfm b/svc_json.cfm new file mode 100644 index 0000000..5ae9aaf --- /dev/null +++ b/svc_json.cfm @@ -0,0 +1,44 @@ + + + + + + + + + + select + + measure_id + measure + measure_short + + from measure + where 1=1 + order by measure_id + + + + + + + + + + + + + + + + + + + +#serializeJSON(temp.out)# \ No newline at end of file diff --git a/usr.cfm b/usr.cfm new file mode 100644 index 0000000..942bfe2 --- /dev/null +++ b/usr.cfm @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + update usr set password= + where usr_id= + + + + + + + pageInfo=#pageInfo# + id="#d.usr_id#" + status=#pageInfo.status# + trackOut="tr" + idAttributesOut="id" +/> + + + + select + a.login as creator, a.shortname as creator_shortname, m.login as updater, m.shortname as updater_shortname + from #pageInfo.entity# e + left outer join usr a on (e.creator_id=a.usr_id) + left outer join usr m on (e.updater_id=m.usr_id) + where e.#pageInfo.key#= + + + + + + + Пользователь + + #d.login# + [#d.usr_id#] + + + + + + +
    #status.errorMessage#
    +
    + + + + + + + + +
    + + +
    +
    ID
    +
    + #d.usr_id# +
    +
    + +
    +
    Логин
    +
    + +
    +
    + +
    +
    E-mail
    +
    + +
    +
    + +
    +
    Имя
    +
    + +
    +
    + +
    +
    Отчество
    +
    + +
    +
    + +
    +
    Фамилия
    +
    + +
    +
    + +
    +
    Пароль
    +
    + +
    +
    + +
    +
    Описание
    +
    + +
    +
    + +
    +
    Создано
    +
    + #dateFormat(d.dt_created,'DD.MM.YYYY')# #timeFormat(d.dt_created,'HH:MM')# + #qDecoration.creator# (#qDecoration.creator_shortname#) +       + Изменено + #dateFormat(d.dt_updated,'DD.MM.YYYY')# #timeFormat(d.dt_updated,'HH:MM')# + #qDecoration.updater# (#qDecoration.updater_shortname#) +
    +
    + +
    +
    + + + + + + * Для добавления пользователю роли выберите желаемую роль в выпадающем списке и нажмите кнопку со "*" слева от него (нажимать "Сохранить" в основной форме - справа вверху - для этого не нужно) + + +
    + + \ No newline at end of file diff --git a/usr_ls.cfm b/usr_ls.cfm new file mode 100644 index 0000000..020c653 --- /dev/null +++ b/usr_ls.cfm @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + select + + m.usr_id + m.login + m.firstname + m.middlename + m.lastname + m.email + + from usr m + where 1=1 + order by + + + + + + + + + +select count(*) as cnt from usr where 1=1 + + + + + + + + + + + + Пользователи + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + #usr_id##login##email##lastname##firstname##middlename#
    + + #gridFooter# + +
    + \ No newline at end of file diff --git a/util/Application.cfm b/util/Application.cfm new file mode 100644 index 0000000..bcf4bf7 --- /dev/null +++ b/util/Application.cfm @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/util/hash.cfm b/util/hash.cfm new file mode 100644 index 0000000..0f818e6 --- /dev/null +++ b/util/hash.cfm @@ -0,0 +1,15 @@ + + + +
    + + +
    + #GenerateArgon2Hash(#passwd#, 'argon2id', 1, 16000, 2)# + + +
    +
    + #(GetTickCount()-tStart)# ms +
    + diff --git a/util/secret.cfm b/util/secret.cfm new file mode 100644 index 0000000..a7e97b6 --- /dev/null +++ b/util/secret.cfm @@ -0,0 +1,24 @@ + + + +
    + + +
    + + + #h#
    + #hdef#
    + + + +
    + Argon2CheckHash(passwd, h, 'argon2id'):#Argon2CheckHash(passwd, h, 'argon2id')#
    + Argon2CheckHash(passwd, h):#Argon2CheckHash(passwd, h)#
    + + Argon2CheckHash(passwd, hdef, 'argon2id'):#Argon2CheckHash(passwd, hdef, 'argon2id')#
    + Argon2CheckHash(passwd, hdef):#Argon2CheckHash(passwd, hdef)#
    + + #(GetTickCount()-tStart)# ms +
    +