026 ceiling
This commit is contained in:
+2
-2
@@ -8,7 +8,7 @@
|
||||
<!--- Set up the application. --->
|
||||
<cfset this.Name = "PAYG-REPORT" />
|
||||
<cfset this.applicationTimeout = createTimeSpan( 0, 3, 0, 0 ) />
|
||||
<cfset this.applicationTimeout = createTimeSpan( 0, 0, 0, 10 ) />
|
||||
<cfset this.requestTimeout = createTimeSpan( 0, 0, 2, 0 )/>
|
||||
<cfset this.sessionmanagement="Yes"/>
|
||||
<cfset this.clientmanagement="No"/>
|
||||
<cfset this.sessiontimeout=CreateTimeSpan(0, 1, 0, 0)/>
|
||||
@@ -94,7 +94,7 @@
|
||||
|
||||
<!--- global settings --->
|
||||
<cfset request.RECORDS_PER_PAGE=500/>
|
||||
<cfset request.APP_VERSION="0.00.024"/>
|
||||
<cfset request.APP_VERSION="0.00.026"/>
|
||||
<cfheader name="X-Application-Version" value=#request.APP_VERSION#/>
|
||||
<cfset request.STAND=getStand()/>
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
pvdc_map(pvdc,code) as (VALUES
|
||||
('v1cl1-vsan-pvdc',''),
|
||||
('v1cl2-pvdc',''),
|
||||
('v2cl2-1c-pvdc',''),
|
||||
('v1cl4-vsan-pvdc',''),
|
||||
('v1cl6-vsan-pvdc',''),
|
||||
('v1cl7-vsan-pvdc',''),
|
||||
('hystax-pvdc',''),
|
||||
('','')
|
||||
)
|
||||
@@ -4,64 +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"
|
||||
returntype="string"
|
||||
output="false"
|
||||
hint="convert snake style name to camel style name">
|
||||
<cfargument name="snake" type="string" required="true" />
|
||||
<cfreturn #reReplace(ARGUMENTS.snake,"_([a-z])","\u\1","ALL")#/>
|
||||
</cffunction>
|
||||
|
||||
<cffunction name="camel2snake"
|
||||
returntype="string"
|
||||
output="false"
|
||||
hint="convert camel style name to snake style name">
|
||||
<cfargument name="camel" type="string" required="true" />
|
||||
<cfreturn #reReplace(ARGUMENTS.camel,"([A-Z])","_\l\1","ALL")#/>
|
||||
</cffunction>
|
||||
|
||||
|
||||
<cffunction name="iso8601dtFormat"
|
||||
returntype="string"
|
||||
output="false"
|
||||
hint="formates date and time like this: 2023-12-18T15:41:42.516+0300">
|
||||
<cfargument name="input" required="true" />
|
||||
<cfreturn "#dateFormat( input, "yyyy-mm-dd" )#T#timeFormat( input, "HH:mm:ss.lXX" )#"/>
|
||||
</cffunction>
|
||||
|
||||
|
||||
<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 --->
|
||||
<cfargument name="convertSnakeToCamel" type="boolean" default=true/>
|
||||
|
||||
<cfset var columnsIn=#arguments.qry.columnList()#/>
|
||||
<cfset var columnsOut=""/>
|
||||
|
||||
<cfif arguments.convertSnakeToCamel>
|
||||
<cfloop list=#columnsIn# item="col">
|
||||
<cfset columnsOut=listAppend(columnsOut,snake2camel(lcase(col)))/>
|
||||
</cfloop>
|
||||
|
||||
<cfset var outArray=arrayNew(1)/>
|
||||
<!--- //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)#>
|
||||
<cfset structInsert(structRow,"#listGetAt(#columnsOut#,i)#",arguments.qry["#listGetAt(#columnsIn#,i)#"])/>
|
||||
</cfloop>
|
||||
<cfset arrayAppend(outArray,structRow)/>
|
||||
</cfloop>
|
||||
<!--- <cfdump var=#outArray#/> --->
|
||||
<cfreturn outArray/>
|
||||
<cfelse>
|
||||
<cfreturn #arguments.qry.reduce((result, row) => {
|
||||
result.append(row);
|
||||
return result;
|
||||
}, [])#/>
|
||||
</cfif>
|
||||
</cffunction> --->
|
||||
|
||||
<cfscript>
|
||||
function gaussianRound(numeric number, numeric precision = 0) {
|
||||
@@ -117,7 +60,7 @@ function gaussianRound(numeric number, numeric precision = 0) {
|
||||
<!--- <cfset var accum_metric_component = 0/> --->
|
||||
|
||||
<cfset "temp.service"=["svc"="#svc#"
|
||||
,"serviceСode"="#service_code#"
|
||||
,"serviceCode"="#service_code#"
|
||||
,"serviceCustomName"="#serviceCustomName#"
|
||||
<!--- ,"note"="#(serviceHash EQ '')?'не найдено в договоре':''#" --->
|
||||
,"hash"="#serviceHash#"
|
||||
@@ -155,7 +98,7 @@ function gaussianRound(numeric number, numeric precision = 0) {
|
||||
</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 payable_metric_dimension_1 = (isNumeric(accum_metric_dimension_1))? max(ceiling(accum_metric_dimension_1) - free_tier, 0):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")/>
|
||||
|
||||
|
||||
+13
-6
@@ -186,13 +186,20 @@ from a
|
||||
join ngcloud_ru.vdc on capacity_storage.vdc_id=vdc.id
|
||||
join ngcloud_ru.tenant on tenant.id=vdc.tenant_id
|
||||
join ngcloud_ru.storage_profile_types on capacity_storage.storage_profile_types_id=storage_profile_types.id
|
||||
where tenant.wzcode = <cfqueryparam cfsqltype="cf_sql_integer" value=#ATTRIBUTES.tenant_wz_index#/>
|
||||
where tenant.wzcode = <cfqueryparam cfsqltype="cf_sql_integer" value=#ATTRIBUTES.tenant_wz_index#/> --AND 1=0
|
||||
AND capacity_storage.timestamp::date >= <cfqueryparam cfsqltype="cf_sql_timestamp" value=#attributes.dt_start#/>
|
||||
AND capacity_storage.timestamp::date <= <cfqueryparam cfsqltype="cf_sql_timestamp" value=#attributes.dt_finish#/>
|
||||
group by tenant.wzcode, vdc.name, storage_profile_types.name, capacity_storage.timestamp::date
|
||||
order by tenant.wzcode, vdc.name, storage_profile_types.name, capacity_storage.timestamp::date;
|
||||
order by tenant.wzcode, vdc.name, storage_profile_types.name, capacity_storage.timestamp::date
|
||||
;
|
||||
</cfquery>
|
||||
|
||||
<!--- create index IX_capacity_storage_sort on ngcloud_ru.capacity_storage(vdc_id,storage_profile_types_id,timestamp); --->
|
||||
<cfif (ATTRIBUTES.debug)>
|
||||
qStorage
|
||||
<cfoutput>#getTickCount() - request.startTickCount#</cfoutput>
|
||||
<cfdump var=#qStorage#/>
|
||||
<cfflush/>
|
||||
</cfif>
|
||||
|
||||
<!---
|
||||
"placement" "size_gb" "get_10k" "put_10k" "bytes_sent_gb"
|
||||
@@ -466,7 +473,7 @@ from a
|
||||
<!--- Здесь агрегировано за месяц, но детализировано по измерениям --->
|
||||
<cfquery name="qChargeMonthly" dbType="query">
|
||||
SELECT
|
||||
<d:field_set titleMapOut="titleMap" lengthOut="fieldCount">
|
||||
<d:field_set titleMapOut="chargeTitleMap" lengthOut="chargeFieldCount">
|
||||
<d:field title="Артикул по договору">s_code</d:field>
|
||||
<d:field title="Артикул по системам">m_code</d:field>
|
||||
<d:field title="Артикул">s_code as code</d:field>
|
||||
@@ -538,8 +545,8 @@ from a
|
||||
<cfset report.qSpecification = qSpecification/>
|
||||
<cfset report.qCharge = qChargeMonthly/>
|
||||
<cfset report.qFreeTier = qFreeTier/><!--- мы не применяем скидку на уровне детализации, а только после агрегации. На самом деле правильно было бы агрегировать натуральные метрики, а умножать на цену уже агрегаты --->
|
||||
<!--- <cfset report.chargeTitleMap = titleMap/>
|
||||
<cfset report.chargeFieldCount = fieldCount/> --->
|
||||
<cfset report.chargeTitleMap = chargeTitleMap/><!--- нужен для экспорта в XL --->
|
||||
<!--- <cfset report.chargeFieldCount = chargeFieldCount/> --->
|
||||
|
||||
<cfset "CALLER.#ATTRIBUTES.output#" = report/>
|
||||
|
||||
|
||||
@@ -29,7 +29,8 @@
|
||||
output="report"
|
||||
debug=#isDefined("DEBUG")#
|
||||
restrict_to_own_instances=#restrict_to_own_instances#
|
||||
/><layout:xml qRead=#report.qCharge# titleMap=#report.chargeTitleMap# filename="#pageInfo.entity#.xml"/>
|
||||
/>
|
||||
<layout:xml qRead=#report.qCharge# titleMap=#report.chargeTitleMap# filename="#pageInfo.entity#.xml"/>
|
||||
<cfabort/>
|
||||
</cfif><cfif isDefined("output_json")><cfmodule template="mod/compute_payg.cfm"
|
||||
dt_finish=#dt_finish#
|
||||
@@ -103,7 +104,7 @@ S3 операции и трафик: <b<cfif datediff("h",report.qS3OpsTrfAge.dt
|
||||
#dateFormat(report.qS3OpsTrfAge.dt_load,'YYYY-MM-DD')# #timeFormat(report.qS3OpsTrfAge.dt_load,'HH:MM:SS')#
|
||||
</b>
|
||||
<br/>
|
||||
Цены по данным договора из CRM (через elma-cache). Учитываются метрики по S3, vCloud (кроме GPU)
|
||||
Цены по данным договора из CRM (через elma-cache). Учитываются метрики по S3, vCloud (кроме GPU). Внимание! количество за период *** округляется вверх, но делается это после всех агрегаций.
|
||||
<br/>
|
||||
|
||||
|
||||
@@ -209,7 +210,7 @@ S3 операции и трафик: <b<cfif datediff("h",report.qS3OpsTrfAge.dt
|
||||
<td colspan="4">Итого #code# <cfif code EQ "">(#m_code#)</cfif>:</td>
|
||||
<td class="r"><cfif accum_metric_dimension_1 NEQ 0 AND isNumeric(accum_metric_dimension_1)>#round(accum_metric_dimension_1,3)#</cfif></td>
|
||||
<td class="r">#free_tier#</td>
|
||||
<td class="r" style="font-size:120%; padding:0 1em;"><cfif accum_metric_dimension_1 NEQ 0 AND isNumeric(accum_metric_dimension_1)>#round(max(accum_metric_dimension_1 - free_tier, 0),3)#</cfif></td>
|
||||
<td class="r" style="font-size:120%; padding:0 1em;"><cfif accum_metric_dimension_1 NEQ 0 AND isNumeric(accum_metric_dimension_1)>#max(ceiling(accum_metric_dimension_1) - free_tier, 0)#</cfif></td>
|
||||
<td class="c">#unit#</td>
|
||||
<td class="r">#gaussianRound(discounted_price,2)#</td><!--- если цена менялась в периоде, неправильно показыввать последнюю - но мы не тестировали с изменением в периоде --->
|
||||
<!--- непонятно, как вычитать Free Tier для неполных месяцев. Если с 15 по 15 - вычитать 2 раза, вычитать (каким-то сложным образом) 1 раз или ни разу --->
|
||||
|
||||
Reference in New Issue
Block a user