010 json report
This commit is contained in:
+1
-2
@@ -23,7 +23,6 @@
|
|||||||
<cfset this.idpCertUrl = "https://keycloak.nubes.ru/realms/cloud/protocol/openid-connect/certs" />
|
<cfset this.idpCertUrl = "https://keycloak.nubes.ru/realms/cloud/protocol/openid-connect/certs" />
|
||||||
<cfset this.client_secret = createObject("java", "java.lang.System").getEnv("IDP_CLIENT_SECRET")/>
|
<cfset this.client_secret = createObject("java", "java.lang.System").getEnv("IDP_CLIENT_SECRET")/>
|
||||||
|
|
||||||
|
|
||||||
<cfset this.datasource = "rpt"/>
|
<cfset this.datasource = "rpt"/>
|
||||||
<cfset this.defaultdatasource = this.datasource/>
|
<cfset this.defaultdatasource = this.datasource/>
|
||||||
<cfset request.DS = "#this.datasource#">
|
<cfset request.DS = "#this.datasource#">
|
||||||
@@ -78,7 +77,7 @@
|
|||||||
|
|
||||||
<!--- global settings --->
|
<!--- global settings --->
|
||||||
<cfset request.RECORDS_PER_PAGE=500/>
|
<cfset request.RECORDS_PER_PAGE=500/>
|
||||||
<cfset request.APP_VERSION="0.00.009"/>
|
<cfset request.APP_VERSION="0.00.010"/>
|
||||||
<cfset request.STAND=getStand()/>
|
<cfset request.STAND=getStand()/>
|
||||||
|
|
||||||
<!--- application constants --->
|
<!--- application constants --->
|
||||||
|
|||||||
+4
-4
@@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"ds_rpt_class": "org.postgresql.Driver",
|
"ds_rpt_class": "org.postgresql.Driver",
|
||||||
"ds_rpt_connectionString": "jdbc:postgresql://db-services.adl.nubes.ru:5432/dwh",
|
"ds_rpt_connectionString": "jdbc:postgresql://write.09d78921-77a7-401a-b2cb-5ca11be850a0.services.ngcloud.ru:5432/rpt",
|
||||||
"ds_rpt_username": "smishchuk",
|
"ds_rpt_username": "appserver",
|
||||||
"ds_rpt_password": "encrypted:46692f9b4e3bda4931a9b83685a04a15187cb725295dc68627d7eb0b760362bc8a9de8d28395fca70b30fa4595cf3ed4a83772ee73eaf13a",
|
"ds_rpt_password": "encrypted:********",
|
||||||
"ds_rpt_connectionLimit": "5",
|
"ds_rpt_connectionLimit": "5",
|
||||||
"IDP_CLIENT_SECRET": "mXuJehst7ZZSBIFpjpLZFicYRhpLmxVs",
|
"IDP_CLIENT_SECRET": "********",
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"ds_rpt_class": "org.postgresql.Driver",
|
||||||
|
"ds_rpt_connectionString": "jdbc:postgresql://db-services.adl.nubes.ru:5432/dwh",
|
||||||
|
"ds_rpt_username": "smishchuk",
|
||||||
|
"ds_rpt_password": "encrypted:46692f9b4e3bda4931a9b83685a04a15187cb725295dc68627d7eb0b760362bc8a9de8d28395fca70b30fa4595cf3ed4a83772ee73eaf13a",
|
||||||
|
"ds_rpt_connectionLimit": "5",
|
||||||
|
"IDP_CLIENT_SECRET": "mXuJehst7ZZSBIFpjpLZFicYRhpLmxVs",
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
REM set Windows env
|
||||||
|
setx rpt_class org.postgresql.Driver /M
|
||||||
|
setx rpt_connectionString jdbc:postgresql://write.09d78921-77a7-401a-b2cb-5ca11be850a0.services.ngcloud.ru:5432/rpt /M
|
||||||
|
setx rpt_username appserver /M
|
||||||
|
setx rpt_password encrypted:8b11c6e220c6456af3e08294e86cf91283d4119b58e25891e24719b0d27cbd4991d023c88da45113555c98d2cb5e4e969a4f585a94051527 /M
|
||||||
|
setx rpt_connectionLimit 5 /M
|
||||||
|
|
||||||
|
setx IDP_CLIENT_SECRET mXuJehst7ZZSBIFpjpLZFicYRhpLmxVs /M
|
||||||
|
|
||||||
|
pause
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
REM set Windows env
|
||||||
|
setx rpt_class org.postgresql.Driver /M
|
||||||
|
setx rpt_connectionString jdbc:postgresql://write.09d78921-77a7-401a-b2cb-5ca11be850a0.services.ngcloud.ru:5432/rpt /M
|
||||||
|
setx rpt_username smishchuk /M
|
||||||
|
setx rpt_password encrypted:8b11c6e220c6456af3e08294e86cf91283d4119b58e25891e24719b0d27cbd4991d023c88da45113555c98d2cb5e4e969a4f585a94051527 /M
|
||||||
|
setx rpt_connectionLimit 5 /M
|
||||||
|
|
||||||
|
setx IDP_CLIENT_SECRET mXuJehst7ZZSBIFpjpLZFicYRhpLmxVs /M
|
||||||
|
|
||||||
|
pause
|
||||||
+6
-6
@@ -1,10 +1,10 @@
|
|||||||
REM set Windows env
|
REM set Windows env
|
||||||
setx ds_dwh_class org.postgresql.Driver /M
|
setx rpt_class org.postgresql.Driver /M
|
||||||
setx ds_dwh_connectionString jdbc:postgresql://db-services.adl.nubes.ru:5432/dwh /M
|
setx rpt_connectionString jdbc:postgresql://write.09d78921-77a7-401a-b2cb-5ca11be850a0.services.ngcloud.ru:5432/rpt /M
|
||||||
setx ds_dwh_username smishchuk /M
|
setx rpt_username appserver /M
|
||||||
setx ds_dwh_password encrypted:******** /M
|
setx rpt_password encrypted:******** /M
|
||||||
setx ds_dwh_connectionLimit 5 /M
|
setx rpt_connectionLimit 5 /M
|
||||||
|
|
||||||
setx IDP_CLIENT_SECRET ******** /M
|
setx IDP_CLIENT_SECRET ******** /M
|
||||||
|
|
||||||
pause
|
pause
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
REM set Windows env
|
||||||
|
setx rpt_class org.postgresql.Driver /M
|
||||||
|
setx rpt_connectionString jdbc:postgresql://write.09d78921-77a7-401a-b2cb-5ca11be850a0.services.ngcloud.ru:5432/rpt /M
|
||||||
|
setx rpt_username smishchuk /M
|
||||||
|
setx rpt_password encrypted:******** /M
|
||||||
|
setx rpt_connectionLimit 5 /M
|
||||||
|
|
||||||
|
setx IDP_CLIENT_SECRET ******** /M
|
||||||
|
|
||||||
|
pause
|
||||||
@@ -7,22 +7,25 @@
|
|||||||
|
|
||||||
<m:prepare_ls entity="payg" accessObject="" pageInfoOut="pageInfo" trackOut="tr"/>
|
<m:prepare_ls entity="payg" accessObject="" pageInfoOut="pageInfo" trackOut="tr"/>
|
||||||
|
|
||||||
|
|
||||||
<cfparam name="dt_finish" type="date" default=#createDateTime(year(Now()),month(Now()),1,0,0,0)#/>
|
<cfparam name="dt_finish" type="date" default=#createDateTime(year(Now()),month(Now()),1,0,0,0)#/>
|
||||||
<cfparam name="dt_start" type="date" default=#dateAdd('m',-1,dt_finish)#/>
|
<cfparam name="dt_start" type="date" default=#dateAdd('m',-1,dt_finish)#/>
|
||||||
<cfset hours=dateDiff('h',dt_start,dt_finish)/>
|
<cfset hours=dateDiff('h',dt_start,dt_finish)/>
|
||||||
|
|
||||||
<cfset tenant_wz_index=val(mid(request.auth.wz,3,5))/><!--- cut off WZ --->
|
<cfset tenant_wz_index=val(mid(request.auth.wz,3,5))/><!--- cut off WZ --->
|
||||||
|
|
||||||
|
|
||||||
<!--- looks like QoQ does not support join syntax, at least of Lucee 5.4--->
|
<cfif isDefined("output_xls")><cfmodule template="mod/payg.cfm"
|
||||||
|
dt_finish=#dt_finish#
|
||||||
|
dt_start=#dt_start#
|
||||||
<cfif isDefined("output_xls")>
|
output="report"
|
||||||
<layout:xml qRead=#qCharge# titleMap=#titleMap# filename="#pageInfo.entity#.xml"/>
|
debug=#isDefined("DEBUG")#
|
||||||
|
/><layout:xml qRead=#report.qCharge# titleMap=#report.chargeTitleMap# filename="#pageInfo.entity#.xml"/>
|
||||||
<cfabort/>
|
<cfabort/>
|
||||||
</cfif><cfif isDefined("output_json")>
|
</cfif><cfif isDefined("output_json")><cfmodule template="mod/payg.cfm"
|
||||||
<layout:json qRead=#qCharge# titleMap=#titleMap# filename="#pageInfo.entity#.json"/>
|
dt_finish=#dt_finish#
|
||||||
|
dt_start=#dt_start#
|
||||||
|
output="report"
|
||||||
|
debug=#isDefined("DEBUG")#
|
||||||
|
/><!--- <cfdump var=#report#/><cfabort/> ---><layout:json qRead=#report.qCharge# titleMap=#report.chargeTitleMap# filename="#pageInfo.entity#.json"/>
|
||||||
<cfabort/>
|
<cfabort/>
|
||||||
</cfif><!---
|
</cfif><!---
|
||||||
---><layout:page section="header" pageInfo=#pageInfo#>
|
---><layout:page section="header" pageInfo=#pageInfo#>
|
||||||
@@ -51,266 +54,19 @@
|
|||||||
|
|
||||||
<cfflush/>
|
<cfflush/>
|
||||||
|
|
||||||
|
<cfmodule template="mod/payg.cfm"
|
||||||
|
dt_finish=#dt_finish#
|
||||||
|
dt_start=#dt_start#
|
||||||
|
output="report"
|
||||||
|
debug=#isDefined("DEBUG")#
|
||||||
|
/>
|
||||||
|
|
||||||
|
Часов в периоде: <b>#hours#</b> Строк в отчете: <b>#report.qCharge.recordCount#</b><br/>
|
||||||
<!--- Для начала выкатываем просто кусок каталога, не фильтруя по спеке (которой иногда нет) --->
|
|
||||||
<cfquery name="qSpec">
|
|
||||||
select * from (
|
|
||||||
values
|
|
||||||
('Объектное хранилище S3 CEPH','Дисковое пространство: Объем хранения','paas.s3.ceph.vol-m','ГБайт',1.80,0)
|
|
||||||
,('Объектное хранилище S3 CEPH','Исходящий трафик','paas.s3.ceph.trf-m','ГБайт',1.50,0)
|
|
||||||
,('Объектное хранилище S3 CEPH','Запросы GET, HEAD, OPTIONS','paas.s3.ceph.get-m','10тыс.шт.',0.35,0)
|
|
||||||
,('Объектное хранилище S3 CEPH','Запросы PUT, POST, PATCH','paas.s3.ceph.put-m','10тыс.шт.',4.50,0)
|
|
||||||
) as
|
|
||||||
s (svc, component, code, unit, price, discount)
|
|
||||||
order by code
|
|
||||||
</cfquery>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!--- Нужно еще реализовать в модели данных политики бесплатного минимума --->
|
|
||||||
<cfquery name="qComputing">
|
|
||||||
select 'WZ'||to_char(tenant.wzcode,'FM00000') as wz, vdc.name as vdc_name,
|
|
||||||
case
|
|
||||||
when vdc.name like '%-v1cl1%' then 'iaas.ngc.i29'
|
|
||||||
when vdc.name like '%-v1cl2%' then 'iaas.ngc.i31'
|
|
||||||
when vdc.name like '%-v1cl4%' then 'iaas.ngc.a28'
|
|
||||||
when vdc.name like '%-v1cl6%' then 'iaas.ngc.i28'
|
|
||||||
else '['||vdc.name||']' end as code,
|
|
||||||
sum(cpu_used/cpu_speed)/4. as core_h,
|
|
||||||
sum(mem_used)/1024/4. as gb_h
|
|
||||||
from ngcloud_ru.capacity_resource
|
|
||||||
join ngcloud_ru.vdc on capacity_resource.vdc_id=vdc.id
|
|
||||||
join ngcloud_ru.tenant on tenant.id=vdc.tenant_id
|
|
||||||
where tenant.wzcode = <cfqueryparam cfsqltype="cf_sql_integer" value=#tenant_wz_index#/>
|
|
||||||
AND capacity_resource.timestamp >= <cfqueryparam cfsqltype="cf_sql_timestamp" value=#dt_start#/>
|
|
||||||
AND capacity_resource.timestamp < <cfqueryparam cfsqltype="cf_sql_timestamp" value=#dt_finish#/>
|
|
||||||
group by tenant.wzcode, vdc.name
|
|
||||||
order by tenant.wzcode, vdc.name;
|
|
||||||
</cfquery>
|
|
||||||
|
|
||||||
<cfif isDefined("DEBUG")>
|
|
||||||
<cfdump var=#qComputing#/>
|
|
||||||
<cfflush/>
|
|
||||||
</cfif>
|
|
||||||
|
|
||||||
<cfquery name="qComputingAge">
|
|
||||||
select max(capacity_resource.timestamp) as dt_load from ngcloud_ru.capacity_resource
|
|
||||||
</cfquery>
|
|
||||||
|
|
||||||
|
|
||||||
<!--- переделать storage_profile_types с расшифровкой ssd, sata, можно прямо до каталожного кода --->
|
|
||||||
<cfquery name="qStorage">
|
|
||||||
select 'WZ'||to_char(tenant.wzcode,'FM00000') as wz, vdc.name as vdc_name,
|
|
||||||
case
|
|
||||||
WHEN vdc.name LIKE '%-v1cl1%' THEN 'iaas.ngc.i29'
|
|
||||||
WHEN vdc.name LIKE '%-v1cl2%' THEN 'iaas.ngc.i31'
|
|
||||||
WHEN vdc.name LIKE '%-v1cl4%' THEN 'iaas.ngc.a28'
|
|
||||||
WHEN vdc.name LIKE '%-v1cl6%' THEN 'iaas.ngc.i28'
|
|
||||||
ELSE '['||vdc.name||']' END
|
|
||||||
|| CASE
|
|
||||||
WHEN storage_profile_types.name ILIKE '%-SSD%' THEN '.ssd-m'
|
|
||||||
WHEN storage_profile_types.name ILIKE '%-SAS' THEN '.sas-m'
|
|
||||||
WHEN storage_profile_types.name ILIKE '%-SATA' THEN '.sata-m'
|
|
||||||
ELSE '.['|| storage_profile_types.name ||']' END
|
|
||||||
as code,
|
|
||||||
storage_profile_types.name, -- *** это не тип, а профайл
|
|
||||||
sum("limit")/1024./4 as gb_h_limit, -- 4 потому, что сбор раз в 15 минут
|
|
||||||
sum(used)/1024./4 as gb_h_used
|
|
||||||
from ngcloud_ru.capacity_storage
|
|
||||||
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=#tenant_wz_index#/>
|
|
||||||
AND capacity_storage.timestamp >= <cfqueryparam cfsqltype="cf_sql_timestamp" value=#dt_start#/>
|
|
||||||
AND capacity_storage.timestamp < <cfqueryparam cfsqltype="cf_sql_timestamp" value=#dt_finish#/>
|
|
||||||
group by tenant.wzcode, vdc.name, storage_profile_types.name
|
|
||||||
order by tenant.wzcode, vdc.name, storage_profile_types.name;
|
|
||||||
</cfquery>
|
|
||||||
<cfquery name="qStorageAge" datasource="rpt">
|
|
||||||
select max(capacity_storage.timestamp) as dt_load from ngcloud_ru.capacity_storage
|
|
||||||
</cfquery>
|
|
||||||
|
|
||||||
<cfif isDefined("DEBUG")>
|
|
||||||
<cfdump var=#qStorage#/>
|
|
||||||
<cfflush/>
|
|
||||||
</cfif>
|
|
||||||
|
|
||||||
<!---
|
|
||||||
"placement" "size_gb" "get_10k" "put_10k" "bytes_sent_gb"
|
|
||||||
HOT_FREE_LIMIT 1 10 1 100
|
|
||||||
--->
|
|
||||||
<!--- надо дисконтировать не ГБ-часы а ГБ-месяцы --->
|
|
||||||
<cfquery name="qS3Vol">
|
|
||||||
select /* *** ниже дублирование кода агрегации - round ceil etc, обратить внимание при правке */
|
|
||||||
(sum(bucket_stat.usage_rgw_main_size_actual)/<cfqueryparam cfsqltype="cf_sql_integer" value=#hours#/>) as vol_B
|
|
||||||
,ceil(sum(bucket_stat.usage_rgw_main_size_actual)/<cfqueryparam cfsqltype="cf_sql_integer" value=#hours#/>/1024/1024/1024) as vol_GB
|
|
||||||
,greatest(ceil(sum(bucket_stat.usage_rgw_main_size_actual)/<cfqueryparam cfsqltype="cf_sql_integer" value=#hours#/>
|
|
||||||
/1024/1024/1024)-
|
|
||||||
case when bucket_stat.placement_id = 1 then 1 else 0 end, 0) as vol_GB_free_tier_subtracted /*считается не в точности так, как в функции*/
|
|
||||||
,case
|
|
||||||
when bucket_stat.placement_id = 1 then 'paas.s3.ceph'
|
|
||||||
when bucket_stat.placement_id = 2 then 'paas.s3.cphc'
|
|
||||||
else '['|| TO_CHAR(bucket_stat.placement_id,'FM9') ||']' end as code
|
|
||||||
--,bucket_stat.placement_id
|
|
||||||
,'WZ'||lpad(bucket_stat.owner, 5, '0') as wz -- *** здесь не число, а строка, поэтому другая формула обратной сборки WZ
|
|
||||||
|
|
||||||
from s3billing.bucket_stat
|
|
||||||
join s3billing.placement ON s3billing.placement.id=bucket_stat.placement_id
|
|
||||||
join s3billing.bucket_info ON bucket_info.id=bucket_stat.bucket_id
|
|
||||||
where bucket_stat.placement_id in (1,2)
|
|
||||||
AND bucket_stat.owner = <cfqueryparam cfsqltype="cf_sql_varchar" value=#tenant_wz_index#/>
|
|
||||||
AND bucket_stat.timestamp_addition >= <cfqueryparam cfsqltype="cf_sql_timestamp" value=#dt_start#/>
|
|
||||||
AND bucket_stat.timestamp_addition < <cfqueryparam cfsqltype="cf_sql_timestamp" value=#dt_finish#/>
|
|
||||||
group by bucket_stat.owner, bucket_stat.placement_id
|
|
||||||
order by bucket_stat.owner, bucket_stat.placement_id;
|
|
||||||
</cfquery>
|
|
||||||
|
|
||||||
<cfif isDefined("DEBUG")>
|
|
||||||
<cfdump var=#qS3Vol#/>
|
|
||||||
<cfflush/>
|
|
||||||
</cfif>
|
|
||||||
|
|
||||||
<cfquery name="qS3VolAge">
|
|
||||||
select max(timestamp_addition) as dt_load from s3billing.bucket_stat
|
|
||||||
</cfquery>
|
|
||||||
|
|
||||||
<cfquery name="qS3OpsTrf">
|
|
||||||
select
|
|
||||||
sum(
|
|
||||||
CASE WHEN
|
|
||||||
(category.name LIKE 'get%'
|
|
||||||
OR category.name LIKE 'head%'
|
|
||||||
OR category.name LIKE 'options%'
|
|
||||||
) THEN ops ELSE 0 END
|
|
||||||
) as get
|
|
||||||
,ceil(sum(
|
|
||||||
CASE WHEN
|
|
||||||
(category.name LIKE 'get%'
|
|
||||||
OR category.name LIKE 'head%'
|
|
||||||
OR category.name LIKE 'options%'
|
|
||||||
) THEN ops ELSE 0 END
|
|
||||||
)/10000) as get_10k
|
|
||||||
,greatest(ceil(sum(
|
|
||||||
CASE WHEN
|
|
||||||
(category.name LIKE 'get%'
|
|
||||||
OR category.name LIKE 'head%'
|
|
||||||
OR category.name LIKE 'options%'
|
|
||||||
) THEN ops ELSE 0 END
|
|
||||||
)/10000) - CASE WHEN bucket_info.placement_id = 1 THEN 10 ELSE 0 END, 0
|
|
||||||
) as get_10k_free_tier_subtracted
|
|
||||||
|
|
||||||
,sum(
|
|
||||||
CASE WHEN
|
|
||||||
(category.name LIKE 'put%'
|
|
||||||
OR category.name LIKE 'post%'
|
|
||||||
OR category.name LIKE 'patch%'
|
|
||||||
OR category.name LIKE 'list%'
|
|
||||||
) THEN ops ELSE 0 END
|
|
||||||
) as put
|
|
||||||
,ceil(sum(
|
|
||||||
CASE WHEN
|
|
||||||
(category.name LIKE 'put%'
|
|
||||||
OR category.name LIKE 'post%'
|
|
||||||
OR category.name LIKE 'patch%'
|
|
||||||
OR category.name LIKE 'list%'
|
|
||||||
) THEN ops ELSE 0 END
|
|
||||||
)/10000) as put_10k
|
|
||||||
,greatest(ceil(sum(
|
|
||||||
CASE WHEN
|
|
||||||
(category.name LIKE 'put%'
|
|
||||||
OR category.name LIKE 'post%'
|
|
||||||
OR category.name LIKE 'patch%'
|
|
||||||
OR category.name LIKE 'list%'
|
|
||||||
) THEN ops ELSE 0 END
|
|
||||||
)/10000) - CASE WHEN bucket_info.placement_id = 1 THEN 1 ELSE 0 END, 0
|
|
||||||
) as put_10k_free_tier_subtracted
|
|
||||||
|
|
||||||
,(sum(bytes_sent)) as bytes_sent
|
|
||||||
,ceil(sum(bytes_sent)/1024/1024/1024) as bytes_sent_GB
|
|
||||||
,greatest(ceil(sum(bytes_sent)/1024/1024/1024) - CASE WHEN bucket_info.placement_id = 1 THEN 100 ELSE 0 END, 0
|
|
||||||
) as bytes_sent_GB_free_tier_subtracted
|
|
||||||
|
|
||||||
,case
|
|
||||||
when bucket_info.placement_id = 1 then 'paas.s3.ceph'
|
|
||||||
when bucket_info.placement_id = 2 then 'paas.s3.cphc'
|
|
||||||
else '['|| TO_CHAR(bucket_info.placement_id,'FM9') ||']' end as code --*** зачем делать там ключ bigint
|
|
||||||
,bucket_info.placement_id
|
|
||||||
--category.name, bucket_info.name
|
|
||||||
,'WZ'||lpad(user_info.name, 5, '0') as wz
|
|
||||||
from s3billing.usage_bucket_by_user
|
|
||||||
join s3billing.user_info on usage_bucket_by_user.user_id=user_info.id
|
|
||||||
join s3billing.category on usage_bucket_by_user.category_id=category.id
|
|
||||||
join s3billing.bucket_info on usage_bucket_by_user.bucketid=bucket_info.id
|
|
||||||
join s3billing.placement on bucket_info.placement_id=placement.id
|
|
||||||
where 1=1
|
|
||||||
AND user_info.name = <cfqueryparam cfsqltype="cf_sql_varchar" value=#tenant_wz_index#/>
|
|
||||||
AND usage_bucket_by_user.time >= <cfqueryparam cfsqltype="cf_sql_timestamp" value=#dt_start#/>
|
|
||||||
AND usage_bucket_by_user.time < <cfqueryparam cfsqltype="cf_sql_timestamp" value=#dt_finish#/>
|
|
||||||
group by user_info.name, bucket_info.placement_id
|
|
||||||
order by user_info.name, bucket_info.placement_id;
|
|
||||||
</cfquery>
|
|
||||||
|
|
||||||
<cfif isDefined("DEBUG")>
|
|
||||||
<cfdump var=#qS3OpsTrf#/>
|
|
||||||
<cfflush/>
|
|
||||||
</cfif>
|
|
||||||
|
|
||||||
<cfquery name="qS3OpsTrfAge">
|
|
||||||
select max(time) as dt_load from s3billing.usage_bucket_by_user
|
|
||||||
</cfquery>
|
|
||||||
|
|
||||||
|
|
||||||
<cfquery name="qUnifiedMetric" dbType="query">
|
|
||||||
select wz, code || '.vcpu-m' as code, core_h as raw_metric, core_h as metric, core_h as chargeable_metric from qComputing
|
|
||||||
union all
|
|
||||||
select wz, code || '.ram-m' as code, gb_h as raw_metric, gb_h as metric, gb_h as chargeable_metric from qComputing
|
|
||||||
union all
|
|
||||||
select wz, code, gb_h_used as raw_metric, gb_h_used as metric, gb_h_used as chargeable_metric from qStorage
|
|
||||||
union all
|
|
||||||
select wz, code || '.vol-m', vol_b as raw_metric, vol_gb as metric, vol_GB_free_tier_subtracted as chargeable_metric from qS3Vol
|
|
||||||
union all
|
|
||||||
select wz, code || '.get-m', get as raw_metric, get_10k as metric, get_10k_free_tier_subtracted as chargeable_metric from qS3OpsTrf
|
|
||||||
union all
|
|
||||||
select wz, code || '.put-m', put as raw_metric, put_10k as metric, put_10k_free_tier_subtracted as chargeable_metric from qS3OpsTrf
|
|
||||||
union all
|
|
||||||
select wz, code || '.trf-m', bytes_sent as raw_metric, bytes_sent_gb as metric, bytes_sent_gb_free_tier_subtracted as chargeable_metric from qS3OpsTrf
|
|
||||||
</cfquery>
|
|
||||||
<cfif isDefined("DEBUG")>
|
|
||||||
<cfdump var=#qUnifiedMetric#/>
|
|
||||||
<cfflush/>
|
|
||||||
</cfif>
|
|
||||||
|
|
||||||
<cfquery name="qCharge" dbType="query">
|
|
||||||
SELECT
|
|
||||||
<d:field_set titleMapOut="titleMap" lengthOut="fieldCount">
|
|
||||||
<d:field title="Артикул">s.code</d:field>
|
|
||||||
<d:field title="Услуга">s.svc</d:field>
|
|
||||||
<d:field title="Компонент">s.component</d:field>
|
|
||||||
<d:field title="Кол-во (метрика)" cfSqlType="CF_SQL_NUMERIC">m.chargeable_metric</d:field>
|
|
||||||
<d:field title="Ед.изм.">s.unit</d:field>
|
|
||||||
<d:field title="Цена &##8381; с НДС" cfSqlType="CF_SQL_NUMERIC">s.price*(100-s.discount)/100 as discounted_price</d:field>
|
|
||||||
<d:field title="Стоимость &##8381; с НДС" cfSqlType="CF_SQL_NUMERIC">s.price*(100-s.discount)/100*m.chargeable_metric as charge</d:field>
|
|
||||||
<!--- <d:field title="Дата НОУ" cfSqlType="CF_SQL_TIMESTAMP">s.dt_from</d:field> --->
|
|
||||||
<!--- <d:field title="Дата оконч." cfSqlType="CF_SQL_TIMESTAMP">s.dt_to</d:field>
|
|
||||||
<d:field title="Ключ строки">s.line_key</d:field> --->
|
|
||||||
<d:field title="GPL с НДС" cfSqlType="CF_SQL_NUMERIC">s.price</d:field>
|
|
||||||
<d:field title="Скидка%" cfSqlType="CF_SQL_NUMERIC">s.discount</d:field>
|
|
||||||
<d:field title="Сырая метрика" cfSqlType="CF_SQL_NUMERIC">m.raw_metric</d:field>
|
|
||||||
<d:field title="Приведен­ная метрика" cfSqlType="CF_SQL_NUMERIC">m.metric</d:field>
|
|
||||||
|
|
||||||
<!--- <d:field title="Клиентс. назв.">s.user_description</d:field> --->
|
|
||||||
</d:field_set>
|
|
||||||
FROM qSpec as s, qUnifiedMetric as m
|
|
||||||
WHERE m.wz=<cfqueryparam cfsqltype="cf_sql_varchar" value=#request.auth.wz#/> AND s.code=m.code
|
|
||||||
order by s.code
|
|
||||||
</cfquery>
|
|
||||||
Часов в периоде: <b>#hours#</b> Строк в отчете: <b>#qCharge.recordCount#</b><br/>
|
|
||||||
Актуальность данных:
|
Актуальность данных:
|
||||||
VCD Computing: <b>#dateFormat(qComputingAge.dt_load,'YYYY-MM-DD')# #timeFormat(qComputingAge.dt_load,'HH:MM:SS')#</b>
|
VCD Computing: <b>#dateFormat(report.qComputingAge.dt_load,'YYYY-MM-DD')# #timeFormat(report.qComputingAge.dt_load,'HH:MM:SS')#</b>
|
||||||
VCD Storage: <b>#dateFormat(qStorageAge.dt_load,'YYYY-MM-DD')# #timeFormat(qStorageAge.dt_load,'HH:MM:SS')#</b>
|
VCD Storage: <b>#dateFormat(report.qStorageAge.dt_load,'YYYY-MM-DD')# #timeFormat(report.qStorageAge.dt_load,'HH:MM:SS')#</b>
|
||||||
S3 хранение: <b>#dateFormat(qS3VolAge.dt_load,'YYYY-MM-DD')# #timeFormat(qS3VolAge.dt_load,'HH:MM:SS')#</b>
|
S3 хранение: <b>#dateFormat(report.qS3VolAge.dt_load,'YYYY-MM-DD')# #timeFormat(report.qS3VolAge.dt_load,'HH:MM:SS')#</b>
|
||||||
S3 операции и трафик: <b>#dateFormat(qS3OpsTrfAge.dt_load,'YYYY-MM-DD')# #timeFormat(qS3OpsTrfAge.dt_load,'HH:MM:SS')#</b>
|
S3 операции и трафик: <b>#dateFormat(report.qS3OpsTrfAge.dt_load,'YYYY-MM-DD')# #timeFormat(report.qS3OpsTrfAge.dt_load,'HH:MM:SS')#</b>
|
||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
<a href="#request.thisPage#?output_xls" title="экспорт в Excel" style="margin-left:.5em; height:100%;" target="_blank"><img src="img/xls.gif" style="vertical-align:text-bottom;"/></a>
|
<a href="#request.thisPage#?output_xls" title="экспорт в Excel" style="margin-left:.5em; height:100%;" target="_blank"><img src="img/xls.gif" style="vertical-align:text-bottom;"/></a>
|
||||||
@@ -349,7 +105,7 @@ S3 операции и трафик: <b>#dateFormat(qS3OpsTrfAge.dt_load,'YYYY-M
|
|||||||
|
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<cfoutput query="qCharge" group="svc">
|
<cfoutput query="report.qCharge" group="svc">
|
||||||
<cfset var acc=0/>
|
<cfset var acc=0/>
|
||||||
<tr>
|
<tr>
|
||||||
<td bgcolor="##ccc"></td>
|
<td bgcolor="##ccc"></td>
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
<cfset msStartAt=getTickCount()/>
|
||||||
|
<cfparam name="dt_finish" type="date" default=#createDateTime(year(Now()),month(Now()),1,0,0,0)#/>
|
||||||
|
<cfparam name="dt_start" type="date" default=#dateAdd('m',-1,dt_finish)#/>
|
||||||
|
<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="query2json"
|
||||||
|
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(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>
|
||||||
|
|
||||||
|
<cfreturn serializeJSON(outArray)/>
|
||||||
|
<cfelse>
|
||||||
|
<cfreturn serializeJSON(arguments.qry,"struct")/>
|
||||||
|
</cfif>
|
||||||
|
</cffunction>
|
||||||
|
|
||||||
|
|
||||||
|
<cfmodule template="mod/payg.cfm"
|
||||||
|
dt_finish=#dt_finish#
|
||||||
|
dt_start=#dt_start#
|
||||||
|
output="report"
|
||||||
|
debug=#isDefined("DEBUG")#
|
||||||
|
/>
|
||||||
|
<cfset out={
|
||||||
|
"hours"=#hours#,
|
||||||
|
"vcdComputingLoadedAt"="#dateFormat(report.qComputingAge.dt_load,'YYYY-MM-DD')# #timeFormat(report.qComputingAge.dt_load,'HH:MM:SS')#",
|
||||||
|
"vcdStorageLoadedAt"="#dateFormat(report.qStorageAge.dt_load,'YYYY-MM-DD')# #timeFormat(report.qStorageAge.dt_load,'HH:MM:SS')#",
|
||||||
|
"s3StorageLoadedAt"="#dateFormat(report.qComputingAge.dt_load,'YYYY-MM-DD')# #timeFormat(report.qS3VolAge.dt_load,'HH:MM:SS')#",
|
||||||
|
"s3OpsTrfLoadedAt"="#dateFormat(report.qS3OpsTrfAge.dt_load,'YYYY-MM-DD')# #timeFormat(report.qS3OpsTrfAge.dt_load,'HH:MM:SS')#",
|
||||||
|
"records"=#report.qCharge.recordCount#,
|
||||||
|
"queryDurationMs"=#(getTickCount() - msStartAt)#,
|
||||||
|
"report"=#report.qCharge.reduce((result, row) => {
|
||||||
|
result.append(row);
|
||||||
|
return result;
|
||||||
|
}, [])#
|
||||||
|
}/>
|
||||||
|
|
||||||
|
<cfcontent
|
||||||
|
type="application/json"
|
||||||
|
/><cfoutput>#serializeJSON(out)#</cfoutput>
|
||||||
|
|
||||||
|
|
||||||
+281
@@ -0,0 +1,281 @@
|
|||||||
|
<cfimport prefix="m" taglib="../lib"/>
|
||||||
|
<cfimport prefix="d" taglib="../lib/data"/>
|
||||||
|
|
||||||
|
<cfparam name="ATTRIBUTES.dt_finish" type="date" default=#createDateTime(year(Now()),month(Now()),1,0,0,0)#/>
|
||||||
|
<cfparam name="ATTRIBUTES.dt_start" type="date" default=#dateAdd('m',-1,ATTRIBUTES.dt_finish)#/>
|
||||||
|
<cfparam name="ATTRIBUTES.output" type="string" default="report"/>
|
||||||
|
<cfparam name="ATTRIBUTES.debug" type="boolean" default=false/>
|
||||||
|
|
||||||
|
<cfset hours=dateDiff('h', ATTRIBUTES.dt_start, ATTRIBUTES.dt_finish)/>
|
||||||
|
<cfset tenant_wz_index=val(mid(request.auth.wz,3,5))/><!--- cut off WZ --->
|
||||||
|
|
||||||
|
|
||||||
|
<!--- QoQ does not support join syntax, at least of Lucee 5.4--->
|
||||||
|
|
||||||
|
|
||||||
|
<!--- Для начала выкатываем просто кусок каталога, не фильтруя по спеке (которой иногда нет) --->
|
||||||
|
<cfquery name="qSpec">
|
||||||
|
select * from (
|
||||||
|
values
|
||||||
|
('Объектное хранилище S3 CEPH','Дисковое пространство: Объем хранения','paas.s3.ceph.vol-m','ГБайт',1.80,0)
|
||||||
|
,('Объектное хранилище S3 CEPH','Исходящий трафик','paas.s3.ceph.trf-m','ГБайт',1.50,0)
|
||||||
|
,('Объектное хранилище S3 CEPH','Запросы GET, HEAD, OPTIONS','paas.s3.ceph.get-m','10тыс.шт.',0.35,0)
|
||||||
|
,('Объектное хранилище S3 CEPH','Запросы PUT, POST, PATCH','paas.s3.ceph.put-m','10тыс.шт.',4.50,0)
|
||||||
|
) as
|
||||||
|
s (svc, component, code, unit, price, discount)
|
||||||
|
order by code
|
||||||
|
</cfquery>
|
||||||
|
|
||||||
|
|
||||||
|
<!--- Нужно еще реализовать в модели данных политики бесплатного минимума --->
|
||||||
|
<cfquery name="qComputing">
|
||||||
|
select 'WZ'||to_char(tenant.wzcode,'FM00000') as wz, vdc.name as vdc_name,
|
||||||
|
case
|
||||||
|
when vdc.name like '%-v1cl1%' then 'iaas.ngc.i29'
|
||||||
|
when vdc.name like '%-v1cl2%' then 'iaas.ngc.i31'
|
||||||
|
when vdc.name like '%-v1cl4%' then 'iaas.ngc.a28'
|
||||||
|
when vdc.name like '%-v1cl6%' then 'iaas.ngc.i28'
|
||||||
|
else '['||vdc.name||']' end as code,
|
||||||
|
sum(cpu_used/cpu_speed)/4. as core_h,
|
||||||
|
sum(mem_used)/1024/4. as gb_h
|
||||||
|
from ngcloud_ru.capacity_resource
|
||||||
|
join ngcloud_ru.vdc on capacity_resource.vdc_id=vdc.id
|
||||||
|
join ngcloud_ru.tenant on tenant.id=vdc.tenant_id
|
||||||
|
where tenant.wzcode = <cfqueryparam cfsqltype="cf_sql_integer" value=#tenant_wz_index#/>
|
||||||
|
AND capacity_resource.timestamp >= <cfqueryparam cfsqltype="cf_sql_timestamp" value=#ATTRIBUTES.dt_start#/>
|
||||||
|
AND capacity_resource.timestamp < <cfqueryparam cfsqltype="cf_sql_timestamp" value=#ATTRIBUTES.dt_finish#/>
|
||||||
|
group by tenant.wzcode, vdc.name
|
||||||
|
order by tenant.wzcode, vdc.name;
|
||||||
|
</cfquery>
|
||||||
|
|
||||||
|
<cfif (ATTRIBUTES.debug)>
|
||||||
|
<cfdump var=#qComputing#/>
|
||||||
|
<cfflush/>
|
||||||
|
</cfif>
|
||||||
|
|
||||||
|
<cfquery name="qComputingAge">
|
||||||
|
select max(capacity_resource.timestamp) as dt_load from ngcloud_ru.capacity_resource
|
||||||
|
</cfquery>
|
||||||
|
|
||||||
|
|
||||||
|
<!--- переделать storage_profile_types с расшифровкой ssd, sata, можно прямо до каталожного кода --->
|
||||||
|
<cfquery name="qStorage">
|
||||||
|
select 'WZ'||to_char(tenant.wzcode,'FM00000') as wz, vdc.name as vdc_name,
|
||||||
|
case
|
||||||
|
WHEN vdc.name LIKE '%-v1cl1%' THEN 'iaas.ngc.i29'
|
||||||
|
WHEN vdc.name LIKE '%-v1cl2%' THEN 'iaas.ngc.i31'
|
||||||
|
WHEN vdc.name LIKE '%-v1cl4%' THEN 'iaas.ngc.a28'
|
||||||
|
WHEN vdc.name LIKE '%-v1cl6%' THEN 'iaas.ngc.i28'
|
||||||
|
ELSE '['||vdc.name||']' END
|
||||||
|
|| CASE
|
||||||
|
WHEN storage_profile_types.name ILIKE '%-SSD%' THEN '.ssd-m'
|
||||||
|
WHEN storage_profile_types.name ILIKE '%-SAS' THEN '.sas-m'
|
||||||
|
WHEN storage_profile_types.name ILIKE '%-SATA' THEN '.sata-m'
|
||||||
|
ELSE '.['|| storage_profile_types.name ||']' END
|
||||||
|
as code,
|
||||||
|
storage_profile_types.name, -- *** это не тип, а профайл
|
||||||
|
sum("limit")/1024./4 as gb_h_limit, -- 4 потому, что сбор раз в 15 минут
|
||||||
|
sum(used)/1024./4 as gb_h_used
|
||||||
|
from ngcloud_ru.capacity_storage
|
||||||
|
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=#tenant_wz_index#/>
|
||||||
|
AND capacity_storage.timestamp >= <cfqueryparam cfsqltype="cf_sql_timestamp" value=#ATTRIBUTES.dt_start#/>
|
||||||
|
AND capacity_storage.timestamp < <cfqueryparam cfsqltype="cf_sql_timestamp" value=#ATTRIBUTES.dt_finish#/>
|
||||||
|
group by tenant.wzcode, vdc.name, storage_profile_types.name
|
||||||
|
order by tenant.wzcode, vdc.name, storage_profile_types.name;
|
||||||
|
</cfquery>
|
||||||
|
<cfquery name="qStorageAge" datasource="rpt">
|
||||||
|
select max(capacity_storage.timestamp) as dt_load from ngcloud_ru.capacity_storage
|
||||||
|
</cfquery>
|
||||||
|
|
||||||
|
<cfif (ATTRIBUTES.debug)>
|
||||||
|
<cfdump var=#qStorage#/>
|
||||||
|
<cfflush/>
|
||||||
|
</cfif>
|
||||||
|
|
||||||
|
<!---
|
||||||
|
"placement" "size_gb" "get_10k" "put_10k" "bytes_sent_gb"
|
||||||
|
HOT_FREE_LIMIT 1 10 1 100
|
||||||
|
--->
|
||||||
|
<!--- надо дисконтировать не ГБ-часы а ГБ-месяцы --->
|
||||||
|
<cfquery name="qS3Vol">
|
||||||
|
select /* *** ниже дублирование кода агрегации - round ceil etc, обратить внимание при правке */
|
||||||
|
(sum(bucket_stat.usage_rgw_main_size_actual)/<cfqueryparam cfsqltype="cf_sql_integer" value=#hours#/>) as vol_B
|
||||||
|
,ceil(sum(bucket_stat.usage_rgw_main_size_actual)/<cfqueryparam cfsqltype="cf_sql_integer" value=#hours#/>/1024/1024/1024) as vol_GB
|
||||||
|
,greatest(ceil(sum(bucket_stat.usage_rgw_main_size_actual)/<cfqueryparam cfsqltype="cf_sql_integer" value=#hours#/>
|
||||||
|
/1024/1024/1024)-
|
||||||
|
case when bucket_stat.placement_id = 1 then 1 else 0 end, 0) as vol_GB_free_tier_subtracted /*считается не в точности так, как в функции*/
|
||||||
|
,case
|
||||||
|
when bucket_stat.placement_id = 1 then 'paas.s3.ceph'
|
||||||
|
when bucket_stat.placement_id = 2 then 'paas.s3.cphc'
|
||||||
|
else '['|| TO_CHAR(bucket_stat.placement_id,'FM9') ||']' end as code
|
||||||
|
--,bucket_stat.placement_id
|
||||||
|
,'WZ'||lpad(bucket_stat.owner, 5, '0') as wz -- *** здесь не число, а строка, поэтому другая формула обратной сборки WZ
|
||||||
|
|
||||||
|
from s3billing.bucket_stat
|
||||||
|
join s3billing.placement ON s3billing.placement.id=bucket_stat.placement_id
|
||||||
|
join s3billing.bucket_info ON bucket_info.id=bucket_stat.bucket_id
|
||||||
|
where bucket_stat.placement_id in (1,2)
|
||||||
|
AND bucket_stat.owner = <cfqueryparam cfsqltype="cf_sql_varchar" value=#tenant_wz_index#/>
|
||||||
|
AND bucket_stat.timestamp_addition >= <cfqueryparam cfsqltype="cf_sql_timestamp" value=#ATTRIBUTES.dt_start#/>
|
||||||
|
AND bucket_stat.timestamp_addition < <cfqueryparam cfsqltype="cf_sql_timestamp" value=#ATTRIBUTES.dt_finish#/>
|
||||||
|
group by bucket_stat.owner, bucket_stat.placement_id
|
||||||
|
order by bucket_stat.owner, bucket_stat.placement_id;
|
||||||
|
</cfquery>
|
||||||
|
|
||||||
|
<cfif (ATTRIBUTES.debug)>
|
||||||
|
<cfdump var=#qS3Vol#/>
|
||||||
|
<cfflush/>
|
||||||
|
</cfif>
|
||||||
|
|
||||||
|
<cfquery name="qS3VolAge">
|
||||||
|
select max(timestamp_addition) as dt_load from s3billing.bucket_stat
|
||||||
|
</cfquery>
|
||||||
|
|
||||||
|
<cfquery name="qS3OpsTrf">
|
||||||
|
select
|
||||||
|
sum(
|
||||||
|
CASE WHEN
|
||||||
|
(category.name LIKE 'get%'
|
||||||
|
OR category.name LIKE 'head%'
|
||||||
|
OR category.name LIKE 'options%'
|
||||||
|
) THEN ops ELSE 0 END
|
||||||
|
) as get
|
||||||
|
,ceil(sum(
|
||||||
|
CASE WHEN
|
||||||
|
(category.name LIKE 'get%'
|
||||||
|
OR category.name LIKE 'head%'
|
||||||
|
OR category.name LIKE 'options%'
|
||||||
|
) THEN ops ELSE 0 END
|
||||||
|
)/10000) as get_10k
|
||||||
|
,greatest(ceil(sum(
|
||||||
|
CASE WHEN
|
||||||
|
(category.name LIKE 'get%'
|
||||||
|
OR category.name LIKE 'head%'
|
||||||
|
OR category.name LIKE 'options%'
|
||||||
|
) THEN ops ELSE 0 END
|
||||||
|
)/10000) - CASE WHEN bucket_info.placement_id = 1 THEN 10 ELSE 0 END, 0
|
||||||
|
) as get_10k_free_tier_subtracted
|
||||||
|
|
||||||
|
,sum(
|
||||||
|
CASE WHEN
|
||||||
|
(category.name LIKE 'put%'
|
||||||
|
OR category.name LIKE 'post%'
|
||||||
|
OR category.name LIKE 'patch%'
|
||||||
|
OR category.name LIKE 'list%'
|
||||||
|
) THEN ops ELSE 0 END
|
||||||
|
) as put
|
||||||
|
,ceil(sum(
|
||||||
|
CASE WHEN
|
||||||
|
(category.name LIKE 'put%'
|
||||||
|
OR category.name LIKE 'post%'
|
||||||
|
OR category.name LIKE 'patch%'
|
||||||
|
OR category.name LIKE 'list%'
|
||||||
|
) THEN ops ELSE 0 END
|
||||||
|
)/10000) as put_10k
|
||||||
|
,greatest(ceil(sum(
|
||||||
|
CASE WHEN
|
||||||
|
(category.name LIKE 'put%'
|
||||||
|
OR category.name LIKE 'post%'
|
||||||
|
OR category.name LIKE 'patch%'
|
||||||
|
OR category.name LIKE 'list%'
|
||||||
|
) THEN ops ELSE 0 END
|
||||||
|
)/10000) - CASE WHEN bucket_info.placement_id = 1 THEN 1 ELSE 0 END, 0
|
||||||
|
) as put_10k_free_tier_subtracted
|
||||||
|
|
||||||
|
,(sum(bytes_sent)) as bytes_sent
|
||||||
|
,ceil(sum(bytes_sent)/1024/1024/1024) as bytes_sent_GB
|
||||||
|
,greatest(ceil(sum(bytes_sent)/1024/1024/1024) - CASE WHEN bucket_info.placement_id = 1 THEN 100 ELSE 0 END, 0
|
||||||
|
) as bytes_sent_GB_free_tier_subtracted
|
||||||
|
|
||||||
|
,case
|
||||||
|
when bucket_info.placement_id = 1 then 'paas.s3.ceph'
|
||||||
|
when bucket_info.placement_id = 2 then 'paas.s3.cphc'
|
||||||
|
else '['|| TO_CHAR(bucket_info.placement_id,'FM9') ||']' end as code --*** зачем делать там ключ bigint
|
||||||
|
,bucket_info.placement_id
|
||||||
|
--category.name, bucket_info.name
|
||||||
|
,'WZ'||lpad(user_info.name, 5, '0') as wz
|
||||||
|
from s3billing.usage_bucket_by_user
|
||||||
|
join s3billing.user_info on usage_bucket_by_user.user_id=user_info.id
|
||||||
|
join s3billing.category on usage_bucket_by_user.category_id=category.id
|
||||||
|
join s3billing.bucket_info on usage_bucket_by_user.bucketid=bucket_info.id
|
||||||
|
join s3billing.placement on bucket_info.placement_id=placement.id
|
||||||
|
where 1=1
|
||||||
|
AND user_info.name = <cfqueryparam cfsqltype="cf_sql_varchar" value=#tenant_wz_index#/>
|
||||||
|
AND usage_bucket_by_user.time >= <cfqueryparam cfsqltype="cf_sql_timestamp" value=#ATTRIBUTES.dt_start#/>
|
||||||
|
AND usage_bucket_by_user.time < <cfqueryparam cfsqltype="cf_sql_timestamp" value=#ATTRIBUTES.dt_finish#/>
|
||||||
|
group by user_info.name, bucket_info.placement_id
|
||||||
|
order by user_info.name, bucket_info.placement_id;
|
||||||
|
</cfquery>
|
||||||
|
|
||||||
|
<cfif (ATTRIBUTES.debug)>
|
||||||
|
<cfdump var=#qS3OpsTrf#/>
|
||||||
|
<cfflush/>
|
||||||
|
</cfif>
|
||||||
|
|
||||||
|
<cfquery name="qS3OpsTrfAge">
|
||||||
|
select max(time) as dt_load from s3billing.usage_bucket_by_user
|
||||||
|
</cfquery>
|
||||||
|
|
||||||
|
|
||||||
|
<cfquery name="qUnifiedMetric" dbType="query">
|
||||||
|
select wz, code || '.vcpu-m' as code, core_h as raw_metric, core_h as metric, core_h as chargeable_metric from qComputing
|
||||||
|
union all
|
||||||
|
select wz, code || '.ram-m' as code, gb_h as raw_metric, gb_h as metric, gb_h as chargeable_metric from qComputing
|
||||||
|
union all
|
||||||
|
select wz, code, gb_h_used as raw_metric, gb_h_used as metric, gb_h_used as chargeable_metric from qStorage
|
||||||
|
union all
|
||||||
|
select wz, code || '.vol-m', vol_b as raw_metric, vol_gb as metric, vol_GB_free_tier_subtracted as chargeable_metric from qS3Vol
|
||||||
|
union all
|
||||||
|
select wz, code || '.get-m', get as raw_metric, get_10k as metric, get_10k_free_tier_subtracted as chargeable_metric from qS3OpsTrf
|
||||||
|
union all
|
||||||
|
select wz, code || '.put-m', put as raw_metric, put_10k as metric, put_10k_free_tier_subtracted as chargeable_metric from qS3OpsTrf
|
||||||
|
union all
|
||||||
|
select wz, code || '.trf-m', bytes_sent as raw_metric, bytes_sent_gb as metric, bytes_sent_gb_free_tier_subtracted as chargeable_metric from qS3OpsTrf
|
||||||
|
</cfquery>
|
||||||
|
|
||||||
|
<cfif (ATTRIBUTES.debug)>
|
||||||
|
<cfdump var=#qUnifiedMetric#/>
|
||||||
|
<cfflush/>
|
||||||
|
</cfif>
|
||||||
|
|
||||||
|
<cfquery name="qCharge" dbType="query">
|
||||||
|
SELECT
|
||||||
|
<d:field_set titleMapOut="titleMap" lengthOut="fieldCount">
|
||||||
|
<d:field title="Артикул">s.code</d:field>
|
||||||
|
<d:field title="Услуга">s.svc</d:field>
|
||||||
|
<d:field title="Компонент">s.component</d:field>
|
||||||
|
<d:field title="Кол-во (метрика)" cfSqlType="CF_SQL_NUMERIC">m.chargeable_metric</d:field>
|
||||||
|
<d:field title="Ед.изм.">s.unit</d:field>
|
||||||
|
<d:field title="Цена &##8381; с НДС" cfSqlType="CF_SQL_NUMERIC">s.price*(100-s.discount)/100 as discounted_price</d:field>
|
||||||
|
<d:field title="Стоимость &##8381; с НДС" cfSqlType="CF_SQL_NUMERIC">s.price*(100-s.discount)/100*m.chargeable_metric as charge</d:field>
|
||||||
|
<!--- <d:field title="Дата НОУ" cfSqlType="CF_SQL_TIMESTAMP">s.dt_from</d:field> --->
|
||||||
|
<!--- <d:field title="Дата оконч." cfSqlType="CF_SQL_TIMESTAMP">s.dt_to</d:field>
|
||||||
|
<d:field title="Ключ строки">s.line_key</d:field> --->
|
||||||
|
<d:field title="GPL с НДС" cfSqlType="CF_SQL_NUMERIC">s.price</d:field>
|
||||||
|
<d:field title="Скидка%" cfSqlType="CF_SQL_NUMERIC">s.discount</d:field>
|
||||||
|
<d:field title="Сырая метрика" cfSqlType="CF_SQL_NUMERIC">m.raw_metric</d:field>
|
||||||
|
<d:field title="Приведенная метрика" cfSqlType="CF_SQL_NUMERIC">m.metric</d:field>
|
||||||
|
|
||||||
|
<!--- <d:field title="Клиентс. назв.">s.user_description</d:field> --->
|
||||||
|
</d:field_set>
|
||||||
|
FROM qSpec as s, qUnifiedMetric as m
|
||||||
|
WHERE m.wz=<cfqueryparam cfsqltype="cf_sql_varchar" value=#request.auth.wz#/> AND s.code=m.code
|
||||||
|
order by s.code
|
||||||
|
</cfquery>
|
||||||
|
|
||||||
|
<cfset var report={}/>
|
||||||
|
|
||||||
|
<cfset report.qComputingAge = qComputingAge/>
|
||||||
|
<cfset report.qStorageAge = qStorageAge/>
|
||||||
|
<cfset report.qS3VolAge = qS3VolAge/>
|
||||||
|
<cfset report.qS3OpsTrfAge = qS3OpsTrfAge/>
|
||||||
|
<cfset report.qCharge = qCharge/>
|
||||||
|
<cfset report.chargeTitleMap = titleMap/>
|
||||||
|
<cfset report.chargeFieldCount = fieldCount/>
|
||||||
|
|
||||||
|
<cfset "CALLER.#ATTRIBUTES.output#" = report/>
|
||||||
|
|
||||||
|
<cfexit method="exittag"/>
|
||||||
@@ -0,0 +1,281 @@
|
|||||||
|
<cfimport prefix="m" taglib="../lib"/>
|
||||||
|
<cfimport prefix="d" taglib="../lib/data"/>
|
||||||
|
|
||||||
|
<cfparam name="ATTRIBUTES.dt_finish" type="date" default=#createDateTime(year(Now()),month(Now()),1,0,0,0)#/>
|
||||||
|
<cfparam name="ATTRIBUTES.dt_start" type="date" default=#dateAdd('m',-1,ATTRIBUTES.dt_finish)#/>
|
||||||
|
<cfparam name="ATTRIBUTES.output" type="string" default="report"/>
|
||||||
|
<cfparam name="ATTRIBUTES.debug" type="boolean" default=false/>
|
||||||
|
|
||||||
|
<cfset hours=dateDiff('h',dt_start,dt_finish)/>
|
||||||
|
<cfset tenant_wz_index=val(mid(request.auth.wz,3,5))/><!--- cut off WZ --->
|
||||||
|
|
||||||
|
|
||||||
|
<!--- QoQ does not support join syntax, at least of Lucee 5.4--->
|
||||||
|
|
||||||
|
|
||||||
|
<!--- Для начала выкатываем просто кусок каталога, не фильтруя по спеке (которой иногда нет) --->
|
||||||
|
<cfquery name="qSpec">
|
||||||
|
select * from (
|
||||||
|
values
|
||||||
|
('Объектное хранилище S3 CEPH','Дисковое пространство: Объем хранения','paas.s3.ceph.vol-m','ГБайт',1.80,0)
|
||||||
|
,('Объектное хранилище S3 CEPH','Исходящий трафик','paas.s3.ceph.trf-m','ГБайт',1.50,0)
|
||||||
|
,('Объектное хранилище S3 CEPH','Запросы GET, HEAD, OPTIONS','paas.s3.ceph.get-m','10тыс.шт.',0.35,0)
|
||||||
|
,('Объектное хранилище S3 CEPH','Запросы PUT, POST, PATCH','paas.s3.ceph.put-m','10тыс.шт.',4.50,0)
|
||||||
|
) as
|
||||||
|
s (svc, component, code, unit, price, discount)
|
||||||
|
order by code
|
||||||
|
</cfquery>
|
||||||
|
|
||||||
|
|
||||||
|
<!--- Нужно еще реализовать в модели данных политики бесплатного минимума --->
|
||||||
|
<cfquery name="qComputing">
|
||||||
|
select 'WZ'||to_char(tenant.wzcode,'FM00000') as wz, vdc.name as vdc_name,
|
||||||
|
case
|
||||||
|
when vdc.name like '%-v1cl1%' then 'iaas.ngc.i29'
|
||||||
|
when vdc.name like '%-v1cl2%' then 'iaas.ngc.i31'
|
||||||
|
when vdc.name like '%-v1cl4%' then 'iaas.ngc.a28'
|
||||||
|
when vdc.name like '%-v1cl6%' then 'iaas.ngc.i28'
|
||||||
|
else '['||vdc.name||']' end as code,
|
||||||
|
sum(cpu_used/cpu_speed)/4. as core_h,
|
||||||
|
sum(mem_used)/1024/4. as gb_h
|
||||||
|
from ngcloud_ru.capacity_resource
|
||||||
|
join ngcloud_ru.vdc on capacity_resource.vdc_id=vdc.id
|
||||||
|
join ngcloud_ru.tenant on tenant.id=vdc.tenant_id
|
||||||
|
where tenant.wzcode = <cfqueryparam cfsqltype="cf_sql_integer" value=#tenant_wz_index#/>
|
||||||
|
AND capacity_resource.timestamp >= <cfqueryparam cfsqltype="cf_sql_timestamp" value=#ATTRIBUTES.dt_start#/>
|
||||||
|
AND capacity_resource.timestamp < <cfqueryparam cfsqltype="cf_sql_timestamp" value=#ATTRIBUTES.dt_finish#/>
|
||||||
|
group by tenant.wzcode, vdc.name
|
||||||
|
order by tenant.wzcode, vdc.name;
|
||||||
|
</cfquery>
|
||||||
|
|
||||||
|
<cfif (ATTRIBUTES.debug)>
|
||||||
|
<cfdump var=#qComputing#/>
|
||||||
|
<cfflush/>
|
||||||
|
</cfif>
|
||||||
|
|
||||||
|
<cfquery name="qComputingAge">
|
||||||
|
select max(capacity_resource.timestamp) as dt_load from ngcloud_ru.capacity_resource
|
||||||
|
</cfquery>
|
||||||
|
|
||||||
|
|
||||||
|
<!--- переделать storage_profile_types с расшифровкой ssd, sata, можно прямо до каталожного кода --->
|
||||||
|
<cfquery name="qStorage">
|
||||||
|
select 'WZ'||to_char(tenant.wzcode,'FM00000') as wz, vdc.name as vdc_name,
|
||||||
|
case
|
||||||
|
WHEN vdc.name LIKE '%-v1cl1%' THEN 'iaas.ngc.i29'
|
||||||
|
WHEN vdc.name LIKE '%-v1cl2%' THEN 'iaas.ngc.i31'
|
||||||
|
WHEN vdc.name LIKE '%-v1cl4%' THEN 'iaas.ngc.a28'
|
||||||
|
WHEN vdc.name LIKE '%-v1cl6%' THEN 'iaas.ngc.i28'
|
||||||
|
ELSE '['||vdc.name||']' END
|
||||||
|
|| CASE
|
||||||
|
WHEN storage_profile_types.name ILIKE '%-SSD%' THEN '.ssd-m'
|
||||||
|
WHEN storage_profile_types.name ILIKE '%-SAS' THEN '.sas-m'
|
||||||
|
WHEN storage_profile_types.name ILIKE '%-SATA' THEN '.sata-m'
|
||||||
|
ELSE '.['|| storage_profile_types.name ||']' END
|
||||||
|
as code,
|
||||||
|
storage_profile_types.name, -- *** это не тип, а профайл
|
||||||
|
sum("limit")/1024./4 as gb_h_limit, -- 4 потому, что сбор раз в 15 минут
|
||||||
|
sum(used)/1024./4 as gb_h_used
|
||||||
|
from ngcloud_ru.capacity_storage
|
||||||
|
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=#tenant_wz_index#/>
|
||||||
|
AND capacity_storage.timestamp >= <cfqueryparam cfsqltype="cf_sql_timestamp" value=#ATTRIBUTES.dt_start#/>
|
||||||
|
AND capacity_storage.timestamp < <cfqueryparam cfsqltype="cf_sql_timestamp" value=#ATTRIBUTES.dt_finish#/>
|
||||||
|
group by tenant.wzcode, vdc.name, storage_profile_types.name
|
||||||
|
order by tenant.wzcode, vdc.name, storage_profile_types.name;
|
||||||
|
</cfquery>
|
||||||
|
<cfquery name="qStorageAge" datasource="rpt">
|
||||||
|
select max(capacity_storage.timestamp) as dt_load from ngcloud_ru.capacity_storage
|
||||||
|
</cfquery>
|
||||||
|
|
||||||
|
<cfif (ATTRIBUTES.debug)>
|
||||||
|
<cfdump var=#qStorage#/>
|
||||||
|
<cfflush/>
|
||||||
|
</cfif>
|
||||||
|
|
||||||
|
<!---
|
||||||
|
"placement" "size_gb" "get_10k" "put_10k" "bytes_sent_gb"
|
||||||
|
HOT_FREE_LIMIT 1 10 1 100
|
||||||
|
--->
|
||||||
|
<!--- надо дисконтировать не ГБ-часы а ГБ-месяцы --->
|
||||||
|
<cfquery name="qS3Vol">
|
||||||
|
select /* *** ниже дублирование кода агрегации - round ceil etc, обратить внимание при правке */
|
||||||
|
(sum(bucket_stat.usage_rgw_main_size_actual)/<cfqueryparam cfsqltype="cf_sql_integer" value=#hours#/>) as vol_B
|
||||||
|
,ceil(sum(bucket_stat.usage_rgw_main_size_actual)/<cfqueryparam cfsqltype="cf_sql_integer" value=#hours#/>/1024/1024/1024) as vol_GB
|
||||||
|
,greatest(ceil(sum(bucket_stat.usage_rgw_main_size_actual)/<cfqueryparam cfsqltype="cf_sql_integer" value=#hours#/>
|
||||||
|
/1024/1024/1024)-
|
||||||
|
case when bucket_stat.placement_id = 1 then 1 else 0 end, 0) as vol_GB_free_tier_subtracted /*считается не в точности так, как в функции*/
|
||||||
|
,case
|
||||||
|
when bucket_stat.placement_id = 1 then 'paas.s3.ceph'
|
||||||
|
when bucket_stat.placement_id = 2 then 'paas.s3.cphc'
|
||||||
|
else '['|| TO_CHAR(bucket_stat.placement_id,'FM9') ||']' end as code
|
||||||
|
--,bucket_stat.placement_id
|
||||||
|
,'WZ'||lpad(bucket_stat.owner, 5, '0') as wz -- *** здесь не число, а строка, поэтому другая формула обратной сборки WZ
|
||||||
|
|
||||||
|
from s3billing.bucket_stat
|
||||||
|
join s3billing.placement ON s3billing.placement.id=bucket_stat.placement_id
|
||||||
|
join s3billing.bucket_info ON bucket_info.id=bucket_stat.bucket_id
|
||||||
|
where bucket_stat.placement_id in (1,2)
|
||||||
|
AND bucket_stat.owner = <cfqueryparam cfsqltype="cf_sql_varchar" value=#tenant_wz_index#/>
|
||||||
|
AND bucket_stat.timestamp_addition >= <cfqueryparam cfsqltype="cf_sql_timestamp" value=#ATTRIBUTES.dt_start#/>
|
||||||
|
AND bucket_stat.timestamp_addition < <cfqueryparam cfsqltype="cf_sql_timestamp" value=#ATTRIBUTES.dt_finish#/>
|
||||||
|
group by bucket_stat.owner, bucket_stat.placement_id
|
||||||
|
order by bucket_stat.owner, bucket_stat.placement_id;
|
||||||
|
</cfquery>
|
||||||
|
|
||||||
|
<cfif (ATTRIBUTES.debug)>
|
||||||
|
<cfdump var=#qS3Vol#/>
|
||||||
|
<cfflush/>
|
||||||
|
</cfif>
|
||||||
|
|
||||||
|
<cfquery name="qS3VolAge">
|
||||||
|
select max(timestamp_addition) as dt_load from s3billing.bucket_stat
|
||||||
|
</cfquery>
|
||||||
|
|
||||||
|
<cfquery name="qS3OpsTrf">
|
||||||
|
select
|
||||||
|
sum(
|
||||||
|
CASE WHEN
|
||||||
|
(category.name LIKE 'get%'
|
||||||
|
OR category.name LIKE 'head%'
|
||||||
|
OR category.name LIKE 'options%'
|
||||||
|
) THEN ops ELSE 0 END
|
||||||
|
) as get
|
||||||
|
,ceil(sum(
|
||||||
|
CASE WHEN
|
||||||
|
(category.name LIKE 'get%'
|
||||||
|
OR category.name LIKE 'head%'
|
||||||
|
OR category.name LIKE 'options%'
|
||||||
|
) THEN ops ELSE 0 END
|
||||||
|
)/10000) as get_10k
|
||||||
|
,greatest(ceil(sum(
|
||||||
|
CASE WHEN
|
||||||
|
(category.name LIKE 'get%'
|
||||||
|
OR category.name LIKE 'head%'
|
||||||
|
OR category.name LIKE 'options%'
|
||||||
|
) THEN ops ELSE 0 END
|
||||||
|
)/10000) - CASE WHEN bucket_info.placement_id = 1 THEN 10 ELSE 0 END, 0
|
||||||
|
) as get_10k_free_tier_subtracted
|
||||||
|
|
||||||
|
,sum(
|
||||||
|
CASE WHEN
|
||||||
|
(category.name LIKE 'put%'
|
||||||
|
OR category.name LIKE 'post%'
|
||||||
|
OR category.name LIKE 'patch%'
|
||||||
|
OR category.name LIKE 'list%'
|
||||||
|
) THEN ops ELSE 0 END
|
||||||
|
) as put
|
||||||
|
,ceil(sum(
|
||||||
|
CASE WHEN
|
||||||
|
(category.name LIKE 'put%'
|
||||||
|
OR category.name LIKE 'post%'
|
||||||
|
OR category.name LIKE 'patch%'
|
||||||
|
OR category.name LIKE 'list%'
|
||||||
|
) THEN ops ELSE 0 END
|
||||||
|
)/10000) as put_10k
|
||||||
|
,greatest(ceil(sum(
|
||||||
|
CASE WHEN
|
||||||
|
(category.name LIKE 'put%'
|
||||||
|
OR category.name LIKE 'post%'
|
||||||
|
OR category.name LIKE 'patch%'
|
||||||
|
OR category.name LIKE 'list%'
|
||||||
|
) THEN ops ELSE 0 END
|
||||||
|
)/10000) - CASE WHEN bucket_info.placement_id = 1 THEN 1 ELSE 0 END, 0
|
||||||
|
) as put_10k_free_tier_subtracted
|
||||||
|
|
||||||
|
,(sum(bytes_sent)) as bytes_sent
|
||||||
|
,ceil(sum(bytes_sent)/1024/1024/1024) as bytes_sent_GB
|
||||||
|
,greatest(ceil(sum(bytes_sent)/1024/1024/1024) - CASE WHEN bucket_info.placement_id = 1 THEN 100 ELSE 0 END, 0
|
||||||
|
) as bytes_sent_GB_free_tier_subtracted
|
||||||
|
|
||||||
|
,case
|
||||||
|
when bucket_info.placement_id = 1 then 'paas.s3.ceph'
|
||||||
|
when bucket_info.placement_id = 2 then 'paas.s3.cphc'
|
||||||
|
else '['|| TO_CHAR(bucket_info.placement_id,'FM9') ||']' end as code --*** зачем делать там ключ bigint
|
||||||
|
,bucket_info.placement_id
|
||||||
|
--category.name, bucket_info.name
|
||||||
|
,'WZ'||lpad(user_info.name, 5, '0') as wz
|
||||||
|
from s3billing.usage_bucket_by_user
|
||||||
|
join s3billing.user_info on usage_bucket_by_user.user_id=user_info.id
|
||||||
|
join s3billing.category on usage_bucket_by_user.category_id=category.id
|
||||||
|
join s3billing.bucket_info on usage_bucket_by_user.bucketid=bucket_info.id
|
||||||
|
join s3billing.placement on bucket_info.placement_id=placement.id
|
||||||
|
where 1=1
|
||||||
|
AND user_info.name = <cfqueryparam cfsqltype="cf_sql_varchar" value=#tenant_wz_index#/>
|
||||||
|
AND usage_bucket_by_user.time >= <cfqueryparam cfsqltype="cf_sql_timestamp" value=#ATTRIBUTES.dt_start#/>
|
||||||
|
AND usage_bucket_by_user.time < <cfqueryparam cfsqltype="cf_sql_timestamp" value=#ATTRIBUTES.dt_finish#/>
|
||||||
|
group by user_info.name, bucket_info.placement_id
|
||||||
|
order by user_info.name, bucket_info.placement_id;
|
||||||
|
</cfquery>
|
||||||
|
|
||||||
|
<cfif (ATTRIBUTES.debug)>
|
||||||
|
<cfdump var=#qS3OpsTrf#/>
|
||||||
|
<cfflush/>
|
||||||
|
</cfif>
|
||||||
|
|
||||||
|
<cfquery name="qS3OpsTrfAge">
|
||||||
|
select max(time) as dt_load from s3billing.usage_bucket_by_user
|
||||||
|
</cfquery>
|
||||||
|
|
||||||
|
|
||||||
|
<cfquery name="qUnifiedMetric" dbType="query">
|
||||||
|
select wz, code || '.vcpu-m' as code, core_h as raw_metric, core_h as metric, core_h as chargeable_metric from qComputing
|
||||||
|
union all
|
||||||
|
select wz, code || '.ram-m' as code, gb_h as raw_metric, gb_h as metric, gb_h as chargeable_metric from qComputing
|
||||||
|
union all
|
||||||
|
select wz, code, gb_h_used as raw_metric, gb_h_used as metric, gb_h_used as chargeable_metric from qStorage
|
||||||
|
union all
|
||||||
|
select wz, code || '.vol-m', vol_b as raw_metric, vol_gb as metric, vol_GB_free_tier_subtracted as chargeable_metric from qS3Vol
|
||||||
|
union all
|
||||||
|
select wz, code || '.get-m', get as raw_metric, get_10k as metric, get_10k_free_tier_subtracted as chargeable_metric from qS3OpsTrf
|
||||||
|
union all
|
||||||
|
select wz, code || '.put-m', put as raw_metric, put_10k as metric, put_10k_free_tier_subtracted as chargeable_metric from qS3OpsTrf
|
||||||
|
union all
|
||||||
|
select wz, code || '.trf-m', bytes_sent as raw_metric, bytes_sent_gb as metric, bytes_sent_gb_free_tier_subtracted as chargeable_metric from qS3OpsTrf
|
||||||
|
</cfquery>
|
||||||
|
|
||||||
|
<cfif (ATTRIBUTES.debug)>
|
||||||
|
<cfdump var=#qUnifiedMetric#/>
|
||||||
|
<cfflush/>
|
||||||
|
</cfif>
|
||||||
|
|
||||||
|
<cfquery name="qCharge" dbType="query">
|
||||||
|
SELECT
|
||||||
|
<d:field_set titleMapOut="titleMap" lengthOut="fieldCount">
|
||||||
|
<d:field title="Артикул">s.code</d:field>
|
||||||
|
<d:field title="Услуга">s.svc</d:field>
|
||||||
|
<d:field title="Компонент">s.component</d:field>
|
||||||
|
<d:field title="Кол-во (метрика)" cfSqlType="CF_SQL_NUMERIC">m.chargeable_metric</d:field>
|
||||||
|
<d:field title="Ед.изм.">s.unit</d:field>
|
||||||
|
<d:field title="Цена &##8381; с НДС" cfSqlType="CF_SQL_NUMERIC">s.price*(100-s.discount)/100 as discounted_price</d:field>
|
||||||
|
<d:field title="Стоимость &##8381; с НДС" cfSqlType="CF_SQL_NUMERIC">s.price*(100-s.discount)/100*m.chargeable_metric as charge</d:field>
|
||||||
|
<!--- <d:field title="Дата НОУ" cfSqlType="CF_SQL_TIMESTAMP">s.dt_from</d:field> --->
|
||||||
|
<!--- <d:field title="Дата оконч." cfSqlType="CF_SQL_TIMESTAMP">s.dt_to</d:field>
|
||||||
|
<d:field title="Ключ строки">s.line_key</d:field> --->
|
||||||
|
<d:field title="GPL с НДС" cfSqlType="CF_SQL_NUMERIC">s.price</d:field>
|
||||||
|
<d:field title="Скидка%" cfSqlType="CF_SQL_NUMERIC">s.discount</d:field>
|
||||||
|
<d:field title="Сырая метрика" cfSqlType="CF_SQL_NUMERIC">m.raw_metric</d:field>
|
||||||
|
<d:field title="Приведенная метрика" cfSqlType="CF_SQL_NUMERIC">m.metric</d:field>
|
||||||
|
|
||||||
|
<!--- <d:field title="Клиентс. назв.">s.user_description</d:field> --->
|
||||||
|
</d:field_set>
|
||||||
|
FROM qSpec as s, qUnifiedMetric as m
|
||||||
|
WHERE m.wz=<cfqueryparam cfsqltype="cf_sql_varchar" value=#request.auth.wz#/> AND s.code=m.code
|
||||||
|
order by s.code
|
||||||
|
</cfquery>
|
||||||
|
|
||||||
|
<cfset var report={}/>
|
||||||
|
|
||||||
|
<cfset report.qComputingAge = qComputingAge/>
|
||||||
|
<cfset report.qStorageAge = qStorageAge/>
|
||||||
|
<cfset report.qS3VolAge = qS3VolAge/>
|
||||||
|
<cfset report.qS3OpsTrfAge = qS3OpsTrfAge/>
|
||||||
|
<cfset report.qCharge = qCharge/>
|
||||||
|
<cfset report.chargeTitleMap = titleMap/>
|
||||||
|
<cfset report.chargeFieldCount = fieldCount/>
|
||||||
|
|
||||||
|
<cfset "CALLER.#ATTRIBUTES.output#" = report/>
|
||||||
|
|
||||||
|
<cfexit method="exittag"/>
|
||||||
Reference in New Issue
Block a user