224 subparam compute fix

This commit is contained in:
2026-04-02 12:38:30 +03:00
parent b42aa109f0
commit 9409b2cd74
5 changed files with 62 additions and 57 deletions
+1 -1
View File
@@ -57,7 +57,7 @@
//variables.framework.docs={}; //variables.framework.docs={};
variables.framework.docs.APIName="svc-api"; variables.framework.docs.APIName="svc-api";
variables.framework.docs.APIVersion="0.223"; /*$ git config --global --unset user.password*/ variables.framework.docs.APIVersion="0.224"; /*$ git config --global --unset user.password*/
variables.framework.globalHeaders = structNew(); variables.framework.globalHeaders = structNew();
variables.framework.globalHeaders["Access-Control-Expose-Headers"] = "Location"; variables.framework.globalHeaders["Access-Control-Expose-Headers"] = "Location";
+10 -2
View File
@@ -260,13 +260,20 @@ arguments.requestArguments.specificationId=usrCustomerInfo.specificationId; //In
<!--- Секретность игнорируется. Все секреты доступны, как есть ---> <!--- Секретность игнорируется. Все секреты доступны, как есть --->
<!--- правда, мы тут можем работать только с сохраненными параметрами. Можем попробовать полагаться на правило: зависимые параметры всегда позже (не факт, что это получится при конкурентном сохранении) ---> <!--- правда, мы тут можем работать только с сохраненными параметрами. Можем попробовать полагаться на правило: зависимые параметры всегда позже (не факт, что это получится при конкурентном сохранении) --->
<!--- проблема: нам нужен тут instance_operation_uid, но таскать его в аргументах по всей цепочке вызовов неудобно. Если бы это у нас был метод CFS параметра, все было бы просто - это у нас поле параметра ---> <!--- проблема: нам нужен тут instance_operation_uid, но таскать его в аргументах по всей цепочке вызовов неудобно. Если бы это у нас был метод CFS параметра, все было бы просто - это у нас поле параметра --->
<!--- ошибка: в строке параметров у нас ключ param.subparam, а в аргументах он разобран по частям
при этом мы ожидаем в параметрах структуру paramName:{subparamName:subparamValue}
но почему не находим в сохраненных? возможно такое совпадение, что в сценарии у нас как раз надо выбрать svcId а они не --->
<!--- {"startupConfiguration":{"vdcUid":"ea81db31-2197-407d-b32b-e60577c2671c"}} --->
<!--- this.params <cfdump var=#this.params#/>
arguments <cfdump var=#arguments# /> --->
<cfif structKeyExists(this.params,arguments.param)><!--- AND len(this.params[arguments.param]) ---> <cfif structKeyExists(this.params,arguments.param)><!--- AND len(this.params[arguments.param]) --->
<cfif structKeyExists(arguments,"subparam")><!--- *** не изящно, но просто и понятно ---> <cfif structKeyExists(arguments,"subparam")><!--- *** не изящно, но просто и понятно --->
<cfreturn deserializeJson(this.params[arguments.param])[arguments.subparam]/> <cfreturn (this.params[arguments.param])[arguments.subparam]/>
<cfelse> <cfelse>this.params[arguments.param] <!--- <cfdump var=#this.params[arguments.param]#/> --->
<cfreturn this.params[arguments.param]/> <cfreturn this.params[arguments.param]/>
</cfif> </cfif>
</cfif> </cfif>
<!--- не нашли параметра в запросе, ищем в сохраненных --->
<cfquery name="local.qCfsParam"> <cfquery name="local.qCfsParam">
select p.param_value select p.param_value
from instance_operation_cfs_param p from instance_operation_cfs_param p
@@ -274,6 +281,7 @@ arguments.requestArguments.specificationId=usrCustomerInfo.specificationId; //In
where p.instance_operation_uid = <cfqueryparam cfsqltype="cf_sql_other" value=#this.instance_operation_uid# null=#!isValid('guid',this.instance_operation_uid)#/> where p.instance_operation_uid = <cfqueryparam cfsqltype="cf_sql_other" value=#this.instance_operation_uid# null=#!isValid('guid',this.instance_operation_uid)#/>
AND s.svc_operation_cfs_param = <cfqueryparam cfsqltype="cf_sql_varchar" value=#arguments.param#/> AND s.svc_operation_cfs_param = <cfqueryparam cfsqltype="cf_sql_varchar" value=#arguments.param#/>
</cfquery> </cfquery>
<!--- <cfdump var=#this.keys#/> --->
<cfif structKeyExists(arguments,"subparam")><!--- *** не изящно, но просто и понятно ---> <cfif structKeyExists(arguments,"subparam")><!--- *** не изящно, но просто и понятно --->
<cfset var value = deserializeJson(local.qCfsParam.param_value)/> <cfset var value = deserializeJson(local.qCfsParam.param_value)/>
<cfif isStruct(value) AND structKeyExists(value, arguments.subparam)> <cfif isStruct(value) AND structKeyExists(value, arguments.subparam)>
+35 -37
View File
@@ -187,45 +187,42 @@
order by sp.sort order by sp.sort
</cfquery> </cfquery>
<cfif len(local.qSubparam.func)><!--- приоритет отдается функции перед списком значений--->
<cfset var args = {
"functionName":"#local.qSubparam.func#",
"svcId":#local.qSvcOperation.svc_id#,
"contractId":#arguments.contractId#
}/>
<cfinvoke component="instance_operation_cfs_param" method="generateValueList" argumentCollection=#args# returnVariable="local.qSubparam.value_list"/>
<cfif len(trim(local.qSubparam.value_list)) AND listLen(local.qSubparam.value_list) EQ 1>
<cfset local.qSubparam.default_value=local.qSubparam.value_list/><!--- *** не очень красиво перетирать query, но делаем это довольно часто --->
</cfif>
<!--- <cfelseif len(local.qSubparam.nested_ref)>
<cfset var args = {
"functionName":"#local.qSubparam.nested_ref#",
"config":"#local.qSubparam.config#"
}/>
<cfinvoke component="instance_operation_cfs_param" method="generateClosure" argumentCollection=#args# returnVariable="local.fNestedRef"/>
<cfset local.qSubparam.nested_ref_data = local.fNestedRef() /> --->
<!--- <cfelseif len(local.qSubparam.state_path) AND isStruct(currentState)>
<cfset var args = {
"state":#currentState#,
"path":"#local.qSubparam.state_path#"
}/>
<cfinvoke component="instance_operation_cfs_param"
method="getListFromState"
argumentCollection=#args#
returnVariable="local.qSubparam.value_list"
/> --->
</cfif>
<cfif (len(local.qSubparam.func) OR len(local.qSubparam.expression) <!--- OR len(local.qSubparam.state_path) OR len(local.qSubparam.nested_ref)---> )
AND len(local.qSubparam.value_list) EQ 0>
<cfset local.qSubparam.value_list = []/>
</cfif>
<cfset var mapDescriptor=structNew("linked")/> <cfset var mapDescriptor=structNew("linked")/>
<!--- *** выдавать на фронт expression нам ни к чему, это временное явление ---> <!--- *** выдавать на фронт expression нам ни к чему, это временное явление --->
<cfloop query="local.qSubparam"> <cfloop query="local.qSubparam">
<cfif len(local.qSubparam.func)><!--- приоритет отдается функции перед списком значений--->
<cfset var args = {
"functionName":"#local.qSubparam.func#",
"svcId":#local.qSvcOperation.svc_id#,
"contractId":#arguments.contractId#
}/>
<cfinvoke component="instance_operation_cfs_param" method="generateValueList" argumentCollection=#args# returnVariable="local.qSubparam.value_list"/>
<cfif len(trim(local.qSubparam.value_list)) AND listLen(local.qSubparam.value_list) EQ 1>
<cfset local.qSubparam.default_value=local.qSubparam.value_list/><!--- *** не очень красиво перетирать query, но делаем это довольно часто --->
</cfif>
</cfif>
<cfif (len(local.qSubparam.func) OR len(local.qSubparam.expression) )
AND len(local.qSubparam.value_list) EQ 0>
<cfset local.qSubparam.value_list = []/>
</cfif>
<cfset var def = computeDefault(local.qSubparam.default_compute, local.qSubparam.default_value, qSvcOperation.svc_id, arguments.usrId)/>
<!--- *** пока не пытаемся восстановить значения из стейта
<cfif len(local.qSubparam.default_value) EQ 0>
<!--- и вот наконец мы извлекаем старое значение из стейта --->
<cfset var paramName = this.helper.snake2camel(local.qSubparam.svc_operation_cfs_subparam)/>
<cfif structKeyExists(local.instanceDataParams, paramName)>
<cfset var oldValue = structFind(local.instanceDataParams, paramName)/>
<cfset def = isStruct(oldValue) ? serializeJson(oldValue) : oldValue/> <!--- потому что передаем строку, а не объект --->
</cfif>
</cfif> --->
<cfset structInsert(mapDescriptor, local.qSubparam.svc_operation_cfs_subparam, <cfset structInsert(mapDescriptor, local.qSubparam.svc_operation_cfs_subparam,
{ {
"svcOperationCfsSubparamId":"#local.qSubparam.svc_operation_cfs_subparam_id#", "svcOperationCfsSubparamId":"#local.qSubparam.svc_operation_cfs_subparam_id#",
@@ -240,7 +237,7 @@
"regex":"#local.qSubparam.regex#", "regex":"#local.qSubparam.regex#",
"man":"#local.qSubparam.man#", "man":"#local.qSubparam.man#",
"descr":"#local.qSubparam.descr#", "descr":"#local.qSubparam.descr#",
"defaultValue":"#local.qSubparam.default_value#", "defaultValue":"#def#",
"isRequired":#request.castToBool(local.qSubparam.is_required)#, "isRequired":#request.castToBool(local.qSubparam.is_required)#,
"isSensitive":#request.castToBool(local.qSubparam.is_sensitive)#, "isSensitive":#request.castToBool(local.qSubparam.is_sensitive)#,
"refSvcId":#local.qSubparam.ref_svc_id#, "refSvcId":#local.qSubparam.ref_svc_id#,
@@ -250,8 +247,9 @@
"isModifiableDefinition":false "isModifiableDefinition":false
}, true }, true
) )
/> /><!--- *** вообще-то передавать в дескриптор func и default_compute не нужно, это для не забыть --->
</cfloop> <!--- *** вообще-то передавать в дескриптор func и default_compute не нужно, это для не забыть --->
</cfloop>
<cfset local.qCfsParam.data_descriptor = mapDescriptor/> <cfset local.qCfsParam.data_descriptor = mapDescriptor/>
</cfif><!---/map ---> </cfif><!---/map --->
@@ -31,7 +31,6 @@ arguments.requestArguments.specificationId=usrCustomerInfo.specificationId; //In
<!--- Вероятно, нам не очень нужно вычислять набор значений для инстанса параметра, мы всегда знаем класс ---> <!--- Вероятно, нам не очень нужно вычислять набор значений для инстанса параметра, мы всегда знаем класс --->
<!--- контест: ---> <!--- контест: --->
<cfargument name="svcOperationCfsParamId" type="string" required=true hint="type:integer"/> <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="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"/> <cfargument name="params" type="string" default="{}" hint="type:json any parameters we depend on"/>
@@ -53,7 +52,7 @@ arguments.requestArguments.specificationId=usrCustomerInfo.specificationId; //In
<cfset local.keys.svcOperationCfsParamId=arguments.svcOperationCfsParamId/><!--- дополняем ---> <cfset local.keys.svcOperationCfsParamId=arguments.svcOperationCfsParamId/><!--- дополняем --->
<cfset local.params = deserializeJson(arguments.params)/> <cfset local.params = deserializeJson(arguments.params)/>
<cfset local.keys.svcOperationCfsParamId = arguments.svcOperationCfsParamId/> <!--- *** сомнительное дело гонять аргументы туда-сюда ---> <!--- <cfset local.keys.svcOperationCfsParamId = arguments.svcOperationCfsParamId/> ---> <!--- *** сомнительное дело гонять аргументы туда-сюда --->
<!--- Нам нужен либо класс и параметры, либо инстанс с сохраненными параметрами (при этом в контексте параметры имеют приоритет перед сохраненными, но если их нет - хватит нам и сохраненных) ---> <!--- Нам нужен либо класс и параметры, либо инстанс с сохраненными параметрами (при этом в контексте параметры имеют приоритет перед сохраненными, но если их нет - хватит нам и сохраненных) --->
@@ -30,11 +30,10 @@ arguments.requestArguments.specificationId=usrCustomerInfo.specificationId; //In
<!--- *** Важно: мы должны уметь посчитать параметр, если он не сохранен, то есть мы знаем его класс, а не инстанс ---> <!--- *** Важно: мы должны уметь посчитать параметр, если он не сохранен, то есть мы знаем его класс, а не инстанс --->
<!--- Вероятно, нам не очень нужно вычислять набор значений для инстанса параметра, мы всегда знаем класс ---> <!--- Вероятно, нам не очень нужно вычислять набор значений для инстанса параметра, мы всегда знаем класс --->
<!--- контест: ---> <!--- контест: --->
<cfargument name="svcOperationCfsSubparamId" type="string" required=false hint="type:integer"/> <cfargument name="svcOperationCfsSubparamId" type="string" required=true 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="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 posted parameters we depend on"/> <cfargument name="params" type="string" default="{}" hint="type:json any posted parameters we depend on"/>
<cftry> <cftry>
<cfset this.helper.validateField(arguments, "svcOperationCfsSubparamId", "integer")/> <cfset this.helper.validateField(arguments, "svcOperationCfsSubparamId", "integer")/>
<cfset this.helper.validateField(arguments, "keys", "json")/> <!--- *** может, не лучшая идея передавать ключ в контексте ---> <cfset this.helper.validateField(arguments, "keys", "json")/> <!--- *** может, не лучшая идея передавать ключ в контексте --->
@@ -45,12 +44,12 @@ arguments.requestArguments.specificationId=usrCustomerInfo.specificationId; //In
</cftry> </cftry>
<cfset local={}/> <cfset local={}/>
<cfset local.expression = ""/> <!--- нет смысла выносить это в поля класса, оно нужно только локально ---> <cfset "local.expression" = ""/> <!--- нет смысла выносить это в поля класса, оно нужно только локально --->
<cfset local.calculatedValueList = ""/> <cfset "local.calculatedValueList" = ""/>
<cfset local.keys = deserializeJson(arguments.keys)/> <cfset "local.keys" = deserializeJson(arguments.keys)/>
<cfset local.params = deserializeJson(arguments.params)/> <cfset "local.params" = deserializeJson(arguments.params)/>
<cfset local.keys.svcOperationCfsSubparamId = arguments.svcOperationCfsSubparamId/> <!--- *** сомнительное дело гонять аргументы туда-сюда ---><!--- *** по-моему, не используется, поэтому достанем svcOperationCfsParamId прямо тут ---> <cfset "local.keys.svcOperationCfsSubparamId" = arguments.svcOperationCfsSubparamId/> <!--- *** сомнительное дело гонять аргументы туда-сюда ---><!--- *** по-моему, не используется, поэтому достанем svcOperationCfsParamId прямо тут --->
<cfquery name="local.qCfsSubparam" result="local.result"> <cfquery name="local.qCfsSubparam" result="local.result">
select select
@@ -69,12 +68,12 @@ arguments.requestArguments.specificationId=usrCustomerInfo.specificationId; //In
<cfreturn representationOf(this.helper.formatMessage("Service Operation CFS Parameter Not Found")).withStatus(404)/> <cfreturn representationOf(this.helper.formatMessage("Service Operation CFS Parameter Not Found")).withStatus(404)/>
</cfif> </cfif>
<cfset local.expression=local.qCfsSubparam.expression/> <cfset "local.expression"=local.qCfsSubparam.expression/>
<cfset local.keys.svcOperationCfsParamId = local.qCfsSubparam.svc_operation_cfs_param_id/> <cfset "local.keys.svcOperationCfsParamId" = local.qCfsSubparam.svc_operation_cfs_param_id/>
<!--- *** можно обратить внимание, что мы инстанциируем не субпараметр, а параметр (цинично пользуясь их функциональной идентичностью... но некрасиво) ---> <!--- *** можно обратить внимание, что мы инстанциируем не субпараметр, а параметр (цинично пользуясь их функциональной идентичностью... но некрасиво) --->
<cfif len(local.expression)> <cfif len(local.expression)>
<cfset calculatedValueList=createObject("component","lib.expression_parser") <cfset local.calculatedValueList=createObject("component","lib.expression_parser")
.eval( .eval(
local.expression, local.expression,
{/*context*/ {/*context*/
@@ -87,7 +86,9 @@ arguments.requestArguments.specificationId=usrCustomerInfo.specificationId; //In
<cfelse> <cfelse>
<cfreturn representationOf(this.helper.formatMessage("Expression Not Found")).withStatus(404)/> <cfreturn representationOf(this.helper.formatMessage("Expression Not Found")).withStatus(404)/>
</cfif> </cfif>
<!--- <cfdump var=#local.keys#/>
<cfdump var=#local.params#/>
<cfdump var=#local.calculatedValueList# abort=true/> --->
<!--- Тут нам еще придется сформатировать лист в массив. Но обошлось довольно просто ---> <!--- Тут нам еще придется сформатировать лист в массив. Но обошлось довольно просто --->
<cfset var out=structNew("linked")/> <cfset var out=structNew("linked")/>
<cfset "out.queryDurationMs"=getTickCount() - request.startTickCount/> <cfset "out.queryDurationMs"=getTickCount() - request.startTickCount/>
@@ -96,5 +97,4 @@ arguments.requestArguments.specificationId=usrCustomerInfo.specificationId; //In
<cfreturn representationOf(out) /> <cfreturn representationOf(out) />
</cffunction><!--- get ---> </cffunction><!--- get --->
</cfcomponent> </cfcomponent>