/// <summary> /// Gets the quota usage for client accounts. /// </summary> /// <param name="user">The AdWordsUser object for which the quota usage /// should be retrieved.</param> /// <param name="startDate">Start date for the date range for which /// results are to be retrieved.</param> /// <param name="endDate">End date for the date range for which results are /// to be retrieved.</param> /// <returns>A ClientQuotaUsage object that stores the API usage breakup. /// </returns> public static ClientQuotaUsage GetClientQuotaUsage(AdWordsUser user, DateTime startDate, DateTime endDate) { ClientQuotaUsage retVal = new ClientQuotaUsage(); AccountService accountService = (AccountService) user.GetService(AdWordsService.v13.AccountService); AdWordsAccount rootUser = new AdWordsAccount(); rootUser.Email = accountService.emailValue.Value[0]; rootUser.IsManager = true; Hashtable allUsers = new Hashtable(StringComparer.InvariantCultureIgnoreCase); BuildUserGraph(accountService, rootUser, allUsers); InfoService infoService = (InfoService) user.GetService(AdWordsService.v201109.InfoService); FetchUnitUsages(infoService, rootUser, startDate, endDate); foreach (string email in allUsers.Keys) { retVal.UsageMap[email] = GetUnits((AdWordsAccount)allUsers[email], allUsers); } InfoSelector selector = new InfoSelector(); selector.apiUsageTypeSpecified = true; selector.apiUsageType = ApiUsageType.UNIT_COUNT; selector.dateRange = new DateRange(); selector.dateRange.min = startDate.ToString("YYYYMMDD"); selector.dateRange.max = endDate.ToString("YYYYMMDD"); retVal.TotalUnits = infoService.get(selector).cost; retVal.DiffUnits = retVal.TotalUnits - retVal.UsageMap[rootUser.Email]; return retVal; }
/// <summary> /// Recursively walks the account graph hierarchy and fetches the unit /// usages for each account. /// </summary> /// <param name="infoService">InfoService instance to be used while making /// calls.</param> /// <param name="account">The account to be traversed recursively.</param> /// <param name="startDate">Start date for fetching API usage.</param> /// <param name="endDate">End date for fetching API usage.</param> private static void FetchUnitUsages(InfoService infoService, AdWordsAccount account, DateTime startDate, DateTime endDate) { string oldClientEmail = infoService.RequestHeader.clientEmail; startDate = new DateTime(2009, 1, 1); infoService.RequestHeader.clientEmail = account.Email; InfoSelector selector = new InfoSelector(); selector.apiUsageTypeSpecified = true; selector.apiUsageType = ApiUsageType.UNIT_COUNT_FOR_CLIENTS; selector.dateRange = new DateRange(); selector.dateRange.min = startDate.ToString("yyyyMMdd"); selector.dateRange.max = endDate.ToString("yyyyMMdd"); ApiUsageInfo usageInfo = infoService.get(selector); foreach (AdWordsAccount child in account.Children) { if (usageInfo.apiUsageRecords != null) { foreach (ApiUsageRecord usageRecord in usageInfo.apiUsageRecords) { if (child.Email == usageRecord.clientEmail) { child.Units = usageRecord.cost; break; } } } if (child.IsManager) { FetchUnitUsages(infoService, child, startDate, endDate); } } infoService.RequestHeader.clientEmail = oldClientEmail; }
/// <summary> /// Rolls up the API unit usage of an account hierarchy to a /// particular account. /// </summary> /// <param name="account">The account to which the rollup should be done. /// </param> /// <returns>The rolled up API units.</returns> private static long RollupUnits(AdWordsAccount account) { long retVal = 0; if (account.Visited == false) { retVal = account.Units; if (account.IsManager == true) { foreach (AdWordsAccount child in account.Children) { retVal += RollupUnits(child); } } account.Visited = true; } return retVal; }
/// <summary> /// Builds a graph of user accounts, and returns the account root. /// </summary> /// <param name="accountService">An instance of AccountService to be /// used by this method.</param> /// <param name="account">The account to be traversed.</param> /// <param name="allUsers">A table of all accounts traversed so far. /// </param> /// <returns>The root account, with parent and children lists populated /// as per account account hierarchy.</returns> private static AdWordsAccount BuildUserGraph(AccountService accountService, AdWordsAccount account, Hashtable allUsers) { clientEmail oldClientEmail = accountService.clientEmailValue; accountService.clientEmailValue = new clientEmail(); accountService.clientEmailValue.Value = new string[] {account.Email}; if (allUsers.ContainsKey(account.Email) == false) { allUsers.Add(account.Email, account); } ClientAccountInfo[] clients = accountService.getClientAccountInfos(); if (clients != null) { Array.Sort<ClientAccountInfo>(clients, delegate(ClientAccountInfo x, ClientAccountInfo y) { if (x.isCustomerManager == y.isCustomerManager) { return 0; } return (x.isCustomerManager == false && y.isCustomerManager == true) ? 1 : -1; }); foreach (ClientAccountInfo client in clients) { AdWordsAccount child = null; if (allUsers.ContainsKey(client.emailAddress) == true) { child = (AdWordsAccount) allUsers[client.emailAddress]; } else { child = new AdWordsAccount(); child.Email = client.emailAddress; child.IsManager = client.isCustomerManager; } child.Parents.Add(account); account.Children.Add(child); BuildUserGraph(accountService, child, allUsers); } } accountService.clientEmailValue = oldClientEmail; return account; }
/// <summary> /// Gets the API units for an account. /// </summary> /// <param name="account">The account whose units to retrieve units for.</param> /// <param name="allUsers">The list of all user accounts visited so far.</param> /// <returns>The number of API units for an account.</returns> private static long GetUnits(AdWordsAccount account, Hashtable allUsers) { foreach (AdWordsAccount user in allUsers.Values) { user.Visited = false; } return RollupUnits(account); }