Files
svc-api-x/v1/resources/svc_operation_cfs_param_compute.cfc
T
2026-02-12 11:30:19 +03:00

156 lines
11 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="/svcOperationCfsParams/compute/{svcOperationCfsParamId}" hint="вычисляет выражение в поле expression">
<!---
вычисляет выражение в поле expression
для этого нужен контекст - как минимум, сохраненные параметры, но это не работает при создании нового инстанса,
поэтому нужно инициализировать контекст и набивать его всей необходимой информацией
что особенно важно для зависимых параметров - нам нужно положить в контекст все параметры, от которых мы зависим
чтобы знать, какие параметры передавать - конструкцией предусмотрено поле depends_on_params
--->
<!--- Все методы неявно получают
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>
<cffunction name="get" hint="вычисление возможных значений CFS параметра операции инстанса, в текущем контексте. Рекомендуется передавать keys.svcOperationCfsParamId для декларации класса параметра (а не keys.instanceOperationCfsParamUid) - он неизвестен для вновь создаваемых параметров">
<!--- <cfargument name="instanceOperationCfsParamUid" type="string" required=true hint="type:guid"/> а вот ни фига--->
<!--- *** Важно: мы должны уметь посчитать параметр, если он не сохранен, то есть мы знаем его класс, а не инстанс --->
<!--- Вероятно, нам не очень нужно вычислять набор значений для инстанса параметра, мы всегда знаем класс --->
<!--- контест: --->
<cfargument name="svcOperationCfsParamId" type="string" required=true hint="type:integer"/>
<!--- <cfargument name="svcOperationCfsSubparamId" type="string" required=false hint="type:integer"/> --->
<cfargument name="keys" type="string" default={} hint="type:json keys we depend on: of the param uid itself, or operation uid, instance uid, service operation cfs param - if not all entities intstantiated yet"/>
<cfargument name="params" type="string" default="{}" hint="type:json any parameters we depend on"/>
<cftry>
<cfset this.helper.validateField(arguments, "svcOperationCfsParamId", "integer")/>
<!--- <cfset this.helper.validateField(arguments, "svcOperationCfsSubparamId", "integer", false)/> --->
<cfset this.helper.validateField(arguments, "keys", "json")/> <!--- *** может, не лучшая идея передавать ключ в контексте --->
<cfset this.helper.validateField(arguments, "params", "json")/>
<cfcatch type="invalidParamValue">
<cfreturn representationOf(this.helper.formatBadRequestError(cfcatch)).withStatus(400)/>
</cfcatch>
</cftry>
<cfset local={}/>
<cfset local.expression = ""/> <!--- нет смысла выносить это в поля класса, оно нужно только локально --->
<cfset local.calculatedValueList = ""/>
<cfset local.keys = deserializeJson(arguments.keys)/>
<cfset local.keys.svcOperationCfsParamId=arguments.svcOperationCfsParamId/><!--- дополняем --->
<cfset local.params = deserializeJson(arguments.params)/>
<cfset local.keys.svcOperationCfsParamId = arguments.svcOperationCfsParamId/> <!--- *** сомнительное дело гонять аргументы туда-сюда --->
<!--- Нам нужен либо класс и параметры, либо инстанс с сохраненными параметрами (при этом в контексте параметры имеют приоритет перед сохраненными, но если их нет - хватит нам и сохраненных) --->
<!--- нам нужно выражение. чтобы его достать, нужно знать параметр или класс параметра --->
<!--- для получения resourceRealm нужен параметр,операция,инстанс или сам resourceRealm --->
<!--- <cfif structKeyExists(local.keys,"instanceOperationCfsParamUid") AND isValid("guid",local.keys.instanceOperationCfsParamUid)>
<cfquery name="local.qCfsParam" result="local.result">
select
<m:field_set titleMapOut="local.titleMap" lengthOut="fieldCount">
<m:field>iop.instance_operation_cfs_param_uid::text as instance_operation_cfs_param_uid</m:field>
<m:field>iop.instance_operation_uid::text as instance_operation_uid</m:field>
<m:field>iop.svc_operation_cfs_param_id</m:field>
<m:field>sop.data_type</m:field>
<m:field>sop.svc_operation_cfs_param</m:field>
<m:field>sop.expression</m:field>
</m:field_set>
from instance_operation_cfs_param iop
join svc_operation_cfs_param sop on (iop.svc_operation_cfs_param_id=sop.svc_operation_cfs_param_id)
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)
left outer join usr u on (iop.creator_id=u.usr_id)
where iop.instance_operation_cfs_param_uid=<cfqueryparam cfsqltype="cf_sql_other" value="#local.keys.instanceOperationCfsParamUid#" null=#!isValid('guid',local.keys.instanceOperationCfsParamUid)#/>
AND si.specification_id=<cfqueryparam cfsqltype="cf_sql_integer" value=#arguments.specificationId#/>
</cfquery>
<cfif local.qCfsParam.recordCount EQ 0>
<cfreturn representationOf(this.helper.formatMessage("CFS Parameter Not Found Or Not Accessible")).withStatus(404)/>
</cfif>
<cfset local.expression=local.qCfsParam.expression/>
<cfelseif structKeyExists(local.keys,"svcOperationCfsParamId") AND isValid("integer",local.keys.svcOperationCfsParamId)> --->
<cfquery name="local.qCfsParam" result="local.result">
select
<m:field_set titleMapOut="local.titleMap" lengthOut="fieldCount">
<m:field>sop.data_type</m:field>
<m:field>sop.svc_operation_cfs_param</m:field>
<m:field>sop.expression</m:field>
</m:field_set>
from svc_operation_cfs_param sop
where sop.svc_operation_cfs_param_id
= <cfqueryparam cfsqltype="cf_sql_integer" value=#arguments.svcOperationCfsParamId# null=#!isValid('integer',arguments.svcOperationCfsParamId)#/>
</cfquery>
<cfif local.qCfsParam.recordCount EQ 0>
<cfreturn representationOf(this.helper.formatMessage("Service Operation CFS Parameter Not Found")).withStatus(404)/>
</cfif>
<cfset local.expression=local.qCfsParam.expression/>
<!--- <cfelse>
<cfreturn representationOf(this.helper.formatMessage("CFS parameter class undefined")).withStatus(400)/>
</cfif> --->
<!--- параметра у нас может еще не быть! по минимуму нужен его класс
инициализация построена так, чтобы вытащить ту информацию, которую получается, на основании известных ключей и параметров --->
<!--- но тут мы перехитрили сами себя. нам для вызова парсера нужно выражение.
а получать выражение, зная _некоторый_ набор ключей, умеет как раз компонент, который инстанциируется в методе expression_parser.eval
Получается, инстанциировать его надо снаружи
Таким образом, контекст должен состоять просто из компонента-параметра, инстанциированного в полном фарше, а у нас он пока состоит из набора "собери компонент сам"
Конечно, мы можем сейчас сдублировать тут код инициализации параметра, но криво же
или логика не такая, и нет дублирования?
--->
<!--- минуточку, а как мы управляемся с субпараметром? инстанциируем тот же параметр? Это означает, что класс занимается не своим делом *** --->
<cfif len(local.expression)>
<cfset calculatedValueList=createObject("component","lib.expression_parser")
.eval(
local.expression,
{/*context*/
component:"resources.instance_operation_cfs_param",
keys:#local.keys#,
params:#local.params#
}
)
/>
<cfelse>
<cfreturn representationOf(this.helper.formatMessage("Expression Not Found")).withStatus(404)/>
</cfif>
<!--- Тут нам еще придется сформатировать лист в массив. Но обошлось довольно просто --->
<cfset var out=structNew("linked")/>
<cfset "out.queryDurationMs"=getTickCount() - request.startTickCount/>
<cfset "out.values" = listToArray(local.calculatedValueList)/>
<cfset "out.runDurationMs"=getTickCount() - request.startTickCount/>
<cfreturn representationOf(out) />
</cffunction><!--- get --->
</cfcomponent>
<!---
sample urls
/svcOperationCfsParams/compute/335?keys={instanceOperationCfsParamUid="227a5758a7-95f1-44c7-a648-32ac7ec31228"}
/svcOperationCfsParams/compute/335?keys={instanceOperationCfsParamUid="5bcf3ef6-0af3-4bd0-a086-98c54f9b25f7"}
/svcOperationCfsParams/compute/335?params={organizationUid="e5a1e03f-f366-4d58-958d-97669132ba9a"}&keys={instanceUid="9fc0fc70-9075-41e1-b163-ee1adbc3e023"}
/svcOperationCfsParams/compute/335?params={organizationUid="e5a1e03f-f366-4d58-958d-97669132ba9a"}&keys={instanceUid="9fc0fc70-9075-41e1-b163-ee1adbc3e023"}
/svcOperationCfsParams/compute/335?params={organizationUid="e5a1e03f-f366-4d58-958d-97669132ba9a"} --->