021 dimensions dimension1

This commit is contained in:
2026-07-20 11:06:58 +03:00
parent 90aa268918
commit 3bc7cea1d1
16 changed files with 2121 additions and 185 deletions
+115 -28
View File
@@ -4,7 +4,7 @@
<cfset hours=dateDiff('h',dt_start,dt_finish)/>
<cfset tenant_wz_index=val(mid(request.auth.wz,3,5))/><!--- cut off WZ --->
<cffunction name="snake2camel"
<!--- <cffunction name="snake2camel"
returntype="string"
output="false"
hint="convert snake style name to camel style name">
@@ -30,7 +30,7 @@
</cffunction>
<cffunction name="query2json"
<cffunction name="query2array"
output="false"
hint="print query in json format as array of structures">
<cfargument name="qry" type="query" required="true"/><!--- column names should not contain commas --->
@@ -41,11 +41,11 @@
<cfif arguments.convertSnakeToCamel>
<cfloop list=#columnsIn# item="col">
<cfset columnsOut=listAppend(columnsOut,snake2camel(col))/>
<cfset columnsOut=listAppend(columnsOut,snake2camel(lcase(col)))/>
</cfloop>
<cfset var outArray=arrayNew(1)/>
//copy fields to structure, renaming fields, this preserves data type
<!--- //copy fields to structure, renaming fields, this preserves data type --->
<cfloop query=#arguments.qry#>
<cfset var structRow=structNew()/>
<cfloop index="i" from="1" to=#listLen(columnsOut)#>
@@ -53,42 +53,129 @@
</cfloop>
<cfset arrayAppend(outArray,structRow)/>
</cfloop>
<cfreturn serializeJSON(outArray)/>
<!--- <cfdump var=#outArray#/> --->
<cfreturn outArray/>
<cfelse>
<cfreturn serializeJSON(arguments.qry,"struct")/>
<cfreturn #arguments.qry.reduce((result, row) => {
result.append(row);
return result;
}, [])#/>
</cfif>
</cffunction>
</cffunction> --->
<cfscript>
function gaussianRound(numeric number, numeric precision = 0) {
var factor = 10 ^ precision;
var scaledNumber = number * factor;
var absScaled = abs(scaledNumber);
var sign = sgn(scaledNumber);
var floored = int(absScaled);
// If it's not ending in exactly .5, use standard rounding or precision scaling
if (absScaled - floored != 0.5) {
return round(number * factor) / factor;
}
// If it is exactly .5, round towards the nearest even number
if (floored % 2 != 0) {
// Nearest even is UP
return (floored + 1) * sign / factor;
} else {
// Nearest even is DOWN
return floored * sign / factor;
}
}
</cfscript>
<cfmodule template="mod/payg.cfm"
<cfmodule template="mod/compute_payg.cfm"
dt_finish=#dt_finish#
dt_start=#dt_start#
tenant_wz_index=#tenant_wz_index#
output="report"
debug=#isDefined("DEBUG")#
/>
<cfset out={
"appVersion"=#request.APP_VERSION#,
"hours"=#hours#,
"dtStart="=#iso8601dtFormat(dt_start)#,
"dtFinish"=#iso8601dtFormat(dt_finish)#,
"vcdComputingLoadedAt"="#iso8601dtFormat(report.qComputingAge.dt_load)#",
"vcdStorageLoadedAt"="#iso8601dtFormat(report.qStorageAge.dt_load)#",
"s3StorageLoadedAt"="#iso8601dtFormat(report.qComputingAge.dt_load)#",
"s3OpsTrfLoadedAt"="#iso8601dtFormat(report.qS3OpsTrfAge.dt_load)#",
"records"=#report.qCharge.recordCount#,
"queryDurationMs"=#(getTickCount() - msStartAt)#,
"wz"=#request.auth.wz#,
"login"=#request.auth.login#,
"report"=#report.qCharge.reduce((result, row) => {
result.append(row);
return result;
}, [])#
}/>
<cfset temp.out=["dtStart"="#dateFormat(dt_start, "yyyy-mm-dd")#"
,"dtFinish"="#dateFormat(dt_finish, "yyyy-mm-dd")#"
,"hours"=#hours#
,"tenantWzIndex"="#tenant_wz_index#"
,"periods"=[]
]/><!--- using [] instead of {} for struct literals to obtain linked (ordered) structures: keys order preserved --->
<!--- beware nulls --->
<cfoutput query="report.qCharge" group="year">
<cfoutput group="month">
<cfset temp.period=[
"year"=#year#
,"month"=#month#
,"services"=[]
]/>
<cfset arrayAppend(temp.out.periods,temp.period)/>
<cfoutput group="svc">
<cfset var accum_cost_svc = 0/>
<!--- <cfset var accum_metric_component = 0/> --->
<cfset "temp.service"=["svc"="#svc#"
,"serviceСode"="#service_code#"
,"serviceCustomName"="#serviceCustomName#"
<!--- ,"note"="#(serviceHash EQ '')?'не найдено в договоре':''#" --->
,"hash"="#serviceHash#"
<!--- ,"metric"=#accum_metric_component# --->
,"components"=[]
]/>
<cfoutput group="code">
<cfoutput group="serviceStart">
<!--- <cfset accum_metric_component += isNumeric(metric) ? metric : 0/> --->
<cfset accum_metric_dimension_1 = 0/>
<cfset "temp.component"=["code"="#code#"
,"codeMetered"="#m_code#"
,"component"="#component#"
,"unit"="#unit#"
,"freeTier"="#free_tier#"
,"price"="#gaussianRound(discounted_price,2)#"
,"details"=[]
]/>
<cfoutput group="dimension_1">
<cfset accum_metric_dimension_1 += isNumeric(metric) ? metric : 0/>
<cfset temp.dimension=["dimension1name"="#dimension_1_name#"
,"dimension1value"="#dimension_1#"
,"dtBilledFrom"="#dateFormat(dt_billed_from,'YYYY-MM-DD')#"
,"dtBilledTo"="#dateFormat(dt_billed_to,'YYYY-MM-DD')#"
,"metric"=#(metric NEQ 0 AND isNumeric(metric))?round(metric,3):javaCast("null",0)#
,"unit"="#unit#"
<!--- ,"price"="#gaussianRound(discounted_price,2)#" --->
]/>
<cfset arrayAppend(temp.component.details, temp.dimension)/>
</cfoutput><!--- dimension_1 --->
<!--- считаем, что free_tier NOT NULL (вместо NULL 0) --->
<cfset var payable_metric_dimension_1 = (isNumeric(accum_metric_dimension_1))? round(max(accum_metric_dimension_1 - free_tier, 0),3):javaCast("null",0)/>
<cfset var cost_dimension_1 = precisionEvaluate("gaussianRound(payable_metric_dimension_1*gaussianRound(discounted_price, 2), 2)")/>
<cfset accum_cost_svc = precisionEvaluate("accum_cost_svc + cost_dimension_1")/>
<cfset "temp.component.metric"=#(accum_metric_dimension_1 NEQ 0 AND isNumeric(accum_metric_dimension_1))? round(accum_metric_dimension_1,3):javaCast("null",0)#/>
<cfset "temp.component.metricPayable"=#payable_metric_dimension_1#/>
<cfset "temp.component.cost"=#cost_dimension_1#/>
<cfset arrayAppend(temp.service.components, temp.component)/>
</cfoutput><!--- serviceStart (component version in specification, that is svc version joined down to the component) --->
<cfset "temp.service.cost"=#accum_cost_svc#/>
</cfoutput><!--- code (component) --->
<cfset arrayAppend(temp.period.services, temp.service)/>
</cfoutput><!--- svc --->
</cfoutput><!--- month --->
</cfoutput><!--- year --->
<cfset "temp.out.durationMs"=(getTickCount()-request.startTickCount)/>
<cfcontent
type="application/json"
/><cfoutput>#serializeJSON(out)#</cfoutput>
/><cfoutput>#serializeJSON(temp.out)#</cfoutput>