def query_usage_report(context, datetime_from=None, datetime_to=None, **kwargs): usage_report = dict() subscriptions = db.subscription_get_all_by_project(context, context.project_id) for subscription in subscriptions: subscription_id = subscription['id'] resource_uuid = subscription['resource_uuid'] resource_name = subscription['resource_name'] region_name = subscription['product']['region']['name'] item_name = subscription['product']['item']['name'] item_type_name = subscription['product']['item_type']['name'] order_unit = subscription['product']['order_unit'] price = subscription['product']['price'] currency = subscription['product']['currency'] purchases = db.purchase_get_all_by_subscription_and_timeframe(context, subscription_id, datetime_from, datetime_to) quantity_sum = sum(map(lambda x: x['quantity'], purchases)) line_total_sum = sum(map(lambda x: x['line_total'], purchases)) # TODO(lzyeval): remove #assert (line_total_sum == quantity_sum * price) usage_datum = (resource_uuid, resource_name, item_type_name, order_unit, price, currency, quantity_sum, line_total_sum) item_usage_report = usage_report.get(item_name, dict()) if not item_usage_report: usage_report[item_name] = item_usage_report region_usage_data = item_usage_report.get(region_name, list()) if not region_usage_data: item_usage_report[region_name] = region_usage_data region_usage_data.append(usage_datum) return {'data': usage_report}
def query_monthly_report(context, timestamp_from=None, timestamp_to=None, **kwargs): def find_timeframe(start_time, end_time, target): target_utc = target.replace(tzinfo=UTC_TIMEZONE) current_frame = start_time month_cnt = 1 while current_frame < end_time: # 2012-05-10 00:00:00+00:00-->2012-06-10 00:00:00+00:00 next_frame = start_time + relativedelta(months=month_cnt) if current_frame <= target_utc < next_frame: break month_cnt += 1 current_frame = next_frame assert(current_frame < end_time) return current_frame.isoformat() monthly_report = dict() datetime_from = iso8601.parse_date(timestamp_from) datetime_to = iso8601.parse_date(timestamp_to) subscriptions = list() _subscriptions = db.subscription_get_all_by_project(context, context.project_id) for subscription in _subscriptions: subscription_id = subscription['id'] if subscription is None \ or subscription['product'] is None \ or subscription['product']['region'] is None \ or subscription['product']['region']['name'] is None: continue region_name = subscription['product']['region']['name'] item_name = subscription['product']['item']['name'] subscriptions.append([subscription_id, region_name, item_name]) for subscription_id, region_name, item_name in subscriptions: purchases = db.purchase_get_all_by_subscription_and_timeframe(context, subscription_id, datetime_from, datetime_to) if not purchases: continue for purchase in purchases: line_total = purchase['line_total'] timeframe = find_timeframe(datetime_from, datetime_to, purchase['created_at']) region_usage = monthly_report.setdefault(region_name, dict()) monthly_usage = region_usage.setdefault(timeframe, dict()) monthly_usage.setdefault(item_name, 0) monthly_usage[item_name] += line_total return {'data': monthly_report}
def query_usage_report(context, timestamp_from=None, timestamp_to=None, **kwargs): usage_report = dict() datetime_from = iso8601.parse_date(timestamp_from) datetime_to = iso8601.parse_date(timestamp_to) subscriptions = list() _subscriptions = db.subscription_get_all_by_project(context, context.project_id) for subscription in _subscriptions: if subscription is None \ or subscription['product'] is None \ or subscription['product']['region'] is None \ or subscription['product']['region']['name'] is None: continue subscription_id = subscription['id'] resource_uuid = subscription['resource_uuid'] resource_name = subscription['resource_name'] created_at = subscription['created_at'] expires_at = subscription['expires_at'] region_name = subscription['product']['region']['name'] item_name = subscription['product']['item']['name'] item_type_name = subscription['product']['item_type']['name'] order_unit = subscription['product']['order_unit'] order_size = subscription['product']['order_size'] price = subscription['product']['price'] currency = subscription['product']['currency'] subscriptions.append([subscription_id, resource_uuid, resource_name, created_at, expires_at, region_name, item_name, item_type_name, order_unit, order_size, price, currency]) for (subscription_id, resource_uuid, resource_name, created_at, expires_at, region_name, item_name, item_type_name, order_unit, order_size, price, currency) in subscriptions: purchases = db.purchase_get_all_by_subscription_and_timeframe(context, subscription_id, datetime_from, datetime_to) if not purchases: continue quantity_sum = sum(map(lambda x: x['quantity'], purchases)) line_total_sum = sum(map(lambda x: x['line_total'], purchases)) # TODO(lzyeval): remove #assert (line_total_sum == quantity_sum * price) usage_datum = (resource_uuid, resource_name, item_type_name, order_unit, order_size, price, currency, quantity_sum, line_total_sum, created_at.isoformat(), expires_at.isoformat()) region_usage = usage_report.setdefault(region_name, dict()) item_usage = region_usage.setdefault(item_name, list()) item_usage.append(usage_datum) return {'data': usage_report}
def test_query_usage_report(self): timestamp_from = '2012-03-24T16:44:21' timestamp_to = '2012-03-24T16:46:21' datetime_from = iso8601.parse_date(timestamp_from) datetime_to = iso8601.parse_date(timestamp_to) project_subscriptions = [ { 'id': self.subscription_id, 'resource_uuid': self.resource_uuid, 'resource_name': self.resource_name, 'product': { 'region': { 'name': self.region_name, }, 'item': { 'name': self.item_name, }, 'item_type': { 'name': self.item_type_name, }, 'order_unit': 'hours', 'order_size': 1, 'price': self.product_price, 'currency': 'CNY', } }, { 'id': 60, 'resource_uuid': 'a-fake-uuid-1', 'resource_name': 'a_fake_name_1', 'product': { 'region': { 'name': 'default', }, 'item': { 'name': 'instance', }, 'item_type': { 'name': 'm1.large', }, 'order_unit': 'months', 'order_size': 1, 'price': Decimal(2100.00).quantize(Decimal('0.01')), 'currency': 'CNY', } }, { 'id': 61, 'resource_uuid': 'a-fake-uuid-2', 'resource_name': '10.211.23.45', 'product': { 'region': { 'name': 'default', }, 'item': { 'name': 'floating_ip', }, 'item_type': { 'name': 'default', }, 'order_unit': 'days', 'order_size': 1, 'price': Decimal(1.10).quantize(Decimal('0.01')), 'currency': 'CNY', } }, { 'id': 62, 'resource_uuid': 'a-fake-uuid-3', 'resource_name': '170.1.223.5', 'product': { 'region': { 'name': 'default', }, 'item': { 'name': 'floating_ip', }, 'item_type': { 'name': 'default', }, 'order_unit': 'days', 'order_size': 1, 'price': Decimal(1.10).quantize(Decimal('0.01')), 'currency': 'CNY', } }, { 'id': 63, 'resource_uuid': 'a-fake-uuid-4', 'resource_name': 'a_fake_name_4', 'product': { 'region': { 'name': 'default', }, 'item': { 'name': 'load_balancer', }, 'item_type': { 'name': 'default', }, 'order_unit': 'days', 'order_size': 1, 'price': Decimal(2.70).quantize(Decimal('0.01')), 'currency': 'CNY', } }, { 'id': 64, 'resource_uuid': 'a-fake-uuid-5', 'resource_name': 'a_fake_name_5', 'product': { 'region': { 'name': 'default', }, 'item': { 'name': 'load_balancer', }, 'item_type': { 'name': 'default', }, 'order_unit': 'days', 'order_size': 1, 'price': Decimal(2.70).quantize(Decimal('0.01')), 'currency': 'CNY', } }, { 'id': 65, 'resource_uuid': self.resource_uuid, 'resource_name': '192.168.0.2', 'product': { 'region': { 'name': self.region_name, }, 'item': { 'name': 'network-out', }, 'item_type': { 'name': 'default', }, 'order_unit': 'KBytes', 'order_size': 1, 'price': Decimal(0.70).quantize(Decimal('0.01')), 'currency': 'CNY', } }, { 'id': 66, 'resource_uuid': 'a-fake-uuid-1', 'resource_name': '192.168.0.3', 'product': { 'region': { 'name': 'default', }, 'item': { 'name': 'network-out', }, 'item_type': { 'name': 'default', }, 'order_unit': 'KBytes', 'order_size': 1, 'price': Decimal(0.70).quantize(Decimal('0.01')), 'currency': 'CNY', } }, ] purchases1 = [ { 'quantity': 6, 'line_total': Decimal(14.40).quantize(Decimal('0.01')), }, { 'quantity': 8, 'line_total': Decimal(19.20).quantize(Decimal('0.01')), }, { 'quantity': 2, 'line_total': Decimal(4.80).quantize(Decimal('0.01')), }, ] purchases2 = [ { 'quantity': 1, 'line_total': Decimal(2100.00).quantize(Decimal('0.01')), }, ] purchases3 = [ { 'quantity': 6, 'line_total': Decimal(6.60).quantize(Decimal('0.01')), }, { 'quantity': 8, 'line_total': Decimal(8.80).quantize(Decimal('0.01')), }, { 'quantity': 5, 'line_total': Decimal(5.50).quantize(Decimal('0.01')), }, ] purchases4 = [ { 'quantity': 6, 'line_total': Decimal(6.60).quantize(Decimal('0.01')), }, { 'quantity': 3, 'line_total': Decimal(3.30).quantize(Decimal('0.01')), }, { 'quantity': 2, 'line_total': Decimal(2.20).quantize(Decimal('0.01')), }, ] purchases5 = [ { 'quantity': 6, 'line_total': Decimal(16.20).quantize(Decimal('0.01')), }, { 'quantity': 3, 'line_total': Decimal(8.10).quantize(Decimal('0.01')), }, { 'quantity': 4, 'line_total': Decimal(10.80).quantize(Decimal('0.01')), }, ] purchases6 = [ { 'quantity': 6, 'line_total': Decimal(16.20).quantize(Decimal('0.01')), }, { 'quantity': 8, 'line_total': Decimal(21.60).quantize(Decimal('0.01')), }, { 'quantity': 13, 'line_total': Decimal(35.10).quantize(Decimal('0.01')), }, ] purchases7 = [ { 'quantity': 1000, 'line_total': Decimal(700.00).quantize(Decimal('0.01')), }, { 'quantity': 800, 'line_total': Decimal(560.00).quantize(Decimal('0.01')), }, { 'quantity': 52, 'line_total': Decimal(36.40).quantize(Decimal('0.01')), }, ] purchases8 = [ { 'quantity': 9000, 'line_total': Decimal(6300.00).quantize(Decimal('0.01')), }, { 'quantity': 800, 'line_total': Decimal(560.00).quantize(Decimal('0.01')), }, { 'quantity': 53, 'line_total': Decimal(37.10).quantize(Decimal('0.01')), }, ] usage_report = { 'load_balancer': { 'default': [ ('a-fake-uuid-4', 'a_fake_name_4', 'default', 'days', 2.70, 'CNY', 13, 35.10), ('a-fake-uuid-5', 'a_fake_name_5', 'default', 'days', 2.70, 'CNY', 27, 72.90), ] }, 'instance': { 'default': [ (self.resource_uuid, self.resource_name, self.item_type_name, 'hours', float(self.product_price), 'CNY', 16, 38.40), ('a-fake-uuid-1', 'a_fake_name_1', 'm1.large', 'months', 2100.00, 'CNY', 1, 2100.00), ], }, 'floating_ip': { 'default': [ ('a-fake-uuid-2', '10.211.23.45', 'default', 'days', 1.10, 'CNY', 19, 20.90), ('a-fake-uuid-3', '170.1.223.5', 'default', 'days', 1.10, 'CNY', 11, 12.10), ], }, 'network-out': { 'default': [ (self.resource_uuid, '192.168.0.2', 'default', 'KBytes', 0.70, 'CNY', 1852, 1296.40), ('a-fake-uuid-1', '192.168.0.3', 'default', 'KBytes', 0.70, 'CNY', 9853, 6897.10), ] }, } self.mox.StubOutWithMock(db, 'subscription_get_all_by_project') _purchase_func = 'purchase_get_all_by_subscription_and_timeframe' self.mox.StubOutWithMock(db, _purchase_func) db.subscription_get_all_by_project(self.context, self.tenant_id).\ AndReturn(project_subscriptions) db.purchase_get_all_by_subscription_and_timeframe(self.context, self.subscription_id, datetime_from, datetime_to).\ InAnyOrder().AndReturn(purchases1) db.purchase_get_all_by_subscription_and_timeframe(self.context, 60, datetime_from, datetime_to).\ InAnyOrder().AndReturn(purchases2) db.purchase_get_all_by_subscription_and_timeframe(self.context, 61, datetime_from, datetime_to).\ InAnyOrder().AndReturn(purchases3) db.purchase_get_all_by_subscription_and_timeframe(self.context, 62, datetime_from, datetime_to).\ InAnyOrder().AndReturn(purchases4) db.purchase_get_all_by_subscription_and_timeframe(self.context, 63, datetime_from, datetime_to).\ InAnyOrder().AndReturn(purchases5) db.purchase_get_all_by_subscription_and_timeframe(self.context, 64, datetime_from, datetime_to).\ InAnyOrder().AndReturn(purchases6) db.purchase_get_all_by_subscription_and_timeframe(self.context, 65, datetime_from, datetime_to).\ InAnyOrder().AndReturn(purchases7) db.purchase_get_all_by_subscription_and_timeframe(self.context, 66, datetime_from, datetime_to).\ InAnyOrder().AndReturn(purchases8) self.mox.ReplayAll() result = api.query_usage_report(self.context, timestamp_from, timestamp_to) self.mox.VerifyAll() expect_keys = usage_report.keys().sort() actual_keys = result['data'].keys().sort() self.assertEqual(expect_keys, actual_keys) for k, v in result['data'].iteritems(): self.assertEqual(v, usage_report[k])
def query_report(context, timestamp_from=None, timestamp_to=None, period=None, item_name=None, resource_name=None, **kwargs): """period='days' or 'hours'""" print "query_report", timestamp_from, timestamp_to, item_name, resource_name # period = int(period) if not period in ['days', 'hours', 'months']: return {'data': None} def find_timeframe(start_time, end_time, target): target_utc = target.replace(tzinfo=UTC_TIMEZONE) current_frame = start_time cnt = 1 while current_frame < end_time: foo = {period: cnt} next_frame = start_time + relativedelta(**foo) if current_frame <= target_utc < next_frame: break cnt += 1 current_frame = next_frame assert(current_frame < end_time) return current_frame.isoformat() monthly_report = dict() #usage_report = dict() datetime_from = iso8601.parse_date(timestamp_from) datetime_to = iso8601.parse_date(timestamp_to) subscriptions = list() _subscriptions = list() __subscriptions = db.subscription_get_all_by_project(context, context.project_id) if not __subscriptions: return {'data': None} # print "context.project_id", context.project_id for subscription in __subscriptions: # print subscription['id'], subscription['resource_name'], subscription['product']['item']['name'] if subscription['resource_name'] != resource_name: continue elif subscription['product']['item']['name'] != item_name: continue _subscriptions.append(subscription) for subscription in _subscriptions: subscription_id = subscription['id'] resource_uuid = subscription['resource_uuid'] resource_name = subscription['resource_name'] created_at = subscription['created_at'] expires_at = subscription['expires_at'] region_name = subscription['product']['region']['name'] item_name = subscription['product']['item']['name'] item_type_name = subscription['product']['item_type']['name'] order_unit = subscription['product']['order_unit'] order_size = subscription['product']['order_size'] price = subscription['product']['price'] currency = subscription['product']['currency'] subscriptions.append([subscription_id, resource_uuid, resource_name, created_at, expires_at, region_name, item_name, item_type_name, order_unit, order_size, price, currency]) for (subscription_id, resource_uuid, resource_name, created_at, expires_at, region_name, item_name, item_type_name, order_unit, order_size, price, currency) in subscriptions: purchases = db.purchase_get_all_by_subscription_and_timeframe(context, subscription_id, datetime_from, datetime_to) if not purchases: continue i = 0 for purchase in purchases: line_total = purchase['line_total'] quantity = purchase['quantity'] timeframe = find_timeframe(datetime_from, datetime_to, purchase['created_at']) # print timeframe i += 1 usage_datum = (resource_uuid, resource_name, item_type_name, order_unit, order_size, price, currency, quantity, line_total, created_at.isoformat(), expires_at.isoformat()) region_usage = monthly_report.setdefault(region_name, dict()) monthly_usage = region_usage.setdefault(timeframe, dict()) monthly_usage.setdefault(item_name, 0) monthly_usage[item_name] = usage_datum monthly_usage.setdefault("quantity", 0) monthly_usage.setdefault("line_total", 0) monthly_usage["quantity"] += quantity monthly_usage["line_total"] += line_total print "total:", i return {'data': monthly_report}
def test_query_usage_report(self): timestamp_from = '2012-03-24T16:44:21+00:00' timestamp_to = '2012-03-24T16:46:21+00:00' datetime_from = iso8601.parse_date(timestamp_from) datetime_to = iso8601.parse_date(timestamp_to) project_subscriptions = [ { 'id': self.subscription_id, 'resource_uuid': self.resource_uuid, 'resource_name': self.resource_name, 'created_at': datetime_from, 'expires_at': datetime_to, 'product': { 'region': { 'name': self.region_name, }, 'item': { 'name': self.item_name, }, 'item_type': { 'name': self.item_type_name, }, 'order_unit': 'hours', 'order_size': 1, 'price': self.product_price, 'currency': 'CNY', } }, { 'id': 60, 'resource_uuid': 'a-fake-uuid-1', 'resource_name': 'a_fake_name_1', 'created_at': datetime_from, 'expires_at': datetime_to, 'product': { 'region': { 'name': 'default', }, 'item': { 'name': 'instance', }, 'item_type': { 'name': 'm1.large', }, 'order_unit': 'months', 'order_size': 1, 'price': 2100.00, 'currency': 'CNY', } }, { 'id': 61, 'resource_uuid': 'a-fake-uuid-2', 'resource_name': '10.211.23.45', 'created_at': datetime_from, 'expires_at': datetime_to, 'product': { 'region': { 'name': 'default', }, 'item': { 'name': 'floating_ip', }, 'item_type': { 'name': 'default', }, 'order_unit': 'days', 'order_size': 1, 'price': 1.10, 'currency': 'CNY', } }, { 'id': 62, 'resource_uuid': 'a-fake-uuid-3', 'resource_name': '170.1.223.5', 'created_at': datetime_from, 'expires_at': datetime_to, 'product': { 'region': { 'name': 'default', }, 'item': { 'name': 'floating_ip', }, 'item_type': { 'name': 'default', }, 'order_unit': 'days', 'order_size': 1, 'price': 1.10, 'currency': 'CNY', } }, { 'id': 63, 'resource_uuid': 'a-fake-uuid-4', 'resource_name': 'a_fake_name_4', 'created_at': datetime_from, 'expires_at': datetime_to, 'product': { 'region': { 'name': 'default', }, 'item': { 'name': 'load_balancer', }, 'item_type': { 'name': 'default', }, 'order_unit': 'days', 'order_size': 1, 'price': 2.70, 'currency': 'CNY', } }, { 'id': 64, 'resource_uuid': 'a-fake-uuid-5', 'resource_name': 'a_fake_name_5', 'created_at': datetime_from, 'expires_at': datetime_to, 'product': { 'region': { 'name': 'default', }, 'item': { 'name': 'load_balancer', }, 'item_type': { 'name': 'default', }, 'order_unit': 'days', 'order_size': 1, 'price': 2.70, 'currency': 'CNY', } }, { 'id': 65, 'resource_uuid': self.resource_uuid, 'resource_name': '192.168.0.2', 'created_at': datetime_from, 'expires_at': datetime_to, 'product': { 'region': { 'name': self.region_name, }, 'item': { 'name': 'network', }, 'item_type': { 'name': 'default', }, 'order_unit': 'KBytes', 'order_size': 1, 'price': 0.70, 'currency': 'CNY', } }, { 'id': 66, 'resource_uuid': 'a-fake-uuid-1', 'resource_name': '192.168.0.3', 'created_at': datetime_from, 'expires_at': datetime_to, 'product': { 'region': { 'name': 'default', }, 'item': { 'name': 'network', }, 'item_type': { 'name': 'default', }, 'order_unit': 'KBytes', 'order_size': 1, 'price': 0.70, 'currency': 'CNY', } }, ] purchases1 = [ { 'quantity': 6, 'line_total': 14.40, }, { 'quantity': 8, 'line_total': 19.20, }, { 'quantity': 2, 'line_total': 4.80, }, ] purchases2 = [ { 'quantity': 1, 'line_total': 2100.00, }, ] purchases3 = [ { 'quantity': 6, 'line_total': 6.60, }, { 'quantity': 8, 'line_total': 8.80, }, { 'quantity': 5, 'line_total': 5.50, }, ] purchases4 = [ { 'quantity': 6, 'line_total': 6.60, }, { 'quantity': 3, 'line_total': 3.30, }, { 'quantity': 2, 'line_total': 2.20, }, ] purchases5 = [ { 'quantity': 6, 'line_total': 16.20, }, { 'quantity': 3, 'line_total': 8.10, }, { 'quantity': 4, 'line_total': 10.80, }, ] purchases6 = [ { 'quantity': 6, 'line_total': 16.20, }, { 'quantity': 8, 'line_total': 21.60, }, { 'quantity': 13, 'line_total': 35.10, }, ] purchases7 = [ { 'quantity': 1000, 'line_total': 700.00, }, { 'quantity': 800, 'line_total': 560.00, }, { 'quantity': 52, 'line_total': 36.40, }, ] purchases8 = [ { 'quantity': 9000, 'line_total': 6300.00, }, { 'quantity': 800, 'line_total': 560.00, }, { 'quantity': 53, 'line_total': 37.10, }, ] usage_report = { 'default': { 'load_balancer': [ ('a-fake-uuid-4', 'a_fake_name_4', 'default', 'days', 2.70, 'CNY', 13, 35.10, timestamp_from, timestamp_to), ('a-fake-uuid-5', 'a_fake_name_5', 'default', 'days', 2.70, 'CNY', 27, 72.90, timestamp_from, timestamp_to), ], 'instance': [ (self.resource_uuid, self.resource_name, self.item_type_name, 'hours', self.product_price, 'CNY', 16, 38.40, timestamp_from, timestamp_to), ('a-fake-uuid-1', 'a_fake_name_1', 'm1.large', 'months', 2100.00, 'CNY', 1, 2100.00, timestamp_from, timestamp_to), ], 'floating_ip': [ ('a-fake-uuid-2', '10.211.23.45', 'default', 'days', 1.10, 'CNY', 19, 20.90, timestamp_from, timestamp_to), ('a-fake-uuid-3', '170.1.223.5', 'default', 'days', 1.10, 'CNY', 11, 12.10, timestamp_from, timestamp_to), ], 'network': [ (self.resource_uuid, '192.168.0.2', 'default', 'KBytes', 0.70, 'CNY', 1852, 1296.40, timestamp_from, timestamp_to), ('a-fake-uuid-1', '192.168.0.3', 'default', 'KBytes', 0.70, 'CNY', 9853, 6897.10, timestamp_from, timestamp_to), ], }, } self.mox.StubOutWithMock(db, 'subscription_get_all_by_project') _purchase_func = 'purchase_get_all_by_subscription_and_timeframe' self.mox.StubOutWithMock(db, _purchase_func) db.subscription_get_all_by_project(self.context, self.tenant_id).\ AndReturn(project_subscriptions) db.purchase_get_all_by_subscription_and_timeframe(self.context, self.subscription_id, datetime_from, datetime_to).\ InAnyOrder().AndReturn(purchases1) db.purchase_get_all_by_subscription_and_timeframe(self.context, 60, datetime_from, datetime_to).\ InAnyOrder().AndReturn(purchases2) db.purchase_get_all_by_subscription_and_timeframe(self.context, 61, datetime_from, datetime_to).\ InAnyOrder().AndReturn(purchases3) db.purchase_get_all_by_subscription_and_timeframe(self.context, 62, datetime_from, datetime_to).\ InAnyOrder().AndReturn(purchases4) db.purchase_get_all_by_subscription_and_timeframe(self.context, 63, datetime_from, datetime_to).\ InAnyOrder().AndReturn(purchases5) db.purchase_get_all_by_subscription_and_timeframe(self.context, 64, datetime_from, datetime_to).\ InAnyOrder().AndReturn(purchases6) db.purchase_get_all_by_subscription_and_timeframe(self.context, 65, datetime_from, datetime_to).\ InAnyOrder().AndReturn(purchases7) db.purchase_get_all_by_subscription_and_timeframe(self.context, 66, datetime_from, datetime_to).\ InAnyOrder().AndReturn(purchases8) self.mox.ReplayAll() result = api.query_usage_report(self.context, timestamp_from, timestamp_to) self.mox.VerifyAll() expect_keys = usage_report.keys().sort() actual_keys = result['data'].keys().sort() self.assertEqual(expect_keys, actual_keys) for k, v in result['data'].iteritems(): new_report = dict() for region_name, usage_data in v.iteritems(): new_data = new_report.setdefault(region_name, list()) for a, b, c, d, e, f, g, h, i, j in usage_data: datum = (a, b, c, d, e, f, g, float(Decimal(h).quantize(Decimal('0.01'))), i, j) new_data.append(datum) self.assertEqual(new_report, usage_report[k])
def query_report(context, timestamp_from=None, timestamp_to=None, period=None, item_name=None, resource_name=None, **kwargs): """period='days' or 'hours'""" print "query_report", timestamp_from, timestamp_to, item_name, resource_name if not period in ['days', 'hours', 'months']: return {'data': None} def find_timeframe(start_time, end_time, target): target_utc = target.replace(tzinfo=UTC_TIMEZONE) current_frame = start_time cnt = 1 while current_frame < end_time: foo = {period: cnt} next_frame = start_time + relativedelta(**foo) if current_frame <= target_utc < next_frame: break cnt += 1 current_frame = next_frame assert(current_frame < end_time) return current_frame.isoformat() monthly_report = dict() datetime_from = iso8601.parse_date(timestamp_from) datetime_to = iso8601.parse_date(timestamp_to) subscriptions = list() _subscriptions = list() __subscriptions = db.subscription_get_all_by_project(context, context.project_id) if not __subscriptions: return {'data': None} for subscription in __subscriptions: if subscription['resource_name'] != resource_name: continue elif subscription['product']['item']['name'] != item_name: continue _subscriptions.append(subscription) for subscription in _subscriptions: subscription_id = subscription['id'] resource_uuid = subscription['resource_uuid'] resource_name = subscription['resource_name'] created_at = subscription['created_at'] expires_at = subscription['expires_at'] region_name = subscription['product']['region']['name'] item_name = subscription['product']['item']['name'] item_type_name = subscription['product']['item_type']['name'] order_unit = subscription['product']['order_unit'] order_size = subscription['product']['order_size'] price = subscription['product']['price'] currency = subscription['product']['currency'] subscriptions.append([subscription_id, resource_uuid, resource_name, created_at, expires_at, region_name, item_name, item_type_name, order_unit, order_size, price, currency]) for (subscription_id, resource_uuid, resource_name, created_at, expires_at, region_name, item_name, item_type_name, order_unit, order_size, price, currency) in subscriptions: purchases = db.purchase_get_all_by_subscription_and_timeframe(context, subscription_id, datetime_from, datetime_to) if not purchases: continue i = 0 for purchase in purchases: line_total = purchase['line_total'] quantity = purchase['quantity'] timeframe = find_timeframe(datetime_from, datetime_to, purchase['created_at']) # print timeframe i += 1 usage_datum = (resource_uuid, resource_name, item_type_name, order_unit, order_size, price, currency, quantity, line_total, created_at.isoformat(), expires_at.isoformat()) region_usage = monthly_report.setdefault(region_name, dict()) monthly_usage = region_usage.setdefault(timeframe, dict()) monthly_usage.setdefault(item_name, 0) monthly_usage[item_name] = usage_datum monthly_usage.setdefault("quantity", 0) monthly_usage.setdefault("line_total", 0) monthly_usage["quantity"] += quantity monthly_usage["line_total"] += line_total print "total:", i return {'data': monthly_report}