Migration from Amazon MWS to Selling Partner API

This commit is contained in:
Bobbie Hodgetts
2024-04-11 12:26:13 +01:00
committed by GitHub
parent e054278cdd
commit a7bc00e73a
1318 changed files with 2778105 additions and 5936 deletions

View File

@@ -8,23 +8,94 @@ namespace bnhtrade.Core.Logic.Sku
{
public class GetSkuConditionInfo
{
private string sqlConnectionString;
private Data.Database.Sku.ReadSkuConditionInfo dbRead;
public GetSkuConditionInfo(string sqlConnectionString)
public GetSkuConditionInfo()
{
this.sqlConnectionString = sqlConnectionString;
dbRead = new Data.Database.Sku.ReadSkuConditionInfo(sqlConnectionString);
Init();
}
public void Init()
{
dbRead = new Data.Database.Sku.ReadSkuConditionInfo();
}
public List<Model.Sku.SkuConditionInfo> GetAll()
{
return dbRead.Read(new List<int>());
return dbRead.ByConditionCode(null);
}
public List<Model.Sku.SkuConditionInfo> GetByConditionId(List<int> conditionIdList)
public Model.Sku.SkuConditionInfo GetByConditionCode(string conditionCode)
{
return dbRead.Read(conditionIdList);
var temp = dbRead.ByConditionCode(new List<string> { conditionCode });
if (temp.Any())
{
return temp[0];
}
else
{
return null;
}
}
public List<Model.Sku.SkuConditionInfo> GetByConditionCode(List<string> conditionCodeList)
{
return dbRead.ByConditionCode(conditionCodeList);
}
public Dictionary<string, Model.Sku.SkuConditionInfo> GetBySkuNumber(List<string> skuNumberList)
{
var returnDictionary = new Dictionary<string, Model.Sku.SkuConditionInfo>();
if (skuNumberList == null || !skuNumberList.Any())
{
return returnDictionary;
}
var skuDictionary = dbRead.ReadSkuConditionCode(skuNumberList);
var conditionInfoList = dbRead.ByConditionCode(skuDictionary.Values.ToList());
// build return dictionary
foreach (var skuNumber in skuDictionary)
{
foreach (var conditionInfo in conditionInfoList)
{
if (conditionInfo.SkuConditionCode == skuNumber.Value)
{
returnDictionary.Add(skuNumber.Key, conditionInfo);
break;
}
}
}
return returnDictionary;
}
public bool AddToSkuInfo(List<Model.Sku.Sku> skuList)
{
bool missionSuccess = true;
if (skuList == null || !skuList.Any())
{
return true;
}
// get list of sku numbers to condition codes
var lookupDictionary = GetBySkuNumber(skuList.Select(x => x.SkuNumber).ToList());
for (int i = 0; i < skuList.Count; i++)
{
if (lookupDictionary.ContainsKey(skuList[i].SkuNumber))
{
skuList[i].ConditionInfo = lookupDictionary[skuList[i].SkuNumber];
}
else
{
missionSuccess = false;
}
}
return missionSuccess;
}
}
}
}

View File

