Stock SKU transaction reconciliation

This commit is contained in:
2020-05-29 14:07:46 +01:00
committed by GitHub
parent 43d61c2ef8
commit 3a53350f85
16 changed files with 520 additions and 173 deletions

View File

@@ -27,6 +27,8 @@ namespace bnhtrade.ComTypeLib
object ReconcileStockTransactions(ConnectionCredential sqlConnCred); object ReconcileStockTransactions(ConnectionCredential sqlConnCred);
void UnReconcileSkuTransaction(ConnectionCredential sqlConnCred, int skuTransactionId);
bool StockJournalConsistencyCheck(ConnectionCredential sqlConnCred, int stockId); bool StockJournalConsistencyCheck(ConnectionCredential sqlConnCred, int stockId);
} }
@@ -118,6 +120,11 @@ namespace bnhtrade.ComTypeLib
} }
public void UnReconcileSkuTransaction(ConnectionCredential sqlConnCred, int skuTransactionId)
{
new Core.Logic.Stock.SkuTransactionReconcile(sqlConnCred.ConnectionString).UnReconcileTransaction(skuTransactionId);
}
public bool StockJournalConsistencyCheck(ConnectionCredential sqlConnCred, int stockId) public bool StockJournalConsistencyCheck(ConnectionCredential sqlConnCred, int stockId)
{ {
return Core.Stock.StockJournal.WIP_StockJournalConsistencyCheck(sqlConnCred.ConnectionString, stockId, null); return Core.Stock.StockJournal.WIP_StockJournalConsistencyCheck(sqlConnCred.ConnectionString, stockId, null);

View File

@@ -34,7 +34,11 @@ namespace bnhtrade.Core.Data.Database.Stock
OUTPUT INSERTED.StockSkuTransactionID OUTPUT INSERTED.StockSkuTransactionID
VALUES ( VALUES (
@transactionDate @transactionDate
,@stockSkuTransactionTypeID ,(
SELECT StockSkuTransactionTypeID
FROM tblStockSkuTransactionType
WHERE TypeCode = @skuTransactionTypeCode
)
,@foreignKey ,@foreignKey
,@reference ,@reference
,@Detail ,@Detail
@@ -50,7 +54,7 @@ namespace bnhtrade.Core.Data.Database.Stock
", conn)) ", conn))
{ {
cmd.Parameters.AddWithValue("@transactionDate", skuTransaction.TransactionDate.ToUniversalTime()); cmd.Parameters.AddWithValue("@transactionDate", skuTransaction.TransactionDate.ToUniversalTime());
cmd.Parameters.AddWithValue("@stockSkuTransactionTypeID", skuTransaction.SkuTransactionTypeId); cmd.Parameters.AddWithValue("@skuTransactionTypeCode", skuTransaction.SkuTransactionTypeCode);
if (!skuTransaction.IsSetForeignKey) { cmd.Parameters.AddWithValue("@foreignKey", DBNull.Value); } if (!skuTransaction.IsSetForeignKey) { cmd.Parameters.AddWithValue("@foreignKey", DBNull.Value); }
else { cmd.Parameters.AddWithValue("@foreignKey", skuTransaction.ForeignKey); } else { cmd.Parameters.AddWithValue("@foreignKey", skuTransaction.ForeignKey); }
if (!skuTransaction.IsSetReference) { cmd.Parameters.AddWithValue("@reference", DBNull.Value); } if (!skuTransaction.IsSetReference) { cmd.Parameters.AddWithValue("@reference", DBNull.Value); }

View File

@@ -10,11 +10,45 @@ namespace bnhtrade.Core.Data.Database.Stock
{ {
public class ReadSkuTransaction : Connection public class ReadSkuTransaction : Connection
{ {
private Data.Database.WhereBuilder whereBuilder = new WhereBuilder();
public ReadSkuTransaction(string sqlConnectionString) : base(sqlConnectionString) public ReadSkuTransaction(string sqlConnectionString) : base(sqlConnectionString)
{ {
} }
/// <summary>
/// Initialise result filters
/// </summary>
public void Init()
{
whereBuilder = new WhereBuilder();
IsReconciled = null;
StockTransactionTypeName = null;
StockTransactionTypeCode = null;
}
/// <summary>
/// Read result filter
/// </summary>
public bool? IsReconciled { get; set; }
/// <summary>
/// Read result filter
/// </summary>
public List<string> StockTransactionTypeName { get; set; }
/// <summary>
/// Read result filter
/// </summary>
public List<string> StockTransactionTypeCode { get; set; }
/// <summary>
/// Retrive a 'Stock Journal ID' for a reconciled SKU transaction
/// </summary>
/// <param name="skuTransactionId">Stock SKU Transaction ID</param>
/// <returns>Stock Journal ID</returns>
public int? GetJournalId(int skuTransactionId) public int? GetJournalId(int skuTransactionId)
{ {
using (var conn = new SqlConnection(sqlConnectionString)) using (var conn = new SqlConnection(sqlConnectionString))
@@ -41,24 +75,19 @@ namespace bnhtrade.Core.Data.Database.Stock
} }
} }
public List<Model.Stock.SkuTransaction> GetUnreconciled()
/// <summary>
/// Populates model class from filtered database results
/// </summary>
/// <returns>List of SkuTransaction</returns>
public List<Model.Stock.SkuTransaction> Read()
{ {
// order by stocktransId desc = Amazon reports are listed in datetime ASC order, some reports have date only, // order by stocktransId desc = Amazon reports are listed in datetime ASC order, some reports have date only,
// however I have reason to believe these are in time order. // however I have reason to believe these are in time order.
// Adding this means they at least get processed in the correct order (maybe)! // Adding this means they at least get processed in the correct order (maybe)!
string sqlWhere = @"
WHERE tblStockSkuTransaction.IsProcessed = 0
AND (
tblStockSkuTransactionType.StockJournalEntryEnabled = 1
OR tblStockSkuTransactionType.IsNewReviewRequired = 1
) ";
return Read(sqlWhere, new DynamicParameters());
}
private List<Model.Stock.SkuTransaction> Read(string sqlWhere, DynamicParameters parameters)
{
var resultList = new List<Model.Stock.SkuTransaction>(); var resultList = new List<Model.Stock.SkuTransaction>();
var parameters = new DynamicParameters();
string sql = @" string sql = @"
SELECT tblStockSkuTransaction.StockSkuTransactionID AS SkuTransactionId SELECT tblStockSkuTransaction.StockSkuTransactionID AS SkuTransactionId
@@ -70,14 +99,43 @@ namespace bnhtrade.Core.Data.Database.Stock
,tblStockSkuTransaction.Quantity ,tblStockSkuTransaction.Quantity
,tblStockSkuTransaction.IsProcessed ,tblStockSkuTransaction.IsProcessed
,tblStockSkuTransaction.StockJournalID AS StockJournalId ,tblStockSkuTransaction.StockJournalID AS StockJournalId
,tblStockSkuTransactionType.TypeTitle AS SkuTransactionTypeName ,tblStockSkuTransactionType.TypeName AS SkuTransactionTypeName
,tblSku.skuSkuNumber AS SkuNumber ,tblSku.skuSkuNumber AS SkuNumber
,tblStockSkuTransaction.SkuID ,tblStockSkuTransaction.SkuID
FROM tblStockSkuTransaction FROM tblStockSkuTransaction
INNER JOIN tblStockSkuTransactionType ON tblStockSkuTransaction.StockSkuTransactionTypeID = tblStockSkuTransactionType.StockSkuTransactionTypeID INNER JOIN tblStockSkuTransactionType ON tblStockSkuTransaction.StockSkuTransactionTypeID = tblStockSkuTransactionType.StockSkuTransactionTypeID
INNER JOIN tblSku ON tblStockSkuTransaction.SkuID = tblSku.skuSkuID "; INNER JOIN tblSku ON tblStockSkuTransaction.SkuID = tblSku.skuSkuID
WHERE 1=1 ";
sql += sqlWhere; if (IsReconciled != null)
{
sql += @"
AND tblStockSkuTransaction.IsProcessed =";
if (IsReconciled.GetValueOrDefault())
{
sql += " 1 ";
}
else
{
sql += " 0 ";
}
}
if (StockTransactionTypeName != null && StockTransactionTypeName.Any())
{
parameters.Add("@stockTransactionTypeName", StockTransactionTypeName);
sql += @"
AND tblStockSkuTransactionType.TypeName IN @stockTransactionTypeName ";
}
if (StockTransactionTypeCode != null && StockTransactionTypeCode.Any())
{
parameters.Add("@stockTransactionTypeCode", StockTransactionTypeCode);
sql += @"
AND tblStockSkuTransactionType.TypeCode IN @stockTransactionTypeCode ";
}
sql += @" sql += @"
ORDER BY tblStockSkuTransaction.TransactionDate ASC, tblStockSkuTransaction.StockSkuTransactionID DESC;"; ORDER BY tblStockSkuTransaction.TransactionDate ASC, tblStockSkuTransaction.StockSkuTransactionID DESC;";

View File

@@ -54,15 +54,11 @@ namespace bnhtrade.Core.Data.Database.Stock
{ {
if (reader.Read()) if (reader.Read())
{ {
int index01 = reader.GetOrdinal("StockSkuTransactionTypeID"); int transactionTypeId = reader.GetInt32(0);
int index02 = reader.GetOrdinal("IsNewReviewRequired"); bool isNew = reader.GetBoolean(1);
int index03 = reader.GetOrdinal("TransactionImportEnabled"); bool importEnabled = reader.GetBoolean(2);
int transactionTypeId = reader.GetInt32(index01); if (isNew == true)
bool isNew = reader.GetBoolean(index02);
bool? importEnabled = reader[index03] as bool? ?? null; // column can be null
if (isNew == true || importEnabled == null)
{ {
// return 0 and 'skip' item // return 0 and 'skip' item
return 0; return 0;

View File

@@ -148,14 +148,18 @@ namespace bnhtrade.Core.Data.Database.Stock
public void Update(Model.Stock.SkuTransaction skuTransaction) public void Update(Model.Stock.SkuTransaction skuTransaction)
{ {
using (var conn = new SqlConnection()) using (var conn = new SqlConnection(sqlConnectionString))
{ {
conn.Open(); conn.Open();
using (SqlCommand cmd = new SqlCommand(@" using (SqlCommand cmd = new SqlCommand(@"
UPDATE tblStockSkuTransaction UPDATE tblStockSkuTransaction
SET TransactionDate = @transactionDate SET TransactionDate = @transactionDate
,StockSkuTransactionTypeID = @stockSkuTransactionTypeID ,StockSkuTransactionTypeID = (
SELECT StockSkuTransactionTypeID
FROM tblStockSkuTransactionType
WHERE TypeCode = @skuTransactionTypeCode
)
,ForeignKey = @foreignKey ,ForeignKey = @foreignKey
,Reference = @reference ,Reference = @reference
,Detail = @Detail ,Detail = @Detail
@@ -171,7 +175,7 @@ namespace bnhtrade.Core.Data.Database.Stock
", conn)) ", conn))
{ {
cmd.Parameters.AddWithValue("@transactionDate", skuTransaction.TransactionDate.ToUniversalTime()); cmd.Parameters.AddWithValue("@transactionDate", skuTransaction.TransactionDate.ToUniversalTime());
cmd.Parameters.AddWithValue("@stockSkuTransactionTypeID", skuTransaction.SkuTransactionTypeId); cmd.Parameters.AddWithValue("@skuTransactionTypeCode", skuTransaction.SkuTransactionTypeCode);
if (!skuTransaction.IsSetForeignKey) { cmd.Parameters.AddWithValue("@foreignKey", DBNull.Value); } if (!skuTransaction.IsSetForeignKey) { cmd.Parameters.AddWithValue("@foreignKey", DBNull.Value); }
else { cmd.Parameters.AddWithValue("@foreignKey", skuTransaction.ForeignKey); } else { cmd.Parameters.AddWithValue("@foreignKey", skuTransaction.ForeignKey); }
if (!skuTransaction.IsSetReference) { cmd.Parameters.AddWithValue("@reference", DBNull.Value); } if (!skuTransaction.IsSetReference) { cmd.Parameters.AddWithValue("@reference", DBNull.Value); }

View File

@@ -8,12 +8,12 @@ using bnhtrade.Core.Data;
namespace bnhtrade.Core.Logic.AmazonFBAInbound namespace bnhtrade.Core.Logic.AmazonFBAInbound
{ {
public class UpdateDatabaseShipmentInfo public class ShipmentInfoPersistanceUpdate
{ {
private string sqlConnectionString; private string sqlConnectionString;
private readonly string logDateTimeId = "FbaInboundShipmentNewCheck"; private readonly string logDateTimeId = "FbaInboundShipmentNewCheck";
public int TotalUpdated { get; private set; } = 0; public int TotalUpdated { get; private set; } = 0;
public UpdateDatabaseShipmentInfo(string sqlConnectionString) public ShipmentInfoPersistanceUpdate(string sqlConnectionString)
{ {
this.sqlConnectionString = sqlConnectionString; this.sqlConnectionString = sqlConnectionString;
} }

View File

@@ -24,6 +24,31 @@ namespace bnhtrade.Core.Logic.Stock
log = new Log.LogEvent(); log = new Log.LogEvent();
} }
/// <summary>
/// Initialise result filters
/// </summary>
public void Init()
{
IsReconciled = null;
StockTransactionTypeName = null;
StockTransactionTypeCode = null;
}
/// <summary>
/// Read result filter
/// </summary>
public bool? IsReconciled { get; set; }
/// <summary>
/// Read result filter
/// </summary>
public List<string> StockTransactionTypeName { get; set; }
/// <summary>
/// Read result filter
/// </summary>
public List<string> StockTransactionTypeCode { get; set; }
private Data.Database.Stock.DeleteSkuTransaction DatabaseSkuTransDelete(bool forceNew = false) private Data.Database.Stock.DeleteSkuTransaction DatabaseSkuTransDelete(bool forceNew = false)
{ {
if (dbSkuTransDelete == null || forceNew) if (dbSkuTransDelete == null || forceNew)
@@ -93,13 +118,18 @@ namespace bnhtrade.Core.Logic.Stock
} }
} }
/// <summary>
/// Deletes an attached journal entry, if one is present.
/// </summary>
/// <param name="skuTransactionId">Stock SKU Transaction ID</param>
public void DeleteJournalEntry(int skuTransactionId) public void DeleteJournalEntry(int skuTransactionId)
{ {
using (var scope = new TransactionScope()) using (var scope = new TransactionScope())
{ {
try try
{ {
// is there a journal entry attached? // comfirm there is a journal entry attached
int? journalId = DatabaseSkuTransRead().GetJournalId(skuTransactionId); int? journalId = DatabaseSkuTransRead().GetJournalId(skuTransactionId);
if (journalId != null) if (journalId != null)
{ {
@@ -116,6 +146,10 @@ namespace bnhtrade.Core.Logic.Stock
} }
} }
/// <summary>
/// Validates and then creates a Stock SKU Tranaction
/// </summary>
/// <param name="skuTransaction">'Stock SKU Transaction' model</param>
public void Create(Model.Stock.SkuTransaction skuTransaction) public void Create(Model.Stock.SkuTransaction skuTransaction)
{ {
if (skuTransaction == null) if (skuTransaction == null)
@@ -134,6 +168,31 @@ namespace bnhtrade.Core.Logic.Stock
DatabaseSkuTransInsert().Create(skuTransaction); DatabaseSkuTransInsert().Create(skuTransaction);
} }
/// <summary>
///
/// </summary>
/// <param name="retriveTransactionTypeInfo">Retrive and include transaction type model class</param>
public List<Model.Stock.SkuTransaction> Read(bool retriveTransactionTypeInfo = true)
{
var dbRead = new Data.Database.Stock.ReadSkuTransaction(sqlConnectionString);
dbRead.IsReconciled = IsReconciled;
dbRead.StockTransactionTypeCode = StockTransactionTypeCode;
dbRead.StockTransactionTypeName = StockTransactionTypeName;
var resultList = dbRead.Read();
if (retriveTransactionTypeInfo)
{
var dbReadType = new Logic.Stock.SkuTransactionTypePersistance(sqlConnectionString);
dbReadType.GetBySkuTransaction(resultList);
}
return resultList;
}
/// <summary>
/// Validates and then updates a Stock SKU Tranaction
/// </summary>
/// <param name="skuTransaction">'Stock SKU Transaction' model</param>
public void Update(Model.Stock.SkuTransaction skuTransaction) public void Update(Model.Stock.SkuTransaction skuTransaction)
{ {
if (skuTransaction == null) if (skuTransaction == null)
@@ -159,7 +218,7 @@ namespace bnhtrade.Core.Logic.Stock
DeleteJournalEntry(skuTransaction.SkuTransactionId); DeleteJournalEntry(skuTransaction.SkuTransactionId);
} }
} }
dbSkuTransUpdate.Update(skuTransaction); DatabaseSkuTransUpdate().Update(skuTransaction);
scope.Complete(); scope.Complete();
} }
} }

View File

@@ -86,10 +86,13 @@ namespace bnhtrade.Core.Logic.Stock
logEvent.LogInformation("Starting ReconcileStockTransactions()"); logEvent.LogInformation("Starting ReconcileStockTransactions()");
int recordSkip = 0; int recordSkip = 0;
ProcessLostAndFound(); ReconcileLostAndFound();
// get list of sku transactions to reconcile // get list of sku transactions to reconcile
var transList = new Data.Database.Stock.ReadSkuTransaction(sqlConnectionString).GetUnreconciled(); dbSkuTransaction.Init();
dbSkuTransaction.IsReconciled = false;
var transList = dbSkuTransaction.Read();
var shipmentInfoDic = new Dictionary<string, Model.AmazonFba.ShipmentInfo>();
ItemsRemaining = transList.Count; ItemsRemaining = transList.Count;
ItemsCompleted = 0; ItemsCompleted = 0;
@@ -106,88 +109,113 @@ namespace bnhtrade.Core.Logic.Stock
// setup return values // setup return values
CurrentSkuTransaction = transList[i]; CurrentSkuTransaction = transList[i];
CurrentTransactionId = transList[i].SkuTransactionId; CurrentTransactionId = transList[i].SkuTransactionId;
CurrentTransactionTypeId = transList[i].SkuTransactionTypeId; CurrentTransactionTypeId = transList[i].SkuTransactionType.TypeId;
LastItemDateTime = transList[i].TransactionDate; LastItemDateTime = transList[i].TransactionDate;
// load type into variable // load type into variable
var transType = dbSkuTransactionType.GetByTypeName(transList[i].SkuTransactionTypeName); //var transType = dbSkuTransactionType.GetByTypeName(transList[i].SkuTransactionTypeName);
// stop if a new transactiontype is encountered // stop if a new transactiontype is encountered
if (transType.IsNewReviewRequired) if (transList[i].SkuTransactionType.IsNewReviewRequired)
{ {
ProgressMessage = "New 'Transaction-Type' encountered"; ProgressMessage = "New 'Transaction-Type' encountered";
//Console.Write("\r"); //Console.Write("\r");
//MiscFunction.EventLogInsert(errMessage, 1); //MiscFunction.EventLogInsert(errMessage, 1);
goto Stop; break;
} }
// set debit/credit status' for special cases (i.e. NULL or 0 debit/credit ids in stockTransactionType table) else if (transList[i].SkuTransactionType.StockJournalEntryEnabled == false)
if (transType.StockJournalEntryEnabled == true && (transType.DebitStockStatusId == 0 || transType.CreditStockStatusId == 0))
{ {
// FBA Shipment Receipt +ve transList[i].IsProcessed = true;
if (transType.TypeCode == "<AmazonReport><_GET_FBA_FULFILLMENT_INVENTORY_RECEIPTS_DATA_><+ve>" dbSkuTransaction.Update(transList[i]);
|| transType.TypeCode == "<AmazonReport><_GET_FBA_FULFILLMENT_INVENTORY_RECEIPTS_DATA_><-ve>") }
// stock journal entry is enabled
else
{ {
var shipmentInfo = readShipmentInfo.HeaderByFbaShipmentId(transList[i].Reference); // check debit/credits
if (transList[i].SkuTransactionType.DebitStockStatusId.GetValueOrDefault() == 0
|| transList[i].SkuTransactionType.CreditStockStatusId.GetValueOrDefault() == 0)
{
// special case FBA Shipment Receipt +ve
if (transList[i].SkuTransactionType.TypeCode == "<AmazonReport><_GET_FBA_FULFILLMENT_INVENTORY_RECEIPTS_DATA_><+ve>"
|| transList[i].SkuTransactionType.TypeCode == "<AmazonReport><_GET_FBA_FULFILLMENT_INVENTORY_RECEIPTS_DATA_><-ve>")
{
Model.AmazonFba.ShipmentInfo shipmentInfo = null;
if (!shipmentInfoDic.ContainsKey(transList[i].Reference))
{
shipmentInfo = readShipmentInfo.HeaderByFbaShipmentId(transList[i].Reference);
if (shipmentInfo == null)
{
throw new Exception("Unable to retrive shipment info for reference '" + transList[i].Reference + "'.");
}
else
{
shipmentInfoDic.Add(transList[i].Reference, shipmentInfo);
}
}
if (shipmentInfo.IsSetShipmentStockStatusId()) if (shipmentInfo.IsSetShipmentStockStatusId())
{ {
// +ve shipment receipt // +ve shipment receipt
if (transType.CreditStockStatusId == 0 && transType.DebitStockStatusId > 0) if (transList[i].SkuTransactionType.CreditStockStatusId == 0
{ transType.CreditStockStatusId = shipmentInfo.ShipmentStockStatusId; } && transList[i].SkuTransactionType.DebitStockStatusId > 0)
{
transList[i].SkuTransactionType.CreditStockStatusId = shipmentInfo.ShipmentStockStatusId;
}
// -ve shipment receipt // -ve shipment receipt
else if (transType.DebitStockStatusId == 0 && transType.CreditStockStatusId > 0) else if (transList[i].SkuTransactionType.DebitStockStatusId == 0
{ transType.DebitStockStatusId = shipmentInfo.ShipmentStockStatusId; } && transList[i].SkuTransactionType.CreditStockStatusId > 0)
{
transList[i].SkuTransactionType.DebitStockStatusId = shipmentInfo.ShipmentStockStatusId;
}
// something went wrong, raise error // something went wrong, raise error
else else
{ {
ProgressMessage = "Unable to retrive FBA shipment location/status from tblAmazonShipment for Amazon shipment '" + shipmentInfo.FbaShipmentId + "'."; ProgressMessage = "Unable to retrive FBA shipment location/status from tblAmazonShipment for Amazon shipment '" + shipmentInfo.FbaShipmentId + "'.";
recordSkip = recordSkip + 1; recordSkip = recordSkip + 1;
goto Stop; break;
} }
} }
}
// something went wrong, raise error
else else
{ {
ProgressMessage = "Coding required. Unhandled special case Transaction-Type encountered (Transaction-Type debit or credit is set to 0)."; throw new Exception("Unable to retrive shipment info.");
}
}
// manual entry
else
{
ProgressMessage = "Transaction-Type debit or credit is not set, is this a manual entry?";
recordSkip = recordSkip + 1; recordSkip = recordSkip + 1;
goto Stop; break;
} }
} }
// make the changes // make the journal entries
if (transType.StockJournalEntryEnabled == false)
{
transList[i].IsProcessed = true;
dbSkuTransaction.Update(transList[i]);
}
else
{
var list = new List<(int StockJournalId, int Quantity)>(); var list = new List<(int StockJournalId, int Quantity)>();
if (transType.FilterStockOnDateTime) if (transList[i].SkuTransactionType.FilterStockOnDateTime)
{ {
list = stockReallocate.StockReallocateBySkuNumber( list = stockReallocate.StockReallocateBySkuNumber(
transType.StockJournalTypeId, transList[i].SkuTransactionType.StockJournalTypeId,
transList[i].SkuNumber, transList[i].SkuNumber,
transList[i].Quantity, transList[i].Quantity,
transType.DebitStockStatusId, transList[i].SkuTransactionType.DebitStockStatusId.GetValueOrDefault(),
transType.CreditStockStatusId, transList[i].SkuTransactionType.CreditStockStatusId.GetValueOrDefault(),
transType.FirstInFirstOut, transList[i].SkuTransactionType.FirstInFirstOut,
transList[i].TransactionDate, transList[i].TransactionDate,
false); false);
} }
else else
{ {
list = stockReallocate.StockReallocateBySkuNumber( list = stockReallocate.StockReallocateBySkuNumber(
transType.StockJournalTypeId, transList[i].SkuTransactionType.StockJournalTypeId,
transList[i].SkuNumber, transList[i].SkuNumber,
transList[i].Quantity, transList[i].Quantity,
transType.DebitStockStatusId, transList[i].SkuTransactionType.DebitStockStatusId.GetValueOrDefault(),
transType.CreditStockStatusId, transList[i].SkuTransactionType.CreditStockStatusId.GetValueOrDefault(),
transType.FirstInFirstOut, transList[i].SkuTransactionType.FirstInFirstOut,
DateTime.UtcNow, DateTime.UtcNow,
false); false);
} }
@@ -196,15 +224,15 @@ namespace bnhtrade.Core.Logic.Stock
if (list == null || !list.Any()) if (list == null || !list.Any())
{ {
// in special case (found inventory), continue // in special case (found inventory), continue
if (transType.TypeCode.Contains("<AmazonReport><_GET_FBA_FULFILLMENT_INVENTORY_ADJUSTMENTS_DATA_><F>")) if (transList[i].SkuTransactionType.TypeCode.Contains("<AmazonReport><_GET_FBA_FULFILLMENT_INVENTORY_ADJUSTMENTS_DATA_><F>"))
{ {
continue;// <--------------------------------------------------------------------------------------------------- is this the soruce of the bug? continue;
} }
else else
{ {
ProgressMessage = "Insurficent status/location balance to relocate stock"; ProgressMessage = "Insurficent status/location balance to relocate stock";
recordSkip = recordSkip + 1; recordSkip = recordSkip + 1;
goto Stop; break;
} }
} }
@@ -260,8 +288,9 @@ namespace bnhtrade.Core.Logic.Stock
dbSkuTransaction.Create(newRecordList[j]); dbSkuTransaction.Create(newRecordList[j]);
} }
} }
ItemsCompleted++; ItemsCompleted++;
ItemsRemaining++; ItemsRemaining--;
scope.Complete(); scope.Complete();
} }
// end of scope // end of scope
@@ -275,41 +304,49 @@ namespace bnhtrade.Core.Logic.Stock
return; return;
} }
Stop: if (ItemsRemaining == 0)
Console.Write("\r"); {
MiscFunction.EventLogInsert("ProcessStockTransactions() compete. " + ItemsCompleted + " total records processed, " + recordSkip + " rows uncompllete due to insurficent stock.");
MiscFunction.EventLogInsert("ProcessStockTransactions(), " + recordSkip + " rows skipped due to insurficent stock.", 2);
ReconciliationComplete = true; ReconciliationComplete = true;
ProgressMessage = "Operation complete."; ProgressMessage = "Operation complete.";
return;
} }
//Stop:
Console.Write("\r");
MiscFunction.ConsoleUpdate("ProcessStockTransactions() compete. " + ItemsCompleted + " total records processed, " + recordSkip + " rows uncompllete due to insurficent stock.");
MiscFunction.ConsoleUpdate("ProcessStockTransactions(), " + recordSkip + " rows skipped due to insurficent stock.");
return;
}
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public void ProcessLostAndFound() public void ReconcileLostAndFound()
{ {
using (var scope = new TransactionScope()) using (var scope = new TransactionScope())
{ {
// get list of sku transactions to reconcile
var transList = new Data.Database.Stock.ReadSkuTransaction(sqlConnectionString).GetUnreconciled();
ItemsRemaining = transList.Count;
ItemsCompleted = 0;
// need to loop though table and cancel out any found before they are lost (in reality they were never // need to loop though table and cancel out any found before they are lost (in reality they were never
// lost, therefore should not be entered into journal as lost) // lost, therefore should not be entered into journal as lost)
string lost = "<AmazonReport><_GET_FBA_FULFILLMENT_INVENTORY_ADJUSTMENTS_DATA_><M><-ve><InventoryMisplaced><SELLABLE>"; string lost = "<AmazonReport><_GET_FBA_FULFILLMENT_INVENTORY_ADJUSTMENTS_DATA_><M><-ve><InventoryMisplaced><SELLABLE>";
string found = "<AmazonReport><_GET_FBA_FULFILLMENT_INVENTORY_ADJUSTMENTS_DATA_><F><+ve><InventoryFound><SELLABLE>"; string found = "<AmazonReport><_GET_FBA_FULFILLMENT_INVENTORY_ADJUSTMENTS_DATA_><F><+ve><InventoryFound><SELLABLE>";
var codeList = new List<string>();
codeList.Add(lost);
codeList.Add(found);
// get list of sku transactions to reconcile
dbSkuTransaction.Init();
dbSkuTransaction.IsReconciled = false;
dbSkuTransaction.StockTransactionTypeCode = codeList;
var transList = dbSkuTransaction.Read();
ItemsRemaining = transList.Count;
ItemsCompleted = 0;
for (int i = 0; i < transList.Count; i++) for (int i = 0; i < transList.Count; i++)
{ {
var transType = dbSkuTransactionType.GetByTypeName(transList[i].SkuTransactionTypeName); if (transList[i].SkuTransactionTypeCode == found && !transList[i].IsProcessed)
if (transType.TypeCode == found && !transList[i].IsProcessed)
{ {
string sku = transList[i].SkuNumber; string sku = transList[i].SkuNumber;
int foundQty = transList[i].Quantity; int foundQty = transList[i].Quantity;
@@ -318,21 +355,36 @@ namespace bnhtrade.Core.Logic.Stock
// loop though list and find matching missing // loop though list and find matching missing
for (int j = 0; j < transList.Count; j++) for (int j = 0; j < transList.Count; j++)
{ {
// we have a match // update the 'lost' transaction
if (transList[j].SkuNumber == sku && !transList[j].IsProcessed && transType.TypeCode == lost) if (transList[j].SkuNumber == sku
&& transList[j].IsProcessed == false
&& transList[j].SkuTransactionTypeCode == lost)
{ {
// split transaction and break // split 'lost' transaction
if (foundQtyUnAllocated - transList[j].Quantity < 0) if (foundQtyUnAllocated - transList[j].Quantity < 0)
{ {
// create and validate clone // create 'reconciled' clone
var clone = transList[j].Clone(); var clone = transList[j].Clone();
clone.Quantity = (short)foundQtyUnAllocated;
clone.IsProcessed = true; clone.IsProcessed = true;
clone.Quantity = (short)foundQtyUnAllocated;
// modifiy and validate existing record // modifiy and validate existing record
transList[j].IsProcessed = false; transList[j].IsProcessed = false;
transList[j].Quantity = (short)(transList[j].Quantity - foundQtyUnAllocated); transList[j].Quantity = (short)(transList[j].Quantity - foundQtyUnAllocated);
foundQtyUnAllocated = 0;
// fail safe check
if (clone.IsProcessed)
{
foundQtyUnAllocated -= clone.Quantity;
}
if (transList[j].IsProcessed)
{
foundQtyUnAllocated -= transList[j].Quantity;
}
if (foundQtyUnAllocated != 0)
{
throw new Exception("Unallocated quantity should equal zero.");
}
// submitt to database // submitt to database
dbSkuTransaction.Create(clone); dbSkuTransaction.Create(clone);
@@ -354,8 +406,9 @@ namespace bnhtrade.Core.Logic.Stock
} }
} }
} }
// drop out of the 'find lost' loop
// update the found record // update the 'found' record
if (foundQty != foundQtyUnAllocated) if (foundQty != foundQtyUnAllocated)
{ {
// set isprocess = true // set isprocess = true
@@ -367,17 +420,14 @@ namespace bnhtrade.Core.Logic.Stock
// split record // split record
else if (foundQtyUnAllocated > 0) else if (foundQtyUnAllocated > 0)
{ {
throw new NotImplementedException(); // create 'reconciled' clone
// create clone
var clone = transList[i].Clone(); var clone = transList[i].Clone();
clone.Quantity -= (short)foundQtyUnAllocated;
clone.IsProcessed = true; clone.IsProcessed = true;
clone.Quantity = (short)(clone.Quantity - foundQtyUnAllocated);
// modifiy and validate existing record // modifiy existing record
transList[i].IsProcessed = false; transList[i].IsProcessed = false;
transList[i].Quantity -= (short)foundQtyUnAllocated; transList[i].Quantity = (short)foundQtyUnAllocated;
foundQtyUnAllocated = 0;
// submitt to database // submitt to database
dbSkuTransaction.Create(clone); dbSkuTransaction.Create(clone);
@@ -391,8 +441,14 @@ namespace bnhtrade.Core.Logic.Stock
} }
} }
} }
// drop out of the 'find found' loop
scope.Complete(); scope.Complete();
} }
} }
public void UnReconcileTransaction(int skuTransactionId)
{
dbSkuTransaction.DeleteJournalEntry(skuTransactionId);
}
} }
} }

View File

@@ -16,14 +16,75 @@ namespace bnhtrade.Core.Logic.Stock
{ {
this.sqlConnectionString = sqlConnectionString; this.sqlConnectionString = sqlConnectionString;
dbRead = new Data.Database.Stock.ReadSkuTransactionType(sqlConnectionString); dbRead = new Data.Database.Stock.ReadSkuTransactionType(sqlConnectionString);
InnitCache(); CacheInnit();
} }
public void InnitCache() public void CacheInnit()
{ {
cache = new List<Model.Stock.SkuTransactionType>(); cache = new List<Model.Stock.SkuTransactionType>();
} }
public void CacheFillByTypeName(List<string> typeNameList)
{
CacheInnit();
if (typeNameList == null || !typeNameList.Any())
{
return;
}
//fill cache
cache = dbRead.ByTypeName(typeNameList.Distinct().ToList());
}
public void CacheFillByTypeCode(List<string> typeCodeList)
{
CacheInnit();
if (typeCodeList == null || !typeCodeList.Any())
{
return;
}
//fill cache
cache = dbRead.ByTypeCode(typeCodeList.Distinct().ToList());
}
/// <summary>
/// Using 'SKU Transaction Type Code', adds Sku Transaction Type info to a list of Stock SKU Transactions.
/// </summary>
/// <param name="skuTransactionList">Stock SKU Transaction list</param>
/// <param name="clearCache">Force database read</param>
/// <returns>Returns false if a 'Type Code' is not found, otherwise true</returns>
public bool GetBySkuTransaction(List<Model.Stock.SkuTransaction> skuTransactionList)
{
bool allCodesFound = true;
if (skuTransactionList == null || !skuTransactionList.Any())
{
return allCodesFound;
}
CacheFillByTypeCode(skuTransactionList.Select(x => x.SkuTransactionTypeCode).Distinct().ToList());
for (int i = 0; i < skuTransactionList.Count(); i++)
{
if (skuTransactionList[i].IsSetSkuTransactionTypeCode)
{
var transType = GetByTypeCode(skuTransactionList[i].SkuTransactionTypeCode);
if (transType == null)
{
allCodesFound = false;
}
else
{
skuTransactionList[i].SkuTransactionType = transType;
}
}
}
return allCodesFound;
}
public Model.Stock.SkuTransactionType GetByTypeCode(string typeCode, bool clearCache = false) public Model.Stock.SkuTransactionType GetByTypeCode(string typeCode, bool clearCache = false)
{ {
if (string.IsNullOrWhiteSpace(typeCode)) if (string.IsNullOrWhiteSpace(typeCode))
@@ -33,7 +94,7 @@ namespace bnhtrade.Core.Logic.Stock
if (clearCache) if (clearCache)
{ {
InnitCache(); CacheInnit();
} }
else else
{ {
@@ -68,7 +129,7 @@ namespace bnhtrade.Core.Logic.Stock
if (clearCache) if (clearCache)
{ {
InnitCache(); CacheInnit();
} }
else else
{ {

View File

@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace bnhtrade.Core.Model.Stock
{
public class JournalEntry
{
public string TypeTitle { get; set; }
public int StockId { get; set; }
public int StockNumber { get; set; }
public DateTime EntryDate { get; set; }
public DateTime PostDate { get; set; }
public DateTime LastModified { get; set; }
public bool IsLocked { get; set; }
}
}

View File

@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace bnhtrade.Core.Model.Stock
{
public class JournalEntryPost : IValidatableObject
{
public int JournalPostId { get; set; }
public int StockStatusId { get; set; }
[Required()]
public string StockStatus { get; set; }
[Required()]
public int Quantity { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
throw new NotImplementedException();
var resultList = new List<ValidationResult>();
if (Quantity == 0)
{
resultList.Add(new ValidationResult("Quantity must be greater than, or less than, zero"));
}
}
}
}

View File

@@ -16,6 +16,8 @@ namespace bnhtrade.Core.Model.Stock
private int? skuTransactionId = null; private int? skuTransactionId = null;
private int? skuTransactionTypeId = null; private int? skuTransactionTypeId = null;
private int? foreignKey = null; private int? foreignKey = null;
private string skuTransactionTypeCode;
private Model.Stock.SkuTransactionType skuTransactionType;
public int SkuTransactionId public int SkuTransactionId
{ {
@@ -41,22 +43,60 @@ namespace bnhtrade.Core.Model.Stock
} }
[Required()] [Required()]
public int SkuTransactionTypeId public string SkuTransactionTypeCode
{ {
get { return skuTransactionTypeId.GetValueOrDefault(); } get
private set { skuTransactionTypeId = value; } {
if (IsSetSkuTransactionType)
{
return SkuTransactionType.TypeCode;
}
else
{
return skuTransactionTypeCode;
}
}
set
{
if (IsSetSkuTransactionType)
{
if (SkuTransactionType.TypeCode != value)
{
SkuTransactionType = null;
skuTransactionTypeCode = value;
}
}
else
{
skuTransactionTypeCode = value;
}
}
} }
public bool IsSetSkuTransactionTypeId public bool IsSetSkuTransactionTypeCode
{ {
get { return skuTransactionTypeId != null; } get { return SkuTransactionTypeCode != null; }
} }
public string SkuTransactionTypeName { get; private set; } public Model.Stock.SkuTransactionType SkuTransactionType
public bool IsSetReconcileSkuTypeName
{ {
get { return SkuTransactionTypeName != null; } get
{
return skuTransactionType;
}
set
{
if (IsSetSkuTransactionTypeCode)
{
skuTransactionTypeCode = null;
}
skuTransactionType = value;
}
}
public bool IsSetSkuTransactionType
{
get { return SkuTransactionType != null; }
} }
public int ForeignKey public int ForeignKey
@@ -126,15 +166,6 @@ namespace bnhtrade.Core.Model.Stock
get { return stockjournalId != null; } get { return stockjournalId != null; }
} }
public void SetReconcileSkuType(int reconcileSkuTypeId, string reconcileSkuTypeName)
{
if (!string.IsNullOrWhiteSpace(reconcileSkuTypeName) || reconcileSkuTypeId == 0)
{
SkuTransactionTypeId = reconcileSkuTypeId;
SkuTransactionTypeName = reconcileSkuTypeName;
}
}
public SkuTransaction Clone() public SkuTransaction Clone()
{ {
var clone = new SkuTransaction(); var clone = new SkuTransaction();
@@ -145,11 +176,11 @@ namespace bnhtrade.Core.Model.Stock
if (IsSetQuantity) { clone.Quantity = this.Quantity; } if (IsSetQuantity) { clone.Quantity = this.Quantity; }
if (IsSetReference) { clone.Reference = string.Copy(this.Reference); } if (IsSetReference) { clone.Reference = string.Copy(this.Reference); }
if (IsSetSkuNumber) { clone.SkuNumber = string.Copy(this.SkuNumber); } if (IsSetSkuNumber) { clone.SkuNumber = string.Copy(this.SkuNumber); }
if (IsSetReconcileSkuTypeName) { clone.SkuTransactionTypeName = string.Copy(this.SkuTransactionTypeName); }
if (IsSetStockJournalId) { clone.StockJournalId = this.StockJournalId; } if (IsSetStockJournalId) { clone.StockJournalId = this.StockJournalId; }
if (IsSetSkuTransactionId) { clone.SkuTransactionId = this.SkuTransactionId; } if (IsSetSkuTransactionId) { clone.SkuTransactionId = this.SkuTransactionId; }
if (IsSetSkuTransactionTypeId) { clone.SkuTransactionTypeId = this.SkuTransactionTypeId; }
if (IsSetTransactionDate) { clone.TransactionDate = this.TransactionDate; } if (IsSetTransactionDate) { clone.TransactionDate = this.TransactionDate; }
if (IsSetSkuTransactionType) { clone.SkuTransactionType = this.SkuTransactionType; }
else if (IsSetSkuTransactionTypeCode) { clone.SkuTransactionTypeCode = string.Copy(this.SkuTransactionTypeCode); }
return clone; return clone;
} }
@@ -174,10 +205,6 @@ namespace bnhtrade.Core.Model.Stock
{ {
result.Add(new ValidationResult("Stock Transaction Id is not set")); result.Add(new ValidationResult("Stock Transaction Id is not set"));
} }
if (!IsSetSkuTransactionTypeId)
{
result.Add(new ValidationResult("Stock Transaction TypeId is not set"));
}
if (IsSetStockJournalId && (!IsSetIsProcessed || IsProcessed == false)) if (IsSetStockJournalId && (!IsSetIsProcessed || IsProcessed == false))
{ {
result.Add(new ValidationResult("Stock Journal Id is set, IsProcessed must be set to true")); result.Add(new ValidationResult("Stock Journal Id is set, IsProcessed must be set to true"));

View File

@@ -46,11 +46,11 @@ namespace bnhtrade.Core.Model.Stock
public bool StockJournalEntryEnabled { get; set; } public bool StockJournalEntryEnabled { get; set; }
public int DebitStockStatusId { get; set; } public int? DebitStockStatusId { get; set; }
public string DebitStockStatus { get; set; } public string DebitStockStatus { get; set; }
public int CreditStockStatusId { get; set; } public int? CreditStockStatusId { get; set; }
public string CreditStockStatus { get; set; } public string CreditStockStatus { get; set; }
@@ -58,6 +58,6 @@ namespace bnhtrade.Core.Model.Stock
public bool FilterStockOnDateTime { get; set; } public bool FilterStockOnDateTime { get; set; }
public bool FirstInFirstOut { get; set; } public bool FirstInFirstOut { get; set; } // TODO: move FIFO rule to 'Stock Status'
} }
} }

View File

@@ -23,6 +23,7 @@ using bnhtrade.Core.AmazonAPI;
using bnhtrade.Core.Order; using bnhtrade.Core.Order;
using bnhtrade.Core.Data.AmazonMWS; using bnhtrade.Core.Data.AmazonMWS;
using bnhtrade.Core.Logic.Sku; using bnhtrade.Core.Logic.Sku;
using bnhtrade.Core.Data.Database.Log;
namespace bnhtrade.Core namespace bnhtrade.Core
{ {
@@ -2109,9 +2110,9 @@ namespace bnhtrade.Core
* level transaction scope, this nested dispose() also rolls back the all transacopes scopes it is a child of. * level transaction scope, this nested dispose() also rolls back the all transacopes scopes it is a child of.
* *
* Therefore, a consistancy check needs to be simulated in code to negate the need to rollback/dispose of a db transaction. * Therefore, a consistancy check needs to be simulated in code to negate the need to rollback/dispose of a db transaction.
* This would also have ome slight performance benefits. * This would also have some slight performance benefits.
* *
* Once you've done this, fix the SkuTransactionReconcile class: Currently it's transactionscope onyl covers updates. * Once you've done this, fix the SkuTransactionReconcile class: Currently it's transactionscope only covers updates.
* Need to set the scope to cover the intial table read (to lock the records). The issue above restricts this. * Need to set the scope to cover the intial table read (to lock the records). The issue above restricts this.
*/ */
@@ -2846,7 +2847,7 @@ namespace bnhtrade.Core
} }
} }
public static int StockTransactionTypeIdInsert(string sqlConnectionString, int stockJournalTypeId, string matchString, bool transScopeSuppress = true) public static int StockTransactionTypeIdInsert(string sqlConnectionString, int stockJournalTypeId, string typeCode, bool transScopeSuppress = true)
{ {
int transactionTypeId; int transactionTypeId;
var scopeOption = new TransactionScopeOption(); var scopeOption = new TransactionScopeOption();
@@ -2871,10 +2872,10 @@ namespace bnhtrade.Core
tblStockSkuTransactionType tblStockSkuTransactionType
WHERE WHERE
tblStockSkuTransactionType.StockJournalTypeID=@stockJournalTypeId tblStockSkuTransactionType.StockJournalTypeID=@stockJournalTypeId
AND tblStockSkuTransactionType.MatchString=@matchString; AND tblStockSkuTransactionType.TypeCode=@typeCode;
", conn)) ", conn))
{ {
cmd.Parameters.AddWithValue("@matchString", matchString); cmd.Parameters.AddWithValue("@typeCode", typeCode);
cmd.Parameters.AddWithValue("@stockJournalTypeId", stockJournalTypeId); cmd.Parameters.AddWithValue("@stockJournalTypeId", stockJournalTypeId);
object obj = cmd.ExecuteScalar(); object obj = cmd.ExecuteScalar();
@@ -2888,14 +2889,15 @@ namespace bnhtrade.Core
// insert new and retrive new value // insert new and retrive new value
using (SqlCommand cmd = new SqlCommand(@" using (SqlCommand cmd = new SqlCommand(@"
INSERT INTO tblStockSkuTransactionType INSERT INTO tblStockSkuTransactionType
( StockJournalTypeID, MatchString ) ( TypeName, StockJournalTypeID, TypeCode )
OUTPUT OUTPUT
INSERTED.StockSkuTransactionTypeID INSERTED.StockSkuTransactionTypeID
VALUES VALUES
( @stockJournalTypeId, @matchString ); ( @typeName, @stockJournalTypeId, @typeCode );
", conn)) ", conn))
{ {
cmd.Parameters.AddWithValue("@matchString", matchString); cmd.Parameters.AddWithValue("@typeName", typeCode);
cmd.Parameters.AddWithValue("@typeCode", typeCode);
cmd.Parameters.AddWithValue("@stockJournalTypeId", stockJournalTypeId); cmd.Parameters.AddWithValue("@stockJournalTypeId", stockJournalTypeId);
transactionTypeId = (int)cmd.ExecuteScalar(); transactionTypeId = (int)cmd.ExecuteScalar();
@@ -6914,6 +6916,11 @@ namespace bnhtrade.Core
int columnCount = headers.Length; int columnCount = headers.Length;
if (columnCount != 38)
{
throw new Exception("Chnages found to 'Fba Inventory Age Data' flatfile structure");
}
int index01 = Array.IndexOf(headers, "snapshot-date"); int index01 = Array.IndexOf(headers, "snapshot-date");
int index02 = Array.IndexOf(headers, "marketplace"); int index02 = Array.IndexOf(headers, "marketplace");
int index03 = Array.IndexOf(headers, "sku"); int index03 = Array.IndexOf(headers, "sku");
@@ -6947,7 +6954,8 @@ namespace bnhtrade.Core
int index31 = Array.IndexOf(headers, "Recommended sales price"); int index31 = Array.IndexOf(headers, "Recommended sales price");
int index32 = Array.IndexOf(headers, "Recommended sale duration (days)"); int index32 = Array.IndexOf(headers, "Recommended sale duration (days)");
int index33 = Array.IndexOf(headers, "Recommended Removal Quantity"); int index33 = Array.IndexOf(headers, "Recommended Removal Quantity");
int index34 = Array.IndexOf(headers, "Estimated cost savings of removal"); int index34 = Array.IndexOf(headers, "estimated-cost-savings-of-recommended-actions");
int index35 = Array.IndexOf(headers, "sell-through");
string fileRow; string fileRow;
while ((fileRow = reader.ReadLine()) != null) while ((fileRow = reader.ReadLine()) != null)
@@ -7002,7 +7010,8 @@ namespace bnhtrade.Core
string recommendedSalesPrice = Regex.Replace(items[index31], "[^.0-9]", ""); // strip currency code prefix string recommendedSalesPrice = Regex.Replace(items[index31], "[^.0-9]", ""); // strip currency code prefix
string recommendedSaleDuration = items[index32]; string recommendedSaleDuration = items[index32];
string recommendedRemovalQuantity = items[index33]; string recommendedRemovalQuantity = items[index33];
string estimatedCostSavingsOfRemoval = items[index34]; string estimatedCostSavingsOfRecommendedActions = items[index34];
string sellThrough = items[index35];
using (SqlCommand cmd = new SqlCommand(@" using (SqlCommand cmd = new SqlCommand(@"
INSERT INTO tblImportFbaInventoryAgeReport( INSERT INTO tblImportFbaInventoryAgeReport(
@@ -7012,13 +7021,15 @@ namespace bnhtrade.Core
[qty-to-be-charged-ltsf-12-mo], [projected-ltsf-12-mo], [units-shipped-last-7-days], [units-shipped-last-30-days], [qty-to-be-charged-ltsf-12-mo], [projected-ltsf-12-mo], [units-shipped-last-7-days], [units-shipped-last-30-days],
[units-shipped-last-60-days], [units-shipped-last-90-days], alert, [your-price], sales_price, lowest_price_new, [units-shipped-last-60-days], [units-shipped-last-90-days], alert, [your-price], sales_price, lowest_price_new,
lowest_price_used, [Recommended action], [Healthy Inventory Level], [Recommended sales price], lowest_price_used, [Recommended action], [Healthy Inventory Level], [Recommended sales price],
[Recommended sale duration (days)], [Recommended Removal Quantity], [Estimated cost savings of removal] ) [Recommended sale duration (days)], [Recommended Removal Quantity], [estimated-cost-savings-of-recommended-actions],
[sell-through] )
VALUES ( VALUES (
@snapshotDate, @marketplace, @sku, @fnsku, @asin, @productName, @condition, @avaliableQuantity, @snapshotDate, @marketplace, @sku, @fnsku, @asin, @productName, @condition, @avaliableQuantity,
@qtyWithRemovalsInProgress, @invAge0To90Days, @invAge91To180Days, @invAge181To270Days, @invAge271To365Days, @invAge365PlusDays, @currency, @qtyToBeChargedLtsf6Mo, @qtyWithRemovalsInProgress, @invAge0To90Days, @invAge91To180Days, @invAge181To270Days, @invAge271To365Days, @invAge365PlusDays, @currency, @qtyToBeChargedLtsf6Mo,
@projectedLtsf6Mo, @qtyToBeChargedLtsf12Mo, @projectedLtsf12Mo, @unitsShippedLast7Days, @unitsShippedLast30Days, @unitsShippedLast60Days, @unitsShippedLast90Days, @alert, @projectedLtsf6Mo, @qtyToBeChargedLtsf12Mo, @projectedLtsf12Mo, @unitsShippedLast7Days, @unitsShippedLast30Days, @unitsShippedLast60Days, @unitsShippedLast90Days, @alert,
@yourPrice, @salesPrice, @lowestPriceNew, @lowestPriceUsed, @recommendedAction, @healthyInventoryLevel, @recommendedSalesPrice, @recommendedSaleDuration, @yourPrice, @salesPrice, @lowestPriceNew, @lowestPriceUsed, @recommendedAction, @healthyInventoryLevel, @recommendedSalesPrice,
@recommendedRemovalQuantity, @estimatedCostSavingsOfRemoval ); @recommendedSaleDuration, @recommendedRemovalQuantity, @estimatedCostSavingsOfRecommendedActions,
@sellThrough );
", sqlConn)) ", sqlConn))
{ {
// add parameters // add parameters
@@ -7121,8 +7132,11 @@ namespace bnhtrade.Core
if (recommendedRemovalQuantity.Length == 0) { cmd.Parameters.AddWithValue("@recommendedRemovalQuantity", DBNull.Value); } if (recommendedRemovalQuantity.Length == 0) { cmd.Parameters.AddWithValue("@recommendedRemovalQuantity", DBNull.Value); }
else { cmd.Parameters.AddWithValue("@recommendedRemovalQuantity", int.Parse(recommendedRemovalQuantity)); } else { cmd.Parameters.AddWithValue("@recommendedRemovalQuantity", int.Parse(recommendedRemovalQuantity)); }
if (estimatedCostSavingsOfRemoval.Length == 0) { cmd.Parameters.AddWithValue("@estimatedCostSavingsOfRemoval", DBNull.Value); } if (estimatedCostSavingsOfRecommendedActions.Length == 0) { cmd.Parameters.AddWithValue("@estimatedCostSavingsOfRemoval", DBNull.Value); }
else { cmd.Parameters.AddWithValue("@estimatedCostSavingsOfRemoval", decimal.Parse(estimatedCostSavingsOfRemoval)); } else { cmd.Parameters.AddWithValue("@estimatedCostSavingsOfRecommendedActions", decimal.Parse(estimatedCostSavingsOfRecommendedActions)); }
if (sellThrough.Length == 0) { cmd.Parameters.AddWithValue("@sellThrough", DBNull.Value); }
else { cmd.Parameters.AddWithValue("@sellThrough", decimal.Parse(sellThrough)); }
// execute the query // execute the query
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();

View File

@@ -115,7 +115,7 @@
<Compile Include="Logic\Validate\AccountCode.cs" /> <Compile Include="Logic\Validate\AccountCode.cs" />
<Compile Include="Logic\Validate\CurrencyCode.cs" /> <Compile Include="Logic\Validate\CurrencyCode.cs" />
<Compile Include="Logic\Validate\SalesInvoice.cs" /> <Compile Include="Logic\Validate\SalesInvoice.cs" />
<Compile Include="Logic\AmazonFBAInbound\UpdateDatabaseShipmentInfo.cs" /> <Compile Include="Logic\AmazonFBAInbound\ShipmentInfoPersistanceUpdate.cs" />
<Compile Include="Data\Database\Export\CreateSalesInvoice.cs" /> <Compile Include="Data\Database\Export\CreateSalesInvoice.cs" />
<Compile Include="Logic\Export\AmazonSubmitFile.cs" /> <Compile Include="Logic\Export\AmazonSubmitFile.cs" />
<Compile Include="Logic\Export\AmazonSubmitFileStatus.cs" /> <Compile Include="Logic\Export\AmazonSubmitFileStatus.cs" />
@@ -160,6 +160,8 @@
<Compile Include="Model\Sku\Price\PriceInfo.cs" /> <Compile Include="Model\Sku\Price\PriceInfo.cs" />
<Compile Include="Model\Sku\Price\SkuPriceParameter.cs" /> <Compile Include="Model\Sku\Price\SkuPriceParameter.cs" />
<Compile Include="Model\Sku\SkuConditionInfo.cs" /> <Compile Include="Model\Sku\SkuConditionInfo.cs" />
<Compile Include="Model\Stock\JournalEntry.cs" />
<Compile Include="Model\Stock\JournalEntryPost.cs" />
<Compile Include="Model\Stock\SkuTransactionType.cs" /> <Compile Include="Model\Stock\SkuTransactionType.cs" />
<Compile Include="Model\Stock\SkuTransaction.cs" /> <Compile Include="Model\Stock\SkuTransaction.cs" />
<Compile Include="Test\Account\Account.cs" /> <Compile Include="Test\Account\Account.cs" />

View File

@@ -291,7 +291,7 @@ namespace bnhtradeScheduledTasks
Console.WriteLine("<6> Test SKU"); Console.WriteLine("<6> Test SKU");
Console.WriteLine("<7> Test xxxxxxx"); Console.WriteLine("<7> Test xxxxxxx");
Console.WriteLine("<8> Test xxxxxxx"); Console.WriteLine("<8> Test xxxxxxx");
Console.WriteLine("<9> Detele Sku Transaction"); Console.WriteLine("<9> Detele Sku Transaction 'n'");
Console.WriteLine(); Console.WriteLine();
Console.WriteLine("<0> Back"); Console.WriteLine("<0> Back");
Console.WriteLine(""); Console.WriteLine("");
@@ -386,7 +386,7 @@ namespace bnhtradeScheduledTasks
{ {
Console.Clear(); Console.Clear();
new bnhtrade.Core.Logic.Stock.SkuTransactionPersistance(sqlConnectionString).DeleteJournalEntry(80774); new bnhtrade.Core.Logic.Stock.SkuTransactionPersistance(sqlConnectionString).DeleteJournalEntry(32731);
Console.WriteLine("Done"); Console.WriteLine("Done");
Console.WriteLine("Complete, press any key to continue..."); Console.WriteLine("Complete, press any key to continue...");