Files
svc-api-x/v1/resources/instance_operation_cfs_param_ls.cfc
T

487 lines
29 KiB
Plaintext
Raw 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.
<cfcomponent extends="taffy.core.resource" taffy:uri="/instanceOperationCfsParams">
<!--- Вот здесь мы могли бы строить URI /instances/{instanceUid}/instanceOperations/{instanceOperationUid}/CfsParams, но это создает избыточность, у нас простые суррогатные первичные ключи. С другой стороны, контекст инстанса и операции у клиента всегда имеется. Но стоит ли передавать избыточную информацию? Это иногда провоцирует путаницу. Для POST мы можем передать необходимый контекст в теле запроса, а можем в URL.
В данном случае никакого смысла смотреть на все CFS параметры нет, только в рамках операции
Но: мы не хотели бы менять положение сущности в дереве. Либо она в корне, либо она ниже. И получится, когда мы выбираем один параметр, нам ни к чему контекст - мы к нему однозначно адресуемся.
Проголосуем за отсутстие избыточности?
--->
<!--- Проверять принадлежность инстанса текущему клиенту
При выборке CFS параметров проверятся принадлежность текущей спецификации пользователя
--->
<!--- Все методы неявно получают
arguments.usrId
arguments.contragentId
arguments.contractId
arguments.specificationId
arguments.requestArguments.usrId=usrCustomerInfo.usrId; //Integer!
arguments.requestArguments.contragentId=usrCustomerInfo.contragentId; //Integer
arguments.requestArguments.contractId=usrCustomerInfo.contractId; //Integer
arguments.requestArguments.specificationId=usrCustomerInfo.specificationId; //Integer
--->
<cfsilent>
<cfimport prefix="m" taglib="../lib"/>
<cfset this.helper=CreateObject("component","lib.rest_api_helper")/><!---*** странно, почему мы его видим?---><!---вынести в апп?--->
</cfsilent>
<!---спецификация полей, пригодных для фильтрации --->
<cfset this.fieldsSpec={
dt_created={prefix="iop", type="date"},
svc_operation_cfs_param={prefix="sop", type="string"},
login={prefix="iop", type="string"},
creator_id={prefix="iop", type="integer"},
sort={prefix="sop", type="integer"},
is_sensitive={prefix="sop", type="boolean"},
depends_on_cfs_params={prefix="sop", type="string"}
<!--- ,
dt_updated={prefix="e", type="date"},
service_id={prefix="e", type="integer"},
svc={prefix="v", type="string"},
is_test={prefix="e", type="boolean"} --->
}
/>
<cffunction name="get" hint="Список CFS параметров">
<cfargument name="pageSize" type="string" hint="type:integer" default="1000"/> <!--- *** тут на самом деле есть лимит --->
<cfargument name="page" type="string" hint="type:integer" default="1"/>
<cfargument name="orderBy" type="string" hint="type:string, description:comma-separated list of fields to sort by, example:fld1.ASC,fld2.DESC,fld3.ASC" default=""/>
<cfargument name="instanceOperationUid" type="string" required=false hint="type:guid"/>
<!---parse and validate request parameters--->
<cftry>
<!--- *** Добавить проверку ссылочной целостности --->
<cfif !this.helper.keyExistsAndValid(arguments,"instanceOperationUid","guid")>
<cfthrow type="invalidParamValue" message="Missing required parameter" detail="instanceOperationUid is missing or not a valid GUID"/>
</cfif>
<cfset this.helper.validateField(arguments, "pageSize", "integer")/>
<cfset this.helper.validateField(arguments, "page", "integer")/>
<!---мы мирно игнорируем поля, отсутствующие в спецификации, что позволяет не делать исключения для orderBy и т.п.--->
<cfset var filter=this.helper.parseFilterParams(this.fieldsSpec)/>
<!--- <cfset var order=this.helper.parseOrderBy(this.fieldsSpec, arguments.orderBy)/> --->
<cfcatch type="invalidParamValue">
<cfreturn representationOf(this.helper.formatBadRequestError(cfcatch)).withStatus(400)/>
</cfcatch>
</cftry>
<cfset var out={}/>
<cfset var maxrows=arguments.pageSize*arguments.page/>
<cfset var startrow=arguments.pageSize*(arguments.page-1)+1/>
<cfset var local={}/>
<!--- *** обширное дублирование с instance_operation_cfs_param.cfc --->
<cfquery name="local.qCfsParam" result="local.result">
select
<m:field_set titleMapOut="local.titleMap" lengthOut="fieldCount">
<m:field title="instance_operation_cfs_param_uid">iop.instance_operation_cfs_param_uid::text as instance_operation_cfs_param_uid</m:field>
<m:field title="instance_operation_uid">iop.instance_operation_uid::text as instance_operation_uid</m:field>
<m:field title="svc_operation_cfs_param_id">iop.svc_operation_cfs_param_id</m:field>
<m:field title="param_value">case when sop.is_sensitive then '********' else iop.param_value end as param_value </m:field>
<m:field>iop.note</m:field>
<m:field>to_char(iop.dt_created, 'YYYY-MM-DD"T"HH24:MI:SS.FF3TZHTZM') as dt_created</m:field>
<m:field>iop.creator_id</m:field>
<m:field>u.login as creator_login</m:field>
<m:field>u.shortname as creator_shortname</m:field>
<m:field>sop.svc_operation_cfs_param</m:field>
<m:field>sop.sort</m:field>
<m:field formatter=#request.castToBool#>sop.is_sensitive</m:field>
<m:field>sop.data_type</m:field>
<m:field formatter=#function(x){return listToArray(x);}#>sop.value_list</m:field>
<m:field>sop.default_value</m:field>
<m:field>sop.func</m:field>
<m:field>sop.man</m:field>
<m:field>sop.depends_on_cfs_params</m:field>
<m:field>null as data_descriptor</m:field>
<m:field>e.service_id</m:field>
</m:field_set>
from instance_operation_cfs_param iop
join instance_operation io on (iop.instance_operation_uid=io.instance_operation_uid)
join instance e on (io.instance_uid=e.instance_uid)
join specification_item si on (e.specification_item_id=si.specification_item_id)
join svc_operation_cfs_param sop on (iop.svc_operation_cfs_param_id=sop.svc_operation_cfs_param_id)
left outer join usr u on (iop.creator_id=u.usr_id)
where iop.instance_operation_uid=<cfqueryparam cfsqltype="cf_sql_other" value="#arguments.instanceOperationUid#" null=#!isValid('guid',arguments.instanceOperationUid)#/>
AND si.specification_id=<cfqueryparam cfsqltype="cf_sql_integer" value=#arguments.specificationId#/>
<m:filter_build filter=#filter#/>
order by <m:order_build sortCollection=#this.helper.parseNumericOrder(local.titleMap, arguments.orderBy)# fieldCount=0/><!---no sort length limit--->
--limit #maxrows#
</cfquery>
<cfquery name="local.qTotal">
select count(*) as cnt
from instance_operation_cfs_param iop
where iop.instance_operation_uid=<cfqueryparam cfsqltype="cf_sql_other" value="#arguments.instanceOperationUid#" null=#!isValid('guid',arguments.instanceOperationUid)#/>
</cfquery>
<cfloop query="local.qCfsParam">
<cfif len(func)><!--- приоритет отдается функции перед списком значений--->
<!--- *** отличается от аналогичных вызовов --->
<cfset var args = {
"functionName":"#func#",
"svcId":#local.qCfsParam.service_id#,
"contractId":#arguments.contractId#
}/> <!--- если появятся новые аргументы у новых функций, будем добавлять их сюда --->
<!--- <cfset local.qCfsParam.value_list=generateValueList(argumentCollection=#args#)/> --->
<cfinvoke component="instance_operation_cfs_param" method="generateValueList" argumentCollection=#args# returnVariable="local.qCfsParam.value_list"/><!--- *** тут засада с форматом списка: массив или лист --->
<!--- можно перечислить именованные аргументы обычным порядком, но с коллекцией потенциально более гибко --->
<cfif len(trim(local.qCfsParam.value_list)) AND listLen(local.qCfsParam.value_list) EQ 1>
<cfset local.qCfsParam.default_value=local.qCfsParam.value_list/>
</cfif>
</cfif>
<cfif data_type EQ "map" OR data_type EQ "map-fixed" OR data_type EQ "array-map-fixed">
<cfinvoke component="instance_operation_cfs_param" method="processMap" qParam=#local.qCfsParam#/>
</cfif>
</cfloop>
<cfset "out.queryDurationMs"=getTickCount() - request.startTickCount/>
<cfset "out.total"=#local.qTotal.cnt#/>
<cfset "out.resultSetSize"=#local.qCfsParam.recordCount#/>
<cfset "out.pageSize"=#arguments.pageSize*1#/>
<cfset "out.page"=#arguments.page*1#/>
<cfset "out.orderBy"=#arguments.orderBy#/>
<cfset var resultCollection=[]/>
<cfloop query=#local.qCfsParam# startRow=#startrow# endRow=#(startrow+maxrows-1)#>
<cfset var rec={}/>
<cfset this.helper.appendRecord(rec, "", local.titleMap, local.qCfsParam, this.helper.snake2camel)/>
<cfset arrayAppend(resultCollection, rec)/>
</cfloop>
<cfset "out.size"=#arrayLen(resultCollection)#/>
<cfset "out.results"=#resultCollection#/>
<cfset "out.runDurationMs"=getTickCount()-request.startTickCount/>
<!---<cfset "out.sql"=#local.result.sql#/>--->
<cfreturn representationOf(out)/>
</cffunction><!--- get --->
<cffunction name="post" hint="Создание нового CFS параметра операции.">
<cfargument name="instanceOperationUid" type="string" required=true hint="type:guid"/>
<cfargument name="svcOperationCfsParamId" type="string" required=true hint="type:integer"/>
<cfargument name="paramValue" type="string" required=true hint="type:string ***Валидацию пока не проводим, а надо"/>
<cfargument name="note" type="string" required=false default="" hint="type:string description: комментарий пользователя"/>
<!---
неявно инжектируются
arguments.usrId (используется)
arguments.contragentId
arguments.contractId
arguments.specificationId
Мы их не декларитуем, иначе Taffy их увидит и будет думать, что надо их получить,
и включит в документацию,
и можно будет их задать принудительно, что нам совершенно не нужно
--->
<cftry>
<cfset this.helper.validateField(arguments, "instanceOperationUid", "guid")/>
<cfset this.helper.validateField(arguments, "svcOperationCfsParamId", "integer")/>
<!--- Еще возможна ошибка, что мы подадим параметр не от своей операции или сервиса - он останется невидим для всех --->
<cfset checkParam(arguments.svcOperationCfsParamId, arguments.paramValue, arguments.usrId)/>
<cfset checkResourceRealmAccess(arguments.instanceOperationUid, arguments.svcOperationCfsParamId, arguments.paramValue)/>
<cfcatch type="invalidParamValue">
<cfreturn representationOf(this.helper.formatBadRequestError(cfcatch)).withStatus(400)/>
</cfcatch>
</cftry>
<cfset var local={}/>
<cfset local.instanceOperationCfsParamUid=#createGUID()#/>
<cftry>
<cfquery name="local.qCheck" result="local.result">
select io.dt_submit, io.dt_finish, io.submit_result
from instance_operation io
where io.instance_operation_uid=<cfqueryparam cfsqltype="cf_sql_other" value="#arguments.instanceOperationUid#" null=#!isValid('guid',arguments.instanceOperationUid)#/>
</cfquery>
<cfif left(local.qCheck.submit_result,1) EQ "2" AND len(local.qCheck.dt_finish) EQ 0><!--- 201 etc --->
<cfreturn representationOf(this.helper.formatMessage("Operation already started", "Parameter creation disabled for started operation")).withStatus(422)/>
</cfif>
<!--- Проверка: параметр от нашего ли сервиса *** и операции --->
<cfquery name="local.qInstanceService" result="local.result">
select e.service_id, io.operation, si.specification_id
from instance_operation io
join instance e on (io.instance_uid=e.instance_uid)
left outer join specification_item si on (e.specification_item_id=si.specification_item_id)
where io.instance_operation_uid=<cfqueryparam cfsqltype="cf_sql_other" value="#arguments.instanceOperationUid#"/>
</cfquery>
<cfquery name="local.qTemplateSvc" result="local.result">
select so.svc_id, so.operation
from svc_operation_cfs_param sop
join svc_operation so on (sop.svc_operation_id=so.svc_operation_id)
where sop.svc_operation_cfs_param_id=<cfqueryparam cfsqltype="cf_sql_integer" value="#arguments.svcOperationCfsParamId#"/>
</cfquery>
<cfif local.qInstanceService.specification_id NEQ arguments.specificationId>
<cfreturn representationOf(this.helper.formatMessage("Instance not accessible", "Instance does not belong to the current specification, contract or contragent")).withStatus(403)/>
</cfif>
<cfif local.qInstanceService.service_id NEQ local.qTemplateSvc.svc_id>
<cfreturn representationOf(this.helper.formatMessage("Invalid CFS parameter", "Parameter specified does not belong to this service")).withStatus(400)/>
</cfif>
<cfif local.qInstanceService.operation NEQ local.qTemplateSvc.operation>
<cfreturn representationOf(this.helper.formatMessage("Invalid CFS parameter", "Parameter specified does not belong to this operation")).withStatus(400)/>
</cfif>
<cfquery name="local.qSave">
insert into instance_operation_cfs_param (
instance_operation_cfs_param_uid,instance_operation_uid,svc_operation_cfs_param_id,param_value,note,dt_created,creator_id
) values (
<cfqueryparam cfsqltype="cf_sql_other" value="#local.instanceOperationCfsParamUid#"/>
,<cfqueryparam cfsqltype="cf_sql_other" value="#arguments.instanceOperationUid#"/>
,<cfqueryparam cfsqltype="cf_sql_integer" value="#arguments.svcOperationCfsParamId#"/>
,<cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.paramValue#"/><!--- htmlEditFormat --->
,<cfqueryparam cfsqltype="cf_sql_varchar" value="#htmlEditFormat(arguments.note)#"/>
,<cfqueryparam cfsqltype="cf_sql_timestamp" value="#Now()#" />
,<cfqueryparam cfsqltype="cf_sql_integer" value="#arguments.usrId#" />
);
</cfquery>
<!--- <cfcatch type="invalidParamValue">
<cfreturn representationOf(this.helper.formatBadRequestError(cfcatch)).withStatus(400)/>
</cfcatch> --->
<cfcatch type="any">
<cfreturn representationOf(this.helper.formatException(cfcatch, "Internal Error")).withStatus(500)/>
</cfcatch>
</cftry>
<cfreturn noData()
.withHeaders({location: "./#local.instanceOperationCfsParamUid#"})
.withStatus(201, "Created")
/>
</cffunction><!--- post --->
<cffunction name="checkParam" returnType="void">
<!--- проверка параметров по метаданным, независимо от семантики самого параметра --->
<cfargument name="svcOperationCfsParamId" type="numeric" required = true/>
<cfargument name="paramValue" required = true/>
<cfargument name="usrId" type="numeric"/>
<cfargument name="instanceOperationCfsParamUid" type="guid" default="00000000-0000-0000-0000-000000000000"/><!--- используется при проверке уникальности, чтобы не сравнивать с собой --->
<!--- *** Вероятно, стоит возвращать конкретную ругань --->
<!--- принадлежит ли параметр данному сервису, проверяется выше --->
<!--- получаем метаданные параметра --->
<cfset var local={}/>
<cfquery name="local.qSvcOperationCfsParam">
select sop.svc_operation_cfs_param_id
,sop.svc_operation_cfs_param
,sop.value_list
,sop.data_type
,sop.is_required
,sop.maxlength
,sop.minlength
,sop.regex
,sop.unique_scope
,sop.maxvalue
,sop.minvalue
from svc_operation_cfs_param sop
where sop.svc_operation_cfs_param_id=<cfqueryparam cfsqltype="cf_sql_integer" value="#arguments.svcOperationCfsParamId#"/>
</cfquery>
<cfif local.qSvcOperationCfsParam.is_required GT 0 AND len(arguments.paramValue) EQ 0>
<cfthrow type="invalidParamValue" message="Missing required parameter (#local.qSvcOperationCfsParam.svc_operation_cfs_param#)"/>
<cfelseif len(arguments.paramValue) AND NOT validateDataType(arguments.paramValue,local.qSvcOperationCfsParam.data_type)>
<cfthrow type="invalidParamValue" message="Invalid format #local.qSvcOperationCfsParam.data_type# #local.qSvcOperationCfsParam.svc_operation_cfs_param#"/>
</cfif>
<cfif len(arguments.paramValue) AND listLen(local.qSvcOperationCfsParam.value_list) GT 0 AND NOT listFind(local.qSvcOperationCfsParam.value_list, arguments.paramValue)>
<cfthrow type="invalidParamValue" message="Значение параметра #local.qSvcOperationCfsParam.svc_operation_cfs_param# отсутствует в списке '#local.qSvcOperationCfsParam.value_list#'" detail="listLen:#listLen(local.qSvcOperationCfsParam.value_list)#"/>
</cfif>
<cfif len(arguments.paramValue) AND local.qSvcOperationCfsParam.maxlength GT 0 AND len(arguments.paramValue) GT local.qSvcOperationCfsParam.maxlength>
<cfthrow type="invalidParamValue" message="Длина #local.qSvcOperationCfsParam.svc_operation_cfs_param# превышает #local.qSvcOperationCfsParam.maxlength#"/>
</cfif>
<cfif len(arguments.paramValue) AND local.qSvcOperationCfsParam.minlength GT 0 AND len(arguments.paramValue) LT local.qSvcOperationCfsParam.minlength>
<cfthrow type="invalidParamValue" message="Длина #local.qSvcOperationCfsParam.svc_operation_cfs_param# меньше #local.qSvcOperationCfsParam.minlength#"/>
</cfif>
<cfif len(arguments.paramValue) AND len(local.qSvcOperationCfsParam.regex) AND reFind(local.qSvcOperationCfsParam.regex,arguments.paramValue) EQ 0>
<cfthrow type="invalidParamValue" message='Parameter "#local.qSvcOperationCfsParam.svc_operation_cfs_param#" value "#arguments.paramValue#" does not match pattern "#local.qSvcOperationCfsParam.regex#" '/>
</cfif>
<cfif isNumeric(arguments.paramValue) AND isNumeric(local.qSvcOperationCfsParam.maxvalue) AND arguments.paramValue GT local.qSvcOperationCfsParam.maxvalue>
<cfthrow type="invalidParamValue" message='Parameter "#local.qSvcOperationCfsParam.svc_operation_cfs_param#" value "#arguments.paramValue#" is greater than "#local.qSvcOperationCfsParam.maxvalue#" '/>
</cfif>
<cfif isNumeric(arguments.paramValue) AND isNumeric(local.qSvcOperationCfsParam.minvalue) AND arguments.paramValue LT local.qSvcOperationCfsParam.minvalue>
<cfthrow type="invalidParamValue" message='Parameter "#local.qSvcOperationCfsParam.svc_operation_cfs_param#" value "#arguments.paramValue#" is less than "#local.qSvcOperationCfsParam.minvalue#" '/>
</cfif>
<!--- *** интересно, как мы ухитряемся проверить уникальность параметра, если он относится к операции, а не к экземпляру. Нам-то нужна уникальность для стейта (и то, скорее, единовременная, и интересовать будут только успешные операции) --->
<!--- ****** Внимание! Этот код сравнивает параметры одноименных операций, но уникальность должна быть и между create-modify и т.п. --->
<cfset checkUniqueness(
arguments.svcOperationCfsParamId,
qSvcOperationCfsParam.svc_operation_cfs_param,
arguments.paramValue,
qSvcOperationCfsParam.unique_scope,
arguments.instanceOperationCfsParamUid,
arguments.usrId
)/>
</cffunction>
<cffunction name="checkUniqueness" returnType="void">
<!--- использую void, потому что с исключением проще передавать информацию о конкретном характере ошибки. Чем возвращать объект ошибки - проше бросить исключение --->
<cfargument name="svcOperationCfsParamId" type="numeric"/>
<cfargument name="svcOperationCfsParamName" type="string"/><!--- нужен только для формирования текста сообщения об ошибке --->
<cfargument name="paramValue" type="string"/>
<cfargument name="scope" type="string"/>
<cfargument name="instanceOperationCfsParamUid" type="guid"/>
<cfargument name="usrId" type="numeric"/>
<cfset var local={}/>
<cfswitch expression=#arguments.scope#>
<cfcase value="provider">
<cfquery name="local.qUnique">
select count(*) as cnt
from instance_operation_cfs_param p
join instance_operation o on (p.instance_operation_uid=o.instance_operation_uid)
join instance e on (o.instance_uid=e.instance_uid)
where p.param_value=<cfqueryparam cfsqltype="cf_sql_varchar" value=#arguments.paramValue#/>
AND p.svc_operation_cfs_param_id=<cfqueryparam cfsqltype="cf_sql_integer" value=#arguments.svcOperationCfsParamId#/>/*limit to the current svc param*/
<cfif arguments.instanceOperationCfsParamUid NEQ "00000000-0000-0000-0000-000000000000">
<!--- не решаюсь оставить эту проверку на БД, потому что наличие записи с 00000000-0000-0000-0000-000000000000 может все сломать --->
AND p.instance_operation_cfs_param_uid <> <cfqueryparam cfsqltype="cf_sql_other" value=#arguments.instanceOperationCfsParamUid#/>/*exclude itself*/
</cfif>
AND (select cast(st.instance_data->>'isDeleted' as boolean) from instance_state st where st.instance_uid=e.instance_uid order by version desc limit 1) IS NOT TRUE /*ignore deleted instances*/
</cfquery><!--- ****** здесь может таиться трудно понимаемый баг с отсутствием записи --->
<!--- <cfdump var=#qUnique#/><cfabort/> --->
<cfif local.qUnique.cnt GT 0>
<cfthrow type="invalidParamValue" message='#arguments.svcOperationCfsParamName# = "#arguments.paramValue#" is not unique in the provider scope'/>
</cfif>
</cfcase>
<cfcase value="tenant">
<cfquery name="local.qUnique">
select count(*) as cnt
from instance_operation_cfs_param p
join instance_operation o on (p.instance_operation_uid=o.instance_operation_uid)
join instance e on (o.instance_uid=e.instance_uid)
join specification_item i on (e.specification_item_id=i.specification_item_id)
join specification s on (i.specification_id=s.specification_id)
join contract d on (s.contract_id=d.contract_id)
join contragent k on (d.contragent_id=k.contragent_id)
join usr u on (k.contragent_id=u.contragent_id)
where p.param_value=<cfqueryparam cfsqltype="cf_sql_varchar" value=#arguments.paramValue#/>
AND svc_operation_cfs_param_id=<cfqueryparam cfsqltype="cf_sql_integer" value=#arguments.svcOperationCfsParamId#/>/*limit to the current svc param*/
AND u.usr_id=<cfqueryparam cfsqltype="cf_sql_integer" value=#arguments.usrId#/>/*limit to the contragent of current user*/
<cfif arguments.instanceOperationCfsParamUid NEQ "00000000-0000-0000-0000-000000000000">
<!--- не решаюсь оставить эту проверку на БД, потому что наличие записи с 00000000-0000-0000-0000-000000000000 может все сломать --->
AND p.instance_operation_cfs_param_uid <> <cfqueryparam cfsqltype="cf_sql_other" value=#arguments.instanceOperationCfsParamUid#/>/*exclude itself*/
</cfif>
AND (select cast(st.instance_data->>'isDeleted' as boolean) from instance_state st where st.instance_uid=e.instance_uid order by version desc limit 1) IS NOT TRUE /*ignore deleted instances*/
</cfquery><!--- ****** здесь может таиться трудно понимаемый баг с отсутствием записи --->
<!--- <cfdump var=#qUnique#/> --->
<cfif local.qUnique.cnt GT 0>
<cfthrow type="invalidParamValue" message='#arguments.svcOperationCfsParamName# = "#arguments.paramValue#" is not unique in the tenant scope'/>
</cfif>
</cfcase>
<cfdefaultcase></cfdefaultcase>
</cfswitch>
</cffunction>
<cffunction name="validateDataType" returnType="boolean">
<cfargument name="value" type="string"/>
<cfargument name="dataType" type="string"/>
<!--- Что возвращать-то?
Идею бросать исключение при некорректном вводе надо отринуть. Все введенные параметры надо обработать и не терять --->
<cfswitch expression=#arguments.dataType#>
<cfcase value=",string">
<cfreturn true/>
</cfcase>
<cfcase value="boolean">
<cfreturn IsBoolean(arguments.value)/><!--- можно было сделать и единообразно --->
</cfcase>
<cfcase value="integer">
<cfreturn isValid("integer",arguments.value)/>
</cfcase>
<cfcase value="integer &gt; 0">
<cfreturn isValid("integer",arguments.value) AND arguments.value GT 0/>
</cfcase>
<cfcase value="integer &gt;= 0">
<cfreturn isValid("integer",arguments.value) AND arguments.value GE 0/>
</cfcase>
<cfcase value="numeric">
<cfreturn isNumeric(arguments.value)/>
</cfcase>
<cfcase value="uuid">
<cfreturn isValid("guid",arguments.value)/><!--- *** или GUID? Или принимать оба формата GUID UUID и приводить к одному? А как быть с БД--->
</cfcase>
<cfcase value="map,map-fixed">
<cftry>
<cfset var v = deserializeJson(arguments.value)/>
<cfreturn isStruct(v)/><!--- массив нас не устроит --->
<cfcatch type="ANY">
<cfreturn false/>
</cfcatch>
</cftry>
</cfcase>
<cfcase value="array-map-fixed">
<cftry>
<cfset var v = deserializeJson(arguments.value)/>
<cfreturn isArray(v)/>
<cfcatch type="ANY">
<cfreturn false/>
</cfcatch>
</cftry>
</cfcase>
<cfdefaultcase><cfreturn true/>
<cfthrow type="custom" detail="unsupported CFS parameter value type (#arguments.dataType#)"/>
<!--- --->
</cfdefaultcase>
</cfswitch>
<!--- --->
</cffunction>
<cffunction name="checkResourceRealmAccess" returnType="void">
<!---*** В отличие от других методов, этому небезразлично имя параметра --->
<cfargument name="instanceOperationUid" type="guid"/>
<cfargument name="svcOperationCfsParamId" type="numeric"/>
<cfargument name="paramValue" type="string"/>
<cfset var local={}/>
<cfquery name="local.qSvcOperationCfsParam">
select sop.svc_operation_cfs_param_id
,sop.svc_operation_cfs_param
from svc_operation_cfs_param sop
where sop.svc_operation_cfs_param_id=<cfqueryparam cfsqltype="cf_sql_integer" value="#arguments.svcOperationCfsParamId#"/>
</cfquery>
<cfif lcase(trim(local.qSvcOperationCfsParam.svc_operation_cfs_param)) NEQ lcase("resourceRealm")>
<cfreturn/>
</cfif>
<cfquery name="local.qContract">
select c.contract_id
from instance_operation io
join instance e on (io.instance_uid=e.instance_uid)
join specification_item si on (e.specification_item_id=si.specification_item_id)
join specification s on (si.specification_id=s.specification_id)
join contract c on (s.contract_id=c.contract_id)
where io.instance_operation_uid=<cfqueryparam cfsqltype="cf_sql_other" value="#arguments.instanceOperationUid#" null=#!isValid("guid",arguments.instanceOperationUid)#/>
</cfquery>
<cfquery name="local.qCheckResourceRealmAccess">
select r.resource_realm_id, r.resource_realm, a.contract_id, a.is_enabled
from resource_realm r
join resource_realm_access a on (r.resource_realm_id=a.resource_realm_id)
where r.resource_realm = <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.paramValue#"/>
AND (a.contract_id=<cfqueryparam cfsqltype="cf_sql_integer" value=#local.qContract.contract_id# null=#!isValid("integer",local.qContract.contract_id)#/> OR a.contract_id=0)
AND a.is_enabled
</cfquery>
<cfif local.qCheckResourceRealmAccess.recordCount EQ 0>
<cfthrow message="Resource realm specified in CFS param is not available for the current contract" detail="CFS resource realm #arguments.paramValue# unawailable. Instance operation UID #arguments.instanceOperationUid#. Contract ID #local.qContract.contract_id#"/>
</cfif>
</cffunction>
</cfcomponent>