-
Notifications
You must be signed in to change notification settings - Fork 1
Update dv360 query to deal with advertiser-level query #62
Changes from 4 commits
4b50b34
60cda34
ad617bf
bb94a7d
e6b6056
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,11 +2,12 @@ import 'package:angular/angular.dart'; | |
import 'package:angular_forms/angular_forms.dart'; | ||
|
||
import 'excel.dart'; | ||
import 'insertion_order_parser.dart'; | ||
import 'json_js.dart' as json; | ||
import 'public_api_parser.dart'; | ||
import 'json_js.dart'; | ||
import 'proto/insertion_order_query.pb.dart'; | ||
import 'query_service.dart'; | ||
import 'reporting_query_parser.dart'; | ||
import 'util.dart'; | ||
|
||
@Component( | ||
selector: 'query', | ||
|
@@ -16,31 +17,62 @@ import 'reporting_query_parser.dart'; | |
<input [(ngModel)]="insertionOrderId" | ||
placeholder="Insertion Order ID: 8127549" debugId="io-id-input"> | ||
<br> | ||
|
||
<input type="radio" [(ngModel)]="advertiserQuery" name="advertiser-query"> | ||
<label for="advertiser-query">By advertiser</label><br> | ||
<input type="radio" [(ngModel)]="insertionOrderQuery" name="advertiser-query"> | ||
<label for="advertiser-query">By insertion order</label><br> | ||
|
||
<input type="checkbox" [(ngModel)]="highlightUnderpacing" | ||
debugId="underpacing" name="underpacing"> | ||
<label for="underpacing">Highlight underpacing insertion orders</label><br> | ||
|
||
<button (click)="onClick()" debugId="populate-btn"> | ||
{{buttonName}} | ||
</button> | ||
''', | ||
providers: [ClassProvider(QueryService), ClassProvider(ExcelDart)], | ||
providers: [ | ||
ClassProvider(QueryService), | ||
ClassProvider(ExcelDart), | ||
FORM_PROVIDERS, | ||
], | ||
directives: [coreDirectives, formDirectives], | ||
) | ||
class QueryComponent { | ||
final buttonName = 'populate'; | ||
final QueryService _queryService; | ||
final ExcelDart _excel; | ||
|
||
QueryType _queryType; | ||
|
||
String advertiserId; | ||
String insertionOrderId; | ||
|
||
bool highlightUnderpacing = false; | ||
|
||
// Radio button states with byAdvertiser selected as default. | ||
RadioButtonState advertiserQuery = RadioButtonState(true, 'byAdvertiser'); | ||
RadioButtonState insertionOrderQuery = RadioButtonState(false, 'byIO'); | ||
|
||
QueryComponent(this._queryService, this._excel); | ||
|
||
void onClick() async { | ||
// Determines the query type from radio buttons. | ||
_queryType = advertiserQuery.checked | ||
? QueryType.byAdvertiser | ||
: QueryType.byInsertionOrder; | ||
|
||
// Uses DV360 public APIs to fetch entity data. | ||
final insertionOrder = await _queryAndParseInsertionOrderEntityData(); | ||
var insertionOrders = await _queryAndParseInsertionOrderEntityData(); | ||
|
||
// If [_queryType.byAdvertiser], filters out insertion orders | ||
// that are not in-flight. | ||
insertionOrders = _queryType == QueryType.byAdvertiser | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. opt: if the filtering happened in place you could avoid re-assigning this variable There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Dart doesn't seem to have an in-place filter :( |
||
? _filterInFlightInsertionOrders(insertionOrders) | ||
: insertionOrders; | ||
|
||
// TODO: update reporting query to deal with multiple IOs. | ||
// Issue: https://github.com/googleinterns/dv360-excel-plugin/issues/61 | ||
final insertionOrder = insertionOrders.first; | ||
|
||
// Gets dateRange for the active budget segment. | ||
final activeDateRange = insertionOrder.budget.activeBudgetSegment.dateRange; | ||
|
@@ -52,16 +84,31 @@ class QueryComponent { | |
insertionOrder.spent = revenueMap[insertionOrder.insertionOrderId] ?? ''; | ||
|
||
// Populate the spreadsheet. | ||
await _excel.populate([insertionOrder], highlightUnderpacing); | ||
await _excel.populate(insertionOrders, highlightUnderpacing); | ||
} | ||
|
||
/// Fetches insertion order entity related data using DV360 public APIs, | ||
/// then return a parsed [InsertionOrder] instance. | ||
Future<InsertionOrder> _queryAndParseInsertionOrderEntityData() async { | ||
final response = | ||
await _queryService.execDV3Query(advertiserId, insertionOrderId); | ||
|
||
return InsertionOrderParser.parse(json.stringify(response)); | ||
/// then return a list of parsed [InsertionOrder] instance. | ||
Future<List<InsertionOrder>> _queryAndParseInsertionOrderEntityData() async { | ||
final insertionOrderList = <InsertionOrder>[]; | ||
var jsonResponse = '{}'; | ||
|
||
do { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nice do while loop |
||
// Gets the nextPageToken, and having an empty token | ||
// doesn't affect the query. | ||
final nextPageToken = PublicApiParser.parseNextPageToken(jsonResponse); | ||
|
||
// Executes dv360 query, parses the response and adds results to the list. | ||
final response = await _queryService.execDV3Query( | ||
_queryType, nextPageToken, advertiserId, insertionOrderId); | ||
jsonResponse = JsonJS.stringify(response); | ||
|
||
// Adds all insertion orders in this iteration to the list. | ||
insertionOrderList | ||
.addAll(PublicApiParser.parseInsertionOrders(jsonResponse)); | ||
} while (PublicApiParser.parseNextPageToken(jsonResponse).isNotEmpty); | ||
|
||
return insertionOrderList; | ||
} | ||
|
||
/// Fetches revenue spent data using DBM reporting APIs, | ||
|
@@ -72,25 +119,34 @@ class QueryComponent { | |
final jsonCreateQueryResponse = await _queryService | ||
.execReportingCreateQuery(advertiserId, insertionOrderId, dateRange); | ||
final reportingQueryId = ReportingQueryParser.parseQueryIdFromJsonString( | ||
json.stringify(jsonCreateQueryResponse)); | ||
JsonJS.stringify(jsonCreateQueryResponse)); | ||
|
||
try { | ||
// Uses the queryId to get the report download path. | ||
final jsonGetQueryResponse = | ||
await _queryService.execReportingGetQuery(reportingQueryId); | ||
await _queryService.execReportingGetQuery(reportingQueryId); | ||
final reportingDownloadPath = | ||
ReportingQueryParser.parseDownloadPathFromJsonString( | ||
json.stringify(jsonGetQueryResponse)); | ||
ReportingQueryParser.parseDownloadPathFromJsonString( | ||
JsonJS.stringify(jsonGetQueryResponse)); | ||
|
||
// Downloads the report and parse the response into a revenue map. | ||
final report = | ||
await _queryService.execReportingDownload(reportingDownloadPath); | ||
await _queryService.execReportingDownload(reportingDownloadPath); | ||
|
||
return ReportingQueryParser.parseRevenueFromJsonString(report); | ||
} catch(e) { | ||
} catch (e) { | ||
/// TODO: proper error handling. | ||
/// Issue: https://github.com/googleinterns/dv360-excel-plugin/issues/52. | ||
return <String, String>{}; | ||
} | ||
} | ||
|
||
List<InsertionOrder> _filterInFlightInsertionOrders( | ||
List<InsertionOrder> insertionOrders) { | ||
return insertionOrders | ||
.where((io) => | ||
io.budget.activeBudgetSegment != | ||
InsertionOrder_Budget_BudgetSegment()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this doesnt need to check dates? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the IO is not in-flight, it will have an empty InsertionOrder_Budget_BudgetSegment() for the activeBudgetSegment field. Date checking has already been done during parsing. |
||
.toList(); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like the radio button can only take string values :(
Saw other people complain about this too.