agreement list added

This commit is contained in:
msyu 2025-06-14 12:32:09 +03:00
parent 38b621bc44
commit 13cc175dc3
47 changed files with 362 additions and 5932 deletions

View File

@ -1,3 +1,3 @@
# Svc
# Spec
Каталог услуг
Макет версионных спецификаций. Отработка модели данных

View File

@ -1,575 +0,0 @@
<cfsilent>
<cfimport prefix="m" taglib="lib"/>
<cfimport prefix="c" taglib="lib/controls"/>
<cfimport prefix="d" taglib="lib/data"/>
<cfimport prefix="layout" taglib="layout"/>
</cfsilent><m:silent silent="Yes">
<cffunction name="plain2HtmClean">
<cfargument name="s" type="string"/>
<cfreturn request.plain2htm(request.cleanHtm(s))/>
</cffunction>
<cffunction name="cleanInput">
<cfargument name="s" type="string"/>
<cfreturn htmlEditFormat(s)/>
</cffunction>
<m:prepare_detail entity="abstract_service" key="abstract_service_id" pageInfoOut="pageInfo"/>
<d:bean readonly=#!pageInfo.writePermitted()# table="abstract_service" datasource="#request.DS#" output="d" status="status">
<d:param field="abstract_service_id" type="integer" key autoincrement/>
<d:param field="measure_id" type="integer" init="1" required/>
<d:param field="precision" type="integer" init="0" required/>
<d:param field="area_id" type="integer" required/>
<d:param field="modifier_class_id" type="integer" forNull=""/>
<d:param field="manager_id" type="integer" forNull=""/>
<d:param field="abstract_service" type="varchar" size="255" preprocessor=#cleanInput#/>
<d:param field="abstract_service_en" type="varchar" size="255" preprocessor=#cleanInput#/>
<d:param field="code" type="varchar" size="31" preprocessor=#cleanInput#/>
<d:param field="version" type="integer" default="1" init="1"/>
<d:param field="status_id" type="integer" default="1" init="1"/>
<d:param field="dt_status" type="timestamp" default="#Now()#" init="#Now()#"/>
<d:param field="descr" type="varchar" preprocessor=#plain2HtmClean#/>
<d:param field="commercial_note" type="varchar" preprocessor=#plain2HtmClean#/>
<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:bean>
<cfset pageInfo.status=#status#/>
<m:dispatch_detail
usePRG="No"<!---*** --->
pageInfo=#pageInfo#
id="#d.abstract_service_id#"
status=#pageInfo.status#
trackOut="tr"
idAttributesOut="id"
/>
<!--- save doc --->
<cfmodule template="mod/documents.cfm" section="model" entity="#pageInfo.entity#" id="#id.value#" tr=#tr# writePermitted=#pageInfo.writePermitted()#/>
<!---/save doc --->
<cfquery name="qArea" datasource="#request.DS#">
select a.analytic_code, a.area_code, a.area
from area a
where area_id=<cfqueryparam cfsqltype="cf_sql_integer" value="#d.area_id#" null=#!isNumeric(d.area_id)#/>
</cfquery>
<cfquery name="qDecoration" datasource="#request.DS#">
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#=<cfqueryparam attributeCollection=#id#/>
</cfquery>
</m:silent><!---
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
---><layout:page section="header" pageInfo=#pageInfo#>
<layout:attribute name="title">
<cfoutput>
Абстрактная услуга
<cfif d.abstract_service_id GT 0>
<b>#d.abstract_service#</b>
[#d.abstract_service_id#]
</cfif>
</cfoutput>
</layout:attribute>
</layout:page>
<!---<cfif status.errorState GT 0>
<cfoutput><div class="err">#status.errorMessage#</div></cfoutput>
</cfif>
--->
<cfoutput>
<input type="hidden" name="abstract_service_id" value="#d.abstract_service_id#"/>
<input type="hidden" name="track" value="#tr.self#" size="200"/>
<input type="hidden" name="pass" value=""/><!--- pass marker to prevent save on submit --->
<div class="detail">
<div class="tr">
<div class="th">Номенклатура (RUS)</div>
<div class="td">
<input type="text" name="abstract_service" value="#d.abstract_service#" size="70" style="width:97%"/>
</div>
</div>
<div class="tr">
<div class="th">Номенклатура (ENG)</div>
<div class="td">
<input type="text" name="abstract_service_en" value="#d.abstract_service_en#" size="70" style="width:97%"/>
</div>
</div>
<div class="tr">
<div class="th">Группа услуг</div>
<div class="td">
<cfquery name="qList" datasource="#request.DS#">
select area_id, area_code, analytic_code, area
from area
order by 3
</cfquery>
<c:combo
query=#qList#
combo="area_id"
id="area_id"
key="area_id"
selected="#d.area_id#"
displayf="##analytic_code## ##area##"
class=""
<!---onchange="submit();"--->
/>
</div>
</div>
<div class="tr">
<div class="th">Код услуги</div>
<div class="td">
#qArea.area_code#.<input type="text" name="code" value="#d.code#" size="7"/>
</div>
</div>
<div class="tr">
<div class="th">Единица измерения</div>
<div class="td">
<cfquery name="qList" datasource="#request.DS#">
select measure_id, measure
from measure
order by 2
</cfquery>
<c:combo
query=#qList#
combo="measure_id"
id="measure_id"
key="measure_id"
selected="#d.measure_id#"
displayf="##measure##"
empty=""
class=""
<!---onchange="submit();"--->
/>
<i>для композитных услуг (состоящих из компонентов) указывать штуки. Часто композитные услуги попадают в спецификацию в количестве 1 шт.</i>
</div>
</div>
<div class="tr">
<div class="th">Точность</div>
<div class="td">
<input type="text" name="precision" value="#d.precision#" size="1" class="r"/>
<i>Количество знаков после запятой, 0 - целое число</i>
</div>
</div>
<div class="tr">
<div class="th">Класс характеристики</div>
<div class="td">
<cfquery name="qList" datasource="#request.DS#">
select modifier_class_id, modifier_class
from modifier_class
order by 2
</cfquery>
<c:combo
query=#qList#
combo="modifier_class_id"
id="modifier_class_id"
key="modifier_class_id"
selected="#d.modifier_class_id#"
displayf="##modifier_class##"
empty=""
class=""
<!---onchange="submit();"--->
/>
<cfif d.abstract_service_id GT 0>
<cfif d.modifier_class_id GT 0>
<a href="modifier_class.cfm?modifier_class_id=#d.modifier_class_id#&#tr.fwx#">
<img src="img/edit.gif"/>
</a>
</cfif>
<a href="modifier_class.cfm?modifier_class_id=-1&#tr.fwx#">
<img src="img/add.gif"/>
</a>
</cfif>
<i>
Список, из которого выбирается значение характеристики-модификатора, определяющее конкретную услугу (вариант). <br/>
Если варианты не предусмотрены, нужно оставить поле пустым.
</i>
</div>
</div>
<div class="tr">
<div class="th">Ответственный</div>
<div class="td">
<cfquery name="qList" datasource="#request.DS#">
select usr_id, firstname, middlename, lastname
from usr
order by 4,2,3
</cfquery>
<c:combo
query=#qList#
combo="manager_id"
id="manager_id"
key="usr_id"
selected="#d.manager_id#"
displayf="##lastname## ##firstname## ##middlename## "
empty=""
class=""
/>
</div>
</div>
<div class="tr">
<div class="th">Версия</div>
<div class="td">
<input type="text" name="version" value="#d.version#" size="3"/>
</div>
</div>
<div class="tr">
<div class="th">Статус</div>
<div class="td">
<cfquery name="qList" datasource="#request.DS#">
select status_id, status
from status
order by 1
</cfquery>
<c:combo
query=#qList#
combo="status_id"
id="status_id"
key="status_id"
selected="#d.status_id#"
displayf="##status##"
class=""
<!---onchange="submit();"--->
/>
с <input type="text" name="dt_status" id="dt_status" value="#dateFormat(d.dt_status,'DD.MM.YYYY')#" size="10"/>
<button type="button" onclick="document.getElementById('dt_status').value='#DateFormat(Now(), 'DD.MM.YYYY')#';">Сегодня</button>
</div>
</div>
<div class="tr">
<div class="th">Описание</div>
<div class="td">
<textarea name="descr" rows="5" cols="100" style="width:97%">#request.htm2plain(d.descr)#</textarea>
</div>
</div>
<div class="tr">
<div class="th">Коммерческие примечания</div>
<div class="td">
<textarea name="commercial_note" rows="5" cols="100" style="width:97%">#request.htm2plain(d.commercial_note)#</textarea>
</div>
</div>
<div class="tr">
<div class="th">Создано</div>
<div class="td">
#dateFormat(d.dt_created,'DD.MM.YYYY')# #timeFormat(d.dt_created,'HH:MM')#
#qDecoration.creator# <cfif len(qDecoration.creator_shortname)>(#qDecoration.creator_shortname#)</cfif>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Изменено
#dateFormat(d.dt_updated,'DD.MM.YYYY')# #timeFormat(d.dt_updated,'HH:MM')#
#qDecoration.updater# <cfif len(qDecoration.updater_shortname)>(#qDecoration.updater_shortname#)</cfif>
</div>
</div>
</div>
</cfoutput>
<layout:page section="extension" closeForm="Yes"/>
<!--- --------------------------------------------------- --->
<!--- --------------------------------------------------- --->
<!--- --------------------------------------------------- --->
<cfif d.abstract_service_id GT 0>
<!--- documents ---><!--- call MODEL section for save! --->
<cfmodule template="mod/documents.cfm" section="view" entity="#pageInfo.entity#" id="#id.value#" tr=#tr# writePermitted=#pageInfo.writePermitted()#/>
<!---/documents --->
<!--- <cfmodule template="mod/abstract_service_param_class.cfm"
abstract_service_id=#d.abstract_service_id#
fwx=#tr.fwx#
self=#tr.self#
editable=#pageInfo.writePermitted()#
/> --->
<!--- ------------------------------------------------------------------------------- --->
<!--- ------------------------------------------------------------------------------- --->
<!--- ------------------------------------------------------------------------------- --->
<cfquery name="qAbstractServiceParamClass" datasource="#request.DS#">
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 price p where p.service_param_id=sp.service_param_id) as prc_cnt --->
,(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=<cfqueryparam cfsqltype="cf_sql_integer" value="#d.abstract_service_id#"/>
order by ac.sort
</cfquery>
<cfoutput>
<p>
<b>Компоненты (#qAbstractServiceParamClass.recordCount#)</b>
<cfif pageInfo.writePermitted()>
<cfoutput>
<cfset addUrl="abstract_service_param_class.cfm?abstract_service_param_class_id=-1&abstract_service_id=#d.abstract_service_id#&#tr.fwx#"/>
<button type="button" class="maincontrol" onclick="document.location.href='#addUrl#'">
<a href="#addUrl#">Добавить</a>
</button>
</cfoutput>
</cfif>
</p>
</cfoutput>
<table class="worktable">
<thead>
<tr>
<th></th>
<th>Компонент</th>
<th>Единица измерения</th>
<th>Вариантов</th>
<th>Множественный</th>
<th>Сортировка</th>
<th></th>
</tr>
</thead>
<cfoutput query="qAbstractServiceParamClass">
<tr>
<td>
<c:link_view_edit canWrite=#pageInfo.writePermitted()# entity="abstract_service_param_class" id=#abstract_service_param_class_id# fwx=#tr.fwx#/>
</td>
<td>
<cfif param_class_id GT 0><a href="param_class.cfm?param_class_id=#param_class_id#&#tr.fwx#">#param_class#</a></cfif>
</td>
<td class="c">
#measure# <cfif len(#measure_short#)>(#measure_short#)</cfif>
</td>
<td class="c">
<cfif param_cnt GT 0>#param_cnt#</cfif>
</td>
<td class="c">
<cfif is_multiple GT 0>
Да
</cfif>
</td>
<td class="c">
#sort#
</td>
<td class="c">
<c:link_del canWrite=#pageInfo.writePermitted()# entity="abstract_service_param_class" id=#abstract_service_param_class_id# fwx=#tr.fwx#/>
</td>
</tr>
</cfoutput>
</table>
<!--- --------------------------------------------------- --->
<cfquery name="qService" datasource="#request.DS#">
select
s.service_id
,m.modifier_id
,m.modifier
<!--- ,s.base_price--->
,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=<cfqueryparam cfsqltype="cf_sql_integer" value="#d.abstract_service_id#"/>
order by m.sort, m.code, m.modifier
</cfquery>
<!--- <cfdump var=#qService#/> --->
<cffunction name="formatPrice" output="true">
<cfargument name="price"/>
<cfif isNumeric(price)><cfreturn numberFormat(price,'.00')/><cfelse><cfreturn "(по запросу)"></cfif>
</cffunction>
<cfoutput>
<p>
<b>Варианты услуги (#qService.recordCount#)</b><!---#d.code# #d.abstract_service#--->
<cfif pageInfo.writePermitted()>
<cfoutput>
<cfset addUrl="service.cfm?service_id=-1&abstract_service_id=#d.abstract_service_id#&#tr.fwx#"/>
<button type="button" class="maincontrol" onclick="document.location.href='#addUrl#'">
<a href="#addUrl#">Создать</a>
</button>
</cfoutput>
</cfif>
</p>
</cfoutput>
<table class="worktable">
<thead>
<tr>
<th></th>
<th></th>
<th>Код</th>
<th>Название</th>
<!--- <th>Кл. модиф.</th>--->
<!--- <th>Порядок</th> --->
<th>Цена усл. инст.</th>
<th>Цена усл. фикс.</th>
<th>Цена усл. payg</th>
<th>Компонентов</th>
<th>Цен комп-в</th>
<!--- <th>Цена без НДС, ₽</th>--->
<th></th>
</tr>
</thead>
<cfoutput query="qService">
<tr>
<td>
<c:link_view_edit canWrite=#pageInfo.writePermitted()# entity="service" id=#service_id# fwx=#tr.fwx#/>
</td>
<td>
<form name="frmClone#service_id#" action="service_clone.cfm">
<input type="hidden" name="service_id" value="#service_id#"/>
<input type="hidden" name="track" value="#tr.fw#"/>
<button type="submit"<cfif !pageInfo.writePermitted()> disabled</cfif>>clone</button>
</form>
</td>
<td>#request.skuCode(qArea.area_code,d.code,modifier_code)#</td>
<td>#d.abstract_service#<cfif len(modifier) GT 0> - #modifier#</cfif></td>
<!--- <td class="r">#modifier_class#</td> --->
<!--- <td>#sort#</td> --->
<td class="r">
<cfif prc_inst_id GT 0>
<a href="service_price.cfm?service_price_id=#prc_inst_id#&#tr.fwx#">#formatPrice(prc_inst)#</a>
</cfif>
</td>
<td class="r">
<cfif prc_fix_id GT 0>
<a href="service_price.cfm?service_price_id=#prc_fix_id#&#tr.fwx#">#formatPrice(prc_fix)#</a>
</cfif>
</td>
<td class="r">
<cfif prc_payg_id GT 0>
<a href="service_price.cfm?service_price_id=#prc_payg_id#&#tr.fwx#">#formatPrice(prc_payg)#</a>
</cfif>
</td>
<td class="r"><cfif param_count GT 0>#param_count#</cfif></td>
<td class="r"><cfif service_param_price_count GT 0>#service_param_price_count#</cfif></td>
<!--- <td class="r">#base_price#</td> --->
<td class="c">
<c:link_del canWrite=#pageInfo.writePermitted()# entity="service" id=#service_id# fwx=#tr.fwx#/>
</td>
</tr>
</cfoutput>
</table>
<!--- --------------------------------------------------- --->
<cfquery name="qAbstractServiceComplementary" datasource="#request.DS#">
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=<cfqueryparam cfsqltype="cf_sql_integer" value="#d.abstract_service_id#"/>
order by ac.sort
</cfquery>
<cfoutput>
<p>
<b>Дополнительные услуги (#qAbstractServiceComplementary.recordCount#)</b>
<cfif pageInfo.writePermitted()>
<cfoutput>
<cfset addUrl="abstract_service_complementary.cfm?abstract_service_complementary_id=-1&abstract_service_id=#d.abstract_service_id#&#tr.fwx#"/>
<button type="button" class="maincontrol" onclick="document.location.href='#addUrl#'">
<a href="#addUrl#">Добавить</a>
</button>
</cfoutput>
</cfif>
</p>
</cfoutput>
<table class="worktable">
<thead>
<tr>
<th></th>
<th>Код</th>
<th>Абстрактная услуга</th>
<th>Кол-во</th>
<th>Сортировка</th>
<th></th>
</tr>
</thead>
<cfoutput query="qAbstractServiceComplementary">
<tr>
<td>
<c:link_view_edit canWrite=#pageInfo.writePermitted()# entity="abstract_service_complementary" id=#abstract_service_complementary_id# fwx=#tr.fwx#/>
</td>
<td>
<a href="abstract_service.cfm?abstract_service_id=#complementary_id#&#tr.fwx#">#request.skuCode(area_code,code)#</a>
</td>
<td>
<a href="abstract_service.cfm?abstract_service_id=#complementary_id#&#tr.fwx#">#abstract_service#</a>
</td>
<td class="c">
#quantity#
</td>
<td class="c">
#sort#
</td>
<td class="c">
<c:link_del canWrite=#pageInfo.writePermitted()# entity="abstract_service_complementary" id=#abstract_service_complementary_id# fwx=#tr.fwx#/>
</td>
</tr>
</cfoutput>
</table>
</cfif>
<!--- Добавить "дополнительна для услуг"? --->
<layout:page section="footer"/>

View File

@ -1,200 +0,0 @@
<cfsilent>
<cfimport prefix="m" taglib="lib"/>
<cfimport prefix="c" taglib="lib/controls"/>
<cfimport prefix="d" taglib="lib/data"/>
<cfimport prefix="layout" taglib="layout"/>
</cfsilent><m:silent silent="No">
<cffunction name="plain2HtmClean">
<cfargument name="s" type="string"/>
<cfreturn request.plain2htm(request.cleanHtm(s))/>
</cffunction>
<cffunction name="cleanInput">
<cfargument name="s" type="string"/>
<cfreturn htmlEditFormat(s)/>
</cffunction>
<m:prepare_detail entity="abstract_service_complementary" key="abstract_service_complementary_id" pageInfoOut="pageInfo"/>
<d:bean readonly=#!pageInfo.writePermitted()# table="#pageInfo.entity#" datasource="#request.DS#" output="d" status="status">
<d:param field="abstract_service_complementary_id" type="integer" key autoincrement/>
<d:param field="abstract_service_id" type="integer" required/>
<d:param field="complementary_id" type="integer" required/>
<d:param field="quantity" type="integer" forNull=""/>
<d:param field="sort" type="integer" forNull=""/>
<d:param field="descr" type="varchar" preprocessor=#plain2HtmClean#/>
<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:bean>
<!--- <cfdump var=#form#/>
<cfdump var=#d#/> --->
<m:dispatch_detail
usePRG="No"<!---*** --->
pageInfo=#pageInfo#
id="#d.abstract_service_complementary_id#"
status=#pageInfo.status#
trackOut="tr"
idAttributesOut="id"
/>
<cfquery name="qAbstractService" datasource="#request.DS#">
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=<cfqueryparam cfsqltype="cf_sql_integer" value="#d.abstract_service_id#" null=#!isNumeric(d.abstract_service_id)#/>
</cfquery>
<!---*** Имена запросов ниже по тексту переопределяются--->
<cfquery name="qComplementary" datasource="#request.DS#">
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=<cfqueryparam cfsqltype="cf_sql_integer" value="#d.complementary_id#" null=#!isNumeric(d.complementary_id)#/>
</cfquery>
<cfquery name="qDecoration" datasource="#request.DS#">
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#=<cfqueryparam attributeCollection=#id#/>
</cfquery>
<!--- *** при создании не проверяется Permission --->
</m:silent><!---
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
---><layout:page section="header" pageInfo=#pageInfo#>
<layout:attribute name="title">
<cfoutput>
Дополнительная абстрактная услуга
<cfif d.complementary_id GT 0>
<b>#qComplementary.abstract_service#</b>
#request.skuCode(qComplementary.area_code,qComplementary.code)#
[#d.complementary_id#]
</cfif>
для абстрактной услуги
<cfif d.abstract_service_id GT 0>
<b>#qAbstractService.abstract_service#</b>
#request.skuCode(qAbstractService.area_code,qAbstractService.code)#
[#d.abstract_service_id#]
</cfif>
</cfoutput>
</layout:attribute>
</layout:page>
<cfif status.errorState GT 0>
<cfoutput><div class="err">#status.errorMessage#</div></cfoutput>
</cfif>
<cfoutput>
<input type="hidden" name="abstract_service_complementary_id" value="#d.abstract_service_complementary_id#"/>
<input type="hidden" name="abstract_service_id" value="#d.abstract_service_id#"/>
<input type="hidden" name="track" value="#tr.self#"/>
<input type="hidden" name="pass" value=""/><!--- pass marker to prevent save on submit --->
<div class="detail">
<div class="tr">
<div class="th">Абстрактная услуга</div>
<div class="td">
<a href="abstract_service.cfm?abstract_service_id=#qAbstractService.abstract_service_id#&#tr.fwx#">#qAbstractService.code# <b>#qAbstractService.abstract_service#</b> </a>
</div>
</div>
<div class="tr">
<div class="th">Дополнительная услуга</div>
<div class="td">
<cfquery name="qList" datasource="#request.DS#">
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 <> <cfqueryparam cfsqltype="cf_sql_integer" value="#d.abstract_service_id#"/>
<!--- AND NOT exists (select * from abstract_service_complementary sc where sc.abstract_service_id=<cfqueryparam cfsqltype="cf_sql_integer" value="#d.abstract_service_id#"/> AND sc.complementary_id=a.complementary_id) --->
order by g.analytic_code, a.code
</cfquery>
<c:combo
query=#qList#
combo="complementary_id"
id="complementary_id"
key="abstract_service_id"
selected="#d.complementary_id#"
displayf="##request.skuCode(area_code,code)## ##abstract_service##"
empty=""
class=""
<!--- onchange="document.getElementById('param_id').selectedIndex=0; /*document.getElementById('base_price').value='';*/ --->
onchange="submit();"
/>
<cfif d.abstract_service_id GT 0>
<a href="abstract_service.cfm?abstract_service_id=#d.complementary_id#&#tr.fwx#">
<img src="img/edit.gif"/>
</a>
</cfif>
<i>Эта услуга предлагается дополнительно к основной при формировании спецификации</i>
</div>
</div>
<div class="tr">
<div class="th">Кол-во по умолчанию</div>
<div class="td">
<input type="text" name="quantity" id="quantity" value="#d.quantity#" size="2" class="r"/>
<i>В каком количестве предлагать на каждый экземпляр основной услуги</i>
</div>
</div>
<div class="tr">
<div class="th">Сортировка</div>
<div class="td">
<input type="text" name="sort" id="sort" value="#d.sort#" size="2" class="r"/>
<i>Целое число - порядок, в котором Компонент будет выводиться в составе данной услуги. Рекомендуется ставить через 100, чтобы потом удобнее было тасовать</i>
</div>
</div>
<div class="tr">
<div class="th">Описание</div>
<div class="td">
<textarea name="descr" rows="10" cols="100">#request.htm2plain(d.descr)#</textarea>
</div>
</div>
<div class="tr">
<div class="th">Создано</div>
<div class="td">
#dateFormat(d.dt_created,'DD.MM.YYYY')# #timeFormat(d.dt_created,'HH:MM')#
#qDecoration.creator# <cfif len(qDecoration.creator_shortname)>(#qDecoration.creator_shortname#)</cfif>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Изменено
#dateFormat(d.dt_updated,'DD.MM.YYYY')# #timeFormat(d.dt_updated,'HH:MM')#
#qDecoration.updater# <cfif len(qDecoration.updater_shortname)>(#qDecoration.updater_shortname#)</cfif>
</div>
</div>
</div>
</cfoutput>
<layout:page section="footer"/>

View File

@ -1,72 +0,0 @@
<cfsilent>
<cfimport prefix="m" taglib="lib"/>
<cfimport prefix="d" taglib="lib/data"/>
<cfimport prefix="layout" taglib="layout"/>
</cfsilent><m:silent silent="No">
<m:prepare_detail entity="abstract_service_complementary" pageInfoOut="pageInfo"/>
<cfparam name="abstract_service_complementary_id" type="integer"/>/***use case: составное имя неоднозначно читается*/
<d:del
entity="#pageInfo.entity#"
confirmMessage="Удалить дополнительную услугу?"
denyMessage="Удаление данной дополнительной услуги невозможно (ситуация не предусмотрена)."
accessObj="#pageInfo.entity#"
status="status"
output="markup">
<d:del_condition field="abstract_service_complementary_id" value="#abstract_service_complementary_id#" cfsqltype="cf_sql_integer"/>
</d:del>
<m:dispatch_detail
usePRG="Yes"
pageInfo=#pageInfo#
id="#abstract_service_complementary_id#"
status=#status#
trackOut="tr"
idAttributesOut="id"
/>
<cfquery name="qDecoration" datasource="#request.DS#">
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=<cfqueryparam cfsqltype="cf_sql_integer" value="#abstract_service_complementary_id#" null=#!isNumeric(d.abstract_service_complementary_id)#/>
</cfquery>
</m:silent><!--- ----------------------------------------------------------------------------
---------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------
---><layout:page section="header" pageInfo=#pageInfo#>
<layout:attribute name="title">
<cfoutput>
Удаление дополнительной абстрактной услуги
#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)#
</cfoutput>
</layout:attribute>
<layout:attribute name="controls">&nbsp;</layout:attribute>
</layout:page>
<cfoutput>#markup#</cfoutput>
<layout:page section="footer"/>

View File

@ -1,136 +0,0 @@
<cfsilent>
<cfimport prefix="m" taglib="lib"/>
<cfimport prefix="c" taglib="lib/controls"/>
<cfimport prefix="d" taglib="lib/data"/>
<cfimport prefix="layout" taglib="layout"/>
</cfsilent><m:silent silent="No">
<m:prepare_filter entity="abstract_service" pageInfoOut="pageInfo" trackOut="tr"/>
<m:filter_settings target="#pageInfo.entity#_ls">
<!--- <m:filterparam filter=#filter# param="service_type_id" ftype="numeric" compare="EQ" field="a.service_type_id" default=""/> --->
<m:filterparam filter=#filter# param="abstract_service" ftype="string" compare="LIKE%" field="a.abstract_service" default=""/>
<m:filterparam filter=#filter# param="code" ftype="string" compare="LIKE%" field="a.code" default=""/>
<!---<m:filterparam filter=#filter# param="area_id" ftype="numeric" compare="EQ" field="a.area_id" default=""/>--->
<m:filterparam filter=#filter# param="area_id_list" ftype="numeric" list="Yes" expression="(a.area_id in (?))" default=""/>
<m:filterparam filter=#filter# param="area" ftype="string" compare="LIKE%" field="g.area" default=""/>
<m:filterparam filter=#filter# param="area_code" ftype="string" compare="LIKE%" field="g.area_code" default=""/>
<!--- <m:filterparam filter=#filter# param="payment_periodicity_id" ftype="numeric" compare="EQ" field="b.payment_periodicity_id" default=""/> --->
<m:filterparam filter=#filter# param="status_id" ftype="numeric" compare="EQ" field="a.status_id" default=""/>
</m:filter_settings>
<cfif isDefined("resetAndClose") or isDefined("saveAndClose")>
<cflocation url="#tr.backUrl#" addtoken="No"/>
</cfif>
</m:silent><!--- ----------------------------------------------------------------------------
---------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------
---><layout:page section="header" pageInfo=#pageInfo#>
<layout:attribute name="title"><cfoutput>Каталог услуг - фильтр</cfoutput></layout:attribute>
</layout:page>
<!---<script type="text/javascript"/>
$(document).ready(function() {
try {
$("#customer_id").searchable({maxMultiMatch: 50});
$("#service_manager_id").searchable({maxMultiMatch: 50});
} catch (e) {alert(e)}
});
</script>--->
<cfoutput>
<input type="hidden" name="track" value="#tr.self#"/>
<div class="detail">
<div class="tr">
<div class="th"></div>
<div class="td">
<button type="button" name="reset" onClick="document.location.href='#request.thisPage#?reset=yes&track=#tr.self#'">#i18("Очистить","Clear")#</button>
</div>
</div>
<div class="tr">
<div class="th">#i18("Номенклатура","Service")#</div>
<div class="td">
<input type="text" name="abstract_service" value="#abstract_service#" size="50"/>
<i>#i18("по вхождению подстроки","by substring")#</i>
</div>
</div>
<div class="tr">
<div class="th">#i18("Код услуги","Service Code")#</div>
<div class="td">
<input type="text" name="code" value="#code#" size="20"/>
<i>#i18("по вхождению подстроки","by substring")#</i>
</div>
</div>
<div class="tr">
<div class="th">#i18("Статус","Status")#</div>
<div class="td" style="vertical-align:top;">
<cfquery name="qStatus" datasource="#request.DS#">
select status_id, status
from status
order by status_id
</cfquery>
<c:combo
query=#qStatus#
combo="status_id"
id="status_id"
key="status_id"
displayf="##status##"
selected=#status_id#
empty=""
/>
</div>
</div>
<div class="tr">
<div class="th">#i18("Группа каталога","Catalog Group")#</div>
<div class="td" style="vertical-align:top;">
<cfquery name="qArea" datasource="#request.DS#">
select g.area_id, g.area, g.area_code
from area g
order by g.area_code
</cfquery>
<c:combo
query=#qArea#
combo="area_id_list"
id="area_id"
key="area_id"
displayf="##area_code## ##area##"
selected=#area_id_list#
empty=""
multiple="multiple"
size="7"
/>
<div style="display:inline-block; vertical-align:top; line-height:2em;">
#i18("Код","Code")#
<input type="text" name="area_code" value="#area_code#" size="10"/>
<br/>
#i18("Группа","Group")#
<input type="text" name="area" value="#area#" size="20"/>
<br/>
<i>#i18("по вхождению подстроки","by substring")#</i>
</div>
</div>
</div>
</div><!--- detail --->
</cfoutput>
<layout:page section="footer" closeForm="Yes"/>
<!--- <cfdump var=#filter#> --->

View File

@ -1,164 +0,0 @@
<cfsilent>
<cfimport prefix="m" taglib="lib"/>
<cfimport prefix="c" taglib="lib/controls"/>
<cfimport prefix="d" taglib="lib/data"/>
<cfimport prefix="layout" taglib="layout"/>
</cfsilent><m:silent silent="No">
<m:prepare_ls entity="abstract_service" pageInfoOut="pageInfo" trackOut="tr"/>
<m:filter_settings target="#pageInfo.entity#_ls">
<m:filterparam filter=#filter# param="quickfilter" ftype="string" prefix="%" suffix="%" expression="((p.project like ?) OR (p.customer like ?) OR (p.customer_alias like ?) OR (p.abstract_service_type like ?) OR (p.division like ?) OR (p.performer_short like ?))" default=""/>
</m:filter_settings>
<cfset pageInfo.settings.filter=#filter#/>
<cftry>
<cfquery name="qRead" datasource="#request.DS#">
select
<d:field_set titleMapOut="titleMap" lengthOut="fieldCount">
<d:field title="ID" cfSqlType="CF_SQL_INTEGER">a.abstract_service_id</d:field>
<d:field title="Код группы">g.area_code</d:field>
<d:field title="Группа">g.analytic_code</d:field>
<d:field title="Группа">g.area</d:field>
<d:field>a.area_id</d:field>
<d:field title="Номенклатура (RUS)">a.abstract_service</d:field>
<d:field title="Номенклатура (ENG)">a.abstract_service_en</d:field>
<d:field title="Код">a.code</d:field>/***use case: составное поле. А как сортировать*/
<d:field title="Статус">a.status_id</d:field>
<d:field title="Статус">s.status</d:field>
<d:field title="Ед. изм.">m.measure</d:field>
<d:field title="Ед. изм.">m.measure_short</d:field>
<d:field title="Ответственный">a.manager_id</d:field>
<d:field title="">u.login</d:field>
<d:field title="">u.firstname</d:field>
<d:field title="">u.middlename</d:field>
<d:field title="Ответственный">u.lastname</d:field>
<d:field title="Email ответственного">u.email</d:field>
<d:field title="">a.descr</d:field>
<d:field title="Коммерческие примечания">a.commercial_note</d:field>
<!--- <d:field title="Провайдер" cfSqlType="CF_SQL_INTEGER">(select count(*) from abstract_service_provider sp where sp.abstract_service_id=a.abstract_service_id) as provider_count</d:field> --->
<!---https://habr.com/ru/post/200120/--->
<!---<d:field title="Провайдеры">
/*MSSQL*/STUFF(CAST((
select [text()] = ', ' || "provider"
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 PATH(''), TYPE) AS VARCHAR(MAX)), 1, 2, '')
as providers
</d:field>--->
<!--- <d:field title="Провайдеры">
/*PostgreSQL*/(select STRING_AGG(p.provider,', ')
from abstract_service_provider sp
join provider p on (sp.provider_id=p.provider_id)
where sp.abstract_service_id=a.abstract_service_id
)as providers
</d:field> --->
<!---<d:field title="Периодичность">p.payment_periodicity</d:field>--->
<d:field title="Компон.">(select count(*) from abstract_service_param_class ac where ac.abstract_service_id=a.abstract_service_id) as param_count</d:field>
<d:field title="Класс характеристики">c.modifier_class</d:field>
<d:field>a.modifier_class_id</d:field>
<d:field title="Вариан." cfSqlType="CF_SQL_INTEGER">(select count(*) from service s where s.abstract_service_id=a.abstract_service_id) as service_count</d:field>
<d:field title="Доп.усл.">(select count(*) from abstract_service_complementary ac where ac.abstract_service_id=a.abstract_service_id) as complementary_count</d:field>
<d:field title="Документов" cfSqlType="CF_SQL_INTEGER">(select count(*) from abstract_service_doc d where d.abstract_service_id=a.abstract_service_id) as doc_count</d:field>
</d:field_set>
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)
<!---left outer join payment_periodicity p on (b.payment_periodicity_id=p.payment_periodicity_id)--->
where 1=1 <m:filter_build filter=#pageInfo.settings.filter#/>
order by <m:order_build sortArray=#pageInfo.settings.sort.sortArray# fieldCount=#fieldCount#/>
</cfquery>
<cfcatch type="database">
<cfrethrow/>
<m:ls_catch catch=#cfcatch# status=#pageInfo.status#/>
</cfcatch>
</cftry>
<cfquery name="qCountTotal" datasource="#request.DS#">
select count(*) as cnt from abstract_service where 1=1
</cfquery>
</m:silent><!---
-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
---><cfif isDefined("output_xls")>
<layout:xml qRead=#qRead# titleMap=#titleMap# filename="#pageInfo.entity#.xml"/>
<cfabort/>
</cfif><cfif isDefined("output_json")>
<layout:json qRead=#qRead# titleMap=#titleMap# filename="#pageInfo.entity#.json"/>
<cfabort/>
</cfif><!---
---><layout:page section="header" pageInfo=#pageInfo#>
<layout:attribute name="title">
<cfoutput><b>Абстрактные услуги</b> </cfoutput>
</layout:attribute>
</layout:page>
<cfif pageInfo.readPermitted() AND !pageInfo.status.errorState>
<layout:grid_summary
recordCount=#qRead.recordCount#
totalCount=#qCountTotal.cnt#
footerOut="gridFooter"
excelLink="Yes"
jsonLink="Yes"
/>
<table class="worktable">
<thead>
<layout:grid_head titleMap=#titleMap# sortArray=#pageInfo.settings.sort.sortArray#>
<th width="1%">
<c:link_add canWrite=#pageInfo.writePermitted()# entity=#pageInfo.entity# fwx=#tr.fwx#/>
</th>
<th width="1%"></th>
<th width="7%"><layout:column_head name="analytic_code"/></th>
<th width="2%"><layout:column_head name="code"/></th>
<th width="15%"><layout:column_head name="abstract_service"/></th>
<th width="3%"><layout:column_head name="measure_short"/></th>
<th width="2%"><layout:column_head name="param_count"/></th>
<th width="15%"><layout:column_head name="modifier_class"/></th>
<th width="2%"><layout:column_head name="service_count"/></th>
<th width="2%"><layout:column_head name="complementary_count"/></th>
<th width="2%"><layout:column_head name="lastname"/></th>
<th width="3%"><layout:column_head name="status"/></th>
<th width="1%"></th>
</layout:grid_head>
</thead>
<cfoutput query="qRead" maxrows=#pageInfo.recordsPerPage# startrow=#pageInfo.nStart#>
<tr>
<td class="c">
<c:link_view_edit canWrite=#pageInfo.writePermitted()# entity=#pageInfo.entity# id=#qRead[pageInfo.entity&'_id'][currentRow]# fwx=#tr.fwx#/>
</td>
<td class="c"><cfif doc_count GT 0><img src="img/paperclip.gif" title="#doc_count# док."/></cfif></td>
<td><a href="area.cfm?area_id=#area_id#&#tr.fwx#">#analytic_code# #area#</a></td>
<td>#request.skuCode(area_code,code)#</td>
<td><a href="abstract_service.cfm?abstract_service_id=#abstract_service_id#&#tr.fwx#">#abstract_service#</a></td>
<td class="c">#measure_short#</td>
<td class="c"><cfif param_count GT 0>#param_count#</cfif></td>
<td><a href="modifier_class.cfm?modifier_class_id=#modifier_class_id#&#tr.fwx#">#modifier_class#</a></td>
<td class="c"><cfif service_count GT 0>#service_count#</cfif></td>
<td class="c"><cfif complementary_count GT 0>#complementary_count#</cfif></td>
<td class="c"><cfif manager_id GT 0><a href="mailto:#email#">#lastname# #firstname# #middlename#</a></cfif></td>
<td>#status#</td>
<td class="c">
<c:link_del canWrite=#pageInfo.writePermitted()# entity=#pageInfo.entity# id=#qRead[pageInfo.entity&'_id'][currentRow]# fwx=#tr.fwx#/>
</td>
</tr>
</cfoutput>
</table>
<cfoutput>#gridFooter#</cfoutput>
</cfif>
<layout:page section="footer"/>

View File

@ -1,277 +0,0 @@
<cfsilent>
<cfimport prefix="m" taglib="lib"/>
<cfimport prefix="c" taglib="lib/controls"/>
<cfimport prefix="d" taglib="lib/data"/>
<cfimport prefix="layout" taglib="layout"/>
</cfsilent><m:silent silent="No">
<cffunction name="plain2HtmClean">
<cfargument name="s" type="string"/>
<cfreturn request.plain2htm(request.cleanHtm(s))/>
</cffunction>
<cffunction name="cleanInput">
<cfargument name="s" type="string"/>
<cfreturn htmlEditFormat(s)/>
</cffunction>
<m:prepare_detail entity="abstract_service_param_class" key="abstract_service_param_class_id" pageInfoOut="pageInfo"/>
<d:bean readonly=#!pageInfo.writePermitted()# table="#pageInfo.entity#" datasource="#request.DS#" output="d" status="status">
<d:param field="abstract_service_param_class_id" type="integer" key autoincrement/>
<d:param field="abstract_service_id" type="integer" required/>
<d:param field="param_class_id" type="integer" forNull=""/>
<d:param field="is_multiple" type="bit" init="0" default="0"/>
<d:param field="sort" type="integer" forNull=""/>
<d:param field="descr" type="varchar" preprocessor=#plain2HtmClean#/>
<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:bean>
<!--- <cfdump var=#form#/>
<cfdump var=#d#/> --->
<m:dispatch_detail
usePRG="No"<!---*** --->
pageInfo=#pageInfo#
id="#d.abstract_service_param_class_id#"
status=#pageInfo.status#
trackOut="tr"
idAttributesOut="id"
/>
<cfquery name="qAbstractService" datasource="#request.DS#">
select
a.abstract_service
,a.abstract_service_id
,a.code
from abstract_service a
where a.abstract_service_id=<cfqueryparam cfsqltype="cf_sql_integer" value="#d.abstract_service_id#" null=#!isNumeric(d.abstract_service_id)#/>
</cfquery>
<!---*** Имена запросов ниже по тексту переопределяются--->
<cfquery name="qParamClass" datasource="#request.DS#">
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=<cfqueryparam cfsqltype="cf_sql_integer" value="#d.param_class_id#" null=#!isNumeric(d.param_class_id)#/>
</cfquery>
<cfquery name="qDecoration" datasource="#request.DS#">
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#=<cfqueryparam attributeCollection=#id#/>
</cfquery>
</m:silent><!---
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
---><layout:page section="header" pageInfo=#pageInfo#>
<layout:attribute name="title">
<cfoutput>
Компонент [#d.abstract_service_param_class_id#]
<cfif d.param_class_id GT 0>
<b>#qParamClass.param_class#</b> [#d.param_class_id#]
</cfif>
абстрактной услуги
<cfif d.abstract_service_id GT 0>
<b>#qAbstractService.abstract_service#</b> [#d.abstract_service_id#]
</cfif>
</cfoutput>
</layout:attribute>
</layout:page>
<cfif status.errorState GT 0>
<cfoutput><div class="err">#status.errorMessage#</div></cfoutput>
</cfif>
<cfoutput>
<input type="hidden" name="abstract_service_param_class_id" value="#d.abstract_service_param_class_id#"/>
<input type="hidden" name="abstract_service_id" value="#d.abstract_service_id#"/>
<!--- <input type="hidden" name="param_class_id" value="#d.param_class_id#"/> --->
<input type="hidden" name="track" value="#tr.self#"/>
<input type="hidden" name="pass" value=""/><!--- pass marker to prevent save on submit --->
<div class="detail">
<div class="tr">
<div class="th">Абстрактная услуга</div>
<div class="td">
<a href="abstract_service.cfm?abstract_service_id=#qAbstractService.abstract_service_id#&#tr.fwx#">#qAbstractService.code# <b>#qAbstractService.abstract_service#</b> </a>
</div>
</div>
<div class="tr">
<div class="th">Компонент</div>
<div class="td">
<cfquery name="qList" datasource="#request.DS#">
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
</cfquery>
<c:combo
query=#qList#
combo="param_class_id"
id="param_class_id"
key="param_class_id"
selected="#d.param_class_id#"
displayf="##param_class## ##measure_short##"
empty=""
class=""
<!--- onchange="documen t.getElementById('param_id').selectedIndex=0; /*document.getElementById('base_price').value='';*/ --->
onchange="submit();"
/>
<cfif d.param_class_id GT 0>
<a href="param_class.cfm?param_class_id=#d.param_class_id#&#tr.fwx#">
<img src="img/edit.gif"/>
</a>
</cfif>
<a href="param_class.cfm?param_class_id=-1&#tr.fwx#">
<img src="img/add.gif"/>
</a>
<cfif d.param_class_id GT 0>
Единица измерения:
<b><cfif qParamClass.measure_id GT 0>#qParamClass.measure#<cfelse>(нет)</cfif></b>
</cfif>
<i>Вариант компонента либо фиксируется в варианте услуги, либо выбирается при формировании спецификации</i>
</div>
</div>
<div class="tr">
<div class="th">Множественный</div>
<div class="td">
<input type="checkbox" name="is_multiple" id="is_multiple" value="1"<cfif d.is_multiple> checked</cfif> />
<i>Если отметка стоит, то для экземпляра услуги можно выбирать несколько вариантов компонента, например, несколько типов диска</i>
</div>
</div>
<div class="tr">
<div class="th">Сортировка</div>
<div class="td">
<input type="text" name="sort" id="sort" value="#d.sort#" size="2"/>
<i>Целое число - порядок, в котором Компонент будет выводиться в составе данной услуги. Рекомендуется ставить через 100, чтобы потом удобнее было тасовать</i>
</div>
</div>
<div class="tr">
<div class="th">Описание</div>
<div class="td">
<textarea name="descr" rows="10" cols="100">#request.htm2plain(d.descr)#</textarea>
</div>
</div>
<div class="tr">
<div class="th">Создано</div>
<div class="td">
#dateFormat(d.dt_created,'DD.MM.YYYY')# #timeFormat(d.dt_created,'HH:MM')#
#qDecoration.creator# <cfif len(qDecoration.creator_shortname)>(#qDecoration.creator_shortname#)</cfif>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Изменено
#dateFormat(d.dt_updated,'DD.MM.YYYY')# #timeFormat(d.dt_updated,'HH:MM')#
#qDecoration.updater# <cfif len(qDecoration.updater_shortname)>(#qDecoration.updater_shortname#)</cfif>
</div>
</div>
</div>
Это шаблон для компонента экземпляра услуги (строки спецификации). Если в компонентах услуги определен Компонент, а не конкретный вариант компонента, то нужно присвоить цены всем компонентам этого класса, которые актуальны для данной услуги. Это требуется не только для назначения цен, но и для ограничения списка возможных вариантов выбора компонента для данной услуги. *** Может быть, вместо "компонент" нужно ввести термин "тип компонента", потому что это не экземпляр. Например, Компонент - дисковое пространство, а компонент - дисковое пространство SSD, это уточнение класса компонента, но не конкретный объем на конкретном СХД, и даже не конкретная дисковая квота в рамках контракта (спецификации)
<br/>
</cfoutput>
<layout:page section="extension" closeForm="Yes"/>
<cfif d.abstract_service_param_class_id GT 0>
<h4>Реализации (конкретные параметры вариантов услуг), использующих данный компонент</h4>
<cfquery name="qServiceParam" datasource="#request.DS#">
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=<cfqueryparam cfsqltype="cf_sql_integer" value="#d.abstract_service_param_class_id#"/>
order by p.sort, ac.abstract_service_param_class_id
</cfquery>
<!---<cfdump var=#qServiceParam#/>--->
<cfoutput>
</cfoutput>
<table class="worktable">
<thead>
<tr>
<th></th>
<th>ID</th>
<th>Вариант услуги</th>
<th>Код</th>
<th>Компонент</th>
<th>Ед.изм.</th>
<th>Сортировка</th>
</tr>
</thead>
<cfoutput query="qServiceParam">
<tr>
<td>
<c:link_view_edit canWrite=#pageInfo.writePermitted()# entity="service_param" id=#service_param_id# fwx=#tr.fwx#/>
</td>
<td>#service_param_id#</td>
<td><a href="service.cfm?service_id=#service_id#&#tr.fwx#">#abstract_service# #modifier#</a></td>
<td>
<a href="service_param.cfm?service_param_id=#service_param_id#&#tr.fwx#"/>#request.skuCode(area_code, code, modifier_code, param_code)#</a>
</td>
<td>
<cfif param_id GT 0><a href="param_class.cfm?param_class_id=#param_class_id#&#tr.fwx#">#param_class#</a><cfif len(param)>: <a href="param.cfm?param_id=#param_id#&#tr.fwx#">#param#</a></cfif></cfif>
</td>
<td class="c">#measure_short#</td>
<td class="c">#sort#</td>
</tr>
</cfoutput>
</table>
<!---
При формировании спецификации доступны только компоненты (компоненты, параметры), для которых указаны базовые цены. Термин не вполне корректный, точнее было бы - вариант компонента.
--->
</cfif>
<layout:page section="footer"/>

View File

@ -1,90 +0,0 @@
<cfsilent>
<cfimport prefix="m" taglib="lib"/>
<cfimport prefix="d" taglib="lib/data"/>
<cfimport prefix="layout" taglib="layout"/>
</cfsilent><m:silent silent="No">
<m:prepare_detail entity="abstract_service_param_class" pageInfoOut="pageInfo"/>
<cfparam name="abstract_service_param_class_id" type="integer"/><!--- /***use case: составное имя неоднозначно читается*/ --->
<d:del
entity="#pageInfo.entity#"
confirmMessage="Удалить компонент абстрактной услуги?"
denyMessage="Удаление данного компонента невозможно (существуют зависимые объекты)."
accessObj="#pageInfo.entity#"
status="status"
output="markup">
<!---*** эту же зависимость можно построить по составному ключу? --->
<d:dependency entity="service_param" title="Параметры конкретных услуг">
<d:dependency_field key>service_param_id</d:dependency_field>
<d:dependency_field title="Код">a.code</d:dependency_field>
<d:dependency_field title="Абстрактная услуга">a.abstract_service</d:dependency_field>
<d:dependency_field title="Класс характеристики">c.modifier_class</d:dependency_field>
<d:dependency_field title="Характеристика">m.modifier</d:dependency_field>
<d:dependency_field title="Компонент">pc.param_class</d:dependency_field>
<d:dependency_field title="Компонент">p.param</d:dependency_field>
<d:dependency_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 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)
</d:dependency_from>
<d:dependency_condition cfsqltype="cf_sql_integer" value='#abstract_service_param_class_id#'>sp.abstract_service_param_class_id</d:dependency_condition>
<d:dependency_order_by>1 desc</d:dependency_order_by>
</d:dependency>
<d:del_condition field="abstract_service_param_class_id" value="#abstract_service_param_class_id#" cfsqltype="cf_sql_integer"/>
</d:del>
<m:dispatch_detail
usePRG="Yes"
pageInfo=#pageInfo#
id="#abstract_service_param_class_id#"
status=#status#
trackOut="tr"
idAttributesOut="id"
/>
<!--- decoration --->
<cfquery name="qDecoration" datasource="#request.DS#">
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=<cfqueryparam cfsqltype="cf_sql_integer" value="#abstract_service_param_class_id#" null=#!isValid("integer", abstract_service_param_class_id)#/>
</cfquery>
</m:silent><!--- ----------------------------------------------------------------------------
---------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------
---><layout:page section="header" pageInfo=#pageInfo#>
<layout:attribute name="title">
<cfoutput>
Удаление компонента абстрактной услуги
#qDecoration.abstract_service#
(#qDecoration.code#)
#qDecoration.param_class#
<cfif abstract_service_param_class_id GT 0>
[#abstract_service_param_class_id#]
</cfif>
</cfoutput>
</layout:attribute>
<layout:attribute name="controls">&nbsp;</layout:attribute>
</layout:page>
<!---<cfdump var=#qDecoration#/>--->
<!--- <i>компонент абстрактной услуги - это (абстрактный) компонент. У конкретной услуги - конкретные компоненты (варианты), у абстрактной услуги - классы параметров</i> --->
<cfoutput>#markup#</cfoutput>
<layout:page section="footer"/>

View File

@ -1,270 +0,0 @@
<cfsilent>
<cfimport prefix="m" taglib="lib"/>
<cfimport prefix="c" taglib="lib/controls"/>
<cfimport prefix="d" taglib="lib/data"/>
<cfimport prefix="layout" taglib="layout"/>
</cfsilent><m:silent silent="No">
<m:prepare_ls entity="abstract_service" accessObject="abstract_service_rpt" pageInfoOut="pageInfo" trackOut="tr"/>
<m:filter_settings target="#pageInfo.entity#_ls">
<m:filterparam filter=#filter# param="quickfilter" ftype="string" prefix="%" suffix="%" expression="((p.project like ?) OR (p.customer like ?) OR (p.customer_alias like ?) OR (p.abstract_service_type like ?) OR (p.division like ?) OR (p.performer_short like ?))" default=""/>
</m:filter_settings>
<cfset pageInfo.settings.filter=#filter#/>
<cftry>
<cfquery name="qRead" datasource="#request.DS#">
select
<d:field_set titleMapOut="titleMap" lengthOut="fieldCount">
<d:field title="ID" cfSqlType="CF_SQL_INTEGER">a.abstract_service_id</d:field>
<d:field title=#i18("Код группы","Group Code")#>g.area_code</d:field>
<d:field title="Группа каталога">g.area</d:field>
<d:field title="Catalog Group">g.area_en</d:field>
<d:field title="Статус">u.status</d:field>
<d:field title="Status">u.status_en</d:field>
<d:field title=#i18("Код услуги","Service Code")#>a.code</d:field>
<d:field title=#i18("Номенклатура (RUS)","Service (RUS)")#>a.abstract_service</d:field>
<d:field title=#i18("Номенклатура (ENG)","Service (ENG)")#>a.abstract_service_en</d:field>
<d:field title="Ед.изм.">m.measure_short</d:field>
<d:field title="Measure">m.measure_short_en</d:field>
<d:field title="Провайдер" cfSqlType="CF_SQL_INTEGER">(select count(*) from abstract_service_provider sp where sp.abstract_service_id=a.abstract_service_id) as provider_count</d:field>
<d:field title="Провайдеры">
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
</d:field>
<d:field title="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
</d:field>
<d:field title="Периодичность">p.payment_periodicity</d:field>
<d:field title="Periodicity">p.payment_periodicity_en</d:field>
<d:field title=#i18("Код","Code")#>b.budget_code</d:field>
<d:field title="Бюджетная статья">b.budget</d:field>
<d:field title="Budget Item">b.budget_en</d:field>
<d:field title="Тип">st.service_type</d:field>
<d:field title="Type">st.service_type_en</d:field>
<d:field title=#i18("Класс характеристики","Characteristic class")#>mc.modifier_class</d:field>
<d:field title=#i18("Вариантов","Variants")# cfSqlType="CF_SQL_INTEGER">(select count(*) from service s where s.abstract_service_id=a.abstract_service_id) as service_count</d:field>
<d:field title=#i18("Документы","Documents")# cfSqlType="CF_SQL_INTEGER">(select count(*) from abstract_service_doc d where d.abstract_service_id=a.abstract_service_id) as doc_count</d:field>
<d:field title=#i18("Документы","Documents")# >
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
</d:field>
</d:field_set>
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 <m:filter_build filter=#pageInfo.settings.filter#/>
order by <m:order_build sortArray=#pageInfo.settings.sort.sortArray# fieldCount=#fieldCount#/>
</cfquery>
<cfcatch type="database">
<m:ls_catch catch=#cfcatch# status=#pageInfo.status#/>
</cfcatch>
</cftry>
<cfquery name="qCountTotal" datasource="#request.DS#">
select count(*) as cnt from abstract_service where 1=1
</cfquery>
</m:silent><!---
-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
---><cfif isDefined("output_xls")>
<layout:xml qRead=#qRead# titleMap=#titleMap# filename="#pageInfo.entity#.xml"/>
<cfabort/>
</cfif><cfif isDefined("output_json")>
<layout:json qRead=#qRead# titleMap=#titleMap# filename="#pageInfo.entity#.json"/>
<cfabort/>
</cfif><!---
---><layout:page section="header" pageInfo=#pageInfo#>
<layout:attribute name="title">
<cfoutput><b>#i18("Каталог","Catalog")#</b> </cfoutput>
</layout:attribute>
</layout:page>
<cfif pageInfo.readPermitted() AND !pageInfo.status.errorState>
<layout:grid_summary
recordCount=#qRead.recordCount#
totalCount=#qCountTotal.cnt#
footerOut="gridFooter"
excelLink="Yes"
jsonLink="Yes"
/>
<cffunction name="formatProviders" output="true">
<cfargument name="providers"/>
<cfif len(ARGUMENTS.providers)>
<cftry>
<cfset providerCollection=xmlParse(ARGUMENTS.providers)/>
<cfloop array=#providerCollection.providers.XmlChildren# index="d">
<p style="margin:.5em 0;">
#d.XmlAttributes.provider#
</p>
</cfloop>
<cfcatch type="ANY">#cfcatch.message# #cfcatch.detail#</cfcatch>
</cftry>
</cfif>
</cffunction>
<cfset request.formatProviders=formatProviders/>
<!---NB CALLER.tr.fwx! --->
<cffunction name="formatDocs" output="true">
<cfargument name="docs"/>
<cfif len(docs)>
<cftry>
<cfset docsCollection=xmlParse(docs)/><!---<cfdump var=#docsCollection#/>--->
<cfloop array=#docsCollection.docs.XmlChildren# index="d"> <!---<cfdump var=#d.XmlAttributes#/>--->
<p style="line-height:1.8em;">
<a href="doc_get.cfm?entity=abstract_service&doc_id=#d.XmlAttributes.abstract_service_doc_id#" title="открыть (#d.XmlAttributes.contenttype#)" target="_blank">
<m:contenttype_icon contenttype=#d.XmlAttributes.contenttype#/>
</a>
<a href="doc.cfm?entity=abstract_service&doc_id=#d.XmlAttributes.abstract_service_doc_id#&#CALLER.tr.fwx#" title="редактировать атрибуты"><cfif len(d.XmlAttributes.abstract_service_doc)>#d.XmlAttributes.abstract_service_doc#<cfelse>#d.XmlAttributes.abstract_fname#</cfif> (#dateFormat(d.XmlAttributes.dt_created,'DD.MM.YYYY')#)</a>
</p>
</cfloop>
<cfcatch type="ANY">#cfcatch.message# #cfcatch.detail#</cfcatch>
</cftry>
</cfif>
</cffunction>
<cfset request.formatDocs=formatDocs/>
<!---*** очень осторожно: используется Dynamic Evaluation! --->
<c:table query=#qRead# recordsPerPage=#pageInfo.recordsPerPage# nStart=#pageInfo.nStart# titleMap=#titleMap# sortArray=#pageInfo.settings.sort.sortArray# class="worktable wide">
<c:column width="1%" field="area_code"/>
<c:column width="5%" field="area" lang="ru"/><c:column width="5%" field="area_en" lang="en"/>
<c:column width="3%" field="status" lang="ru"/><c:column width="3%" field="status_en" lang="en"/>
<c:column width="3%" field="service_type" lang="ru"/><c:column width="3%" field="service_type_en" lang="en"/>
<c:column width="15%" field="abstract_service"><c:td><a href="abstract_service.cfm?abstract_service_id=#abstract_service_id#&#CALLER.tr.fwx#">#abstract_service#</a></c:td></c:column>
<c:column width="15%" field="abstract_service_en"><c:td><a href="abstract_service.cfm?abstract_service_id=#abstract_service_id#&#CALLER.tr.fwx#">#abstract_service_en#</a></c:td></c:column>
<c:column width="5%" field="code"><c:td><a href="abstract_service.cfm?abstract_service_id=#abstract_service_id#&#CALLER.tr.fwx#">#code#</a></c:td></c:column>
<c:column width="2%" field="measure_short" lang="ru"/><c:column width="2%" field="measure_short_en" lang="en"/>
<c:column width="15%" field="provider_count" lang="ru">
<c:th>Провайдеры</c:th>
<c:td>#request.formatProviders(providers)#<!---<pre>#replace(replace(providers,'<','&lt;', 'ALL'),'>','&gt;', 'ALL')#</pre>---></c:td>
</c:column>
<c:column width="15%" field="provider_count" lang="en">
<c:th>Providers</c:th>
<c:td>#request.formatProviders(providers_en)#<!---<pre>#replace(replace(providers_en,'<','&lt;', 'ALL'),'>','&gt;', 'ALL')#</pre>---></c:td>
</c:column>
<c:column width="20%" field="doc_count">
<c:td>#request.formatDocs(docs)#</c:td>
</c:column>
</c:table>
<!--- <table class="worktable">
<thead>
<layout:grid_head titleMap=#titleMap# sortArray=#pageInfo.settings.sort.sortArray#>
<th width="1%"></th>
<th width="3%"><layout:column_head name="area_code"/></th>
<th width="10%"><layout:column_head name="area"/></th>
<th width="3%"><layout:column_head name="status"/></th>
<th width="5%"><layout:column_head name="service_type"/></th>
<th width="10%"><layout:column_head name="abstract_service"/></th>
<th width="2%"><layout:column_head name="code"/></th>
<th width="2%"><layout:column_head name="measure_short"/></th>
<th width="5%"><layout:column_head name="provider_count"/></th>
<th width="15%"><layout:column_head name="doc_count"/></th>
</layout:grid_head>
</thead>
<cfoutput query="qRead" maxrows=#pageInfo.recordsPerPage# startrow=#pageInfo.nStart#>
<tr>
<td class="c">
<c:link_view_edit canWrite=#pageInfo.writePermitted()# entity=#pageInfo.entity# id=#qRead[pageInfo.entity&'_id'][currentRow]# fwx=#tr.fwx#/>
</td>
<td>#area_code#</td>
<td>#area#</td>
<td>#status#</td>
<td class="c">#service_type#</td>
<td>#abstract_service#</td>
<td>#code#</td>
<td class="c">#measure_short#</td>
<td>
<cfif len(providers)>
<cftry>
<cfset providerCollection=xmlParse(providers)/>
<cfloop array=#providerCollection.providers.XmlChildren# index="d">
<p style="margin:.5em 0;">
#d.XmlAttributes.provider#
</p>
</cfloop>
<cfcatch type="ANY">#cfcatch.message# #cfcatch.detail#</cfcatch>
</cftry>
</cfif>
</td>
<td>
<cfif len(docs)>
<cftry>
<cfset docsCollection=xmlParse(docs)/>
<cfloop array=#docsCollection.docs.XmlChildren# index="d">
<p style="line-height:1.8em;">
<a href="doc_get.cfm?entity=abstract_service&doc_id=#d.XmlAttributes.abstract_service_doc_id#" title="открыть (#d.XmlAttributes.contenttype#)" target="_blank">
<m:contenttype_icon contenttype=#d.XmlAttributes.contenttype#/>
</a>
<a href="doc.cfm?entity=abstract_service&doc_id=#d.XmlAttributes.abstract_service_doc_id#&#tr.fwx#" title="редактировать атрибуты"><cfif len(d.XmlAttributes.abstract_service_doc)>#d.XmlAttributes.abstract_service_doc#<cfelse>#d.XmlAttributes.abstract_fname#</cfif> (#dateFormat(d.XmlAttributes.dt_created,'DD.MM.YYYY')#)</a>
</p>
</cfloop>
<cfcatch type="ANY">#cfcatch.message# #cfcatch.detail#</cfcatch>
</cftry>
</cfif>
</td>
</tr>
</cfoutput>
</table>--->
<cfoutput>#gridFooter#</cfoutput>
</cfif>
<layout:page section="footer"/>

130
agreement_ls.cfm Normal file
View File

@ -0,0 +1,130 @@
<cfsilent>
<cfimport prefix="m" taglib="lib"/>
<cfimport prefix="c" taglib="lib/controls"/>
<cfimport prefix="d" taglib="lib/data"/>
<cfimport prefix="layout" taglib="layout"/>
</cfsilent><m:silent silent="No">
<cffunction name="hideNonPositive">
<cfargument name="a"/>
<cfreturn (a GT 0)? a : ""/>
</cffunction>
<m:prepare_ls entity="agreement" accessObject="" pageInfoOut="pageInfo" trackOut="tr"/>
<!--- <m:filter_settings target="#pageInfo.entity#_ls">
<m:filterparam filter=#filter# param="quickfilter" ftype="string" prefix="%" suffix="%" expression="((p.project like ?) OR (p.customer like ?) OR (p.customer_alias like ?) OR (p.agreement_class_type like ?) OR (p.division like ?) OR (p.performer_short like ?))" default=""/>
</m:filter_settings> --->
<!--- <cfset pageInfo.settings.filter=#filter#/> --->
<cftry>
<cfquery name="qRead" datasource="#request.DS#">
select
<d:field_set titleMapOut="titleMap" lengthOut="fieldCount">
<d:field title="contract_id" cfSqlType="CF_SQL_INTEGER">a.contract_id</d:field>
<d:field title="Н-р согл." cfSqlType="CF_SQL_INTEGER">a.agreement_version</d:field>
<d:field title="Ключ сделки">a.deal_uid</d:field>
<d:field title="Соглашение">a.agreement</d:field>
<d:field title="Дата соглашения">a.dt_agreement</d:field>
<d:field title="Описание">a.descr</d:field>
<d:field title="Номер договора">d.contract</d:field>
<d:field title="Дата договора">d.dt_contract</d:field>
<d:field title="Контрагент">k.contragent</d:field>
<d:field title="Строк изменено">(select count(*) from specification_item_version siv join specification_item si on (siv.specification_item_uid=si.specification_item_uid) join specification s on (si.specification_id=s.specification_id) where a.contract_id=s.contract_id AND a.agreement_version=siv.agreement_version) as change_cnt</d:field>
</d:field_set>
from agreement a
join contract d on (a.contract_id=d.contract_id)
join contragent k on (d.contragent_id=k.contragent_id)
where 1=1 <m:filter_build filter=#pageInfo.settings.filter#/>
order by <m:order_build sortArray=#pageInfo.settings.sort.sortArray# fieldCount=#fieldCount#/>
</cfquery>
<cfcatch type="database">
<m:ls_catch catch=#cfcatch# status=#pageInfo.status#/>
</cfcatch>
</cftry>
<cfquery name="qCountTotal" datasource="#request.DS#">
select count(*) as cnt from agreement where 1=1
</cfquery>
</m:silent><!---
-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
---><cfif isDefined("output_xls")>
<layout:xml qRead=#qRead# titleMap=#titleMap# filename="#pageInfo.entity#.xml"/>
<cfabort/>
</cfif><cfif isDefined("output_json")>
<layout:json qRead=#qRead# titleMap=#titleMap# filename="#pageInfo.entity#.json"/>
<cfabort/>
</cfif><!---
---><layout:page section="header" pageInfo=#pageInfo#>
<layout:attribute name="title">
<cfoutput><b>Сделки (соглашения)</b></cfoutput>
</layout:attribute>
<layout:attribute name="controls">
<!---skip filter link, filter is not implemented--->
<!---<layout:language_switch/>--->
</layout:attribute>
</layout:page>
<cfif pageInfo.readPermitted() AND !pageInfo.status.errorState>
<layout:grid_summary
recordCount=#qRead.recordCount#
totalCount=#qCountTotal.cnt#
footerOut="gridFooter"
excelLink="Yes"
jsonLink="Yes"
/>
<!--- так довольно громоздко, но можно обойтись без Dynamic Evaluation --->
<cfset queryAddColumn(qRead,'f_link_view_edit')/>
<cfset titleMap.f_link_view_edit={ordinal=#StructCount(titleMap)+1#}/><!--- *** Это легко забыть, потому что TitleMap никак не сцеплен с qRead. Напрашивается: упаковать их в одну обертку (но тогда обращение станет длиннее). Еще идея - назвать qRead и TitleMap так, чтобы была видна их связь. --->
<!--- <cfdump var=#titleMap#/> --->
<cfset queryAddColumn(qRead,'f_contract')/>
<cfset titleMap.f_contract=titleMap.contract/>
<cfset queryAddColumn(qRead,'f_link_del')/>
<cfset titleMap.f_link_del={ordinal=0}/>
<!--- <cfdump var=#titleMap#/> --->
<cfoutput query=#qRead# startRow=#pageInfo.nStart# maxRows=#pageInfo.recordsPerPage#><!--- *** Здесь некомфортное дублирование startRow, maxRows с вызовом c:table ниже, причем в c:table оно закопано в модуль, и аргументы называются по-разному... но мы хотим немного сэкономить и не обрабатывать весь резалтсет --->
<!--- *** тут можно было бы спокойно использовать суррогатный альтернативный ключ, но хочется проверить, как будет работать track на составном ключе. Кстати, я все равно его использую как ancor name --->
<cfsavecontent variable="qRead.f_link_view_edit">
<a href="agreement.cfm?contract_id=#contract_id#&agreement_version=#agreement_version#&#tr.fwx#" name="#deal_uid#" <cfif pageInfo.writePermitted()>title="редактировать" class="edit"<cfelse>title="просмотр" class="view"</cfif>></a>
</cfsavecontent>
<cfsavecontent variable="qRead.f_contract">
<a href="contract.cfm?contract_id=#contract_id#&#tr.fwx#">#contract#</a>
</cfsavecontent>
<cfsavecontent variable="qRead.f_link_del">
<cfif pageInfo.writePermitted()><a href="agreement_del.cfm?contract_id=#contract_id#&agreement_version=#agreement_version#&#tr.fwx#" class="del" title="удалить"></a></cfif>
</cfsavecontent>
</cfoutput>
<c:table query=#qRead# recordsPerPage=#pageInfo.recordsPerPage# nStart=#pageInfo.nStart# titleMap=#titleMap# sortArray=#pageInfo.settings.sort.sortArray# class="worktable wide">
<c:column width="1%" sortable="false"><!---*** class="c" не пробрасывается --->
<c:th><c:link_add canWrite=#pageInfo.writePermitted()# entity=#pageInfo.entity# fwx=#tr.fwx#/></c:th>
<c:td field="f_link_view_edit" class="c"/>
</c:column>
<c:column width="2%" field="agreement_version"><c:td class="r"/></c:column>
<c:column width="12%" field="deal_uid"/>
<c:column width="7%" field="f_contract"/>
<c:column width="5%" field="dt_contract" formatter=#function(dt){return dateformat(dt,"YYYY-MM-DD");}#><c:td class="c"/></c:column>
<c:column width="10%" field="contragent"/>
<c:column width="7%" field="agreement"/>
<c:column width="5%" field="dt_agreement" formatter=#function(dt){return dateformat(dt,"YYYY-MM-DD");}#><c:td class="c"/></c:column>
<c:column width="15%" field="descr"/>
<c:column width="2%" field="change_cnt"><c:td class="c"/></c:column>
<c:column width="1%" sortable="false">
<c:td field="f_link_del" class="c"/>
</c:column>
</c:table>
<cfoutput>#gridFooter#</cfoutput>
</cfif>
<layout:page section="footer"/>

200
area.cfm
View File

@ -1,200 +0,0 @@
<cfsilent>
<cfimport prefix="m" taglib="lib"/>
<cfimport prefix="c" taglib="lib/controls"/>
<cfimport prefix="d" taglib="lib/data"/>
<cfimport prefix="layout" taglib="layout"/>
</cfsilent><m:silent silent="No">
<cffunction name="plain2HtmClean">
<cfargument name="s" type="string"/>
<cfreturn request.plain2htm(request.cleanHtm(s))/>
</cffunction>
<cffunction name="cleanInput">
<cfargument name="s" type="string"/>
<cfreturn htmlEditFormat(s)/>
</cffunction>
<m:prepare_detail entity="area" key="area_id" pageInfoOut="pageInfo"/>
<d:bean readonly=#!pageInfo.writePermitted()# table="area" datasource="#request.DS#" output="d" status="status">
<d:param field="area_id" type="integer" key autoincrement/>
<d:param field="area_code" type="varchar" size="31" preprocessor=#cleanInput#/>
<d:param field="analytic_code" type="varchar" size="31" preprocessor=#cleanInput#/>
<d:param field="area" type="varchar" size="255" preprocessor=#cleanInput#/>
<d:param field="area_en" type="varchar" size="255" preprocessor=#cleanInput#/>
<d:param field="descr" type="varchar" preprocessor=#plain2HtmClean#/>
<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:bean>
<m:dispatch_detail
usePRG="No"<!---*** --->
pageInfo=#pageInfo#
id="#d.area_id#"
status=#pageInfo.status#
trackOut="tr"
idAttributesOut="id"
/>
<!--- decoration --->
<cfquery name="qDecoration" datasource="#request.DS#">
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=<cfqueryparam attributeCollection=#id#/>
</cfquery>
</m:silent><!---
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
---><layout:page section="header" pageInfo=#pageInfo#>
<layout:attribute name="title">
<cfoutput>
Группа каталога
<cfif d.area_id GT 0>
<b>#d.area#</b>
[#d.area_id#]
</cfif>
</cfoutput>
</layout:attribute>
</layout:page>
<cfif status.errorState GT 0>
<cfoutput><div class="err">#status.errorMessage#</div></cfoutput>
</cfif>
<cfoutput>
<input type="hidden" name="area_id" value="#d.area_id#"/>
<input type="hidden" name="track" value="#tr.self#"/>
<input type="hidden" name="pass" value=""/><!--- pass marker to prevent save on submit --->
<div class="detail">
<div class="tr">
<div class="th">ID</div>
<div class="td">
#d.area_id#
</div>
</div>
<div class="tr">
<div class="th">Код</div>
<div class="td">
<input type="text" name="area_code" value="#d.area_code#" size="70"/>
<i>используется для формирования кода услуги и кода sku</i>
</div>
</div>
<div class="tr">
<div class="th">Аналитический код</div>
<div class="td">
<input type="text" name="analytic_code" value="#d.analytic_code#" size="70"/>
</div>
</div>
<div class="tr">
<div class="th">Группа (RUS)</div>
<div class="td">
<input type="text" name="area" value="#d.area#" size="70"/>
</div>
</div>
<div class="tr">
<div class="th">Группа (ENG)</div>
<div class="td">
<input type="text" name="area_en" value="#d.area_en#" size="70"/>
</div>
</div>
<div class="tr">
<div class="th">Описание</div>
<div class="td">
<textarea name="descr" rows="10" cols="100">#request.htm2plain(d.descr)#</textarea>
</div>
</div>
<div class="tr">
<div class="th">Создано</div>
<div class="td">
#dateFormat(d.dt_created,'DD.MM.YYYY')# #timeFormat(d.dt_created,'HH:MM')#
#qDecoration.creator# <cfif len(qDecoration.creator_shortname)>(#qDecoration.creator_shortname#)</cfif>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Изменено
#dateFormat(d.dt_updated,'DD.MM.YYYY')# #timeFormat(d.dt_updated,'HH:MM')#
#qDecoration.updater# <cfif len(qDecoration.updater_shortname)>(#qDecoration.updater_shortname#)</cfif>
</div>
</div>
</div>
</cfoutput>
<layout:page section="extension" closeForm="Yes"/>
<cfif d.area_id GT 0>
<cfquery name="qAbstractService" datasource="#request.DS#">
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=<cfqueryparam cfsqltype="cf_sql_integer" value="#d.area_id#"/>
order by a.code, a.abstract_service
</cfquery>
<cfoutput>
<h4>Абстрактные услуги (#qAbstractService.recordCount#)</h4>
</cfoutput>
<table class="worktable">
<thead>
<tr>
<th></th>
<th>Код услуги</th>
<th>Абстрактная услуга</th>
<th>Вариантов</th>
<th>Компонентов</th>
<th></th>
</tr>
</thead>
<cfoutput query="qAbstractService">
<tr>
<td>
<c:link_view_edit canWrite=#pageInfo.writePermitted()# entity="abstract_service" id=#abstract_service_id# fwx=#tr.fwx#/>
</td>
<td>
<cfif abstract_service_id GT 0><a href="abstract_service.cfm?abstract_service_id=#abstract_service_id#&#tr.fwx#">#code#</a></cfif>
</td>
<td>
<cfif abstract_service_id GT 0><a href="abstract_service.cfm?abstract_service_id=#abstract_service_id#&#tr.fwx#">#abstract_service#</a></cfif>
</td>
<td class="c">
<cfif svc_cnt GT 0>#svc_cnt#</cfif>
</td>
<td class="c">
<cfif param_cnt GT 0>#param_cnt#</cfif>
</td>
<td class="c">
<c:link_del canWrite=#pageInfo.writePermitted()# entity="abstract_service" id=#abstract_service_id# fwx=#tr.fwx#/>
</td>
</tr>
</cfoutput>
</table>
</cfif>
<layout:page section="footer"/>

View File

@ -1,67 +0,0 @@
<cfsilent>
<cfimport prefix="m" taglib="lib"/>
<cfimport prefix="d" taglib="lib/data"/>
<cfimport prefix="layout" taglib="layout"/>
</cfsilent><m:silent silent="No">
<m:prepare_detail entity="area" pageInfoOut="pageInfo"/>
<cfparam name="area_id" type="integer"/>
<d:del
entity="#pageInfo.entity#"
confirmMessage="Удалить группу услуг?"
denyMessage="Удаление данной группы невозможно (используется абстрактными услугами)."
accessObj="#pageInfo.entity#"
status="status"
output="markup">
<d:dependency entity="service" title="Абстрактные услуги">
<d:dependency_field key>a.abstract_service_id</d:dependency_field>
<d:dependency_field title="Код услуги">a.code</d:dependency_field>
<d:dependency_field title="Абстрактная услуга">a.abstract_service</d:dependency_field>
<d:dependency_from>
abstract_service a
left outer join area g on (a.area_id=g.area_id)
</d:dependency_from>
<d:dependency_condition cfsqltype="cf_sql_integer" value='#area_id#'>g.area_id</d:dependency_condition>
<d:dependency_order_by>2</d:dependency_order_by>
</d:dependency>
<d:del_condition field="area_id" value="#area_id#" cfsqltype="cf_sql_integer"/>
</d:del>
<m:dispatch_detail
usePRG="Yes"
pageInfo=#pageInfo#
id="#area_id#"
status=#status#
trackOut="tr"
idAttributesOut="id"
/>
<!--- decoration --->
<cfquery name="qDecoration" datasource="#request.DS#">
select
m.area
from area m
where m.area_id=<cfqueryparam cfsqltype="cf_sql_integer" value="#area_id#" null=#!isValid("integer", area_id)#/>
</cfquery>
</m:silent><!--- ----------------------------------------------------------------------------
---------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------
---><layout:page section="header" pageInfo=#pageInfo#>
<layout:attribute name="title">
<cfoutput>
Удаление группы услуг
#qDecoration.area#
[#area_id#]
</cfoutput>
</layout:attribute>
<layout:attribute name="controls">&nbsp;</layout:attribute>
</layout:page>
<cfoutput>#markup#</cfoutput>
<layout:page section="footer"/>

View File

@ -1,145 +0,0 @@
<cfsilent>
<cfimport prefix="m" taglib="lib"/>
<cfimport prefix="c" taglib="lib/controls"/>
<cfimport prefix="d" taglib="lib/data"/>
<cfimport prefix="layout" taglib="layout"/>
</cfsilent><m:silent silent="No">
<cffunction name="hideNonPositive">
<cfargument name="a"/>
<cfreturn (a GT 0)? a : ""/>
</cffunction>
<m:prepare_ls entity="area" pageInfoOut="pageInfo" trackOut="tr"/>
<m:filter_settings target="#pageInfo.entity#_ls">
<m:filterparam filter=#filter# param="quickfilter" ftype="string" prefix="%" suffix="%" expression="((p.project like ?) OR (p.customer like ?) OR (p.customer_alias like ?) OR (p.area_class_type like ?) OR (p.division like ?) OR (p.performer_short like ?))" default=""/>
</m:filter_settings>
<cfset pageInfo.settings.filter=#filter#/>
<cftry>
<cfquery name="qRead" datasource="#request.DS#">
select
<d:field_set titleMapOut="titleMap" lengthOut="fieldCount">
<d:field title="ID" cfSqlType="CF_SQL_INTEGER">m.area_id</d:field>
<d:field title="Код группы">m.area_code</d:field>
<d:field title="Аналитический код">m.analytic_code</d:field>
<d:field title="Группа (RUS)">m.area</d:field>
<d:field title="Группа (ENG)">m.area_en</d:field>
<d:field title="Абстр. услуг">(select count(*) from abstract_service a where a.area_id=m.area_id) as as_cnt</d:field>
<d:field title="Вариантов услуг">(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</d:field>
</d:field_set>
from area m
where 1=1 <m:filter_build filter=#pageInfo.settings.filter#/>
order by <m:order_build sortArray=#pageInfo.settings.sort.sortArray# fieldCount=#fieldCount#/>
</cfquery>
<cfcatch type="database">
<m:ls_catch catch=#cfcatch# status=#pageInfo.status#/>
</cfcatch>
</cftry>
<cfquery name="qCountTotal" datasource="#request.DS#">
select count(*) as cnt from area where 1=1
</cfquery>
</m:silent><!---
-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
---><cfif isDefined("output_xls")>
<layout:xml qRead=#qRead# titleMap=#titleMap# filename="#pageInfo.entity#.xml"/>
<cfabort/>
</cfif><cfif isDefined("output_json")>
<layout:json qRead=#qRead# titleMap=#titleMap# filename="#pageInfo.entity#.json"/>
<cfabort/>
</cfif><!---
---><layout:page section="header" pageInfo=#pageInfo#>
<layout:attribute name="title">
<cfoutput><b>Группы услуг</b></cfoutput>
</layout:attribute>
<layout:attribute name="controls">
<!---skip filter link, filter is not implemented--->
<!---<layout:language_switch/>--->
</layout:attribute>
</layout:page>
<cfif pageInfo.readPermitted() AND !pageInfo.status.errorState>
<layout:grid_summary
recordCount=#qRead.recordCount#
totalCount=#qCountTotal.cnt#
footerOut="gridFooter"
excelLink="Yes"
jsonLink="Yes"
/>
<!--- так довольно громоздко, но можно обойтись без Dynamic Evaluation --->
<cfset queryAddColumn(qRead,'f_link_view_edit')/>
<cfset titleMap.f_link_view_edit={ordinal=#StructCount(titleMap)+1#}/><!--- *** Это легко забыть, потому что TitleMap никак не сцеплен с qRead. Напрашивается: упаковать их в одну обертку (но тогда обращение станет длиннее). Еще идея - назвать qRead и TitleMap так, чтобы была видна их связь. --->
<!--- <cfdump var=#titleMap#/> --->
<cfset queryAddColumn(qRead,'f_link_del')/>
<cfset titleMap.f_link_del={ordinal=0}/>
<!--- <cfdump var=#titleMap#/> --->
<cfoutput query=#qRead# startRow=#pageInfo.nStart# maxRows=#pageInfo.recordsPerPage#><!--- *** Здесь некомфортное дублирование startRow, maxRows с вызовом c:table ниже, причем в c:table оно закопано в модуль, и аргументы называются по-разному... но мы хотим немного сэкономить и не обрабатывать весь резалтсет --->
<cfsavecontent variable="qRead.f_link_view_edit">
<a href="#pageInfo.entity#.cfm?#pageInfo.entity#_id=#area_id#&#tr.fwx#" name="#area_id#" <cfif pageInfo.writePermitted()>title="редактировать" class="edit"<cfelse>title="просмотр" class="view"</cfif>></a>
</cfsavecontent>
<cfsavecontent variable="qRead.f_link_del">
<cfif pageInfo.writePermitted()><a href="#pageInfo.entity#_del.cfm?#pageInfo.entity#_id=#area_id#&#tr.fwx#" name="#area_id#" class="del" title="удалить"></a></cfif>
</cfsavecontent>
</cfoutput>
<c:table query=#qRead# recordsPerPage=#pageInfo.recordsPerPage# nStart=#pageInfo.nStart# titleMap=#titleMap# sortArray=#pageInfo.settings.sort.sortArray# class="worktable wide">
<c:column width="1%" sortable="false"><!---*** class="c" не пробрасывается --->
<c:th><c:link_add canWrite=#pageInfo.writePermitted()# entity=#pageInfo.entity# fwx=#tr.fwx#/></c:th>
<c:td field="f_link_view_edit" class="c"/>
<!--- <a href="#CALLER.pageInfo.entity#.cfm?#CALLER.pageInfo.entity#_id=#area_id#&#CALLER.tr.fwx#" name="#area_id#" <cfif pageInfo.writePermitted()>title="редактировать" class="edit"<cfelse>title="просмотр" class="view"</cfif>></a> --->
</c:column>
<c:column width="3%" field="area_id"/>
<c:column width="5%" field="area_code"/>
<c:column width="5%" field="analytic_code"/>
<c:column width="20%" field="area"/>
<c:column width="20%" field="area_en"/>
<c:column width="5%" field="as_cnt" formatter=#hideNonPositive#><c:td class="c"/></c:column>
<c:column width="5%" field="svc_cnt" formatter=#hideNonPositive#><c:td class="c"/></c:column>
<c:column width="1%" sortable="false">
<c:td field="f_link_del" class="c"/>
</c:column>
</c:table>
<cfoutput>#gridFooter#</cfoutput>
</cfif>
<layout:page section="footer"/>
<!---*** критика синтаксиса: CALLER в данном контексте выглядит ужасно. Когда применять #service_id#, когда ##service_id##
Может быть, стоит отказаться от пользовательского тега и обратиться к более ровному способу форматирования.
Например (явно плохая идея, но для примера) печатать таблицу, а потом ее парсить и переформатировать... некоторые это могли сделать на клиенте.
На самом деле все, что нужно нам из скоупа CALLER, уже определено в момент вызова тега, и мы можем заменить CALLER на <cfoutput>. Это тоже неуклюже. То есть тащить весь CALLER внутрь как бы избыточно (не говоря о том, что можно словить каких-то сложносочиненных глюков)
Сортировка должна происходить на сервере БД, иначе паджинатор бесполезен. Вытаскивать резалтсет на сервер приложений и там его сортировать выглядит очень плохим решением (еще глупее сортировать на клиенте). Для корректной сортировки нужно делать композицию колонок на сервере, что не очень хорошо, например, с нуллами надо обращаться осторожно (вот аргумент в пользу NOT NULL), и синтаксис становится зависим от диалекта SQL. Возможный вариант, если у нас композиция из 2 колонок, сортировать по обеим. Либо отказаться от сортировки по композитной колонке, что кажется проще всего.
Контекст query выглядит естественно, но эта простота вводит в заблуждение - на вид обычный синтаксис, а функции недоступны (паковать в реквест еще то удовольствие), контекст страницы недоступен, ищи его через CALLER - догадаться невозможно.
Можно передавать внутрь тега все, что может понадобиться - функции, переменные?
Можно придумать собственный синтаксис, заменяющий cfif
--->
<!--- тонкости
в примере ниже
Атрибуты тега вычисляются до вызова, в контексте вызывающей страницы, а содержимое обрабатывается самим тегом в его контексте (собственно, мы сказали ему так делать). Но при чтении исходника это совсем не очевидно и может порвать мозг.
Можно, конечно, обрабатывать исключение и подставлять контекст вызывающей страницы? Как заставить тег видеть контекст вызывающей страницы? Попробовал взять весь тег в cfoutput. В результате перестал видеть поля query. Откатился.
Печаль в том, что мы в одном месте (чего и хотели - чтобы рядом) получаем контекст вызывающей страницы и контекст query, поля которого хотим называть неквалифицированными именами.
Вариант: действуем в 2 прохода, сначала формируем структуру, а потом рендерим ее. В принципе, с учетом пагинации, может потреблять памяти меньше, чем сам query
<c:th><c:link_add canWrite=#pageInfo.writePermitted()# entity=#pageInfo.entity# fwx=#tr.fwx#/><cfoutput>#pageInfo.entity#</cfoutput>#pageInfo.entity#</c:th> --->
<!--- Хотелось бы:
чтобы контекст страницы был явно доступен во всех вложенных тегах. >> The custom tag's Caller scope is a reference to the calling page's Variables scope (добавить все из CALLER в Variables? А не зациклимся?
чтобы итератор работал прозрачно, как в cfoutput query
Как обойтись без динамического исполнения? Для всех форматтеров снаружи объявлять closure? нечитабельно.
Хотя читабельность простыней ниже - так себе
В общем, получается пока плохо
? полиморфизм i18(measure_short) - как бы избежать отдельной далекой декларации длинного списка похожих функций. Можно полю придать признак языка? Соглашение с суффиксами? Это уже какая-то морфология получается!
--->

View File

@ -1,121 +0,0 @@
<cfsilent>
<cfimport prefix="m" taglib="lib"/>
<cfimport prefix="c" taglib="lib/controls"/>
<cfimport prefix="d" taglib="lib/data"/>
<cfimport prefix="layout" taglib="layout"/>
</cfsilent><m:silent silent="No">
<m:prepare_ls entity="area" pageInfoOut="pageInfo" trackOut="tr"/>
<m:filter_settings target="#pageInfo.entity#_ls">
<m:filterparam filter=#filter# param="quickfilter" ftype="string" prefix="%" suffix="%" expression="((p.project like ?) OR (p.customer like ?) OR (p.customer_alias like ?) OR (p.area_class_type like ?) OR (p.division like ?) OR (p.performer_short like ?))" default=""/>
</m:filter_settings>
<cfset pageInfo.settings.filter=#filter#/>
<cftry>
<cfquery name="qRead" datasource="#request.DS#">
select
<d:field_set titleMapOut="titleMap" lengthOut="fieldCount">
<d:field title="ID" cfSqlType="CF_SQL_INTEGER">m.area_id</d:field>
<d:field title="Код группы">m.area_code</d:field>
<d:field title="Аналитический код">m.analytic_code</d:field>
<d:field title="Группа">m.area</d:field>
</d:field_set>
from area m
where 1=1 <m:filter_build filter=#pageInfo.settings.filter#/>
order by <m:order_build sortArray=#pageInfo.settings.sort.sortArray# fieldCount=#fieldCount#/>
</cfquery>
<cfcatch type="database">
<m:ls_catch catch=#cfcatch# status=#pageInfo.status#/>
</cfcatch>
</cftry>
<cfquery name="qCountTotal" datasource="#request.DS#">
select count(*) as cnt from area where 1=1
</cfquery>
</m:silent><!---
-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
---><cfif isDefined("output_xls")>
<layout:xml qRead=#qRead# titleMap=#titleMap# filename="#pageInfo.entity#.xml"/>
<cfabort/>
</cfif><cfif isDefined("output_json")>
<layout:json qRead=#qRead# titleMap=#titleMap# filename="#pageInfo.entity#.json"/>
<cfabort/>
</cfif><!---
---><layout:page section="header" pageInfo=#pageInfo#>
<layout:attribute name="title">
<cfoutput><b>Группы каталога</b></cfoutput>
</layout:attribute>
</layout:page>
<cfif pageInfo.readPermitted() AND !pageInfo.status.errorState>
<layout:grid_summary
recordCount=#qRead.recordCount#
totalCount=#qCountTotal.cnt#
footerOut="gridFooter"
excelLink="Yes"
jsonLink="Yes"
/>
<cfscript>
function uc(x) {return UCase(x);}
</cfscript>
<c:grid query=#qRead# titleMap=#titleMap# sortArray=#pageInfo.settings.sort.sortArray# class="worktable">
<c:column width="1%">
<c:th><c:link_add canWrite=#pageInfo.writePermitted()# entity=#pageInfo.entity# fwx=#tr.fwx#/></c:th>
<c:td>
<!---<c:link_view_edit canWrite="#CALLER.pageInfo.writePermitted()#" entity="#CALLER.pageInfo.entity#" id=#qRead.area_id# fwx="#CALLER.tr.fwx#"/>--->
<a href="#CALLER.pageInfo.entity#.cfm?#CALLER.pageInfo.entity#_id=#area_id#&#CALLER.tr.fwx#" name="#area_id#" <cfif pageInfo.writePermitted()>title="редактировать" class="edit"<cfelse>title="просмотр" class="view"</cfif>></a>
</c:td>
</c:column>
<c:column width="3%" lang="en">
<c:th field="area_id">rrrrrrr</c:th>
<c:td>(#area_id#)</c:td>
</c:column>
<c:column width="5%" field="area_code">_#area_code#_</c:column>
<c:column width="5%" field="area_code"></c:column>
<c:column width="5%" field="area_code"/>
<!---<c:column width="80%" field="area" formatter=#function (x) {return UCase(x)}#/>---><!---длинно--->
<c:column width="80%" field="area" formatter=#uc#/><!---если переиспользовать форматтер на той же странице, можно так--->
</c:grid>
<!--- <table class="worktable">
<thead>
<layout:grid_head titleMap=#titleMap# sortArray=#pageInfo.settings.sort.sortArray#>
<th width="1%">
<c:link_add canWrite=#pageInfo.writePermitted()# entity=#pageInfo.entity# fwx=#tr.fwx#/>
</th>
<th width="3%"><layout:column_head name="area_id"/></th>
<th width="5%"><layout:column_head name="area_code"/></th>
<th width="80%"><layout:column_head name="area"/></th>
</layout:grid_head>
</thead>
<cfoutput query="qRead" maxrows=#pageInfo.recordsPerPage# startrow=#pageInfo.nStart#>
<tr>
<td class="c">
<c:link_view_edit canWrite=#pageInfo.writePermitted()# entity=#pageInfo.entity# id=#qRead[pageInfo.entity&'_id'][currentRow]# fwx=#tr.fwx#/>
</td>
<td class="c">#area_id#</td>
<td>#area_code#</td>
<td>#area#</td>
</tr>
</cfoutput>
</table>--->
<cfoutput>#gridFooter#</cfoutput>
</cfif>
<layout:page section="footer"/>

View File

@ -1,200 +0,0 @@
<!--- примитивный конструктор селектов, чтобы не набирать руками колонки --->
<!--- v0.1 2018.02.27 --->
<cfimport prefix="m" taglib="lib"/>
<cfimport prefix="d" taglib="lib/data"/>
<cfparam name="obj" default=""/>
<cfparam name="ds" default="metadata"/>
<cfparam name="out" default="field_set,bean"/>
<!---<cfswitch expression=#ds#>
<cfcase value="metadata"><cfset request.ds="mms"/></cfcase>
<cfcase value="data"><cfset request.ds="ditcloud"/></cfcase>
<cfdefaultcase><cfset request.ds=""/></cfdefaultcase>
</cfswitch>--->
<cfquery name="qObj" datasource="#request.DS#">
select o.type, o.name from sys.objects o where o.type in ('U','V') order by o.type, o.name
</cfquery>
<!---<cfdump var=#qObj#/>--->
<cfquery name="qCol" datasource="#request.DS#">
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=<cfqueryparam cfsqltype="cf_sql_varchar" value="#obj#"/>
</cfquery>
<!---<cfdump var=#qCol#/>--->
<form action="" method="post">
<!--- <select name="ds" onchange="submit();">
<option <cfif #ds# EQ "data"> selected</cfif>>data</option>
<option <cfif #ds# EQ "metadata"> selected</cfif>>metadata</option>
</select>--->
<select name="obj">
<cfoutput query="qObj">
<option <cfif #obj# EQ #name#> selected</cfif> value="#name#">
<cfif #trim(qObj.type)# EQ 'U'>(table)<cfelseif #trim(qObj.type)# EQ 'V'>(view)<cfelse></cfif> #name#
</option>
</cfoutput>
</select>
<input type="checkbox" name="out_all" id="out_all" value="1" onchange="; for (var i=0, checkboxes=document.getElementsByName('out'), n=checkboxes.length; i < n ; i++) {checkboxes[i].checked = this.checked;}"/>
<label for="out_all">(все)</label>
<cfloop list="field_set,select,insert,update,bean,grid,detail" item="outformat">
<cfoutput>
<input type="checkbox" name="out" id="#outformat#" value="#outformat#"<cfif structKeyExists(form, "out")><cfif listFind(form.out,outformat)> checked</cfif></cfif>/>
<label for="#outformat#">#outformat#</label>
</cfoutput>
</cfloop>
<input type="submit" name="do" value="Сформировать"/>
</form>
<cfif structKeyExists(form, "do")>
<cfif structKeyExists(form, "out")>
<cfif listFind(form.out,"field_set")>
<pre>
select
&lt;d:field_set titleMapOut="titleMap" lengthOut="fieldCount"&gt;<cfoutput query="qCol">
&lt;d:field title="#name#"&gt;#name#&lt;/d:field&gt;</cfoutput>
&lt;/d:field_set&gt;
from <cfoutput>#obj#</cfoutput>
</pre>
</cfif>
<cfif listFind(form.out,"select")>
<cfset comma="No"/>
<pre>
select <cfoutput query="qCol">
<cfif comma>,<cfelse><cfset comma="Yes"/></cfif>#name#</cfoutput>
from <cfoutput>#obj#</cfoutput>
</pre>
</cfif>
<cfif listFind(form.out,"insert")>
<pre>
insert into <cfoutput>#obj#</cfoutput> (<cfset comma="No"/>
<cfoutput query="qCol"><cfif !is_identity><cfif comma>,<cfelse><cfset comma="Yes"/></cfif>#name#</cfif></cfoutput>
) values (<cfset comma="No"/><cfoutput query="qCol"><cfif !is_identity>
<cfif comma>,<cfelse><cfset comma="Yes"/></cfif>&lt;cfqueryparam cfsqltype="cf_sql_#fieldType(system_type_id)#" value="###name###"/&gt;</cfif></cfoutput>
)
</pre>
</cfif>
<cfif listFind(form.out,"update")>
<cfset comma="No"/>
<pre>
update <cfoutput>#obj#</cfoutput> set <cfoutput query="qCol"><cfif !is_identity>
<cfif comma>,<cfelse><cfset comma="Yes"/></cfif>#name#=&lt;cfqueryparam cfsqltype="cf_sql_#fieldType(system_type_id)#" value="###name###"/&gt;</cfif></cfoutput>
<cfoutput>where #obj#_id=&lt;cfqueryparam cfsqltype="cf_sql_integer" value="###obj#_id##" null=##!isNumeric(#obj#_id)##/&gt;</cfoutput>
</pre>
</cfif>
<cfif listFind(form.out,"bean")>
<pre>
&lt;d:bean readonly=#!pageInfo.writePermitted()# table="<cfoutput>#obj#</cfoutput>" datasource="#request.DS#" output="d" status="status"&gt;<cfoutput query="qCol">
<cfswitch expression=#name#>
<cfcase value="creator_id">&lt;d:param field="creator_id" type="integer" value="##request.usr_id##" skipUpdate/&gt;</cfcase>
<cfcase value="updater_id">&lt;d:param field="updater_id" type="integer" value="##request.usr_id##"/&gt;</cfcase>
<cfcase value="dt_created">&lt;d:param field="dt_created" type="timestamp" value="##Now()##" skipUpdate/&gt;</cfcase>
<cfcase value="dt_updated">&lt;d:param field="dt_updated" type="timestamp" value="##Now()##"/&gt;</cfcase>
<cfdefaultcase>&lt;d:param field="#name#" type="#fieldType(system_type_id)#"<cfif (system_type_id EQ 167) AND (max_length GT 0)> size="#max_length#" preprocessor=##cleanInput##</cfif><cfif (system_type_id EQ 167) AND (max_length LE 0)> preprocessor=##plain2HtmClean##</cfif><cfif "#name#" EQ "#obj#_id"> key autoincrement<cfelseif is_nullable AND listFind("127,104,106,62,59,36,56,108,52,41,58,61,189,48",system_type_id)> forNull=""</cfif><cfif system_type_id EQ 104> default="0" init="0"</cfif>/&gt;</cfdefaultcase>
</cfswitch></cfoutput>
&lt;/d:bean&gt;
</pre>
</cfif>
<cfif listFind(form.out,"grid")>
<pre>
&lt;table class="worktable"&gt;
&lt;thead&gt;
&lt;layout:grid_head titleMap=#titleMap# sortArray=#pageInfo.settings.sort.sortArray#&gt;
<cfoutput query="qCol">&lt;th&gt;&lt;layout:column_head name="#name#"/&gt;&lt;/th&gt;
</cfoutput>
&lt;/layout:grid_head&gt;
&lt;/thead&gt;
&lt;cfoutput query="qRead" maxrows="#pageInfo.recordsPerPage#" startrow="#pageInfo.nStart#"&gt;
&lt;tr&gt;
<cfoutput query="qCol">&lt;td class="c"&gt;##<cfif listFind("58,61,189",system_type_id)>dateFormat(#name#,'DD.MM.YYYY')<cfelse>#name#</cfif>##&lt;/td&gt;
</cfoutput>
&lt;/tr&gt;
&lt;/cfoutput&gt;
&lt;/table&gt;
</pre>
</cfif>
<cfif listFind(form.out,"detail")>
<pre>
&lt;div class="detail"&gt;
<cfoutput query="qCol"><cfif "#name#" NEQ "#obj#_id">
&lt;div class="tr"&gt;
&lt;div class="th"&gt;#name#&lt;/div&gt;
&lt;div class="td"&gt;<cfif ((system_type_id EQ 167) AND (max_length GT 0)) OR listFind("127,106,62,59,36,56,108,52,41,58,61,189,48",system_type_id)>&lt;input type="text" name="#name#" id="#name#" value="<cfelseif ((system_type_id EQ 167) AND (max_length LE 0))>&lt;textarea rows="5" cols="70" name="#name#" id="#name#"&gt;<cfelseif system_type_id EQ 104>&lt;input type="checkbox" name="#name#" id="name" value="1"&lt;cfif (</cfif><!---
--->##<cfif listFind("58,61,189",system_type_id)>dateFormat(d.#name#,'DD.MM.YYYY')<cfelse>d.#name#</cfif>##<cfif ((system_type_id EQ 167) AND (max_length GT 0)) OR listFind("127,106,62,59,36,56,108,52,41,58,61,189,48",system_type_id)>"/&gt;<cfelseif ((system_type_id EQ 167) AND (max_length LE 0))>&lt;/textarea&gt;<cfelseif system_type_id EQ 104> GT 0)&gt; checked&lt;/cfif&gt;/&gt;</cfif><!---
--->&lt;/div&gt;
&lt;/div&gt;
</cfif></cfoutput>
&lt;/div&gt;
</pre>
</cfif>
</cfif>
</cfif>
<cffunction name="fieldType" output="No">
<cfargument name="xtype"/>
<cfswitch expression=#xtype#>
<cfcase value="127"><cfreturn "bigint"/></cfcase>
<cfcase value="104"><cfreturn "integer"/></cfcase><!---bit--->
<cfcase value="175"><cfreturn "char"/></cfcase>
<cfcase value="40"><cfreturn "date"/></cfcase>
<cfcase value="106"><cfreturn "decimal"/></cfcase>
<cfcase value="62"><cfreturn "double"/></cfcase><!---float--cf_sql_double--->
<cfcase value="59"><cfreturn "float"/></cfcase><!---real--cf_sql_float--->
<cfcase value="36"><cfreturn "idstamp"/></cfcase><!---uniqueidentifier--->
<cfcase value="56"><cfreturn "integer"/></cfcase>
<cfcase value="108"><cfreturn "numeric"/></cfcase>
<!---<cfcase value="59"><cfreturn "real"/></cfcase>--->
<cfcase value="52"><cfreturn "smallint"/></cfcase>
<cfcase value="41"><cfreturn "time"/></cfcase>
<cfcase value="58,61,189"><cfreturn "timestamp"/></cfcase><!---smalldatetime,datetime,timestamp--->
<cfcase value="48"><cfreturn "tinyint"/></cfcase>
<cfcase value="165"><cfreturn "varbinary"/></cfcase>
<cfcase value="167,231"><cfreturn "varchar"/></cfcase>
<cfdefaultcase><cfreturn "varchar"/></cfdefaultcase>
</cfswitch>
</cffunction>
<!---
CF_SQL_BIGINT
CF_SQL_BIT
CF_SQL_CHAR
CF_SQL_BLOB
CF_SQL_CLOB
CF_SQL_DATE
CF_SQL_DECIMAL
CF_SQL_DOUBLE
CF_SQL_FLOAT
CF_SQL_IDSTAMP
CF_SQL_INTEGER
CF_SQL_LONGVARCHAR
CF_SQL_MONEY
CF_SQL_MONEY4
CF_SQL_NUMERIC
CF_SQL_REAL
CF_SQL_REFCURSOR
CF_SQL_SMALLINT
CF_SQL_TIME
CF_SQL_TIMESTAMP
CF_SQL_TINYINT
CF_SQL_VARCHAR
--->

View File

@ -140,56 +140,7 @@
<layout:page section="extension" closeForm="No"/>
<cfif d.contract_id GT 0>
<cfquery name="qSpecification">
select
s.specification_id
,s.specification
,(select count(*) from specification_item i where i.specification_id=s.specification_id) as item_cnt
/*,(select count(*) from specification_version v where v.specification_id=s.specification_id) as version_cnt*/
from specification s
where s.contract_id=<cfqueryparam cfsqltype="cf_sql_integer" value="#d.contract_id#"/>
order by 1
</cfquery>
<cfoutput>
<h4>Спецификации (#qSpecification.recordCount#)</h4>
</cfoutput>
<cfif pageInfo.writePermitted()>
<cfoutput>
<cfset addUrl="specification.cfm?specification_id=-1&contract_id=#d.contract_id#&#tr.fwx#"/>
<button type="button" class="maincontrol" onclick="document.location.href='#addUrl#'">
<a href="#addUrl#">Создать</a>
</button>
</cfoutput>
</cfif>
Как правило, в договоре 1 спецификация, а ее версии определяются дополнительными соглашениями
<table class="worktable">
<thead>
<tr>
<th></th>
<th>Номер спецификации</th>
<th>Строк</th>
<th></th>
</tr>
</thead>
<cfoutput query="qSpecification">
<tr>
<td>
<c:link_view_edit canWrite=#pageInfo.writePermitted()# entity="specification" id=#specification_id# fwx=#tr.fwx#/>
</td>
<td>#specification#</td>
<td class="c">
<cfif item_cnt GT 0>#item_cnt#</cfif>
</td>
<td class="c">
<c:link_del canWrite=#pageInfo.writePermitted()# entity="specification" id=#specification_id# fwx=#tr.fwx#/>
</td>
</tr>
</cfoutput>
</table>
<cfif d.contract_id GT 0>
<cfquery name="qAgreement">
select
@ -244,6 +195,61 @@
</cfoutput>
</table>
любопытное последствие использования составного ключа: отпадает желание делать для сущности самостоятельный реестр (может быть, только если есть явная сущность-владелец, как договор для соглашения). Это аналогично отразится на структуре ReST API URL, если вдруг
<!--- ---------------------------------------------------- --->
<!--- ---------------------------------------------------- --->
<!--- ---------------------------------------------------- --->
<cfquery name="qSpecification">
select
s.specification_id
,s.specification
,s.descr
,(select count(*) from specification_item i where i.specification_id=s.specification_id) as item_cnt
/*,(select count(*) from specification_version v where v.specification_id=s.specification_id) as version_cnt*/
from specification s
where s.contract_id=<cfqueryparam cfsqltype="cf_sql_integer" value="#d.contract_id#"/>
order by 1
</cfquery>
<cfoutput>
<h4>Спецификации (#qSpecification.recordCount#)</h4>
</cfoutput>
<cfif pageInfo.writePermitted()>
<cfoutput>
<cfset addUrl="specification.cfm?specification_id=-1&contract_id=#d.contract_id#&#tr.fwx#"/>
<button type="button" class="maincontrol" onclick="document.location.href='#addUrl#'">
<a href="#addUrl#">Создать</a>
</button>
</cfoutput>
</cfif>
Как правило, в договоре 1 спецификация, а ее версии определяются дополнительными соглашениями
<table class="worktable">
<thead>
<tr>
<th></th>
<th>Номер спецификации</th>
<th>Строк</th>
<th>Описание</th>
<th></th>
</tr>
</thead>
<cfoutput query="qSpecification">
<tr>
<td>
<c:link_view_edit canWrite=#pageInfo.writePermitted()# entity="specification" id=#specification_id# fwx=#tr.fwx#/>
</td>
<td>#specification#</td>
<td class="c">
<cfif item_cnt GT 0>#item_cnt#</cfif>
</td>
<td>#descr#</td>
<td class="c">
<c:link_del canWrite=#pageInfo.writePermitted()# entity="specification" id=#specification_id# fwx=#tr.fwx#/>
</td>
</tr>
</cfoutput>
</table>
</cfif>
<layout:page section="extension" closeForm="Yes"/> <!--- *** правильно так? --->

View File

@ -26,7 +26,8 @@
<d:field title="Номер договора">d.contract</d:field>
<d:field title="Дата договора">d.dt_contract</d:field>
<d:field title="Описание">d.descr</d:field>
<d:field title="Соглашений">(select count(*) from agreement s where s.contract_id=d.contract_id) as spec_cnt</d:field>
<d:field title="Соглашений">(select count(*) from agreement s where s.contract_id=d.contract_id) as agreement_cnt</d:field>
<d:field title="Спецификаций">(select count(*) from specification s where s.contract_id=d.contract_id) as spec_cnt</d:field>
</d:field_set>
from contract d
join contragent c on (d.contragent_id=c.contragent_id)
@ -97,13 +98,13 @@ select count(*) as cnt from contract where 1=1
<c:column width="1%" sortable="false"><!---*** class="c" не пробрасывается --->
<c:th><c:link_add canWrite=#pageInfo.writePermitted()# entity=#pageInfo.entity# fwx=#tr.fwx#/></c:th>
<c:td field="f_link_view_edit" class="c"/>
<!--- <a href="#CALLER.pageInfo.entity#.cfm?#CALLER.pageInfo.entity#_id=#contract_id#&#CALLER.tr.fwx#" name="#contract_id#" <cfif pageInfo.writePermitted()>title="редактировать" class="edit"<cfelse>title="просмотр" class="view"</cfif>></a> --->
</c:column>
<c:column width="2%" field="contract_id"><c:td class="r"/></c:column>
<c:column width="10%" field="contragent"/>
<c:column width="10%" field="contract"/>
<c:column width="5%" field="dt_contract" formatter=#function(dt){return dateformat(dt,"YYYY-MM-DD");}#><c:td class="c"/></c:column>
<c:column width="15%" field="descr"/>
<c:column width="2%" field="agreement_cnt" formatter=#hideNonPositive#><c:td class="c"/></c:column>
<c:column width="2%" field="spec_cnt" formatter=#hideNonPositive#><c:td class="c"/></c:column>
<c:column width="1%" sortable="false">
<c:td field="f_link_del" class="c"/>

View File

@ -5,12 +5,7 @@
<cfimport prefix="layout" taglib="layout"/>
</cfsilent>
<m:prepare_ls entity="price" accessObject="price_rpt" pageInfoOut="pageInfo" trackOut="tr"/><!---synthetic entity, not a table--->
<m:filter_settings target="#pageInfo.entity#_ls">
<m:filterparam filter=#filter# param="quickfilter" ftype="string" prefix="%" suffix="%" expression="((p.project like ?) OR (p.customer like ?) OR (p.customer_alias like ?) OR (p.param_class_type like ?) OR (p.division like ?) OR (p.performer_short like ?))" default=""/>
</m:filter_settings>
<cfset pageInfo.settings.filter=#filter#/>
<!---<cftry>--->

View File

@ -1,8 +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
setx datasource_spec_class org.postgresql.Driver /M
setx datasource_spec_connectionString jdbc:postgresql://localhost:5432/spec /M
setx datasource_spec_username postgres /M
setx datasource_spec_password encrypted:8ea2101f286dfcf2947cb2162e927cb769b3f845b6d4c57ef2ae89463d72d97842a2228c7ba562a24ee8eaf728350ab6 /M
setx datasource_spec_connectionLimit 5 /M
pause

View File

@ -65,13 +65,12 @@ insert into contract (contragent_id,contract,dt_contract) values (2,'test',CURRE
-- соглашение обеспечивает явную прикладную версионность
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 действующее соглашение - которые до него, те устарели, которые после, те в проекте
,deal_uid uuid NOT NULL DEFAULT gen_random_uuid() -- ýòî ìîã áûòü ïåðâè÷íûé êëþ÷, ïîêà îí íå èñïîëüçóåòñÿ - òîëüêî èìèòèðóåò êëþ÷ ñäåëêè
,descr text NULL
,dt_created timestamptz NOT NULL default CURRENT_TIMESTAMP --
@ -82,6 +81,8 @@ create table agreement (
);
ALTER TABLE agreement OWNER TO dbo;
insert into agreement (contract_id,agreement_version,dt_agreement,is_actual) values (1,0,CURRENT_TIMESTAMP,true);
-- alter table agreement add deal_uid uuid NOT NULL DEFAULT gen_random_uuid();
CREATE INDEX IF NOT EXISTS UX_deal_uid ON agreement(deal_uid);
-- шапка спецификации, не версионная (не темпоральная)
drop table if exists specification CASCADE;

View File

@ -1,3 +1,22 @@
2025-06-14 11:02:46
Центральный селект
select * from specification_item_version siv
join specification_item si on (siv.specification_item_uid=si.specification_item_uid)
join specification s on (si.specification_id=s.specification_id)
join agreement a on (s.contract_id=a.contract_id AND siv.agreement_version=a.agreement_version)
Теперь дифференциальный вариант. Для каждого варианта строки можно найти предыдущий (если он есть) и с ним сравнивать.
Нужно ли добавить типы экземпляров инсталл и пейг? С пейгом чтобы получить дифф, нужно количество - иначе мы можем дифф только на цену. Если мы хотим брать во внимание дату НОУ, то без количества разницу в стоимости мы не получим.
Как вообще учитывать дату в диффе? Или никак, просто передавать.
16:12 12.06.2025
Предлагается использовать конечную дату только для завершения действия всей строки спеки. Тогда ее просто убрать из версии? Некорректно, она же возникает в какой-то версии.
Если захочется делать одним соглашением 2 изменения строки, можно соглашению сделать суррогатный ключ, а номер соглашения для версии строки убрать из первичного ключа
2025-06-10
Отчет-дифф
Сделать автосоздание нового соглашения (например, если самое новое не действует - аттачить изменения к нему, если действует - создать новое не действующее)
Сделать прозрачно-версионное редактирование спецификации
Форма-отчет версии спецификации доделать
2025-06-02
можно отметить, что тут смешаны версионность допника и темпоральность строки
Можно сделать таблицу, собирающую версии строк, чтобы не искать каждый раз (а может, нам не нужен снапшот на произвольную дату? или версию допника - вот, я уже запутался)

View File

@ -1,46 +0,0 @@
<cfsilent>
<cfimport prefix="m" taglib="lib"/>
<cfimport prefix="c" taglib="lib/controls"/>
<cfimport prefix="d" taglib="lib/data"/>
<cfimport prefix="layout" taglib="layout"/>
</cfsilent><m:silent silent="No">
<m:prepare_filter entity="export" pageInfoOut="pageInfo" trackOut="tr" lsPage="."/>
<m:filter_settings target="export">
<m:filterparam filter=#filter# param="service_type_id" ftype="numeric" compare="EQ" field="a.service_type_id" default=""/>
<m:filterparam filter=#filter# param="abstract_service" ftype="string" compare="LIKE%" field="a.abstract_service" default=""/>
<m:filterparam filter=#filter# param="code" ftype="string" compare="LIKE%" field="a.code" default=""/>
</m:filter_settings>
</m:silent><!---
-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
---><!---
---><layout:page section="header" pageInfo=#pageInfo#>
<layout:attribute name="title">
<cfoutput><b>#i18("Экспорт","Export")#</b></cfoutput>
</layout:attribute>
<layout:attribute name="controls">
<!---skip filter link, filter is not implemented--->
<!---<layout:language_switch/>--->
</layout:attribute>
</layout:page>
<cfif pageInfo.readPermitted() AND !pageInfo.status.errorState>
<div style="padding:2em; font-size:110%">
<a href="sc_onyma_service.cfm">SC_onyma_service</a><br/>
<a href="sc_service_param_price.cfm">SC_service_param_price</a><br/>
<a href="sc_rcode.cfm">SC_Rcode</a><br/>
<a href="sc_service_param_price_service_rcode.cfm">SC_service_param_price_Service_Rcode</a><br/>
</div>
</cfif>
<layout:page section="footer"/>

View File

@ -14,6 +14,7 @@
<c:menu_item acl="" page="contract_ls.cfm" label="Договоры"/>
<c:menu_item acl="" page="specification_ls.cfm" label="Спецификации"/>
<c:menu_item acl="" page="agreement_ls.cfm" label="Сделки"/>
<li class="menu-title">Справочники</li>

View File

@ -1,237 +0,0 @@
<cfsilent>
<cfimport prefix="m" taglib="lib"/>
<cfimport prefix="c" taglib="lib/controls"/>
<cfimport prefix="d" taglib="lib/data"/>
<cfimport prefix="layout" taglib="layout"/>
</cfsilent><m:silent silent="No">
<cffunction name="plain2HtmClean">
<cfargument name="s" type="string"/>
<cfreturn request.plain2htm(request.cleanHtm(s))/>
</cffunction>
<cffunction name="cleanInput">
<cfargument name="s" type="string"/>
<cfreturn htmlEditFormat(s)/>
</cffunction>
<m:prepare_detail entity="modifier" key="modifier_id" pageInfoOut="pageInfo"/>
<d:bean readonly=#!pageInfo.writePermitted()# table="#pageInfo.entity#" datasource="#request.DS#" output="d" status="status">
<d:param field="modifier_id" type="integer" key autoincrement/>
<d:param field="modifier_class_id" type="integer"/>
<d:param field="modifier" type="varchar" size="255" preprocessor=#cleanInput#/>
<d:param field="modifier_en" type="varchar" size="255" preprocessor=#cleanInput#/>
<d:param field="code" type="varchar" size="15" preprocessor=#cleanInput#/>
<d:param field="sort" type="integer" forNull=""/>
<d:param field="descr" type="varchar" preprocessor=#plain2HtmClean#/>
<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:bean>
<m:dispatch_detail
usePRG="No"<!---*** --->
pageInfo=#pageInfo#
id="#d.modifier_id#"
status=#pageInfo.status#
trackOut="tr"
idAttributesOut="id"
/>
<cfquery name="qUsr" datasource="#request.DS#">
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#=<cfqueryparam attributeCollection=#id#/>
</cfquery>
<!--- в данном случае пробуем выделить декорирующий селект, потому что селект упрощенного аудита одинаков для всех сущностей --->
<cfquery name="qDecoration" datasource="#request.DS#">
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=<cfqueryparam attributeCollection=#id#/>
</cfquery>
</m:silent><!---
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
---><layout:page section="header" pageInfo=#pageInfo#>
<layout:attribute name="title">
<cfoutput>
Характеристика (модификатор)
<cfif d.modifier_id GT 0>
<b>#qDecoration.modifier_class#</b>
[#d.modifier_class_id#]<cfif len(#qDecoration.modifier_class#) GT 0>:</cfif>
<b>#d.modifier#</b>
[#d.modifier_id#]
</cfif>
</cfoutput>
</layout:attribute>
</layout:page>
<cfif status.errorState GT 0>
<cfoutput><div class="err">#status.errorMessage#</div></cfoutput>
</cfif>
<cfoutput>
<input type="hidden" name="modifier_id" value="#d.modifier_id#"/>
<input type="hidden" name="track" value="#tr.self#"/>
<input type="hidden" name="pass" value=""/><!--- pass marker to prevent save on submit --->
<div class="detail">
<div class="tr">
<div class="th">Класс характеристики</div>
<div class="td">
<cfquery name="qModifierClass" datasource="#request.DS#">
select modifier_class_id, modifier_class
from modifier_class
order by 2
</cfquery>
<c:combo
query=#qModifierClass#
combo="modifier_class_id"
id="modifier_class_id"
key="modifier_class_id"
selected="#d.modifier_class_id#"
displayf="##modifier_class##"
empty=""
class=""
<!---onchange="submit();"--->
/>
<cfif d.modifier_id GT 0>
<cfif d.modifier_class_id GT 0>
<a href="modifier_class.cfm?modifier_class_id=#d.modifier_class_id#&#tr.fwx#">
<img src="img/edit.gif"/>
</a>
</cfif>
<a href="modifier_class.cfm?modifier_class_id=-1&#tr.fwx#">
<img src="img/add.gif"/>
</a>
</cfif>
</div>
</div>
<div class="tr">
<div class="th">Характеристика (RUS)</div>
<div class="td">
<input type="text" name="modifier" value="#d.modifier#" size="70"/>
</div>
</div>
<div class="tr">
<div class="th">Характеристика (ENG)</div>
<div class="td">
<input type="text" name="modifier_en" value="#d.modifier_en#" size="70"/>
</div>
</div>
<div class="tr">
<div class="th">Код</div>
<div class="td">
<input type="text" name="code" value="#d.code#" size="5"/>
</div>
</div>
<div class="tr">
<div class="th">Сортировка</div>
<div class="td">
<input type="text" name="sort" id="sort" value="#d.sort#" size="2" class="r"/>
<i>Целое число - порядок, в котором Характеристика будет выводиться в списке (или соответствующий Вариант услуги в списке вариантов). Рекомендуется ставить через 100, чтобы потом удобнее было тасовать</i>
</div>
</div>
<div class="tr">
<div class="th">Описание</div>
<div class="td">
<textarea name="descr" rows="10" cols="100">#request.htm2plain(d.descr)#</textarea>
</div>
</div>
<div class="tr">
<div class="th">Создано</div>
<div class="td">
#dateFormat(d.dt_created,'DD.MM.YYYY')# #timeFormat(d.dt_created,'HH:MM')#
#qUsr.creator# <cfif len(qUsr.creator_shortname)>(#qUsr.creator_shortname#)</cfif>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Изменено
#dateFormat(d.dt_updated,'DD.MM.YYYY')# #timeFormat(d.dt_updated,'HH:MM')#
#qUsr.updater# <cfif len(qUsr.updater_shortname)>(#qUsr.updater_shortname#)</cfif>
</div>
</div>
</div>
</cfoutput>
<layout:page section="extension" closeForm="Yes"/>
<cfif d.modifier_id GT 0>
<cfquery name="qService" datasource="#request.DS#">
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=<cfqueryparam cfsqltype="cf_sql_integer" value="#d.modifier_id#"/>
order by a.code, a.abstract_service
</cfquery>
<cfoutput>
<h4>Используется услугами (#qService.recordCount#)</h4>
</cfoutput>
<table class="worktable">
<thead>
<tr>
<th></th>
<th>Код услуги</th>
<th>Абстрактная услуга</th>
<th>Характеристика</th>
<th></th>
</tr>
</thead>
<cfoutput query="qService">
<tr>
<td>
<c:link_view_edit canWrite=#pageInfo.writePermitted()# entity="service" id=#service_id# fwx=#tr.fwx#/>
</td>
<td>
<cfif abstract_service_id GT 0>#abstract_service_code#.#d.code#</cfif>
</td>
<td>
<cfif abstract_service_id GT 0><a href="abstract_service.cfm?abstract_service_id=#abstract_service_id#&#tr.fwx#">#abstract_service#</a></cfif>
</td>
<td class="c">
#modifier#
</td>
<td class="c">
<c:link_del canWrite=#pageInfo.writePermitted()# entity="service" id=#service_id# fwx=#tr.fwx#/>
</td>
</tr>
</cfoutput>
</table>
</cfif>
<p>Конкретные услуги (варианты услуги) определяются значением характеристики-модификатора. В тривиальном случае услуга может иметь только один вариант. Разные варианты услуги могут иметь различный состав компонентов (более того, этот состав определяется именно для конкретной услуги), например, в разных кластерах виртуализации может быть доступен разный набор типов дисков. </p>
<p>Один и тот же класс модификатора может применяться к разным абстрактным услугам.</p>
<p>Модификатор может состоять из нескольких переменных, например, система виртуализации + частота процессора. В этом случае в справочник нужно включить все актуальные комбинации</p>
<layout:page section="footer"/>

View File

@ -1,205 +0,0 @@
<cfsilent>
<cfimport prefix="m" taglib="lib"/>
<cfimport prefix="c" taglib="lib/controls"/>
<cfimport prefix="d" taglib="lib/data"/>
<cfimport prefix="layout" taglib="layout"/>
</cfsilent><m:silent silent="No">
<cffunction name="plain2HtmClean">
<cfargument name="s" type="string"/>
<cfreturn request.plain2htm(request.cleanHtm(s))/>
</cffunction>
<cffunction name="cleanInput">
<cfargument name="s" type="string"/>
<cfreturn htmlEditFormat(s)/>
</cffunction>
<m:prepare_detail entity="modifier_class" key="modifier_class_id" pageInfoOut="pageInfo"/>
<d:bean readonly=#!pageInfo.writePermitted()# table="modifier_class" datasource="#request.DS#" output="d" status="status">
<d:param field="modifier_class_id" type="integer" key autoincrement/>
<d:param field="modifier_class" type="varchar" size="255" preprocessor=#cleanInput#/>
<d:param field="modifier_class_en" type="varchar" size="255" preprocessor=#cleanInput#/>
<d:param field="descr" type="varchar" preprocessor=#plain2HtmClean#/>
<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:bean>
<m:dispatch_detail
usePRG="No"<!---*** --->
pageInfo=#pageInfo#
id="#d.modifier_class_id#"
status=#pageInfo.status#
trackOut="tr"
idAttributesOut="id"
/>
<cfquery name="qDecoration" datasource="#request.DS#">
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#=<cfqueryparam attributeCollection=#id#/>
</cfquery>
</m:silent><!---
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
---><layout:page section="header" pageInfo=#pageInfo#>
<layout:attribute name="title">
<cfoutput>
Класс характеристики (модификатора)
<cfif d.modifier_class_id GT 0>
<b>#d.modifier_class#</b>
[#d.modifier_class_id#]
</cfif>
</cfoutput>
</layout:attribute>
</layout:page>
<cfif status.errorState GT 0>
<cfoutput><div class="err">#status.errorMessage#</div></cfoutput>
</cfif>
<cfoutput>
<input type="hidden" name="modifier_class_id" value="#d.modifier_class_id#"/>
<input type="hidden" name="track" value="#tr.self#"/>
<input type="hidden" name="pass" value=""/><!--- pass marker to prevent save on submit --->
<div class="detail">
<div class="tr">
<div class="th">Класс характеристики (RUS)</div>
<div class="td">
<input type="text" name="modifier_class" value="#d.modifier_class#" size="70"/>
</div>
</div>
<div class="tr">
<div class="th">Класс характеристики (ENG)</div>
<div class="td">
<input type="text" name="modifier_class_en" value="#d.modifier_class_en#" size="70"/>
</div>
</div>
<div class="tr">
<div class="th">Описание</div>
<div class="td">
<textarea name="descr" rows="10" cols="100">#request.htm2plain(d.descr)#</textarea>
</div>
</div>
<div class="tr">
<div class="th">Создано</div>
<div class="td">
#dateFormat(d.dt_created,'DD.MM.YYYY')# #timeFormat(d.dt_created,'HH:MM')#
#qDecoration.creator# <cfif len(qDecoration.creator_shortname)>(#qDecoration.creator_shortname#)</cfif>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Изменено
#dateFormat(d.dt_updated,'DD.MM.YYYY')# #timeFormat(d.dt_updated,'HH:MM')#
#qDecoration.updater# <cfif len(qDecoration.updater_shortname)>(#qDecoration.updater_shortname#)</cfif>
</div>
</div>
</div>
</cfoutput>
<layout:page section="extension" closeForm="Yes"/>
<cfif d.modifier_class_id GT 0>
<cfquery name="qModifier" datasource="#request.DS#">
select
p.modifier_id
,p.modifier
,p.code
,p.sort
from modifier p
where p.modifier_class_id=<cfqueryparam cfsqltype="cf_sql_integer" value="#d.modifier_class_id#"/>
order by p.sort, p.code, p.modifier
</cfquery>
<cfoutput>
<h4>Характеристики (#qModifier.recordCount#)
<cfif pageInfo.writePermitted()>
<cfoutput>
<cfset addUrl="modifier.cfm?modifier_id=-1&modifier_class_id=#d.modifier_class_id#&#tr.fwx#"/>
<button type="button" class="maincontrol" onclick="document.location.href='#addUrl#'">
<a href="#addUrl#">Создать</a>
</button>
</cfoutput>
</cfif>
</h4>
</cfoutput>
<table class="worktable">
<thead>
<tr>
<th></th>
<th>Характеристика</th>
<th>Код</th>
<th>Сортировка</th>
<th></th>
</tr>
</thead>
<cfoutput query="qModifier">
<tr>
<td>
<c:link_view_edit canWrite=#pageInfo.writePermitted()# entity="modifier" key="modifier_id" id=#modifier_id# fwx=#tr.fwx#/>
</td>
<td>
<a href="modifier.cfm?modifier_id=#modifier_id#&#tr.fwx#">#modifier#</a>
</td>
<td>#code#</td>
<td class="r">#sort#</td>
<td>
<c:link_del canWrite=#pageInfo.writePermitted()# entity="modifier" id=#modifier_id# fwx=#tr.fwx#/>
</td>
</tr>
</cfoutput>
</table>
<cfquery name="qAbstractService" datasource="#request.DS#">
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=<cfqueryparam cfsqltype="cf_sql_integer" value="#d.modifier_class_id#"/>
order by 2
</cfquery>
<cfoutput>
<h4>Используется абстрактными услугами (#qAbstractService.recordCount#)</h4>
</cfoutput>
<table class="worktable">
<thead>
<tr>
<th>Код услуги</th>
<th>Номенклатура (RUS)</th>
<th>Номенклатура (ENG)</th>
</tr>
</thead>
<cfoutput query="qAbstractService">
<tr>
<td><a href="abstract_service.cfm?abstract_service_id=#abstract_service_id#&#tr.fwx#">#code#</a></td>
<td><a href="abstract_service.cfm?abstract_service_id=#abstract_service_id#&#tr.fwx#">#abstract_service#</a></td>
<td><a href="abstract_service.cfm?abstract_service_id=#abstract_service_id#&#tr.fwx#">#abstract_service_en#</a></td>
</tr>
</cfoutput>
</table>
</cfif>
<layout:page section="footer"/>

View File

@ -1,70 +0,0 @@
<cfsilent>
<cfimport prefix="m" taglib="lib"/>
<cfimport prefix="d" taglib="lib/data"/>
<cfimport prefix="layout" taglib="layout"/>
</cfsilent><m:silent silent="No">
<m:prepare_detail entity="modifier_class" pageInfoOut="pageInfo"/>
<cfparam name="modifier_class_id" type="integer"/>
<d:del
entity="#pageInfo.entity#"
confirmMessage="Удалить класс характеристики (модификатора)?"
denyMessage="Удаление данного класса характеристики невозможно (в нем есть характеристики)."
accessObj="#pageInfo.entity#"
status="status"
output="markup">
<d:dependency entity="modifier" title="Характеристика">
<d:dependency_field key>m.modifier_id</d:dependency_field>
<d:dependency_field title="ID">m.modifier_ID</d:dependency_field>
<d:dependency_field title="Характеристика">m.modifier</d:dependency_field>
<d:dependency_from>
modifier m
</d:dependency_from>
<d:dependency_condition cfsqltype="cf_sql_integer" value='#modifier_class_id#'>m.modifier_class_id</d:dependency_condition>
<d:dependency_order_by>2</d:dependency_order_by>
</d:dependency>
<d:del_condition field="modifier_class_id" value="#modifier_class_id#" cfsqltype="cf_sql_integer"/>
</d:del>
<m:dispatch_detail
usePRG="Yes"
pageInfo=#pageInfo#
id="#modifier_class_id#"
status=#status#
trackOut="tr"
idAttributesOut="id"
/>
<!--- decoration --->
<cfquery name="qDecoration" datasource="#request.DS#">
select
c.modifier_class
from modifier_class c
where c.modifier_class_id=<cfqueryparam cfsqltype="cf_sql_integer" value="#modifier_class_id#" null=#!isValid("integer", modifier_class_id)#/>
</cfquery>
</m:silent><!--- ----------------------------------------------------------------------------
---------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------
---><layout:page section="header" pageInfo=#pageInfo#>
<layout:attribute name="title">
<cfoutput>
Удаление класса характеристики
#qDecoration.modifier_class#
<cfif modifier_class_id GT 0>
[#modifier_class_id#]
</cfif>
</cfoutput>
</layout:attribute>
<layout:attribute name="controls">&nbsp;</layout:attribute>
</layout:page>
<!---<cfdump var=#qDecoration#/>--->
<cfoutput>#markup#</cfoutput>
<layout:page section="footer"/>

View File

@ -1,111 +0,0 @@
<cfsilent>
<cfimport prefix="m" taglib="lib"/>
<cfimport prefix="c" taglib="lib/controls"/>
<cfimport prefix="d" taglib="lib/data"/>
<cfimport prefix="layout" taglib="layout"/>
</cfsilent><m:silent silent="No">
<m:prepare_ls entity="modifier_class" pageInfoOut="pageInfo" trackOut="tr"/>
<m:filter_settings target="#pageInfo.entity#_ls">
<m:filterparam filter=#filter# param="quickfilter" ftype="string" prefix="%" suffix="%" expression="((p.project like ?) OR (p.customer like ?) OR (p.customer_alias like ?) OR (p.modifier_class_type like ?) OR (p.division like ?) OR (p.performer_short like ?))" default=""/>
</m:filter_settings>
<cfset pageInfo.settings.filter=#filter#/>
<cftry>
<cfquery name="qRead" datasource="#request.DS#">
select
<d:field_set titleMapOut="titleMap" lengthOut="fieldCount">
<d:field title="ID" cfSqlType="CF_SQL_INTEGER">c.modifier_class_id</d:field>
<d:field title="Класс характеристики (RUS)">c.modifier_class</d:field>
<d:field title="Класс характеристики (ENG)">c.modifier_class_en</d:field>
<d:field title="Используется абстрактными услугами">
(select count(*) from abstract_service a where a.modifier_class_id=c.modifier_class_id) as abstract_service_cnt
</d:field>
<d:field title="Характеристик">
(select count(*) from modifier a where a.modifier_class_id=c.modifier_class_id) as modifier_cnt
</d:field>
</d:field_set>
from modifier_class c
where 1=1 <m:filter_build filter=#pageInfo.settings.filter#/>
order by <m:order_build sortArray=#pageInfo.settings.sort.sortArray# fieldCount=#fieldCount#/>
</cfquery>
<cfcatch type="database">
<m:ls_catch catch=#cfcatch# status=#pageInfo.status#/>
</cfcatch>
</cftry>
<cfquery name="qCountTotal" datasource="#request.DS#">
select count(*) as cnt from modifier_class where 1=1
</cfquery>
</m:silent><!---
-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
---><cfif isDefined("output_xls")>
<layout:xml qRead=#qRead# titleMap=#titleMap# filename="#pageInfo.entity#.xml"/>
<cfabort/>
</cfif><cfif isDefined("output_json")>
<layout:json qRead=#qRead# titleMap=#titleMap# filename="#pageInfo.entity#.json"/>
<cfabort/>
</cfif><!---
---><layout:page section="header" pageInfo=#pageInfo#>
<layout:attribute name="title">
<b>Классы характеристик</b> (модификаторов)
</layout:attribute>
<layout:attribute name="controls">
<!---skip filter link, filter is not implemented--->
<!---<layout:language_switch/>--->
</layout:attribute>
</layout:page>
<cfif pageInfo.readPermitted() AND !pageInfo.status.errorState>
<layout:grid_summary
recordCount=#qRead.recordCount#
totalCount=#qCountTotal.cnt#
footerOut="gridFooter"
excelLink="Yes"
jsonLink="Yes"
/>
<table class="worktable">
<thead>
<layout:grid_head titleMap=#titleMap# sortArray=#pageInfo.settings.sort.sortArray#>
<th width="1%">
<c:link_add canWrite=#pageInfo.writePermitted()# entity=#pageInfo.entity# fwx=#tr.fwx#/>
</th>
<th width="30%"><layout:column_head name="modifier_class"/></th>
<th width="30%"><layout:column_head name="modifier_class_en"/></th>
<th width="10%"><layout:column_head name="abstract_service_cnt"/></th>
<th width="10%"><layout:column_head name="modifier_cnt"/></th>
<th width="1%"></th>
</layout:grid_head>
</thead>
<cfoutput query="qRead" maxrows=#pageInfo.recordsPerPage# startrow=#pageInfo.nStart#>
<tr>
<td class="c">
<c:link_view_edit canWrite=#pageInfo.writePermitted()# entity=#pageInfo.entity# id=#qRead[pageInfo.entity&'_id'][currentRow]# fwx=#tr.fwx#/>
</td>
<td>#modifier_class#</td>
<td>#modifier_class_en#</td>
<td class="c"><cfif abstract_service_cnt GT 0>#abstract_service_cnt#</cfif></td>
<td class="c"><cfif modifier_cnt GT 0>#modifier_cnt#</cfif></td>
<td class="c">
<c:link_del canWrite=#pageInfo.writePermitted()# entity=#pageInfo.entity# id=#qRead[pageInfo.entity&'_id'][currentRow]# fwx=#tr.fwx#/>
</td>
</tr>
</cfoutput>
</table>
<cfoutput>#gridFooter#</cfoutput>
</cfif>
<layout:page section="footer"/>

View File

@ -1,69 +0,0 @@
<cfsilent>
<cfimport prefix="m" taglib="lib"/>
<cfimport prefix="d" taglib="lib/data"/>
<cfimport prefix="layout" taglib="layout"/>
</cfsilent><m:silent silent="No">
<m:prepare_detail entity="modifier" pageInfoOut="pageInfo"/>
<cfparam name="modifier_id" type="integer"/>
<d:del
entity="#pageInfo.entity#"
confirmMessage="Удалить характеристику (модификатор)?"
denyMessage="Удаление данной характеристики (модификатора) невозможно (используется конкретными услугами)."
accessObj="#pageInfo.entity#"
status="status"
output="markup">
<d:dependency entity="service" title="Конкретные услуги">
<d:dependency_field key>s.service_id</d:dependency_field>
<d:dependency_field title="Код услуги">a.code</d:dependency_field>
<d:dependency_field title="Абстрактная услуга">a.abstract_service</d:dependency_field>
<d:dependency_field title="Характеристика">m.modifier</d:dependency_field>
<d:dependency_from>
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)
</d:dependency_from>
<d:dependency_condition cfsqltype="cf_sql_integer" value='#modifier_id#'>m.modifier_id</d:dependency_condition>
<d:dependency_order_by>2</d:dependency_order_by>
</d:dependency>
<d:del_condition field="modifier_id" value="#modifier_id#" cfsqltype="cf_sql_integer"/>
</d:del>
<m:dispatch_detail
usePRG="Yes"
pageInfo=#pageInfo#
id="#modifier_id#"
status=#status#
trackOut="tr"
idAttributesOut="id"
/>
<!--- decoration --->
<cfquery name="qDecoration" datasource="#request.DS#">
select
m.modifier
from modifier m
where m.modifier_id=<cfqueryparam cfsqltype="cf_sql_integer" value="#modifier_id#" null=#!isValid("integer", modifier_id)#/>
</cfquery>
</m:silent><!--- ----------------------------------------------------------------------------
---------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------
---><layout:page section="header" pageInfo=#pageInfo#>
<layout:attribute name="title">
<cfoutput>
Удаление характеристики
#qDecoration.modifier#
[#modifier_id#]
</cfoutput>
</layout:attribute>
<layout:attribute name="controls">&nbsp;</layout:attribute>
</layout:page>
<cfoutput>#markup#</cfoutput>
<layout:page section="footer"/>

View File

@ -1,112 +0,0 @@
<cfsilent>
<cfimport prefix="m" taglib="lib"/>
<cfimport prefix="c" taglib="lib/controls"/>
<cfimport prefix="d" taglib="lib/data"/>
<cfimport prefix="layout" taglib="layout"/>
</cfsilent><m:silent silent="No">
<m:prepare_ls entity="modifier" pageInfoOut="pageInfo" trackOut="tr"/>
<m:filter_settings target="#pageInfo.entity#_ls">
<m:filterparam filter=#filter# param="quickfilter" ftype="string" prefix="%" suffix="%" expression="((p.project like ?) OR (p.customer like ?) OR (p.customer_alias like ?) OR (p.modifier_type like ?) OR (p.division like ?) OR (p.performer_short like ?))" default=""/>
</m:filter_settings>
<cfset pageInfo.settings.filter=#filter#/>
<cftry>
<cfquery name="qRead" datasource="#request.DS#">
select
<d:field_set titleMapOut="titleMap" lengthOut="fieldCount">
<d:field title="ID" cfSqlType="CF_SQL_INTEGER">m.modifier_id</d:field>
<d:field title="Код">m.code as modifier_code</d:field>
<d:field title="Класс характеристики">c.modifier_class</d:field>
<d:field title="Характеристика (RUS)">m.modifier</d:field>
<d:field title="Характеристика (ENG)">m.modifier_en</d:field>
<d:field title="Сортировка">m.sort</d:field>
</d:field_set>
from modifier m
join modifier_class c on (m.modifier_class_id=c.modifier_class_id)
where 1=1 <m:filter_build filter=#pageInfo.settings.filter#/>
order by <m:order_build sortArray=#pageInfo.settings.sort.sortArray# fieldCount=#fieldCount#/>
</cfquery>
<cfcatch type="database">
<m:ls_catch catch=#cfcatch# status=#pageInfo.status#/>
</cfcatch>
</cftry>
<cfquery name="qCountTotal" datasource="#request.DS#">
select count(*) as cnt from modifier where 1=1
</cfquery>
</m:silent><!---
-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
---><cfif isDefined("output_xls")>
<layout:xml qRead=#qRead# titleMap=#titleMap# filename="#pageInfo.entity#.xml"/>
<cfabort/>
</cfif><cfif isDefined("output_json")>
<layout:json qRead=#qRead# titleMap=#titleMap# filename="#pageInfo.entity#.json"/>
<cfabort/>
</cfif><!---
---><layout:page section="header" pageInfo=#pageInfo#>
<layout:attribute name="title">
<b>Характеристики</b> (модификаторы услуг)
</layout:attribute>
<layout:attribute name="controls">
<!---skip filter link, filter is not implemented--->
<!---<layout:language_switch/>--->
</layout:attribute>
</layout:page>
<cfif pageInfo.readPermitted() AND !pageInfo.status.errorState>
<layout:grid_summary
recordCount=#qRead.recordCount#
totalCount=#qCountTotal.cnt#
footerOut="gridFooter"
excelLink="Yes"
jsonLink="Yes"
/>
<table class="worktable">
<thead>
<layout:grid_head titleMap=#titleMap# sortArray=#pageInfo.settings.sort.sortArray#>
<th width="1%">
<c:link_add canWrite=#pageInfo.writePermitted()# entity=#pageInfo.entity# fwx=#tr.fwx#/>
</th>
<th width="5%"><layout:column_head name="modifier_id"/></th>
<th width="15%"><layout:column_head name="modifier_class"/></th>
<th width="15%"><layout:column_head name="modifier"/></th>
<th width="15%"><layout:column_head name="modifier_en"/></th>
<th width="5%"><layout:column_head name="modifier_code"/></th>
<th width="5%"><layout:column_head name="sort"/></th>
<th width="1%"></th>
</layout:grid_head>
</thead>
<cfoutput query="qRead" maxrows=#pageInfo.recordsPerPage# startrow=#pageInfo.nStart#>
<tr>
<td class="c">
<c:link_view_edit canWrite=#pageInfo.writePermitted()# entity=#pageInfo.entity# id=#qRead[pageInfo.entity&'_id'][currentRow]# fwx=#tr.fwx#/>
</td>
<td>#modifier_id#</td>
<td>#modifier_class#</td>
<td>#modifier#</td>
<td>#modifier_en#</td>
<td>#modifier_code#</td>
<td class="r">#sort#</td>
<td class="c">
<c:link_del canWrite=#pageInfo.writePermitted()# entity=#pageInfo.entity# id=#qRead[pageInfo.entity&'_id'][currentRow]# fwx=#tr.fwx#/>
</td>
</tr>
</cfoutput>
</table>
<cfoutput>#gridFooter#</cfoutput>
</cfif>
<layout:page section="footer"/>

View File

@ -1,102 +0,0 @@
<cfsilent>
<cfimport prefix="m" taglib="lib"/>
<cfimport prefix="d" taglib="lib/data"/>
<cfimport prefix="layout" taglib="layout"/>
</cfsilent><m:silent silent="No">
<m:prepare_detail entity="param_class" pageInfoOut="pageInfo"/>
<cfparam name="param_class_id" type="integer"/>
<d:del
entity="#pageInfo.entity#"
confirmMessage="Удалить компонент?"
denyMessage="Удаление данного компонента невозможно (есть зависимые объекты)."
accessObj="#pageInfo.entity#"
status="status"
output="markup">
<!--- <d:dependency entity="provider_backup" title="Записи о резервном копировании">
<d:dependency_field key>provider_backup_id</d:dependency_field>
<d:dependency_field title="Дата и время резервного копирования" formatter=#date104#>dt_backup</d:dependency_field>
<d:dependency_from>
provider_backup
</d:dependency_from>
<d:dependency_condition cfsqltype="cf_sql_integer" value='#vcenter_guid#'>vcenter_guid</d:dependency_condition>
<d:dependency_order_by>1 desc</d:dependency_order_by>
</d:dependency> --->
<d:dependency entity="param" title="Вариант компонента">
<d:dependency_field key>p.param_id</d:dependency_field>
<d:dependency_field title="ID">p.param_id</d:dependency_field>
<d:dependency_field title="Вариант компонента">p.param</d:dependency_field>
<d:dependency_field title="Сокращенное название">p.param_short</d:dependency_field>
<d:dependency_field title="Код">p.code</d:dependency_field>
<d:dependency_from>
param p
</d:dependency_from>
<d:dependency_condition cfsqltype="cf_sql_integer" value='#param_class_id#'>p.param_class_id</d:dependency_condition>
<d:dependency_order_by>2 desc</d:dependency_order_by>
</d:dependency>
<d:dependency entity="service_param" title="Компонент варианта услуги">
<d:dependency_field key>sp.service_param_id</d:dependency_field>
<d:dependency_field title="Код услуги">a.code</d:dependency_field>
<d:dependency_field title="Абстрактная услуга">a.abstract_service</d:dependency_field>
<d:dependency_field title="Характеристика">m.modifier</d:dependency_field>
<d:dependency_field title="Компонент">c.param_class</d:dependency_field>
<d:dependency_field title="Вариант компонента">p.param</d:dependency_field>
<d:dependency_from>
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
</d:dependency_from>
<d:dependency_condition cfsqltype="cf_sql_integer" value='#param_class_id#'>ac.param_class_id</d:dependency_condition>
<d:dependency_order_by>2 desc</d:dependency_order_by>
</d:dependency>
<d:del_condition field="param_class_id" value="#param_class_id#" cfsqltype="cf_sql_integer"/>
</d:del>
<m:dispatch_detail
usePRG="Yes"
pageInfo=#pageInfo#
id="#param_class_id#"
status=#status#
trackOut="tr"
idAttributesOut="id"
/>
<!--- decoration --->
<cfquery name="qDecoration" datasource="#request.DS#">
select
c.param_class
FROM param_class c
where c.param_class_id=<cfqueryparam cfsqltype="cf_sql_integer" value="#param_class_id#" null=#!isValid("integer", param_class_id)#/>
</cfquery>
</m:silent><!--- ----------------------------------------------------------------------------
---------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------
---><layout:page section="header" pageInfo=#pageInfo#>
<layout:attribute name="title">
<cfoutput>
Удаление компонента
#qDecoration.param_class#
<cfif param_class_id GT 0>
[#param_class_id#]
</cfif>
</cfoutput>
</layout:attribute>
<layout:attribute name="controls">&nbsp;</layout:attribute>
</layout:page>
<!---<cfdump var=#qDecoration#/>--->
<cfoutput>#markup#</cfoutput>
<layout:page section="footer"/>

View File

@ -1,141 +0,0 @@
<cfsilent>
<cfimport prefix="m" taglib="lib"/>
<cfimport prefix="d" taglib="lib/data"/>
<cfimport prefix="layout" taglib="layout"/>
</cfsilent><m:silent silent="No">
<m:prepare_detail entity="param" pageInfoOut="pageInfo"/>
<cfparam name="param_id" type="integer"/>
<d:del
entity="#pageInfo.entity#"
confirmMessage="Удалить вариант компонента?"
denyMessage="Удаление данного варианта компонента невозможно (есть зависимые объекты)."
accessObj="#pageInfo.entity#"
status="status"
output="markup">
<!--- <d:dependency entity="provider_backup" title="Записи о резервном копировании">
<d:dependency_field key>provider_backup_id</d:dependency_field>
<d:dependency_field title="Дата и время резервного копирования" formatter=#date104#>dt_backup</d:dependency_field>
<d:dependency_from>
provider_backup
</d:dependency_from>
<d:dependency_condition cfsqltype="cf_sql_integer" value='#vcenter_guid#'>vcenter_guid</d:dependency_condition>
<d:dependency_order_by>1 desc</d:dependency_order_by>
</d:dependency> --->
<d:dependency entity="service_param" title="Вариант компонента услуги">
<d:dependency_field key>sp.service_param_id</d:dependency_field>
<d:dependency_field title="Код услуги">a.code</d:dependency_field>
<d:dependency_field title="Абстрактная услуга">a.abstract_service</d:dependency_field>
<d:dependency_field title="Характеристика">m.modifier</d:dependency_field>
<d:dependency_field title="Компонент">c.param_class</d:dependency_field>
<d:dependency_field title="Вариант компонента">p.param</d:dependency_field>
<d:dependency_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 abstract_service a on s.abstract_service_id=a.abstract_service_id
</d:dependency_from>
<d:dependency_condition cfsqltype="cf_sql_integer" value='#param_id#'>sp.param_id</d:dependency_condition>
<d:dependency_order_by>2 desc</d:dependency_order_by>
</d:dependency>
<d:dependency entity="service_param" title="Вариант компонента экземпляра услуги">
<d:dependency_field key>sip.specification_item_param_id</d:dependency_field>
<d:dependency_field title="Спецификация">spec.specification</d:dependency_field>
<d:dependency_field title="Код услуги">a.code</d:dependency_field>
<d:dependency_field title="Абстрактная услуга">a.abstract_service</d:dependency_field>
<d:dependency_field title="Характеристика">m.modifier</d:dependency_field>
<d:dependency_field title="Компонент">c.param_class</d:dependency_field>
<d:dependency_field title="Вариант компонента">p.param</d:dependency_field>
<d:dependency_field title="Количество">sip.quantity</d:dependency_field>
<d:dependency_field title="Цена">sip.price</d:dependency_field>
<d:dependency_from>
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
</d:dependency_from>
<d:dependency_condition cfsqltype="cf_sql_integer" value='#param_id#'>sp.param_id</d:dependency_condition>
<d:dependency_order_by>2 desc</d:dependency_order_by>
</d:dependency>
<d:dependency entity="service_param_price" title="Цена варианта компонента (параметра) услуги">
<d:dependency_field key>spp.service_param_price_id</d:dependency_field>
<d:dependency_field title="Код услуги">a.code</d:dependency_field>
<d:dependency_field title="Абстрактная услуга">a.abstract_service</d:dependency_field>
<d:dependency_field title="Характеристика">m.modifier</d:dependency_field>
<d:dependency_field title="Компонент">c.param_class</d:dependency_field>
<d:dependency_field title="Вариант компонента">coalesce(p.param, p1.param) as param</d:dependency_field>
<d:dependency_field title="Цена">spp.price</d:dependency_field>
<d:dependency_from>
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
</d:dependency_from>
<d:dependency_condition cfsqltype="cf_sql_integer" value='#param_id#'>sp.param_id</d:dependency_condition>
<d:dependency_order_by>2 desc</d:dependency_order_by>
</d:dependency>
<d:del_condition field="param_id" value="#param_id#" cfsqltype="cf_sql_integer"/>
</d:del>
<m:dispatch_detail
usePRG="Yes"
pageInfo=#pageInfo#
id="#param_id#"
status=#status#
trackOut="tr"
idAttributesOut="id"
/>
<!--- decoration --->
<cfquery name="qDecoration" datasource="#request.DS#">
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=<cfqueryparam cfsqltype="cf_sql_integer" value="#param_id#" null=#!isValid("integer", param_id)#/>
</cfquery>
</m:silent><!--- ----------------------------------------------------------------------------
---------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------
---><layout:page section="header" pageInfo=#pageInfo#>
<layout:attribute name="title">
<cfoutput>
Удаление варианта компонента
<cfif len(qDecoration.param_class)>
#qDecoration.param_class#
</cfif>
#qDecoration.param#
<cfif param_id GT 0>
[#param_id#]
</cfif>
</cfoutput>
</layout:attribute>
<layout:attribute name="controls">&nbsp;</layout:attribute>
</layout:page>
<!---<cfdump var=#qDecoration#/>--->
<cfoutput>#markup#</cfoutput>
<layout:page section="footer"/>

View File

@ -1,367 +0,0 @@
<cfsilent>
<cfimport prefix="m" taglib="lib"/>
<cfimport prefix="c" taglib="lib/controls"/>
<cfimport prefix="d" taglib="lib/data"/>
<cfimport prefix="layout" taglib="layout"/>
</cfsilent><m:silent silent="No">
<m:prepare_ls entity="service_price" pageInfoOut="pageInfo" trackOut="tr"/>
<m:filter_settings target="#pageInfo.entity#_ls">
<m:filterparam filter=#filter# param="quickfilter" ftype="string" prefix="%" suffix="%" expression="((p.param_class_type like ?) OR (p.division like ?) )" default=""/>
</m:filter_settings>
<cfset pageInfo.settings.filter=#filter#/>
<!---<cftry>--->
<cfquery name="qRead" datasource="#request.DS#">
select
<d:field_set titleMapOut="qReadTitleMap" lengthOut="qReadFieldCount">
<d:field title="service_price_id" cfSqlType="CF_SQL_VARCHAR">prc.service_price_id</d:field>
<d:field title="service_param_price_id" cfSqlType="CF_SQL_VARCHAR">prc.service_param_price_id</d:field>
<d:field title="Модель цены">prm.pricing_model</d:field>
<d:field title="Модель цены">prm.pricing_model_short</d:field>
<d:field title="Модель цены">prm.pricing_model_code</d:field>
<d:field title="Период цены">prc.pricing_period</d:field>
<d:field title="Период опроса">prc.rating_period</d:field>
<d:field title="НДС%">s.vat_perc</d:field>
<d:field title="НДС не обл.">s.vat_free</d:field>
<d:field>case when s.vat_free then 0. else vat_perc/100. end as vat_rate</d:field>
<d:field title=#i18("GPL без НДС, ₽","GPL w/VAT, ₽")# cfSqlType="CF_SQL_DECIMAL">prc.price</d:field>
<d:field title=#i18("Цена со ск. без НДС, ₽","Price disc. w/VAT, ₽")# cfSqlType="CF_SQL_DECIMAL">case when price*.95 > min_price then price*.95 else min_price end as discount_price</d:field>/***/
<d:field title="Дно" cfSqlType="CF_SQL_DECIMAL">min_price</d:field>
<d:field title="Статус цены" cfSqlType="CF_SQL_DECIMAL">prc.status as price_status</d:field>
<d:field title="Начальная дата действия цены" cfSqlType="CF_SQL_TIMESTAMP">prc.dt_from</d:field>
<d:field title="Конечная дата действия цены" cfSqlType="CF_SQL_TIMESTAMP">prc.dt_to</d:field>
<d:field title=#i18("Макс. скидка, %","Max discount %")# cfSqlType="CF_SQL_DECIMAL">case when prc.price >0 then (prc.price-prc.min_price)/prc.price else NULL end as max_discount</d:field>
<d:field title="abstract_service_id" cfSqlType="CF_SQL_INTEGER">a.abstract_service_id</d:field>
<d:field title="service_id" cfSqlType="CF_SQL_INTEGER">s.service_id</d:field>
<d:field title=#i18("Код группы","Group Code")#>g.area_code</d:field>
<d:field title="Группа">g.area</d:field>
<d:field title="Группа">g.analytic_code</d:field>
<d:field title="Catalog Group">g.area_en</d:field>
<d:field title="Статус">u.status</d:field>
<d:field title="Status">u.status_en</d:field>
<d:field>g.area_code||'.'||a.code||'.'||m.code||'.'||p.code as code</d:field>
<d:field>a.code as abstract_service_code</d:field>
<d:field>m.code as modifier_code</d:field>
<d:field>p.code as param_code</d:field>
<d:field title="ID статуса абстрактной услуги">a.status_id</d:field>
<d:field title="Абстрактная услуга">a.abstract_service</d:field>
<d:field title="Abstract Service">a.abstract_service_en</d:field>
<d:field title="modifier_id" cfSqlType="CF_SQL_INTEGER">m.modifier_id</d:field>
<d:field title="Класс модификатора">mc.modifier_class</d:field>
<d:field title="Модификатор">m.modifier</d:field>
<d:field title="Modifier class">mc.modifier_class_en</d:field>
<d:field title="Modifier">m.modifier_en</d:field>
<d:field title="service_param_id" cfSqlType="CF_SQL_INTEGER">sp.service_param_id</d:field>
<d:field title="param_class_id" cfSqlType="CF_SQL_INTEGER">pc.param_class_id</d:field>
<d:field title="param_class">pc.param_class</d:field>
<d:field title="Сортировка компонента">ac.sort as param_class_sort</d:field><!--- порядок сортировки в списке компонентов, например CPU-RAM-HDD-GPU --->
<d:field title="Сортировка варианта компонента">p.sort as param_sort</d:field><!--- порядок сортировки в списке вариантов компонентов, например SATA-SAS-SSD --->
<d:field title="Компонент">p.param</d:field>
<d:field title="Resource">p.param_en</d:field>
<d:field title="param_id" cfSqlType="CF_SQL_INTEGER">p.param_id</d:field>
<d:field title="Ед.изм.">case when p.param_id IS NULL then se.measure_short else e.measure_short end as measure_short</d:field>
<d:field title="Measure">case when p.param_id IS NULL then se.measure_short_en else e.measure_short_en end as measure_short_en</d:field>
</d:field_set>
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 <m:filter_build filter=#pageInfo.settings.filter#/>
order by <m:order_build sortArray=#pageInfo.settings.sort.sortArray# fieldCount=#qReadFieldCount#/>
</cfquery>
<!---
<cfcatch type="database">
<m:ls_catch catch=#cfcatch# status=#pageInfo.status#/>
</cfcatch>
</cftry>--->
<!--- <cfdump var=#qRead#/> --->
<cfquery name="qCountTotal" datasource="#request.DS#">
select (select count(*) from service_param_price) + (select count(*) from service_price) as cnt;
</cfquery>
</m:silent><!---
-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
---><cfif isDefined("output_xls")>
<layout:xml qRead=#qRead# titleMap=#qReadTitleMap# filename="#pageInfo.entity#.xml"/>
<cfabort/><!--- *** nonstandard name for titleMap --->
</cfif><cfif isDefined("output_json")><!--- *** incorrect dt_from, dt_to format --->
<layout:json qRead=#qRead# titleMap=#qReadTitleMap# filename="#pageInfo.entity#.json"/>
<cfabort/><!--- *** nonstandard name for titleMap --->
</cfif><!---
---><layout:page section="header" pageInfo=#pageInfo#>
<layout:attribute name="title">
<cfoutput><b>#i18("Прайс-лист базовый","General Price List")#</b></cfoutput>
</layout:attribute>
</layout:page>
<cfif pageInfo.readPermitted() AND !pageInfo.status.errorState>
<layout:grid_summary
recordCount=#qRead.recordCount#
totalCount=#qCountTotal.cnt#
footerOut="gridFooter"
excelLink="YES"<!--- #pageInfo.writePermitted()# --->
jsonLink="YES"<!--- #pageInfo.writePermitted()# --->
/>
<!---<cfdump var=#qRead#/>--->
<cffunction name="formatPrice" output="true">
<cfargument name="price"/>
<cfif isNumeric(price)><cfreturn numberFormat(price,'.00')/><cfelse><cfreturn "(по запросу)"></cfif>
</cffunction>
<cfset request.formatPrice=formatPrice/>
<!--- add formatted fields (запись форматированного значения в поле на место исходного выглядит неопрятно) --->
<!--- можно заметить, что если многие поля оформлены ссылками, то форматировать много, и выглядит это громоздко --->
<cfset queryAddColumn(qRead,'f_link_view_edit')/>
<!--- <cfset qReadTitleMap.f_link_view_edit={ordinal=#StructCount(qReadTitleMap)+1#}/> --->
<cfset qReadTitleMap.f_link_view_edit={ordinal=0}/><!--- сортировки по этой колонке нет, ее порядок в исходном резалтсете не нужен, как и заголовок --->
<cfset queryAddColumn(qRead,'f_link_del')/>
<cfset qReadTitleMap.f_link_del={ordinal=0}/><!--- сортировки по этой колонке нет, ее порядок в исходном резалтсете не нужен, как и заголовок --->
<cfset queryAddColumn(qRead,'f_service')/>
<!--- <cfset qReadTitleMap.f_service={ordinal=#qReadTitleMap.abstract_service.ordinal#}/> --->
<cfset qReadTitleMap.f_service=qReadTitleMap.abstract_service/>
<cfset qReadTitleMap.f_service.title="Вариант услуги"/>
<!--- "кодовый" стиль, плохо читается. А все ради лаконичного формата c:table (который скорее тривиален) --->
<cfset queryAddColumn(qRead,'f_area_code')/>
<cfset qReadTitleMap.f_area_code=qReadTitleMap.analytic_code/><!--- просто копируем метаданные колонки аналитического кода --->
<cfset queryAddColumn(qRead,'f_component')/>
<cfset qReadTitleMap.f_component=qReadTitleMap.param_class/>
<cfset qReadTitleMap.f_component.title="Компонент"/>
<cfset queryAddColumn(qRead,'f_pricing_model')/>
<cfset qReadTitleMap.f_pricing_model={ordinal=qReadTitleMap.pricing_model.ordinal,title="Модель цены"}/>
<!--- *** Неудобно высчитывать ordinal, надо привязаться к существующей колонке
*** Хочется иметь возможность сортировки по нескольким колонкам, раз уж нереально по синтетической - поскольку мы вынесли форматирование из БД --->
<cfset queryAddColumn(qRead,'f_code')/>
<cfset qReadTitleMap.f_code={ordinal=qReadTitleMap.area_code.ordinal,title="Код"}/>
<cfset queryAddColumn(qRead,'f_price')/>
<cfset qReadTitleMap.f_price=qReadTitleMap.price/>
<cfset queryAddColumn(qRead,'f_min_price')/>
<cfset qReadTitleMap.f_min_price=qReadTitleMap.min_price/>
<cfset queryAddColumn(qRead,'f_discount_price')/>
<cfset qReadTitleMap.f_discount_price=qReadTitleMap.discount_price/>
<cfset queryAddColumn(qRead,'f_max_discount')/>
<cfset qReadTitleMap.f_max_discount=qReadTitleMap.max_discount/>
<cfset queryAddColumn(qRead,'f_area')/>
<cfset qReadTitleMap.f_area=qReadTitleMap.analytic_code/>
<cfset queryAddColumn(qRead,'f_param_class_sort')/>
<cfset qReadTitleMap.f_param_class_sort=qReadTitleMap.param_class_sort/>
<cfset queryAddColumn(qRead,'f_param_sort')/>
<cfset qReadTitleMap.f_param_sort=qReadTitleMap.param_sort/>
<cfset queryAddColumn(qRead,'f_vat_free')/>
<cfset qReadTitleMap.f_vat_free=qReadTitleMap.vat_free/>
<!--- preformat resultset fields --->
<cfoutput query=#qRead# startRow=#pageInfo.nStart# maxRows=#pageInfo.recordsPerPage#>
<cfsavecontent variable="qRead.f_link_view_edit">
<cfif len(service_param_price_id)>
<a href="service_param_price.cfm?service_param_price_id=#service_param_price_id#&#tr.fwx#" name="#service_param_price_id#"
<cfif pageInfo.writePermitted()>title="редактировать"
<cfelse>title="просмотр"</cfif>><img src="img/piece.png" width="13" height="13"/></a>
<cfelse>
<a href="service_price.cfm?service_price_id=#service_price_id#&#tr.fwx#" name="#service_price_id#"
<cfif pageInfo.writePermitted()>title="редактировать"
<cfelse>title="просмотр"</cfif>><img src="img/svc.jpg" width="16" height="16"/></a>
</cfif>
</cfsavecontent>
<cfsavecontent variable="qRead.f_link_del">
<cfif len(service_param_price_id)>
<a href="service_param_price_del.cfm?service_param_price_id=#service_param_price_id#&#tr.fwx#" class="del"></a>
<cfelse>
<a href="service_price_del.cfm?service_price_id=#service_price_id#&#tr.fwx#" class="del"></a>
</cfif>
</cfsavecontent>
<cfsavecontent variable="qRead.f_area_code">
#analytic_code# #area_code#
</cfsavecontent>
<cfsavecontent variable="qRead.f_service">
<a href="service.cfm?service_id=#service_id#&#tr.fwx#">
#abstract_service#<!--- <cfif modifier_id GT 0>:</cfif> ---> #modifier#
</a>
</cfsavecontent>
<cfsavecontent variable="qRead.f_component">
<a href="service_param.cfm?service_param_id=#service_param_id#&#tr.fwx#">
#param_class#
#param# <!--- *** может быть param_id для тривиального варианта - а как правильно? Разница с вариантом услуги - в механизме образования варианта, для услуги тривиальный вариант образуется null-модификатором, а для параметра - пустым названием (оба способа не слишком изящны, а наличие двух еще усложняет игру) --->
</a>
</cfsavecontent>
<cfsavecontent variable="qRead.f_pricing_model">
#pricing_model#
</cfsavecontent>
<cfsavecontent variable="qRead.f_code">
#request.skuCode(area_code,abstract_service_code,modifier_code,param_code,pricing_model_code)#
</cfsavecontent>
<cfsavecontent variable="qRead.f_area">
#analytic_code# #area#
</cfsavecontent>
<cfsavecontent variable="qRead.f_price">
<cfif isNumeric(price)>
<cfif len(service_price_id)>
<a href="service_price.cfm?service_price_id=#service_price_id#&#tr.fwx#">
#numberFormat(price,'.00')#
</a>
<cfelseif len(service_param_price_id)>
<a href="service_param_price.cfm?service_param_price_id=#service_param_price_id#&#tr.fwx#">
#numberFormat(price,'.00')#
</a>
</cfif>
<cfelse>
<i>по запросу</i>
</cfif>
</cfsavecontent>
<cfsavecontent variable="qRead.f_discount_price">
<cfif isNumeric(discount_price)>
#numberFormat(discount_price,'.00')#
<cfelse>
<i>по запросу</i>
</cfif>
</cfsavecontent>
<cfsavecontent variable="qRead.f_min_price">
<cfif isNumeric(min_price)>
#numberFormat(min_price,'.00')#
<cfelse>
<i>по запросу</i>
</cfif>
</cfsavecontent>
<cfsavecontent variable="qRead.f_max_discount">
#numberFormat(f_max_discount,'.0')#
</cfsavecontent>
<cfsavecontent variable="qRead.f_param_class_sort">
#f_param_class_sort#
</cfsavecontent>
<cfsavecontent variable="qRead.f_param_sort">
#f_param_sort#
</cfsavecontent>
<cfsavecontent variable="qRead.f_vat_free">
<cfif qRead.vat_free GT 0>Не облагается</cfif>
</cfsavecontent>
</cfoutput>
<!---build table markup --->
<c:table query=#qRead# recordsPerPage=#pageInfo.recordsPerPage# nStart=#pageInfo.nStart# titleMap=#qReadTitleMap# sortArray=#pageInfo.settings.sort.sortArray# class="worktable wide">
<c:column width="1%" sortable=false>
<c:th><c:link_add canWrite=#pageInfo.writePermitted()# entity=#pageInfo.entity# key="service_price_id" fwx=#tr.fwx#/></c:th>
<c:td field="f_link_view_edit" class="c"/>
</c:column>
<c:column width="7%" field="f_area"/>
<c:column width="7%" field="f_code"/>
<c:column width="3%" field="status"><c:td class="c"/><!--- иллюстрация передачи атрибута ---></c:column>
<c:column width="20%" field="f_service"/>
<c:column width="15%" field="f_component"/><!---columnOrder="3"--->
<c:column width="5%" field="f_pricing_model"><c:td class="l"/></c:column>
<c:column width="3%" field="pricing_period"><c:td class="c"/></c:column>
<c:column width="3%" field="rating_period"><c:td class="c"/></c:column>
<c:column width="1%" field="measure_short"/>
<c:column width="3%" field="f_price"><c:td class="r"/></c:column>
<!--- <c:column width="3%" field="f_max_discount"><c:td class="r"/></c:column> --->
<c:column width="3%" field="f_discount_price"><c:td class="r"/></c:column>
<c:column width="3%" field="f_min_price"><c:td class="r"/></c:column>
<c:column width="2%" field="f_vat_free"><c:td class="c"/></c:column>
<c:column width="2%" field="vat_perc"><c:td class="r"/></c:column>
<c:column width="1%" sortable=false>
<c:th><!--- &nbsp; ---><!---*** пришлось что-нибудь написать, иначе c:th ищет field.title и, не найдя, бросает исключение ---></c:th>
<c:td field="f_link_del" class="c"/>
</c:column>
</c:table>
<cfoutput>#gridFooter#</cfoutput>
</cfif>
<layout:page section="footer"/>
<!---*** критика синтаксиса: CALLER в данном контексте выглядит ужасно. Когда применять #service_id#, когда ##service_id##
Может быть, стоит отказаться от пользовательского тега и обратиться к более ровному способу форматирования.
Например (явно плохая идея, но для примера) печатать таблицу, а потом ее парсить и переформатировать... некоторые это могли сделать на клиенте.
На самом деле все, что нужно нам из скоупа CALLER, уже определено в момент вызова тега, и мы можем заменить CALLER на <cfoutput>. Это тоже неуклюже. То есть тащить весь CALLER внутрь как бы избыточно (не говоря о том, что можно словить каких-то сложносочиненных глюков)
Сортировка должна происходить на сервере БД, иначе паджинатор бесполезен. Вытаскивать резалтсет на сервер приложений и там его сортировать выглядит очень плохим решением (еще глупее сортировать на клиенте). Для корректной сортировки нужно делать композицию колонок на сервере, что не очень хорошо, например, с нуллами надо обращаться осторожно (вот аргумент в пользу NOT NULL), и синтаксис становится зависим от диалекта SQL. Возможный вариант, если у нас композиция из 2 колонок, сортировать по обеим. Либо отказаться от сортировки по композитной колонке, что кажется проще всего.
Контекст query выглядит естественно, но эта простота вводит в заблуждение - на вид обычный синтаксис, а функции недоступны (паковать в реквест еще то удовольствие), контекст страницы недоступен, ищи его через CALLER - догадаться невозможно.
Можно передавать внутрь тега все, что может понадобиться - функции, переменные?
Можно придумать собственный синтаксис, заменяющий cfif
--->
<!--- тонкости
в примере ниже
Атрибуты тега вычисляются до вызова, в контексте вызывающей страницы, а содержимое обрабатывается самим тегом в его контексте (собственно, мы сказали ему так делать). Но при чтении исходника это совсем не очевидно и может порвать мозг.
Можно, конечно, обрабатывать исключение и подставлять контекст вызывающей страницы? Как заставить тег видеть контекст вызывающей страницы? Попробовал взять весь тег в cfoutput. В результате перестал видеть поля query. Откатился.
Печаль в том, что мы в одном месте (чего и хотели - чтобы рядом) получаем контекст вызывающей страницы и контекст query, поля которого хотим называть неквалифицированными именами.
Вариант: действуем в 2 прохода, сначала формируем структуру, а потом рендерим ее. В принципе, с учетом пагинации, может потреблять памяти меньше, чем сам query
<c:th><c:link_add canWrite=#pageInfo.writePermitted()# entity=#pageInfo.entity# fwx=#tr.fwx#/><cfoutput>#pageInfo.entity#</cfoutput>#pageInfo.entity#</c:th> --->
<!--- Хотелось бы:
чтобы контекст страницы был явно доступен во всех вложенных тегах. >> The custom tag's Caller scope is a reference to the calling page's Variables scope (добавить все из CALLER в Variables? А не зациклимся?
чтобы итератор работал прозрачно, как в cfoutput query
Как обойтись без динамического исполнения? Для всех форматтеров снаружи объявлять closure? нечитабельно.
Хотя читабельность простыней ниже - так себе
В общем, получается пока плохо
? полиморфизм i18(measure_short) - как бы избежать отдельной далекой декларации длинного списка похожих функций. Можно полю придать признак языка? Соглашение с суффиксами? Это уже какая-то морфология получается!
--->

View File

@ -1,365 +0,0 @@
<cfsilent>
<cfimport prefix="m" taglib="lib"/>
<cfimport prefix="c" taglib="lib/controls"/>
<cfimport prefix="d" taglib="lib/data"/>
<cfimport prefix="layout" taglib="layout"/>
</cfsilent><m:silent silent="No">
<cffunction name="priceWithVAT">
<cfargument name="price"/>
<cfargument name="vatRate"/>
<cftry>
<cfif isNumeric(arguments.price)>
<cfreturn price*(1+arguments.vatRate)/>
<cfelse>
<cfreturn ""/>
<!--- если вернуть "по запросу", Excel падает с ошибкой Ошибка XML в "Таблица"
Причина: Ошибочное значение
Файл: C:\Users\root\Downloads\price (5).xml
Группа: Cell
Тег: Data
Значение: по запросу --->
</cfif>
<cfcatch type="ANY"><cfreturn ""/></cfcatch>
</cftry>
</cffunction>
<m:prepare_ls entity="price" accessObject="price_rpt" pageInfoOut="pageInfo" trackOut="tr"/><!---synthetic entity, not a table--->
<m:filter_settings target="#pageInfo.entity#_ls">
<m:filterparam filter=#filter# param="quickfilter" ftype="string" prefix="%" suffix="%" expression="((p.project like ?) OR (p.customer like ?) OR (p.customer_alias like ?) OR (p.param_class_type like ?) OR (p.division like ?) OR (p.performer_short like ?))" default=""/>
</m:filter_settings>
<cfset pageInfo.settings.filter=#filter#/>
<!---<cftry>--->
<cfquery name="qRead" datasource="#request.DS#">
select
<d:field_set titleMapOut="qReadTitleMap" lengthOut="qReadFieldCount">
<d:field title="service_price_id" cfSqlType="CF_SQL_VARCHAR">prc.service_price_id</d:field>
<d:field title="service_param_price_id" cfSqlType="CF_SQL_VARCHAR">prc.service_param_price_id</d:field>
<d:field title="Модель цены">prm.pricing_model_id</d:field>
<d:field title="Модель цены">prm.pricing_model</d:field>
<d:field title="Модель цены">prm.pricing_model_short</d:field>
<d:field title="Модель цены">prm.pricing_model_code</d:field>
<d:field title="Период цены">prc.pricing_period</d:field>
<d:field title="Период опроса">prc.rating_period</d:field>
<d:field title="GPL, ₽" cfSqlType="CF_SQL_DECIMAL">prc.price</d:field>
<d:field title="Цена со ск., ₽" cfSqlType="CF_SQL_DECIMAL">case when price*.95 > coalesce(min_price,0) then price*.95 else min_price end as discount_price</d:field>/***/
<d:field title="Дно" cfSqlType="CF_SQL_DECIMAL">min_price</d:field>
<d:field title="Статус цены" cfSqlType="CF_SQL_DECIMAL">prc.status as price_status</d:field>
<d:field title="Начальная дата действия цены" cfSqlType="CF_SQL_TIMESTAMP">prc.dt_from</d:field>
<d:field title="Конечная дата действия цены" cfSqlType="CF_SQL_TIMESTAMP">prc.dt_to</d:field>
<d:field title="abstract_service_id" cfSqlType="CF_SQL_INTEGER">a.abstract_service_id</d:field>
<d:field title="service_id" cfSqlType="CF_SQL_INTEGER">s.service_id</d:field>
<d:field title=#i18("Код группы","Group Code")#>g.area_code</d:field>
<d:field title="Группа">g.area</d:field>
<d:field title="Группа">g.analytic_code</d:field>
<d:field title="Catalog Group">g.area_en</d:field>
<d:field title="ID статуса абстрактной услуги">a.status_id</d:field>
<d:field title="Статус абстрактной услуги">u.status</d:field>
<d:field title="Abstract Service Status">u.status_en</d:field>
<d:field>a.code</d:field>
<d:field>m.code as modifier_code</d:field>
<d:field>p.code as param_code</d:field>
<d:field title="Абстрактная услуга">a.abstract_service</d:field>
<d:field title="Abstract Service">a.abstract_service_en</d:field>
<d:field title="Описание услуги">case when (prc.service_price_id > 0) then s.descr else '' end as service_descr</d:field>
<d:field title="Коммерческие примечания">s.commercial_note</d:field>
<d:field title="modifier_id" cfSqlType="CF_SQL_INTEGER">m.modifier_id</d:field>
<d:field title="Класс модификатора">mc.modifier_class</d:field>
<d:field title="Модификатор">m.modifier</d:field>
<d:field title="Modifier class">mc.modifier_class_en</d:field>
<d:field title="Modifier">m.modifier_en</d:field>
<d:field title="service_param_id" cfSqlType="CF_SQL_INTEGER">sp.service_param_id</d:field>
<d:field title="param_class_id" cfSqlType="CF_SQL_INTEGER">pc.param_class_id</d:field>
<d:field title="param_class">pc.param_class</d:field>
<d:field title="Сортировка компонента">ac.sort as param_class_sort</d:field><!--- порядок сортировки в списке компонентов, например CPU-RAM-HDD-GPU --->
<d:field title="Сортировка варианта компонента">p.sort as param_sort</d:field><!--- порядок сортировки в списке вариантов компонентов, например SATA-SAS-SSD --->
<d:field title="Компонент">p.param</d:field>
<d:field title="param_id" cfSqlType="CF_SQL_INTEGER">p.param_id</d:field>
<d:field title="Ед.изм.">case when p.param_id IS NULL then se.measure_short else e.measure_short end as measure_short</d:field>
<d:field title="Measure">case when p.param_id IS NULL then se.measure_short_en else e.measure_short_en end as measure_short_en</d:field>
<d:field title="НДС%">s.vat_perc</d:field>
<d:field title="НДС не обл.">s.vat_free</d:field>
<d:field>case when s.vat_free then 0. else vat_perc/100. end as vat_rate</d:field>
<!--- <d:field title="service_param_price_cnt" cfSqlType="CF_SQL_INTEGER">(select count(*) from service_param_price spp join service_param sp on spp.service_param_id=sp.service_param_id )</d:field> --->
</d:field_set>
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 <m:filter_build filter=#pageInfo.settings.filter#/>
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
</cfquery>
<!---
<cfcatch type="database">
<m:ls_catch catch=#cfcatch# status=#pageInfo.status#/>
</cfcatch>
</cftry>--->
<cfquery name="qCountTotal" datasource="#request.DS#">
select (select count(*) from service_param_price) + (select count(*) from service_price) as cnt;
</cfquery>
<!--- Тут проблема, serializeJSON неправильно форматирует дату-время --->
<cfset qFmt=queryNew("area,code,service,param,measure_short,pricing_model_short,pricing_period,rating_period,price,discount_price,service_descr,commercial_note,param_class_sort,param_sort, sku, status_id, status, price_status, dt_from, dt_to, vat_free, vat_perc",
"varchar,varchar,varchar,varchar,varchar,varchar,varchar,varchar,numeric,numeric,varchar,varchar,numeric,numeric,varchar,numeric,varchar,varchar,varchar,varchar,varchar,varchar")/>
<!--- Столь неудобная конструкция привела сразу к нескольким ошибкам, когда я добавил 2 поля vat_free, vat_perc - добавлять их надо в нескольких местах --->
<cfset qFmtTitleMap={
area={ordinal=1,title="Группа услуг",cfSqlType="CF_SQL_VARCHAR"}
,code={ordinal=2,title="Код",cfSqlType="CF_SQL_VARCHAR"}
,service={ordinal=3,title="Услуга",cfSqlType="CF_SQL_VARCHAR"}
,param={ordinal=4,title="Компонент",cfSqlType="CF_SQL_VARCHAR"}
,measure_short={ordinal=5,title="Ед.изм.",cfSqlType="CF_SQL_VARCHAR"}
,pricing_model_short={ordinal=6,title="Модель ц-обр.",cfSqlType="CF_SQL_VARCHAR"}
,pricing_period={ordinal=7,title="Период цены",cfSqlType="CF_SQL_VARCHAR"}
,rating_period={ordinal=8,title="Период замера",cfSqlType="CF_SQL_VARCHAR"}
,price={ordinal=9,title="Цена GPL, ₽ с НДС",cfSqlType="CF_SQL_DECIMAL"}
,discount_price={ordinal=10,title="GPL-5%, ₽ с НДС",cfSqlType="CF_SQL_DECIMAL"}
,service_descr={ordinal=11,title="Описание услуги",cfSqlType="CF_SQL_VARCHAR"}
,commercial_note={ordinal=12,title="Коммерческие примечания",cfSqlType="CF_SQL_VARCHAR"}
,param_class_sort={ordinal=13,title="Сортировка компонента",cfSqlType="CF_SQL_NUMERIC"}
,param_sort={ordinal=14,title="Сортировка варианта компонента",cfSqlType="CF_SQL_NUMERIC"}
,sku={ordinal=15,title="Полное название",cfSqlType="CF_SQL_VARCHAR"}
,status_id={ordinal=16,title="ID статуса абстрактной услуги",cfSqlType="CF_SQL_NUMERIC"}
,status={ordinal=17,title="Статус абстрактной услуги",cfSqlType="CF_SQL_VARCHAR"}
,price_status={ordinal=18,title="Статус цены",cfSqlType="CF_SQL_VARCHAR"}
,dt_from={ordinal=19,title="Начальная дата действия цены",cfSqlType="CF_SQL_TIMESTAMP"}
,dt_to={ordinal=20,title="Конечная дата действия цены",cfSqlType="CF_SQL_TIMESTAMP"}
,vat_free={ordinal=21,title="НДС не облагается",cfSqlType="CF_SQL_BIT"}
,vat_perc={ordinal=22,title="НДС%",cfSqlType="CF_SQL_INTEGER"}
}/><!--- когда я здесь забыл переименовать поле, в дальнейшем адресация шла по номеру, а количество полей в структуре было меньше, чем ordinal, xml.cfm падал с ошибкой --->
<!--- DIRTY HACK: in the query we have string formatted as ISO 8601 (json serializer takes it as is), but for excel declare CF_SQL_TIMESTAMP in titleMap metadata, and obtain decent formatting--->
<!--- <cfdump var=#qReadTitleMap#/>
<cfdump var=#qFmtTitleMap#/> --->
<cfloop query="qRead">
<cfset queryAddRow(qFmt ,[
"#analytic_code# #area#"
,#request.skuCode(area_code,code,modifier_code,param_code,pricing_model_code)#
,"#abstract_service# #modifier#"
,"#param_class##(len(param))?': ':''##param#"
,measure_short
,pricing_model_short
,pricing_period
,rating_period
,priceWithVAT(price,vat_rate)
,priceWithVAT(discount_price,vat_rate)
,service_descr
,commercial_note
,param_class_sort
,param_sort
,"#abstract_service# #modifier##(len(param_class))? ( ' (' & ((len(param))? param : param_class) & ')' ) : ''#"
/*,"#abstract_service# #modifier##(len(param_class))? ( ' [' & ((len(param))? param : param_class) & ']' ) : ''#"*/
/*,"#abstract_service# #modifier##(len(param_class))? (' (' & param_class & ((len(param)) ? (': ' & param) : '' ) & ')') : ''#"*/
/*,"#abstract_service# #modifier# (#param_class#: #param#)"*/
,status_id
,status
,price_status
,LSDateTimeFormat(dt_from,"yyyy-MM-dd'T'HH:nn:ssZ")
,LSDateTimeFormat(dt_to,"yyyy-MM-dd'T'HH:nn:ssZ")
,vat_free
,vat_perc
])/>
</cfloop>
<!--- <cfdump var=#qFmt#/> --->
</m:silent><!---
-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
---><cfif isDefined("output_xls")><!---<cfdump var=#qFmt#/><cfdump var=#qFmtTitleMap#/><cfdump var=#pageInfo.entity#/><cfabort/>--->
<layout:xml qRead=#qFmt# titleMap=#qFmtTitleMap# filename="#pageInfo.entity#.xml"/>
<cfabort/>
</cfif><cfif isDefined("output_json")>
<layout:json qRead=#qFmt# filename="#pageInfo.entity#.json"/>
<cfabort/>
</cfif><!---
---><layout:page section="header" pageInfo=#pageInfo#>
<layout:attribute name="title">
<cfoutput><b>#i18("Прайс-лист на компоненты","Resource Price List")#</b></cfoutput>
</layout:attribute>
</layout:page>
<!---<cfdump var=#qRead#/>--->
<cfif pageInfo.readPermitted() AND !pageInfo.status.errorState>
<layout:grid_summary
recordCount=#qRead.recordCount#
totalCount=#qCountTotal.cnt#
footerOut="gridFooter"
excelLink=#pageInfo.writePermitted()#
jsonLink=#pageInfo.writePermitted()#
/>
<cffunction name="formatPrice" output="true">
<cfargument name="price"/>
<cfif isNumeric(price)><cfreturn numberFormat(price,'.00')/><cfelse><cfreturn "(по запросу)"></cfif>
</cffunction>
<cfset request.formatPrice=formatPrice/>
<table class="worktable wide">
<thead>
<layout:grid_head titleMap=#qReadTitleMap# sortArray=#pageInfo.settings.sort.sortArray#>
<th width="5%">Группа услуг</th>
<th width="5%">Код</th>
<th width="10%">Услуга</th>
<th width="15%">Компонент</th>
<th width="3%">Единица измерения</th>
<th width="3%">Модель ц-обр.</th>
<th width="3%">Период цены</th>
<th width="3%">Период замера</th>
<th width="7%">Цена GPL, ₽ с НДС</th>
<th width="7%">GPL-5%, ₽ с НДС</th>
<th width="2%">НДС не обл.</th>
<th width="2%">НДС%</th>
</layout:grid_head>
</thead>
<cfoutput query="qRead" group="service_id">
<cfset groupCnt=0/>
<cfoutput>
<cfset groupCnt++/>
</cfoutput>
<cfif groupCnt GT 1>
<tr style="background-color:rgb(240,240,240);">
<td>#analytic_code# #area#</td>
<td>
<a href="service.cfm?service_id=#service_id#&#tr.fwx#">#request.skuCode(area_code,code,modifier_code)#</a>
</td>
<td class="c" colspan="100">
<a href="abstract_service.cfm?abstract_service_id=#abstract_service_id#&#tr.fwx#">#abstract_service#</a> #modifier#
</td>
</tr>
</cfif>
<cfoutput group="pricing_model_id">
<cfoutput>
<tr>
<td>#analytic_code# #area#</td>
<td>
<cfif service_param_price_id GT 0>
<a href="service_param.cfm?service_param_id=#service_param_id#&#tr.fwx#">#request.skuCode(area_code,code,modifier_code,param_code,pricing_model_code)#</a>
<cfelse>
<a href="service.cfm?service_id=#service_id#&#tr.fwx#">#request.skuCode(area_code,code,modifier_code,param_code,pricing_model_code)#</a>
</cfif>
</td>
<cfif service_param_price_id GT 0>
<td><a href="abstract_service.cfm?abstract_service_id=#abstract_service_id#&#tr.fwx#">#abstract_service#</a> #modifier#</td>
<td>#param_class#<cfif len(param)>: #param#</cfif></td>
<cfelse>
<td colspan="2">
<a href="abstract_service.cfm?abstract_service_id=#abstract_service_id#&#tr.fwx#">#abstract_service#</a> #modifier#
</td>
<!--- <td></td> --->
</cfif>
<td>#measure_short#</td>
<td class="c">#pricing_model_short#</td>
<td class="c">#pricing_period#</td>
<td class="c">#rating_period#</td>
<td class="r">
<cftry>
<cfif service_price_id GT 0>
<a href="service_price.cfm?service_price_id=#service_price_id#&#tr.fwx#">
<cfif isNumeric(price)>
#request.numFmt(priceWithVAT(price,vat_rate),2)#
<cfelse>
<i>по запросу</i>
</cfif>
</a>
<cfelse>
<a href="service_param_price.cfm?service_param_price_id=#service_param_price_id#&#tr.fwx#">
<cfif isNumeric(price)>
#request.numFmt(priceWithVAT(price,vat_rate),2)#
<cfelse>
<i>по запросу</i>
</cfif>
</a>
</cfif>
<cfcatch type="ANY">?<!--- #cfcatch.message# ---></cfcatch>
</cftry>
</td>
<td class="r">
<cftry>
<cfif service_price_id GT 0>
<cfif isNumeric(discount_price)>
#request.numFmt(priceWithVAT(discount_price,vat_rate),2)#
<cfelse>
<i>по запросу</i>
</cfif>
<cfelse>
<cfif isNumeric(discount_price)>
#request.numFmt(priceWithVAT(discount_price,vat_rate),2)#
<cfelse>
<i>по запросу</i>
</cfif>
</cfif>
<cfcatch type="ANY">?</cfcatch>
</cftry>
</td>
<td class="c"><cfif vat_free GT 0>Не облагается</cfif></td>
<td class="c">#vat_perc#</td>
</tr>
</cfoutput>
</cfoutput>
<cfif groupCnt GT 1>
<tr style="height:1em;"><td colspan="100" style="height:0;"></td></tr>
</cfif>
</cfoutput>
</table>
<cfoutput>#gridFooter#</cfoutput>
</cfif>
<layout:page section="footer"/>

View File

@ -1,239 +0,0 @@
<cfsilent>
<cfimport prefix="m" taglib="lib"/>
<cfimport prefix="c" taglib="lib/controls"/>
<cfimport prefix="d" taglib="lib/data"/>
<cfimport prefix="layout" taglib="layout"/>
</cfsilent><m:silent silent="No">
<m:prepare_ls entity="price" accessObject="price_rpt" pageInfoOut="pageInfo" trackOut="tr"/><!---synthetic entity, not a table--->
<m:filter_settings target="#pageInfo.entity#_ls">
<m:filterparam filter=#filter# param="quickfilter" ftype="string" prefix="%" suffix="%" expression="((p.project like ?) OR (p.customer like ?) OR (p.customer_alias like ?) OR (p.param_class_type like ?) OR (p.division like ?) OR (p.performer_short like ?))" default=""/>
</m:filter_settings>
<cfset pageInfo.settings.filter=#filter#/>
<!---<cftry>--->
<cfquery name="qRead" datasource="#request.DS#">
select
<d:field_set titleMapOut="qReadTitleMap" lengthOut="qReadFieldCount">
<d:field title="service_price_id" cfSqlType="CF_SQL_VARCHAR">prc.service_price_id</d:field>
<d:field title="service_param_price_id" cfSqlType="CF_SQL_VARCHAR">prc.service_param_price_id</d:field>
<d:field title="Модель цены">prm.pricing_model</d:field>
<d:field title="Модель цены">prm.pricing_model_short</d:field>
<d:field title="Модель цены">prm.pricing_model_code</d:field>
<d:field title="Модель цены">prm.pricing_model_id</d:field>
<d:field title="Период цены">prc.pricing_period</d:field>
<d:field title="Период опроса">prc.rating_period</d:field>
<d:field title="GPL, ₽" cfSqlType="CF_SQL_DECIMAL">prc.price</d:field>
<d:field title="Цена со ск., ₽" cfSqlType="CF_SQL_DECIMAL">case when price*.95 > coalesce(min_price,0) then price*.95 else min_price end as discount_price</d:field>/***/
<d:field title="Дно" cfSqlType="CF_SQL_DECIMAL">min_price</d:field>
<d:field title="abstract_service_id" cfSqlType="CF_SQL_INTEGER">a.abstract_service_id</d:field>
<d:field title="service_id" cfSqlType="CF_SQL_INTEGER">s.service_id</d:field>
<d:field title=#i18("Код группы","Group Code")#>g.area_code</d:field>
<d:field title="Группа">g.area</d:field>
<d:field title="Группа">g.analytic_code</d:field>
<d:field title="Catalog Group">g.area_en</d:field>
<d:field title="Статус">u.status</d:field>
<d:field title="Status">u.status_en</d:field>
<d:field>a.code</d:field>
<d:field>m.code as modifier_code</d:field>
<d:field>p.code as param_code</d:field>
<d:field title="Абстрактная услуга">a.abstract_service</d:field>
<d:field title="Abstract Service">a.abstract_service_en</d:field>
<d:field title="modifier_id" cfSqlType="CF_SQL_INTEGER">m.modifier_id</d:field>
<d:field title="Класс модификатора">mc.modifier_class</d:field>
<d:field title="Модификатор">m.modifier</d:field>
<d:field title="Modifier class">mc.modifier_class_en</d:field>
<d:field title="Modifier">m.modifier_en</d:field>
<d:field title="service_param_id" cfSqlType="CF_SQL_INTEGER">sp.service_param_id</d:field>
<d:field title="param_class_id" cfSqlType="CF_SQL_INTEGER">pc.param_class_id</d:field>
<d:field title="param_class">pc.param_class</d:field>
<d:field title="Компонент">p.param</d:field>
<d:field title="param_id" cfSqlType="CF_SQL_INTEGER">p.param_id</d:field>
<d:field title="Ед.изм.">case when p.param_id IS NULL then se.measure_short else e.measure_short end as measure_short</d:field>
<d:field title="Measure">case when p.param_id IS NULL then se.measure_short_en else e.measure_short_en end as measure_short_en</d:field>
</d:field_set>
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 <m:filter_build filter=#pageInfo.settings.filter#/>
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
</cfquery>
<!---
<cfcatch type="database">
<m:ls_catch catch=#cfcatch# status=#pageInfo.status#/>
</cfcatch>
</cftry>--->
<cfquery name="qCountTotal" datasource="#request.DS#">
select (select count(*) from service_param_price) + (select count(*) from service_price) as cnt;
</cfquery>
</m:silent><!---
-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
---><cfif isDefined("output_xls")>
<layout:xml qRead=#qRead# titleMap=#qReadTitleMap# filename="#pageInfo.entity#.xml"/>
<cfabort/>
</cfif><cfif isDefined("output_json")>
<layout:json qRead=#qRead# filename="#pageInfo.entity#.json"/>
<cfabort/>
</cfif><!---
---><layout:page section="header" pageInfo=#pageInfo#>
<layout:attribute name="title">
<cfoutput><b>#i18("Прайс-лист на компоненты","Resource Price List")#</b></cfoutput>
</layout:attribute>
</layout:page>
<!---<cfdump var=#qRead#/>--->
<cfif pageInfo.readPermitted() AND !pageInfo.status.errorState>
<layout:grid_summary
recordCount=#qRead.recordCount#
totalCount=#qCountTotal.cnt#
footerOut="gridFooter"
excelLink=#pageInfo.writePermitted()#
jsonLink=#pageInfo.writePermitted()#
/>
<cffunction name="formatPrice" output="true">
<cfargument name="price"/>
<cfif isNumeric(price)><cfreturn numberFormat(price,'.00')/><cfelse><cfreturn "(по запросу)"></cfif>
</cffunction>
<cfset request.formatPrice=formatPrice/>
<table class="worktable wide">
<thead>
<layout:grid_head titleMap=#qReadTitleMap# sortArray=#pageInfo.settings.sort.sortArray#>
<th width="5%">Группа услуг</th>
<th width="5%">Код</th>
<th width="5%">Услуга</th>
<th width="15%">Компонент</th>
<th width="3%">Единица измерения</th>
<th width="3%">Модель ц-обр.</th>
<th width="3%">Период цены</th>
<th width="3%">Период опроса</th>
<th width="7%">Цена GPL, ₽ с НДС</th>
<th width="7%">GPL-5%, ₽ с НДС</th>
</layout:grid_head>
</thead>
<cfoutput query="qRead" group="service_id">
<cfoutput group="pricing_model_id">
<tr>
<td>#analytic_code# #area#</td>
<td><a href="service.cfm?service_id=#service_id#&#tr.fwx#">#request.skuCode(area_code,code,modifier_code)#</a></td>
<td colspan="8"><a href="abstract_service.cfm?abstract_service_id=#abstract_service_id#&#tr.fwx#">#abstract_service#</a> #modifier#</td>
<!--- <td><cfif service_price_id GT 0>#measure_short#</cfif></td>
<td class="c"><cfif service_price_id GT 0>#pricing_model_short#</cfif></td>
<td class="c"><cfif service_price_id GT 0>#pricing_period#</cfif></td>
<td class="c"><cfif service_price_id GT 0>#rating_period#</cfif></td>
<td class="r">
<cftry>
<cfif service_price_id GT 0>
<a href="service_price.cfm?service_price_id=#service_price_id#&#tr.fwx#">
<cfif isNumeric(price)>
#request.numFmt(price*(1+request.VAT),2)#
<cfelse>
<i>по запросу</i>
</cfif>
</a>
</cfif>
<cfcatch type="ANY">?</cfcatch>
</cftry>
</td>
<td class="r">
<cftry>
<cfif service_price_id GT 0>
<cfif isNumeric(discount_price)>
#request.numFmt(discount_price*(1+request.VAT),2)#
<cfelse>
<i>по запросу</i>
</cfif>
</cfif>
<cfcatch type="ANY">?</cfcatch>
</cftry>
</td> --->
</tr>
<cfoutput>
<tr>
<td>#analytic_code# #area#</td>
<td><a href="service_param.cfm?service_param_id=#service_param_id#&#tr.fwx#">#request.skuCode(area_code,code,modifier_code,param_code,pricing_model_code)#</a></td>
<td><!--- <a href="abstract_service.cfm?abstract_service_id=#abstract_service_id#&#tr.fwx#">#abstract_service#</a> #modifier# ---></td>
<td>#param_class#<cfif len(param)>: #param#</cfif></td>
<td>#measure_short#</td>
<td class="c">#pricing_model_short#</td>
<td class="c">#pricing_period#</td>
<td class="c">#rating_period#</td>
<td class="r">
<cftry>
<a href="service_param_price.cfm?service_param_price_id=#service_param_price_id#&#tr.fwx#">
<cfif isNumeric(price)>
#request.numFmt(price*(1+request.VAT),2)#
<cfelse>
<i>по запросу</i>
</cfif>
</a>
<cfcatch type="ANY">?</cfcatch>
</cftry>
</td>
<td class="r">
<cftry>
<cfif isNumeric(discount_price)>
#request.numFmt(discount_price*(1+request.VAT),2)#
<cfelse>
<i>по запросу</i>
</cfif>
<cfcatch type="ANY">?</cfcatch>
</cftry>
</td>
</tr>
</cfoutput>
</cfoutput>
</cfoutput>
</table>
<cfoutput>#gridFooter#</cfoutput>
</cfif>
<layout:page section="footer"/>

View File

@ -1,129 +0,0 @@
<cfsilent>
<cfimport prefix="m" taglib="lib"/>
<cfimport prefix="c" taglib="lib/controls"/>
<cfimport prefix="d" taglib="lib/data"/>
<cfimport prefix="layout" taglib="layout"/>
</cfsilent><m:silent silent="No">
<cffunction name="plain2HtmClean">
<cfargument name="s" type="string"/>
<cfreturn request.plain2htm(request.cleanHtm(s))/>
</cffunction>
<cffunction name="cleanInput">
<cfargument name="s" type="string"/>
<cfreturn htmlEditFormat(s)/>
</cffunction>
<m:prepare_detail entity="provider" key="provider_id" pageInfoOut="pageInfo"/>
<d:bean readonly=#!pageInfo.writePermitted()# table="provider" datasource="#request.DS#" output="d" status="status">
<d:param field="provider_id" type="integer" key autoincrement/>
<d:param field="provider" type="varchar" size="255" preprocessor=#cleanInput#/>
<d:param field="provider_en" type="varchar" size="255" preprocessor=#cleanInput#/>
<d:param field="descr" type="varchar" preprocessor=#plain2HtmClean#/>
<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:bean>
<m:dispatch_detail
usePRG="No"<!---*** --->
pageInfo=#pageInfo#
id="#d.provider_id#"
status=#pageInfo.status#
trackOut="tr"
idAttributesOut="id"
/>
<cfquery name="qDecoration" datasource="#request.DS#">
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#=<cfqueryparam attributeCollection=#id#/>
</cfquery>
</m:silent><!---
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
---><layout:page section="header" pageInfo=#pageInfo#>
<layout:attribute name="title">
<cfoutput>
Провайдер услуг
<cfif d.provider_id GT 0>
<b>#d.provider#</b>
[#d.provider_id#]
</cfif>
</cfoutput>
</layout:attribute>
</layout:page>
<cfif status.errorState GT 0>
<cfoutput><div class="err">#status.errorMessage#</div></cfoutput>
</cfif>
<cfoutput>
<input type="hidden" name="provider_id" value="#d.provider_id#"/>
<input type="hidden" name="track" value="#tr.self#"/>
<input type="hidden" name="pass" value=""/><!--- pass marker to prevent save on submit --->
<div class="detail">
<div class="tr">
<div class="th">ID</div>
<div class="td">
#d.provider_id#
</div>
</div>
<div class="tr">
<div class="th">Наименование провайдера услуг (RUS)</div>
<div class="td">
<input type="text" name="provider" value="#d.provider#" size="70"/>
</div>
</div>
<div class="tr">
<div class="th">Наименование провайдера услуг (ENG)</div>
<div class="td">
<input type="text" name="provider_en" value="#d.provider_en#" size="70"/>
</div>
</div>
<div class="tr">
<div class="th">Описание</div>
<div class="td">
<textarea name="descr" rows="10" cols="100">#request.htm2plain(d.descr)#</textarea>
</div>
</div>
<div class="tr">
<div class="th">Создано</div>
<div class="td">
#dateFormat(d.dt_created,'DD.MM.YYYY')# #timeFormat(d.dt_created,'HH:MM')#
#qDecoration.creator# <cfif len(qDecoration.creator_shortname)>(#qDecoration.creator_shortname#)</cfif>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Изменено
#dateFormat(d.dt_updated,'DD.MM.YYYY')# #timeFormat(d.dt_updated,'HH:MM')#
#qDecoration.updater# <cfif len(qDecoration.updater_shortname)>(#qDecoration.updater_shortname#)</cfif>
</div>
</div>
</div>
</cfoutput>
<layout:page section="extension" closeForm="Yes"/>
*** вывести список услуг провайдера
<layout:page section="footer"/>

View File

@ -1,97 +0,0 @@
<cfsilent>
<cfimport prefix="m" taglib="lib"/>
<cfimport prefix="c" taglib="lib/controls"/>
<cfimport prefix="d" taglib="lib/data"/>
<cfimport prefix="layout" taglib="layout"/>
</cfsilent><m:silent silent="No">
<m:prepare_ls entity="provider" pageInfoOut="pageInfo" trackOut="tr"/>
<m:filter_settings target="#pageInfo.entity#_ls">
<m:filterparam filter=#filter# param="quickfilter" ftype="string" prefix="%" suffix="%" expression="((p.project like ?) OR (p.customer like ?) OR (p.customer_alias like ?) OR (p.provider_class_type like ?) OR (p.division like ?) OR (p.performer_short like ?))" default=""/>
</m:filter_settings>
<cfset pageInfo.settings.filter=#filter#/>
<cftry>
<cfquery name="qRead" datasource="#request.DS#">
select
<d:field_set titleMapOut="titleMap" lengthOut="fieldCount">
<d:field title="ID" cfSqlType="CF_SQL_INTEGER">m.provider_id</d:field>
<d:field title="Провайдер услуг (RUS)">m.provider</d:field>
<d:field title="Провайдер услуг (ENG)">m.provider_en</d:field>
</d:field_set>
from provider m
where 1=1 <m:filter_build filter=#pageInfo.settings.filter#/>
order by <m:order_build sortArray=#pageInfo.settings.sort.sortArray# fieldCount=#fieldCount#/>
</cfquery>
<cfcatch type="database">
<m:ls_catch catch=#cfcatch# status=#pageInfo.status#/>
</cfcatch>
</cftry>
<cfquery name="qCountTotal" datasource="#request.DS#">
select count(*) as cnt from provider where 1=1
</cfquery>
</m:silent><!---
-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
---><cfif isDefined("output_xls")>
<layout:xml qRead=#qRead# titleMap=#titleMap# filename="#pageInfo.entity#.xml"/>
<cfabort/>
</cfif><cfif isDefined("output_json")>
<layout:json qRead=#qRead# titleMap=#titleMap# filename="#pageInfo.entity#.json"/>
<cfabort/>
</cfif><!---
---><layout:page section="header" pageInfo=#pageInfo#>
<layout:attribute name="title">
<cfoutput><b>Провайдеры услуг</b></cfoutput>
</layout:attribute>
<layout:attribute name="controls">
<!---skip filter link, filter is not implemented--->
<!---<layout:language_switch/>--->
</layout:attribute>
</layout:page>
<cfif pageInfo.readPermitted() AND !pageInfo.status.errorState>
<layout:grid_summary
recordCount=#qRead.recordCount#
totalCount=#qCountTotal.cnt#
footerOut="gridFooter"
excelLink="Yes"
jsonLink="Yes"
/>
<table class="worktable">
<thead>
<layout:grid_head titleMap=#titleMap# sortArray=#pageInfo.settings.sort.sortArray#>
<th width="1%">
<c:link_add canWrite=#pageInfo.writePermitted()# entity=#pageInfo.entity# fwx=#tr.fwx#/>
</th>
<th width="5%"><layout:column_head name="provider_id"/></th>
<th width="40%"><layout:column_head name="provider"/></th>
<th width="40%"><layout:column_head name="provider_en"/></th>
</layout:grid_head>
</thead>
<cfoutput query="qRead" maxrows=#pageInfo.recordsPerPage# startrow=#pageInfo.nStart#>
<tr>
<td class="c">
<c:link_view_edit canWrite=#pageInfo.writePermitted()# entity=#pageInfo.entity# id=#qRead[pageInfo.entity&'_id'][currentRow]# fwx=#tr.fwx#/>
</td>
<td class="c">#provider_id#</td>
<td>#provider#</td>
<td>#provider_en#</td>
</tr>
</cfoutput>
</table>
<cfoutput>#gridFooter#</cfoutput>
</cfif>
<layout:page section="footer"/>

View File

@ -1,313 +0,0 @@
<cfsilent>
<cfimport prefix="m" taglib="lib"/>
<cfimport prefix="c" taglib="lib/controls"/>
<cfimport prefix="d" taglib="lib/data"/>
<cfimport prefix="layout" taglib="layout"/>
</cfsilent><m:silent silent="No">
<cffunction name="plain2HtmClean">
<cfargument name="s" type="string"/>
<cfreturn request.plain2htm(request.cleanHtm(s))/>
</cffunction>
<cffunction name="cleanInput">
<cfargument name="s" type="string"/>
<cfreturn htmlEditFormat(s)/>
</cffunction>
<cffunction name="wrapGUID">
<cfargument name="s" type="string"/>
<cfreturn "cast(#request.cleanHtm(s)# as UUID)"/>
</cffunction>
<!--- <cfoutput>*** #isValid('UUID','7b4f10f5-e36a-40ed-9f464c30f43da3b4')#</cfoutput><cfabort/> --->
<m:prepare_detail entity="service_param_price" key="service_param_price_id" pageInfoOut="pageInfo"/>
<d:bean readonly=#!pageInfo.writePermitted()# table="service_param_price" datasource="#request.DS#" output="d" status="status">
<d:param field="service_param_price_id" type="integer" key autoincrement/>
<d:param field="service_param_id" type="integer" required/>
<d:param field="pricing_model_id" type="integer" required init="2"/>
<d:param field="pricing_period" type="varchar" size="31" preprocessor=#cleanInput# forNull="" init="m"/>
<d:param field="rating_period" type="varchar" size="31" preprocessor=#cleanInput# forNull="" init="m"/>
<!--- <d:param field="discount_policy_id" type="integer" forNull=""/> --->
<d:param field="dt_from" type="timestamp" format="yyyy-MM-dd" preprocessor=#cleanInput# forNull=""/><!--- !!! Important yyyy-MM-dd NOT YYYY-MM-DD --->
<d:param field="dt_to" type="timestamp" format="yyyy-MM-dd" preprocessor=#cleanInput# forNull=""/><!--- !!! Important yyyy-MM-dd NOT YYYY-MM-DD --->
<d:param field="status" type="varchar" size="255" preprocessor=#cleanInput# init="draft"/>
<d:param field="price" type="numeric" forNull=""/>
<d:param field="min_price" type="numeric" forNull=""/>
<d:param field="cost" type="numeric" forNull=""/>
<d:param field="descr" type="varchar" preprocessor=#plain2HtmClean#/>
<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:bean>
<!---
<cfdump var=#form#/>
<cfdump var=#d#/>
--->
<m:dispatch_detail
usePRG="No"<!---*** --->
pageInfo=#pageInfo#
id="#d.service_param_price_id#"
status=#pageInfo.status#
trackOut="tr"
idAttributesOut="id"
/>
<cfparam name="service_param_id" default="#d.service_param_id#"/>
<cfset service_param_id=(isValid('integer',service_param_id)? service_param_id: -1)/>
<!--- *** тянет на паттерн. Мы берем из ссылки по неосновному внешнему ключу, а потом доопределяем этот ключ из бина.
Если нужен qDecoration, мы включим в него только те поля, которые не попадают сюда
А если можно зайти по 2 разным ключам (актуально только при создании записи, когда определена часть ключей - то есть сущность, для которой мы создаем зависимую запись, на самом деле один из внешних ключей, потому что мы заходим только с одной записи... но потом можем зафиксировать и второй ключ на вторую верхнюю сущность)? В этом случае поля могут быть определены по разным ключам, если в графе есть циклы, что бывает - лучше тогда определиться, с кого начинать, потому что это все нужно для красоты (иначе попадаем на селектор - какой ключ определен, от того и поля)
Но именовать переменную service_param_id небезопасно, в запросе она будет переопределена, и легко спутать с d.service_param_id - безопасно только, если декларирована рядом, тогда не ошибешься --->
<cfquery name="qServiceParam" datasource="#request.DS#">
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=<cfqueryparam cfsqltype="cf_sql_integer" value="#service_param_id#" null=#!isNumeric(service_param_id)#/>
</cfquery>
<cfquery name="qDecoration" datasource="#request.DS#">
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#=<cfqueryparam attributeCollection=#id#/>
</cfquery>
</m:silent><!---
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
---><layout:page section="header" pageInfo=#pageInfo#>
<layout:attribute name="title">
<cfoutput>
Цена компонента
<b>#qServiceParam.abstract_service#</b>
[#qServiceParam.abstract_service_id#]
<b><cfif len(qServiceParam.modifier) GT 0>#qServiceParam.modifier#<cfelse>(основной вариант)</cfif></b>
[#qServiceParam.service_id#]
:
<b>#qServiceParam.param_class#</b>
[#qServiceParam.param_class_id#]
<b><cfif len(qServiceParam.param) GT 0>#qServiceParam.param#<cfelse>(основной вариант)</cfif></b>
[#qServiceParam.param_id#]
<b>#request.skuCode(qServiceParam.area_code,qServiceParam.abstract_service_code,
qServiceParam.modifier_code,qServiceParam.param_code)#</b>
<cfif len(d.service_param_price_id) GT 0>
[#d.service_param_price_id#]
</cfif>
</cfoutput>
</layout:attribute>
</layout:page>
<cfif status.errorState GT 0>
<cfoutput><div class="err">#status.errorMessage#</div></cfoutput>
</cfif>
<cfoutput>
<input type="hidden" name="service_param_price_id" value="#d.service_param_price_id#"/>
<input type="hidden" name="service_param_id" value="#d.service_param_id#"/><!--- это поле должно быть в форме, в контролы мы его не выводим - странный будет выбор из списка --->
<input type="hidden" name="track" value="#tr.self#"/>
<input type="hidden" name="pass" value=""/><!--- pass marker to prevent save on submit --->
<div class="detail">
<div class="tr">
<div class="th">Вариант услуги</div>
<div class="td">
<a href="service.cfm?service_id=#qServiceParam.service_id#&#tr.fwx#" title="Вариант услуги"/>
<b>#request.skuCode(qServiceParam.area_code,qServiceParam.abstract_service_code,qServiceParam.modifier_code)#</b>
</a>
<a href="abstract_service.cfm?abstract_service_id=#qServiceParam.abstract_service_id#&#tr.fwx#" title="Абстрактная услуга"/>#qServiceParam.abstract_service#</a><cfif #qServiceParam.modifier_id# GT 0>:</cfif>
<a href="modifier.cfm?modifier_id=#qServiceParam.modifier_id#&#tr.fwx#" title="Характеристика"/>
#qServiceParam.modifier#
</a>
</div>
</div>
<div class="tr">
<div class="th">Компонент</div>
<div class="td">
<a href="service_param.cfm?service_param_id=#qServiceParam.service_param_id#&#tr.fwx#" class="b" title="Компонент варианта услуги">
#request.skuCode(qServiceParam.area_code,qServiceParam.abstract_service_code,qServiceParam.modifier_code,qServiceParam.param_code)#
</a>
<a href="param_class.cfm?param_class_id=#qServiceParam.param_class_id#&#tr.fwx#" title="Компонент"/>#qServiceParam.param_class#</a><!--- <cfif #qServiceParam.param_id# GT 0>:</cfif> ---><cfif len(qServiceParam.param) GT 0>:</cfif>
<a href="param.cfm?param_id=#qServiceParam.param_id#&#tr.fwx#" title="Вариант компонента"/>
#qServiceParam.param#
</a>
</div>
</div>
<div class="tr">
<div class="th">Единица измерения</div>
<div class="td">
#qServiceParam.measure# (#qServiceParam.measure_short#)
</div>
</div>
<div class="tr">
<div class="th">Модель ценообразования</div>
<div class="td">
<c:combo
queryString="select pricing_model_id, pricing_model_short from pricing_model order by 1"
combo="pricing_model_id"
id="pricing_model_id"
key="pricing_model_id"
selected="#d.pricing_model_id#"
displayf="##pricing_model_short##"
empty=""
class=""
/>
</div>
</div>
<div class="tr">
<div class="th">Период цены</div>
<div class="td">
<select name="pricing_period">
<option value=""></option>
<option value="s"<cfif d.pricing_period EQ "s"> selected</cfif>>секунда</option>
<option value="n"<cfif d.pricing_period EQ "n"> selected</cfif>>минута</option>
<option value="h"<cfif d.pricing_period EQ "h"> selected</cfif>>час</option>
<option value="d"<cfif d.pricing_period EQ "d"> selected</cfif>>сутки</option>
<option value="m"<cfif d.pricing_period EQ "m"> selected</cfif>>месяц</option>
</select>
<i>за какое время указана цена</i>
</div>
</div>
<div class="tr">
<div class="th">Период опроса</div>
<div class="td">
<select name="rating_period">
<option value=""></option>
<option value="s"<cfif d.rating_period EQ "s"> selected</cfif>>секунда</option>
<option value="15s"<cfif d.rating_period EQ "15s"> selected</cfif>>15 секунд</option>
<option value="n"<cfif d.rating_period EQ "n"> selected</cfif>>минута</option>
<option value="15n"<cfif d.rating_period EQ "15n"> selected</cfif>>15 минут</option>
<option value="h"<cfif d.rating_period EQ "h"> selected</cfif>>час</option>
<option value="d"<cfif d.rating_period EQ "d"> selected</cfif>>сутки</option>
<option value="m"<cfif d.rating_period EQ "m"> selected</cfif>>месяц</option>
</select>
<i>с какой периодичностью собирается тарифицируемая метрика</i>
</div>
</div>
<div class="tr">
<div class="th">Цена GPL</div>
<div class="td">
<input type="text" name="price" value="#d.price#" size="12" class="r"/>
<i>публичная цена без скидки, без НДС</i>
</div>
</div>
<div class="tr">
<div class="th">Минимальная цена</div>
<div class="td">
<input type="text" name="min_price" value="#d.min_price#" size="12" class="r"/>
<i>ценовое дно, предел скидки - как правило, равна себестоимости, но может быть и ниже. Без НДС</i>
</div>
</div>
<div class="tr">
<div class="th">Себестоимость</div>
<div class="td">
<input type="text" name="cost" value="#d.cost#" size="12" class="r"/>
<i>ведется для справки и для контроля. Без НДС</i>
</div>
</div>
<!--- <div class="tr">
<div class="th">Политика дисконтирования</div>
<div class="td">
<select name="discount_policy_id">
<option value=""></option>
<option value="1"<cfif d.discount_policy_id EQ "1"> selected</cfif>>tiered</option>
<option value="2"<cfif d.discount_policy_id EQ "2"> selected</cfif>>some other policy</option>
</select>
*** может быть, нужны параметры дисконтирования (с какого объема и т.д.)
</div>
</div> --->
<div class="tr">
<div class="th">Статус</div>
<div class="td">
<select name="status">
<option value=""></option>
<option value="draft"<cfif d.status EQ "draft"> selected</cfif>>черновик</option>
<option value="active"<cfif d.status EQ "active"> selected</cfif>>активен</option>
<option value="archive"<cfif d.status EQ "archive"> selected</cfif>>архивирован</option>
</select>
*** правила переходов
</div>
</div>
<div class="tr">
<div class="th">Действует с</div>
<div class="td">
<input type="date" name="dt_from" id="dt_from" value="#dateFormat(d.dt_from,"YYYY-MM-DD")#"/>
<button type="button" onclick="document.getElementById('dt_from').value='#DateFormat(Now(), 'YYYY-MM-DD')#';">Сегодня</button>
</div>
</div>
<div class="tr">
<div class="th">Действует по</div>
<div class="td">
<input type="date" name="dt_to" id="dt_to" value="#dateFormat(d.dt_to,"YYYY-MM-DD")#"/>
<button type="button" onclick="document.getElementById('dt_to').value='#DateFormat(Now(), 'YYYY-MM-DD')#';">Сегодня</button>
</div>
</div>
<div class="tr">
<div class="th">Описание</div>
<div class="td">
<textarea name="descr" rows="10" cols="100">#request.htm2plain(d.descr)#</textarea>
</div>
</div>
<div class="tr">
<div class="th">Создано</div>
<div class="td">
#dateFormat(d.dt_created,'DD.MM.YYYY')# #timeFormat(d.dt_created,'HH:MM')#
#qDecoration.creator# <cfif len(qDecoration.creator_shortname)>(#qDecoration.creator_shortname#)</cfif>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Изменено
#dateFormat(d.dt_updated,'DD.MM.YYYY')# #timeFormat(d.dt_updated,'HH:MM')#
#qDecoration.updater# <cfif len(qDecoration.updater_shortname)>(#qDecoration.updater_shortname#)</cfif>
</div>
</div>
</div>
</cfoutput>
<layout:page section="extension" closeForm="Yes"/>
<layout:page section="footer"/>

View File

@ -1,73 +0,0 @@
<cfsilent>
<cfimport prefix="m" taglib="lib"/>
<cfimport prefix="d" taglib="lib/data"/>
<cfimport prefix="layout" taglib="layout"/>
</cfsilent><m:silent silent="No">
<m:prepare_detail entity="service_param_price" key="service_param_price_id" pageInfoOut="pageInfo"/>
<!--- <cfparam name="service_param_price_id" type="integer"/> --->
<!--- на самом деле удаление цены запрещено, если по ней что-то продано. Поскольку продажи осуществляются вне системы управления каталогом, признаком запрета удаления может быть статус цены Активен (в котором он может использоваться для продаж) --->
<d:del
entity="#pageInfo.entity#"
confirmMessage="Удалить цену?"
denyMessage="Удаление данной цены невозможно (ситуация не предусмотрена)."
accessObj="#pageInfo.entity#"
status="status"
output="markup">
<d:del_condition field="service_param_price_id" value="#service_param_price_id#" cfsqltype="cf_sql_other"/> <!--- *** Postgresql dependent --->
</d:del>
<m:dispatch_detail
usePRG="Yes"
pageInfo=#pageInfo#
id="#service_param_price_id#"
status=#status#
trackOut="tr"
idAttributesOut="id"
/>
<!--- decoration --->
<cfquery name="qDecoration" datasource="#request.DS#">
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 s.service_param_price_id=<cfqueryparam cfsqltype="cf_sql_integer" value="#service_param_price_id#" null=#!isValid("integer", service_param_price_id)#/> --->
where t.service_param_price_id=<cfqueryparam cfsqltype="cf_sql_other" value="#service_param_price_id#" null=#!isValid("integer", service_param_price_id)#/>
</cfquery>
</m:silent><!--- ----------------------------------------------------------------------------
---------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------
---><layout:page section="header" pageInfo=#pageInfo#>
<layout:attribute name="title">
<cfoutput query="qDecoration">
Удаление цены компонента
#request.skuCode(area_code,code,modifier_code,param_code)#
#abstract_service#
#modifier#
#param#
<cfif len(dt_from)>с #dateFormat(dt_from,"DD.MM.YYYY")#</cfif>
<cfif len(dt_to)>по #dateFormat(dt_to,"DD.MM.YYYY")#</cfif>
#price#
[#service_param_price_id#]
</cfoutput>
</layout:attribute>
<layout:attribute name="controls">&nbsp;</layout:attribute>
</layout:page>
<!---<cfdump var=#qDecoration#/>--->
<cfoutput>#markup#</cfoutput>
<layout:page section="footer"/>

View File

@ -1,279 +0,0 @@
<cfsilent>
<cfimport prefix="m" taglib="lib"/>
<cfimport prefix="c" taglib="lib/controls"/>
<cfimport prefix="d" taglib="lib/data"/>
<cfimport prefix="layout" taglib="layout"/>
</cfsilent><m:silent silent="No">
<cffunction name="plain2HtmClean">
<cfargument name="s" type="string"/>
<cfreturn request.plain2htm(request.cleanHtm(s))/>
</cffunction>
<cffunction name="cleanInput">
<cfargument name="s" type="string"/>
<cfreturn htmlEditFormat(s)/>
</cffunction>
<cffunction name="wrapGUID">
<cfargument name="s" type="string"/>
<cfreturn "cast(#request.cleanHtm(s)# as UUID)"/>
</cffunction>
<!--- <cfdump var=#form#/> --->
<m:prepare_detail entity="service_price" key="service_price_id" pageInfoOut="pageInfo"/>
<d:bean readonly=#!pageInfo.writePermitted()# table="service_price" datasource="#request.DS#" output="d" status="status">
<d:param field="service_price_id" type="integer" key autoincrement/>
<d:param field="service_id" type="integer" required/>
<d:param field="pricing_model_id" type="integer" required init="2"/>
<d:param field="pricing_period" type="varchar" size="31" preprocessor=#cleanInput# forNull="" init="m"/>
<d:param field="rating_period" type="varchar" size="31" preprocessor=#cleanInput# forNull="" init="m"/>
<!--- <d:param field="discount_policy_id" type="integer" forNull=""/> --->
<d:param field="dt_from" type="timestamp" format="yyyy-MM-dd" preprocessor=#cleanInput# forNull=""/><!--- !!! Important yyyy-MM-dd NOT YYYY-MM-DD --->
<d:param field="dt_to" type="timestamp" format="yyyy-MM-dd" preprocessor=#cleanInput# forNull=""/><!--- !!! Important yyyy-MM-dd NOT YYYY-MM-DD --->
<d:param field="status" type="varchar" size="255" preprocessor=#cleanInput# init="draft"/>
<d:param field="price" type="numeric" forNull=""/>
<d:param field="min_price" type="numeric" forNull=""/>
<d:param field="cost" type="numeric" forNull=""/>
<d:param field="descr" type="varchar" preprocessor=#plain2HtmClean#/>
<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:bean>
<!---
<cfdump var=#form#/>
<cfdump var=#d#/>
--->
<m:dispatch_detail
usePRG="No"<!---*** --->
pageInfo=#pageInfo#
id="#d.service_price_id#"
status=#pageInfo.status#
trackOut="tr"
idAttributesOut="id"
/>
<cfparam name="service_id" default=#d.service_id#/>
<cfset service_id=(isValid('integer',service_id)? service_id: -1)/>
<!--- *** тянет на паттерн. Мы берем из ссылки по неосновному внешнему ключу, а потом доопределяем этот ключ из бина.
Если нужен qDecoration, мы включим в него только те поля, которые не попадают сюда
А если можно зайти по 2 разным ключам (актуально только при создании записи, когда определена часть ключей - то есть сущность, для которой мы создаем зависимую запись, на самом деле один из внешних ключей, потому что мы заходим только с одной записи... но потом можем зафиксировать и второй ключ на вторую верхнюю сущность)? В этом случае поля могут быть определены по разным ключам, если в графе есть циклы, что бывает - лучше тогда определиться, с кого начинать, потому что это все нужно для красоты (иначе попадаем на селектор - какой ключ определен, от того и поля)
Но именовать переменную service_id небезопасно, в запросе она будет переопределена, и легко спутать с d.service_id - безопасно только, если декларирована рядом, тогда не ошибешься --->
<!--- *** селект выглядит случайным --->
<cfquery name="qService" datasource="#request.DS#">
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=<cfqueryparam cfsqltype="cf_sql_integer" value="#service_id#" null=#!isNumeric(service_id)#/>
</cfquery>
<cfquery name="qDecoration" datasource="#request.DS#">
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#=<cfqueryparam attributeCollection=#id#/><!--- *** потенциальная ошибка при пустом id --->
</cfquery>
</m:silent><!---
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
---><layout:page section="header" pageInfo=#pageInfo#>
<layout:attribute name="title">
<cfoutput>
Цена услуги
<b>#request.skuCode(qService.area_code, qService.abstract_service_code, qService.modifier_code)#</b>
<b>#qService.abstract_service# #qService.modifier#</b>
[#d.service_price_id#]
</cfoutput>
</layout:attribute>
</layout:page>
<cfif status.errorState GT 0>
<cfoutput><div class="err">#status.errorMessage#</div></cfoutput>
</cfif>
<cfoutput>
<input type="hidden" name="service_price_id" value="#d.service_price_id#"/>
<input type="hidden" name="service_id" value="#d.service_id#"/><!--- это поле должно быть в форме, но в контролы (выпадающим списком) мы его не выводим - будет невнятно --->
<input type="hidden" name="track" value="#tr.self#"/>
<input type="hidden" name="pass" value=""/><!--- pass marker to prevent save on submit --->
<div class="detail">
<div class="tr">
<div class="th">Услуга</div>
<div class="td">
<a href="service.cfm?service_id=#d.service_id#&#tr.fwx#" class="b">#request.skuCode(qService.area_code, qService.abstract_service_code, qService.modifier_code)#</a>
<a href="abstract_service.cfm?abstract_service_id=#qService.abstract_service_id#&#tr.fwx#">#qService.abstract_service#</a>
#qService.modifier#
</div>
</div>
<div class="tr">
<div class="th">Модель ценообразования</div>
<div class="td">
<c:combo
queryString="select pricing_model_id, pricing_model_short from pricing_model order by 1"
combo="pricing_model_id"
id="pricing_model_id"
key="pricing_model_id"
selected="#d.pricing_model_id#"
displayf="##pricing_model_short##"
empty=""
class=""
/>
</div>
</div>
<div class="tr">
<div class="th">Период цены</div>
<div class="td">
<select name="pricing_period">
<option value=""></option>
<option value="s"<cfif d.pricing_period EQ "s"> selected</cfif>>секунда</option>
<option value="n"<cfif d.pricing_period EQ "n"> selected</cfif>>минута</option>
<option value="h"<cfif d.pricing_period EQ "h"> selected</cfif>>час</option>
<option value="d"<cfif d.pricing_period EQ "d"> selected</cfif>>сутки</option>
<option value="m"<cfif d.pricing_period EQ "m"> selected</cfif>>месяц</option>
</select>
<i>за какое время указана цена. Для фиксированной оплаты обычно месяц</i>
</div>
</div>
<div class="tr">
<div class="th">Период опроса</div>
<div class="td">
<select name="rating_period">
<option value=""></option>
<option value="s"<cfif d.rating_period EQ "s"> selected</cfif>>секунда</option>
<option value="15s"<cfif d.rating_period EQ "15s"> selected</cfif>>15 секунд</option>
<option value="n"<cfif d.rating_period EQ "n"> selected</cfif>>минута</option>
<option value="15n"<cfif d.rating_period EQ "15n"> selected</cfif>>15 минут</option>
<option value="h"<cfif d.rating_period EQ "h"> selected</cfif>>час</option>
<option value="d"<cfif d.rating_period EQ "d"> selected</cfif>>сутки</option>
<option value="m"<cfif d.rating_period EQ "m"> selected</cfif>>месяц</option>
</select>
<i>с какой периодичностью собирается тарифицируемая метрика. Для фиксированной оплаты не указывать</i>
</div>
</div>
<div class="tr">
<div class="th">Единица измерения</div>
<div class="td">
#qService.measure# (#qService.measure_short#)
</div>
</div>
<div class="tr">
<div class="th">Цена GPL</div>
<div class="td">
<input type="text" name="price" value="#d.price#" size="12" class="r"/>
<i>публичная цена без скидки, без НДС</i>
</div>
</div>
<div class="tr">
<div class="th">Минимальная цена</div>
<div class="td">
<input type="text" name="min_price" value="#d.min_price#" size="12" class="r"/>
<i>ценовое дно, предел скидки - как правило, равна себестоимости, но может быть и ниже. Без НДС</i>
</div>
</div>
<div class="tr">
<div class="th">Себестоимость</div>
<div class="td">
<input type="text" name="cost" value="#d.cost#" size="12" class="r"/>
<i>ведется для справки и для контроля. Без НДС</i>
</div>
</div>
<!--- <div class="tr">
<div class="th">Политика дисконтирования</div>
<div class="td">
<select name="discount_policy_id">
<option value=""></option>
<option value="1"<cfif d.discount_policy_id EQ "1"> selected</cfif>>tiered</option>
<option value="2"<cfif d.discount_policy_id EQ "2"> selected</cfif>>some other policy</option>
</select>
*** может быть, нужны параметры дисконтирования (с какого объема и т.д.)
</div>
</div> --->
<div class="tr">
<div class="th">Статус</div>
<div class="td">
<select name="status">
<option value=""></option>
<option value="draft"<cfif d.status EQ "draft"> selected</cfif>>черновик</option>
<option value="active"<cfif d.status EQ "active"> selected</cfif>>активен</option>
<option value="archive"<cfif d.status EQ "archive"> selected</cfif>>архивирован</option>
</select>
*** реализовать правила переходов
</div>
</div>
<div class="tr">
<div class="th">Действует с</div>
<div class="td">
<input type="date" name="dt_from" id="dt_from" value="#dateFormat(d.dt_from,"YYYY-MM-DD")#"/>
<button type="button" onclick="document.getElementById('dt_from').value='#DateFormat(Now(), 'YYYY-MM-DD')#';">Сегодня</button>
</div>
</div>
<div class="tr">
<div class="th">Действует по</div>
<div class="td">
<input type="date" name="dt_to" id="dt_to" value="#dateFormat(d.dt_to,"YYYY-MM-DD")#"/>
<button type="button" onclick="document.getElementById('dt_to').value='#DateFormat(Now(), 'YYYY-MM-DD')#';">Сегодня</button>
</div>
</div>
<div class="tr">
<div class="th">Описание</div>
<div class="td">
<textarea name="descr" rows="10" cols="100">#request.htm2plain(d.descr)#</textarea>
</div>
</div>
<div class="tr">
<div class="th">Создано</div>
<div class="td">
#dateFormat(d.dt_created,'DD.MM.YYYY')# #timeFormat(d.dt_created,'HH:MM')#
#qDecoration.creator# <cfif len(qDecoration.creator_shortname)>(#qDecoration.creator_shortname#)</cfif>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Изменено
#dateFormat(d.dt_updated,'DD.MM.YYYY')# #timeFormat(d.dt_updated,'HH:MM')#
#qDecoration.updater# <cfif len(qDecoration.updater_shortname)>(#qDecoration.updater_shortname#)</cfif>
</div>
</div>
</div>
</cfoutput>
<layout:page section="extension" closeForm="Yes"/>
<i>Это цена услуги, не включая компоненты. Если компоненты есть, их суммарная стоимость (количество по каждому компоненту, умноженное на цену этого компонента) добавляется к цене услуги. Если для всех компонентов количество 0, то останется только цена услуги. Если в спецификации количество для данной услуги больше 1, то полученная сумма будет умножена на количество по данной услуге. Если стоимость, как для большинства композитных услуг, формируется только из компонентов, цена самой услуги равна нулю или (что правильнее) отсутствует в прайс-листе. </i>
<layout:page section="footer"/>

View File

@ -1,70 +0,0 @@
<cfsilent>
<cfimport prefix="m" taglib="lib"/>
<cfimport prefix="d" taglib="lib/data"/>
<cfimport prefix="layout" taglib="layout"/>
</cfsilent><m:silent silent="No">
<m:prepare_detail entity="service_price" key="service_price_id" pageInfoOut="pageInfo"/>
<!--- <cfparam name="service_price_id" type="integer"/> --->
<!--- на самом деле удаление цены запрещено, если по ней что-то продано. Поскольку продажи осуществляются вне системы управления каталогом, признаком запрета удаления может быть статус цены Активен (в котором он может использоваться для продаж) --->
<d:del
entity="#pageInfo.entity#"
confirmMessage="Удалить цену?"
denyMessage="Удаление данной цены невозможно (ситуация не предусмотрена)."
accessObj="#pageInfo.entity#"
status="status"
output="markup">
<d:del_condition field="service_price_id" value="#service_price_id#" cfsqltype="cf_sql_other"/> <!--- *** Postgresql dependent --->
</d:del>
<m:dispatch_detail
usePRG="Yes"
pageInfo=#pageInfo#
id="#service_price_id#"
status=#status#
trackOut="tr"
idAttributesOut="id"
/>
<!--- decoration --->
<cfquery name="qDecoration" datasource="#request.DS#">
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 s.service_price_id=<cfqueryparam cfsqltype="cf_sql_integer" value="#service_price_id#" null=#!isValid("integer", service_price_id)#/> --->
where t.service_price_id=<cfqueryparam cfsqltype="cf_sql_other" value="#service_price_id#" null=#!isValid("integer", service_price_id)#/>
</cfquery>
</m:silent><!--- ----------------------------------------------------------------------------
---------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------
---><layout:page section="header" pageInfo=#pageInfo#>
<layout:attribute name="title">
<cfoutput query="qDecoration">
Удаление цены услуги
#request.skuCode(area_code,code,modifier_code)#
#abstract_service#
#modifier#
<cfif len(dt_from)>с #dateFormat(dt_from,"DD.MM.YYYY")#</cfif>
<cfif len(dt_to)>по #dateFormat(dt_to,"DD.MM.YYYY")#</cfif>
#price#
[#service_price_id#]
</cfoutput>
</layout:attribute>
<layout:attribute name="controls">&nbsp;</layout:attribute>
</layout:page>
<!---<cfdump var=#qDecoration#/>--->
<cfoutput>#markup#</cfoutput>
<layout:page section="footer"/>

129
site.cfm
View File

@ -1,129 +0,0 @@
<cfsilent>
<cfimport prefix="m" taglib="lib"/>
<cfimport prefix="c" taglib="lib/controls"/>
<cfimport prefix="d" taglib="lib/data"/>
<cfimport prefix="layout" taglib="layout"/>
</cfsilent><m:silent silent="No">
<cffunction name="plain2HtmClean">
<cfargument name="s" type="string"/>
<cfreturn request.plain2htm(request.cleanHtm(s))/>
</cffunction>
<cffunction name="cleanInput">
<cfargument name="s" type="string"/>
<cfreturn htmlEditFormat(s)/>
</cffunction>
<m:prepare_detail entity="site" key="site_id" pageInfoOut="pageInfo"/>
<d:bean readonly=#!pageInfo.writePermitted()# table="site" datasource="#request.DS#" output="d" status="status">
<d:param field="site_id" type="integer" key autoincrement/>
<d:param field="site" type="varchar" size="255" preprocessor=#cleanInput#/>
<d:param field="site_en" type="varchar" size="255" preprocessor=#cleanInput#/>
<d:param field="descr" type="varchar" preprocessor=#plain2HtmClean#/>
<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:bean>
<m:dispatch_detail
usePRG="No"<!---*** --->
pageInfo=#pageInfo#
id="#d.site_id#"
status=#pageInfo.status#
trackOut="tr"
idAttributesOut="id"
/>
<!--- decoration --->
<cfquery name="qDecoration" datasource="#request.DS#">
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#=<cfqueryparam attributeCollection=#id#/>
</cfquery>
</m:silent><!---
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
---><layout:page section="header" pageInfo=#pageInfo#>
<layout:attribute name="title">
<cfoutput>
Площадка
<cfif d.site_id GT 0>
<b>#d.site#</b>
[#d.site_id#]
</cfif>
</cfoutput>
</layout:attribute>
</layout:page>
<cfif status.errorState GT 0>
<cfoutput><div class="err">#status.errorMessage#</div></cfoutput>
</cfif>
<cfoutput>
<input type="hidden" name="site_id" value="#d.site_id#"/>
<input type="hidden" name="track" value="#tr.self#"/>
<input type="hidden" name="pass" value=""/><!--- pass marker to prevent save on submit --->
<div class="detail">
<div class="tr">
<div class="th">ID</div>
<div class="td">
#d.site_id#
</div>
</div>
<div class="tr">
<div class="th">Площадка (RUS)</div>
<div class="td">
<input type="text" name="site" value="#d.site#" size="70"/>
</div>
</div>
<div class="tr">
<div class="th">Площадка (ENG)</div>
<div class="td">
<input type="text" name="site_en" value="#d.site_en#" size="70"/>
</div>
</div>
<div class="tr">
<div class="th">Описание</div>
<div class="td">
<textarea name="descr" rows="10" cols="100">#request.htm2plain(d.descr)#</textarea>
</div>
</div>
<div class="tr">
<div class="th">Создано</div>
<div class="td">
#dateFormat(d.dt_created,'DD.MM.YYYY')# #timeFormat(d.dt_created,'HH:MM')#
#qDecoration.creator# <cfif len(qDecoration.creator_shortname)>(#qDecoration.creator_shortname#)</cfif>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Изменено
#dateFormat(d.dt_updated,'DD.MM.YYYY')# #timeFormat(d.dt_updated,'HH:MM')#
#qDecoration.updater# <cfif len(qDecoration.updater_shortname)>(#qDecoration.updater_shortname#)</cfif>
</div>
</div>
</div>
</cfoutput>
<layout:page section="extension" closeForm="Yes"/>
<layout:page section="footer"/>

View File

@ -1,99 +0,0 @@
<cfsilent>
<cfimport prefix="m" taglib="lib"/>
<cfimport prefix="c" taglib="lib/controls"/>
<cfimport prefix="d" taglib="lib/data"/>
<cfimport prefix="layout" taglib="layout"/>
</cfsilent><m:silent silent="No">
<m:prepare_ls entity="site" pageInfoOut="pageInfo" trackOut="tr"/>
<m:filter_settings target="#pageInfo.entity#_ls">
<m:filterparam filter=#filter# param="quickfilter" ftype="string" prefix="%" suffix="%" expression="((p.project like ?) OR (p.customer like ?) OR (p.customer_alias like ?) OR (p.site_class_type like ?) OR (p.division like ?) OR (p.performer_short like ?))" default=""/>
</m:filter_settings>
<cfset pageInfo.settings.filter=#filter#/>
<cftry>
<cfquery name="qRead" datasource="#request.DS#">
select
<d:field_set titleMapOut="titleMap" lengthOut="fieldCount">
<d:field title="ID" cfSqlType="CF_SQL_INTEGER">m.site_id</d:field>
<d:field title="Площадка (RUS)">m.site</d:field>
<d:field title="Площадка (ENG)">m.site_en</d:field>
</d:field_set>
from site m
where 1=1 <m:filter_build filter=#pageInfo.settings.filter#/>
order by <m:order_build sortArray=#pageInfo.settings.sort.sortArray# fieldCount=#fieldCount#/>
</cfquery>
<cfcatch type="database">
<m:ls_catch catch=#cfcatch# status=#pageInfo.status#/>
</cfcatch>
</cftry>
<cfquery name="qCountTotal" datasource="#request.DS#">
select count(*) as cnt from site where 1=1
</cfquery>
</m:silent><!---
-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
---><cfif isDefined("output_xls")>
<layout:xml qRead=#qRead# titleMap=#titleMap# filename="#pageInfo.entity#.xml"/>
<cfabort/>
</cfif><cfif isDefined("output_json")>
<layout:json qRead=#qRead# titleMap=#titleMap# filename="#pageInfo.entity#.json"/>
<cfabort/>
</cfif><!---
---><layout:page section="header" pageInfo=#pageInfo#>
<layout:attribute name="title">
<cfoutput><b>Площадки</b></cfoutput>
</layout:attribute>
<layout:attribute name="controls">
<!---skip filter link, filter is not implemented--->
<!---<layout:language_switch/>--->
</layout:attribute>
</layout:page>
<cfif pageInfo.readPermitted() AND !pageInfo.status.errorState>
<layout:grid_summary
recordCount=#qRead.recordCount#
totalCount=#qCountTotal.cnt#
footerOut="gridFooter"
excelLink="Yes"
jsonLink="Yes"
/>
<table class="worktable">
<thead>
<layout:grid_head titleMap=#titleMap# sortArray=#pageInfo.settings.sort.sortArray#>
<th width="1%">
<c:link_add canWrite=#pageInfo.writePermitted()# entity=#pageInfo.entity# fwx=#tr.fwx#/>
</th>
<th width="15%"><layout:column_head name="site_id"/></th>
<th width="42%"><layout:column_head name="site"/></th>
<th width="42%"><layout:column_head name="site_en"/></th>
</layout:grid_head>
</thead>
<cfoutput query="qRead" maxrows=#pageInfo.recordsPerPage# startrow=#pageInfo.nStart#>
<tr>
<td class="c">
<c:link_view_edit canWrite=#pageInfo.writePermitted()# entity=#pageInfo.entity# id=#qRead[pageInfo.entity&'_id'][currentRow]# fwx=#tr.fwx#/>
</td>
<td class="c">#site_id#</td>
<td class="c">#site#</td>
<td class="c">#site_en#</td>
</tr>
</cfoutput>
</table>
<cfoutput>#gridFooter#</cfoutput>
</cfif>
<layout:page section="footer"/>

View File

@ -163,6 +163,10 @@
join agreement a on (siv.agreement_version=a.agreement_version AND a.contract_id=s.contract_id)
where siv.specification_item_uid=i.specification_item_uid AND a.is_actual
order by siv.agreement_version desc limit 1) as agreement
,(select a.is_actual from specification_item_version siv
join agreement a on (siv.agreement_version=a.agreement_version AND a.contract_id=s.contract_id)
where siv.specification_item_uid=i.specification_item_uid AND a.is_actual
order by siv.agreement_version desc limit 1) as is_actual
,(select a.dt_agreement from specification_item_version siv
join agreement a on (siv.agreement_version=a.agreement_version AND a.contract_id=s.contract_id)
where siv.specification_item_uid=i.specification_item_uid AND a.is_actual
@ -198,7 +202,7 @@
<cfoutput>
<p>
Строки спецификации (#qItem.recordCount#)
Фактура. Строки спецификации (#qItem.recordCount#)
<cfif pageInfo.writePermitted()>
<cfoutput>
<cfset addUrl="specification_item.cfm?specification_item_uid=&specification_id=#d.specification_id#&#tr.fwx#"/>
@ -241,7 +245,10 @@
<td class="c">#item_version_count#</td>
<td class="c"></td>
<td><a href="agreement.cfm?contract_id=#contract_id#&agreement_version=#agreement_version#&#tr.fwx#">#agreement# #dateFormat(dt_agreement,'DD.MM.YYYY')#</td>
<td class="c"><a href="specification_item_version.cfm?specification_item_uid=#specification_item_uid#&agreement_version=#agreement_version#&#tr.fwx#">#agreement_version#</a></td>
<td class="c">
<a href="specification_item_version.cfm?specification_item_uid=#specification_item_uid#&agreement_version=#agreement_version#&#tr.fwx#">#agreement_version#</a>
<cfif is_actual GT 0><img src="img/ok.png"/></cfif>
</td>
<td class="c">#dateFormat(dt_from,'DD.MM.YYYY')#</td>
<td class="c">#dateFormat(dt_to,'DD.MM.YYYY')#</td>
<td class="r">#quantity#</td>
@ -283,7 +290,7 @@
where si.specification_id=s.specification_id
AND iv.agreement_version=a.agreement_version
)*/
order by 2
order by a.agreement_version
</cfquery>
<cfoutput>
@ -303,9 +310,10 @@
<thead>
<tr>
<th></th>
<th>Соглашение</th>
<th>Соглашение (имя)</th>
<th>Дата соглашения</th>
<th>Версия</th>
<th>Версия номер</th>
<th>Действует</th>
<th>Строк изменено</th>
</tr>
</thead>
@ -313,10 +321,14 @@
<tr>
<td>
<!--- <c:link_view_edit canWrite=#pageInfo.writePermitted()# entity="specification_item" key="specification_item_uid" id=#specification_item_uid# fwx=#tr.fwx#/> --->
<a href="specification_version.cfm?specification_id=#specification_id#&agreement_version=#agreement_version#&#tr.fwx#"><img src="img/view.gif"/></a>
</td>
<td>#agreement#</td>
<td class="c">#dateFormat(dt_agreement,'DD.MM.YYYY')#</td>
<td class="c"><a href="specification_version.cfm?specification_id=#specification_id#&agreement_version=#agreement_version#&#tr.fwx#">#agreement_version#</a></td>
<td class="c">
<a href="agreement.cfm?contract_id=#d.contract_id#&agreement_version=#agreement_version#&#tr.fwx#">#agreement_version#</a>
</td>
<td class="c"><cfif is_actual GT 0><img src="img/ok.png"/></cfif></td>
<td class="c">#changed_item_cnt#</td>
</tr>
</cfoutput>

View File

@ -180,7 +180,7 @@
Версии строки (#qSpecificationItemVersion.recordCount#) (история инстанса)
<cfif pageInfo.writePermitted()>
<cfoutput>
<cfset addUrl="specification_item_version.cfm?agreement_version=-1&specification_item_uid=#d.specification_item_uid#&#tr.fwx#"/>
<cfset addUrl="specification_item_version.cfm?agreement_version=&specification_item_uid=#d.specification_item_uid#&#tr.fwx#"/>
<button type="button" class="maincontrol" onclick="document.location.href='#addUrl#'">
<a href="#addUrl#">Создать</a>
</button>

View File

@ -18,7 +18,8 @@
<!--- так... а у нас ключ составной, prepare_detail несколько сложнее --->
<cfparam name="specification_item_uid" type="guid"/>
<cfparam name="agreement_version" type="integer" default="-1"/>
<cfparam name="agreement_version" default=""/>
<m:prepare_detail
entity="specification_item_version"
key="undefined"
@ -27,17 +28,29 @@
defaultBackUrl="specification_item.cfm?specification_item_uid=#specification_item_uid#"
/>
<cfquery name="qLastVersion">
select agreement_version, quantity, price, specification_item_version
from specification_item_version
where specification_item_uid=<cfqueryparam cfsqltype="cf_sql_other" value="#specification_item_uid#" null=#!IsValid('guid',specification_item_uid)#/>
order by agreement_version desc limit 1
</cfquery>
<cfif qLastVersion.recordCount EQ 0>
<cfset queryAddRow(qLastVersion,[0,1,0,""])/>
<!--- <cfdump var=#lastVersion#/> --->
</cfif>
<!--- <cfdump var=#pageInfo#/>
<cfdump var=#specification_item_version#/>
<cfabort/> --->
<d:bean readonly=#!pageInfo.writePermitted()# table="#pageInfo.entity#" datasource="#request.DS#" output="d" status="status">
<d:param field="specification_item_uid" type="guid" key/>
<d:param field="agreement_version" type="integer" key/>
<d:param field="agreement_version" type="integer" key/> <!--- init=#qLastVersion.agreement_version# --->
<d:param field="specification_item_version" type="varchar" size="1023" preprocessor=#cleanInput#/>
<d:param field="quantity" type="numeric" init="1"/>
<d:param field="price" type="numeric" init="0"/>
<d:param field="specification_item_version" type="varchar" size="1023" init="#qLastVersion.specification_item_version#" preprocessor=#cleanInput#/>
<d:param field="quantity" type="numeric" init=#qLastVersion.quantity#/>
<d:param field="price" type="numeric" init=#qLastVersion.price#/>
<d:param field="dt_from" type="timestamp" format="yyyy-MM-dd" forNull="" init="#dateFormat(Now(),'YYYY-MM-DD')#"/> <!--- !!! Important yyyy-MM-dd NOT YYYY-MM-DD --->
<d:param field="dt_to" type="timestamp" format="yyyy-MM-dd" forNull="" init=""/> <!--- !!! Important yyyy-MM-dd NOT YYYY-MM-DD --->
@ -60,7 +73,7 @@
<!--- контекст строки всегда известен при создании версии, полный ключ не нужен для него - соответственно, джойн с основной таблицей. При этом мы собираем неверсионную часть данных, а версионная образует параллельную ветку --->
<!--- можно обратить внимание на то, что это один джойн, который растет сверху вниз (возможно, ветвится), добавляются таблицы и поля. На самом деле джойны внешние только для удобства отладки - так ошибки виднее --->
<cfquery name="qSpecificationItem" datasource="#request.DS#">
<cfquery name="qSpecificationItem">
select i.svc_id, v.svc
,s.specification_id, s.specification, s.contract_id
,d.contract, d.dt_contract, d.contragent_id
@ -74,45 +87,8 @@
</cfquery>
<!--- <cfquery name="qCost" datasource="#request.DS#">
select sum(sip.price*sip.quantity) as cost
from specification_item_version_param sip
where sip.specification_item_version_id=<cfqueryparam cfsqltype="cf_sql_integer" value="#d.specification_item_version_id#" null=#!isNumeric(d.specification_item_version_id)#/>
</cfquery> --->
<!--- <cfquery name="qSpecificationItemParam" datasource="#request.DS#">
select
sip.specification_item_version_param_id
,sp.service_param_id
,sp.param_id
,sip.price
,sip.quantity
,p.param_id
,p.param
,p.param_short
,p.code
,p.precision
,c.param_class
,m.measure_short
,spp.min_price
from service_param sp
left outer join specification_item_version_param sip
on (sp.service_param_id=sip.service_param_id AND sip.specification_item_version_id=<cfqueryparam cfsqltype="cf_sql_integer" value="#d.specification_item_version_id#"/>)
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 measure m on (c.measure_id=m.measure_id)
left outer join service_param_price spp on
(sp.service_param_id=spp.service_param_id) /***из-за полиморфизма тут надо сложнее*/
where sp.service_id=<cfqueryparam cfsqltype="cf_sql_integer" value="#d.service_id#"/>
order by c.param_class, p.param
</cfquery> --->
<!--- Здесь выборка строится от шаблона, и на него уже накручиваются реквизиты экземпляра --->
<!--- <cfdump var=#qSpecificationItemParam#/> --->
<!--- decoration --->
<cfquery name="qDecoration" datasource="#request.DS#">
<cfquery name="qDecoration">
select
a.login as creator, a.shortname as creator_shortname, m.login as updater, m.shortname as updater_shortname
from specification_item_version e
@ -169,7 +145,7 @@
select a.agreement_version, a.agreement, a.dt_agreement
from agreement a
where a.contract_id=<cfqueryparam cfsqltype="cf_sql_integer" value="#qSpecificationItem.contract_id#" null=#!isValid('integer',qSpecificationItem.contract_id)#/>
order by 1
order by 1 desc
</cfquery>
<c:combo
query=#qList#
@ -203,6 +179,7 @@
<layout:detail_line title="Дата по">
<input type="date" name="dt_to" id="dt_to" value="#dateFormat(d.dt_to,"YYYY-MM-DD")#"/>
<button type="button" onclick="document.getElementById('dt_to').value='#DateFormat(Now(), 'YYYY-MM-DD')#';">Сегодня</button>
<i>Если оставлено пустым, то версия действует до начала действия следующей. Заполнять, если хотим прекратить услугу постоянно или временно</i>
</layout:detail_line>
<layout:detail_line title="Имя для печати">
@ -211,11 +188,11 @@
</layout:detail_line>
<layout:detail_line title="Количество">
<input type="text" name="quantity" value="#d.quantity#" size="10" class="r"/><!---*** Халява с точностью ---><!--- <cftry>#round(d.quantity,qService.precision)#<cfcatch type="ANY"></cfcatch></cftry> --->
<input type="text" name="quantity" value="#d.quantity#" size="7" class="r"/><!---*** Халява с точностью ---><!--- <cftry>#round(d.quantity,qService.precision)#<cfcatch type="ANY"></cfcatch></cftry> --->
</layout:detail_line>
<layout:detail_line title="Цена">
<input type="text" name="price" id="price" value="#d.price#" size="10" class="r"/>
<input type="text" name="price" id="price" value="#d.price#" size="7" class="r"/>
</layout:detail_line>
<layout:detail_line title="Создано">

View File

@ -17,10 +17,18 @@
select
<d:field_set titleMapOut="titleMap" lengthOut="fieldCount">
<d:field title="ID" cfSqlType="CF_SQL_INTEGER">s.specification_id</d:field>
<d:field title="Контрагент">k.contragent</d:field>
<d:field>d.contragent_id</d:field>
<d:field title="Договор">d.contract</d:field>
<d:field title="Дата договора">d.dt_contract</d:field>
<d:field>s.contract_id</d:field>
<d:field title="Спецификация">s.specification</d:field>
<d:field title="Строк">(select count(*) from specification_item i where i.specification_id=s.specification_id) as item_count</d:field>
<d:field title="Соглашений">(select count(*) from agreement a where a.contract_id=s.contract_id) as agreement_count</d:field>
</d:field_set>
from specification s
left outer join contract d on (s.contract_id=d.contract_id)
left outer join contragent k on (d.contragent_id=k.contragent_id)
where 1=1 <m:filter_build filter=#pageInfo.settings.filter#/>
order by <m:order_build sortArray=#pageInfo.settings.sort.sortArray# fieldCount=#fieldCount#/>
</cfquery>
@ -69,8 +77,11 @@ select count(*) as cnt from specification where 1=1
<th width="1%">
<c:link_add canWrite=#pageInfo.writePermitted()# entity=#pageInfo.entity# fwx=#tr.fwx#/>
</th>
<th width="50%"><layout:column_head name="specification"/></th>
<th width="15%"><layout:column_head name="item_count"/></th>
<th width="15%"><layout:column_head name="specification"/></th>
<th width="5%"><layout:column_head name="item_count"/></th>
<th width="15%"><layout:column_head name="contract"/></th>
<th width="5%"><layout:column_head name="agreement_count"/></th>
<th width="15%"><layout:column_head name="contragent"/></th>
<th width="1%"></th>
</layout:grid_head>
</thead>
@ -82,6 +93,9 @@ select count(*) as cnt from specification where 1=1
</td>
<td>#specification#</td>
<td class="c">#item_count#</td>
<td>#contract# #dateFormat(dt_contract,'DD.MM.YYYY')#</td>
<td class="c">#agreement_count#</td>
<td>#contragent#</td>
<td class="c">
<c:link_del canWrite=#pageInfo.writePermitted()# entity=#pageInfo.entity# id=#qRead[pageInfo.entity&'_id'][currentRow]# fwx=#tr.fwx#/>
</td>

View File

@ -39,7 +39,9 @@
status=#pageInfo.status#
trackOut="tr"
idAttributesOut="id"
queryString="specification_id=#specification_id#&agreement_version=#agreement_version#"
/>
<!--- <cfdump var=#tr#/> --->
<!--- decoration --->
<cfquery name="qDecoration" datasource="#request.DS#">
@ -57,13 +59,30 @@
left outer join contragent c on (d.contragent_id=c.contragent_id)
where d.contract_id=<cfqueryparam cfsqltype="cf_sql_integer" value="#d.contract_id#"/>
</cfquery>
<cfquery name="qAgreement" datasource="#request.DS#">
select a.agreement, a.agreement_version, a.dt_agreement
select a.agreement, a.agreement_version, a.dt_agreement, a.is_actual
from agreement a
where a.contract_id=<cfqueryparam cfsqltype="cf_sql_integer" value="#d.contract_id#"/>
AND a.agreement_version=<cfqueryparam cfsqltype="cf_sql_integer" value="#agreement_version#" null=#!isValid('integer', agreement_version)#>
</cfquery>
<cfquery name="qVersion" datasource="#request.DS#">
select
a.agreement
,a.dt_agreement
,a.agreement_version
,a.is_actual
,(select count(*) from specification_item si
join specification_item_version iv on (si.specification_item_uid=iv.specification_item_uid)
where si.specification_id=<cfqueryparam cfsqltype="cf_sql_integer" value="#d.specification_id#"/>
AND iv.agreement_version=a.agreement_version
) as changed_item_cnt
from agreement a
where a.contract_id=<cfqueryparam cfsqltype="cf_sql_integer" value="#d.contract_id#"/>
order by a.agreement_version
</cfquery>
</m:silent><!---
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
@ -82,9 +101,11 @@
</cfoutput>
</layout:attribute>
<layout:attribute name="controls">
<cfoutput>
<button type="button" name="close" class="maincontrol" onClick="document.location.href='#tr.backUrl#'">
Закрыть
</button>
</cfoutput>
</layout:attribute>
</layout:page>
@ -102,9 +123,9 @@
<div class="tr">
<div class="th">Спецификация (номер)</div>
<div class="th">Спецификация</div>
<div class="td">
#d.specification#
#d.specification# [#d.specification_id#]
</div>
</div>
@ -144,6 +165,20 @@
#dateFormat(d.dt_updated,'DD.MM.YYYY')# #timeFormat(d.dt_updated,'HH:MM')#
#qDecoration.updater# <cfif len(qDecoration.updater_shortname)>(#qDecoration.updater_shortname#)</cfif>
</div>
</div>
<div class="tr">
<div class="th">Версии</div>
<div class="td">
<cfoutput query=#qVersion#>
<cfif qVersion.agreement_version EQ qAgreement.agreement_version>
<b>#agreement_version#</b>
<cfelse>
<a href="specification_version.cfm?specification_id=#specification_id#&agreement_version=#agreement_version#&track=#tr.self#">#agreement_version#</a>
</cfif>
&nbsp;
</cfoutput>
</div>
</div>
</div>
@ -156,55 +191,62 @@
<cfquery name="qItem" datasource="#request.DS#">
select
i.specification_item_uid
i.specification_item_uid::text as specification_item_uid
,svc.svc_id
,svc.svc
,svc.code
,s.specification_id
,s.contract_id
<!--- ,i.price*i.quantity as cost --->
<!--- ,(select count(*) from svc_param sp where sp.svc_id=i.svc_id) as svc_param_count --->
,(select siv.agreement_version from specification_item_version siv
join agreement a on (siv.agreement_version=a.agreement_version AND a.contract_id=s.contract_id)
where siv.specification_item_uid=i.specification_item_uid AND a.is_actual
order by siv.agreement_version desc limit 1) as agreement_version
,(select a.agreement from specification_item_version siv
join agreement a on (siv.agreement_version=a.agreement_version AND a.contract_id=s.contract_id)
where siv.specification_item_uid=i.specification_item_uid AND a.is_actual
order by siv.agreement_version desc limit 1) as agreement
,(select a.dt_agreement from specification_item_version siv
join agreement a on (siv.agreement_version=a.agreement_version AND a.contract_id=s.contract_id)
where siv.specification_item_uid=i.specification_item_uid AND a.is_actual
order by siv.agreement_version desc limit 1) as dt_agreement
,(select siv.specification_item_version from specification_item_version siv
join agreement a on (siv.agreement_version=a.agreement_version AND a.contract_id=s.contract_id)
where siv.specification_item_uid=i.specification_item_uid AND a.is_actual
order by siv.agreement_version desc limit 1) as specification_item
,(select siv.quantity from specification_item_version siv
join agreement a on (siv.agreement_version=a.agreement_version AND a.contract_id=s.contract_id)
where siv.specification_item_uid=i.specification_item_uid AND a.is_actual
order by siv.agreement_version desc limit 1) as quantity
,(select siv.price from specification_item_version siv
join agreement a on (siv.agreement_version=a.agreement_version AND a.contract_id=s.contract_id)
where siv.specification_item_uid=i.specification_item_uid AND a.is_actual
order by siv.agreement_version desc limit 1) as price
,(select siv.dt_from from specification_item_version siv
join agreement a on (siv.agreement_version=a.agreement_version AND a.contract_id=s.contract_id)
where siv.specification_item_uid=i.specification_item_uid AND a.is_actual
order by siv.agreement_version desc limit 1) as dt_from
,(select siv.dt_to from specification_item_version siv
join agreement a on (siv.agreement_version=a.agreement_version AND a.contract_id=s.contract_id)
where siv.specification_item_uid=i.specification_item_uid AND a.is_actual
order by siv.agreement_version desc limit 1) as dt_to
,(select count(*) from specification_item_version siv where siv.specification_item_uid=i.specification_item_uid) as item_version_count
,ver.agreement_version
,ver.specification_item_uid
,ver.agreement
,ver.dt_agreement
,ver.is_actual
,ver.specification_item_version as specification_item
,ver.quantity
,ver.price
,ver.dt_from
,ver.dt_to
from specification_item i
join specification s on (i.specification_id=s.specification_id)
--left outer join ()
join (select
siv.agreement_version
,siv.specification_item_uid
,a.agreement
,a.contract_id
,a.dt_agreement
,a.is_actual
,siv.specification_item_version
,siv.quantity
,siv.price
,siv.dt_from
,siv.dt_to
,ii1.specification_id
from specification_item_version siv
join specification_item ii1 on (siv.specification_item_uid=ii1.specification_item_uid)
join specification is1 on (ii1.specification_id=is1.specification_id)
join agreement a on (siv.agreement_version=a.agreement_version AND is1.contract_id=a.contract_id)
where a.agreement_version = (select max(iiv.agreement_version)
from specification_item_version iiv
join specification_item ii on (iiv.specification_item_uid=ii.specification_item_uid)
join specification isp on (ii.specification_id=isp.specification_id)
join agreement ia on (isp.contract_id=ia.contract_id AND iiv.agreement_version=ia.agreement_version)
where iiv.specification_item_uid=siv.specification_item_uid
<!--- <cfif qAgreement.is_actual GT 0> --->
AND ia.is_actual
<!--- </cfif> --->
AND ia.agreement_version <= <cfqueryparam cfsqltype="cf_sql_integer" value="#agreement_version#"/>
)
) ver on (i.specification_item_uid=ver.specification_item_uid AND s.contract_id=ver.contract_id AND ver.specification_id=s.specification_id)
left outer join svc on (i.svc_id=svc.svc_id)
where i.specification_id=<cfqueryparam cfsqltype="cf_sql_integer" value="#d.specification_id#"/>
order by 2
</cfquery>
<!--- <cfdump var=#qItem#/> --->
<cfoutput>
<p>
Строки спецификации (#qItem.recordCount#)
@ -250,7 +292,7 @@
<td class="c">#item_version_count#</td>
<td class="c"></td>
<td><a href="agreement.cfm?contract_id=#contract_id#&agreement_version=#agreement_version#&#tr.fwx#">#agreement# #dateFormat(dt_agreement,'DD.MM.YYYY')#</td>
<td class="c"><a href="specification_item_version.cfm?specification_item_uid=#specification_item_uid#&agreement_version=#agreement_version#&#tr.fwx#">#agreement_version#</a></td>
<td class="c"><a href="specification_item_version.cfm?specification_item_uid=#specification_item_uid#&agreement_version=#qItem.agreement_version#&#tr.fwx#">#qItem.agreement_version#</a> <cfif is_actual><img src="img/ok.png"/></cfif></td>
<td class="c">#dateFormat(dt_from,'DD.MM.YYYY')#</td>
<td class="c">#dateFormat(dt_to,'DD.MM.YYYY')#</td>
<td class="r">#quantity#</td>
@ -262,6 +304,8 @@
</tr>
</cfoutput>
</table>
<br/>
учитываются только действующие соглашения
</cfif>