From bcd6195ddca464f03efa26bb6b54bdee222aaa2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0smail=20Kundakc=C4=B1?= Date: Mon, 17 Jun 2024 23:00:27 +0300 Subject: [PATCH 1/3] upgrade packages, bump to netstandard2.1 and upgrade package version --- .../FikaAmazonAPI.SampleCode.csproj | 18 +++++++++--------- Source/FikaAmazonAPI/FikaAmazonAPI.csproj | 18 +++++++++--------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Source/FikaAmazonAPI.SampleCode/FikaAmazonAPI.SampleCode.csproj b/Source/FikaAmazonAPI.SampleCode/FikaAmazonAPI.SampleCode.csproj index 792af85d..b452e77e 100644 --- a/Source/FikaAmazonAPI.SampleCode/FikaAmazonAPI.SampleCode.csproj +++ b/Source/FikaAmazonAPI.SampleCode/FikaAmazonAPI.SampleCode.csproj @@ -19,17 +19,17 @@ - - + + - - - - - + + + + + - - + + diff --git a/Source/FikaAmazonAPI/FikaAmazonAPI.csproj b/Source/FikaAmazonAPI/FikaAmazonAPI.csproj index 6f416698..bd5fece2 100644 --- a/Source/FikaAmazonAPI/FikaAmazonAPI.csproj +++ b/Source/FikaAmazonAPI/FikaAmazonAPI.csproj @@ -7,9 +7,9 @@ CSharp Amazon Sp API true 8.0 - 1.7.19 - 1.7.19 - 1.7.19 + 1.7.20 + 1.7.20 + 1.7.20 true https://github.com/abuzuhri/Amazon-SP-API-CSharp MIT @@ -21,7 +21,7 @@ .Net C# library for the new Amazon Selling Partner API git icon.jpg - netstandard2.0 + netstandard2.1 2ff602c6-a213-4df0-88f2-cf1a1df95fbc @@ -32,13 +32,13 @@ - - + + - - - + + + From a9c3a7ab6f97a4fa4c1a831b2a6b2d005078fdd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0smail=20Kundakc=C4=B1?= Date: Tue, 18 Jun 2024 00:35:16 +0300 Subject: [PATCH 2/3] Update FikaAmazonAPI.csproj --- Source/FikaAmazonAPI/FikaAmazonAPI.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/FikaAmazonAPI/FikaAmazonAPI.csproj b/Source/FikaAmazonAPI/FikaAmazonAPI.csproj index bd5fece2..ac987cd6 100644 --- a/Source/FikaAmazonAPI/FikaAmazonAPI.csproj +++ b/Source/FikaAmazonAPI/FikaAmazonAPI.csproj @@ -21,7 +21,7 @@ .Net C# library for the new Amazon Selling Partner API git icon.jpg - netstandard2.1 + netstandard2.0 2ff602c6-a213-4df0-88f2-cf1a1df95fbc From 00a41f6ce3aec47a5f2467d3a98d9fce8dfcf954 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0smail=20Kundakc=C4=B1?= Date: Tue, 18 Jun 2024 01:09:57 +0300 Subject: [PATCH 3/3] fix some async usings --- .../FikaAmazonAPI.SampleCode/FeedsSample.cs | 2 +- .../ReportGeneration/ReportManager.cs | 200 ++++++++++++++---- .../FikaAmazonAPI/Services/ReportService.cs | 4 +- .../FikaAmazonAPI/Services/RequestService.cs | 83 +++++--- Source/FikaAmazonAPI/Utils/RateLimits.cs | 4 +- 5 files changed, 215 insertions(+), 78 deletions(-) diff --git a/Source/FikaAmazonAPI.SampleCode/FeedsSample.cs b/Source/FikaAmazonAPI.SampleCode/FeedsSample.cs index c4e8e6c7..ce37a18a 100644 --- a/Source/FikaAmazonAPI.SampleCode/FeedsSample.cs +++ b/Source/FikaAmazonAPI.SampleCode/FeedsSample.cs @@ -180,7 +180,7 @@ public void SubmitFeedPRICING(double PRICE, string SKU) } - public async void SubmitFeedPricingWithSalePrice(string sku, decimal price, decimal salePrice, DateTime startDate, DateTime endDate) + public async Task SubmitFeedPricingWithSalePrice(string sku, decimal price, decimal salePrice, DateTime startDate, DateTime endDate) { var currencyCode = amazonConnection.GetCurrentMarketplace.CurrencyCode.ToString(); diff --git a/Source/FikaAmazonAPI/ReportGeneration/ReportManager.cs b/Source/FikaAmazonAPI/ReportGeneration/ReportManager.cs index aad8d64c..5c31bc61 100644 --- a/Source/FikaAmazonAPI/ReportGeneration/ReportManager.cs +++ b/Source/FikaAmazonAPI/ReportGeneration/ReportManager.cs @@ -15,47 +15,60 @@ public class ReportManager private const int DAY_60 = 60; private const int DAY_90 = 90; private AmazonConnection _amazonConnection { get; set; } + public ReportManager(AmazonConnection amazonConnection) { _amazonConnection = amazonConnection; } #region feedback + public List GetFeedbackFromDays(int days) => Task.Run(() => GetFeedbackFromDaysAsync(days)).ConfigureAwait(false).GetAwaiter().GetResult(); + public async Task> GetFeedbackFromDaysAsync(int days) { DateTime fromDate = DateTime.UtcNow.AddDays(-1 * days); DateTime toDate = DateTime.UtcNow; return await GetFeedbackFromDateAsync(fromDate, toDate); } + public async Task> GetFeedbackFromDateAsync(DateTime fromDate, DateTime toDate) { var path = await GetFeedbackFromDateAsync(_amazonConnection, fromDate, toDate); FeedbackOrderReport report = new FeedbackOrderReport(path, _amazonConnection.RefNumber); return report.Data; } - private async Task GetFeedbackFromDateAsync(AmazonConnection amazonConnection, DateTime fromDate, DateTime toDate) + + private async Task GetFeedbackFromDateAsync(AmazonConnection amazonConnection, DateTime fromDate, + DateTime toDate) { - return await amazonConnection.Reports.CreateReportAndDownloadFileAsync(ReportTypes.GET_SELLER_FEEDBACK_DATA, fromDate); + return await amazonConnection.Reports.CreateReportAndDownloadFileAsync(ReportTypes.GET_SELLER_FEEDBACK_DATA, + fromDate); } #endregion #region Performance + #endregion #region Reimbursement + public IList GetReimbursementsOrder(int days) => Task.Run(() => GetReimbursementsOrderAsync(days)).ConfigureAwait(false).GetAwaiter().GetResult(); + public async Task> GetReimbursementsOrderAsync(int days) { DateTime fromDate = DateTime.UtcNow.AddDays(-1 * days); DateTime toDate = DateTime.UtcNow; return await GetReimbursementsOrderAsync(fromDate, toDate); } + public IList GetReimbursementsOrder(DateTime fromDate, DateTime toDate) => - Task.Run(() => GetReimbursementsOrderAsync(fromDate, toDate)).ConfigureAwait(false).GetAwaiter().GetResult(); + Task.Run(() => GetReimbursementsOrderAsync(fromDate, toDate)).ConfigureAwait(false).GetAwaiter() + .GetResult(); + public async Task> GetReimbursementsOrderAsync(DateTime fromDate, DateTime toDate) { var path = await GetReimbursementsOrderAsync(_amazonConnection, fromDate, toDate); @@ -63,51 +76,68 @@ public async Task> GetReimbursementsOrderAsync(Dat return report.Data; } - private async Task GetReimbursementsOrderAsync(AmazonConnection amazonConnection, DateTime fromDate, DateTime toDate) + private async Task GetReimbursementsOrderAsync(AmazonConnection amazonConnection, DateTime fromDate, + DateTime toDate) { - return await amazonConnection.Reports.CreateReportAndDownloadFileAsync(ReportTypes.GET_FBA_REIMBURSEMENTS_DATA, fromDate, toDate); + return await amazonConnection.Reports.CreateReportAndDownloadFileAsync( + ReportTypes.GET_FBA_REIMBURSEMENTS_DATA, fromDate, toDate); } + #endregion #region ReturnFBAOrder + public List GetReturnFBAOrder(int days, List marketplaces = null) => Task.Run(() => GetReturnFBAOrderAsync(days, marketplaces)).ConfigureAwait(false).GetAwaiter().GetResult(); - public async Task> GetReturnFBAOrderAsync(int days, List marketplaces = null, CancellationToken cancellationToken = default) + + public async Task> GetReturnFBAOrderAsync(int days, + List marketplaces = null, CancellationToken cancellationToken = default) { DateTime fromDate = DateTime.UtcNow.AddDays(-1 * days); DateTime toDate = DateTime.UtcNow; return await GetReturnFBAOrderAsync(fromDate, toDate, marketplaces, cancellationToken); } - public List GetReturnFBAOrder(DateTime fromDate, DateTime toDate, List marketplaces = null) => - Task.Run(() => GetReturnFBAOrderAsync(fromDate, toDate, marketplaces)).ConfigureAwait(false).GetAwaiter().GetResult(); - public async Task> GetReturnFBAOrderAsync(DateTime fromDate, DateTime toDate, List marketplaces = null, CancellationToken cancellationToken = default) + public List GetReturnFBAOrder(DateTime fromDate, DateTime toDate, + List marketplaces = null) => + Task.Run(() => GetReturnFBAOrderAsync(fromDate, toDate, marketplaces)).ConfigureAwait(false).GetAwaiter() + .GetResult(); + + public async Task> GetReturnFBAOrderAsync(DateTime fromDate, DateTime toDate, + List marketplaces = null, CancellationToken cancellationToken = default) { - var path = await GetReturnFBAOrderAsync(_amazonConnection, fromDate, toDate, marketplaces, cancellationToken); + var path = await GetReturnFBAOrderAsync(_amazonConnection, fromDate, toDate, marketplaces, + cancellationToken); ReturnFBAOrderReport report = new ReturnFBAOrderReport(path, _amazonConnection.RefNumber); return report.Data; } - private async Task GetReturnFBAOrderAsync(AmazonConnection amazonConnection, DateTime fromDate, DateTime toDate, List marketplaces = null, CancellationToken cancellationToken = default) + private async Task GetReturnFBAOrderAsync(AmazonConnection amazonConnection, DateTime fromDate, + DateTime toDate, List marketplaces = null, CancellationToken cancellationToken = default) { - return await amazonConnection.Reports.CreateReportAndDownloadFileAsync(ReportTypes.GET_FBA_FULFILLMENT_CUSTOMER_RETURNS_DATA, fromDate, toDate, marketplaces: marketplaces, cancellationToken: cancellationToken); + return await amazonConnection.Reports.CreateReportAndDownloadFileAsync( + ReportTypes.GET_FBA_FULFILLMENT_CUSTOMER_RETURNS_DATA, fromDate, toDate, marketplaces: marketplaces, + cancellationToken: cancellationToken); } - #endregion #region ReturnFBMOrder + public List GetReturnMFNOrder(int days) => Task.Run(() => GetReturnMFNOrderAsync(days)).ConfigureAwait(false).GetAwaiter().GetResult(); + public async Task> GetReturnMFNOrderAsync(int days) { DateTime fromDate = DateTime.UtcNow.AddDays(-1 * days); DateTime toDate = DateTime.UtcNow; return await GetReturnMFNOrderAsync(fromDate, toDate); } + public List GetReturnMFNOrder(DateTime fromDate, DateTime toDate) => Task.Run(() => GetReturnMFNOrderAsync(fromDate, toDate)).ConfigureAwait(false).GetAwaiter().GetResult(); + public async Task> GetReturnMFNOrderAsync(DateTime fromDate, DateTime toDate) { List list = new List(); @@ -119,23 +149,31 @@ public async Task> GetReturnMFNOrderAsync(DateTime fromD ReturnFBMOrderReport report = new ReturnFBMOrderReport(path, _amazonConnection.RefNumber); list.AddRange(report.Data); } + return list; } - private async Task GetReturnMFNOrderAsync(AmazonConnection amazonConnection, DateTime fromDate, DateTime toDate) + + private async Task GetReturnMFNOrderAsync(AmazonConnection amazonConnection, DateTime fromDate, + DateTime toDate) { - return await amazonConnection.Reports.CreateReportAndDownloadFileAsync(ReportTypes.GET_FLAT_FILE_RETURNS_DATA_BY_RETURN_DATE, fromDate, toDate); + return await amazonConnection.Reports.CreateReportAndDownloadFileAsync( + ReportTypes.GET_FLAT_FILE_RETURNS_DATA_BY_RETURN_DATE, fromDate, toDate); } + #endregion #region Settlement + public List GetSettlementOrder(int days) => Task.Run(() => GetSettlementOrderAsync(days)).ConfigureAwait(false).GetAwaiter().GetResult(); + public async Task> GetSettlementOrderAsync(int days) { DateTime fromDate = DateTime.UtcNow.AddDays(-1 * days); DateTime toDate = DateTime.UtcNow; return await GetSettlementOrderAsync(fromDate, toDate); } + public async Task> GetSettlementOrderAsync(DateTime fromDate, DateTime toDate) { List list = new List(); @@ -152,67 +190,90 @@ public async Task> GetSettlementOrderAsync(DateTime fro return list; } - private async Task> GetSettlementOrderAsync(AmazonConnection amazonConnection, DateTime fromDate, DateTime toDate) + + private async Task> GetSettlementOrderAsync(AmazonConnection amazonConnection, DateTime fromDate, + DateTime toDate) { - return await amazonConnection.Reports.DownloadExistingReportAndDownloadFileAsync(ReportTypes.GET_V2_SETTLEMENT_REPORT_DATA_FLAT_FILE_V2, fromDate, toDate); + return await amazonConnection.Reports.DownloadExistingReportAndDownloadFileAsync( + ReportTypes.GET_V2_SETTLEMENT_REPORT_DATA_FLAT_FILE_V2, fromDate, toDate); } + #endregion #region GetUnsuppressedInventoryData + public async Task> GetUnsuppressedInventoryDataAsync() { var path = await GetUnsuppressedInventoryDatayAsync(_amazonConnection); var report = new UnsuppressedInventoryDataReport(path, _amazonConnection.RefNumber); return report.Data; } + private async Task GetUnsuppressedInventoryDatayAsync(AmazonConnection amazonConnection) { - return await amazonConnection.Reports.CreateReportAndDownloadFileAsync(ReportTypes.GET_FBA_MYI_UNSUPPRESSED_INVENTORY_DATA); + return await amazonConnection.Reports.CreateReportAndDownloadFileAsync(ReportTypes + .GET_FBA_MYI_UNSUPPRESSED_INVENTORY_DATA); } + #endregion #region GetInventoryQty + public async Task> GetAFNInventoryQtyAsync() { var path = await GetAFNInventoryQtyAsync(_amazonConnection); ProductAFNInventoryReport report = new ProductAFNInventoryReport(path, _amazonConnection.RefNumber); return report.Data; } + private async Task GetAFNInventoryQtyAsync(AmazonConnection amazonConnection) { return await amazonConnection.Reports.CreateReportAndDownloadFileAsync(ReportTypes.GET_AFN_INVENTORY_DATA); } + #endregion #region GetInventoryAging + public List GetInventoryAging() => Task.Run(() => GetInventoryAgingAsync()).ConfigureAwait(false).GetAwaiter().GetResult(); + public async Task> GetInventoryAgingAsync() { var path = await GetInventoryAgingAsync(_amazonConnection); InventoryAgingReport report = new InventoryAgingReport(path, _amazonConnection.RefNumber); return report.Data; } + private async Task GetInventoryAgingAsync(AmazonConnection amazonConnection) { - return await amazonConnection.Reports.CreateReportAndDownloadFileAsync(ReportTypes.GET_FBA_INVENTORY_AGED_DATA); + return await amazonConnection.Reports.CreateReportAndDownloadFileAsync(ReportTypes + .GET_FBA_INVENTORY_AGED_DATA); } + #endregion #region Products + public List GetProducts(List marketplaces = null) => Task.Run(() => GetProductsAsync(marketplaces)).ConfigureAwait(false).GetAwaiter().GetResult(); - public async Task> GetProductsAsync(List marketplaces = null, CancellationToken cancellationToken = default) + + public async Task> GetProductsAsync(List marketplaces = null, + CancellationToken cancellationToken = default) { var path = await GetProductsAsync(_amazonConnection, marketplaces, cancellationToken); ProductsReport report = new ProductsReport(path); return report.Data; } - private async Task GetProductsAsync(AmazonConnection amazonConnection, List marketplaces = null, CancellationToken cancellationToken = default) + + private Task GetProductsAsync(AmazonConnection amazonConnection, List marketplaces = null, + CancellationToken cancellationToken = default) { - return await amazonConnection.Reports.CreateReportAndDownloadFileAsync(ReportTypes.GET_MERCHANT_LISTINGS_ALL_DATA, marketplaces: marketplaces, cancellationToken: cancellationToken); + return amazonConnection.Reports.CreateReportAndDownloadFileAsync(ReportTypes.GET_MERCHANT_LISTINGS_ALL_DATA, + marketplaces: marketplaces, cancellationToken: cancellationToken); } + #endregion #region Categories @@ -233,22 +294,25 @@ private async Task GetCategoriesAsync(AmazonConnection amazonConnection, { return await amazonConnection.Reports.CreateReportAndDownloadFileAsync(ReportTypes.GET_XML_BROWSE_TREE_DATA, reportOptions: new ReportOptions - { - { "RootNodesOnly", rootNodesOnly.ToString() } - }); + { + { "RootNodesOnly", rootNodesOnly.ToString() } + }); } #endregion #region Orders + public List GetOrdersByLastUpdate(int days) => Task.Run(() => GetOrdersByLastUpdateAsync(days)).ConfigureAwait(false).GetAwaiter().GetResult(); + public async Task> GetOrdersByLastUpdateAsync(int days) { DateTime fromDate = DateTime.UtcNow.AddDays(-1 * days); DateTime toDate = DateTime.UtcNow; return await GetOrdersByLastUpdateAsync(fromDate, toDate); } + public async Task> GetOrdersByLastUpdateAsync(DateTime fromDate, DateTime toDate) { List list = new List(); @@ -259,23 +323,30 @@ public async Task> GetOrdersByLastUpdateAsync(DateTime fromDate, OrdersReport report = new OrdersReport(path, _amazonConnection.RefNumber); list.AddRange(report.Data); } + return list; } - private async Task GetOrdersByLastUpdateAsync(AmazonConnection amazonConnection, DateTime fromDate, DateTime toDate) + + private async Task GetOrdersByLastUpdateAsync(AmazonConnection amazonConnection, DateTime fromDate, + DateTime toDate) { - return await amazonConnection.Reports.CreateReportAndDownloadFileAsync(ReportTypes.GET_FLAT_FILE_ALL_ORDERS_DATA_BY_LAST_UPDATE_GENERAL, fromDate, toDate); + return await amazonConnection.Reports.CreateReportAndDownloadFileAsync( + ReportTypes.GET_FLAT_FILE_ALL_ORDERS_DATA_BY_LAST_UPDATE_GENERAL, fromDate, toDate); } public List GetOrdersByOrderDate(int days) => Task.Run(() => GetOrdersByOrderDateAsync(days)).ConfigureAwait(false).GetAwaiter().GetResult(); + public async Task> GetOrdersByOrderDateAsync(int days) { DateTime fromDate = DateTime.UtcNow.AddDays(-1 * days); DateTime toDate = DateTime.UtcNow; return await GetOrdersByOrderDateAsync(fromDate, toDate); } + public List GetOrdersByOrderDate(DateTime fromDate, DateTime toDate) => Task.Run(() => GetOrdersByOrderDateAsync(fromDate, toDate)).ConfigureAwait(false).GetAwaiter().GetResult(); + public async Task> GetOrdersByOrderDateAsync(DateTime fromDate, DateTime toDate) { List list = new List(); @@ -286,45 +357,61 @@ public async Task> GetOrdersByOrderDateAsync(DateTime fromDate, OrdersReport report = new OrdersReport(path, _amazonConnection.RefNumber); list.AddRange(report.Data); } + return list; } - private async Task GetOrdersByOrderDateAsync(AmazonConnection amazonConnection, DateTime fromDate, DateTime toDate) + + private async Task GetOrdersByOrderDateAsync(AmazonConnection amazonConnection, DateTime fromDate, + DateTime toDate) { - return await amazonConnection.Reports.CreateReportAndDownloadFileAsync(ReportTypes.GET_FLAT_FILE_ALL_ORDERS_DATA_BY_ORDER_DATE_GENERAL, fromDate, toDate); + return await amazonConnection.Reports.CreateReportAndDownloadFileAsync( + ReportTypes.GET_FLAT_FILE_ALL_ORDERS_DATA_BY_ORDER_DATE_GENERAL, fromDate, toDate); } - public List GetOrderInvoicingData(DateTime fromDate, DateTime toDate, List marketplaces = null) => - Task.Run(() => GetOrderInvoicingDataAsync(fromDate, toDate, marketplaces)).ConfigureAwait(false).GetAwaiter().GetResult(); - public async Task> GetOrderInvoicingDataAsync(DateTime fromDate, DateTime toDate, List marketplaces = null) + public List GetOrderInvoicingData(DateTime fromDate, DateTime toDate, + List marketplaces = null) => + Task.Run(() => GetOrderInvoicingDataAsync(fromDate, toDate, marketplaces)).ConfigureAwait(false) + .GetAwaiter().GetResult(); + + public async Task> GetOrderInvoicingDataAsync(DateTime fromDate, DateTime toDate, + List marketplaces = null) { List list = new List(); var dateList = ReportDateRange.GetDateRange(fromDate, toDate, DAY_30); foreach (var range in dateList) { - var path = await GetOrderInvoicingDataAsync(_amazonConnection, range.StartDate, range.EndDate, marketplaces); + var path = await GetOrderInvoicingDataAsync(_amazonConnection, range.StartDate, range.EndDate, + marketplaces); OrderInvoicingReport report = new OrderInvoicingReport(path, _amazonConnection.RefNumber); list.AddRange(report.Data); } + return list; } - private async Task GetOrderInvoicingDataAsync(AmazonConnection amazonConnection, DateTime fromDate, DateTime toDate, List marketplaces = null) + private async Task GetOrderInvoicingDataAsync(AmazonConnection amazonConnection, DateTime fromDate, + DateTime toDate, List marketplaces = null) { var options = new AmazonSpApiSDK.Models.Reports.ReportOptions(); options.Add("ShowSalesChannel", "true"); - return await amazonConnection.Reports.CreateReportAndDownloadFileAsync(ReportTypes.GET_FLAT_FILE_ORDER_REPORT_DATA_INVOICING, fromDate, toDate, options, false, marketplaces); + return await amazonConnection.Reports.CreateReportAndDownloadFileAsync( + ReportTypes.GET_FLAT_FILE_ORDER_REPORT_DATA_INVOICING, fromDate, toDate, options, false, marketplaces); } + #endregion #region Settlement + public List GetLedgerDetail(int days) => Task.Run(() => GetLedgerDetailAsync(days)).ConfigureAwait(false).GetAwaiter().GetResult(); + public async Task> GetLedgerDetailAsync(int days) { DateTime fromDate = DateTime.UtcNow.AddDays(-1 * days); DateTime toDate = DateTime.UtcNow; return await GetLedgerDetailAsync(fromDate, toDate); } + public async Task> GetLedgerDetailAsync(DateTime fromDate, DateTime toDate) { List list = new List(); @@ -338,30 +425,41 @@ public async Task> GetLedgerDetailAsync(DateTime fro return list; } - private async Task GetLedgerDetailAsync(AmazonConnection amazonConnection, DateTime fromDate, DateTime toDate) + + private async Task GetLedgerDetailAsync(AmazonConnection amazonConnection, DateTime fromDate, + DateTime toDate) { - return await amazonConnection.Reports.CreateReportAndDownloadFileAsync(ReportTypes.GET_LEDGER_DETAIL_VIEW_DATA, fromDate, toDate); + return await amazonConnection.Reports.CreateReportAndDownloadFileAsync( + ReportTypes.GET_LEDGER_DETAIL_VIEW_DATA, fromDate, toDate); } + #endregion #region InventoryPlanningData + public List GetInventoryPlanningData() => Task.Run(() => GetInventoryPlanningDataAsync()).ConfigureAwait(false).GetAwaiter().GetResult(); + public async Task> GetInventoryPlanningDataAsync() { var path = await GetInventoryPlanningDataAsync(_amazonConnection); InventoryPlanningDataReport report = new InventoryPlanningDataReport(path, _amazonConnection.RefNumber); return report.Data; } + private async Task GetInventoryPlanningDataAsync(AmazonConnection amazonConnection) { - return await amazonConnection.Reports.CreateReportAndDownloadFileAsync(ReportTypes.GET_FBA_INVENTORY_PLANNING_DATA); + return await amazonConnection.Reports.CreateReportAndDownloadFileAsync(ReportTypes + .GET_FBA_INVENTORY_PLANNING_DATA); } + #endregion #region FbaEstimateFee + public List GetFbaEstimateFeeData(DateTime fromDate, DateTime toDate) => Task.Run(() => GetFbaEstimateFeeDataAsync(fromDate, toDate)).ConfigureAwait(false).GetAwaiter().GetResult(); + public async Task> GetFbaEstimateFeeDataAsync(DateTime fromDate, DateTime toDate) { List list = new List(); @@ -372,16 +470,23 @@ public async Task> GetFbaEstimateFeeDataAsync(Date return list; } - private async Task GetFbaEstimateFeeDataAsync(AmazonConnection amazonConnection, DateTime fromDate, DateTime toDate) + + private async Task GetFbaEstimateFeeDataAsync(AmazonConnection amazonConnection, DateTime fromDate, + DateTime toDate) { - return await amazonConnection.Reports.CreateReportAndDownloadFileAsync(ReportTypes.GET_FBA_ESTIMATED_FBA_FEES_TXT_DATA, fromDate, toDate); + return await amazonConnection.Reports.CreateReportAndDownloadFileAsync( + ReportTypes.GET_FBA_ESTIMATED_FBA_FEES_TXT_DATA, fromDate, toDate); } + #endregion #region GetReferralFee + public List GetReferralFeeReportData(DateTime fromDate, DateTime toDate) => - Task.Run(() => GetReferralFeeReportDataAsync(fromDate, toDate)).ConfigureAwait(false).GetAwaiter().GetResult(); + Task.Run(() => GetReferralFeeReportDataAsync(fromDate, toDate)).ConfigureAwait(false).GetAwaiter() + .GetResult(); + public async Task> GetReferralFeeReportDataAsync(DateTime fromDate, DateTime toDate) { List list = new List(); @@ -392,9 +497,13 @@ public async Task> GetReferralFeeReportDataAsync(Date return list; } - private async Task GetReferralFeeReportDataAsync(AmazonConnection amazonConnection, DateTime fromDate, DateTime toDate) + + private async Task GetReferralFeeReportDataAsync(AmazonConnection amazonConnection, DateTime fromDate, + DateTime toDate) { - var reportPath = await amazonConnection.Reports.CreateReportAndDownloadFileAsync(ReportTypes.GET_REFERRAL_FEE_PREVIEW_REPORT, fromDate, toDate); + var reportPath = + await amazonConnection.Reports.CreateReportAndDownloadFileAsync( + ReportTypes.GET_REFERRAL_FEE_PREVIEW_REPORT, fromDate, toDate); if (reportPath == null) { var getOldReports = amazonConnection.Reports.GetReports(new Parameter.Report.ParameterReportList() @@ -407,11 +516,12 @@ private async Task GetReferralFeeReportDataAsync(AmazonConnection amazon { var reportId = getOldReports.FirstOrDefault().ReportId; return await amazonConnection.Reports.GetReportFileByReportIdAsync(reportId, false); - } } + return reportPath; } + #endregion } -} +} \ No newline at end of file diff --git a/Source/FikaAmazonAPI/Services/ReportService.cs b/Source/FikaAmazonAPI/Services/ReportService.cs index d4c3ef5f..0f1fbcc9 100644 --- a/Source/FikaAmazonAPI/Services/ReportService.cs +++ b/Source/FikaAmazonAPI/Services/ReportService.cs @@ -297,7 +297,7 @@ public async Task CreateReportAndDownloadFileAsync(ReportTypes reportTyp parameters.marketplaceIds = new MarketplaceIds(); - if (marketplaces == null || marketplaces.Count() == 0) + if (marketplaces == null || !marketplaces.Any()) { parameters.marketplaceIds.Add(AmazonCredential.MarketPlace.ID); } @@ -324,7 +324,7 @@ public async Task GetReportFileByReportIdAsync(string reportId, bool isR var filePath = string.Empty; string ReportDocumentId = string.Empty; - while (string.IsNullOrEmpty(ReportDocumentId)) + while (string.IsNullOrEmpty(ReportDocumentId) && !cancellationToken.IsCancellationRequested) { var reportData = await GetReportAsync(reportId, cancellationToken); if (!string.IsNullOrEmpty(reportData.ReportDocumentId)) diff --git a/Source/FikaAmazonAPI/Services/RequestService.cs b/Source/FikaAmazonAPI/Services/RequestService.cs index e4cf7b59..71ceeda8 100644 --- a/Source/FikaAmazonAPI/Services/RequestService.cs +++ b/Source/FikaAmazonAPI/Services/RequestService.cs @@ -32,6 +32,7 @@ public class RequestService : ApiUrls protected string AmazonProductionUrl { get; set; } protected string AccessToken { get; set; } protected IList> LastHeaders { get; set; } + protected string ApiBaseUrl { get @@ -77,7 +78,10 @@ private void CreateRequest(string url, RestSharp.Method method) Request = new RestRequest(url, method); } - protected async Task CreateAuthorizedRequestAsync(string url, RestSharp.Method method, List> queryParameters = null, object postJsonObj = null, TokenDataType tokenDataType = TokenDataType.Normal, object parameter = null, CancellationToken cancellationToken = default) + protected async Task CreateAuthorizedRequestAsync(string url, RestSharp.Method method, + List> queryParameters = null, object postJsonObj = null, + TokenDataType tokenDataType = TokenDataType.Normal, object parameter = null, + CancellationToken cancellationToken = default) { var PiiObject = parameter as IParameterBasedPII; if (PiiObject != null && PiiObject.IsNeedRestrictedDataToken) @@ -101,6 +105,7 @@ protected void CreateAuthorizedPagedRequest(AmazonFilter filter, string url, Res CreateRequest(url, method); AddLimitHeader(filter.Limit); } + AddAccessToken(); } @@ -109,7 +114,8 @@ protected void CreateAuthorizedPagedRequest(AmazonFilter filter, string url, Res /// /// Type to parse response to /// Returns data of T type - protected async Task ExecuteRequestTry(RateLimitType rateLimitType = RateLimitType.UNSET, CancellationToken cancellationToken = default) where T : new() + protected async Task ExecuteRequestTry(RateLimitType rateLimitType = RateLimitType.UNSET, + CancellationToken cancellationToken = default) where T : new() { RestHeader(); AddAccessToken(); @@ -123,12 +129,15 @@ protected void CreateAuthorizedPagedRequest(AmazonFilter filter, string url, Res await SleepForRateLimit(response.Headers, rateLimitType, cancellationToken); ParseResponse(response); - if (response.StatusCode == HttpStatusCode.OK && !string.IsNullOrEmpty(response.Content) && response.Data == null) + if (response.StatusCode == HttpStatusCode.OK && !string.IsNullOrEmpty(response.Content) && + response.Data == null) { response.Data = JsonConvert.DeserializeObject(response.Content); } + return response.Data; } + private void SaveLastRequestHeader(IReadOnlyCollection parameters) { LastHeaders = new List>(); @@ -136,7 +145,8 @@ private void SaveLastRequestHeader(IReadOnlyCollection(parameter.Name.ToString(), parameter.Value.ToString())); + LastHeaders.Add(new KeyValuePair(parameter.Name.ToString(), + parameter.Value.ToString())); } } } @@ -171,10 +181,11 @@ private void LogRequest(RestRequest request, RestResponse response) }; Console.WriteLine("\n\n"); Console.WriteLine(string.Format("Request completed, \nRequest: {0} \n\nResponse: {1}", - JsonConvert.SerializeObject(requestToLog), - JsonConvert.SerializeObject(responseToLog))); + JsonConvert.SerializeObject(requestToLog), + JsonConvert.SerializeObject(responseToLog))); } } + private void RestHeader() { lock (Request) @@ -184,7 +195,6 @@ private void RestHeader() Request?.Parameters?.RemoveParameter(AccessTokenHeaderName); Request?.Parameters?.RemoveParameter(SecurityTokenHeaderName); Request?.Parameters?.RemoveParameter(ShippingBusinessIdHeaderName); - } } @@ -193,7 +203,8 @@ private void RestHeader() // return this.ExecuteRequestAsync(rateLimitType)).ConfigureAwait(false).GetAwaiter().GetResult(); //} - public async Task ExecuteRequestAsync(RateLimitType rateLimitType = RateLimitType.UNSET, CancellationToken cancellationToken = default) where T : new() + public async Task ExecuteRequestAsync(RateLimitType rateLimitType = RateLimitType.UNSET, + CancellationToken cancellationToken = default) where T : new() { var tryCount = 0; while (true) @@ -220,12 +231,13 @@ private void RestHeader() } } - private async Task SleepForRateLimit(IReadOnlyCollection headers, RateLimitType rateLimitType = RateLimitType.UNSET, CancellationToken cancellationToken = default) + private async Task SleepForRateLimit(IReadOnlyCollection headers, + RateLimitType rateLimitType = RateLimitType.UNSET, CancellationToken cancellationToken = default) { try { decimal rate = 0; - var limitHeader = headers.Where(a => a.Name == RateLimitLimitHeaderName).FirstOrDefault(); + var limitHeader = headers.FirstOrDefault(a => a.Name == RateLimitLimitHeaderName); if (limitHeader != null) { var RateLimitValue = limitHeader.Value.ToString(); @@ -248,19 +260,20 @@ private async Task SleepForRateLimit(IReadOnlyCollection he { AmazonCredential.UsagePlansTimings[rateLimitType].SetRateLimit(rate); } - var time = AmazonCredential.UsagePlansTimings[rateLimitType].NextRate(rateLimitType); + + await AmazonCredential.UsagePlansTimings[rateLimitType].NextRate(rateLimitType); } } } catch (Exception e) { - } } protected void ParseResponse(RestResponse response) { - if (response.StatusCode == HttpStatusCode.OK || response.StatusCode == HttpStatusCode.Accepted || response.StatusCode == HttpStatusCode.Created || response.StatusCode == HttpStatusCode.NoContent) + if (response.StatusCode == HttpStatusCode.OK || response.StatusCode == HttpStatusCode.Accepted || + response.StatusCode == HttpStatusCode.Created || response.StatusCode == HttpStatusCode.NoContent) return; else if (response.StatusCode == HttpStatusCode.NotFound) { @@ -269,7 +282,8 @@ protected void ParseResponse(RestResponse response) else { if (AmazonCredential.IsDebugMode) - Console.WriteLine("Amazon Api didn't respond with Okay, see exception for more details" + response.Content); + Console.WriteLine("Amazon Api didn't respond with Okay, see exception for more details" + + response.Content); var errorResponse = response.Content.ConvertToErrorResponse(); if (errorResponse != null) @@ -289,13 +303,14 @@ protected void ParseResponse(RestResponse response) case "InternalFailure": throw new AmazonInternalErrorException(error.Message, response); } - } } if (response.StatusCode == HttpStatusCode.BadRequest) { - throw new AmazonBadRequestException("BadRequest see https://developer-docs.amazon.com/sp-api/changelog/api-request-validation-for-400-errors-with-html-response for advice", response); + throw new AmazonBadRequestException( + "BadRequest see https://developer-docs.amazon.com/sp-api/changelog/api-request-validation-for-400-errors-with-html-response for advice", + response); } throw new AmazonException("Amazon Api didn't respond with Okay, see exception for more details", response); @@ -311,11 +326,13 @@ protected void AddLimitHeader(int limit) { Request.AddQueryParameter("limit", limit.ToString()); } + protected void AddJsonBody(object jsonData) { var json = JsonConvert.SerializeObject(jsonData); Request.AddJsonBody(json); } + protected void AddAccessToken() { lock (Request) @@ -327,17 +344,19 @@ protected void AddAccessToken() protected void AddShippingBusinessId() { if (AmazonCredential.ShippingBusiness.HasValue) - Request.AddOrUpdateHeader(ShippingBusinessIdHeaderName, AmazonCredential.ShippingBusiness.Value.GetEnumMemberValue()); + Request.AddOrUpdateHeader(ShippingBusinessIdHeaderName, + AmazonCredential.ShippingBusiness.Value.GetEnumMemberValue()); } - protected async void RefreshToken(TokenDataType tokenDataType = TokenDataType.Normal, CreateRestrictedDataTokenRequest requestPII = null) + protected async Task RefreshToken(TokenDataType tokenDataType = TokenDataType.Normal, + CreateRestrictedDataTokenRequest requestPII = null) { var token = AmazonCredential.GetToken(tokenDataType); if (token == null) { if (tokenDataType == TokenDataType.PII) { - var pii = CreateRestrictedDataToken(requestPII); + var pii = await CreateRestrictedDataTokenAsync(requestPII); if (pii != null) { token = new TokenResponse() @@ -363,7 +382,8 @@ protected async void RefreshToken(TokenDataType tokenDataType = TokenDataType.No AccessToken = token.access_token; } - protected async Task RefreshTokenAsync(TokenDataType tokenDataType = TokenDataType.Normal, CreateRestrictedDataTokenRequest requestPII = null, CancellationToken cancellationToken = default) + protected async Task RefreshTokenAsync(TokenDataType tokenDataType = TokenDataType.Normal, + CreateRestrictedDataTokenRequest requestPII = null, CancellationToken cancellationToken = default) { var token = AmazonCredential.GetToken(tokenDataType); if (token == null) @@ -386,7 +406,8 @@ protected async Task RefreshTokenAsync(TokenDataType tokenDataType = TokenDataTy } else { - token = await TokenGeneration.RefreshAccessTokenAsync(AmazonCredential, tokenDataType, cancellationToken); + token = await TokenGeneration.RefreshAccessTokenAsync(AmazonCredential, tokenDataType, + cancellationToken); } AmazonCredential.SetToken(tokenDataType, token); @@ -395,19 +416,25 @@ protected async Task RefreshTokenAsync(TokenDataType tokenDataType = TokenDataTy AccessToken = token.access_token; } + public IList> LastResponseHeader => LastHeaders; - public CreateRestrictedDataTokenResponse CreateRestrictedDataToken(CreateRestrictedDataTokenRequest createRestrictedDataTokenRequest) + public CreateRestrictedDataTokenResponse CreateRestrictedDataToken( + CreateRestrictedDataTokenRequest createRestrictedDataTokenRequest) { - return Task.Run(() => CreateRestrictedDataTokenAsync(createRestrictedDataTokenRequest)).ConfigureAwait(false).GetAwaiter().GetResult(); + return Task.Run(() => CreateRestrictedDataTokenAsync(createRestrictedDataTokenRequest)) + .ConfigureAwait(false).GetAwaiter().GetResult(); } - public async Task CreateRestrictedDataTokenAsync(CreateRestrictedDataTokenRequest createRestrictedDataTokenRequest, CancellationToken cancellationToken = default) + public async Task CreateRestrictedDataTokenAsync( + CreateRestrictedDataTokenRequest createRestrictedDataTokenRequest, + CancellationToken cancellationToken = default) { - await CreateAuthorizedRequestAsync(TokenApiUrls.RestrictedDataToken, RestSharp.Method.Post, postJsonObj: createRestrictedDataTokenRequest, cancellationToken: cancellationToken); - var response = await ExecuteRequestAsync(RateLimitType.Token_CreateRestrictedDataToken, cancellationToken: cancellationToken); + await CreateAuthorizedRequestAsync(TokenApiUrls.RestrictedDataToken, RestSharp.Method.Post, + postJsonObj: createRestrictedDataTokenRequest, cancellationToken: cancellationToken); + var response = await ExecuteRequestAsync( + RateLimitType.Token_CreateRestrictedDataToken, cancellationToken: cancellationToken); return response; } } - -} +} \ No newline at end of file diff --git a/Source/FikaAmazonAPI/Utils/RateLimits.cs b/Source/FikaAmazonAPI/Utils/RateLimits.cs index de20624f..e28fa847 100644 --- a/Source/FikaAmazonAPI/Utils/RateLimits.cs +++ b/Source/FikaAmazonAPI/Utils/RateLimits.cs @@ -18,7 +18,7 @@ internal RateLimits(decimal Rate, int Burst) this.RequestsSent = 0; } private int GetRatePeriodMs() { return (int)(((1 / Rate) * 1000) / 1); } - public RateLimits NextRate(RateLimitType rateLimitType) + public async Task NextRate(RateLimitType rateLimitType) { if (RequestsSent < 0) RequestsSent = 0; @@ -61,7 +61,7 @@ public RateLimits NextRate(RateLimitType rateLimitType) LastRequest = LastRequest.AddMilliseconds(ratePeriodMs); var TempLastRequest = LastRequest; while (TempLastRequest >= DateTime.UtcNow) //.AddMilliseconds(-100) - Task.Delay(100).Wait(); + await Task.Delay(100); }