@@ -0,0 +1,163 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace bnhtrade.Core.Logic.Sku
{
public class GetSkuInfo
{
private string sqlConnectionString;
private Data.Database.Sku.ReadSku dbSkuInfo;
private Logic.Product.GetProductInfo getProductInfo;
private Logic.Sku.GetSkuConditionInfo getConditionInfo;
private Logic.Account.GetTaxCodeInfo getTaxCodeInfo;
public GetSkuInfo(string sqlConnection)
{
this.sqlConnectionString = sqlConnection;
Init();
}
public bool IncludeProductInfo
{
get
{
return getProductInfo != null;
}
set
{
if (value == true)
{
getProductInfo = new Product.GetProductInfo();
}
else
{
getProductInfo = null;
}
}
}
public bool IncludeConditionInfo
{
get
{
return getConditionInfo != null;
}
set
{
if (value == true)
{
getConditionInfo = new Sku.GetSkuConditionInfo();
}
else
{
getConditionInfo = null;
}
}
}
public bool IncludeTaxCodeInfo
{
get
{
return getTaxCodeInfo != null;
}
set
{
if (value == true)
{
getTaxCodeInfo = new Account.GetTaxCodeInfo();
}
else
{
getTaxCodeInfo = null;
}
}
}
protected void Init()
{
dbSkuInfo = new Data.Database.Sku.ReadSku();
if (IncludeProductInfo) { getProductInfo.Init(); }
if (IncludeConditionInfo) { getConditionInfo = new Sku.GetSkuConditionInfo(); }
if (IncludeTaxCodeInfo) { getTaxCodeInfo = new Account.GetTaxCodeInfo(); }
}
public Model.Sku.Sku BySkuNumber(string skuNumber)
{
var skuList = BySkuNumber(new List<string> { skuNumber });
if (skuList.Any())
{
return skuList[0];
}
else
{
return null;
}
}
public List<Model.Sku.Sku> BySkuNumber(List<string> skuNumberList)
{
var returnList = new List<Model.Sku.Sku>();
if (skuNumberList == null || !skuNumberList.Any())
{
return returnList;
}
returnList = dbSkuInfo.BySkuNumber(skuNumberList);
// add pproductInfo
if (IncludeProductInfo)
{
var ack = getProductInfo.AddToSkuInfo(returnList);
if (ack == false)
{
throw new Exception("Unable to load all product info for sku info object");
}
}
// add condition info
if (IncludeConditionInfo)
{
var ack = getConditionInfo.AddToSkuInfo(returnList);
if (ack == false)
{
throw new Exception("Unable to load all condition info for sku info object");
}
}
// add condition info
if (IncludeTaxCodeInfo)
{
var ack = getTaxCodeInfo.AddToSkuInfo(returnList);
if (ack == false)
{
throw new Exception("Unable to load all tax info for sku info object");
}
}
return returnList;
}
public Dictionary<string, Model.Sku.Sku> ConvertToDictionary(List<Model.Sku.Sku> skuInfoList)
{
var returnList = new Dictionary<string, Model.Sku.Sku>();
foreach (var skuInfo in skuInfoList)
{
if (!returnList.ContainsKey(skuInfo.SkuNumber))
{
returnList.Add(skuInfo.SkuNumber, skuInfo);
}
}
return returnList;
}
}
}

View File

