mirror of
https://github.com/stokebob/bnhtrade.git
synced 2026-03-19 06:27:15 +00:00
396 lines
17 KiB
C#
396 lines
17 KiB
C#
using Amazon.Runtime.Internal.Transform;
|
|
using bnhtrade.Core.Model.Stock;
|
|
using FikaAmazonAPI.AmazonSpApiSDK.Models.Restrictions;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Data.SqlClient;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Transactions;
|
|
|
|
namespace bnhtrade.Core.Logic.Stock
|
|
{
|
|
public class SkuTransactionImport
|
|
{
|
|
private Log.LogEvent log = new Log.LogEvent();
|
|
|
|
private string ConstructTransactionTypeCode(Model.Import.FbaReimbursementReport record, bool isPositive)
|
|
{
|
|
if (string.IsNullOrEmpty(record.Reason))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
string transactionCode = "<AmazonReport><_GET_FBA_REIMBURSEMENTS_DATA_>";
|
|
|
|
if (isPositive)
|
|
{
|
|
transactionCode = transactionCode + "<+ve>";
|
|
}
|
|
else
|
|
{
|
|
transactionCode = transactionCode + "<-ve>";
|
|
}
|
|
|
|
transactionCode = transactionCode + "<" + record.Reason + ">";
|
|
return transactionCode;
|
|
}
|
|
|
|
private string ConstructTransactionTypeCode(Model.Import.AmazonFbaInventoryLedgerDetail record)
|
|
{
|
|
//if (string.IsNullOrEmpty(record.Reason))
|
|
//{
|
|
// return null;
|
|
//}
|
|
|
|
string transactionCode = "<AmazonReport><GET_LEDGER_DETAIL_VIEW_DATA><" + record.EventType + ">";
|
|
|
|
if (!string.IsNullOrEmpty(record.Reason))
|
|
{
|
|
transactionCode = transactionCode + "<" + record.Reason + ">";
|
|
}
|
|
|
|
if (record.Quantity < 0)
|
|
{
|
|
transactionCode = transactionCode + "<-ve>";
|
|
}
|
|
else
|
|
{
|
|
transactionCode = transactionCode + "<+ve>";
|
|
}
|
|
|
|
transactionCode = transactionCode + "<" + record.Disposition + ">";
|
|
|
|
return transactionCode;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Imports/Transaposes all data required for reconcilation, into the sku transaction table.
|
|
/// </summary>
|
|
public void ImportAll()
|
|
{
|
|
bool inventoryLedgerDetail = false;
|
|
bool reimbursement = false;
|
|
|
|
while (true)
|
|
{
|
|
try
|
|
{
|
|
if (true)
|
|
{
|
|
if (inventoryLedgerDetail == false) { inventoryLedgerDetail = true; ImportAmazonFbaLedgerDetail(); }
|
|
if (reimbursement == false) { reimbursement = true; ImportAmazonFbaReimbursement(); }
|
|
}
|
|
|
|
break;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.LogError(
|
|
"Exception caught running Importing amazon reports in the SKU transaction table, see for further details",
|
|
ex.ToString()
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Imports/Transaposes data from the Amazon FBA Reimbursement report table, into the SKU transaction table, ready for reconcilation.
|
|
/// </summary>
|
|
/// <exception cref="NotImplementedException"></exception>
|
|
public void ImportAmazonFbaReimbursement()
|
|
{
|
|
//throw new NotImplementedException("Needs testing");
|
|
|
|
/*
|
|
* Not to be used for stock reconciliation! A single stock item can have multiple reimburesements aginst it.
|
|
* Only use to move lost inventory to Amazon ownership (even then, with some caveats!)
|
|
*
|
|
* generally any lost or damaged stock goes to lost and found (and is hence written off)
|
|
* once amazon have reimbursed (confitmation via this report) the stock is then moved to amazon owvership
|
|
* and also the 'Cost of goods' amounts moved to the appropreate account id
|
|
*/
|
|
|
|
log.LogInformation("Starting TransposeFbaRemovalOrderReport()");
|
|
int transposeCount = 0;
|
|
int transposeSkip = 0;
|
|
var dbAmznReport = new Data.Database.Import.AmazonFbaReimbursement();
|
|
var dbTransType = new Logic.Stock.SkuTransactionTypeCrud();
|
|
|
|
try
|
|
{
|
|
var importList = dbAmznReport.Read(false);
|
|
|
|
// we need to retrive the transaction-types from the database
|
|
|
|
// run through the returned records and build list of transaction-type codes
|
|
var transTypeCodeList = new List<string>();
|
|
foreach (var item in importList)
|
|
{
|
|
transTypeCodeList.Add(ConstructTransactionTypeCode(item, false));
|
|
// any that reimburse inventory, will have two entries
|
|
if(item.QuantityReimbursedInventory > 0)
|
|
{
|
|
transTypeCodeList.Add(ConstructTransactionTypeCode(item, true));
|
|
}
|
|
}
|
|
transTypeCodeList = transTypeCodeList.Distinct().ToList();
|
|
|
|
// get transaction-type objects from db
|
|
var transTypeDict = dbTransType.GetByTypeCode(transTypeCodeList);
|
|
|
|
// new transaction-type check
|
|
var foundNewType = false;
|
|
foreach (var transTypeCode in transTypeCodeList)
|
|
{
|
|
// if a transaction-type code did not exist in the db, we need to create it
|
|
if (transTypeDict.ContainsKey(transTypeCode) == false)
|
|
{
|
|
dbTransType.Create(
|
|
transTypeCode,
|
|
(int)Data.Database.Constants.StockJournalType.SkuReconciliationFbaReimbursement
|
|
);
|
|
var newItem = dbTransType.GetByTypeCode(transTypeCode);
|
|
if (newItem == null)
|
|
{
|
|
throw new Exception("Createing new transaction-type returned null");
|
|
}
|
|
transTypeDict.Add(newItem.TypeCode, newItem);
|
|
foundNewType = true;
|
|
}
|
|
|
|
// also check existing transaction-type for 'is new'
|
|
if (transTypeDict[transTypeCode].IsNewReviewRequired)
|
|
{
|
|
foundNewType = true;
|
|
}
|
|
}
|
|
|
|
// don't go any further until the transaction-type has been reviewed/setup
|
|
if (foundNewType)
|
|
{
|
|
log.LogWarning("Cannot complete ImportAmazonFbaReimbursement, new 'Stock Trnasaction Type' found. Review required/");
|
|
return;
|
|
}
|
|
|
|
// we're all setup, time to transpose the report into the transaction table
|
|
using (TransactionScope scope = new TransactionScope())
|
|
{
|
|
var dbTrans = new Logic.Stock.SkuTransactionCrud();
|
|
foreach (var item in importList)
|
|
{
|
|
int? transId = null;
|
|
// always added
|
|
if (true)
|
|
{
|
|
string typeCode = ConstructTransactionTypeCode(item, false);
|
|
var transType = transTypeDict[typeCode];
|
|
|
|
if (transType.IsNewReviewRequired)
|
|
{
|
|
throw new Exception("Fail safe: Buggy code, should not get here!");
|
|
}
|
|
else if (transType.TransactionImportEnabled)
|
|
{
|
|
var newTransaction = new Model.Stock.SkuTransactionCreate(
|
|
item.ApprovalDate,
|
|
typeCode,
|
|
item.FbaReimbursementReportID,
|
|
item.ReimbursementId,
|
|
item.Reason,
|
|
item.Sku,
|
|
item.QuantityReimbursedInventory
|
|
);
|
|
|
|
transId = dbTrans.Create(newTransaction);
|
|
}
|
|
}
|
|
// double transaction added if true
|
|
if (item.QuantityReimbursedInventory > 0)
|
|
{
|
|
string typeCode = ConstructTransactionTypeCode(item, true);
|
|
var transType = transTypeDict[typeCode];
|
|
|
|
if (transType.IsNewReviewRequired)
|
|
{
|
|
throw new Exception("Fail safe: Buggy code, should not get here!");
|
|
}
|
|
else if (transType.TransactionImportEnabled)
|
|
{
|
|
var newTransaction = new Model.Stock.SkuTransactionCreate(
|
|
item.ApprovalDate,
|
|
typeCode,
|
|
item.FbaReimbursementReportID,
|
|
item.ReimbursementId,
|
|
item.Reason,
|
|
item.Sku,
|
|
item.QuantityReimbursedInventory
|
|
);
|
|
|
|
transId = dbTrans.Create(newTransaction);
|
|
}
|
|
}
|
|
// update the amazon report table
|
|
dbAmznReport.UpdateIsProcessed(item.FbaReimbursementReportID, true, transId);
|
|
transposeCount = transposeCount + 1;
|
|
}
|
|
// drop out of loop
|
|
scope.Complete();
|
|
}
|
|
Console.Write("\r");
|
|
log.LogInformation("ProcessFbaReimbursementData() complete, " + transposeCount + " total records transposed, " + transposeSkip + " records skipped.");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.LogError("Exception catch, aborting ProcessFbaReimbursementData(), see detailed info. "
|
|
+ transposeCount + " total records completed, " + transposeSkip + " records skipped.", ex.ToString());
|
|
}
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// Imports/Transaposes data from the Amazon FBA Ledger Detail report table, into the SKU transaction table, ready for reconcilation.
|
|
/// </summary>
|
|
/// <exception cref="NotImplementedException"></exception>
|
|
public void ImportAmazonFbaLedgerDetail()
|
|
{
|
|
//// Done but needs testing!!
|
|
//throw new NotImplementedException("Done but needs testing!!");
|
|
|
|
log.LogInformation("Starting TransposeFbaAdustmentReport()");
|
|
int transposeCount = 0;
|
|
int transposeSkip = 0;
|
|
|
|
using (var scope = new TransactionScope())
|
|
{
|
|
try
|
|
{
|
|
// get unprocessed amazon ledger report items
|
|
var dbImport = new Data.Database.Import.AmazonFbaInventoryLedgerDetail();
|
|
var reportDict = dbImport.Read(null, null, false);
|
|
|
|
// create transaction list to insert into transaction table
|
|
var transactionList = new List<SkuTransactionCreate>();
|
|
var transCodeToJournalTypeId = new Dictionary<string, int>();
|
|
foreach (var item in reportDict)
|
|
{
|
|
// test for internal Amazon stuff that we don't care about and mark as processed
|
|
if (item.Value.EventType == "WhseTransfers")
|
|
{
|
|
dbImport.UpdateIsProcessed(item.Key, true);
|
|
}
|
|
// add the the transaction list
|
|
else
|
|
{
|
|
// build the transaction code
|
|
string transactionCode = ConstructTransactionTypeCode(item.Value);
|
|
|
|
// load the report item into parameter
|
|
DateTime transactionDate = item.Value.DateAndTime;
|
|
|
|
int foreignKey = item.Key;
|
|
|
|
string reference = null;
|
|
if (!string.IsNullOrEmpty(item.Value.ReferenceId))
|
|
{ reference = item.Value.ReferenceId; }
|
|
|
|
string detail = "Fulfillment Center: " + item.Value.FulfillmentCenter;
|
|
|
|
string skuNumber = item.Value.Msku;
|
|
|
|
// quanity in the transaction table is always be +ve
|
|
int quantity = item.Value.Quantity;
|
|
if (quantity < 0)
|
|
quantity = quantity * -1;
|
|
|
|
// create the objet class and add to the list
|
|
var transaction = new Model.Stock.SkuTransactionCreate(
|
|
transactionDate
|
|
, transactionCode
|
|
, foreignKey
|
|
, reference
|
|
, detail
|
|
, skuNumber
|
|
, quantity
|
|
);
|
|
transactionList.Add(transaction);
|
|
|
|
// add transtypecode to dictionary to 'stock journal type' dictionary. Needed if there's a new transaction type
|
|
if (transCodeToJournalTypeId.ContainsKey(transactionCode) == false)
|
|
{
|
|
int journalTypeId = 0;
|
|
if (item.Value.EventType == "Receipts")
|
|
{ journalTypeId = (int)Data.Database.Constants.StockJournalType.SkuReconciliationFbaReceipt; }
|
|
else if (item.Value.EventType == "Shipments")
|
|
{ journalTypeId = (int)Data.Database.Constants.StockJournalType.SkuReconciliationFbaShipment; }
|
|
else if (item.Value.EventType == "Adjustments")
|
|
{ journalTypeId = (int)Data.Database.Constants.StockJournalType.SkuReconciliationFbaAdjustment; }
|
|
else if (item.Value.EventType == "CustomerReturns")
|
|
{ journalTypeId = (int)Data.Database.Constants.StockJournalType.SkuReconciliationFbaCustomerReturn; }
|
|
else if (item.Value.EventType == "VendorReturns")
|
|
{ journalTypeId = (int)Data.Database.Constants.StockJournalType.SkuReconciliationFbaVendorReturn; }
|
|
else if (item.Value.EventType == "WhseTransfers")
|
|
{ journalTypeId = -1; }
|
|
else
|
|
{ throw new Exception("New event-type " + item.Value.EventType + " in the GET_LEDGER_DETAIL_VIEW_DATA report"); }
|
|
|
|
transCodeToJournalTypeId.Add(transactionCode, journalTypeId);
|
|
}
|
|
}
|
|
}
|
|
|
|
// check for any new types codes, and add them if ther are
|
|
var dbTransType = new Logic.Stock.SkuTransactionTypeCrud();
|
|
var transTypeList = dbTransType.GetByTypeCode(transCodeToJournalTypeId.Keys.ToList());
|
|
|
|
foreach ( var transType in transTypeList)
|
|
{
|
|
if (transCodeToJournalTypeId.ContainsKey(transType.Key))
|
|
{
|
|
transCodeToJournalTypeId.Remove(transType.Key);
|
|
}
|
|
}
|
|
|
|
foreach (var newItem in transCodeToJournalTypeId)
|
|
{
|
|
dbTransType.Create(newItem.Key, newItem.Value);
|
|
}
|
|
|
|
// finally, add the transction list to the table
|
|
var dbTransaction = new Logic.Stock.SkuTransactionCrud();
|
|
foreach (var item in transactionList)
|
|
{
|
|
int id = dbTransaction.Create(item);
|
|
dbImport.UpdateIsProcessed((int)item.ForeignKey, id);
|
|
}
|
|
|
|
scope.Complete();
|
|
|
|
log.LogInformation(
|
|
"TransposeFbaAdustmentReport() complete, " + transposeCount + " total records transposed, " + transposeSkip + " records skipped."
|
|
);
|
|
|
|
if (transposeSkip > 0)
|
|
{
|
|
log.LogInformation(
|
|
transposeSkip + " number records skipped during TransposeFbaAdustmentReport() operation."
|
|
);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
scope.Dispose();
|
|
|
|
log.LogError(
|
|
"Exception catch, aborting TransposeFbaAdustmentReport(), see detailed info. "
|
|
+ transposeCount + " total records completed, " + transposeSkip + " records skipped."
|
|
, ex.ToString()
|
|
);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
}
|