01
@@ -0,0 +1,155 @@
|
||||
<cfsilent>
|
||||
<cfimport prefix="m" taglib="lib"/>
|
||||
<cfimport prefix="c" taglib="lib/controls"/>
|
||||
<cfimport prefix="d" taglib="lib/data"/>
|
||||
<cfimport prefix="layout" taglib="layout"/>
|
||||
</cfsilent><m:silent silent="No">
|
||||
|
||||
<cffunction name="plain2HtmClean">
|
||||
<cfargument name="s" type="string"/>
|
||||
<cfreturn request.plain2htm(request.cleanHtm(s))/>
|
||||
</cffunction>
|
||||
|
||||
<cffunction name="cleanInput">
|
||||
<cfargument name="s" type="string"/>
|
||||
<cfreturn htmlEditFormat(s)/>
|
||||
</cffunction>
|
||||
|
||||
<m:prepare_detail entity="contract" accessObject="" key="contract_uid" pageInfoOut="pageInfo"/>
|
||||
|
||||
<d:bean readonly=true table="elma.aggrements" datasource="#request.DS#" output="d" status="status">
|
||||
<d:param field="__id" type="uuid" key/>
|
||||
<d:param field="__name" type="varchar" size="255" preprocessor=#cleanInput# forNull=""/>
|
||||
<d:param field="company_uid" type="uuid"/>
|
||||
<d:param field="date_of_aggrement" type="timestamp"/>
|
||||
<d:param field="date_end_aggrement" type="timestamp"/>
|
||||
</d:bean>
|
||||
|
||||
|
||||
<m:dispatch_detail
|
||||
usePRG="No"<!---*** --->
|
||||
pageInfo=#pageInfo#
|
||||
id="#d.__id#"
|
||||
status=#pageInfo.status#
|
||||
trackOut="tr"
|
||||
idAttributesOut="id"
|
||||
/>
|
||||
|
||||
<!--- decoration --->
|
||||
<cfquery name="qDecoration" datasource="#request.DS#">
|
||||
select
|
||||
__name as contragent
|
||||
from elma.companies k
|
||||
where k.__id=<cfqueryparam cfsqltype="cf_sql_other" value=#d.company_uid#/>
|
||||
</cfquery>
|
||||
|
||||
|
||||
</m:silent><!---
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
---><layout:page section="header" pageInfo=#pageInfo#>
|
||||
<layout:attribute name="title">
|
||||
<cfoutput>
|
||||
Договор
|
||||
<cfif len(d.__id)>
|
||||
<b>#d.__name#</b>
|
||||
[#d.__id#]
|
||||
</cfif>
|
||||
</cfoutput>
|
||||
</layout:attribute>
|
||||
</layout:page>
|
||||
|
||||
<!--- <cfif status.errorState GT 0>
|
||||
<cfoutput><div class="err">#status.errorMessage#</div></cfoutput>
|
||||
</cfif>
|
||||
--->
|
||||
<cfoutput>
|
||||
<input type="hidden" name="__id" value="#d.__id#"/>
|
||||
<input type="hidden" name="track" value="#tr.self#"/>
|
||||
<input type="hidden" name="pass" value=""/><!--- pass marker to prevent save on submit --->
|
||||
|
||||
<div class="detail">
|
||||
|
||||
<div class="tr">
|
||||
<div class="th">__id</div>
|
||||
<div class="td">#d.__id#</div>
|
||||
</div>
|
||||
|
||||
<div class="tr">
|
||||
<div class="th">Номер договора</div>
|
||||
<div class="td">#d.__name#</div>
|
||||
</div>
|
||||
|
||||
<div class="tr">
|
||||
<div class="th">Контрагент</div>
|
||||
<div class="td">#qDecoration.contragent# [#d.company_uid#]</div>
|
||||
</div>
|
||||
|
||||
<div class="tr">
|
||||
<div class="th">Дата договора</div>
|
||||
<div class="td">#d.date_of_aggrement#</div>
|
||||
</div>
|
||||
|
||||
<div class="tr">
|
||||
<div class="th">Дата окончания договора</div>
|
||||
<div class="td">#d.date_end_aggrement#</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</cfoutput>
|
||||
<!---
|
||||
<layout:page section="extension" closeForm="Yes"/>
|
||||
|
||||
<cfif d.contragent_id GT 0>
|
||||
<cfquery name="qContract">
|
||||
select
|
||||
d.contract_id
|
||||
,d.contract
|
||||
,d.dt_contract
|
||||
,(select count(*) from specification s where s.contract_id=d.contract_id) as spec_cnt
|
||||
from contract d
|
||||
where d.contragent_id=<cfqueryparam cfsqltype="cf_sql_integer" value="#d.contragent_id#"/>
|
||||
order by 1
|
||||
</cfquery>
|
||||
|
||||
<cfoutput>
|
||||
<h4>Договоры (#qContract.recordCount#)</h4>
|
||||
</cfoutput>
|
||||
|
||||
<table class="worktable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><c:link_add canWrite=#pageInfo.writePermitted()# entity="contract" id="#contragent_id#" extra="contragent_id=#d.contragent_id#" fwx=#tr.fwx#/></th>
|
||||
<th>Номер договора</th>
|
||||
<th>Дата договора</th>
|
||||
<th>Спецификаций</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<cfoutput query="qContract">
|
||||
<tr>
|
||||
<td>
|
||||
<c:link_view_edit canWrite=#pageInfo.writePermitted()# entity="contract" id=#contract_id# fwx=#tr.fwx#/>
|
||||
</td>
|
||||
<td>#contract#</td>
|
||||
<td class="c">
|
||||
#dateFormat(dt_contract,'YYYY-MM-DD')#
|
||||
</td>
|
||||
<td class="c">
|
||||
<cfif spec_cnt GT 0>#spec_cnt#</cfif>
|
||||
|
||||
</td>
|
||||
<td class="c">
|
||||
<c:link_del canWrite=#pageInfo.writePermitted()# entity="contract" id=#contract_id# fwx=#tr.fwx#/>
|
||||
</td>
|
||||
</tr>
|
||||
</cfoutput>
|
||||
</table>
|
||||
</cfif> --->
|
||||
|
||||
|
||||
<layout:page section="footer"/>
|
||||
@@ -0,0 +1,175 @@
|
||||
<cfsilent>
|
||||
<cfimport prefix="m" taglib="lib"/>
|
||||
<cfimport prefix="c" taglib="lib/controls"/>
|
||||
<cfimport prefix="d" taglib="lib/data"/>
|
||||
<cfimport prefix="layout" taglib="layout"/>
|
||||
</cfsilent><m:silent silent="No">
|
||||
|
||||
<cffunction name="plain2HtmClean">
|
||||
<cfargument name="s" type="string"/>
|
||||
<cfreturn request.plain2htm(request.cleanHtm(s))/>
|
||||
</cffunction>
|
||||
|
||||
<cffunction name="cleanInput">
|
||||
<cfargument name="s" type="string"/>
|
||||
<cfreturn htmlEditFormat(s)/>
|
||||
</cffunction>
|
||||
|
||||
<m:prepare_detail entity="contragent" accessObject="" key="contragent_id" pageInfoOut="pageInfo"/>
|
||||
|
||||
<d:bean readonly=true table="elma.companies" datasource="#request.DS#" output="d" status="status">
|
||||
<d:param field="__id" type="uuid" key/>
|
||||
<d:param field="__name" type="varchar" size="255" preprocessor=#cleanInput# forNull=""/>
|
||||
<d:param field="_inn" type="varchar" size="255" preprocessor=#cleanInput# forNull=""/>
|
||||
<d:param field="_kpp" type="varchar" size="255" preprocessor=#cleanInput# forNull=""/>
|
||||
<d:param field="id_klienta" type="varchar" size="255" preprocessor=#cleanInput# forNull=""/>
|
||||
<!--- *** билдер показывает... <d:param field="wz_id" type="varchar" size="255" preprocessor=#cleanInput# forNull=""/> --->
|
||||
<!--- <d:param field="code_inn" type="varchar" size="255" preprocessor=#cleanInput# forNull=""/>
|
||||
<d:param field="code_kpp" type="varchar" size="255" preprocessor=#cleanInput# forNull=""/> --->
|
||||
</d:bean>
|
||||
|
||||
|
||||
<m:dispatch_detail
|
||||
usePRG="No"<!---*** --->
|
||||
pageInfo=#pageInfo#
|
||||
id="#d.__id#"
|
||||
status=#pageInfo.status#
|
||||
trackOut="tr"
|
||||
idAttributesOut="id"
|
||||
/>
|
||||
|
||||
<!--- decoration --->
|
||||
<!--- <cfquery name="qDecoration" datasource="#request.DS#">
|
||||
select
|
||||
a.login as creator, a.shortname as creator_shortname, m.login as updater, m.shortname as updater_shortname
|
||||
from contragent g
|
||||
left outer join usr a on (g.creator_id=a.usr_id)
|
||||
left outer join usr m on (g.updater_id=m.usr_id)
|
||||
where g.contragent_id=<cfqueryparam attributeCollection=#id#/>
|
||||
</cfquery> --->
|
||||
|
||||
|
||||
</m:silent><!---
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
------------------------------------------------------------------------------------------------------------------------
|
||||
---><layout:page section="header" pageInfo=#pageInfo#>
|
||||
<layout:attribute name="title">
|
||||
<cfoutput>
|
||||
Контрагент
|
||||
<cfif len(d.__id)>
|
||||
<b>#d.__name#</b>
|
||||
[#d.__id#]
|
||||
</cfif>
|
||||
</cfoutput>
|
||||
</layout:attribute>
|
||||
</layout:page>
|
||||
|
||||
<!--- <cfif status.errorState GT 0>
|
||||
<cfoutput><div class="err">#status.errorMessage#</div></cfoutput>
|
||||
</cfif>
|
||||
--->
|
||||
<cfoutput>
|
||||
<input type="hidden" name="__id" value="#d.__id#"/>
|
||||
<input type="hidden" name="track" value="#tr.self#"/>
|
||||
<input type="hidden" name="pass" value=""/><!--- pass marker to prevent save on submit --->
|
||||
|
||||
<div class="detail">
|
||||
|
||||
<div class="tr">
|
||||
<div class="th">__id</div>
|
||||
<div class="td">#d.__id#</div>
|
||||
</div>
|
||||
|
||||
<div class="tr">
|
||||
<div class="th">__name</div>
|
||||
<div class="td">#d.__name#</div>
|
||||
</div>
|
||||
|
||||
<div class="tr">
|
||||
<div class="th">_inn</div>
|
||||
<div class="td">#d._inn#</div>
|
||||
</div>
|
||||
|
||||
<div class="tr">
|
||||
<div class="th">_kpp</div>
|
||||
<div class="td">#d._kpp#</div>
|
||||
</div>
|
||||
|
||||
<div class="tr">
|
||||
<div class="th">id_klienta</div>
|
||||
<div class="td">#d.id_klienta#</div>
|
||||
</div>
|
||||
|
||||
<!--- <div class="tr">
|
||||
<div class="th">wz_id</div>
|
||||
<div class="td">#d.wz_id#"/></div>
|
||||
</div> --->
|
||||
|
||||
<!--- <div class="tr">
|
||||
<div class="th">code_inn</div>
|
||||
<div class="td">#d.code_inn#"/></div>
|
||||
</div>
|
||||
|
||||
<div class="tr">
|
||||
<div class="th">code_kpp</div>
|
||||
<div class="td">#d.code_kpp#"/></div>
|
||||
</div> --->
|
||||
|
||||
</div>
|
||||
|
||||
</cfoutput>
|
||||
<!---
|
||||
<layout:page section="extension" closeForm="Yes"/>
|
||||
|
||||
<cfif d.contragent_id GT 0>
|
||||
<cfquery name="qContract">
|
||||
select
|
||||
d.contract_id
|
||||
,d.contract
|
||||
,d.dt_contract
|
||||
,(select count(*) from specification s where s.contract_id=d.contract_id) as spec_cnt
|
||||
from contract d
|
||||
where d.contragent_id=<cfqueryparam cfsqltype="cf_sql_integer" value="#d.contragent_id#"/>
|
||||
order by 1
|
||||
</cfquery>
|
||||
|
||||
<cfoutput>
|
||||
<h4>Договоры (#qContract.recordCount#)</h4>
|
||||
</cfoutput>
|
||||
|
||||
<table class="worktable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><c:link_add canWrite=#pageInfo.writePermitted()# entity="contract" id="#contragent_id#" extra="contragent_id=#d.contragent_id#" fwx=#tr.fwx#/></th>
|
||||
<th>Номер договора</th>
|
||||
<th>Дата договора</th>
|
||||
<th>Спецификаций</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<cfoutput query="qContract">
|
||||
<tr>
|
||||
<td>
|
||||
<c:link_view_edit canWrite=#pageInfo.writePermitted()# entity="contract" id=#contract_id# fwx=#tr.fwx#/>
|
||||
</td>
|
||||
<td>#contract#</td>
|
||||
<td class="c">
|
||||
#dateFormat(dt_contract,'YYYY-MM-DD')#
|
||||
</td>
|
||||
<td class="c">
|
||||
<cfif spec_cnt GT 0>#spec_cnt#</cfif>
|
||||
|
||||
</td>
|
||||
<td class="c">
|
||||
<c:link_del canWrite=#pageInfo.writePermitted()# entity="contract" id=#contract_id# fwx=#tr.fwx#/>
|
||||
</td>
|
||||
</tr>
|
||||
</cfoutput>
|
||||
</table>
|
||||
</cfif> --->
|
||||
|
||||
|
||||
<layout:page section="footer"/>
|
||||
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 6.1 KiB |
@@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Creator: CorelDRAW X8 -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="78.6273mm" height="70.4009mm" version="1.1" style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd"
|
||||
viewBox="0 0 37746 33797"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs>
|
||||
<style type="text/css">
|
||||
<![CDATA[
|
||||
.fil3 {fill:none}
|
||||
.fil2 {fill:#D7F372}
|
||||
.fil4 {fill:#FEFEFE;fill-rule:nonzero}
|
||||
.fil5 {fill:#638328;fill-rule:nonzero}
|
||||
.fil1 {fill:url(#id1)}
|
||||
.fil0 {fill:url(#id2)}
|
||||
]]>
|
||||
</style>
|
||||
<clipPath id="id0">
|
||||
<path d="M20432 0c8718,-38 15581,2266 15458,9209 -25,787 -197,745 -1206,434 -5376,-1662 -8578,-3016 -12410,-6248 -1067,-900 -1945,-1797 -2743,-2837 -478,-648 -8,-545 901,-558zm-18416 19428c1785,-4186 2803,-6725 6956,-9214 1814,-1088 3728,-1795 5744,-2401 5011,-1469 9917,-953 14495,540 1697,562 2833,1208 4123,2158 602,450 989,178 1872,-71 402,-113 1572,-529 1912,-305 933,615 -675,1120 -1291,1389 -1798,785 -1256,251 -1265,1780 -43,7030 -7302,11174 -13250,12374 -3409,688 -7029,1146 -9343,1499 -5916,900 -5060,-1185 -9071,-2819 -937,-381 -2531,-341 -2879,-1361 -223,-655 1540,-2751 1997,-3569z"/>
|
||||
</clipPath>
|
||||
<linearGradient id="id1" gradientUnits="userSpaceOnUse" x1="-740.954" y1="15224.8" x2="37478.6" y2="11458.4">
|
||||
<stop offset="0" style="stop-opacity:1; stop-color:#C6C517"/>
|
||||
<stop offset="1" style="stop-opacity:1; stop-color:#E7D900"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="id2" gradientUnits="userSpaceOnUse" x1="-442.19" y1="20004.6" x2="37830.6" y2="16055.8">
|
||||
<stop offset="0" style="stop-opacity:1; stop-color:#89A423"/>
|
||||
<stop offset="1" style="stop-opacity:1; stop-color:#638429"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Layer_x0020_1">
|
||||
<metadata id="CorelCorpID_0Corel-Layer"/>
|
||||
<path class="fil0" d="M22767 31689l-14060 2085c-2226,330 -4572,-2956 -6349,-3695 -1559,-649 -1653,-822 -1915,-2004 -266,-1196 -259,-3137 -401,-4460 -150,-1391 203,-1130 973,-2123 591,-795 964,-1292 1359,-2228 1413,-3396 2313,-5352 5285,-7695 3781,-2753 8236,-4067 12877,-4299 774,-89 484,-275 112,-747 -812,-1079 -1165,-2747 -1381,-4068 -68,-416 -308,-2197 198,-2372 228,-79 1093,72 1388,100 101,9 200,16 301,22 1094,51 2280,-41 2615,-17 4852,417 10503,1550 11899,7016 226,935 209,1325 200,2255 -2,142 -8,1026 126,1086 215,97 947,-1057 1467,133 110,344 145,764 169,1126 8,120 17,237 29,356 91,880 115,1755 53,2638 -23,319 -23,817 -223,1077 -611,795 -1576,1292 -2268,2065 -435,506 -635,1974 -834,2703 -720,2633 -1869,4361 -3594,4590l-7936 1054 -90 5402z"/>
|
||||
<path class="fil1" d="M20432 0c8718,-38 15581,2266 15458,9209 -25,787 -197,745 -1206,434 -5376,-1662 -8578,-3016 -12410,-6248 -1067,-900 -1945,-1797 -2743,-2837 -478,-648 -8,-545 901,-558zm-18416 19428c1785,-4186 2803,-6725 6956,-9214 1814,-1088 3728,-1795 5744,-2401 5011,-1469 9917,-953 14495,540 1697,562 2833,1208 4123,2158 602,450 989,178 1872,-71 402,-113 1572,-529 1912,-305 933,615 -675,1120 -1291,1389 -1798,785 -1256,251 -1265,1780 -43,7030 -7302,11174 -13250,12374 -3409,688 -7029,1146 -9343,1499 -5916,900 -5060,-1185 -9071,-2819 -937,-381 -2531,-341 -2879,-1361 -223,-655 1540,-2751 1997,-3569z"/>
|
||||
<g style="clip-path:url(#id0)">
|
||||
<g id="_3107826610240">
|
||||
<path id="1" class="fil2" d="M32620 15645c91,-46 98,-37 3,-91 -66,80 -20,59 -3,91zm-9180 173l399 13 94 3 24 -102c121,-34 39,27 76,-81l-104 -24c-76,-2 -129,-55 -130,-59 -3,-10 -11,-11 -18,-15l-68 -4c-94,14 -151,38 -213,69l-167 12 -8 120 12 65 103 3zm3362 -16369c31,57 -35,35 43,50 123,23 4,11 64,-18 -27,-64 39,-43 -41,-56 -131,-22 -7,-12 -66,24zm10290 3584c-14,-80 10,-36 -56,-77 -2,4 -94,5 -19,84 51,53 74,-7 75,-7zm2277 11808c100,-46 108,-71 4,-122 -65,81 -40,56 -4,122zm-598 -13384c72,-96 70,-72 -25,-113 -75,90 -74,70 25,113zm-486 7658c-47,-62 -81,7 -83,7 65,99 -66,22 64,80 3,-6 100,22 19,-87zm-14361 -9918c35,-131 44,-89 -39,-138 -4,7 -53,-26 -31,67 27,121 -23,26 70,71zm13953 15010c7,-87 -6,-35 -58,-63 -74,84 -46,57 -4,129 45,-22 53,54 62,-66zm1320 -15163c106,-113 26,-91 4,-126 -51,29 -67,-45 -62,71 4,73 20,40 58,55zm2646 15025c-2,-2 9,-68 -88,-57 -109,12 -37,7 -73,64 105,50 64,60 161,-7zm-292 -3726c48,-52 47,-33 49,-171 -84,-2 -93,-38 -195,78 -83,11 -33,-18 -92,47l115 91c47,-29 48,-35 123,-45zm-2986 3302c-113,22 -40,12 -65,57 182,135 184,-23 184,-24 -10,-6 19,-60 -119,-33zm-1300 1033c-76,-44 -26,-43 -193,-4 18,157 33,163 111,169 166,12 14,18 79,-36l3 -129zm-28 818c-15,-28 43,-120 -226,-46 35,72 -28,65 93,92 164,37 124,-39 133,-46zm-7887 -16516l182 4c21,-158 -15,-177 -161,-176l-21 172zm1556 1675l148 114c99,86 124,57 174,-16 -50,-145 -12,-36 -146,-105 -44,-243 65,-253 -76,-325 -82,93 -25,15 -43,187 -15,145 -10,6 -57,145zm-16717 6826c58,-32 47,42 53,-46 7,-83 4,-30 -50,-59l-24 38c3,61 -11,24 21,67zm-1336 -2651c25,-6 44,9 63,-22 77,-123 10,-42 -8,-80 -80,40 -47,5 -55,102zm-4579 -6954l-112 -3 26 95c101,-38 42,50 86,-92zm7494 3833c33,-24 94,21 33,-122 -79,33 -49,-52 -62,48 -20,150 -16,19 29,74zm14390 12465c-110,-30 -18,-3 -62,20 24,35 -18,154 116,33 -22,-35 -5,-40 -54,-53zm-16336 1107c44,-72 -19,-62 -22,-69 -108,42 -55,-27 -72,102 120,-4 51,36 94,-33zm-15555 -8727c0,-1 54,27 19,-104 -41,1 -53,-32 -83,34 -36,76 49,66 64,70zm29578 -7130c115,91 90,22 123,-26 -55,-41 62,-61 -72,-36 -85,16 -30,37 -51,62zm-15613 10133c8,-12 163,46 3,-107 -158,125 -4,106 -3,107zm19829 6238c-113,-3 -59,-5 -148,25 75,104 35,82 146,96l2 -121zm-1810 -750c-9,127 22,73 56,93 13,-18 98,-37 6,-177 -40,23 -55,-4 -62,84zm-22909 -1701c110,-49 103,-21 88,-170l-170 17 -8 103 29 61 61 -11zm17260 -7459c57,-32 46,52 67,-70 25,-145 -10,-61 -33,-93 -62,23 -49,-63 -69,61 -24,151 20,79 35,102zm6292 8218c-86,10 -54,14 -87,55 20,17 25,52 112,48 130,-7 69,-26 89,-71 -34,-23 -5,-44 -114,-32zm-18726 -12582l138 126c48,-78 33,-47 37,-156 -115,-27 -88,-44 -175,30zm5425 2089c112,8 43,39 121,-26l69 -111c-57,-38 50,-12 -63,-36 -108,-23 -8,-17 -111,3l-16 170zm199 -5155c68,-15 102,32 91,-91 -10,-106 -55,-86 -91,-103 -91,200 -13,173 0,194zm-4498 9344c44,-116 -2,-63 -8,-78 -188,-98 -154,47 -70,159 12,-9 44,9 78,-81zm-14595 -8298l-37 -85 -225 -25c13,84 -5,39 37,90 11,13 11,8 29,27 101,111 -29,62 100,79 134,17 77,-16 96,-28l0 -58zm16516 14224c-51,-40 -1,-28 -113,-50 -41,-8 -243,-20 -290,67 61,129 108,18 237,86 55,29 -10,50 104,69 198,32 132,-42 146,-52 -49,-181 23,-57 -89,-111l5 -9zm-15097 58c48,-69 44,-72 16,-145 -273,51 -22,42 -250,167 31,-165 -35,-99 -48,-114l-10 228 209 8 83 -144zm10508 -4775c26,-191 49,60 -34,-54 -80,69 -76,58 -4,123 52,-55 25,22 38,-69zm2333 -7579c33,-5 125,10 56,-109 -99,52 -45,-60 -56,109zm-3430 -2611c31,53 -29,36 45,50 112,21 9,9 62,-17 -23,-52 62,-39 -40,-56 -76,-13 -10,-11 -67,23zm-5194 1548c20,-171 28,-57 -48,-102 -23,40 -71,-39 -25,67 24,53 -2,25 73,35zm2622 14176c16,-129 5,-16 -32,-67 -96,48 -105,68 -4,128 34,-41 21,52 36,-61zm20631 -662c17,-119 -2,-25 -34,-66 -97,47 -110,67 -4,121 35,-34 24,49 38,-55zm-26456 -15122c101,69 78,57 133,-25 -30,-22 47,-55 -72,-37 -124,19 -29,27 -61,62zm-3047 11843c12,19 -43,82 103,51 57,-13 47,-31 63,-80 -75,-40 -83,-41 -168,-21l2 50zm590 1476c-68,85 -67,86 -5,161 100,-47 96,-110 5,-161zm9676 2249c132,-45 120,-6 96,-144 -185,-46 -50,-16 -91,31 11,22 4,32 23,36 49,12 16,9 52,-9 -39,-41 -1,-18 -75,-27 -8,6 -42,26 -44,28 -15,11 -32,39 -36,33 -3,-7 -12,13 -19,19l7 24c-83,-5 -17,-34 -119,21l-151 150c-7,14 -26,96 -30,118 184,-1 47,-2 195,-98 58,-38 107,-51 184,-77l17 -88 -9 -17zm-10949 -16354c55,-82 68,-123 -24,-178 -4,5 -49,-31 -45,89 4,131 35,74 69,89zm5381 2060c95,56 114,57 192,-23 -73,-75 -188,-91 -192,23zm4150 14183c1,-1 64,-22 50,-106 -19,-117 0,-36 -73,-72 -30,39 -121,103 23,178zm17483 -2004c-59,-80 -103,-72 -188,-35 18,24 -70,68 84,81 141,12 94,-39 104,-46zm-13680 -1675c141,42 169,46 247,-29 -37,-39 -45,-69 -145,-59 -99,10 -73,22 -102,88zm-8064 1221l-36 23c-90,81 -54,49 -56,120 261,25 188,-170 188,-171 -115,-7 34,-13 -60,2l-36 26c7,17 -3,42 39,48 3,1 16,-4 19,-4 5,0 15,-7 23,-10 -39,-35 6,-19 -81,-34zm8633 -1952c-7,-10 54,-79 -137,-26 9,87 13,131 90,196 33,-28 19,-1 55,-52 24,-33 -22,88 23,-39 49,-141 4,-71 -31,-79l-78 -1 25 81 53 -80zm-7088 2769c-11,-74 -88,-139 -148,-163l-43 119 162 129c15,-21 48,44 29,-85zm-7692 303l-2 61 261 28c11,-216 -161,-128 -259,-89zm39584 -10253c14,28 -26,64 65,64 135,1 27,20 78,-60 -44,-33 11,-44 -75,-39 -129,8 -18,-2 -68,35zm419 750c28,-36 34,52 41,-69 10,-164 -9,-60 -36,-101 -30,17 -56,-27 -71,73 -20,138 30,78 66,97zm3066 2473c55,-72 68,-95 66,-198 -92,-19 -136,-38 -155,50 -18,87 89,148 89,148zm2396 -3620c57,42 -52,30 106,49 159,20 20,7 113,-14 -22,-95 28,-126 -112,-132 -102,-5 -86,13 -107,97zm-718 4372l-51 -56c213,-116 92,-238 -70,-239 -152,-1 -176,38 -165,195l14 39c15,128 95,141 227,140l45 -79zm-11882 -7680c96,59 33,27 76,3l-58 -18c-3,-8 -12,11 -18,15zm-21198 15445c35,43 20,47 60,29 5,-2 14,-15 22,-22l-82 -7zm5007 1132l97 3 -6 -58c-40,-60 5,-36 -76,-65 -35,-12 -55,0 -88,1l5 117 68 2zm19326 -14421l-61 0c-35,54 -28,-70 -32,67 -4,136 11,60 30,93 73,-19 31,14 65,-50 146,-35 47,16 96,-68 -57,-55 15,-32 -98,-42zm-8429 13335c39,-6 206,-169 -164,-173 -70,95 -80,76 -102,170l266 3zm14571 -9261c47,74 57,123 127,4 -116,-124 -105,-20 -127,-4zm909 -1194c55,84 170,131 199,-23 -26,-14 -10,-39 -115,-26 -57,8 -60,10 -84,49zm271 2163c-1,-1 34,-56 -85,-37 -107,17 -28,-8 -84,61 38,68 -52,70 107,81 68,5 70,-17 106,-46 -12,-97 2,-33 -44,-59l-117 15 83 62c43,-50 20,-9 34,-77zm2227 -30c105,19 81,28 165,-11 -16,-86 -60,-131 -144,-155 -48,81 -43,60 -21,166zm-680 -1938c36,-37 13,13 35,-54 59,-184 69,-195 19,-219 -7,-2 -19,-13 -22,-4 -3,7 -75,-30 -95,109 -15,102 -6,135 63,168zm-7887 -1031c174,9 174,-15 198,-181l-195 0 -3 181zm-434 -3677c0,-132 -97,-207 -219,-204 -14,163 61,224 219,204zm9067 10670l-228 -20c15,143 32,200 191,182 20,-35 15,-15 29,-68 0,-1 7,-80 8,-94zm-11458 -8654l180 15c41,-77 53,-78 67,-187l-240 -2 -7 174zm-13484 -1787c67,65 -100,40 38,31 70,-5 24,3 66,-28 -77,-64 98,-40 -43,-30 -87,6 4,-25 -61,27zm15318 6420c8,8 -37,96 94,3 -76,-59 111,-37 -40,-27 -71,5 -10,-11 -54,24zm-4361 -5494c0,-176 44,-57 -80,-98 19,109 -24,65 80,98zm5777 11913c-52,-67 -18,-71 -104,-32 75,108 -101,-50 19,46 3,3 11,10 15,12 122,59 35,-5 70,-26zm452 -9192c-16,-105 17,-46 -64,-89 -51,58 -31,28 -37,112l0 24c139,141 57,117 171,135l19 -142 -89 -40zm1300 -184c26,36 -55,67 176,58 3,-16 70,-189 -107,-115 -68,28 -31,-2 -69,57zm-6645 5321c35,-145 -23,-89 -32,-106 -123,17 -84,-60 -108,72 -22,127 47,87 73,100 61,-30 38,56 67,-66zm12539 -5533c161,1 121,36 140,-122 -54,-35 -31,-46 -160,-30 -8,73 -19,77 20,152zm-7898 4642l158 -3 13 -151 -160 -4 -11 158zm-17042 -7038c56,111 45,115 104,4 -52,-38 -53,-32 -104,-4zm9439 14921c154,-74 34,-104 32,-108 -148,63 -33,108 -32,108zm-15492 -14617c77,-131 38,-84 -75,-106 31,146 -22,74 75,106zm2595 5412c115,-55 112,-64 4,-122 -16,20 -39,-42 -33,60 3,61 1,30 29,62zm3716 -5475c14,118 -32,80 92,86 38,-95 6,-127 -92,-86zm-11754 7101c6,-101 5,-86 -98,-105 -13,127 -2,118 98,105zm5801 -8233c54,-27 68,45 62,-68 -3,-75 -27,-45 -58,-61 -2,3 -85,14 -4,129zm-10835 7881c-39,-69 -44,-121 -135,-4 60,52 -67,23 67,40 113,15 27,-3 68,-36zm25397 -740c-39,10 -173,13 -98,95 96,105 86,-47 98,-95zm-2065 8351c-44,-72 23,-10 -75,-89 -65,-51 0,-9 -75,-42l-42 107 31 161c92,9 87,6 142,-32l19 -105zm-14954 -14214c87,52 55,48 150,6 -45,-139 -121,-139 -150,-6zm2674 8592c-160,2 -83,47 -93,81l164 16c3,-66 28,-97 -71,-97zm-12857 -11651c60,116 145,73 198,6 -88,-66 -119,-55 -198,-6zm14730 9603c8,31 -35,70 85,81 110,11 71,-14 85,-76 -83,-43 -68,-37 -170,-5zm-1945 -4959c-114,-51 -60,-57 -140,3l-4 58c93,64 166,73 228,-21 -41,-48 23,-26 -84,-40l-116 0c37,83 -28,35 83,68 54,-39 15,12 33,-68zm1791 10456c-76,-57 -141,-72 -205,22 16,13 16,57 118,48 109,-8 68,-30 87,-70zm6791 -1117c36,-46 36,70 46,-94 8,-128 -24,-68 -40,-87 -41,17 -64,-27 -71,84 -7,141 28,77 65,97zm-19845 -1831c156,4 126,-56 115,-191 -148,46 -119,6 -115,191zm28588 2560c110,14 138,-57 145,-166l-129 10c-85,158 -16,155 -16,156zm-24535 1960c-95,25 -67,45 -80,133 123,4 100,21 190,-35 -15,-82 23,-133 -110,-98zm-1340 -12555c34,-29 35,29 35,-82 -176,-85 -220,125 -198,245 233,90 139,21 170,-18l-9 -56 2 -89zm-138 10191c7,-3 15,-9 19,-11 187,-98 143,-30 160,-133 -81,-49 -97,-61 -235,49 -9,7 -14,11 -18,14l-10 -4 3 8c-6,4 -7,6 -36,40 48,43 -12,16 62,44 104,41 37,-1 55,-7zm8367 -12746l142 -3 17 -140c-107,-42 -56,-44 -174,-39 -39,107 -19,70 15,182zm13541 9864c19,-155 31,-118 -58,-202l-114 -68 -18 135c5,4 38,33 47,42 111,117 -30,57 143,93zm988 4753c45,-102 30,10 23,-135l-34 -127c-82,44 -10,4 -55,41l-47 40c-59,65 -45,-8 -44,128 63,55 64,54 157,53zm12225 -12623c69,-36 48,37 60,-51 11,-77 1,-29 -27,-74 -74,34 -47,-58 -61,47 -12,85 -16,23 28,78zm-541 532c79,-38 56,43 72,-73 18,-134 -33,-95 -37,-102 -62,28 -51,-64 -71,68 -26,164 18,78 36,107zm3249 -2408c42,-47 40,67 48,-70 9,-158 -18,-67 -43,-99 -62,25 -63,-61 -81,69 -20,138 47,86 76,100zm1303 9111c11,10 -39,54 99,53 166,-1 78,-27 103,-76 -9,-7 35,-50 -103,-50 -165,1 -70,41 -99,73zm-491 -3647c91,-9 105,-16 198,-88 -55,-161 -128,-160 -199,-171 8,167 44,104 1,259zm-24692 -3316c89,44 53,43 105,-26 -38,-27 54,-78 -66,-29 -4,1 -13,8 -16,10l-23 45zm13671 13200c-34,-129 31,-90 -104,-104 13,123 -20,66 104,104zm-2531 -392c-27,-46 15,-108 -118,-32 19,31 -50,43 47,68 133,33 20,3 71,-36zm7334 520c-76,-6 -56,36 -71,58 59,45 -67,20 67,36 129,15 17,4 69,-31 -26,-54 52,-54 -65,-63zm-2346 -1174c-22,-102 14,-11 -61,-51 -44,43 -78,-66 -39,94 19,78 18,22 64,42 41,-48 53,-4 36,-85zm-2672 1531c-126,3 -69,18 -100,66 34,27 41,99 222,7 -23,-40 -10,-76 -122,-73zm2389 -1391c-144,-10 -215,11 -139,175l166 10 -27 -185zm-13510 -6878c31,-55 21,-40 3,-86 -56,59 -65,-88 -32,42 34,130 -97,-14 29,44zm11036 7899c51,38 -7,20 62,28 135,17 -25,23 42,-24 -37,-35 4,-24 -62,-33 -161,-23 46,-43 -42,29zm-26597 -10879c62,73 10,58 96,32 -17,-44 72,-25 -23,-45 -72,-14 -23,-8 -73,13zm24877 10019c-13,-82 1,-14 -47,-36 -75,86 -26,63 26,92 24,-39 30,7 21,-56zm-13301 -13607c15,-24 58,33 23,-60 -25,-65 14,-8 -49,-43 -39,74 -63,63 26,103zm-1474 10770c72,-89 63,-70 -26,-109 -101,108 -21,86 26,109zm2490 -9768c5,-7 104,11 5,-148 -44,51 -53,-76 -44,73 6,81 4,33 39,75zm-455 582l45 -26c-21,-110 32,-69 -101,-93 -6,111 -40,72 56,119zm-2645 4875c5,-126 -3,-96 -98,-104 -11,117 -39,123 98,104zm-15387 -7335c18,35 -39,43 62,61 137,25 73,-13 98,-27 -5,-10 32,-155 -160,-34zm3775 14905c-5,113 34,83 37,87 96,-48 93,-123 5,-181 -22,29 -35,-53 -42,94zm16124 -7293c1,0 19,130 175,5 -14,-31 12,-58 -77,-63 -125,-7 -71,37 -98,58zm4169 4706c36,-17 59,39 73,-89 14,-124 -31,-78 -39,-88 -47,21 -58,-27 -69,83 -13,129 26,80 35,94zm-14149 1449c-78,-12 -84,28 -88,128l195 -3c-12,-79 -17,-110 -107,-125zm-10285 -377c144,13 156,25 270,-28 -59,-65 -141,-121 -249,-121l-21 149zm30877 -12750c85,40 49,47 105,-26 -20,-16 24,-117 -105,26zm-4545 -547c57,-82 74,-71 -25,-119 -65,93 -66,76 25,119zm6390 36c29,-122 42,-90 -84,-116 14,175 -38,71 84,116zm5154 2987c-1,45 -19,42 30,111 107,-34 39,71 81,-92 -1,-4 -13,-87 -13,-87 -16,-49 -13,-36 -31,-65 -83,37 -49,-29 -67,133zm-7078 -529c164,-26 122,59 107,-100 -108,-4 -71,-31 -107,100zm1289 -911c4,-125 47,-86 -67,-119 -93,100 -38,96 67,119zm2389 12606c-126,16 -58,-23 -117,61 78,102 120,95 117,-61zm-6679 -14484c93,-49 101,-26 33,-126 -50,15 -41,-45 -66,34 -45,140 4,62 33,92zm-6632 -463c15,26 -10,57 69,74 138,32 72,-15 95,-30 -35,-82 47,-48 -65,-68 -29,-6 -93,19 -99,24zm9162 3323c39,-11 64,56 82,-82 14,-103 -25,-89 -47,-113 -98,45 -81,123 -35,195zm11121 7323c77,-41 52,57 68,-98 6,-49 -11,-65 -20,-97 -60,22 -76,-44 -92,91 -17,134 36,91 44,104zm-6944 6433l64 2c35,-109 52,-107 -11,-201 -29,8 -65,-56 -82,91 -8,64 4,48 29,108zm-9851 -12707c33,-80 14,-192 -50,-252 -80,-76 -14,-26 -117,-47 51,222 26,39 90,163 44,86 -28,59 77,136zm17007 11129c-5,-4 -12,-10 -18,-14l-82 -58c-96,106 -9,225 150,201 10,-144 19,-76 -50,-129zm-14523 -7357l6 118 177 17 4 -157c-119,-17 -93,-25 -187,22zm1634 621c122,-10 52,43 137,-39 82,-80 30,-20 53,-141l-179 10 -11 170zm4069 -5651l169 46c4,-99 16,-85 -35,-146 -85,-102 -17,-50 -154,-73l20 173zm10176 12053c-10,-85 13,-6 -49,-52 -38,41 -37,-9 -30,69 9,97 -12,14 55,43 37,-56 37,58 24,-60zm-8682 -13172c37,61 -40,39 51,54 69,12 24,3 66,-21 -13,-32 49,-134 -117,-33zm2107 1274c32,-19 113,33 33,-122 -78,35 -50,-47 -63,48 -17,129 -11,23 30,74zm-2180 -3663l-108 -3c2,174 -2,49 42,106 98,-52 42,59 66,-103zm10237 6623c21,-30 58,43 35,-71 -21,-101 17,-22 -68,-66 -52,93 -66,71 33,137zm-4681 8279c36,-113 -28,-91 -30,-94 -79,34 -36,-30 -61,65 -8,29 10,72 15,95 50,-25 47,25 76,-66zm1712 -10475c91,-11 72,27 106,-40 54,-109 -37,-81 -62,-94l-37 44c-16,57 -18,8 -7,90zm-2158 653c14,19 -16,66 79,65 118,-2 32,5 75,-60 -18,-16 33,-129 -154,-5zm-9161 -4516c140,63 104,33 149,-46 -10,-8 40,-74 -77,-47 -186,44 -11,10 -72,93zm14791 10390c-148,-15 -74,13 -105,64 54,49 -82,47 102,53 102,4 98,-46 99,-47 -19,-29 7,-60 -96,-70zm-7396 -6688c36,71 -84,46 67,61 7,-6 18,-26 21,-20l74 -89c49,-90 34,-58 -1,-120 -66,20 -27,3 -73,42 -4,4 -10,10 -14,14 -4,4 -10,10 -14,14 -5,5 -12,11 -16,16l-35 33 -9 49zm3325 -2979c18,41 -50,73 94,76 129,2 71,-21 95,-70 -6,-6 38,-52 -90,-53 -164,-1 -55,12 -99,47zm-4326 1161l115 0c21,-126 29,-84 -30,-190 -116,49 -118,87 -85,190zm5264 1728c3,-4 48,17 51,-93 3,-169 -3,-47 -45,-100 -39,16 -76,-51 -89,107 -7,77 16,64 83,86zm3737 8908c127,-174 17,-185 6,-201 -65,17 -98,-21 -96,100 3,114 51,86 90,101zm-578 -7651c-69,-84 28,-32 -83,-63 -47,-14 -89,-4 -137,1 12,162 117,193 220,62zm-10792 -2729c100,-7 112,56 202,-184l-175 3 -27 181zm11216 4612c69,-72 57,-54 46,-178l-200 -7c-4,7 -10,9 -11,18l-76 95c135,22 67,-7 160,87l81 -15zm-25274 1701c77,60 7,56 87,3 -48,-47 101,-40 -34,-29 -73,6 -3,-17 -53,26zm-2320 -4177c8,14 14,124 93,3 -55,-40 95,-28 -36,-22 -55,3 -22,-1 -57,19zm3531 6166c27,41 -51,47 54,45 61,-2 16,-6 40,-42 -34,-25 -1,-17 -55,-23 -3,0 -17,14 -19,7 -3,-7 -13,9 -20,13zm9742 -9188c141,-30 64,23 96,-75 -192,-10 -27,10 -96,75zm-816 7909c14,-101 12,5 -30,-35 -126,99 -4,94 -3,96 46,-55 21,17 33,-61zm4718 4713c-57,112 -6,23 20,71 19,-13 146,-53 23,-91 -70,-21 -30,-5 -43,20zm-8122 -431c-16,-86 16,-10 -58,-43 -83,124 13,93 34,107 35,-58 47,63 24,-64zm17489 -3007c175,99 121,19 148,5 -163,-141 -131,-17 -148,-5zm-22342 4930c132,-4 153,38 191,-77l-183 -33c-126,37 -56,-3 -107,63 48,51 -83,44 99,47zm12980 -12068c-5,14 -15,15 -16,31 -2,16 -12,19 -13,27 -6,30 -6,60 -4,92l176 14 5 -153 -148 -11zm3361 -432c36,-54 25,-37 3,-87 -60,72 -60,-95 -28,43 33,144 -77,-37 25,44zm-4106 70c11,-16 62,31 29,-65 -27,-79 22,-7 -54,-51 -28,44 -74,-63 -27,70 23,65 -11,17 52,46zm4107 -1014c84,-42 48,57 62,-54 19,-151 13,-10 -29,-78 -90,38 -52,-66 -66,48 -12,105 -22,20 33,84zm5309 -1291c25,-37 79,60 36,-83 -31,-104 27,-9 -60,-59 -32,47 -83,-71 -36,83 27,91 -22,17 60,59zm1248 6583c63,-42 37,35 61,-54 36,-132 -10,-66 -27,-91 -56,21 -39,-53 -66,42 -50,177 2,67 32,103zm-3412 -2551c58,-28 78,64 72,-75 -4,-112 -22,-47 -68,-70 0,1 -117,-7 -4,145zm-290 -1225c21,58 -53,43 42,70 192,56 47,8 103,-36 -35,-66 28,-44 -52,-65 -126,-33 -82,23 -93,31zm-5356 -3095l-18 46c15,128 58,97 106,82 112,-34 73,-59 86,-77 -19,-13 -52,-43 -84,-53l-90 2zm8115 7257c60,-74 70,111 51,-115 -8,-93 -53,-79 -74,-92 -6,7 -48,-10 -51,93 -7,206 -25,60 74,114zm-358 -3417c71,-45 53,62 74,-83 25,-183 -18,-80 -39,-116 -80,37 -60,-87 -83,79 -26,191 22,83 48,120zm-17157 14c84,70 -122,41 42,30 72,-5 22,6 65,-27 -62,-52 99,-38 -41,-29 -76,5 -12,-10 -66,26zm5328 -1528c64,-38 48,39 53,-51 7,-103 14,-24 -49,-60 -33,49 -32,66 -4,111zm-27615 8986c78,-37 55,63 54,-88 -92,2 -45,-22 -73,27 -47,84 8,41 19,61zm32764 3684c-10,-69 1,-14 -45,-37 -107,108 -16,75 26,101 17,-36 27,-9 19,-64zm-6438 -13319c1,0 47,9 52,-34 12,-113 25,-18 -49,-67 -15,24 -88,9 -3,101zm-2549 -1315c-17,8 -170,44 -28,87 58,17 34,0 42,-20 45,-117 9,-15 -14,-67zm4500 3122c50,-16 41,47 55,-34 13,-73 3,-24 -22,-71 -54,37 -107,11 -33,105zm100 11390c59,41 -62,18 67,32 141,16 7,10 72,-28 -141,-125 -131,-11 -139,-4zm5906 333c26,-38 129,23 33,-116 -108,38 -98,26 -33,116zm-36586 -127c129,-18 2,10 67,-35 -65,-124 -157,-104 -185,26 57,9 59,18 118,9zm29127 1316c73,-30 40,-35 106,4 -33,22 14,19 -51,22 -116,5 -14,2 -55,-26zm-38 58l179 5 2 -117 -181 -1 0 113zm-23361 -15949c1,-1 61,10 45,-97 -16,-103 8,-32 -68,-78 -13,20 -65,-31 -41,104 21,124 2,35 64,71zm7079 11660c-101,8 -43,-8 -107,52 -56,54 -46,20 -62,107l176 18 -7 -177zm27110 -785c-83,-43 -52,-52 -103,26 49,34 -62,39 59,24 76,-9 15,3 44,-50zm-1211 -2487c86,-45 122,22 33,-115 -52,20 -45,-52 -59,40 -13,86 -25,15 26,75zm849 -5816c135,-10 77,32 107,-104 -166,22 -89,-39 -107,104zm-8045 -1393l59 -2c61,-97 37,-142 -53,-191 -5,7 -123,39 -6,193zm-12585 2344c3,-126 9,-31 -32,-70 -25,25 -18,13 -37,64l39 57 30 -51zm21445 8401c-173,28 -5,162 -5,162 17,-23 34,53 35,-88 2,-133 2,-16 -30,-74zm-7726 -10714c54,-16 48,46 60,-34 14,-86 9,-15 -27,-73 -49,31 -121,-28 -33,107zm2226 -437c29,-40 52,53 35,-69 -15,-105 -2,-34 -59,-73 -14,17 -58,-43 -43,72 17,126 -14,33 67,70zm-13381 14473c-108,-44 -32,2 -69,25 153,144 93,45 120,32 -37,-65 17,-30 -51,-57zm-16107 -2399c103,-46 70,-13 61,-117 -96,10 -54,-27 -90,34 -46,78 29,83 29,83zm6804 -10029c-8,-5 -18,-24 -24,-15l-95 -9c0,144 -25,145 119,124l0 -100c-90,37 -68,-13 -76,69 108,-5 13,38 76,-69zm-11048 7103c11,-112 26,21 -39,-41l8 93c60,-55 22,37 31,-52zm6 -5040c76,71 -99,41 38,30 70,-5 11,13 56,-27 -53,-44 90,-32 -36,-25 -65,4 -11,-8 -58,22zm701 2991c38,31 32,40 85,3 -102,-100 -85,-3 -85,-3zm38576 5668c152,93 87,13 102,3 -42,-43 17,-22 -57,-32l-45 29z"/>
|
||||
<path class="fil2" d="M22443 33531c91,-46 99,-37 3,-91 -65,80 -19,59 -3,91zm-9179 174l399 12 94 3 23 -102c121,-33 40,27 77,-81l-104 -24c-77,-2 -129,-55 -130,-59 -3,-10 -12,-11 -18,-15l-68 -4c-94,14 -152,38 -213,70l-167 11 -9 121 13 64 103 4zm3362 -16370c31,57 -35,35 43,50 123,23 4,11 64,-17 -27,-65 39,-44 -41,-57 -132,-21 -7,-12 -66,24zm10290 3584c-14,-80 9,-36 -56,-77 -3,4 -94,6 -19,84 51,53 74,-6 75,-7zm2277 11808c100,-46 108,-71 3,-122 -64,81 -39,56 -3,122zm-598 -13384c72,-96 69,-72 -26,-113 -75,90 -73,70 26,113zm-487 7658c-46,-62 -80,7 -82,7 65,99 -67,22 63,80 4,-5 100,22 19,-87zm-14360 -9918c34,-131 44,-88 -39,-138 -4,7 -53,-26 -32,67 28,121 -23,26 71,71zm13953 15010c6,-87 -6,-35 -58,-63 -75,84 -46,57 -4,130 44,-23 53,54 62,-67zm1319 -15162c106,-114 26,-92 4,-127 -51,29 -67,-45 -61,71 4,73 20,40 57,56zm2647 15024c-2,-2 8,-68 -88,-57 -109,12 -38,7 -73,64 105,50 64,60 161,-7zm-293 -3726c49,-51 48,-33 50,-171 -85,-2 -93,-38 -195,78 -83,12 -33,-18 -93,47l116 91c47,-29 48,-34 122,-45zm-2986 3302c-112,22 -39,12 -64,57 182,135 183,-23 184,-23 -10,-7 18,-61 -120,-34zm-1299 1033c-77,-44 -27,-43 -194,-4 19,157 34,164 112,169 166,12 14,18 78,-36l4 -129zm-29 818c-14,-28 44,-120 -225,-46 34,72 -28,65 93,92 164,37 124,-39 132,-46zm-7886 -16516l181 4c22,-158 -15,-177 -160,-176l-21 172zm1555 1675l149 114c98,86 124,57 174,-16 -50,-145 -13,-36 -146,-105 -44,-243 65,-253 -76,-325 -82,93 -26,15 -43,187 -15,145 -11,7 -58,145zm-16716 6826c57,-32 46,42 53,-46 6,-83 4,-30 -50,-59l-24 38c3,61 -12,24 21,67zm-1337 -2651c26,-6 45,9 64,-22 76,-123 9,-42 -9,-80 -79,40 -46,5 -55,102zm-4578 -6954l-112 -3 26 95c100,-38 42,50 86,-92zm7494 3833c33,-24 94,21 33,-122 -79,33 -50,-52 -63,48 -20,150 -15,19 30,74zm14390 12465c-111,-30 -19,-3 -63,20 25,35 -17,155 117,33 -23,-35 -5,-39 -54,-53zm-16337 1107c45,-72 -18,-62 -21,-68 -108,41 -55,-28 -72,101 119,-4 51,36 93,-33zm-15554 -8727c0,0 54,27 19,-104 -42,1 -53,-32 -84,34 -35,76 50,66 65,70zm29578 -7130c115,91 90,22 123,-26 -55,-41 62,-61 -72,-36 -85,16 -31,37 -51,62zm-15614 10133c9,-12 164,46 4,-107 -159,125 -4,106 -4,107zm19830 6238c-114,-3 -59,-5 -148,25 75,104 35,82 145,96l3 -121zm-1810 -750c-9,127 22,73 56,93 12,-18 98,-37 5,-177 -39,23 -54,-4 -61,84zm-22909 -1701c109,-48 103,-21 88,-170l-170 17 -8 103 28 61 62 -11zm17260 -7459c57,-31 46,52 67,-70 25,-145 -11,-61 -33,-93 -63,23 -49,-63 -69,61 -24,151 20,79 35,102zm6292 8218c-87,10 -54,14 -87,55 20,17 25,52 112,48 129,-7 69,-26 89,-70 -34,-24 -5,-45 -114,-33zm-18726 -12582l138 126c48,-78 33,-47 37,-155 -115,-28 -88,-44 -175,29zm5425 2089c111,8 43,39 121,-26l69 -111c-57,-37 50,-12 -63,-36 -108,-23 -9,-17 -111,3l-16 170zm198 -5155c69,-15 103,32 92,-91 -10,-106 -55,-86 -92,-103 -90,200 -13,173 0,194zm-4497 9344c43,-116 -3,-63 -8,-78 -188,-98 -155,47 -70,159 12,-9 44,9 78,-81zm-14595 -8298l-38 -84 -224 -26c12,84 -6,39 36,90 11,13 12,8 29,28 102,110 -28,62 101,78 134,18 76,-16 96,-27l0 -59zm16516 14224c-52,-40 -1,-28 -113,-50 -42,-8 -243,-19 -291,67 61,129 109,18 238,86 55,29 -10,50 104,69 197,32 132,-42 145,-52 -48,-181 24,-57 -88,-111l5 -9zm-15098 58c48,-69 45,-72 17,-145 -274,51 -23,42 -250,167 30,-165 -35,-99 -48,-113l-11 227 209 8 83 -144zm10508 -4775c27,-191 50,60 -34,-54 -79,69 -75,58 -4,123 52,-55 26,22 38,-69zm2333 -7579c33,-5 126,10 57,-109 -99,52 -45,-60 -57,109zm-3429 -2611c31,53 -29,36 45,50 112,21 8,9 62,-17 -23,-52 62,-39 -41,-56 -76,-13 -10,-11 -66,23zm-5194 1548c20,-171 28,-57 -49,-102 -23,40 -71,-39 -24,67 24,53 -2,25 73,35zm2621 14176c16,-129 6,-16 -31,-67 -97,48 -106,68 -4,128 34,-41 21,52 35,-61zm20632 -662c16,-119 -2,-25 -34,-66 -97,47 -111,67 -4,122 35,-34 23,48 38,-56zm-26456 -15122c101,69 77,57 133,-25 -31,-22 47,-55 -73,-37 -124,19 -29,27 -60,62zm-3048 11843c12,19 -42,82 104,51 57,-12 47,-31 63,-80 -76,-39 -83,-41 -168,-21l1 50zm591 1476c-69,86 -68,86 -5,161 100,-47 96,-110 5,-161zm9675 2249c133,-45 121,-5 97,-144 -185,-45 -50,-16 -91,31 11,22 3,32 23,36 48,12 16,9 52,-9 -40,-40 -1,-18 -75,-27 -8,6 -43,27 -44,28 -15,11 -33,39 -36,33 -3,-7 -13,13 -19,19l7 24c-84,-5 -18,-34 -119,21l-151 150c-8,14 -26,96 -31,118 184,-1 48,-2 196,-98 58,-38 107,-51 184,-77l16 -87 -9 -18zm-10948 -16354c55,-82 67,-123 -24,-178 -4,5 -50,-31 -46,89 4,132 36,74 70,89zm5381 2060c95,56 114,57 192,-23 -74,-75 -188,-91 -192,23zm4150 14183c1,-1 63,-22 50,-106 -19,-117 0,-36 -74,-72 -29,39 -120,103 24,178zm17482 -2004c-59,-80 -103,-72 -188,-35 18,24 -69,68 85,81 140,12 94,-39 103,-46zm-13680 -1675c142,42 170,46 247,-29 -36,-39 -44,-68 -144,-58 -99,9 -73,21 -103,87zm-8064 1221l-36 23c-90,81 -54,49 -55,120 261,25 188,-170 188,-171 -115,-6 33,-13 -60,2l-37 26c8,17 -2,42 39,48 4,1 17,-4 20,-4 4,0 15,-7 22,-10 -39,-35 7,-19 -81,-34zm8634 -1952c-7,-10 54,-79 -138,-26 10,87 13,131 91,196 33,-28 19,-1 54,-52 25,-33 -21,88 23,-39 49,-141 5,-71 -30,-79l-79 -1 26 81 53 -80zm-7088 2769c-11,-74 -89,-139 -148,-163l-44 119 162 129c15,-21 49,45 30,-85zm-7692 303l-2 61 260 28c12,-216 -160,-128 -258,-89zm39584 -10253c14,28 -26,64 64,64 136,1 28,20 79,-60 -44,-33 10,-44 -75,-38 -129,7 -19,-3 -68,34zm419 750c28,-36 34,52 41,-69 10,-164 -9,-60 -36,-101 -30,17 -56,-27 -71,73 -20,138 30,78 66,97zm3065 2473c56,-72 68,-95 66,-198 -91,-19 -135,-38 -154,50 -19,87 88,148 88,148zm2397 -3620c57,42 -53,30 105,50 159,19 21,7 114,-15 -23,-95 27,-126 -112,-132 -103,-5 -87,13 -107,97zm-719 4372l-51 -56c213,-116 93,-238 -69,-239 -152,-1 -176,38 -165,195l14 39c14,128 95,141 226,140l45 -79zm-11881 -7680c95,59 33,27 75,3l-58 -18c-2,-8 -11,11 -17,15zm-21198 15445c35,43 20,47 60,29 5,-2 14,-15 21,-22l-81 -7zm5007 1132l96 3 -5 -58c-40,-60 5,-36 -76,-65 -36,-12 -55,0 -88,1l4 117 69 2zm19325 -14421l-61 0c-35,54 -27,-70 -32,67 -4,136 12,61 31,94 73,-20 31,13 65,-51 145,-35 46,16 95,-68 -56,-55 16,-32 -98,-42zm-8429 13335c40,-6 207,-169 -164,-173 -69,95 -80,76 -101,170l265 3zm14572 -9261c47,74 56,123 127,4 -117,-124 -105,-20 -127,-4zm909 -1194c54,84 169,131 199,-23 -27,-13 -10,-39 -116,-25 -56,7 -60,9 -83,48zm271 2163c-1,-1 33,-56 -85,-37 -108,17 -29,-7 -85,61 38,68 -51,70 108,81 68,5 70,-17 106,-46 -12,-97 2,-33 -44,-59l-117 16 83 62c42,-51 19,-10 34,-78zm2226 -30c105,20 81,29 165,-11 -16,-86 -60,-131 -144,-155 -47,81 -42,60 -21,166zm-680 -1938c37,-37 13,14 35,-54 59,-183 70,-195 20,-219 -8,-1 -19,-13 -23,-4 -2,7 -74,-30 -94,109 -15,102 -7,135 62,168zm-7886 -1031c174,9 174,-15 198,-181l-195 0 -3 181zm-435 -3677c1,-132 -96,-207 -218,-204 -14,163 61,224 218,204zm9068 10670l-229 -20c16,143 33,200 192,182 19,-35 15,-15 28,-68 1,-1 7,-80 9,-94zm-11458 -8654l179 16c42,-78 53,-79 68,-188l-240 -2 -7 174zm-13484 -1787c67,65 -101,40 38,31 69,-5 24,3 66,-28 -78,-63 97,-40 -43,-30 -88,6 4,-25 -61,27zm15318 6420c8,8 -38,96 94,3 -76,-59 111,-37 -40,-27 -71,5 -10,-11 -54,24zm-4361 -5494c0,-176 44,-57 -80,-98 19,110 -24,65 80,98zm5776 11913c-52,-67 -17,-71 -103,-32 75,108 -101,-50 18,46 3,3 12,10 15,12 123,59 36,-5 70,-26zm452 -9192c-15,-105 18,-46 -63,-89 -52,58 -31,28 -37,112l0 24c138,141 57,117 171,135l18 -141 -89 -41zm1300 -184c26,36 -55,67 177,58 3,-16 69,-189 -108,-115 -67,28 -30,-2 -69,57zm-6644 5321c34,-145 -23,-89 -32,-106 -123,17 -85,-60 -108,72 -22,127 47,87 73,100 61,-30 38,56 67,-66zm12539 -5533c161,1 121,36 140,-122 -54,-35 -31,-46 -161,-30 -7,73 -19,77 21,152zm-7899 4642l158 -3 14 -151 -161 -4 -11 158zm-17041 -7038c56,111 45,115 103,4 -51,-38 -52,-32 -103,-4zm9438 14921c155,-74 35,-103 33,-108 -148,63 -33,108 -33,108zm-15491 -14617c76,-131 38,-84 -75,-106 30,146 -22,74 75,106zm2595 5412c114,-55 112,-64 4,-122 -17,20 -39,-42 -33,60 3,62 0,30 29,62zm3715 -5475c14,118 -32,80 93,86 37,-95 5,-127 -93,-86zm-11753 7101c5,-101 4,-86 -99,-104 -13,126 -1,117 99,104zm5801 -8233c54,-27 68,45 62,-68 -4,-75 -27,-45 -58,-61 -3,3 -85,14 -4,129zm-10835 7881c-39,-69 -44,-121 -135,-4 59,52 -68,23 66,40 114,15 28,-3 69,-36zm25397 -740c-39,10 -173,13 -98,95 96,105 85,-47 98,-95zm-2065 8351c-44,-72 23,-10 -75,-89 -65,-51 0,-9 -75,-42l-43 107 31 161c93,9 88,6 142,-32l20 -105zm-14954 -14214c87,52 55,48 150,6 -45,-139 -121,-139 -150,-6zm2674 8593c-160,1 -84,46 -93,80l164 16c3,-66 28,-97 -71,-96zm-12857 -11652c59,116 145,73 198,6 -89,-66 -119,-55 -198,-6zm14729 9603c9,31 -34,70 86,81 110,11 71,-13 85,-75 -84,-44 -68,-38 -171,-6zm-1945 -4959c-113,-51 -59,-57 -140,3l-3 59c93,63 166,72 228,-22 -42,-48 23,-26 -85,-40l-115 0c37,83 -28,35 82,68 55,-38 15,12 33,-68zm1792 10456c-77,-56 -141,-72 -205,23 16,12 15,56 118,47 109,-8 68,-30 87,-70zm6791 -1117c36,-46 36,70 46,-94 7,-128 -25,-68 -41,-87 -41,17 -64,-27 -70,84 -8,141 28,77 65,97zm-19845 -1831c156,4 126,-56 115,-191 -148,47 -119,6 -115,191zm28588 2560c110,14 138,-57 145,-166l-129 10c-85,158 -17,155 -16,156zm-24536 1960c-95,25 -67,45 -79,133 122,4 100,21 190,-35 -16,-82 22,-133 -111,-98zm-1339 -12555c34,-29 35,29 35,-82 -176,-85 -220,125 -198,245 232,90 139,21 169,-18l-8 -56 2 -89zm-138 10191c6,-3 15,-9 19,-11 187,-98 143,-30 160,-133 -81,-49 -97,-61 -235,49 -9,7 -15,11 -19,14l-10 -4 4 8c-6,4 -7,6 -36,41 47,43 -13,15 61,44 105,40 38,-2 56,-8zm8367 -12746l142 -3 16 -140c-106,-42 -55,-43 -174,-39 -38,108 -18,70 16,182zm13540 9864c20,-155 32,-118 -57,-201l-114 -69 -18 135c4,4 38,33 46,42 112,117 -30,57 143,93zm988 4753c45,-102 30,10 24,-135l-34 -127c-82,44 -11,4 -56,41l-47 40c-58,65 -44,-8 -43,128 63,55 64,54 156,53zm12226 -12623c69,-36 48,37 60,-51 10,-77 0,-29 -27,-74 -74,34 -47,-58 -62,47 -11,85 -16,23 29,78zm-541 532c79,-38 56,43 72,-73 18,-134 -33,-95 -37,-102 -62,28 -51,-64 -72,68 -25,164 18,78 37,107zm3249 -2408c42,-47 39,67 47,-70 10,-158 -17,-67 -42,-99 -63,25 -63,-60 -82,69 -19,138 47,86 77,100zm1303 9111c11,10 -39,54 99,53 165,-1 78,-27 103,-76 -9,-7 34,-50 -103,-50 -165,1 -71,41 -99,73zm-492 -3647c92,-9 106,-16 198,-88 -55,-161 -128,-160 -198,-171 8,167 44,104 0,259zm-24691 -3316c88,44 53,43 105,-26 -39,-27 54,-78 -66,-29 -4,1 -13,8 -16,10l-23 45zm13670 13200c-33,-129 32,-90 -103,-104 13,123 -21,66 103,104zm-2530 -391c-27,-47 15,-109 -119,-33 20,31 -50,44 47,68 133,33 20,3 72,-35zm7333 519c-75,-6 -55,36 -70,58 59,45 -67,20 67,36 128,15 17,5 68,-31 -26,-54 53,-54 -65,-63zm-2346 -1174c-21,-102 14,-11 -60,-51 -44,43 -78,-66 -39,94 19,78 18,22 64,42 41,-48 52,-4 35,-85zm-2671 1531c-126,3 -69,18 -100,67 33,26 41,98 222,6 -23,-40 -11,-75 -122,-73zm2389 -1391c-144,-10 -216,11 -140,175l167 10 -27 -185zm-13510 -6878c31,-55 21,-40 2,-86 -55,59 -65,-88 -31,42 34,130 -97,-14 29,44zm11036 7899c51,38 -7,20 62,28 135,17 -26,24 42,-24 -37,-35 3,-24 -62,-33 -162,-23 46,-43 -42,29zm-26597 -10879c61,73 10,58 96,32 -17,-44 72,-25 -24,-45 -72,-14 -22,-8 -72,13zm24876 10019c-12,-82 2,-14 -47,-36 -75,86 -25,63 27,92 24,-39 30,7 20,-56zm-13300 -13607c15,-24 58,33 23,-60 -25,-65 14,-8 -49,-43 -39,74 -64,63 26,103zm-1474 10770c72,-89 63,-70 -26,-109 -102,108 -21,86 26,109zm2490 -9768c5,-7 104,11 5,-148 -45,51 -53,-76 -44,73 5,81 3,34 39,75zm-455 582l45 -26c-21,-109 31,-69 -102,-93 -6,111 -39,73 57,119zm-2646 4875c5,-126 -2,-96 -98,-104 -10,117 -38,124 98,104zm-15387 -7335c19,35 -38,43 63,61 137,25 73,-13 97,-27 -4,-10 32,-155 -160,-34zm3776 14905c-5,113 33,83 36,87 97,-48 94,-123 6,-180 -22,28 -35,-54 -42,93zm16124 -7293c1,0 19,130 175,5 -14,-31 11,-58 -77,-63 -125,-7 -71,37 -98,58zm4168 4706c37,-17 60,39 74,-88 13,-125 -31,-79 -39,-89 -47,21 -58,-27 -69,83 -13,129 25,80 34,94zm-14149 1449c-77,-12 -83,28 -88,128l196 -3c-13,-79 -18,-110 -108,-125zm-10285 -377c145,13 156,25 271,-27 -60,-66 -141,-122 -250,-121l-21 148zm30878 -12750c85,40 49,48 105,-26 -21,-16 24,-117 -105,26zm-4545 -547c57,-82 74,-71 -26,-119 -64,93 -65,76 26,119zm6389 36c29,-122 43,-90 -83,-116 14,175 -39,72 83,116zm5155 2988c-2,44 -19,42 29,111 108,-35 40,70 81,-93 0,-4 -13,-87 -13,-87 -15,-49 -13,-36 -31,-65 -82,38 -49,-29 -66,134zm-7078 -530c164,-26 121,59 106,-100 -107,-4 -71,-31 -106,100zm1288 -911c5,-125 48,-86 -66,-119 -93,100 -38,96 66,119zm2390 12606c-127,16 -58,-23 -117,61 77,102 120,95 117,-61zm-6680 -14484c93,-49 102,-26 33,-126 -50,15 -40,-45 -66,34 -44,140 5,62 33,92zm-6631 -463c15,26 -10,57 69,75 138,31 72,-16 95,-31 -35,-82 47,-48 -66,-68 -28,-5 -93,19 -98,24zm9161 3323c39,-11 65,56 83,-82 13,-103 -26,-89 -48,-112 -98,44 -81,122 -35,194zm11122 7323c77,-41 52,57 68,-98 5,-49 -11,-64 -20,-96 -60,21 -77,-45 -93,90 -16,134 36,91 45,104zm-6944 6433l64 2c34,-109 52,-107 -11,-201 -30,8 -66,-56 -83,91 -7,64 4,48 30,108zm-9852 -12707c33,-80 15,-192 -49,-252 -81,-76 -14,-26 -117,-47 50,222 25,40 89,163 45,86 -28,59 77,136zm17007 11129c-5,-4 -12,-10 -17,-14l-83 -58c-95,106 -8,225 151,201 10,-144 18,-76 -51,-129zm-14522 -7357l6 118 177 17 4 -157c-119,-17 -94,-25 -187,22zm1633 621c122,-9 53,43 137,-39 83,-80 31,-20 54,-141l-180 10 -11 170zm4070 -5651l169 46c4,-99 16,-85 -35,-146 -85,-102 -17,-49 -154,-73l20 173zm10175 12053c-9,-85 14,-6 -49,-52 -37,41 -36,-9 -29,69 9,97 -12,14 55,43 36,-56 37,58 23,-60zm-8682 -13171c38,60 -39,38 51,53 70,12 25,3 66,-21 -12,-32 50,-133 -117,-32zm2108 1273c32,-19 113,33 33,-122 -78,35 -51,-47 -63,49 -17,128 -11,22 30,73zm-2180 -3663l-109 -3c3,174 -2,49 43,106 98,-52 42,59 66,-103zm10237 6624c21,-31 58,42 35,-72 -21,-101 16,-22 -69,-66 -51,93 -65,71 34,138zm-4681 8278c35,-113 -29,-91 -30,-94 -79,35 -36,-30 -61,65 -8,30 9,72 15,95 49,-25 47,25 76,-66zm1712 -10475c90,-11 72,27 105,-40 54,-109 -36,-81 -61,-94l-37 44c-16,57 -18,8 -7,90zm-2159 653c14,19 -15,66 80,65 117,-2 32,5 75,-60 -19,-16 33,-129 -155,-5zm-9160 -4516c140,63 103,33 149,-46 -10,-8 40,-74 -77,-47 -186,44 -11,10 -72,93zm14791 10390c-149,-15 -74,13 -105,64 54,49 -82,47 102,53 102,4 97,-46 99,-47 -19,-29 7,-60 -96,-70zm-7396 -6688c36,71 -84,46 66,62 8,-7 18,-27 22,-21l74 -89c49,-90 34,-58 -1,-120 -66,20 -27,3 -73,42 -5,4 -10,10 -14,14 -5,4 -11,10 -15,14 -4,5 -11,12 -16,16l-35 34 -8 48zm3324 -2979c19,41 -49,73 95,76 129,2 70,-21 95,-70 -7,-6 38,-52 -90,-53 -165,-1 -56,12 -100,47zm-4325 1161l115 0c20,-126 28,-84 -30,-190 -117,49 -118,87 -85,190zm5264 1728c2,-3 48,17 50,-92 4,-170 -3,-48 -44,-101 -39,16 -77,-51 -90,107 -6,77 17,64 84,86zm3736 8908c128,-174 17,-185 7,-200 -65,16 -98,-21 -96,99 2,114 50,86 89,101zm-577 -7651c-69,-84 28,-31 -83,-63 -48,-14 -90,-4 -138,1 13,162 117,193 221,62zm-10793 -2729c100,-7 113,56 202,-184l-174 3 -28 181zm11216 4612c69,-72 58,-54 46,-178l-199 -7c-4,7 -10,9 -12,18l-76 95c135,22 68,-7 161,87l80 -15zm-25273 1701c76,60 6,56 86,3 -47,-47 102,-40 -34,-29 -72,6 -2,-17 -52,26zm-2321 -4177c9,14 14,125 94,3 -55,-40 95,-28 -36,-22 -55,3 -22,-1 -58,19zm3532 6166c27,41 -52,47 54,45 61,-2 15,-6 40,-42 -34,-25 -1,-17 -55,-23 -4,0 -17,14 -19,7 -3,-7 -13,9 -20,13zm9741 -9188c141,-29 65,23 97,-75 -192,-10 -27,11 -97,75zm-816 7909c15,-101 13,5 -29,-35 -126,99 -5,94 -3,96 46,-55 21,17 32,-61zm4719 4713c-57,112 -6,24 19,71 20,-12 147,-53 24,-91 -71,-21 -31,-5 -43,20zm-8123 -431c-15,-86 16,-10 -58,-43 -82,124 13,93 35,107 35,-58 46,63 23,-64zm17490 -3007c175,100 121,20 148,5 -164,-141 -131,-17 -148,-5zm-22342 4930c132,-4 153,38 190,-77l-182 -33c-126,37 -57,-3 -107,63 47,51 -83,44 99,47zm12980 -12068c-5,14 -15,15 -17,31 -2,16 -11,19 -13,27 -5,31 -5,60 -3,92l176 14 5 -153 -148 -11zm3361 -432c36,-54 25,-37 3,-87 -60,72 -60,-95 -28,43 33,144 -77,-37 25,44zm-4106 70c11,-16 62,31 29,-65 -28,-79 21,-7 -55,-51 -27,44 -74,-63 -27,70 23,65 -11,17 53,46zm4107 -1014c83,-42 48,57 62,-54 19,-151 12,-10 -29,-78 -91,38 -53,-66 -66,49 -13,104 -23,19 33,83zm5309 -1291c25,-37 79,60 36,-83 -31,-103 26,-8 -61,-59 -32,47 -82,-71 -36,83 28,92 -21,17 61,59zm1248 6583c63,-42 37,35 61,-54 35,-132 -11,-66 -27,-91 -56,21 -40,-53 -67,42 -50,177 3,67 33,103zm-3413 -2551c58,-28 79,64 73,-75 -5,-112 -22,-47 -68,-70 -1,1 -117,-7 -5,145zm-289 -1224c21,57 -53,42 41,69 192,56 47,8 104,-36 -35,-66 27,-44 -52,-65 -126,-33 -82,23 -93,32zm-5357 -3096l-17 46c15,129 58,97 106,82 112,-34 72,-59 86,-77 -20,-13 -52,-43 -84,-53l-91 2zm8116 7257c60,-74 70,111 51,-114 -8,-94 -53,-80 -74,-93 -6,8 -48,-10 -52,93 -7,206 -24,60 75,114zm-359 -3417c72,-45 54,62 74,-83 26,-183 -17,-80 -38,-116 -80,37 -61,-87 -83,79 -26,191 21,83 47,120zm-17157 14c85,70 -121,41 43,30 71,-4 21,6 65,-27 -62,-52 98,-38 -42,-29 -76,5 -12,-10 -66,26zm5329 -1528c63,-38 47,39 53,-51 6,-102 14,-24 -50,-60 -32,49 -31,66 -3,111zm-27615 8986c78,-36 55,63 54,-88 -92,3 -46,-22 -73,28 -47,83 8,40 19,60zm32764 3684c-10,-69 0,-14 -45,-36 -107,107 -16,74 26,100 17,-35 26,-9 19,-64zm-6439 -13319c1,0 48,9 52,-33 12,-114 25,-19 -48,-68 -16,24 -89,9 -4,101zm-2549 -1315c-16,8 -169,44 -28,87 59,17 35,0 43,-20 45,-117 8,-15 -15,-67zm4501 3122c50,-16 41,47 55,-34 13,-73 3,-24 -23,-71 -53,37 -106,11 -32,105zm100 11390c59,41 -62,18 66,32 141,16 8,10 73,-28 -142,-125 -131,-11 -139,-4zm5906 333c25,-38 129,23 33,-116 -109,38 -98,26 -33,116zm-36586 -127c129,-18 2,10 67,-34 -65,-125 -157,-104 -185,25 57,9 59,18 118,9zm29127 1317c73,-31 40,-35 105,3 -33,22 15,19 -51,22 -115,5 -13,3 -54,-25zm-38 57l179 5 2 -117 -181 -1 0 113zm-23361 -15949c1,-1 61,10 45,-96 -16,-104 8,-33 -69,-78 -13,19 -64,-32 -40,103 21,124 1,35 64,71zm7078 11660c-100,8 -43,-8 -106,52 -56,54 -46,20 -62,107l175 18 -7 -177zm27110 -785c-82,-43 -51,-52 -102,26 49,34 -62,39 58,24 76,-9 15,3 44,-50zm-1210 -2487c86,-45 122,22 32,-114 -51,19 -45,-53 -58,39 -14,86 -25,15 26,75zm849 -5816c135,-10 76,32 106,-104 -166,22 -89,-39 -106,104zm-8045 -1393l58 -2c62,-97 37,-142 -52,-191 -5,7 -124,39 -6,193zm-12585 2344c3,-126 9,-31 -32,-70 -26,25 -18,13 -37,64l38 57 31 -51zm21445 8402c-173,27 -5,161 -5,161 16,-23 33,53 35,-88 2,-133 2,-16 -30,-73zm-7726 -10715c54,-16 48,46 60,-34 13,-86 8,-15 -27,-73 -49,31 -122,-28 -33,107zm2226 -437c29,-40 52,53 35,-69 -16,-105 -3,-34 -60,-73 -13,17 -57,-43 -42,72 16,126 -15,33 67,70zm-13381 14473c-109,-44 -32,2 -69,25 153,144 93,45 120,33 -37,-65 17,-30 -51,-58zm-16107 -2399c103,-46 70,-13 61,-117 -97,10 -54,-27 -90,34 -46,78 29,83 29,83zm6804 -10029c-8,-5 -18,-24 -24,-15l-96 -9c1,144 -24,145 120,124l0 -100c-90,37 -68,-13 -76,69 108,-5 13,38 76,-69zm-11049 7103c12,-112 26,21 -38,-41l7 93c60,-55 22,37 31,-52zm7 -5040c76,71 -99,41 37,30 71,-5 11,13 56,-27 -52,-44 90,-32 -35,-25 -65,4 -11,-8 -58,22zm700 2992c39,30 32,39 86,2 -102,-100 -86,-3 -86,-2zm38577 5667c152,93 87,13 102,3 -42,-43 16,-22 -58,-32l-44 29z"/>
|
||||
</g>
|
||||
</g>
|
||||
<path class="fil3" d="M20432 0c8718,-38 15581,2266 15458,9209 -25,787 -197,745 -1206,434 -5376,-1662 -8578,-3016 -12410,-6248 -1067,-900 -1945,-1797 -2743,-2837 -478,-648 -8,-545 901,-558zm-18416 19428c1785,-4186 2803,-6725 6956,-9214 1814,-1088 3728,-1795 5744,-2401 5011,-1469 9917,-953 14495,540 1697,562 2833,1208 4123,2158 602,450 989,178 1872,-71 402,-113 1572,-529 1912,-305 933,615 -675,1120 -1291,1389 -1798,785 -1256,251 -1265,1780 -43,7030 -7302,11174 -13250,12374 -3409,688 -7029,1146 -9343,1499 -5916,900 -5060,-1185 -9071,-2819 -937,-381 -2531,-341 -2879,-1361 -223,-655 1540,-2751 1997,-3569z"/>
|
||||
<path class="fil4" d="M10113 32164l548 -85c566,-87 655,-815 655,-1696 0,-1108 -152,-1559 -630,-1485l-573 89 0 3177zm-872 -3711l1541 -239c770,-120 1425,167 1425,1818l0 225c0,1013 -203,2283 -1374,2464l-1592 246 0 -4514z"/>
|
||||
<path class="fil4" d="M14753 30269l-349 -2047 -421 2167 770 -120zm-922 -2527l1171 -182 1019 4358 -943 146 -216 -1141 -987 152 -274 1218 -935 145 1165 -4696z"/>
|
||||
<polygon class="fil4" points="17968,31617 17096,31752 17096,27924 16014,28092 16014,27404 19050,26934 19050,27622 17968,27790 "/>
|
||||
<path class="fil5" d="M24269 30700l88 -3885 -824 115 -106 4640 2357 -329 17 -755 -1532 214zm2552 396l105 -4640 -824 115 -106 4640 825 -115zm3488 -5112l-525 1811c-157,575 -298,1154 -410,1687l-17 3c-83,-518 -193,-1044 -319,-1586l-423 -1679 -1020 143 -395 4680 752 -105 124 -1798c41,-577 85,-1269 109,-1855l17 -3c87,553 207,1162 334,1668l432 1780 624 -87 566 -1950c157,-539 327,-1176 462,-1748l17 -3c-16,472 -6,1216 3,1822l37 1793 785 -109 -139 -4606 -1014 142zm2380 3547l29 -1291 1399 -196 16 -730 -1398 196 25 -1123 1483 -207 17 -748 -2307 322 -106 4640 2396 -334 17 -749 -1571 220z"/>
|
||||
<path class="fil4" d="M21036 29298l-350 -2048 -420 2166 770 -118zm-923 -2529l1172 -182 1019 4359 -943 145 -217 -1141 -986 152 -274 1218 -936 145 1165 -4696z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 69 B |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 174 B |
|
After Width: | Height: | Size: 173 B |
|
After Width: | Height: | Size: 173 B |
|
After Width: | Height: | Size: 180 B |
|
After Width: | Height: | Size: 179 B |
|
After Width: | Height: | Size: 180 B |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 255 B |
|
After Width: | Height: | Size: 8.9 KiB |
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 24.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#555555;}
|
||||
</style>
|
||||
<g>
|
||||
<path class="st0" d="M476.7,88.3h-88.3c0-48.8-39.5-88.3-88.3-88.3s-88.3,39.5-88.3,88.3h-88.3c-19.5,0-35.3,15.8-35.3,35.3v88.3
|
||||
C39.5,211.9,0,251.4,0,300.1s39.5,88.3,88.3,88.3v88.3c0,19.5,15.8,35.3,35.3,35.3h123.6v-35.3c0-29.3,23.7-53,53-53s53,23.7,53,53
|
||||
V512h123.6c19.5,0,35.3-15.8,35.3-35.3V353.1h-35.3c-29.3,0-53-23.7-53-53s23.7-53,53-53H512V123.6
|
||||
C512,104.1,496.2,88.3,476.7,88.3z M388.4,300.1c0,48.8,39.5,88.3,88.3,88.3v88.3h-88.3c0-31.5-16.8-60.7-44.1-76.5
|
||||
c-27.3-15.8-61-15.8-88.3,0c-27.3,15.8-44.1,44.9-44.1,76.5h-88.3V353.1H88.3c-29.3,0-53-23.7-53-53s23.7-53,53-53h35.3V123.6
|
||||
h123.6V88.3c0-29.3,23.7-53,53-53s53,23.7,53,53v35.3h123.6v88.3C427.9,211.9,388.4,251.4,388.4,300.1z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 46 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 141 B |
|
After Width: | Height: | Size: 222 B |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1023 B |
|
After Width: | Height: | Size: 889 B |
|
After Width: | Height: | Size: 81 B |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 15 KiB |
@@ -0,0 +1,16 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z" />
|
||||
<polyline points="14 2 14 8 20 8" />
|
||||
<path d="M10 12a1 1 0 0 0-1 1v1a1 1 0 0 1-1 1 1 1 0 0 1 1 1v1a1 1 0 0 0 1 1" />
|
||||
<path d="M14 18a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1 1 1 0 0 1-1-1v-1a1 1 0 0 0-1-1" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 498 B |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 7.1 KiB |
|
After Width: | Height: | Size: 431 B |
|
After Width: | Height: | Size: 725 B |
|
After Width: | Height: | Size: 996 B |
|
After Width: | Height: | Size: 743 B |
|
After Width: | Height: | Size: 972 B |
|
After Width: | Height: | Size: 517 B |
|
After Width: | Height: | Size: 665 B |
|
After Width: | Height: | Size: 692 B |
|
After Width: | Height: | Size: 271 B |
|
After Width: | Height: | Size: 691 B |
|
After Width: | Height: | Size: 71 B |
|
After Width: | Height: | Size: 71 B |
|
After Width: | Height: | Size: 537 B |
|
After Width: | Height: | Size: 305 B |
|
After Width: | Height: | Size: 350 B |
|
After Width: | Height: | Size: 346 B |
|
After Width: | Height: | Size: 1000 B |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 54 B |
|
After Width: | Height: | Size: 54 B |
|
After Width: | Height: | Size: 103 B |
|
After Width: | Height: | Size: 241 B |
|
After Width: | Height: | Size: 362 B |
|
After Width: | Height: | Size: 243 B |
|
After Width: | Height: | Size: 97 KiB |
|
After Width: | Height: | Size: 51 B |
|
After Width: | Height: | Size: 84 B |
|
After Width: | Height: | Size: 990 B |
@@ -0,0 +1,54 @@
|
||||
<cfimport prefix="m" taglib="../lib"/>
|
||||
<cfimport prefix="c" taglib="../lib/controls"/>
|
||||
<cfparam name="ATTRIBUTES.fwx" default=""/>
|
||||
<cfparam name="ATTRIBUTES.thisUrl" default=""/>
|
||||
|
||||
<cfset i18=request.i18/>
|
||||
|
||||
<!---<style>ul#mainmenu li.menu-item-noaction a.inline{display:inline;}</style>--->
|
||||
<cfoutput>
|
||||
<ul id="mainmenu">
|
||||
<cfif request.usrAuthenticated()></cfif>
|
||||
|
||||
<!--- <li class="menu-title">Реестры</li>
|
||||
|
||||
<c:menu_item acl="" page="contract_ls.cfm" label="Договоры"/>
|
||||
<c:menu_item acl="" page="specification_ls.cfm" label="Спецификации"/>
|
||||
<c:menu_item acl="" page="agreement_ls.cfm" label="Сделки"/>
|
||||
<c:menu_item acl="" page="specification_item_ls.cfm" label="Экземпляры услуг"/> --->
|
||||
<li class="menu-title">Отчеты</li>
|
||||
<c:menu_item acl="" page="payg.cfm" label="PAYG"/>
|
||||
<!--- <c:menu_item acl="" page="detail_daily_rpt.cfm" label="Детализация по дням"/>
|
||||
<c:menu_item acl="" page="income_daily_rpt.cfm" label="Выручка по дням"/>
|
||||
<c:menu_item acl="" page="income_monthly_rpt.cfm" label="Выручка по месяцам"/> --->
|
||||
|
||||
<!--- <li class="menu-title">Справочники</li>
|
||||
|
||||
<c:menu_item acl="" page="svc_ls.cfm" label="Сервисы"/>
|
||||
<c:menu_item acl="" page="contragent_ls.cfm" label="Контрагенты"/>
|
||||
<c:menu_item acl="" page="measure_ls.cfm" label="Единицы измерения"/>
|
||||
|
||||
<c:menu_item acl="" page="usr_ls.cfm" label="Пользователи"/>
|
||||
--->
|
||||
<li class="menu-title">"Пользователь"</li>
|
||||
|
||||
<cfif request.usrAuthenticated()>
|
||||
<cfquery name="qUsr" datasource="#request.DS#">
|
||||
select shortname/*, login, firstname, middlename, lastname*/
|
||||
from usr
|
||||
where usr_id=<cfqueryparam cfsqltype="CF_SQL_INTEGER" value=#request.usr_id#/>
|
||||
</cfquery>
|
||||
<li class="menu-item-noaction">#qUsr.shortname#</li> <!---#request.usr_id#--->
|
||||
<c:menu_item acl="" page="password.cfm" queryString="#ATTRIBUTES.fwx#" label="Смена пароля"/>
|
||||
<c:menu_item acl="" page="logout.cfm" queryString="target_page=#URLEncodedFormat(ATTRIBUTES.thisUrl)#" label="Выход"/>
|
||||
|
||||
<cfelse>
|
||||
<c:menu_item acl="" page="saml/login.cfm" queryString="target_page=#URLEncodedFormat(ATTRIBUTES.thisUrl)#" label="Вход через WebSSO"/>
|
||||
<c:menu_item acl="" page="login.cfm" queryString="#ATTRIBUTES.fwx#" label="Вход"/>
|
||||
<c:menu_item acl="" page="logout.cfm" queryString="target_page=#URLEncodedFormat(ATTRIBUTES.thisUrl)#" label="Выход"/>
|
||||
</cfif>
|
||||
|
||||
|
||||
</ul>
|
||||
</cfoutput>
|
||||
<cfexit method="exittag"/>
|
||||
@@ -1,241 +0,0 @@
|
||||
|
||||
<cfset dt_finish=createDateTime(year(Now()),month(Now()),1,0,0,0)/>
|
||||
<cfset dt_start=dateAdd('m',-1,dt_finish)/>
|
||||
|
||||
Нужно еще применить политики бесплатного минимума
|
||||
<!---
|
||||
<cfquery name="qCode" datasource="dwh">
|
||||
select distinct p.code
|
||||
from elma.deals d
|
||||
join elma.deals_services siv on (d.__id=ANY(siv.deal))
|
||||
join elma.service_parametrs p on (p.__id = ANY(siv.params))
|
||||
join elma.companies k on (d._companies=k.__id)
|
||||
join elma.additional_agreements aa on (aa.__id = ANY(siv.additional_agreement))
|
||||
join elma.aggrements a on (aa.contract_uid = a.__id)
|
||||
where p.type=3 AND aa.is_actual
|
||||
order by p.code
|
||||
</cfquery>
|
||||
<cfdump var=#qCode#/>
|
||||
|
||||
<cfquery name="qSpec" datasource="dwh">
|
||||
select k.id_klienta, p.code, p.price, p.discount, k.__name as contragent, a.__name as contract, d.__name as deal, siv.abstractive_service as abstract_service, siv.modifier, siv.user_description
|
||||
,p.__name as metric, p.ed_izm
|
||||
--, aa.is_actual
|
||||
from elma.deals d
|
||||
join elma.deals_services siv on (d.__id=ANY(siv.deal))
|
||||
join elma.service_parametrs p on (p.__id = ANY(siv.params))
|
||||
join elma.companies k on (d._companies=k.__id)
|
||||
join elma.additional_agreements aa on (aa.__id = ANY(siv.additional_agreement))
|
||||
join elma.aggrements a on (aa.contract_uid = a.__id)
|
||||
where p.type=3 AND aa.is_actual
|
||||
order by k.id_klienta, p.code
|
||||
</cfquery>
|
||||
здесь имеем список кодов с ценами и WZ. Каждому коду можно поставить в соответствие запрос, который даст по нему выборку. Изредка один запрос может вывести 2 кода, но разбить на 2 запроса легко. Кроме того, запросы можно объединить через union в один - может быть, так будет лучше читаться (быстрее выполняться не будет)
|
||||
<cfdump var=#qSpec#/>
|
||||
|
||||
|
||||
<cfquery name="qComputing" datasource="billing-vc">
|
||||
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 'unknown' 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 > 0
|
||||
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>
|
||||
<cfdump var=#qComputing#/>
|
||||
|
||||
<cfquery name="qStorage" datasource="billing-vc">
|
||||
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 'unknown' end as code,
|
||||
storage_profile_types.name as storage_profile_type_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 > 0
|
||||
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>
|
||||
<cfdump var=#qStorage#/>
|
||||
|
||||
<cfquery name="qS3Vol" datasource="billing-s3">
|
||||
select
|
||||
sum(bucket_stat.usage_rgw_main_size_actual) as vol,
|
||||
case
|
||||
when bucket_stat.placement_id = 1 then 'paas.s3.ceph.vol'
|
||||
when bucket_stat.placement_id = 2 then 'paas.s3.cphc.vol'
|
||||
else 'unknown' end as code,
|
||||
'WZ'||lpad(bucket_stat.owner, 5, '0') as 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.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>
|
||||
<cfdump var=#qS3Vol#/>
|
||||
|
||||
<cfquery name="qS3OpsDefaultPlacement" datasource="billing-s3">
|
||||
select sum(ops) as ops,
|
||||
case
|
||||
when category.name like 'get%' then 'get'
|
||||
when category.name like 'put%' then 'put'
|
||||
when category.name like 'post%' then 'post'
|
||||
when category.name like 'list%' then 'list'
|
||||
else 'unknown' end as op,
|
||||
'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 and placement.name='default-placement'
|
||||
where 1=1
|
||||
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, category.name
|
||||
order by user_info.name, category.name;
|
||||
</cfquery>
|
||||
<cfdump var=#qS3OpsDefaultPlacement#/>
|
||||
|
||||
<cfquery name="qS3OpsDefault" datasource="billing-s3">
|
||||
select sum(ops) as ops,
|
||||
case
|
||||
--when category.name like 'get%' then 'get' /*get встречается*/
|
||||
when category.name like 'put%' then 'put'
|
||||
--when category.name like 'post%' then 'post'
|
||||
when category.name like 'list%' then 'list'
|
||||
else 'unknown' end as op,
|
||||
'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 and placement.name='default-placement'
|
||||
where s3billing.usage_bucket_by_user.bucketid='0'
|
||||
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, category.name
|
||||
order by user_info.name, category.name;
|
||||
</cfquery>
|
||||
<cfdump var=#qS3OpsDefault#/>
|
||||
--->
|
||||
|
||||
Трафик хранится в той же таблице, что и остальной юзадж, можно было бы доставать в общем резалтсете
|
||||
|
||||
<cfquery name="qS3TrafficDefaultPlacement" datasource="billing-s3">
|
||||
select sum(bytes_sent) as bytes,
|
||||
placement.name as placement
|
||||
'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 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
|
||||
order by user_info.name;
|
||||
</cfquery>
|
||||
<cfdump var=#qS3TrafficDefaultPlacement#/>
|
||||
|
||||
|
||||
<cfquery name="qS3TrafficDefault" datasource="billing-s3">
|
||||
select sum(bytes_sent) as bytes,
|
||||
'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 AND placement.name='default-placement'
|
||||
where s3billing.usage_bucket_by_user.bucketid='0'
|
||||
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
|
||||
order by user_info.name;
|
||||
</cfquery>
|
||||
<cfdump var=#qS3TrafficDefault#/>
|
||||
|
||||
<!---
|
||||
задача (вызванная сыростью базы биллинга)
|
||||
смапить код параметра с VDC (1:n)
|
||||
iaas.ngc.i31.ram-m
|
||||
iaas.ngc.a28.ram-m
|
||||
|
||||
cl01:
|
||||
7 хостов Lenovo ThinkSystem SR650 -[7X06CTO1WW]-
|
||||
2 процессора Xeon(R) Gold 6226R 16 ядер 32 потока каждый 2.9 ГГц
|
||||
1.25тб озу в каждом.
|
||||
В 4 из 7 есть по 4 GPU NVIDIA A16 16GB в каждом.
|
||||
|
||||
cl01-vsan:
|
||||
16 хостов Lenovo ThinkSystem SR650 -[7X06CTO1WW]-
|
||||
2 процессора Xeon(R) Gold 6226R 16 ядер 32 потока каждый 2.9 ГГц
|
||||
1.25тб озу в каждом.
|
||||
В 9 из 16 есть по 4 GPU NVIDIA A16 16GB в каждом.
|
||||
|
||||
cl02:
|
||||
10 Huawei 2488H V5
|
||||
4 процессора Xeon(R) Gold 6254 18 ядер 36 потоков каждый. 3.1 ГГц
|
||||
2тб озу в каждом.
|
||||
|
||||
5 Huawei Atlas 800 (Model 3010)
|
||||
2 процессора Xeon(R) Gold 6254 18 ядер 36 потоков каждый. 3.1 ГГц
|
||||
1.5тб озу в каждом.
|
||||
|
||||
cl04-vsan:
|
||||
10 Apex AR320-12
|
||||
2 процессора AMD EPYC 7543 32 ядра 64 потока каждый. 2.8 ГГц
|
||||
2тб озу в каждом.
|
||||
18 Apex AR320-12-E7543
|
||||
2 процессора AMD EPYC 7543 32 ядра 64 потока каждый. 2.8 ГГц
|
||||
2тб озу в каждом.
|
||||
|
||||
cl05-1c:
|
||||
1 Asus RS720A-E12-RS24U
|
||||
2 процессора AMD EPYC 9274F 24 ядра 48 потоков каждый. 4.05 ГГц
|
||||
1тб озу.
|
||||
|
||||
7 ручная сборка
|
||||
MB Asus ProArt B650-Creator
|
||||
Процессор AMD Ryzen 9 7950X 16 ядер 32 потока каждый. 4.5 ГГц
|
||||
192гб озу каждый.
|
||||
|
||||
1 ручная сборка
|
||||
процессор AMD Ryzen Threadripper PRO 5995WX 64 ядра 128 потоков каждый. 2.7 ГГц
|
||||
512гб озу.
|
||||
|
||||
cl06-vsan:
|
||||
15 R320
|
||||
2 процессора Xeon(R) Gold 6342 24 ядра 48 потоков каждый. 2.8 ГГц
|
||||
1тб озу каждый.
|
||||
|
||||
Xeon(R) Gold 6226R 2.9 ГГц
|
||||
Xeon(R) Gold 6254 3.1 ГГц
|
||||
AMD EPYC 7543 2.8 ГГц
|
||||
AMD EPYC 9274F 4.05 ГГц
|
||||
AMD Ryzen 9 7950X 4.5 ГГц
|
||||
AMD Ryzen Threadripper PRO 5995WX 2.7 ГГц
|
||||
Xeon(R) Gold 6342 2.8 ГГц --->
|
||||
@@ -1,457 +1 @@
|
||||
|
||||
<cfset dt_finish=createDateTime(year(Now()),month(Now()),1,0,0,0)/>
|
||||
<cfset dt_start=dateAdd('m',-1,dt_finish)/>
|
||||
<cfset hours=dateDiff('h',dt_start,dt_finish)/>
|
||||
|
||||
Внимание! округление вверх при расчете метрик
|
||||
|
||||
<cfdump var=#dt_start#/>
|
||||
<cfdump var=#dt_finish#/>
|
||||
<cfdump var=#hours#/>
|
||||
|
||||
<!--- Нужно еще применить политики бесплатного минимума --->
|
||||
<!---
|
||||
<cfquery name="qCode" datasource="dwh">
|
||||
select distinct p.code
|
||||
from elma.deals d
|
||||
join elma.deals_services siv on (d.__id=ANY(siv.deal))
|
||||
join elma.service_parametrs p on (p.__id = ANY(siv.params))
|
||||
join elma.companies k on (d._companies=k.__id)
|
||||
join elma.additional_agreements aa on (aa.__id = ANY(siv.additional_agreement))
|
||||
join elma.aggrements a on (aa.contract_uid = a.__id)
|
||||
where p.type=3 AND aa.is_actual
|
||||
order by p.code
|
||||
</cfquery>
|
||||
<cfdump var=#qCode#/>
|
||||
|
||||
<cfquery name="qSpec" datasource="dwh">
|
||||
select k.id_klienta, p.code, p.price, p.discount, k.__name as contragent, a.__name as contract, d.__name as deal, siv.abstractive_service as abstract_service, siv.modifier, siv.user_description
|
||||
,p.__name as metric, p.ed_izm
|
||||
--, aa.is_actual
|
||||
from elma.deals d
|
||||
join elma.deals_services siv on (d.__id=ANY(siv.deal))
|
||||
join elma.service_parametrs p on (p.__id = ANY(siv.params))
|
||||
join elma.companies k on (d._companies=k.__id)
|
||||
join elma.additional_agreements aa on (aa.__id = ANY(siv.additional_agreement))
|
||||
join elma.aggrements a on (aa.contract_uid = a.__id)
|
||||
where p.type=3 AND aa.is_actual
|
||||
order by k.id_klienta, p.code
|
||||
</cfquery>
|
||||
здесь имеем список кодов с ценами и WZ. Каждому коду можно поставить в соответствие запрос, который даст по нему выборку. Изредка один запрос может вывести 2 кода, но разбить на 2 запроса легко. Кроме того, запросы можно объединить через union в один - может быть, так будет лучше читаться (быстрее выполняться не будет)
|
||||
<cfdump var=#qSpec#/>
|
||||
|
||||
|
||||
<cfquery name="qComputing" datasource="billing-vc">
|
||||
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 'unknown' 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 > 0
|
||||
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>
|
||||
<cfdump var=#qComputing#/>
|
||||
|
||||
<cfquery name="qStorage" datasource="billing-vc">
|
||||
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 'unknown' end as code,
|
||||
storage_profile_types.name as storage_profile_type_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 > 0
|
||||
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>
|
||||
<cfdump var=#qStorage#/>
|
||||
--->
|
||||
<!---
|
||||
"placement" "size_gb" "get_10k" "put_10k" "bytes_sent_gb"
|
||||
HOT_FREE_LIMIT 1 10 1 100
|
||||
--->
|
||||
<!--- надо дисконтировать не ГБ-часы а ГБ-месяцы --->
|
||||
<cfquery name="qS3Vol" datasource="billing-s3">
|
||||
select /* *** ниже дублирование кода агрегации round ceil etc, обратить внимание при правке */
|
||||
(sum(bucket_stat.usage_rgw_main_size_actual)/<cfqueryparam cfsqltype="cf_sql_integer" value=#hours#/>) as vol_B
|
||||
,round(sum(bucket_stat.usage_rgw_main_size_actual)/<cfqueryparam cfsqltype="cf_sql_integer" value=#hours#/>/1024/1024/1024) as vol_GB
|
||||
,greatest(round(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_substracted /*считается не в точности так, как в функции*/
|
||||
|
||||
,case
|
||||
when bucket_stat.placement_id = 1 then 'paas.s3.ceph'
|
||||
when bucket_stat.placement_id = 2 then 'paas.s3.cphc'
|
||||
else 'unknown' 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.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>
|
||||
<cfdump var=#qS3Vol#/>
|
||||
|
||||
<cfquery name="qS3OpsTrf" datasource="billing-s3">
|
||||
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 'unknown' end as code
|
||||
,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 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>
|
||||
<cfdump var=#qS3OpsTrf#/>
|
||||
|
||||
<!--- В одном месте user_id int в другом owner varchar --->
|
||||
|
||||
|
||||
|
||||
|
||||
<!--- Трафик хранится в той же таблице, что и остальной юзадж, можно было бы доставать в общем резалтсете
|
||||
<!--- расчет запихнут в функцию. Неделю этим не занимался - забыл все совершенно --->
|
||||
<cfquery name="qS3TrafficDefaultPlacement" datasource="billing-s3">
|
||||
select sum(bytes_sent) as bytes,
|
||||
--placement.name as placement,
|
||||
case
|
||||
when placement.name = 'COLD' then 'paas.s3.cphc'
|
||||
when placement.name = 'default-placement' then 'paas.s3.ceph'
|
||||
else 'unknown' end as code,
|
||||
'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 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, placement.name
|
||||
order by user_info.name;
|
||||
</cfquery>
|
||||
<cfdump var=#qS3TrafficDefaultPlacement#/> --->
|
||||
|
||||
|
||||
<!--- <cfquery name="qS3TrafficDefault" datasource="billing-s3">
|
||||
select sum(bytes_sent) as bytes,
|
||||
case
|
||||
when placement.name = 'COLD' then 'paas.s3.cphc'
|
||||
when placement.name = 'default-placement' then 'paas.s3.ceph'
|
||||
else 'unknown' end as code,
|
||||
'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 AND placement.name='default-placement'
|
||||
where s3billing.usage_bucket_by_user.bucketid='0'
|
||||
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
|
||||
order by user_info.name;
|
||||
</cfquery>
|
||||
<cfdump var=#qS3TrafficDefault#/> --->
|
||||
|
||||
<!---
|
||||
задача (вызванная сыростью базы биллинга)
|
||||
смапить код параметра с VDC (1:n)
|
||||
iaas.ngc.i31.ram-m
|
||||
iaas.ngc.a28.ram-m
|
||||
|
||||
cl01:
|
||||
7 хостов Lenovo ThinkSystem SR650 -[7X06CTO1WW]-
|
||||
2 процессора Xeon(R) Gold 6226R 16 ядер 32 потока каждый 2.9 ГГц
|
||||
1.25тб озу в каждом.
|
||||
В 4 из 7 есть по 4 GPU NVIDIA A16 16GB в каждом.
|
||||
|
||||
cl01-vsan:
|
||||
16 хостов Lenovo ThinkSystem SR650 -[7X06CTO1WW]-
|
||||
2 процессора Xeon(R) Gold 6226R 16 ядер 32 потока каждый 2.9 ГГц
|
||||
1.25тб озу в каждом.
|
||||
В 9 из 16 есть по 4 GPU NVIDIA A16 16GB в каждом.
|
||||
|
||||
cl02:
|
||||
10 Huawei 2488H V5
|
||||
4 процессора Xeon(R) Gold 6254 18 ядер 36 потоков каждый. 3.1 ГГц
|
||||
2тб озу в каждом.
|
||||
|
||||
5 Huawei Atlas 800 (Model 3010)
|
||||
2 процессора Xeon(R) Gold 6254 18 ядер 36 потоков каждый. 3.1 ГГц
|
||||
1.5тб озу в каждом.
|
||||
|
||||
cl04-vsan:
|
||||
10 Apex AR320-12
|
||||
2 процессора AMD EPYC 7543 32 ядра 64 потока каждый. 2.8 ГГц
|
||||
2тб озу в каждом.
|
||||
18 Apex AR320-12-E7543
|
||||
2 процессора AMD EPYC 7543 32 ядра 64 потока каждый. 2.8 ГГц
|
||||
2тб озу в каждом.
|
||||
|
||||
cl05-1c:
|
||||
1 Asus RS720A-E12-RS24U
|
||||
2 процессора AMD EPYC 9274F 24 ядра 48 потоков каждый. 4.05 ГГц
|
||||
1тб озу.
|
||||
|
||||
7 ручная сборка
|
||||
MB Asus ProArt B650-Creator
|
||||
Процессор AMD Ryzen 9 7950X 16 ядер 32 потока каждый. 4.5 ГГц
|
||||
192гб озу каждый.
|
||||
|
||||
1 ручная сборка
|
||||
процессор AMD Ryzen Threadripper PRO 5995WX 64 ядра 128 потоков каждый. 2.7 ГГц
|
||||
512гб озу.
|
||||
|
||||
cl06-vsan:
|
||||
15 R320
|
||||
2 процессора Xeon(R) Gold 6342 24 ядра 48 потоков каждый. 2.8 ГГц
|
||||
1тб озу каждый.
|
||||
|
||||
Xeon(R) Gold 6226R 2.9 ГГц
|
||||
Xeon(R) Gold 6254 3.1 ГГц
|
||||
AMD EPYC 7543 2.8 ГГц
|
||||
AMD EPYC 9274F 4.05 ГГц
|
||||
AMD Ryzen 9 7950X 4.5 ГГц
|
||||
AMD Ryzen Threadripper PRO 5995WX 2.7 ГГц
|
||||
Xeon(R) Gold 6342 2.8 ГГц --->
|
||||
|
||||
<!--- 2025-08-15 20:47:44 *** Операции S3 считаются не так, как написано в тарифе. Например, считается list. В тарифе вообще не описан минимальный лимит --->
|
||||
|
||||
<!--- BEGIN
|
||||
RETURN QUERY
|
||||
(
|
||||
select
|
||||
billing_per_user_fix_pl.placement as placement,
|
||||
(CASE
|
||||
WHEN ( billing_per_user_fix_pl.placement = 'HOT'
|
||||
) THEN greatest(ceil(sum(size)/1024/1024/1024)-1,0)
|
||||
WHEN ( not billing_per_user_fix_pl.placement = 'HOT'
|
||||
) THEN ceil(sum(size)/1024/1024/1024)
|
||||
END) AS size_GB,
|
||||
(CASE
|
||||
WHEN ( billing_per_user_fix_pl.placement = 'HOT'
|
||||
) THEN greatest(ceil(sum(get)/10000)-10,0)
|
||||
WHEN ( not billing_per_user_fix_pl.placement = 'HOT'
|
||||
) THEN ceil(sum(get)/10000)
|
||||
END) AS get_10k,
|
||||
(CASE
|
||||
WHEN ( billing_per_user_fix_pl.placement = 'HOT'
|
||||
) THEN greatest(ceil(sum(put)/10000)-1,0)
|
||||
WHEN ( not billing_per_user_fix_pl.placement = 'HOT'
|
||||
) THEN ceil(sum(put)/10000)
|
||||
END) AS put_10k,
|
||||
(CASE
|
||||
WHEN ( billing_per_user_fix_pl.placement = 'HOT'
|
||||
) then greatest(ceil(sum(bytes_sent)/1024/1024/1024)-100,0)
|
||||
WHEN ( not billing_per_user_fix_pl.placement = 'HOT'
|
||||
) THEN ceil(sum(bytes_sent)/1024/1024/1024)
|
||||
END) AS bytes_sent_GB
|
||||
from s3billing.billing_per_user_fix_pl(_ds,_df,_user)
|
||||
group by billing_per_user_fix_pl.placement
|
||||
UNION all
|
||||
select
|
||||
'HOT_FREE_LIMIT' as placement,
|
||||
'1' AS size_GB,
|
||||
'10' AS get_10k,
|
||||
'1' AS put_10k,
|
||||
'100' AS bytes_sent_GB
|
||||
);
|
||||
END; --->
|
||||
|
||||
<!---
|
||||
BEGIN
|
||||
RETURN QUERY
|
||||
|
||||
SELECT
|
||||
s3billing.bucket_info.name AS bucket_name,
|
||||
(case
|
||||
when ( s3billing.placement.name = 'default-placement') then 'HOT'
|
||||
WHEN ( not s3billing.placement.name = 'default-placement' ) THEN s3billing.placement.name
|
||||
end
|
||||
) as placement,
|
||||
coalesce(round(sum(usage_rgw_main_size_actual)/
|
||||
(SELECT (DATE_PART('day',
|
||||
((TO_TIMESTAMP(_df, 'YYYY-MM-DD HH24:MI:SS'))
|
||||
-TO_TIMESTAMP(_ds, 'YYYY-MM-DD HH24:MI:SS'))
|
||||
)*24+
|
||||
DATE_PART('hour',
|
||||
((TO_TIMESTAMP(_df, 'YYYY-MM-DD HH24:MI:SS'))
|
||||
-TO_TIMESTAMP(_ds, 'YYYY-MM-DD HH24:MI:SS'))
|
||||
)))
|
||||
|
||||
)::numeric,0) AS size
|
||||
,coalesce(s2.get, 0) AS get
|
||||
,coalesce(s2.put, 0) AS put
|
||||
,coalesce(s2.bytes_sent, 0) as bytes_sent
|
||||
FROM s3billing.bucket_stat
|
||||
INNER JOIN s3billing.placement ON s3billing.bucket_stat.placement_id=s3billing.placement.id
|
||||
INNER JOIN s3billing.bucket_info ON s3billing.bucket_stat.bucket_id=s3billing.bucket_info.id
|
||||
LEFT JOIN (
|
||||
SELECT
|
||||
s1.bucket_id AS bucket_id
|
||||
,s1.bucket_name AS bucket_name,
|
||||
(case
|
||||
when ( s1.placement = 'default-placement') then 'HOT'
|
||||
WHEN ( not s1.placement = 'default-placement' ) THEN s1.placement
|
||||
end
|
||||
) as placement
|
||||
,coalesce(sum(s1.get) ,0) AS get
|
||||
,coalesce(sum(s1.put) ,0) AS put
|
||||
,coalesce(sum(s1.bytes_sent), 0) AS bytes_sent
|
||||
FROM (
|
||||
SELECT
|
||||
s3billing.bucket_info.id AS bucket_id
|
||||
,s3billing.bucket_info.name AS bucket_name
|
||||
,(case
|
||||
when ( s3billing.placement.name = 'default-placement') then 'HOT'
|
||||
WHEN ( not s3billing.placement.name = 'default-placement' ) THEN s3billing.placement.name
|
||||
end
|
||||
) as placement
|
||||
,(CASE
|
||||
WHEN ( s3billing.category.name LIKE 'get%'
|
||||
OR s3billing.category.name LIKE 'head%'
|
||||
OR s3billing.category.name LIKE 'options%'
|
||||
) THEN coalesce(sum(ops), 0)
|
||||
END) AS get
|
||||
,(CASE
|
||||
WHEN ( s3billing.category.name LIKE 'put%'
|
||||
OR s3billing.category.name LIKE 'post%'
|
||||
OR s3billing.category.name LIKE 'patch%'
|
||||
OR s3billing.category.name LIKE 'list%'
|
||||
) THEN coalesce(sum(ops), 0)
|
||||
END) AS put
|
||||
,coalesce(sum(usage_bucket_by_user.bytes_sent), 0) AS bytes_sent
|
||||
|
||||
FROM
|
||||
s3billing.usage_bucket_by_user
|
||||
INNER JOIN s3billing.bucket_info ON s3billing.usage_bucket_by_user.bucketid = s3billing.bucket_info.id
|
||||
INNER JOIN s3billing.placement ON s3billing.bucket_info.placement_id = s3billing.placement.id
|
||||
INNER JOIN s3billing.user_info ON s3billing.usage_bucket_by_user.user_id = s3billing.user_info.id
|
||||
INNER JOIN s3billing.category ON s3billing.usage_bucket_by_user.category_id = s3billing.category.id
|
||||
|
||||
WHERE
|
||||
s3billing.user_info.name=_user
|
||||
AND s3billing.usage_bucket_by_user.time >=TO_TIMESTAMP(_ds, 'YYYY-MM-DD HH24:MI:SS')
|
||||
AND s3billing.usage_bucket_by_user.time < TO_TIMESTAMP(_df, 'YYYY-MM-DD HH24:MI:SS')
|
||||
GROUP BY
|
||||
s3billing.bucket_info.name
|
||||
,s3billing.placement.name
|
||||
,s3billing.category.name
|
||||
,s3billing.bucket_info.id
|
||||
) AS s1
|
||||
|
||||
GROUP BY
|
||||
s1.bucket_name
|
||||
,s1.bucket_id
|
||||
,s1.placement
|
||||
|
||||
ORDER BY
|
||||
s1.placement
|
||||
,s1.bucket_name
|
||||
|
||||
) AS s2 ON s2.bucket_id = s3billing.bucket_stat.bucket_id
|
||||
WHERE owner=_user
|
||||
AND timestamp_addition >= TO_TIMESTAMP(_ds, 'YYYY-MM-DD HH24:MI:SS')
|
||||
AND timestamp_addition < TO_TIMESTAMP(_df, 'YYYY-MM-DD HH24:MI:SS')
|
||||
GROUP BY
|
||||
s3billing.bucket_info.name
|
||||
,s3billing.placement.name
|
||||
,s3billing.bucket_stat.bucket_id
|
||||
,s2.get
|
||||
,s2.put
|
||||
,s2.bytes_sent
|
||||
ORDER BY
|
||||
s3billing.placement.name
|
||||
,s3billing.bucket_info.name
|
||||
;
|
||||
END; --->
|
||||
<!--- select * from s3billing.billing_per_user_fix_pl('2025-05-01 00:00:00','2025-06-01 00:00:00','1395'); --->
|
||||
|
||||
<cflocation url="payg.cfm" addtoken="No"/>
|
||||
@@ -0,0 +1,456 @@
|
||||
|
||||
<cfset dt_finish=createDateTime(year(Now()),month(Now()),1,0,0,0)/>
|
||||
<cfset dt_start=dateAdd('m',-1,dt_finish)/>
|
||||
<cfset hours=dateDiff('h',dt_start,dt_finish)/>
|
||||
|
||||
Внимание! округление вверх при расчете метрик
|
||||
|
||||
<cfdump var=#dt_start#/>
|
||||
<cfdump var=#dt_finish#/>
|
||||
<cfdump var=#hours#/>
|
||||
|
||||
<!--- Нужно еще применить политики бесплатного минимума --->
|
||||
|
||||
<cfquery name="qCode" datasource="dwh">
|
||||
select distinct p.code
|
||||
from elma.deals d
|
||||
join elma.deals_services siv on (d.__id=ANY(siv.deal))
|
||||
join elma.service_parametrs p on (p.__id = ANY(siv.params))
|
||||
join elma.companies k on (d._companies=k.__id)
|
||||
join elma.additional_agreements aa on (aa.__id = ANY(siv.additional_agreement))
|
||||
join elma.aggrements a on (aa.contract_uid = a.__id)
|
||||
where p.type=3 AND aa.is_actual
|
||||
order by p.code
|
||||
</cfquery>
|
||||
<!--- <cfdump var=#qCode#/> --->
|
||||
|
||||
<cfquery name="qSpec" datasource="dwh">
|
||||
select k.id_klienta as wz, p.code, p.price, p.discount, k.__name as contragent, a.__name as contract, d.__name as deal, siv.abstractive_service as abstract_service, siv.modifier, siv.user_description
|
||||
,p.__name as metric, p.ed_izm
|
||||
--, aa.is_actual
|
||||
from elma.deals d
|
||||
join elma.deals_services siv on (d.__id=ANY(siv.deal))
|
||||
join elma.service_parametrs p on (p.__id = ANY(siv.params))
|
||||
join elma.companies k on (d._companies=k.__id)
|
||||
join elma.additional_agreements aa on (aa.__id = ANY(siv.additional_agreement))
|
||||
join elma.aggrements a on (aa.contract_uid = a.__id)
|
||||
where p.type=3 AND aa.is_actual
|
||||
order by k.id_klienta, p.code
|
||||
</cfquery>
|
||||
<!--- здесь имеем список кодов с ценами и WZ. Каждому коду можно поставить в соответствие запрос, который даст по нему выборку. Изредка один запрос может вывести 2 кода, но разбить на 2 запроса легко. Кроме того, запросы можно объединить через union в один - может быть, так будет лучше читаться (быстрее выполняться не будет) --->
|
||||
<cfdump var=#qSpec#/>
|
||||
|
||||
|
||||
<cfquery name="qComputing" datasource="billing-vc">
|
||||
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 > 0
|
||||
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>
|
||||
<!--- <cfdump var=#qComputing#/> --->
|
||||
|
||||
<!--- переделать storage_profile_types с расшифровкой ssd, sata, можно прямо до каталожного кода --->
|
||||
<cfquery name="qStorage" datasource="billing-vc">
|
||||
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 > 0
|
||||
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>
|
||||
<!--- <cfdump var=#qStorage#/> --->
|
||||
|
||||
<!---
|
||||
"placement" "size_gb" "get_10k" "put_10k" "bytes_sent_gb"
|
||||
HOT_FREE_LIMIT 1 10 1 100
|
||||
--->
|
||||
<!--- надо дисконтировать не ГБ-часы а ГБ-месяцы --->
|
||||
<cfquery name="qS3Vol" datasource="billing-s3">
|
||||
select /* *** ниже дублирование кода агрегации - round ceil etc, обратить внимание при правке */
|
||||
(sum(bucket_stat.usage_rgw_main_size_actual)/<cfqueryparam cfsqltype="cf_sql_integer" value=#hours#/>) as vol_B
|
||||
,round(sum(bucket_stat.usage_rgw_main_size_actual)/<cfqueryparam cfsqltype="cf_sql_integer" value=#hours#/>/1024/1024/1024) as vol_GB
|
||||
,greatest(round(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.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>
|
||||
<!--- <cfdump var=#qS3Vol#/> --->
|
||||
|
||||
<cfquery name="qS3OpsTrf" datasource="billing-s3">
|
||||
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 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>
|
||||
<!--- <cfdump var=#qS3OpsTrf#/> --->
|
||||
|
||||
<cfquery name="qUnifiedMetric" dbType="query">
|
||||
select wz, code || '.cpu-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', 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', get as raw_metric, get_10k as metric, get_10k_free_tier_subtracted as chargeable_metric from qS3OpsTrf
|
||||
union all
|
||||
select wz, code || '.put', put as raw_metric, put_10k as metric, put_10k_free_tier_subtracted as chargeable_metric from qS3OpsTrf
|
||||
union all
|
||||
select wz, code || '.trf', bytes_sent as raw_metric, bytes_sent_gb as metric, bytes_sent_gb_free_tier_subtracted as chargeable_metric from qS3OpsTrf
|
||||
</cfquery>
|
||||
<cfdump var=#qUnifiedMetric#/>
|
||||
|
||||
<cfquery name="qCharge" dbType="query">
|
||||
SELECT
|
||||
wz
|
||||
,code
|
||||
,price
|
||||
,discount
|
||||
,contragent
|
||||
,contract
|
||||
,deal
|
||||
,abstract_service
|
||||
,modifier
|
||||
,user_description
|
||||
,ed_izm
|
||||
FROM qSpec as s, qUnifiedMetric as m WHERE s.wz=m.wz AND s.code=m.code
|
||||
</cfquery>
|
||||
<!--- looks like QoQ does not support join syntax, at least of Lucee 5.4--->
|
||||
<cfdump var=#qCharge#/>
|
||||
<!---
|
||||
--->
|
||||
<!--- --,m.*
|
||||
--,s.price*(100-s.discount)/100 as discounted_price
|
||||
--,s.price*(100-s.discount)/100*m.chargeable_metric as charge --->
|
||||
<!--- В одном месте user_id int в другом owner varchar --->
|
||||
|
||||
<!---
|
||||
задача (вызванная сыростью базы биллинга)
|
||||
смапить код параметра с VDC (1:n)
|
||||
iaas.ngc.i31.ram-m
|
||||
iaas.ngc.a28.ram-m
|
||||
|
||||
cl01:
|
||||
7 хостов Lenovo ThinkSystem SR650 -[7X06CTO1WW]-
|
||||
2 процессора Xeon(R) Gold 6226R 16 ядер 32 потока каждый 2.9 ГГц
|
||||
1.25тб озу в каждом.
|
||||
В 4 из 7 есть по 4 GPU NVIDIA A16 16GB в каждом.
|
||||
|
||||
cl01-vsan:
|
||||
16 хостов Lenovo ThinkSystem SR650 -[7X06CTO1WW]-
|
||||
2 процессора Xeon(R) Gold 6226R 16 ядер 32 потока каждый 2.9 ГГц
|
||||
1.25тб озу в каждом.
|
||||
В 9 из 16 есть по 4 GPU NVIDIA A16 16GB в каждом.
|
||||
|
||||
cl02:
|
||||
10 Huawei 2488H V5
|
||||
4 процессора Xeon(R) Gold 6254 18 ядер 36 потоков каждый. 3.1 ГГц
|
||||
2тб озу в каждом.
|
||||
|
||||
5 Huawei Atlas 800 (Model 3010)
|
||||
2 процессора Xeon(R) Gold 6254 18 ядер 36 потоков каждый. 3.1 ГГц
|
||||
1.5тб озу в каждом.
|
||||
|
||||
cl04-vsan:
|
||||
10 Apex AR320-12
|
||||
2 процессора AMD EPYC 7543 32 ядра 64 потока каждый. 2.8 ГГц
|
||||
2тб озу в каждом.
|
||||
18 Apex AR320-12-E7543
|
||||
2 процессора AMD EPYC 7543 32 ядра 64 потока каждый. 2.8 ГГц
|
||||
2тб озу в каждом.
|
||||
|
||||
cl05-1c:
|
||||
1 Asus RS720A-E12-RS24U
|
||||
2 процессора AMD EPYC 9274F 24 ядра 48 потоков каждый. 4.05 ГГц
|
||||
1тб озу.
|
||||
|
||||
7 ручная сборка
|
||||
MB Asus ProArt B650-Creator
|
||||
Процессор AMD Ryzen 9 7950X 16 ядер 32 потока каждый. 4.5 ГГц
|
||||
192гб озу каждый.
|
||||
|
||||
1 ручная сборка
|
||||
процессор AMD Ryzen Threadripper PRO 5995WX 64 ядра 128 потоков каждый. 2.7 ГГц
|
||||
512гб озу.
|
||||
|
||||
cl06-vsan:
|
||||
15 R320
|
||||
2 процессора Xeon(R) Gold 6342 24 ядра 48 потоков каждый. 2.8 ГГц
|
||||
1тб озу каждый.
|
||||
|
||||
Xeon(R) Gold 6226R 2.9 ГГц
|
||||
Xeon(R) Gold 6254 3.1 ГГц
|
||||
AMD EPYC 7543 2.8 ГГц
|
||||
AMD EPYC 9274F 4.05 ГГц
|
||||
AMD Ryzen 9 7950X 4.5 ГГц
|
||||
AMD Ryzen Threadripper PRO 5995WX 2.7 ГГц
|
||||
Xeon(R) Gold 6342 2.8 ГГц --->
|
||||
|
||||
<!--- 2025-08-15 20:47:44 *** Операции S3 считаются не так, как написано в тарифе. Например, считается list. В тарифе вообще не описан минимальный лимит --->
|
||||
|
||||
<!--- BEGIN
|
||||
RETURN QUERY
|
||||
(
|
||||
select
|
||||
billing_per_user_fix_pl.placement as placement,
|
||||
(CASE
|
||||
WHEN ( billing_per_user_fix_pl.placement = 'HOT'
|
||||
) THEN greatest(ceil(sum(size)/1024/1024/1024)-1,0)
|
||||
WHEN ( not billing_per_user_fix_pl.placement = 'HOT'
|
||||
) THEN ceil(sum(size)/1024/1024/1024)
|
||||
END) AS size_GB,
|
||||
(CASE
|
||||
WHEN ( billing_per_user_fix_pl.placement = 'HOT'
|
||||
) THEN greatest(ceil(sum(get)/10000)-10,0)
|
||||
WHEN ( not billing_per_user_fix_pl.placement = 'HOT'
|
||||
) THEN ceil(sum(get)/10000)
|
||||
END) AS get_10k,
|
||||
(CASE
|
||||
WHEN ( billing_per_user_fix_pl.placement = 'HOT'
|
||||
) THEN greatest(ceil(sum(put)/10000)-1,0)
|
||||
WHEN ( not billing_per_user_fix_pl.placement = 'HOT'
|
||||
) THEN ceil(sum(put)/10000)
|
||||
END) AS put_10k,
|
||||
(CASE
|
||||
WHEN ( billing_per_user_fix_pl.placement = 'HOT'
|
||||
) then greatest(ceil(sum(bytes_sent)/1024/1024/1024)-100,0)
|
||||
WHEN ( not billing_per_user_fix_pl.placement = 'HOT'
|
||||
) THEN ceil(sum(bytes_sent)/1024/1024/1024)
|
||||
END) AS bytes_sent_GB
|
||||
from s3billing.billing_per_user_fix_pl(_ds,_df,_user)
|
||||
group by billing_per_user_fix_pl.placement
|
||||
UNION all
|
||||
select
|
||||
'HOT_FREE_LIMIT' as placement,
|
||||
'1' AS size_GB,
|
||||
'10' AS get_10k,
|
||||
'1' AS put_10k,
|
||||
'100' AS bytes_sent_GB
|
||||
);
|
||||
END; --->
|
||||
|
||||
<!---
|
||||
BEGIN
|
||||
RETURN QUERY
|
||||
|
||||
SELECT
|
||||
s3billing.bucket_info.name AS bucket_name,
|
||||
(case
|
||||
when ( s3billing.placement.name = 'default-placement') then 'HOT'
|
||||
WHEN ( not s3billing.placement.name = 'default-placement' ) THEN s3billing.placement.name
|
||||
end
|
||||
) as placement,
|
||||
coalesce(round(sum(usage_rgw_main_size_actual)/
|
||||
(SELECT (DATE_PART('day',
|
||||
((TO_TIMESTAMP(_df, 'YYYY-MM-DD HH24:MI:SS'))
|
||||
-TO_TIMESTAMP(_ds, 'YYYY-MM-DD HH24:MI:SS'))
|
||||
)*24+
|
||||
DATE_PART('hour',
|
||||
((TO_TIMESTAMP(_df, 'YYYY-MM-DD HH24:MI:SS'))
|
||||
-TO_TIMESTAMP(_ds, 'YYYY-MM-DD HH24:MI:SS'))
|
||||
)))
|
||||
|
||||
)::numeric,0) AS size
|
||||
,coalesce(s2.get, 0) AS get
|
||||
,coalesce(s2.put, 0) AS put
|
||||
,coalesce(s2.bytes_sent, 0) as bytes_sent
|
||||
FROM s3billing.bucket_stat
|
||||
INNER JOIN s3billing.placement ON s3billing.bucket_stat.placement_id=s3billing.placement.id
|
||||
INNER JOIN s3billing.bucket_info ON s3billing.bucket_stat.bucket_id=s3billing.bucket_info.id
|
||||
LEFT JOIN (
|
||||
SELECT
|
||||
s1.bucket_id AS bucket_id
|
||||
,s1.bucket_name AS bucket_name,
|
||||
(case
|
||||
when ( s1.placement = 'default-placement') then 'HOT'
|
||||
WHEN ( not s1.placement = 'default-placement' ) THEN s1.placement
|
||||
end
|
||||
) as placement
|
||||
,coalesce(sum(s1.get) ,0) AS get
|
||||
,coalesce(sum(s1.put) ,0) AS put
|
||||
,coalesce(sum(s1.bytes_sent), 0) AS bytes_sent
|
||||
FROM (
|
||||
SELECT
|
||||
s3billing.bucket_info.id AS bucket_id
|
||||
,s3billing.bucket_info.name AS bucket_name
|
||||
,(case
|
||||
when ( s3billing.placement.name = 'default-placement') then 'HOT'
|
||||
WHEN ( not s3billing.placement.name = 'default-placement' ) THEN s3billing.placement.name
|
||||
end
|
||||
) as placement
|
||||
,(CASE
|
||||
WHEN ( s3billing.category.name LIKE 'get%'
|
||||
OR s3billing.category.name LIKE 'head%'
|
||||
OR s3billing.category.name LIKE 'options%'
|
||||
) THEN coalesce(sum(ops), 0)
|
||||
END) AS get
|
||||
,(CASE
|
||||
WHEN ( s3billing.category.name LIKE 'put%'
|
||||
OR s3billing.category.name LIKE 'post%'
|
||||
OR s3billing.category.name LIKE 'patch%'
|
||||
OR s3billing.category.name LIKE 'list%'
|
||||
) THEN coalesce(sum(ops), 0)
|
||||
END) AS put
|
||||
,coalesce(sum(usage_bucket_by_user.bytes_sent), 0) AS bytes_sent
|
||||
|
||||
FROM
|
||||
s3billing.usage_bucket_by_user
|
||||
INNER JOIN s3billing.bucket_info ON s3billing.usage_bucket_by_user.bucketid = s3billing.bucket_info.id
|
||||
INNER JOIN s3billing.placement ON s3billing.bucket_info.placement_id = s3billing.placement.id
|
||||
INNER JOIN s3billing.user_info ON s3billing.usage_bucket_by_user.user_id = s3billing.user_info.id
|
||||
INNER JOIN s3billing.category ON s3billing.usage_bucket_by_user.category_id = s3billing.category.id
|
||||
|
||||
WHERE
|
||||
s3billing.user_info.name=_user
|
||||
AND s3billing.usage_bucket_by_user.time >=TO_TIMESTAMP(_ds, 'YYYY-MM-DD HH24:MI:SS')
|
||||
AND s3billing.usage_bucket_by_user.time < TO_TIMESTAMP(_df, 'YYYY-MM-DD HH24:MI:SS')
|
||||
GROUP BY
|
||||
s3billing.bucket_info.name
|
||||
,s3billing.placement.name
|
||||
,s3billing.category.name
|
||||
,s3billing.bucket_info.id
|
||||
) AS s1
|
||||
|
||||
GROUP BY
|
||||
s1.bucket_name
|
||||
,s1.bucket_id
|
||||
,s1.placement
|
||||
|
||||
ORDER BY
|
||||
s1.placement
|
||||
,s1.bucket_name
|
||||
|
||||
) AS s2 ON s2.bucket_id = s3billing.bucket_stat.bucket_id
|
||||
WHERE owner=_user
|
||||
AND timestamp_addition >= TO_TIMESTAMP(_ds, 'YYYY-MM-DD HH24:MI:SS')
|
||||
AND timestamp_addition < TO_TIMESTAMP(_df, 'YYYY-MM-DD HH24:MI:SS')
|
||||
GROUP BY
|
||||
s3billing.bucket_info.name
|
||||
,s3billing.placement.name
|
||||
,s3billing.bucket_stat.bucket_id
|
||||
,s2.get
|
||||
,s2.put
|
||||
,s2.bytes_sent
|
||||
ORDER BY
|
||||
s3billing.placement.name
|
||||
,s3billing.bucket_info.name
|
||||
;
|
||||
END; --->
|
||||
<!--- select * from s3billing.billing_per_user_fix_pl('2025-05-01 00:00:00','2025-06-01 00:00:00','1395'); --->
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
<cfsilent>
|
||||
<!---Замещает любую переменную (*** небезопасно) тега layout:page --->
|
||||
<!---Тег layout:page проглатывает собственный контент, и вместо него после закрытия выводит разметку на основании атрибутов (при открытии тега он формирует переменные - фрагменты разметки - по шаблону) и вложенных тегов layout:attribute (которые по закрытии тега на самом деле перезаписывают переменные в layout:page).
|
||||
Вложенные теги удобны, чтобы передавать читабельную разметку, а не строку в кавычках.--->
|
||||
<cfparam name="ATTRIBUTES.name"/><!---имя переменной layout:page, чаще всего title, controls--->
|
||||
<!--- ATTRIBUTES.value --->
|
||||
<cfparam name="ATTRIBUTES.append" default=""/><!---before,after--->
|
||||
|
||||
<cfif thisTag.executionMode IS "end">
|
||||
|
||||
<cfassociate basetag="cf_page"/>
|
||||
<cfset layoutTemplate=getBaseTagData('cf_page',1)/>
|
||||
|
||||
<cfif structKeyExists(ATTRIBUTES, "value")>
|
||||
<cfset value=ATTRIBUTES.value/>
|
||||
<cfelse>
|
||||
<cfset value=thisTag.generatedContent/>
|
||||
</cfif>
|
||||
|
||||
<!---ниже в комментариях предполагается, что мы меняем фрагмент разметки, например, controls, но на самом деле это может быть любая переменная тега layout:page--->
|
||||
<cfif structKeyExists(layoutTemplate,"#ATTRIBUTES.name#") AND lcase(ATTRIBUTES.append) EQ "before">
|
||||
<!---дописать в начало фрагмента разметки с именем name, сгенерированного layout:page, например, controls--->
|
||||
<cfset "layoutTemplate.#ATTRIBUTES.name#" = value & layoutTemplate["#ATTRIBUTES.name#"]/>
|
||||
<cfelseif structKeyExists(layoutTemplate,"#ATTRIBUTES.name#") AND lcase(ATTRIBUTES.append) EQ "after">
|
||||
<!---дописать в конец фрагмента разметки с именем name,, сгенерированного layout:page, например, controls--->
|
||||
<cfset "layoutTemplate.#ATTRIBUTES.name#" = layoutTemplate["#ATTRIBUTES.name#"] & value/>
|
||||
<cfelse>
|
||||
<!---заменить фрагмент разметки с именем name, сгенерированный layout:page--->
|
||||
<cfset "layoutTemplate.#ATTRIBUTES.name#"= value/>
|
||||
</cfif>
|
||||
<cfset thisTag.generatedContent=""/>
|
||||
</cfif>
|
||||
</cfsilent>
|
||||
@@ -0,0 +1,43 @@
|
||||
<cfsilent>
|
||||
<cfimport prefix="m" taglib="../lib"/>
|
||||
<cfimport prefix="c" taglib="../lib/controls"/>
|
||||
<!---*** идея включить титул в метаданные была не совсем пустой, но когда титул определяется в селекте, это не слишком удобно --->
|
||||
<cfassociate basetag="cf_grid_head" datacollection="headersArray"/>
|
||||
<cfset envelope=getBaseTagData('cf_grid_head',1)/>
|
||||
|
||||
<cfparam name="ATTRIBUTES.title" type="string" default="#envelope.ATTRIBUTES.titleMap[ATTRIBUTES.name].title#"/>
|
||||
<cfparam name="ATTRIBUTES.name" type="string"/><!--- Заголовок указвается на том поле, по которому будет сортировка, а не на том, которе отображается --->
|
||||
<cfparam name="ATTRIBUTES.arrows" type="boolean" default="Yes"/>
|
||||
|
||||
<cfset attributeList="name,arrows,title"/>
|
||||
|
||||
<!--- В данном случае реализован подход: дополнительные атрибуты передаются вниз.
|
||||
Другой вариант - создавать атрибут extra, в который писать суффикс QueryString.
|
||||
Первый подход, использованный здесь, позволяет иметь доступ к дополнительным атрибутам, но непонятно, зачем - ведь их имена все равно неизвестны.
|
||||
Очевидный минус этого подхода - возможный конфликт имен с именами существующих атрибутов --->
|
||||
<cfset extraAttributes=structNew()/>
|
||||
|
||||
<!--- дополнительные атрибуты родительского тега--->
|
||||
<cfif StructKeyExists(envelope, "extraAttributes") AND isStruct(envelope.extraAttributes)>
|
||||
<cfloop collection=#envelope.extraAttributes# item="attr">
|
||||
<cfif NOT listFindNoCase(attributeList, attr)><!--- проверка относительно локальных атрибутов, чтобы их не перетереть--->
|
||||
<cfset val="#structFind(envelope.extraAttributes, attr)#"/>
|
||||
<cfif IsSimpleValue(val)>
|
||||
<cfset structInsert(extraAttributes, attr, val)/>
|
||||
</cfif>
|
||||
</cfif>
|
||||
</cfloop>
|
||||
</cfif>
|
||||
|
||||
<cfloop collection=#ATTRIBUTES# item="attr">
|
||||
<cfif NOT listFindNoCase(attributeList, attr)>
|
||||
<cfset val="#structFind(ATTRIBUTES, attr)#"/>
|
||||
<cfif IsSimpleValue(val)>
|
||||
<cfset structInsert(extraAttributes, attr, val, "Yes")/><!--- локальные атрибуты перетрут родительские --->
|
||||
</cfif>
|
||||
</cfif>
|
||||
</cfloop>
|
||||
|
||||
|
||||
</cfsilent><cfif thisTag.executionMode is "end"><cfoutput>#ATTRIBUTES.title#
|
||||
<cfif ATTRIBUTES.arrows><c:order_arrows sortArray=#envelope.ATTRIBUTES.sortArray# n=#envelope.ATTRIBUTES.titleMap[ATTRIBUTES.name].ordinal# attributeCollection=#extraAttributes#/></cfif></cfoutput></cfif>
|
||||
@@ -0,0 +1,10 @@
|
||||
<!--- It is strongly recommended to keep this tag closed. Unclosed tag generates output into the variable ATTRIBUTES.output only, which may be confusing --->
|
||||
<cfif thisTag.executionMode IS "end" OR NOT thisTag.hasEndTag>
|
||||
<cfparam name="ATTRIBUTES.backUrl" type="string" default="."/>
|
||||
<cfparam name="ATTRIBUTES.enable" type="boolean" default="No"/>
|
||||
<cfoutput>
|
||||
<button type="submit" name="save" class="maincontrol"<cfif NOT ATTRIBUTES.enable> disabled</cfif>>#request.i18("Сохранить","Save")#</button>
|
||||
<button type="submit" name="saveAndClose" class="maincontrol"<cfif NOT ATTRIBUTES.enable> disabled</cfif>>#request.i18("Сохранить и закрыть","Save and Close")#</button>
|
||||
<button type="button" name="close" class="maincontrol" onClick="document.location.href='#ATTRIBUTES.backUrl#'">#request.i18("Закрыть","Close")#</button>
|
||||
</cfoutput>
|
||||
</cfif>
|
||||
@@ -0,0 +1,10 @@
|
||||
<cfsilent>
|
||||
<cfparam name="ATTRIBUTES.title" default=""/>
|
||||
<!---
|
||||
<cfset var content=thisTag.generagedContent/>
|
||||
|
||||
--->
|
||||
</cfsilent><!---
|
||||
---><cfif thisTag.executionMode is "start"><div class="tr">
|
||||
<div class="th"><cfoutput>#ATTRIBUTES.title#</cfoutput></div><div class="td">
|
||||
<cfelseif thisTag.executionMode is "end"></div></div></cfif>
|
||||
@@ -0,0 +1,8 @@
|
||||
<!--- It is strongly recommended to keep this tag closed. Unclosed tag generates output into the variable ATTRIBUTES.output only, which may be confusing --->
|
||||
<cfif thisTag.executionMode IS "end" OR NOT thisTag.hasEndTag>
|
||||
<cfparam name="ATTRIBUTES.backUrl" type="string" default=""/>
|
||||
<cfoutput>
|
||||
<button type="submit" name="saveAndClose" class="maincontrol">#request.i18("Применить","Apply")#</button>
|
||||
<button type="submit" name="resetAndClose" class="maincontrol">#request.i18("Снять","Reset")#</button>
|
||||
<button type="button" name="close" onClick="document.location.href='#ATTRIBUTES.backUrl#'" class="maincontrol">#request.i18("Закрыть","Close")#</button></cfoutput>
|
||||
</cfif>
|
||||
@@ -0,0 +1,24 @@
|
||||
<!--- It is strongly recommended to keep this tag closed. Unclosed tag generates output into the variable ATTRIBUTES.output only, which may be confusing --->
|
||||
<!---v0.2 10:07 02.01.2019 - skipped url params--->
|
||||
<cfif thisTag.executionMode IS "end" OR NOT thisTag.hasEndTag>
|
||||
<cfparam name="ATTRIBUTES.filterUrl" type="string" default=""/>
|
||||
<cfparam name="ATTRIBUTES.filter" type="struct" default=#structNew()#/>
|
||||
<cfparam name="ATTRIBUTES.fwx" type="string" default=""/>
|
||||
|
||||
<cfset qString="#ATTRIBUTES.fwx#"/>
|
||||
|
||||
<!---Чтобы передавать параметры в URL (и не пользоваться сессией), надо правильно форматировать параметры всех типов--->
|
||||
<!--- <cfloop collection=#ATTRIBUTES.filter# item="item">
|
||||
<cftry>
|
||||
<cfset fltr=structFind(ATTRIBUTES.filter,item)/>
|
||||
<cfset qString=listAppend(qString, "#item#=#fltr.val#", "&")/>
|
||||
<cfcatch type="ANY"></cfcatch>
|
||||
</cftry>
|
||||
</cfloop>--->
|
||||
|
||||
<cfset filterOn=request.filterOn(ATTRIBUTES.filter)/>
|
||||
|
||||
<!--- actually, any non-empty string can be assigned to reset_filter --->
|
||||
<cfoutput><a href="#ATTRIBUTES.filterUrl#?#qString#"><cfif filterOn><b>#request.i18("Фильтр...","Filter")#</b><cfelse>#request.i18("Фильтр","Filter")#</cfif></b></a>
|
||||
<cfif filterOn><a href="#request.thisPage#?reset_filter=yes">(#request.i18("снять","reset")#)</a></cfif></cfoutput>
|
||||
</cfif>
|
||||
@@ -0,0 +1,18 @@
|
||||
<cfsilent>
|
||||
<cfparam name="ATTRIBUTES.titleMap" default=#structNew()#/>
|
||||
<cfparam name="ATTRIBUTES.sortArray" default=#arrayNew(1)#/>
|
||||
|
||||
<cfset attributeList="titleMap,sortArray"/>
|
||||
|
||||
<cfset extraAttributes=structNew()/>
|
||||
<cfloop collection=#ATTRIBUTES# item="attr">
|
||||
<cfif NOT listFindNoCase(attributeList, attr)>
|
||||
<cfset val="#structFind(ATTRIBUTES, attr)#"/>
|
||||
<cfif IsSimpleValue(val)>
|
||||
<cfset structInsert(extraAttributes, attr, val)/>
|
||||
</cfif>
|
||||
</cfif>
|
||||
</cfloop>
|
||||
|
||||
</cfsilent><!---
|
||||
---><cfif thisTag.executionMode is "start"><tr><cfelseif thisTag.executionMode is "end"></tr></cfif>
|
||||
@@ -0,0 +1,82 @@
|
||||
<cfsilent>
|
||||
<cfimport prefix="m" taglib="../lib"/>
|
||||
<cfimport prefix="c" taglib="../lib/controls"/>
|
||||
|
||||
<cfparam name="ATTRIBUTES.useSummary" default="yes"/>
|
||||
<cfparam name="ATTRIBUTES.addtionalUrlParams" type="string" default=""/>
|
||||
<cfparam name="ATTRIBUTES.self" default=""/>
|
||||
<cfparam name="ATTRIBUTES.recordCount" default="0"/>
|
||||
<cfparam name="ATTRIBUTES.totalCount" default="0"/>
|
||||
<cfparam name="ATTRIBUTES.recordsPerPage" default="500"/>
|
||||
<cfparam name="ATTRIBUTES.footerOut" default=""/>
|
||||
<cfparam name="ATTRIBUTES.excelLink" default="No"/>
|
||||
<cfparam name="ATTRIBUTES.jsonLink" default="No"/>
|
||||
<cfparam name="ATTRIBUTES.buttonNew" default="No"/>
|
||||
<cfparam name="ATTRIBUTES.buttonNewTitle" default="Создать"/>
|
||||
<cfparam name="ATTRIBUTES.urlNew" default=""/>
|
||||
|
||||
<cfset UrlSuffix=""/>
|
||||
<cfif len(ATTRIBUTES.addtionalUrlParams) GT 0>
|
||||
<cfset UrlSuffix="&#ATTRIBUTES.addtionalUrlParams#"/>
|
||||
</cfif>
|
||||
<cfif len(ATTRIBUTES.self) GT 0>
|
||||
<cfset UrlSuffix="&track=#ATTRIBUTES.self#"/>
|
||||
</cfif>
|
||||
|
||||
|
||||
<c:paginator
|
||||
thisPage=#request.thisPage#
|
||||
recordCount=#ATTRIBUTES.recordCount#
|
||||
recordsPerPage=#ATTRIBUTES.recordsPerPage#
|
||||
self=#ATTRIBUTES.self#
|
||||
addtionalUrlParams=#ATTRIBUTES.addtionalUrlParams#
|
||||
output="paginator"/>
|
||||
|
||||
</cfsilent>
|
||||
|
||||
<cfoutput>
|
||||
<cfif ATTRIBUTES.useSummary>
|
||||
<div class="table wide" style="margin:3px 0;">
|
||||
<div class="td" style="height:2em; line-height:2em; padding-left:0; vertical-align:middle;">
|
||||
|
||||
<cfif ATTRIBUTES.buttonNew>
|
||||
<button type="button" class="maincontrol" onclick="document.location.href='#ATTRIBUTES.urlNew#'" style="margin:.0 1.5em 0 0;">
|
||||
<a href="#ATTRIBUTES.urlNew#">#ATTRIBUTES.buttonNewTitle#</a>
|
||||
</button>
|
||||
<cfelse>
|
||||
<div style="display:inline-block; width:1em;"/> </div>
|
||||
</cfif>
|
||||
|
||||
<cfif (ATTRIBUTES.recordCount GE 0)>
|
||||
Выбрано <b>#ATTRIBUTES.recordCount#</b>
|
||||
<cfif (ATTRIBUTES.totalCount GE 0)>
|
||||
из <b>#ATTRIBUTES.totalCount#</b>
|
||||
</cfif>
|
||||
</cfif>
|
||||
|
||||
<cfif ATTRIBUTES.excelLink>
|
||||
<a href="#request.thisPage#?output_xls#UrlSuffix#" title="экспорт в Excel" style="margin-left:.5em; height:100%;" target="_blank"><img src="img/xls.gif" style="vertical-align:text-bottom;"/></a>
|
||||
</cfif>
|
||||
<cfif ATTRIBUTES.jsonLink>
|
||||
<a href="#request.thisPage#?output_json#UrlSuffix#" title="экспорт в json" style="margin-left:.5em; height:100%;" target="_blank"><img src="img/json.svg" style="vertical-align:text-bottom;" width="13" height="13"/></a>
|
||||
</cfif>
|
||||
|
||||
</div>
|
||||
<div class="td r">
|
||||
#paginator.links#
|
||||
</div>
|
||||
</div>
|
||||
</cfif>
|
||||
</cfoutput>
|
||||
|
||||
<cfif len(ATTRIBUTES.footerOut)>
|
||||
<cfsavecontent variable="CALLER.#ATTRIBUTES.footerOut#">
|
||||
<cfoutput>
|
||||
<div class="wide r" style="margin:0.3em">
|
||||
#paginator.links#
|
||||
</div>
|
||||
</cfoutput>
|
||||
</cfsavecontent>
|
||||
</cfif>
|
||||
|
||||
<cfexit method="exittag"/>
|
||||
@@ -0,0 +1,99 @@
|
||||
<cfsilent>
|
||||
<cfparam name="ATTRIBUTES.qRead" type="query"/>
|
||||
<cfparam name="ATTRIBUTES.convertSnakeToCamel" type="boolean" default=true/>
|
||||
<!---<cfdump var=#qRead#/>
|
||||
<cfdump var=#ATTRIBUTES.titleMap#/>
|
||||
<cfabort/>--->
|
||||
|
||||
<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="escape4json"
|
||||
returntype="string"
|
||||
output="false"
|
||||
hint="escape string for json format">
|
||||
<cfargument name="s" type="string" required="true" />
|
||||
<cfreturn #reReplace(ARGUMENTS.camel,"([A-Z])","_\l\1","ALL")#/>
|
||||
</cffunction> --->
|
||||
|
||||
<!--- <cffunction name="query2array">
|
||||
<cfargument name="qry" type="query" required="true"/><!--- column names should not contain commas --->
|
||||
<cfargument name="convertSnakeToCamel" type="boolean" default=true/><cfsilent>
|
||||
|
||||
</cffunction> --->
|
||||
|
||||
<!--- <cffunction name="query2json"
|
||||
output="true"
|
||||
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/><cfsilent>
|
||||
<cfset var columnsIn=#qry.columnList()#/>
|
||||
<cfset var columnsOut=""/>
|
||||
<cfif arguments.convertSnakeToCamel>
|
||||
<cfloop list=#columnsIn# item="col">
|
||||
<cfset columnsOut=listAppend(columnsOut,snake2camel(col))/>
|
||||
</cfloop>
|
||||
<cfelse>
|
||||
<cfset columnsOut=#columnsIn#/>
|
||||
</cfif>
|
||||
</cfsilent>[<cfoutput query=#qry#>{<cfloop index="i" from="1" to=#listLen(columnsOut)#>"#listGetAt(#columnsOut#,i)#":"#qry[listGetAt(#columnsIn#,i)]#"<cfif #i# LT #listLen(columnsOut)#>,</cfif></cfloop>}<cfif #qry.currentRow()# LT #qry.recordCount()#>,</cfif></cfoutput>]
|
||||
</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>
|
||||
|
||||
<!--- <cfset request.camel2snake = camel2snake/> --->
|
||||
|
||||
<!---<cfsavecontent variable="strXmlData">--->
|
||||
<!--- <cfif ATTRIBUTES.snake2camel>
|
||||
<cfloop collection=#ATTRIBUTES.qRead.columnList# item="col">
|
||||
<cfset queryRenameColumn(ATTRIBUTES.qRead,col,snake2camel(col))/>
|
||||
<cfset ATTRIBUTES.qREAD.
|
||||
</cfloop>
|
||||
</cfif> --->
|
||||
<cfset msStartAt=getTickCount()/>
|
||||
</cfsilent><cfcontent
|
||||
type="application/json"
|
||||
/><cfoutput>#query2json(ATTRIBUTES.qRead,ATTRIBUTES.convertSnakeToCamel)#</cfoutput><!---
|
||||
,<cfoutput>"duration":"#(getTickCount()- msStartAt)#"</cfoutput>} --->
|
||||
<cfexit method="exittag"/>
|
||||
@@ -0,0 +1,9 @@
|
||||
<cfif thisTag.executionMode IS "end" OR NOT thisTag.hasEndTag>
|
||||
<cfoutput>
|
||||
|
||||
|
||||
|
||||
<a href="?language=ru"<cfif request.language EQ 'ru'> style="font-weight:bold;"</cfif>>Ru</a>
|
||||
<a href="?language=en"<cfif request.language EQ 'en'> style="font-weight:bold;"</cfif>>En</a>
|
||||
</cfoutput>
|
||||
</cfif>
|
||||
@@ -0,0 +1,240 @@
|
||||
|
||||
<cfsilent><!--- *** http://www.bennadel.com/blog/457-a-case-against-coldfusion-custom-tag-page-wrappers.htm--->
|
||||
<cfimport prefix="layout" taglib="../layout"/>
|
||||
<cfimport prefix="c" taglib="../lib/controls"/>
|
||||
|
||||
<cfparam name="ATTRIBUTES.section" type="string"/>
|
||||
<cfparam name="ATTRIBUTES.closeForm" type="boolean" default="No"/>
|
||||
|
||||
<cfparam name="title" default=""/><!---заголовок страницы, отображаемый в теле например, <h1>--->
|
||||
<cfparam name="pageTitle" default="PAYG"/><!---заголовок окна браузера, в теге <title>--->
|
||||
<cfparam name="controls" default=""/>
|
||||
|
||||
</cfsilent><cfsilent>
|
||||
<!---Тег layout:page проглатывает собственный контент, и вместо него после закрытия выводит разметку на основании атрибутов (при открытии тега он формирует переменные - фрагменты разметки - по шаблону) и вложенных тегов layout:attribute (которые по закрытии тега на самом деле перезаписывают переменные в layout:page).
|
||||
Вложенные теги удобны, чтобы передавать читабельную разметку, а не строку в кавычках.--->
|
||||
<cfif thisTag.executionMode IS "start">
|
||||
<!--- Формируется значение переменной controls--->
|
||||
<!--- Но оно может быть переопределено вызовом layout:attribute в теле тега <layout:page>--->
|
||||
<cfif #ATTRIBUTES.section# EQ "header">
|
||||
<cfparam name="ATTRIBUTES.pageInfo" type="struct"/><!--- инициализируется вызывающей страницей --->
|
||||
<cfsavecontent variable="controls">
|
||||
<cfoutput>
|
||||
<cfswitch expression=#ATTRIBUTES.pageInfo.getType()#>
|
||||
<cfcase value="ls">
|
||||
<layout:filter_link filterUrl="#ATTRIBUTES.pageInfo.entity#_filter.cfm" filter=#ATTRIBUTES.pageInfo.settings.filter# fwx="#ATTRIBUTES.pageInfo.track.fwx#" />
|
||||
</cfcase>
|
||||
<cfcase value="detail">
|
||||
<layout:detail_buttons backUrl="#ATTRIBUTES.pageInfo.track.backUrl#" enable="#ATTRIBUTES.pageInfo.writePermitted()#"/>
|
||||
<!---<cfset ATTRIBUTES.form="1"/>--->
|
||||
</cfcase>
|
||||
<cfcase value="filter">
|
||||
<layout:filter_buttons backUrl="#ATTRIBUTES.pageInfo.track.backUrl#"/>
|
||||
<!---<cfset ATTRIBUTES.form="1"/>--->
|
||||
</cfcase><!--- *** not implemented
|
||||
<cfcase value="del">
|
||||
<layout:del_buttons backUrl="#ATTRIBUTES.pageInfo.track.backUrl#"/>
|
||||
<cfset ATTRIBUTES.form="1"/>
|
||||
</cfcase>--->
|
||||
<cfdefaultcase>
|
||||
<!---<cfthrow message="Unsupported page type" detail="Supported page types are ls, detail, filter, del"/>--->
|
||||
</cfdefaultcase>
|
||||
</cfswitch>
|
||||
<!---<layout:language_switch/>--->
|
||||
</cfoutput>
|
||||
</cfsavecontent>
|
||||
</cfif>
|
||||
</cfif>
|
||||
<!--- Переменную (фрагмент разметки) title по традиции заполняем в вызывающей странице через layout:attribute--->
|
||||
</cfsilent><!---
|
||||
|
||||
<!---*******************************************--->
|
||||
---><cfif thisTag.executionMode IS "end"><!---
|
||||
---><cfsilent>
|
||||
<!---никакая разметка из тела даннного тега не выводится,
|
||||
вместо этого по закрытии тега им генерируется собственный контент--->
|
||||
<!---внутри тега на странице определяются его параметры, некорректно названные атрибутами--->
|
||||
<cfset thisTag.generatedContent=""/><!---
|
||||
---></cfsilent><!---
|
||||
---><cfswitch expression=#ATTRIBUTES.section#><!---
|
||||
---><cfcase value="header"><cfsilent>
|
||||
|
||||
</cfsilent><!--- ----------------------------------------------------------------------------
|
||||
---------------------------------------------------------------------------------------------
|
||||
---------------------------------------------------------------------------------------------
|
||||
---><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html lang="en" xml:lang="en" xmlns= "http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge"/><!--- this should be the first line in head --->
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
|
||||
<script type="text/javascript">
|
||||
var timerStart = Date.now();
|
||||
</script>
|
||||
<!---<cfquery name="qUsr" datasource="#request.DS#">
|
||||
select login, firstname, middlename, lastname from worker where id='#request.usr_id#'
|
||||
</cfquery>--->
|
||||
<title><cfoutput>#pageTitle#</cfoutput></title>
|
||||
<link rel="shortcut icon" href="img/favicon.ico"/>
|
||||
|
||||
<!--- <link rel="stylesheet" href="style/fontawesome-all.css"/> --->
|
||||
<link rel="stylesheet" type="text/css" href="style/web.css"/>
|
||||
<!--- override layout header style --->
|
||||
<!--- <cfswitch expression=#request.STAND#>
|
||||
<cfcase value="DEV">
|
||||
<style>.title, .main-controls {background-color:#aaf}</style>
|
||||
</cfcase>
|
||||
<cfcase value="TEST">
|
||||
<style>.title, .main-controls {background-color:#9e9}</style>
|
||||
</cfcase>
|
||||
<cfcase value="PROD">
|
||||
<style>.title, .main-controls {background-color:#faa}</style>
|
||||
</cfcase>
|
||||
<cfdefaultcase>
|
||||
<style>.title, .main-controls {background-color:#aaa}</style><!--- без изменений --->
|
||||
</cfdefaultcase>
|
||||
</cfswitch> --->
|
||||
|
||||
|
||||
<script type="text/javascript" src="js/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="js/jquery.searchabledropdown.js"></script>
|
||||
|
||||
<script>
|
||||
function resetListsById(id){
|
||||
for (var i = 0, j = arguments.length; i < j; i++) {
|
||||
try {
|
||||
document.getElementById(arguments[i]).selectedIndex=-1;
|
||||
} catch (e) {}
|
||||
}
|
||||
}
|
||||
|
||||
window.onload=function(){document.body.style.cursor='default';}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body style="cursor:wait;"><a name="up"></a> <!--- <cfdump var=#ATTRIBUTES.pageInfo.writePermitted()#/> --->
|
||||
|
||||
<div class="page">
|
||||
<div class="page-main">
|
||||
<div class="menu noprint" style="margin:0; padding:0;/*border:1px solid red;*/">
|
||||
<div class="fixed-menu" style="width:145px; height:100%; padding:0 0 0 0; --border:1px solid blue;" />
|
||||
<a name="up"></a>
|
||||
|
||||
<!---<a id="lime_ref" href="http://root" style="display:inline-block; margin: 0; padding: 0 6px; height: 30px; width: 48px; margin: 5px 0 0 0;" title="Home"><img src="img/alarm-arrow-up-icon.png" style="margin: 0; padding: 0; height: 30px; margin: 5px 0 0 0;"/></a>
|
||||
--->
|
||||
|
||||
<!--- <div style="width:20px; height:30px; margin: 5px; background: url('img/logo0.png') 0 0 no-repeat; background-size:contain; display:inline-block;"></div>--->
|
||||
<div style="width:138px; height:30px; margin: 5px 0 0 5px; background: url('img/logo0.png') 0 0 no-repeat; background-size:contain; display:inline-block; -border:1px solid red;">
|
||||
<p class="b r" style="color:white; margin:0 10px 10px 10px; font-size:130%;">
|
||||
Спецификации
|
||||
</p>
|
||||
</div>
|
||||
<p style="color:lightgray; margin:10px 12px; text-align:right;">
|
||||
|
||||
<cfoutput>v.#request.APP_VERSION#</cfoutput>
|
||||
</p>
|
||||
<style>
|
||||
.menu-items-container::-webkit-scrollbar {width: 10px; margin:10px;}
|
||||
}
|
||||
.menu-items-container::-webkit-scrollbar-track {
|
||||
background-color: lightgray;
|
||||
}
|
||||
.menu-items-container::-webkit-scrollbar-thumb {
|
||||
--background-color: rgb(97,127,136);/*lightgray*/;
|
||||
--border-radius: 2px;
|
||||
--border: 1px solid white;
|
||||
}
|
||||
</style>
|
||||
<div class="menu-items-container" style="width:100%; height:100%; overflow:auto; scrollbar-width:thin; --border:1px solid green;">
|
||||
<cfmodule template="../inc/menu.cfm" fwx="#ATTRIBUTES.pageInfo.track.fwx#" thisUrl="#ATTRIBUTES.pageInfo.track.thisUrl#"/>
|
||||
<br/>
|
||||
<br/>
|
||||
<br/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<!-- content -->
|
||||
<div class="content">
|
||||
|
||||
<cfif isInstanceOf(ATTRIBUTES.pageInfo, "form_page_info")>
|
||||
<cfoutput>
|
||||
<form name="#ATTRIBUTES.pageInfo.formName#" action="#ATTRIBUTES.pageInfo.formAction#" method="#ATTRIBUTES.pageInfo.formMethod#" <!---style="height:100%;"---><cfif len(ATTRIBUTES.pageInfo.formEncType)> enctype="#ATTRIBUTES.pageInfo.formEncType#"</cfif>><!--- height:100% is required to make inner elements fill the container vertically ---><!--- but if we close the form in the middle of the page, layout is broken --->
|
||||
</cfoutput>
|
||||
</cfif>
|
||||
|
||||
<div class="header">
|
||||
<div class="control-bar">
|
||||
<!--- <div style="display:table-cell; width:23px; background: #ccc/*rgb(117,147,156)*/; border: 1px solid #bbb;"> --->
|
||||
<!--- <div style="display:table-cell; width:23px; background: #0078c9; border: 1px solid #000;"> --->
|
||||
<!--- <div style="display:table-cell; width:23px; background: #07b; border: 1px solid #000;"></div> --->
|
||||
<!--- <div style="display:table-cell; width:3px;"></div> --->
|
||||
<div class="title">
|
||||
<cfoutput>#title#</cfoutput>
|
||||
</div>
|
||||
<div class="main-controls">
|
||||
<cfoutput>#controls#</cfoutput>
|
||||
</div>
|
||||
</div><!--- control-bar --->
|
||||
</div>
|
||||
|
||||
<div class="layout_vspacer"></div>
|
||||
|
||||
|
||||
<cfif len(ATTRIBUTES.pageInfo.status.errorState)>
|
||||
<span style="color:red"><cfoutput>#ATTRIBUTES.pageInfo.status.errorMessage#</cfoutput></span>
|
||||
<cfexit method="exittag"/>
|
||||
</cfif>
|
||||
|
||||
<!-- content -->
|
||||
</cfcase><cfcase value="extension"><!--- -------------------------------------------------------------------------------------------- --->
|
||||
<cfif ATTRIBUTES.closeForm></form></cfif>
|
||||
</cfcase><cfcase value="footer"><!--- -------------------------------------------------------------------------------------------- --->
|
||||
<!--/content -->
|
||||
<cfif ATTRIBUTES.closeForm></form></cfif>
|
||||
|
||||
</div>
|
||||
<!--/content -->
|
||||
|
||||
</div><!--- page main --->
|
||||
|
||||
<div class="page-footer noprint">
|
||||
<div style="display:table-cell; padding:.5em; background-color:#555;">
|
||||
<cftry>
|
||||
<cfset pageTimeMs=GetTickCount()-request.startTickCount/>
|
||||
<cfoutput><span title="page generation time">#pageTimeMs# ms</span></cfoutput>
|
||||
<cfcatch type="any">request.startTickCount undefined</cfcatch>
|
||||
</cftry>
|
||||
<span id="load-time" title="page loading time"></span>
|
||||
<script type="text/javascript">
|
||||
window.onload=function() {
|
||||
document.body.style.cursor='default';
|
||||
document.getElementById("load-time").innerHTML = (Date.now()-timerStart) + " ms";
|
||||
};
|
||||
<!---alert(document.documentMode);// IE troubles --->
|
||||
</script>
|
||||
</div>
|
||||
<div style="display:table-cell; padding: 3px;">
|
||||
<div class="footer">
|
||||
<cftry>
|
||||
<cflock scope="session" type="readonly" timeout="3">
|
||||
<cfif len(session.authentication_source)>
|
||||
<cfoutput>authentication:#session.authentication_source#</cfoutput>
|
||||
</cfif>
|
||||
</cflock><cfcatch type="ANY"></cfcatch></cftry>
|
||||
<a href="#up" class="up">вверх</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div><!--- page --->
|
||||
|
||||
<!--- fixed-menu class is defined at the bottom of page, so in case of unhandled error menu is not fixed --->
|
||||
<style>
|
||||
div.fixed-menu { position:fixed;}
|
||||
</style>
|
||||
|
||||
</body>
|
||||
</html><!---
|
||||
---></cfcase><cfdefaultcase><cfthrow message="Unsupported 'section' attribute value" detail="Supported section values are 'header','extension','footer'"></cfdefaultcase></cfswitch><!---
|
||||
---></cfif>
|
||||
@@ -0,0 +1,55 @@
|
||||
<!---https://www.bennadel.com/blog/461-creating-microsoft-excel-documents-with-coldfusion-and-xml.htm--->
|
||||
<!---*** locale-specific--->
|
||||
<cfparam name="ATTRIBUTES.qRead" type="query"/>
|
||||
<cfparam name="ATTRIBUTES.titleMap" type="struct"/>
|
||||
<cfparam name="ATTRIBUTES.sheetTitle" type="string" default="Sheet1"/>
|
||||
<cfparam name="ATTRIBUTES.filename" type="string" default="export.xls"/>
|
||||
<cfset fieldArray=structSort(ATTRIBUTES.titleMap, "numeric", "ASC", "ordinal")/>
|
||||
|
||||
<cfsavecontent variable="strXmlData">
|
||||
<cfoutput>
|
||||
<html xmlns:o='urn:schemas-microsoft-com:office:office' xmlns:x='urn:schemas-microsoft-com:office:excel' xmlns='http://www.w3.org/TR/REC-html40'><meta http-equiv="content-type" content="application/vnd.ms-excel; charset=UTF-8"><meta http-equiv="content-type" content="application/vnd.ms-excel; charset=UTF-8"><head><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>#ATTRIBUTES.sheetTitle#</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--></head><body><table><!---
|
||||
<cfloop index="i" from="1" to=#structCount(ATTRIBUTES.titleMap)#>
|
||||
<Column ss:Index="#i#"/>
|
||||
</cfloop>
|
||||
--->
|
||||
<tr>
|
||||
<cfloop from=1 to=#arrayLen(fieldArray)# index="i">
|
||||
<cfset title=structFind(ATTRIBUTES.titleMap, fieldArray[i]).title/>
|
||||
<th><cfif len(title)>#title#<cfelse>#fieldArray[i]#</cfif></th>
|
||||
</cfloop>
|
||||
</tr>
|
||||
|
||||
<cfloop query=#ATTRIBUTES.qRead#>
|
||||
<tr>
|
||||
<cfloop from=1 to=#arrayLen(fieldArray)# index="i">
|
||||
|
||||
<cfset data=#ATTRIBUTES.qRead[fieldArray[i]]#/>
|
||||
<cftry>
|
||||
<cfif isDate(data)><td>#dateFormat(data,'YYYY-MM-DD')#<cfif hour(data) GT 0 OR minute(data) EQ 0> #timeFormat(data,'HH:mm')#</cfif></td><cfelseif isNumeric(data)><td>#Replace(data, '.', ',')#</td><cfelse><td>#data#</td></cfif>
|
||||
<cfcatch type="Any"><td>#data#</td></cfcatch>
|
||||
</cftry>
|
||||
</cfloop>
|
||||
</tr>
|
||||
|
||||
</cfloop>
|
||||
|
||||
</table></body></html>
|
||||
</cfoutput>
|
||||
</cfsavecontent>
|
||||
|
||||
<cfheader
|
||||
name="content-disposition"
|
||||
value="attachment; filename=#ATTRIBUTES.filename#"
|
||||
/>
|
||||
|
||||
<!---
|
||||
When streaming the Excel XML data, trim the data and
|
||||
replace all the inter-tag white space. No need to stream
|
||||
any more content than we have to.
|
||||
--->
|
||||
<cfcontent
|
||||
type="application/msexcel"
|
||||
variable="#ToBinary( ToBase64( strXmlData.Trim().ReplaceAll( '>\s+', '>' ).ReplaceAll( '\s+<', '<' ) ) )#"
|
||||
/><cfabort/>
|
||||
<cfexit method="exittag"/>
|
||||
@@ -0,0 +1,49 @@
|
||||
<!---https://www.bennadel.com/blog/461-creating-microsoft-excel-documents-with-coldfusion-and-xml.htm--->
|
||||
<cfparam name="ATTRIBUTES.qRead" type="query"/>
|
||||
<cfparam name="ATTRIBUTES.titleMap" type="struct"/>
|
||||
<cfparam name="ATTRIBUTES.sheetTitle" type="string" default="Sheet1"/>
|
||||
<cfparam name="ATTRIBUTES.filename" type="string" default="export.xlsx"/>
|
||||
|
||||
<cfsavecontent variable="strXmlData">
|
||||
<cfoutput>
|
||||
<html xmlns:o='urn:schemas-microsoft-com:office:office' xmlns:x='urn:schemas-microsoft-com:office:excel' xmlns='http://www.w3.org/TR/REC-html40'>
|
||||
<meta http-equiv="content-type" content="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet">
|
||||
<head><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>xlsWorksheetName</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--></head>
|
||||
<body>
|
||||
<table>
|
||||
<tr>
|
||||
<cfloop struct=#ATTRIBUTES.titleMap# item="field">
|
||||
<th>#structFind(ATTRIBUTES.titleMap,field).title#</th>
|
||||
</cfloop>
|
||||
</tr>
|
||||
|
||||
<cfloop query=#ATTRIBUTES.qRead#>
|
||||
<tr>
|
||||
<cfloop struct=#ATTRIBUTES.titleMap# item="field">
|
||||
<td>
|
||||
#ATTRIBUTES.qRead[field]#
|
||||
</td>
|
||||
</cfloop>
|
||||
</tr>
|
||||
|
||||
</cfloop>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
</cfoutput>
|
||||
</cfsavecontent>
|
||||
<cfheader
|
||||
name="content-disposition"
|
||||
value="attachment; filename=#ATTRIBUTES.filename#"
|
||||
/>
|
||||
<!---
|
||||
When streaming the Excel XML data, trim the data and
|
||||
replace all the inter-tag white space. No need to stream
|
||||
any more content than we have to.
|
||||
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
|
||||
--->
|
||||
<cfcontent
|
||||
type="application/vnd.ms-excel"
|
||||
variable="#ToBinary( ToBase64( strXmlData.Trim().ReplaceAll( '>\s+', '>' ).ReplaceAll( '\s+<', '<' ) ) )#"
|
||||
/>
|
||||
<cfexit method="exittag"/>
|
||||
@@ -0,0 +1,239 @@
|
||||
<cfsilent>
|
||||
<!---https://www.bennadel.com/blog/461-creating-microsoft-excel-documents-with-coldfusion-and-xml.htm--->
|
||||
<!---порядок колонок, как в селекте, не управляется никак
|
||||
Для определения порядка колонок используется поле ATTRIBUTES.titleMap.ordinal, возможно, не самый надежный способ
|
||||
Можно попробовать использовать порядок колонок в массиве query --->
|
||||
<cfparam name="ATTRIBUTES.qRead" type="query"/>
|
||||
<cfparam name="ATTRIBUTES.titleMap" type="struct"/><!---see ../lib/data/field_set.cfm--->
|
||||
<cfparam name="ATTRIBUTES.sheetTitle" type="string" default="Sheet1"/>
|
||||
<cfparam name="ATTRIBUTES.filename" type="string" default="export.xlsx"/>
|
||||
<cfset AVG_SYMBOL_WIDTH=6.5/>
|
||||
<cfset MAX_COL_LENGTH=30/>
|
||||
|
||||
<cfset qRead=ATTRIBUTES.qRead/>
|
||||
|
||||
<!---<cfdump var=#qRead#/>
|
||||
<cfdump var=#ATTRIBUTES.titleMap#/>
|
||||
|
||||
<cfabort/>
|
||||
--->
|
||||
|
||||
<!---<cfsavecontent variable="strXmlData">--->
|
||||
|
||||
</cfsilent><cfheader
|
||||
name="content-disposition"
|
||||
value="attachment; filename=#ATTRIBUTES.filename#"
|
||||
/><cfcontent
|
||||
type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
||||
/><cfoutput><?xml version="1.0"?>
|
||||
<?mso-application progid="Excel.Sheet"?>
|
||||
<!---
|
||||
This is the Workbook root element. This element
|
||||
stores characteristics and properties of the
|
||||
workbook, such as the namespaces used in
|
||||
SpreadsheetML.
|
||||
--->
|
||||
<Workbook
|
||||
xmlns="urn:schemas-microsoft-com:office:spreadsheet"
|
||||
xmlns:o="urn:schemas-microsoft-com:office:office"
|
||||
xmlns:x="urn:schemas-microsoft-com:office:excel"
|
||||
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
|
||||
xmlns:html="http://www.w3.org/TR/REC-html40">
|
||||
<!---
|
||||
The first child element of the WorkBook element
|
||||
is DocumentProperties. Office documents store
|
||||
metadata related to the document—for example,
|
||||
the author name, company, creation date, and
|
||||
more in the DocumentProperties element.
|
||||
--->
|
||||
<DocumentProperties
|
||||
xmlns="urn:schemas-microsoft-com:office:office">
|
||||
<Author>xls-generator</Author>
|
||||
<Company></Company>
|
||||
</DocumentProperties>
|
||||
<!---
|
||||
The Styles node represents information related
|
||||
to individual styles that can be used to format
|
||||
components of the workbook.
|
||||
--->
|
||||
<Styles>
|
||||
<!--- Basic format used by all cells. --->
|
||||
<Style ss:ID="Default" ss:Name="Normal">
|
||||
<Alignment ss:Vertical="Top"/>
|
||||
<Borders/>
|
||||
<Font ss:FontName="Calibri" x:Family="Swiss" ss:Size="11"/>
|
||||
<Interior/>
|
||||
<NumberFormat/>
|
||||
<Protection/>
|
||||
</Style>
|
||||
<Style ss:ID="Th">
|
||||
<Alignment ss:Horizontal="Center" ss:Vertical="Top"/>
|
||||
<Font ss:FontName="Calibri" x:Family="Swiss" ss:Size="11" ss:Bold="1"/>
|
||||
</Style>
|
||||
<Style ss:ID="Int">
|
||||
<NumberFormat ss:Format="0" />
|
||||
</Style>
|
||||
<Style ss:ID="DateTime">
|
||||
<NumberFormat ss:Format="dd/mm/yyyy\ hh:mm;@"/>
|
||||
</Style>
|
||||
<!---
|
||||
<Style ss:ID="ShortDate">
|
||||
<NumberFormat ss:Format="[ENG][$-409]d\-mmm\-yyyy;@" />
|
||||
</Style>
|
||||
|
||||
<Style ss:ID="YesNo">
|
||||
<NumberFormat ss:Format="Yes/No" />
|
||||
</Style>
|
||||
--->
|
||||
</Styles>
|
||||
<!---
|
||||
This defines the first worksheeet and it's name.
|
||||
We are only using one worksheet in this example,
|
||||
but you could add more Worksheet nodes after
|
||||
this one for multiple tabs. The "Name" attribute
|
||||
here is the name that shows up in the tab.
|
||||
--->
|
||||
<Worksheet ss:Name="#ATTRIBUTES.sheetTitle#">
|
||||
<Table
|
||||
<!---
|
||||
We need a column for each column of the
|
||||
query. This attribute is required to be
|
||||
correct. If the value here does NOT
|
||||
match the data in Excel file, the
|
||||
document will not render properly.
|
||||
--->
|
||||
ss:ExpandedColumnCount="#ListLen(qRead.ColumnList)#"
|
||||
<!---
|
||||
We need a row for every query record
|
||||
plus one for the header row. Again, if
|
||||
this value does not match what is in the
|
||||
document, the excel file will not
|
||||
render properly.
|
||||
--->
|
||||
ss:ExpandedRowCount="#(qRead.RecordCount + 1)#"
|
||||
x:FullColumns="1"
|
||||
x:FullRows="1">
|
||||
<!---
|
||||
Here, we can define general properties
|
||||
regarding each column in the data output.
|
||||
|
||||
<Column ss:Index="1" ss:Width="30" />
|
||||
<Column ss:Index="2" ss:Width="100" />
|
||||
<Column ss:Index="3" ss:Width="42" />
|
||||
<Column ss:Index="4" ss:Width="84" />
|
||||
<Column ss:Index="5" ss:Width="66" />
|
||||
<Column ss:Index="6" ss:Width="70" />--->
|
||||
|
||||
<cfsilent>
|
||||
<cfset columns=arrayNew(1)/>
|
||||
<cfset i=1/>
|
||||
<cfloop struct=#ATTRIBUTES.titleMap# item="field">
|
||||
<cfset col=structNew()/>
|
||||
<cfset fieldSpec=structFind(ATTRIBUTES.titleMap, field)/>
|
||||
<cfset col.name=field/>
|
||||
|
||||
<cfset col.title=fieldSpec.title/>
|
||||
<cfif len(col.title) EQ 0>
|
||||
<cfset col.title=col.name/>
|
||||
</cfif>
|
||||
<cfset col.titleLength=len(col.title)/>
|
||||
|
||||
<cfquery name="qLen" dbtype="query">
|
||||
select coalesce(max(length(#field#)),0) as maxlen from qRead
|
||||
</cfquery>
|
||||
<cfset col.length=max(col.titleLength, qLen.maxLen)/>
|
||||
|
||||
<cfset col.cfSqlType="CF_SQL_VARCHAR"/>
|
||||
<cfif structKeyExists(fieldSpec,"cfSqlType")>
|
||||
<cfset col.cfSqlType=#fieldSpec.cfSqlType#/>
|
||||
</cfif>
|
||||
|
||||
<cfswitch expression=#col.cfSqlType#><!---should use ## around variable name--->
|
||||
<cfcase value="CF_SQL_BIGINT,CF_SQL_INTEGER,CF_SQL_SMALLINT,CF_SQL_TINYINT,CF_SQL_BIT,CF_SQL_NUMERIC,CF_SQL_DECIMAL,CF_SQL_REAL,CF_SQL_FLOAT,CF_SQL_DOUBLE">
|
||||
<cfset col.ssType="Number"/>
|
||||
</cfcase>
|
||||
<cfcase value="CF_SQL_TIMESTAMP,CF_SQL_DATE,CF_SQL_TIME,CF_SQL_DATETIME">
|
||||
<cfset col.ssType="DateTime"/>
|
||||
</cfcase>
|
||||
<cfdefaultcase>
|
||||
<cfset col.ssType="String"/>
|
||||
</cfdefaultcase>
|
||||
</cfswitch>
|
||||
|
||||
<cfset columns[fieldSpec.ordinal]=col/><!---new col created at each iteration, so we have valid references--->
|
||||
<cfset i=i+1/>
|
||||
</cfloop>
|
||||
</cfsilent>
|
||||
|
||||
<cfloop from=1 to=#arrayLen(columns)# index="i">
|
||||
<cfif columns[i].ssType EQ "DateTime"><!--- timestamp string representation is too long, --->
|
||||
<Column ss:Index="#i#" ss:Width="#round(min(columns[i].titleLength, MAX_COL_LENGTH)*AVG_SYMBOL_WIDTH)#" ss:AutoFitWidth="1"/>
|
||||
<cfelse>
|
||||
<Column ss:Index="#i#" ss:Width="#round(min(columns[i].length, MAX_COL_LENGTH)*AVG_SYMBOL_WIDTH)#" ss:AutoFitWidth="1"/>
|
||||
</cfif>
|
||||
</cfloop>
|
||||
<!---
|
||||
This is our header row. All cells in the
|
||||
header row will be of type string.
|
||||
--->
|
||||
<Row>
|
||||
<cfloop from=1 to=#arrayLen(columns)# index="i">
|
||||
<Cell ss:StyleID="Th">
|
||||
<Data ss:Type="String">#columns[i].title#</Data>
|
||||
</Cell>
|
||||
</cfloop>
|
||||
</Row>
|
||||
|
||||
<cfflush/>
|
||||
|
||||
<cfloop query=#qRead#><!---
|
||||
---><Row><!---
|
||||
---><cfloop from=1 to=#ArrayLen(columns)# index="i"><!---
|
||||
---><cfset field=columns[i].name/><!---
|
||||
---><Cell<cfif columns[i].ssType EQ "DateTime"> ss:StyleID="DateTime"</cfif>><!---
|
||||
---><cfif len(qRead[field])><Data ss:Type="#columns[i].ssType#"><!---no extra whitespace allowed here---><!---
|
||||
---><cfswitch expression=#columns[i].ssType#><!---
|
||||
---><cfcase value="DateTime"><!---
|
||||
--->#dateFormat(qRead[field],"YYYY-MM-DD")#T#timeFormat(qRead[field],"HH:mm:ss.l")#<!---
|
||||
---></cfcase><!---
|
||||
---><cfcase value="Number"><!---
|
||||
--->#qRead[field]#<!---
|
||||
---></cfcase><!---
|
||||
---><cfdefaultcase><!---
|
||||
---><![CDATA[#request.clean4CDATA(qRead[field])#]]><!---
|
||||
---></cfdefaultcase><!---
|
||||
---></cfswitch><!---
|
||||
---></Data></cfif><!---
|
||||
---></Cell><!---
|
||||
---></cfloop><!---
|
||||
---></Row><!---
|
||||
---></cfloop><!---
|
||||
|
||||
---></Table>
|
||||
|
||||
</Worksheet>
|
||||
|
||||
</Workbook>
|
||||
|
||||
</cfoutput>
|
||||
<!---</cfsavecontent>--->
|
||||
|
||||
<!---
|
||||
Define the way in which the browser should interpret
|
||||
the content that we are about to stream.
|
||||
--->
|
||||
<!---<cfheader
|
||||
name="content-disposition"
|
||||
value="attachment; filename=#ATTRIBUTES.filename#"
|
||||
/>--->
|
||||
|
||||
<!---
|
||||
When streaming the Excel XML data, trim the data and
|
||||
replace all the inter-tag white space. No need to stream
|
||||
any more content than we have to..ReplaceAll( '>\s+', '>' ).ReplaceAll( '\s+<', '<' )
|
||||
--->
|
||||
<!---<cfcontent
|
||||
type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
||||
variable="#ToBinary( ToBase64( strXmlData.Trim()))#"
|
||||
/>---><!---<cfabort/>--->
|
||||
<cfexit method="exittag"/>
|
||||
@@ -0,0 +1,593 @@
|
||||
<cfsilent>
|
||||
<cfimport prefix="m" taglib="lib"/>
|
||||
<cfimport prefix="c" taglib="lib/controls"/>
|
||||
<cfimport prefix="d" taglib="lib/data"/>
|
||||
<cfimport prefix="layout" taglib="layout"/>
|
||||
</cfsilent>
|
||||
|
||||
<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_start" type="date" default=#dateAdd('m',-1,dt_finish)#/>
|
||||
<cfset hours=dateDiff('h',dt_start,dt_finish)/>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!--- Нужно еще применить политики бесплатного минимума --->
|
||||
|
||||
<cfquery name="qCode" datasource="dwh">
|
||||
select distinct p.code
|
||||
from elma.deals d
|
||||
join elma.deals_services siv on (d.__id=ANY(siv.deal))
|
||||
join elma.service_parametrs p on (p.__id = ANY(siv.params))
|
||||
join elma.companies k on (d._companies=k.__id)
|
||||
join elma.additional_agreements aa on (aa.__id = ANY(siv.additional_agreement))
|
||||
join elma.aggrements a on (aa.contract_uid = a.__id)
|
||||
where p.type=3 AND aa.is_actual
|
||||
order by p.code
|
||||
</cfquery>
|
||||
<!--- <cfdump var=#qCode#/> --->
|
||||
|
||||
<cfquery name="qSpec" datasource="dwh">
|
||||
select k.id_klienta as wz, k.__id::text as contragent_uid, p.code, p.price, p.discount, k.__name as contragent, a.__name as contract, a.__id::text as contract_uid, d.__name as deal, d.__id::text as deal_uid, siv.abstractive_service as abstract_service, siv.modifier, siv.user_description, siv.hash as line_key
|
||||
,siv.date_nop as dt_from, siv.date_end as dt_to
|
||||
/*,p.__name as line_key*/, p.ed_izm, aa.__name as additional_agreement, aa.__id::text as additional_agreement_uid
|
||||
--, aa.is_actual
|
||||
from elma.deals d
|
||||
join elma.deals_services siv on (d.__id=ANY(siv.deal))
|
||||
join elma.service_parametrs p on (p.__id = ANY(siv.params))
|
||||
join elma.companies k on (d._companies=k.__id)
|
||||
join elma.additional_agreements aa on (aa.__id = ANY(siv.additional_agreement))
|
||||
join elma.aggrements a on (aa.contract_uid = a.__id)
|
||||
where p.type=3 AND aa.is_actual
|
||||
order by k.id_klienta, p.code
|
||||
</cfquery>
|
||||
<cfquery name="qSivAge" datasource="dwh">
|
||||
select max(dt_load) as dt_load from elma.deals_services
|
||||
</cfquery>
|
||||
<!--- здесь имеем список кодов с ценами и WZ. Каждому коду можно поставить в соответствие запрос, который даст по нему выборку. Изредка один запрос может вывести 2 кода, но разбить на 2 запроса легко. Кроме того, запросы можно объединить через union в один - может быть, так будет лучше читаться (быстрее выполняться не будет) --->
|
||||
<cfif isDefined("DEBUG")>
|
||||
<cfdump var=#qSpec#/>
|
||||
<cfflush/>
|
||||
</cfif>
|
||||
|
||||
|
||||
<cfquery name="qComputing" datasource="billing-vc">
|
||||
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 > 0
|
||||
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>
|
||||
<!--- <cfdump var=#qComputing#/> --->
|
||||
<cfquery name="qComputingAge" datasource="billing-vc">
|
||||
select max(capacity_resource.timestamp) as dt_load from ngcloud_ru.capacity_resource
|
||||
</cfquery>
|
||||
|
||||
<!--- переделать storage_profile_types с расшифровкой ssd, sata, можно прямо до каталожного кода --->
|
||||
<cfquery name="qStorage" datasource="billing-vc">
|
||||
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 > 0
|
||||
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="billing-vc">
|
||||
select max(capacity_storage.timestamp) as dt_load from ngcloud_ru.capacity_storage
|
||||
</cfquery>
|
||||
<!--- <cfdump var=#qStorage#/> --->
|
||||
|
||||
<!---
|
||||
"placement" "size_gb" "get_10k" "put_10k" "bytes_sent_gb"
|
||||
HOT_FREE_LIMIT 1 10 1 100
|
||||
--->
|
||||
<!--- надо дисконтировать не ГБ-часы а ГБ-месяцы --->
|
||||
<cfquery name="qS3Vol" datasource="billing-s3">
|
||||
select /* *** ниже дублирование кода агрегации - round ceil etc, обратить внимание при правке */
|
||||
(sum(bucket_stat.usage_rgw_main_size_actual)/<cfqueryparam cfsqltype="cf_sql_integer" value=#hours#/>) as vol_B
|
||||
,round(sum(bucket_stat.usage_rgw_main_size_actual)/<cfqueryparam cfsqltype="cf_sql_integer" value=#hours#/>/1024/1024/1024) as vol_GB
|
||||
,greatest(round(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.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>
|
||||
<!--- <cfdump var=#qS3Vol#/> --->
|
||||
<cfquery name="qS3VolAge" datasource="billing-s3">
|
||||
select max(timestamp_addition) as dt_load from s3billing.bucket_stat
|
||||
</cfquery>
|
||||
|
||||
<cfquery name="qS3OpsTrf" datasource="billing-s3">
|
||||
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 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>
|
||||
<cfquery name="qS3OpsTrfAge" datasource="billing-s3">
|
||||
select max(time) as dt_load from s3billing.usage_bucket_by_user
|
||||
</cfquery>
|
||||
<!--- <cfdump var=#qS3OpsTrf#/> --->
|
||||
|
||||
<cfquery name="qUnifiedMetric" dbType="query">
|
||||
select wz, code || '.cpu-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
|
||||
s.wz
|
||||
,s.code
|
||||
,s.price
|
||||
,s.discount
|
||||
,s.contragent, s.contragent_uid
|
||||
,s.contract,s.contract_uid
|
||||
,s.deal, s.deal_uid
|
||||
,s.additional_agreement, s.additional_agreement_uid
|
||||
,s.abstract_service
|
||||
,s.modifier
|
||||
,user_description
|
||||
,s.ed_izm
|
||||
,s.line_key, s.dt_from, s.dt_to
|
||||
,s.deal,s.abstract_service,s.modifier,s.user_description
|
||||
,m.raw_metric
|
||||
,m.metric
|
||||
,m.chargeable_metric
|
||||
,s.price*(100-s.discount)/100 as discounted_price
|
||||
,s.price*(100-s.discount)/100*m.chargeable_metric as charge
|
||||
FROM qSpec as s, qUnifiedMetric as m WHERE s.wz=m.wz AND s.code=m.code
|
||||
order by s.wz, s.code
|
||||
</cfquery>
|
||||
<!--- looks like QoQ does not support join syntax, at least of Lucee 5.4--->
|
||||
|
||||
<layout:page section="header" pageInfo=#pageInfo#>
|
||||
|
||||
<layout:attribute name="title">
|
||||
<cfoutput><b>Отчет по PAYG</b></cfoutput>
|
||||
</layout:attribute>
|
||||
<layout:attribute name="controls">
|
||||
<!---skip filter link, filter is not implemented--->
|
||||
<!---<layout:language_switch/>--->
|
||||
</layout:attribute>
|
||||
</layout:page>
|
||||
|
||||
Внимание! округление вверх при расчете метрик get, put S3. Расчетные суммы могут содержать погрешности округления, поэтому окончательный расчет стоимости (количество * цену) должен выполняться в бухгалтерской программе.
|
||||
<b>Если у клиента больше 1 действующего допника с услугами PAYG, то данные в отчете могут быть замножены, в этом случае считать вручную</b>
|
||||
<br/>
|
||||
Даты актуальности пока проверять вручную
|
||||
<cfoutput>
|
||||
<form method="post" action="">
|
||||
Период с <input type="text" name="dt_start" value="#dateFormat(dt_start,'YYYY-MM-DD')#"/>
|
||||
по <input type="text" name="dt_finish" value="#dateFormat(dt_finish,'YYYY-MM-DD')#"/>
|
||||
<input type="submit" style="cursor:pointer;"/>
|
||||
<input type="submit" name="DEBUG" value="DEBUG" style="cursor:pointer;"/>
|
||||
</form>
|
||||
Часов в периоде: <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 Storage: <b>#dateFormat(qStorageAge.dt_load,'YYYY-MM-DD')# #timeFormat(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(qS3OpsTrfAge.dt_load,'YYYY-MM-DD')# #timeFormat(qS3OpsTrfAge.dt_load,'HH:MM:SS')#</b>
|
||||
</cfoutput>
|
||||
<!--- <cfdump var=#dt_start#/>
|
||||
<cfdump var=#dt_finish#/>
|
||||
<cfdump var=#hours#/> --->
|
||||
|
||||
<table class="worktable">
|
||||
<thead>
|
||||
<td width="1%"></td>
|
||||
<td width="3%">WZ</td>
|
||||
<td width="5%">Артикул</td>
|
||||
<td width="3%">Цена без НДС проверить</td>
|
||||
<td width="3%">Кол-во (метрика)</td>
|
||||
<td width="3%">Ед.изм.</td>
|
||||
<td width="3%">Ст-ть</td>
|
||||
<td width="3%"> </td>
|
||||
<td width="6%">Дата НОУ</td>
|
||||
<td width="6%">Дата оконч.</td>
|
||||
<td width="3%">Ключ строки</td>
|
||||
<td width="3%">GPL без НДС проверить</td>
|
||||
<td width="3%">Скидка%</td>
|
||||
<td width="3%">Сырая метрика</td>
|
||||
<td width="3%">Приведен­ная метрика</td>
|
||||
<td width="7%">Контрагент</td>
|
||||
<td width="3%">Договор</td>
|
||||
<td width="3%">Допник</td>
|
||||
<td width="3%">Сделка</td>
|
||||
<td width="10%">Услуга</td>
|
||||
<td width="8%">Клиентс. назв.</td>
|
||||
</thead>
|
||||
|
||||
<cfoutput query="qCharge" group="wz">
|
||||
<cfset var acc=0/>
|
||||
<cfoutput>
|
||||
<cfset acc=acc+charge/>
|
||||
<tr>
|
||||
<td>#currentRow#</a></td>
|
||||
<td><a href="contragent.cfm?__id=#contragent_uid#&#tr.fwx#">#wz#</a></td>
|
||||
<td>#code#</td>
|
||||
<td class="r">#discounted_price#</td>
|
||||
<td class="r">#chargeable_metric#</td>
|
||||
<td>#ed_izm#</td>
|
||||
<td class="r">#charge#</td>
|
||||
<td></td>
|
||||
<td class="r">#dateFormat(dt_from,'YYYY-MM-DD')#</td>
|
||||
<td class="r">#dateFormat(dt_to,'YYYY-MM-DD')#</td>
|
||||
<td class="r">#line_key#</td>
|
||||
<td class="r">#price#</td>
|
||||
<td class="r">#discount#</td>
|
||||
<td class="r" style="color:lightgray">#raw_metric#</td>
|
||||
<td class="r">#metric#</td>
|
||||
<td><a href="contragent.cfm?__id=#contragent_uid#&#tr.fwx#">#contragent#</a></td>
|
||||
<td><a href="contract.cfm?__id=#contract_uid#&#tr.fwx#">#contract#</a></td>
|
||||
<td><a href="additional_agreement.cfm?__id=#additional_agreement_uid#&#tr.fwx#">#additional_agreement#</a></td>
|
||||
<td><a href="deal.cfm?__id=#deal_uid#&#tr.fwx#">#deal#</a></td>
|
||||
<td>#abstract_service# #modifier#</td>
|
||||
<td>#user_description#</td>
|
||||
</tr>
|
||||
</cfoutput>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td colspan="5" class="b"><a href="contragent.cfm?__id=#contragent_uid#&#tr.fwx#">#wz#</a> #contragent#</td>
|
||||
<td colspan="1" class="r b">#NumFmt(acc,2)#</td>
|
||||
<td colspan="14"></td>
|
||||
</tr>
|
||||
</cfoutput>
|
||||
|
||||
</table>
|
||||
<!--- <cfdump var=#qCharge#/> --->
|
||||
|
||||
|
||||
<layout:page section="footer"/>
|
||||
|
||||
<!---
|
||||
--->
|
||||
<!--- --,m.*
|
||||
--,s.price*(100-s.discount)/100 as discounted_price
|
||||
-- --->
|
||||
<!--- В одном месте user_id int в другом owner varchar --->
|
||||
|
||||
<!---
|
||||
задача (вызванная сыростью базы биллинга)
|
||||
смапить код параметра с VDC (1:n)
|
||||
iaas.ngc.i31.ram-m
|
||||
iaas.ngc.a28.ram-m
|
||||
|
||||
cl01:
|
||||
7 хостов Lenovo ThinkSystem SR650 -[7X06CTO1WW]-
|
||||
2 процессора Xeon(R) Gold 6226R 16 ядер 32 потока каждый 2.9 ГГц
|
||||
1.25тб озу в каждом.
|
||||
В 4 из 7 есть по 4 GPU NVIDIA A16 16GB в каждом.
|
||||
|
||||
cl01-vsan:
|
||||
16 хостов Lenovo ThinkSystem SR650 -[7X06CTO1WW]-
|
||||
2 процессора Xeon(R) Gold 6226R 16 ядер 32 потока каждый 2.9 ГГц
|
||||
1.25тб озу в каждом.
|
||||
В 9 из 16 есть по 4 GPU NVIDIA A16 16GB в каждом.
|
||||
|
||||
cl02:
|
||||
10 Huawei 2488H V5
|
||||
4 процессора Xeon(R) Gold 6254 18 ядер 36 потоков каждый. 3.1 ГГц
|
||||
2тб озу в каждом.
|
||||
|
||||
5 Huawei Atlas 800 (Model 3010)
|
||||
2 процессора Xeon(R) Gold 6254 18 ядер 36 потоков каждый. 3.1 ГГц
|
||||
1.5тб озу в каждом.
|
||||
|
||||
cl04-vsan:
|
||||
10 Apex AR320-12
|
||||
2 процессора AMD EPYC 7543 32 ядра 64 потока каждый. 2.8 ГГц
|
||||
2тб озу в каждом.
|
||||
18 Apex AR320-12-E7543
|
||||
2 процессора AMD EPYC 7543 32 ядра 64 потока каждый. 2.8 ГГц
|
||||
2тб озу в каждом.
|
||||
|
||||
cl05-1c:
|
||||
1 Asus RS720A-E12-RS24U
|
||||
2 процессора AMD EPYC 9274F 24 ядра 48 потоков каждый. 4.05 ГГц
|
||||
1тб озу.
|
||||
|
||||
7 ручная сборка
|
||||
MB Asus ProArt B650-Creator
|
||||
Процессор AMD Ryzen 9 7950X 16 ядер 32 потока каждый. 4.5 ГГц
|
||||
192гб озу каждый.
|
||||
|
||||
1 ручная сборка
|
||||
процессор AMD Ryzen Threadripper PRO 5995WX 64 ядра 128 потоков каждый. 2.7 ГГц
|
||||
512гб озу.
|
||||
|
||||
cl06-vsan:
|
||||
15 R320
|
||||
2 процессора Xeon(R) Gold 6342 24 ядра 48 потоков каждый. 2.8 ГГц
|
||||
1тб озу каждый.
|
||||
|
||||
Xeon(R) Gold 6226R 2.9 ГГц
|
||||
Xeon(R) Gold 6254 3.1 ГГц
|
||||
AMD EPYC 7543 2.8 ГГц
|
||||
AMD EPYC 9274F 4.05 ГГц
|
||||
AMD Ryzen 9 7950X 4.5 ГГц
|
||||
AMD Ryzen Threadripper PRO 5995WX 2.7 ГГц
|
||||
Xeon(R) Gold 6342 2.8 ГГц --->
|
||||
|
||||
<!--- 2025-08-15 20:47:44 *** Операции S3 считаются не так, как написано в тарифе. Например, считается list. В тарифе вообще не описан минимальный лимит --->
|
||||
|
||||
<!--- BEGIN
|
||||
RETURN QUERY
|
||||
(
|
||||
select
|
||||
billing_per_user_fix_pl.placement as placement,
|
||||
(CASE
|
||||
WHEN ( billing_per_user_fix_pl.placement = 'HOT'
|
||||
) THEN greatest(ceil(sum(size)/1024/1024/1024)-1,0)
|
||||
WHEN ( not billing_per_user_fix_pl.placement = 'HOT'
|
||||
) THEN ceil(sum(size)/1024/1024/1024)
|
||||
END) AS size_GB,
|
||||
(CASE
|
||||
WHEN ( billing_per_user_fix_pl.placement = 'HOT'
|
||||
) THEN greatest(ceil(sum(get)/10000)-10,0)
|
||||
WHEN ( not billing_per_user_fix_pl.placement = 'HOT'
|
||||
) THEN ceil(sum(get)/10000)
|
||||
END) AS get_10k,
|
||||
(CASE
|
||||
WHEN ( billing_per_user_fix_pl.placement = 'HOT'
|
||||
) THEN greatest(ceil(sum(put)/10000)-1,0)
|
||||
WHEN ( not billing_per_user_fix_pl.placement = 'HOT'
|
||||
) THEN ceil(sum(put)/10000)
|
||||
END) AS put_10k,
|
||||
(CASE
|
||||
WHEN ( billing_per_user_fix_pl.placement = 'HOT'
|
||||
) then greatest(ceil(sum(bytes_sent)/1024/1024/1024)-100,0)
|
||||
WHEN ( not billing_per_user_fix_pl.placement = 'HOT'
|
||||
) THEN ceil(sum(bytes_sent)/1024/1024/1024)
|
||||
END) AS bytes_sent_GB
|
||||
from s3billing.billing_per_user_fix_pl(_ds,_df,_user)
|
||||
group by billing_per_user_fix_pl.placement
|
||||
UNION all
|
||||
select
|
||||
'HOT_FREE_LIMIT' as placement,
|
||||
'1' AS size_GB,
|
||||
'10' AS get_10k,
|
||||
'1' AS put_10k,
|
||||
'100' AS bytes_sent_GB
|
||||
);
|
||||
END; --->
|
||||
|
||||
<!---
|
||||
BEGIN
|
||||
RETURN QUERY
|
||||
|
||||
SELECT
|
||||
s3billing.bucket_info.name AS bucket_name,
|
||||
(case
|
||||
when ( s3billing.placement.name = 'default-placement') then 'HOT'
|
||||
WHEN ( not s3billing.placement.name = 'default-placement' ) THEN s3billing.placement.name
|
||||
end
|
||||
) as placement,
|
||||
coalesce(round(sum(usage_rgw_main_size_actual)/
|
||||
(SELECT (DATE_PART('day',
|
||||
((TO_TIMESTAMP(_df, 'YYYY-MM-DD HH24:MI:SS'))
|
||||
-TO_TIMESTAMP(_ds, 'YYYY-MM-DD HH24:MI:SS'))
|
||||
)*24+
|
||||
DATE_PART('hour',
|
||||
((TO_TIMESTAMP(_df, 'YYYY-MM-DD HH24:MI:SS'))
|
||||
-TO_TIMESTAMP(_ds, 'YYYY-MM-DD HH24:MI:SS'))
|
||||
)))
|
||||
|
||||
)::numeric,0) AS size
|
||||
,coalesce(s2.get, 0) AS get
|
||||
,coalesce(s2.put, 0) AS put
|
||||
,coalesce(s2.bytes_sent, 0) as bytes_sent
|
||||
FROM s3billing.bucket_stat
|
||||
INNER JOIN s3billing.placement ON s3billing.bucket_stat.placement_id=s3billing.placement.id
|
||||
INNER JOIN s3billing.bucket_info ON s3billing.bucket_stat.bucket_id=s3billing.bucket_info.id
|
||||
LEFT JOIN (
|
||||
SELECT
|
||||
s1.bucket_id AS bucket_id
|
||||
,s1.bucket_name AS bucket_name,
|
||||
(case
|
||||
when ( s1.placement = 'default-placement') then 'HOT'
|
||||
WHEN ( not s1.placement = 'default-placement' ) THEN s1.placement
|
||||
end
|
||||
) as placement
|
||||
,coalesce(sum(s1.get) ,0) AS get
|
||||
,coalesce(sum(s1.put) ,0) AS put
|
||||
,coalesce(sum(s1.bytes_sent), 0) AS bytes_sent
|
||||
FROM (
|
||||
SELECT
|
||||
s3billing.bucket_info.id AS bucket_id
|
||||
,s3billing.bucket_info.name AS bucket_name
|
||||
,(case
|
||||
when ( s3billing.placement.name = 'default-placement') then 'HOT'
|
||||
WHEN ( not s3billing.placement.name = 'default-placement' ) THEN s3billing.placement.name
|
||||
end
|
||||
) as placement
|
||||
,(CASE
|
||||
WHEN ( s3billing.category.name LIKE 'get%'
|
||||
OR s3billing.category.name LIKE 'head%'
|
||||
OR s3billing.category.name LIKE 'options%'
|
||||
) THEN coalesce(sum(ops), 0)
|
||||
END) AS get
|
||||
,(CASE
|
||||
WHEN ( s3billing.category.name LIKE 'put%'
|
||||
OR s3billing.category.name LIKE 'post%'
|
||||
OR s3billing.category.name LIKE 'patch%'
|
||||
OR s3billing.category.name LIKE 'list%'
|
||||
) THEN coalesce(sum(ops), 0)
|
||||
END) AS put
|
||||
,coalesce(sum(usage_bucket_by_user.bytes_sent), 0) AS bytes_sent
|
||||
|
||||
FROM
|
||||
s3billing.usage_bucket_by_user
|
||||
INNER JOIN s3billing.bucket_info ON s3billing.usage_bucket_by_user.bucketid = s3billing.bucket_info.id
|
||||
INNER JOIN s3billing.placement ON s3billing.bucket_info.placement_id = s3billing.placement.id
|
||||
INNER JOIN s3billing.user_info ON s3billing.usage_bucket_by_user.user_id = s3billing.user_info.id
|
||||
INNER JOIN s3billing.category ON s3billing.usage_bucket_by_user.category_id = s3billing.category.id
|
||||
|
||||
WHERE
|
||||
s3billing.user_info.name=_user
|
||||
AND s3billing.usage_bucket_by_user.time >=TO_TIMESTAMP(_ds, 'YYYY-MM-DD HH24:MI:SS')
|
||||
AND s3billing.usage_bucket_by_user.time < TO_TIMESTAMP(_df, 'YYYY-MM-DD HH24:MI:SS')
|
||||
GROUP BY
|
||||
s3billing.bucket_info.name
|
||||
,s3billing.placement.name
|
||||
,s3billing.category.name
|
||||
,s3billing.bucket_info.id
|
||||
) AS s1
|
||||
|
||||
GROUP BY
|
||||
s1.bucket_name
|
||||
,s1.bucket_id
|
||||
,s1.placement
|
||||
|
||||
ORDER BY
|
||||
s1.placement
|
||||
,s1.bucket_name
|
||||
|
||||
) AS s2 ON s2.bucket_id = s3billing.bucket_stat.bucket_id
|
||||
WHERE owner=_user
|
||||
AND timestamp_addition >= TO_TIMESTAMP(_ds, 'YYYY-MM-DD HH24:MI:SS')
|
||||
AND timestamp_addition < TO_TIMESTAMP(_df, 'YYYY-MM-DD HH24:MI:SS')
|
||||
GROUP BY
|
||||
s3billing.bucket_info.name
|
||||
,s3billing.placement.name
|
||||
,s3billing.bucket_stat.bucket_id
|
||||
,s2.get
|
||||
,s2.put
|
||||
,s2.bytes_sent
|
||||
ORDER BY
|
||||
s3billing.placement.name
|
||||
,s3billing.bucket_info.name
|
||||
;
|
||||
END; --->
|
||||
<!--- select * from s3billing.billing_per_user_fix_pl('2025-05-01 00:00:00','2025-06-01 00:00:00','1395'); --->
|
||||
|
||||
@@ -0,0 +1,321 @@
|
||||
/*common elements*/
|
||||
html, body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: none;
|
||||
height: 100%;
|
||||
}
|
||||
body, table, tr, td, th, input, select, textarea, button, form, ul, li, p {
|
||||
font-size: 11px;
|
||||
font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif;
|
||||
color:black;
|
||||
}
|
||||
form {margin: 0;padding:0;}
|
||||
p {margin: 0.5em;}
|
||||
table {border-collapse: collapse;}
|
||||
img {border: none; margin: 0; vertical-align: middle;}
|
||||
a, a:link, a:visited {color: #111111; text-decoration: underline;}
|
||||
a:hover {color: #ff7600; text-decoration: underline;}
|
||||
|
||||
|
||||
/* form elements */
|
||||
input {color: black; padding: 0 0.3em; }
|
||||
input:read-only {color:#555; background-color:#f0f0f0;}
|
||||
input:disabled {color:#555; background-color:#f0f0f0;}
|
||||
select:disabled {color:#555;}
|
||||
select option[disabled] { color:#ddd;}
|
||||
|
||||
.detail .td input[type="text"]:disabled {border:1px solid #aaa; color:#555;}
|
||||
.textbox-disabled {display:inline-block; border: 1px solid #aaa; color:#555; background-color:#f0f0f0; padding:.1em;}
|
||||
|
||||
/*layout*/
|
||||
|
||||
div.vspacer {height:5px;}
|
||||
|
||||
ul#mainmenu {
|
||||
list-style-type:none;
|
||||
padding:0;
|
||||
margin:0;
|
||||
display:block;
|
||||
width:100%;
|
||||
}
|
||||
ul#mainmenu li {
|
||||
text-align:right;
|
||||
vertical-align:baseline;
|
||||
padding:.2em 15px .2em 0 ;
|
||||
margin:.3em 0;
|
||||
background: url('../img/sarrow.gif') center right no-repeat;
|
||||
font-size:120%;
|
||||
font-weight:normal;
|
||||
font-family: Verdana, Tahoma, Arial, Helvetica, sans-serif;
|
||||
line-height: 1.1em;
|
||||
}
|
||||
ul#mainmenu li a{/*display:block;*/color:#cde;text-decoration:none;}
|
||||
ul#mainmenu li a:hover{text-decoration:underline;}
|
||||
ul#mainmenu li.selected {color: /*#4682b4;*/ #fa6 /*#00f*/;}
|
||||
ul#mainmenu li.menu-item-ext {background: url('../img/external.gif') center right no-repeat;}
|
||||
ul#mainmenu li.menu-item-noaction {background: none; color: #777;}
|
||||
ul#mainmenu li.menu-title {
|
||||
color: #111;
|
||||
background:none white;
|
||||
margin:.5em 0 0 0;
|
||||
/*font-weight: bold;*/
|
||||
/*border:1px solid #ccc;*/
|
||||
}
|
||||
|
||||
.page {display:table; table-layout: fixed; width:100%; height:100%;}
|
||||
|
||||
.page-main {display:table-row; height:100%;}
|
||||
|
||||
.page-footer {display:table-row; height:1px;}
|
||||
|
||||
.menu {display:table-cell; width:150px; padding:0 0 0 .5em; background-color: #012; -border:1px solid red;}
|
||||
|
||||
.content {display:table-cell; height:100%; vertical-align:top; padding: 3px;}
|
||||
|
||||
.header {display:block; /*background:url('../img/portlet_dot.gif') center left no-repeat; padding-left:33px;*/ line-height: 21px; font-family: Verdana, Tahoma, sans-serif;}
|
||||
|
||||
.control-bar {display:table; width:100%; color:/*#559*/white; /*border:1px solid #ccc;*/ height:19px; }
|
||||
.header .control-bar a:link, .header .control-bar a:visited {color:white; padding: .2em .5em;}
|
||||
.header .control-bar a:hover {background:white;color:#f90; padding: .2em .5em;}
|
||||
|
||||
.title {display:table-cell; padding:1px 12px; vertical-align:middle; font-size:110%; background-color:#aaa/*#ccc*//*rgb(117,147,156)*/; /*color:#fa6;*/ border: 1px solid #bbb; border-right:none;}
|
||||
.title b {color:#026;}
|
||||
|
||||
.main-controls {display:table-cell; padding:0 7px; text-align:right; vertical-align: middle; background-color:#aaa/*rgb(117,147,156)*/; border: 1px solid #bbb; border-left:none;}
|
||||
|
||||
.footer {height:21px; line-height: 21px; background-color:#e0e0e0; border:1px solid #bbb; text-align: right; vertical-align: middle; padding:0 3px;}
|
||||
|
||||
|
||||
.table {display:table;}
|
||||
.tr {display:table-row;}
|
||||
.td, .th {display:table-cell; padding: 0 0.5em; vertical-align:top;}
|
||||
|
||||
|
||||
.detail {
|
||||
display:table;
|
||||
width:100%;
|
||||
margin: 3px 0;
|
||||
border:1px solid #ddd;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
.detail .tr{
|
||||
line-height: 1.5em;
|
||||
}
|
||||
.detail .th {
|
||||
display:table-cell;
|
||||
text-align:right;
|
||||
background-color:#e0e0e0;
|
||||
padding:0.35em 0.5em;
|
||||
border:none;
|
||||
/*color: #5f5f5f;*/
|
||||
font-weight:normal;
|
||||
vertical-align:top;
|
||||
/*border:1px solid red;*/
|
||||
}
|
||||
.detail .td {
|
||||
display:table-cell;
|
||||
background-color:#e7e7e7;
|
||||
padding:0.2em 0.5em;
|
||||
border:1px solid #ddd;
|
||||
vertical-align:baseline;
|
||||
}
|
||||
.detail .td input, .detail .td select, .detail .td img, .detail .td button, .detail .td div, .detail .td span {
|
||||
vertical-align: baseline;
|
||||
margin: 0 0.3em;
|
||||
}
|
||||
|
||||
.detail .td label {
|
||||
vertical-align: baseline;
|
||||
margin: 0 0.3em 0 0;
|
||||
line-height:normal;
|
||||
}
|
||||
|
||||
.detail .td input[type="checkbox"] {
|
||||
vertical-align: top; margin: 0 0 0 0.3em;
|
||||
}
|
||||
|
||||
/*.detail .td input[type="text"] {
|
||||
width: 97%;
|
||||
}*/
|
||||
|
||||
.detail .td textarea {
|
||||
color: black;
|
||||
width: 97%;
|
||||
margin-left: 0.2em;
|
||||
padding: 0.2em 0.5em;
|
||||
}
|
||||
/***hack*/
|
||||
.detail .td a img {vertical-align:text-bottom;}
|
||||
|
||||
.filter {background-color: #f7f7f7;}
|
||||
.disabled, tr.disabled td, tr.disabled th {color: #888;}
|
||||
.plate {background-color:#f0f0f0; padding:.1em; border:1px solid #ddd;}
|
||||
|
||||
button, .button, .content a.button:link {
|
||||
background: #fafafa;
|
||||
-background: -webkit-linear-gradient(top, #fafafa 0%, #f4f4f4 40%,#e5e5e5 100%);
|
||||
background:-webkit-linear-gradient(top, #dde 0%, #cde 40%,#bcd 100%);
|
||||
border: 1px solid #aad;
|
||||
padding: 1px 10px;
|
||||
color: #black;
|
||||
border-radius: 3px;
|
||||
box-shadow: 0 1px 1px #ddd;
|
||||
}
|
||||
|
||||
button:disabled, .button:disabled, .maincontrol:disabled {
|
||||
background: #fafafa;
|
||||
background: -webkit-linear-gradient(top, #fafafa 0%,#f4f4f4 40%,#e5e5e5 100%);
|
||||
border-color: #aaa;
|
||||
color: #999;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
button:not(:disabled):hover,
|
||||
.button:not(:disabled):hover,
|
||||
.maincontrol:not(:disabled):hover
|
||||
{
|
||||
background: #fefefe;
|
||||
background: -webkit-linear-gradient(top, #fefefe 0%,#f8f8f8 40%,#e9e9e9 100%);
|
||||
box-shadow: 0 1px 3px rgba(7, 7, 7, 0.35);
|
||||
border: 1px solid #aaa;
|
||||
color: #ff7600;
|
||||
}
|
||||
|
||||
button:not(:disabled):active, .button:not(:disabled):active {
|
||||
background: #f4f4f4;
|
||||
background: -webkit-linear-gradient(top, #f4f4f4 0%,#efefef 40%,#dcdcdc 100%);
|
||||
box-shadow: inset 0 1px 3px rgba(7, 7, 7, 0.35);
|
||||
}
|
||||
|
||||
button.maincontrol {
|
||||
/*background-color:#c3c82f;
|
||||
background:-webkit-linear-gradient(top, #cd6 0%, #cd6 40%,#bc5 100%);*/
|
||||
-background-color:#6fa0f0;
|
||||
background-color:#6fa0f0;
|
||||
background:-webkit-linear-gradient(top, #dde 0%, #cde 40%,#bcd 100%);
|
||||
color: black;
|
||||
}
|
||||
|
||||
button.maincontrol:hover {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*не совсем аккуратно, при нажатии выглядит чуть иначе, чем кнопка*/
|
||||
.content button a, .content button a:link, .content button a:visited {color: #790; text-decoration:none; cursor:default;}
|
||||
.content button:hover a, .content button:active {color: #ff7600; text-decoration:none; cursor:default;}
|
||||
.content button.maincontrol a, .content button.maincontrol a:link,.content button.maincontrol a:visited {color: black;}
|
||||
.content button.maincontrol:hover a, .content button.maincontrol:active a {color: #ff7600;}
|
||||
|
||||
.submitnew {
|
||||
background-image:url('../img/new.gif');
|
||||
width:13px; height:13px; border:none; padding:0; color:transparent; cursor:pointer;
|
||||
}
|
||||
.submitsave {
|
||||
background-image:url('../img/save.gif');
|
||||
width:14px; height:14px; border:none; padding:0; color:transparent; cursor:pointer;
|
||||
}
|
||||
.submitdel {
|
||||
background-image:url('../img/del.gif');
|
||||
width:13px; height:13px; border:none; padding:0; color:transparent; cursor:pointer;
|
||||
}
|
||||
.submitminus {
|
||||
background-image:url('../img/minus.gif');
|
||||
width:13px; height:13px; border:none; padding:0; color:transparent; cursor:pointer;
|
||||
}
|
||||
|
||||
.content a, .content a:link, .content a:visited {color: #1111ee; text-decoration: none;}
|
||||
.content a:hover {color: #ff7600; text-decoration: underline;}
|
||||
.content h4 {margin-block-end: .5em;}
|
||||
.content i {color:#555;}
|
||||
|
||||
.cell {border: 1px solid #ddd; width:100%; padding: 0.2em;}
|
||||
|
||||
.l, td.l, th.l{text-align: left;}
|
||||
.r, td.r, th.r{text-align: right;}
|
||||
.c, td.c, th.c{text-align: center;}
|
||||
.nw {white-space: nowrap;}
|
||||
.b {font-weight:bold;}
|
||||
.i {font-style:italic;}
|
||||
.wide {min-width:100%}
|
||||
.wh100 {width:100%; height:100%;}
|
||||
.table {display:table}
|
||||
.tcell {display:table-cell}
|
||||
.mid {vertical-align:middle} /*используется для заполнения ячейки таблицы якорем a href*/
|
||||
|
||||
.err {color: red;}
|
||||
.warn {color: #f80;}
|
||||
|
||||
a.up {background: url('../img/up.gif') center right no-repeat; padding-right: 7px;}
|
||||
a.add {background: url('../img/add.gif') center right no-repeat; width:13px; height:13px; display:inline-block;}
|
||||
a.edit {background: url('../img/edit.gif') center right no-repeat; width:13px; height:13px; display:inline-block;}
|
||||
a.view {background: url('../img/view.gif') center right no-repeat; width:13px; height:13px; display:inline-block;}
|
||||
a.del {background: url('../img/del.gif') center right no-repeat; width:13px; height:13px; display:inline-block;}
|
||||
|
||||
|
||||
/* worktable classes */
|
||||
|
||||
table.worktable {border-collapse:separate; border-spacing:0; border-left:1px solid #ddd;}
|
||||
|
||||
table.worktable th,
|
||||
table.worktable td {
|
||||
border-bottom: thin solid #ddd;
|
||||
border-right: thin solid #ddd;
|
||||
}
|
||||
table.worktable thead th,
|
||||
table.worktable thead td {
|
||||
box-shadow: 0 -1px 0 0 #ddd;
|
||||
}
|
||||
table.worktable thead {
|
||||
top: 0;
|
||||
left: 0;
|
||||
position: sticky;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
table.worktable td p {margin:0;}
|
||||
|
||||
table.worktable thead tr td, table.worktable tr th{padding: 3px; background-color: #999;}
|
||||
|
||||
table.worktable tr {height: 1.7em; background-color: white;}
|
||||
|
||||
table.worktable tr td {padding:0.1em 0.3em; height:2em;}
|
||||
|
||||
table.worktable tr:hover, table.worktable tr td:hover {background-color:#e5e5e5;}
|
||||
|
||||
table.worktable th {font-weight:500; color:white;}
|
||||
|
||||
/*double borders - not tested with border-collapse:separate*/
|
||||
table.worktable tbody tr td.lbd,
|
||||
table.worktable thead tr td.lbd
|
||||
{border-left: double #ccc;}
|
||||
|
||||
table.worktable tbody tr td.rbd,
|
||||
table.worktable thead tr td.rbd
|
||||
{border-right: double #ccc;}
|
||||
|
||||
table.worktable tbody tr td.tbd,
|
||||
table.worktable thead tr td.tbd,
|
||||
table.worktable tbody tr.tbd td,
|
||||
table.worktable thead tr.tbd td
|
||||
{border-top: double #ccc;}
|
||||
|
||||
table.worktable tbody tr td.bbd,
|
||||
table.worktable thead tr td.bbd,
|
||||
table.worktable tbody tr.bbd td,
|
||||
table.worktable thead tr.bbd td
|
||||
{border-bottom: double #ccc;}
|
||||
|
||||
table.worktable tr.hist {background-color: #f6f6f6;}
|
||||
table.worktable tr.hist:hover, table.worktable tr.hist:hover td, table.worktable tr.comment:hover{background-color:#efefef;}
|
||||
table.worktable tr.hist td.marked {background: #ddf5c0;}
|
||||
table.worktable tr.hist:hover td.marked{background-color:#d0f0b9;}
|
||||
|
||||
|
||||
@media print {
|
||||
#mainmenu, .menu, .page-footer, .control-bar, .noprint {display:none;}
|
||||
}
|
||||
|
||||
|
||||
|
||||