@@ -17,9 +17,8 @@ namespace bnhtrade.Core.Logic.Sku.Price
private bnhtrade.Core.Logic.Log.LogEvent log = new Log.LogEvent();
string err = "FbaPricing Error: ";
private string marginSchemeTaxCode = Data.Database.Constants.GetMarginSchemeTaxCode();
int repriceHoldOnSalePeriod = 14; // days
private int newConditionId = Data.Database.Constants.GetProductConditionIdNew();
private List<Model.Sku.Price.SkuPriceParameter> skuInfo;
private List<Model.Sku.Price.SkuRepriceInfo> skuInfo;
private Dictionary<string, Model.Product.CompetitivePrice> competitivePrices;
DateTime newTimeStamp = DateTime.UtcNow;
private int repriceIncrementDivisor = 60;
@@ -35,6 +34,8 @@ namespace bnhtrade.Core.Logic.Sku.Price
marginSchemeMargin = taxCalc.GetMarginMultiplier(newTimeStamp);
}
public int RepriceHoldOnSalePeriod { get; set; } = 14; // days
public void Update(bool overrideDayCheck = false)
{
UpdatePrecheck();
@@ -43,8 +44,29 @@ namespace bnhtrade.Core.Logic.Sku.Price
{
string orderChannel = Data.Database.Constants.GetOrderChannelAmazonUk(); ; // may in future enable other order channels
// get SKU quantities in stock on FBA
var statusTypeList = new List<int> { 3, 4 };
var fbaSkuStock = new Logic.Stock.GetStatusTypeBalance().BySku(statusTypeList);
// retrive SKU info
var getSku = new Logic.Sku.GetSkuInfo(sqlConnectionString);
var skuInfoDict = getSku.ConvertToDictionary(getSku.BySkuNumber(fbaSkuStock.Keys.ToList()));
// get current sku base pricing details (stock quantity, competative price, VAT info, etc.)
skuInfo = new Data.Database.Sku.Price.ReadParameter(sqlConnectionString).Execute();
skuInfo = new Data.Database.Sku.Price.ReadParameter().Execute();
if (skuInfo == null || !skuInfo.Any())
{
err += "Querying the database returned no records.";
@@ -57,10 +79,10 @@ namespace bnhtrade.Core.Logic.Sku.Price
var crDictionary = new Dictionary<string, Model.Sku.Price.PriceInfo>();
// open needed classes
var readAge = new Data.Database.Import.ReadFbaInventoryAge(sqlConnectionString);
var readAge = new Data.Database.Import.AmazonFbaInventoryAgeRead();
// get current db pricing
var dbDictionary = new Data.Database.Sku.Price.ReadPricingDetail(sqlConnectionString).ReadDictionary(skuInfo.Select(o => o.SkuNumber).ToList(), orderChannel);
var dbDictionary = new Data.Database.Sku.Price.ReadPricingDetail().ReadDictionary(skuInfo.Select(o => o.SkuNumber).ToList(), orderChannel);
// get required competivie prices
var readComp = new Logic.Product.GetCompetitivePrice(sqlConnectionString);
@@ -248,7 +270,7 @@ namespace bnhtrade.Core.Logic.Sku.Price
if (skuInfo[i].TaxCode == marginSchemeTaxCode) // taxcodeinfo now has ismarginscheme boolean
{
price = (costPrice + agentFeeFixed - (costPrice * marginSchemeMargin))
price = (costPrice + agentFeeFixed - (costPrice * marginSchemeMargin))
/ (1 - profitMargin - agentFeeMargin - marginSchemeMargin);
}
else
@@ -300,8 +322,8 @@ namespace bnhtrade.Core.Logic.Sku.Price
{
if (!saleCountInPeriod.Any())
{
saleCountInPeriod = new Data.Database.Import.ReadFbaSaleShipment(sqlConnectionString)
.GetSaleCount(skuInfo.Select(x => x.SkuNumber).ToList(), DateTime.Now.AddDays(repriceHoldOnSalePeriod * -1), DateTime.Now);
saleCountInPeriod = new Data.Database.Import.AmazonFbaSaleShipment()
.ReadSaleCount(skuInfo.Select(x => x.SkuNumber).ToList(), DateTime.Now.AddDays(RepriceHoldOnSalePeriod * -1), DateTime.Now);
}
if (saleCountInPeriod.ContainsKey(skuInfo[i].SkuNumber))
{
@@ -313,6 +335,11 @@ namespace bnhtrade.Core.Logic.Sku.Price
}
}
/// <summary>
/// Compares current date and last reprice date to check if SKU can be repriced
/// </summary>
/// <param name="lastPriceUpdate">The date & time the SKU was lasted repriced</param>
/// <returns></returns>
private bool OkayToReprice(DateTime lastPriceUpdate)
{
if (lastPriceUpdate == default(DateTime))
@@ -338,6 +365,10 @@ namespace bnhtrade.Core.Logic.Sku.Price
return update;
}
/// <summary>
/// Saves the pricing info to databse
/// </summary>
/// <param name="crDictionary">Current repricing data in Dictonary form by SKU number</param>
private void SaveToDatabase(Dictionary<string, Model.Sku.Price.PriceInfo> crDictionary)
{
var validate = new Core.Logic.Validate.SkuPriceInfo();
@@ -348,7 +379,7 @@ namespace bnhtrade.Core.Logic.Sku.Price
throw new Exception(err);
}
new Data.Database.Sku.Price.CreatePricingDetail(sqlConnectionString).Executue(crDictionary.Values.ToList());
new Data.Database.Sku.Price.CreatePricingDetail().Executue(crDictionary.Values.ToList());
}
/// <summary>
@@ -409,4 +440,4 @@ namespace bnhtrade.Core.Logic.Sku.Price
submit.SubmitInventoryLoader(stream);
}
}
}
}

View File

@@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace bnhtrade.Core.Model.Sku.Price
{
public class SkuRepriceInfo
{
public int SkuId { get; set; }
public string SkuNumber { get; set; }
public int TotalQuantity { get; set; }
public decimal UnitCostAverage { get; set; }
public int ProductId { get; set; }
public int ConditionId { get; set; }
public string TaxCode { get; set; }
public decimal ProfitMargin { get; set; }
/// <summary>
/// Agent fee as ratio of selling price (i.e. 20% = 0.2)
/// </summary>
public decimal AgentFeeMargin { get; set; }
/// <summary>
/// Total of agent fixed fees
/// </summary>
public decimal AgentFeeFixed { get; set; }
/// <summary>
/// Tax margin as a ratio of 1 (i.e. 20% = 0.2)
/// </summary>
public decimal VatMargin { get; set; }
public string TaxRateName { get; set; }
public bool IsFixedPrice { get; set; }
public decimal CompetitivePriceMultiplierNew { get; set; }
public decimal TotalCost { get; set; }
public decimal PriceMinProfit { get; set; }
}
}