Skip to content

Commit

Permalink
lite-29028 Change retrieve billing request logic
Browse files Browse the repository at this point in the history
  • Loading branch information
bdjilka committed Nov 15, 2023
1 parent f79f8e0 commit 965097b
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 286 deletions.
117 changes: 48 additions & 69 deletions connect_transformations/lookup_billing_request/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#
from typing import Dict

from connect.client import AsyncConnectClient, ClientError
from connect.client import AsyncConnectClient
from connect.eaas.core.decorators import router, transformation
from connect.eaas.core.inject.asynchronous import get_installation_client
from connect.eaas.core.responses import RowTransformationResponse
Expand Down Expand Up @@ -52,7 +52,7 @@ async def lookup_billing_request(
self.billing_settings['asset_column']
]

lookup['asset.params.name'] = self.billing_settings['parameter']['name']
lookup['asset.params.id'] = self.billing_settings['parameter']['name']
lookup['asset.params.value'] = value

try:
Expand All @@ -69,9 +69,7 @@ async def lookup_billing_request(

async def extract_row_from_billing(self, request, output_columns, item_id):
row = {}

item_attrs = []
asset = None

for col_name, col_config in output_columns.items():
value = None
Expand All @@ -83,8 +81,6 @@ async def extract_row_from_billing(self, request, output_columns, item_id):
value = param_data['value']
break
elif attr.startswith('items.'):
if attr == 'items.old_quantity':
asset = await self.get_asset(request)
item_attr = attr.split('.')[-1]
item_attrs.append((col_name, item_attr))
value = ''
Expand All @@ -94,26 +90,19 @@ async def extract_row_from_billing(self, request, output_columns, item_id):
row[col_name] = value

if item_attrs:
self.extract_item_attrs_from_billing(item_attrs, row, request, item_id, asset)
self.extract_items_from_billing(item_attrs, row, request, item_id)

return row

def extract_item_attrs_from_billing( # noqa: CCR001
self,
item_attrs,
row,
request,
item_id_value,
asset,
):
def extract_items_from_billing(self, item_attrs, row, request, item_id_value): # noqa: CCR001
item_id = self.billing_settings['item']['id']
for item in request['items']:
if item_id == 'all' or item.get(item_id) == item_id_value:
for col_name, item_attr in item_attrs:
if item_attr == 'old_quantity' and asset:
items = [x for x in asset.get('items') if x['id'] == item['id']]
asset_item = items[0] if item else {}
item_value = str(asset_item.get(item_attr, ''))
if item_attr == 'old_quantity':
items = [x for x in request['asset']['items'] if x['id'] == item['id']]
old_item = items[0] if item else {}
item_value = str(old_item.get(item_attr, ''))
else:
item_value = str(item.get(item_attr, ''))
row[col_name] += f'{SEPARATOR}{item_value}' if row[col_name] else item_value
Expand All @@ -136,61 +125,51 @@ async def retrieve_billing_requests(self, lookup):
batch_context = self.transformation_request['batch']['context']
period_end = batch_context.get('period', {}).get('end')
additional_filters = {}
additional_ff_filters = {}
if period_end:
additional_filters['events.created.at__lt'] = period_end
additional_ff_filters['updated__lt'] = period_end

requests = self.installation_client('subscriptions').requests.filter(
# get latest approved FF request for given lookup
ff_req = await self.installation_client.requests.filter(
status='approved',
**lookup,
**additional_ff_filters,
).select(
'-activation_key',
'-template',
).order_by('-updated').first()
if not ff_req:
if self.billing_settings.get('action_if_not_found') == 'fail':
raise BillingRequestLookupError(f'No result found for the filter {lookup}')
return

# get first billing request after FF request
additional_filters['events.created.at__gt'] = ff_req['updated']
billing_request = await self.installation_client('subscriptions').requests.filter(
**lookup,
**additional_filters,
).order_by('-events.created.at')
requests = [r async for r in requests]

result = None

for item in requests:
if result is None:
result = item
elif self.billing_settings.get('action_if_multiple') == 'leave_empty':
return
elif self.billing_settings.get('action_if_multiple') == 'use_most_actual':
return result
else:
raise BillingRequestLookupError(f'Many results found for the filter {lookup}')

if result:
return result

if self.billing_settings.get('action_if_not_found') == 'fail':
raise BillingRequestLookupError(f'No result found for the filter {lookup}')

async def get_asset(self, billing_request):
k = 'billing-asset-'
k += f'{billing_request["asset"]["id"]}-{billing_request["events"]["created"]["at"]}'
try:
return self.cache_get(k)
except KeyError:
pass

result = await self.retrieve_asset_from_ff(billing_request)

await self.acache_put(k, result)
return result

async def retrieve_asset_from_ff(self, billing_request):
try:
request = await self.installation_client.requests.filter(
asset__id=billing_request['asset']['id'],
status='approved',
updated__lt=billing_request['events']['created']['at'],
).select(
'-activation_key',
'-template',
).order_by('-updated').first()
except ClientError:
return None

if request:
return request['asset']
).order_by('events.created.at').first()
if not billing_request:
if self.billing_settings.get('action_if_not_found') == 'fail':
raise BillingRequestLookupError(f'No result found for the filter {lookup}')
return

# check that there are no approved request between
additional_ff_filters['updated__gt'] = ff_req['updated']
additional_ff_filters['updated__lt'] = billing_request['events']['created']['at']
ff_req_count = await self.installation_client.requests.filter(
status='approved',
**additional_ff_filters,
).count()
if ff_req_count > 1:
if self.billing_settings.get('action_if_not_found') == 'fail':
raise BillingRequestLookupError(f'No result found for the filter {lookup}')
return

billing_request['asset']['params'] = ff_req['asset']['params']
billing_request['asset']['items'] = ff_req['asset']['items']
return billing_request

@property
def billing_settings(self):
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<!doctype html><html><head><meta charset="utf-8"/><title>Transformations/Lookup Billing request</title><script defer="defer" src="../vendors.b7829ba6a3fa12b6e5cb.js"></script><script defer="defer" src="../transformations/lookup_billing_request.d3b38672aba0c9d35b0c.js"></script><link href="../transformations/lookup_billing_request.421df6826da3f2351526.css" rel="stylesheet"></head><body><div id="loader"></div><div id="app"><div class="main-container lookup" id="content"><div class="subtitle">Supported search by parameter and optional search by Subscription ID or Subscription External ID. Result contains only one item information, matching selected criteria.</div><div class="input-group"><p>Choose search by Subscription ID</p><label class="label" for="criteria">Subscription ID type</label> <select class="input" id="criteria"></select></div><div class="input-group" id="subscription_column"><label class="label" for="column">Input Column</label> <select class="input" id="column"></select></div><div class="input-group"><p>Choose search by parameter</p><label class="label" for="parameter">Parameter name</label> <select class="input" id="parameter"></select></div><div><label class="label" for="parameter_column">Input Column</label> <select class="input" id="parameter_column"></select></div><div class="input-group"><p>Choose Item match criteria</p><label class="label" for="item">Item ID type</label> <select class="input" id="item"></select></div><div id="item_column_group"><label class="label" for="item_column">Input Column</label> <select class="input" id="item_column"></select></div><div class="input-group"><p class="radio-buttons label">Choose what to do if match is not found:</p><div class="radio-buttons input"><input type="radio" id="not_found_leave_empty" name="if_not_found" value="leave_empty"/> <label for="not_found_leave_empty">Leave empty</label> <input type="radio" id="not_found_fail" name="if_not_found" value="fail"/> <label for="not_found_fail">Fail</label></div></div><div class="input-group"><p class="radio-buttons label">Choose what to do if multiple matches are found:</p><div class="radio-buttons input"><input type="radio" id="multiple_use_most_actual" name="if_multiple" value="use_most_actual"/> <label for="multiple_use_most_actual">Use the most recent</label> <input type="radio" id="multiple_leave_empty" name="if_multiple" value="leave_empty"/> <label for="multiple_leave_empty">Leave empty</label> <input type="radio" id="multiple_fail" name="if_multiple" value="fail"/> <label for="multiple_fail">Fail</label></div></div><div class="output"><label>Output columns:</label><div id="output-columns"></div><div class="button-container"><button id="add" class="button">ADD</button></div></div></div></div></body></html>
<!doctype html><html><head><meta charset="utf-8"/><title>Transformations/Lookup Billing request</title><script defer="defer" src="../vendors.b7829ba6a3fa12b6e5cb.js"></script><script defer="defer" src="../transformations/lookup_billing_request.d3b38672aba0c9d35b0c.js"></script><link href="../transformations/lookup_billing_request.421df6826da3f2351526.css" rel="stylesheet"></head><body><div id="loader"></div><div id="app"><div class="main-container lookup" id="content"><div class="subtitle">Supported search by parameter and optional search by Subscription ID or Subscription External ID. Result contains only one item information, matching selected criteria.</div><div class="input-group"><p>Choose search by Subscription ID</p><label class="label" for="criteria">Subscription ID type</label> <select class="input" id="criteria"></select></div><div class="input-group" id="subscription_column"><label class="label" for="column">Input Column</label> <select class="input" id="column"></select></div><div class="input-group"><p>Choose search by parameter</p><label class="label" for="parameter">Parameter name</label> <select class="input" id="parameter"></select></div><div><label class="label" for="parameter_column">Input Column</label> <select class="input" id="parameter_column"></select></div><div class="input-group"><p>Choose Item match criteria</p><label class="label" for="item">Item ID type</label> <select class="input" id="item"></select></div><div id="item_column_group"><label class="label" for="item_column">Input Column</label> <select class="input" id="item_column"></select></div><div class="input-group"><p class="radio-buttons label">Choose what to do if match is not found:</p><div class="radio-buttons input"><input type="radio" id="not_found_leave_empty" name="if_not_found" value="leave_empty"/> <label for="not_found_leave_empty">Leave empty</label> <input type="radio" id="not_found_fail" name="if_not_found" value="fail"/> <label for="not_found_fail">Fail</label></div></div><div class="input-group" hidden="hidden"><p class="radio-buttons label">Choose what to do if multiple matches are found:</p><div class="radio-buttons input"><input type="radio" id="multiple_use_most_actual" name="if_multiple" value="use_most_actual"/> <label for="multiple_use_most_actual">Use the most recent</label> <input type="radio" id="multiple_leave_empty" name="if_multiple" value="leave_empty"/> <label for="multiple_leave_empty">Leave empty</label> <input type="radio" id="multiple_fail" name="if_multiple" value="fail"/> <label for="multiple_fail">Fail</label></div></div><div class="output"><label>Output columns:</label><div id="output-columns"></div><div class="button-container"><button id="add" class="button">ADD</button></div></div></div></div></body></html>
Loading

0 comments on commit 965097b

Please sign in to comment.