spec/param_clone.cfm
2025-06-02 16:16:51 +03:00

294 lines
14 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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="param" key="param_id" pageInfoOut="pageInfo"/>
<cfparam name="original_service_param_id" type="integer"/>
<cfparam name="do_clone" type="integer" default="0"/><!--- форма клонирования может вызываться методом POST --->
<!--- тут должна быть такая хитрость. Сначала прочитать данные по ключу старого параметра
(получить в URL или восстановить из original_service_param_id, что менее избыточно).
А при сохранении подставить в param_id -1.
Но если изначально поместить в param_id валидный ключ, он вместе со всеми данными попадет в структуру d.
Получается, в режиме чтения мы хотим использовать старый ключ, а при первой записи подставить невалидный ключ. При успешном _создании_ записи мы должны сделать вставку в service_param, а при повторной записи, если такая случится - вставку не делать (или вообще предотвратить сохранение, хотя почему бы не разрешить исправления)
Можно просто сделать флаг (скажем, клонирования), который сбрасывать при успешном сохранении.
Через некоторое время можно дойти до того, чтобы включить эту функциональность в param.cfm (в основном сложность и новизна будет в записи в service_param). А так функцию клонирования можно стандартизировать для всех сущностей, кажется полезной.
--->
<cfif do_clone GT 0 AND (structKeyExists(form,"save") OR structKeyExists(form,"saveAndClose"))>
<!--- *** это некрасиво, потому что save, saveAndClose - это маркеры bean и про них другим знать не положено, хотя контролам приходится знать, и то, что маркеров 2, делает ситуацию вдвойне некрасивой. Ниже мы пользуемся полем status.processingMode, но нам надо решить вопрос строго до вызова bean
*** В будущей редакции хотя бы один маркер оставить?
--->
<cfset form.param_id=-1/><!--- *** тоже некрасиво - форму патчить --->
</cfif>
<d:bean readonly=#!pageInfo.writePermitted()# table="param" datasource="#request.DS#" output="d" status="status">
<d:param field="param_id" type="integer" key autoincrement/>
<d:param field="param_class_id" type="integer" forNull=""/>
<d:param field="param" type="varchar" size="255" preprocessor=#cleanInput#/>
<d:param field="param_short" type="varchar" size="255" preprocessor=#cleanInput#/>
<d:param field="param_en" type="varchar" size="255" preprocessor=#cleanInput#/>
<d:param field="param_short_en" type="varchar" size="255" preprocessor=#cleanInput#/>
<d:param field="measure_id" type="integer" forNull=""/>
<d:param field="precision" type="integer" default="0" init="0"/>
<d:param field="sort" type="integer" init="100" forNull=""/>
<d:param field="code" type="varchar" size="15" 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>
<!--- <cfdump var=#d#/> --->
<!---
<cfif status.errorState>
<cfoutput>#status#</cfoutput>
<cfabort/>
</cfif>
--->
<!--- вставить ссылку в service_param --->
<!--- *** попытка вставки будет и при повторном сохранении
но проверка предотвратит ошибку нарушения ключа
*** вообще надо бы придумать какой-то изящный способ вставки записи и ссылки, а то костыль на костыле --->
<cfif status.processingMode EQ "save" AND NOT status.errorState>
<cfset do_clone=0/><!--- если при сохранении ссылки произойдет ошибка, мы не хотим продолжать плодить копии param --->
<cfquery datasource="#request.DS#">
insert into service_param (
service_id,param_id,abstract_service_param_class_id,min_value,max_value,incr,descr
) select
service_id
,<cfqueryparam cfsqltype="cf_sql_integer" value="#d.param_id#"/>
,abstract_service_param_class_id
,min_value
,max_value
,incr
,descr
from service_param sp
where service_param_id=<cfqueryparam cfsqltype="cf_sql_integer" value="#original_service_param_id#"/>
AND NOT exists(select * from service_param sp1 where sp1.service_id=sp.service_id AND sp1.param_id=<cfqueryparam cfsqltype="cf_sql_integer" value="#d.param_id#" null=#!isNumeric(d.param_id)#/>);
</cfquery>
</cfif>
<cfset pageInfo.status=#status#/>
<m:dispatch_detail
usePRG="No"<!---*** --->
pageInfo=#pageInfo#
id="#d.param_id#"
status=#pageInfo.status#
trackOut="tr"
idAttributesOut="id"
/>
<cfquery name="qParamClass" datasource="#request.DS#">
select p.param_class, p.param_class_en, p.measure_id, p.precision
from param_class p
where param_class_id=<cfqueryparam cfsqltype="cf_sql_integer" value="#d.param_class_id#" null=#!isNumeric(d.param_class_id)#/>
</cfquery>
<!--- шаблонирование --->
<cfif NOT d.measure_id GT 0><cfset d.measure_id=qParamClass.measure_id/></cfif>
<cfif NOT d.precision GT 0><cfset d.precision=qParamClass.precision/></cfif>
<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.param_class_id GT 0>
<b>#qParamClass.param_class#</b>
</cfif>
<cfif d.param_id GT 0>
<b>#d.param#</b>
[#d.param_id#]
</cfif>
</cfoutput>
</layout:attribute>
<!--- controls override--->
<layout:attribute name="controls">
<cfoutput>
<button type="submit" name="save" value="Клонировать" class="maincontrol"<cfif NOT pageInfo.writePermitted()> disabled</cfif>>#request.i18("Клонировать","Clone")#</button>
<button type="submit" name="saveAndClose" value="Клонировать и закрыть" class="maincontrol"<cfif NOT pageInfo.writePermitted()> disabled</cfif>>#request.i18("Клонировать и закрыть","Clone and Close")#</button>
<button type="button" name="close" value="Закрыть" onClick="document.location.href='#tr.backUrl#'" class="maincontrol">#request.i18("Закрыть","Close")#</button>
</cfoutput>
</layout:attribute>
</layout:page>
<cfif status.errorState GT 0>
<cfoutput><div class="err">#status.errorMessage#</div></cfoutput>
</cfif>
<cfoutput>
<input type="hidden" name="param_id" value="#d.param_id#"/>
<input type="hidden" name="original_service_param_id" value="#original_service_param_id#"/>
<input type="hidden" name="do_clone" value="#do_clone#"/>
<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="qList" datasource="#request.DS#">
select param_class_id, param_class
from param_class
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##"
empty=""
class=""
onchange="submit();"
/>
<!--- <cfif d.param_id GT 0>
<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> --->
</div>
</div>
<div class="tr">
<div class="th">Вариант компонента</div>
<div class="td">
<cfset m_param=d.param/>
<cfif NOT d.param_id GT 0 <!--- AND NOT len(m_param) GT 0 --->>
<cfset m_param=#qParamClass.param_class#/>
</cfif>
<input type="text" name="param" value="#m_param#" size="70"/>
<i>Имя компонента - должно быть уникальным *** Контроль!</i>
</div>
</div>
<div class="tr">
<div class="th">Сокращение</div>
<div class="td">
<cfset m_param_short=d.param_short/>
<cfif NOT d.param_id GT 0 <!--- AND NOT len(m_param_short) GT 0 --->>
<cfset m_param_short=#qParamClass.param_class#/>
</cfif>
<input type="text" name="param_short" value="#m_param_short#" size="70"/>
<i>Используется при формировании полного названия услуги в спецификации</i>
</div>
</div>
<div class="tr">
<div class="th">Код</div>
<div class="td">
<input type="text" name="code" value="#d.code#" size="7"/>
<i>Должен быть уникальным в пределах компонента (класса компонента)</i>
</div>
</div>
<div class="tr">
<div class="th i">Полное наименование</div>
<div class="td">
<b>#qParamClass.param_class# #d.param#</b>
<i>Формируется из имени класса и имени компонента (уточненного, если есть варианты)</i>
</div>
</div>
<div class="tr">
<div class="th">Единица измерения</div>
<div class="td">
<cfquery name="qMeasure" datasource="#request.DS#">
select measure_id, measure_short
from measure
order by 2
</cfquery>
<c:combo
query=#qMeasure#
combo="measure_id"
id="measure_id"
key="measure_id"
selected="#d.measure_id#"
displayf="##measure_short##"
empty=""
class=""
/>
</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">
<input type="text" name="sort" value="#d.sort#" size="1" 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="extension" closeForm="Yes"/>
<i>Просьба следить за отсутствием дублирования и поменять значения всех полей, которые нужно.</i>
<!--- ------------------------------------------------------------------------------- --->
<!--- ------------------------------------------------------------------------------- --->
<!--- ------------------------------------------------------------------------------- --->
<layout:page section="footer"/>