mirror of
https://github.com/stokebob/bnhtrade.git
synced 2026-03-19 06:27:15 +00:00
Feature repricing min max (#10)
amazon settlement import/export improvements
This commit is contained in:
@@ -2,13 +2,13 @@
|
||||
@set dllpath=%batchpath%
|
||||
::bnhtrade Database Client\bin\Release\
|
||||
|
||||
@copy "%dllpath%bnhtrade.Core.dll" "%SYSTEMROOT%\SysWOW64\bnhtrade.Core.dll"
|
||||
rem @copy "%dllpath%bnhtrade.Core.dll" "%SYSTEMROOT%\SysWOW64\bnhtrade.Core.dll"
|
||||
@copy "%dllpath%bnhtradeCOM.dll" "%SYSTEMROOT%\SysWOW64\bnhtradeCOM.dll"
|
||||
@copy "%dllpath%ABrain.AmazonMWS.dll" "%SYSTEMROOT%\SysWOW64\ABrain.AmazonMWS.dll"
|
||||
rem @copy "%dllpath%ABrain.AmazonMWS.dll" "%SYSTEMROOT%\SysWOW64\ABrain.AmazonMWS.dll"
|
||||
|
||||
@copy "%dllpath%bnhtrade.Core.dll" "%SYSTEMROOT%\System32\bnhtrade.Core.dll"
|
||||
rem @copy "%dllpath%bnhtrade.Core.dll" "%SYSTEMROOT%\System32\bnhtrade.Core.dll"
|
||||
@copy "%dllpath%bnhtradeCOM.dll" "%SYSTEMROOT%\System32\bnhtradeCOM.dll"
|
||||
@copy "%dllpath%ABrain.AmazonMWS.dll" "%SYSTEMROOT%\System32\ABrain.AmazonMWS.dll"
|
||||
rem @copy "%dllpath%ABrain.AmazonMWS.dll" "%SYSTEMROOT%\System32\ABrain.AmazonMWS.dll"
|
||||
|
||||
@c:
|
||||
@cd\Windows\Microsoft.NET\Framework\v4.*
|
||||
|
||||
@@ -8,18 +8,18 @@ rem regasm.exe /u "%SYSTEMROOT%\System32\bnhtrade.Core.dll"
|
||||
regasm.exe /u "%SYSTEMROOT%\SysWOW64\bnhtradeCOM.dll"
|
||||
rem regasm.exe /u "%SYSTEMROOT%\SysWOW64\ABrain.AmazonMWS.dll"
|
||||
cd
|
||||
@del /q "%SYSTEMROOT%\SysWOW64\bnhtrade.Core.dll"
|
||||
rem @del /q "%SYSTEMROOT%\SysWOW64\bnhtrade.Core.dll"
|
||||
rem @del /q "%SYSTEMROOT%\SysWOW64\bnhtrade.Core.tlb"
|
||||
@del /q "%SYSTEMROOT%\SysWOW64\bnhtradeCOM.dll"
|
||||
@del /q "%SYSTEMROOT%\SysWOW64\bnhtradeCOM.tlb"
|
||||
@del /q "%SYSTEMROOT%\SysWOW64\ABrain.AmazonMWS.dll"
|
||||
rem @del /q "%SYSTEMROOT%\SysWOW64\bnhtradeCOM.tlb"
|
||||
rem @del /q "%SYSTEMROOT%\SysWOW64\ABrain.AmazonMWS.dll"
|
||||
rem @del /q "%SYSTEMROOT%\SysWOW64\ABrain.AmazonMWS.tlb"
|
||||
|
||||
@del /q "%SYSTEMROOT%\System32\bnhtrade.Core.dll"
|
||||
rem @del /q "%SYSTEMROOT%\System32\bnhtrade.Core.dll"
|
||||
rem @del /q "%SYSTEMROOT%\System32\bnhtrade.Core.tlb"
|
||||
@del /q "%SYSTEMROOT%\System32\bnhtradeCOM.dll"
|
||||
@del /q "%SYSTEMROOT%\System32\bnhtradeCOM.tlb"
|
||||
@del /q "%SYSTEMROOT%\System32\ABrain.AmazonMWS.dll"
|
||||
rem @del /q "%SYSTEMROOT%\System32\bnhtradeCOM.tlb"
|
||||
rem @del /q "%SYSTEMROOT%\System32\ABrain.AmazonMWS.dll"
|
||||
rem @del /q "%SYSTEMROOT%\System32\ABrain.AmazonMWS.tlb"
|
||||
|
||||
@echo.
|
||||
|
||||
67
src/bnhtrade.ComTypeLib/ILMerge.props
Normal file
67
src/bnhtrade.ComTypeLib/ILMerge.props
Normal file
@@ -0,0 +1,67 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<!-- -->
|
||||
<!-- ILMerge project-specific settings. Almost never need to be set explicitly. -->
|
||||
<!-- for details, see http://research.microsoft.com/en-us/people/mbarnett/ilmerge.aspx -->
|
||||
<!-- -->
|
||||
<!-- *** set this file to Type=None, CopyToOutput=Never *** -->
|
||||
|
||||
<!-- If True, all copy local dependencies will also be merged from referenced projects whether they are referenced in the current project explicitly or not -->
|
||||
<ILMergeTransitive>true</ILMergeTransitive>
|
||||
|
||||
<!-- Extra ILMerge library paths (semicolon-separated). Dont put your package dependencies here, they will be added automagically -->
|
||||
<ILMergeLibraryPath></ILMergeLibraryPath>
|
||||
|
||||
<!-- The solution NuGet package directory if not standard 'SOLUTION\packages' -->
|
||||
<ILMergePackagesPath></ILMergePackagesPath>
|
||||
|
||||
<!-- The merge order file name if differs from standard 'ILMergeOrder.txt' -->
|
||||
<ILMergeOrderFile></ILMergeOrderFile>
|
||||
|
||||
<!-- The strong key file name if not specified in the project -->
|
||||
<ILMergeKeyFile></ILMergeKeyFile>
|
||||
|
||||
<!-- The assembly version if differs for the version of the main assembly -->
|
||||
<ILMergeAssemblyVersion></ILMergeAssemblyVersion>
|
||||
|
||||
<!-- added in Version 1.0.4 -->
|
||||
<ILMergeFileAlignment></ILMergeFileAlignment>
|
||||
|
||||
<!-- added in Version 1.0.4, default=none -->
|
||||
<ILMergeAllowDuplicateType></ILMergeAllowDuplicateType>
|
||||
|
||||
<!-- If the <see cref="CopyAttributes"/> is also set, any assembly-level attributes names that have the same type are copied over into the target assembly -->
|
||||
<ILMergeAllowMultipleAssemblyLevelAttributes></ILMergeAllowMultipleAssemblyLevelAttributes>
|
||||
|
||||
<!-- See ILMerge documentation -->
|
||||
<ILMergeAllowZeroPeKind></ILMergeAllowZeroPeKind>
|
||||
|
||||
<!-- The assembly level attributes of each input assembly are copied over into the target assembly -->
|
||||
<ILMergeCopyAttributes></ILMergeCopyAttributes>
|
||||
|
||||
<!-- Creates a .pdb file for the output assembly and merges into it any .pdb files found for input assemblies, default=true -->
|
||||
<ILMergeDebugInfo>false</ILMergeDebugInfo>
|
||||
|
||||
<!-- Target assembly will be delay signed -->
|
||||
<ILMergeDelaySign></ILMergeDelaySign>
|
||||
|
||||
<!-- Types in assemblies other than the primary assembly have their visibility modified -->
|
||||
<ILMergeInternalize></ILMergeInternalize>
|
||||
|
||||
<!-- The path name of the file that will be used to identify types that are not to have their visibility modified -->
|
||||
<ILMergeInternalizeExcludeFile></ILMergeInternalizeExcludeFile>
|
||||
|
||||
<!-- XML documentation files are merged to produce an XML documentation file for the target assembly -->
|
||||
<ILMergeXmlDocumentation></ILMergeXmlDocumentation>
|
||||
|
||||
<!-- External assembly references in the manifest of the target assembly will use full public keys (false) or public key tokens (true, default value) -->
|
||||
<ILMergePublicKeyTokens></ILMergePublicKeyTokens>
|
||||
|
||||
<!-- Types with the same name are all merged into a single type in the target assembly -->
|
||||
<ILMergeUnionMerge></ILMergeUnionMerge>
|
||||
|
||||
<!-- The version of the target framework, default 40 (works for 45 too) -->
|
||||
<ILTargetPlatform></ILTargetPlatform>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
4
src/bnhtrade.ComTypeLib/ILMergeOrder.txt
Normal file
4
src/bnhtrade.ComTypeLib/ILMergeOrder.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
# this file contains the partial list of the merged assemblies in the merge order
|
||||
# you can fill it from the obj\CONFIG\PROJECT.ilmerge generated on every build
|
||||
# and finetune merge order to your satisfaction
|
||||
|
||||
@@ -64,22 +64,24 @@ namespace bnhtrade.ComTypeLib
|
||||
|
||||
public string ProductCompetitivePriceGet(int productId, int conditionId, ConnectionCredential sqlConnCred)
|
||||
{
|
||||
var request = new Core.Product.ProductQuery();
|
||||
(decimal? price, DateTime? priceDate) result = request.ProductCompetitivePriceGet(sqlConnCred.ConnectionString, productId, conditionId);
|
||||
if (result.price == null || result.priceDate == null)
|
||||
var compPrice = new Core.Logic.Product.GetCompetitivePrice(sqlConnCred.ConnectionString).Execute(productId, conditionId);
|
||||
|
||||
if (compPrice == null)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
else
|
||||
{
|
||||
DateTime priceDate2 = result.priceDate.Value;
|
||||
return result.price.ToString() + ";" + priceDate2.ToOADate();
|
||||
return compPrice.Price + ";" + compPrice.PriceDatetime.ToOADate();
|
||||
}
|
||||
}
|
||||
public int ProductCompetitivePriceSet(int productId, int conditionId, [MarshalAs(UnmanagedType.Currency)] decimal price, bool isBuyBoxPrice, DateTime priceDate, ConnectionCredential sqlConnCred)
|
||||
|
||||
public int ProductCompetitivePriceSet(int productId, int conditionId, [MarshalAs(UnmanagedType.Currency)] decimal price, bool isBuyBoxPrice, DateTime priceDateLocal, ConnectionCredential sqlConnCred)
|
||||
{
|
||||
var request = new Core.Product.ProductQuery();
|
||||
return request.ProductCompetitivePriceSet(sqlConnCred.ConnectionString, productId, conditionId, price, isBuyBoxPrice, priceDate);
|
||||
priceDateLocal = DateTime.SpecifyKind(priceDateLocal, DateTimeKind.Local);
|
||||
|
||||
return new Core.Data.Database.Product.CreateCompetitivePrice(sqlConnCred.ConnectionString)
|
||||
.ProductCompetitivePriceSet(productId, conditionId, price, isBuyBoxPrice, priceDateLocal);
|
||||
}
|
||||
|
||||
public void ProductUpdateAmazonEstimateFee(ConnectionCredential sqlConnCred, object inputList)
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace bnhtrade.ComTypeLib
|
||||
{
|
||||
entryDate = DateTime.SpecifyKind(entryDate, DateTimeKind.Utc);
|
||||
|
||||
return Core.Stock.StockJournal.StockReallocateByStockId(sqlConnCred.ConnectionString, 4, stockId, quantity, debitStatusId, creditStatusId, entryDate);
|
||||
return new Core.Logic.Stock.Reallocate(sqlConnCred.ConnectionString).StockReallocateByStockId(4, stockId, quantity, debitStatusId, creditStatusId, entryDate);
|
||||
}
|
||||
|
||||
public void StockJournalDelete(ConnectionCredential sqlConnCred, int stockJournalId)
|
||||
@@ -71,10 +71,11 @@ namespace bnhtrade.ComTypeLib
|
||||
|
||||
public object ReconcileStockTransactions(ConnectionCredential sqlConnCred)
|
||||
{
|
||||
var request = new Core.Stock.StockReconciliation();
|
||||
var result = new Core.Stock.StockReconciliation.ReconcileStockTransactionsResult();
|
||||
//var request = new Core.Stock.StockReconciliation();
|
||||
//var result = new Core.Stock.StockReconciliation.ReconcileStockTransactionsResult();
|
||||
|
||||
result = request.ReconcileStockTransactions(sqlConnCred.ConnectionString, false);
|
||||
var result = new Core.Logic.Stock.SkuTransactionReconcile(sqlConnCred.ConnectionString);
|
||||
result.ReconcileStockTransactions(false);
|
||||
|
||||
//ReconcileStockTransactionsResult returnObject = new ReconcileStockTransactionsResult();
|
||||
|
||||
@@ -106,8 +107,8 @@ namespace bnhtrade.ComTypeLib
|
||||
object[] returnArray = new object[7];
|
||||
returnArray[0] = result.ReconciliationComplete;
|
||||
returnArray[1] = result.ProgressMessage;
|
||||
returnArray[2] = result.StockTransactionId;
|
||||
returnArray[3] = result.StockTransactionTypeId;
|
||||
returnArray[2] = result.CurrentTransactionId;
|
||||
returnArray[3] = result.CurrentTransactionTypeId;
|
||||
returnArray[4] = result.LastItemDateTime;
|
||||
returnArray[5] = result.ItemsCompleted;
|
||||
returnArray[6] = result.ItemsRemaining;
|
||||
|
||||
11
src/bnhtrade.ComTypeLib/app.config
Normal file
11
src/bnhtrade.ComTypeLib/app.config
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.2.0.1" newVersion="4.2.0.1" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
</configuration>
|
||||
@@ -1,5 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\packages\MSBuild.ILMerge.Task.1.1.3\build\MSBuild.ILMerge.Task.props" Condition="Exists('..\..\packages\MSBuild.ILMerge.Task.1.1.3\build\MSBuild.ILMerge.Task.props')" />
|
||||
<Import Project="..\..\packages\ILMerge.3.0.29\build\ILMerge.props" Condition="Exists('..\..\packages\ILMerge.3.0.29\build\ILMerge.props')" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
@@ -13,6 +15,8 @@
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
<TargetFrameworkProfile />
|
||||
<NuGetPackageImportStamp>
|
||||
</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@@ -30,6 +34,7 @@
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<RunPostBuildEvent>Always</RunPostBuildEvent>
|
||||
@@ -54,13 +59,20 @@
|
||||
<Compile Include="Stock\Stock.cs" />
|
||||
<Compile Include="Utility\LoadComObjextIntoStringArray.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
<None Include="ILMerge.props" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\bnhtrade.Core\bnhtrade.Core.csproj">
|
||||
<Project>{339d7413-3da7-46ea-a55c-255a9a6b95eb}</Project>
|
||||
<Name>bnhtrade.Core</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="ILMergeOrder.txt" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
<PreBuildEvent>
|
||||
@@ -71,4 +83,13 @@
|
||||
copy "$(SolutionDir)build\bnhtrade.ComTypeLib.RegAsmRefresh.bat" "$(TargetDir)bnhtrade.ComTypeLib.RegAsmRefresh.bat"
|
||||
copy "$(SolutionDir)build\bnhtrade.ComTypeLib.RegAsmUninstall.bat" "$(TargetDir)bnhtrade.ComTypeLib.RegAsmUninstall.bat"</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\packages\ILMerge.3.0.29\build\ILMerge.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\ILMerge.3.0.29\build\ILMerge.props'))" />
|
||||
<Error Condition="!Exists('..\..\packages\MSBuild.ILMerge.Task.1.1.3\build\MSBuild.ILMerge.Task.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\MSBuild.ILMerge.Task.1.1.3\build\MSBuild.ILMerge.Task.props'))" />
|
||||
<Error Condition="!Exists('..\..\packages\MSBuild.ILMerge.Task.1.1.3\build\MSBuild.ILMerge.Task.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\MSBuild.ILMerge.Task.1.1.3\build\MSBuild.ILMerge.Task.targets'))" />
|
||||
</Target>
|
||||
<Import Project="..\..\packages\MSBuild.ILMerge.Task.1.1.3\build\MSBuild.ILMerge.Task.targets" Condition="Exists('..\..\packages\MSBuild.ILMerge.Task.1.1.3\build\MSBuild.ILMerge.Task.targets')" />
|
||||
</Project>
|
||||
5
src/bnhtrade.ComTypeLib/packages.config
Normal file
5
src/bnhtrade.ComTypeLib/packages.config
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="ILMerge" version="3.0.29" targetFramework="net471" />
|
||||
<package id="MSBuild.ILMerge.Task" version="1.1.3" targetFramework="net471" />
|
||||
</packages>
|
||||
@@ -1,15 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<configSections>
|
||||
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<section name="e2A_Client.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false"/>
|
||||
<section name="e2A_Client.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
|
||||
</sectionGroup>
|
||||
</configSections>
|
||||
<connectionStrings>
|
||||
<add name="e2A_Client.Properties.Settings.ConnectionString" connectionString="Data Source=SQL-Server;Initial Catalog=e2A;Persist Security Info=True;User ID=e2A Client;Password=eSYH4EYoK6Guc5KIclhgFDlGc4;MultipleActiveResultSets=true" providerName="System.Data.SqlClient"/>
|
||||
<add name="e2A_Client.Properties.Settings.ConnectionString" connectionString="Data Source=SQL-Server;Initial Catalog=e2A;Persist Security Info=True;User ID=e2A Client;Password=eSYH4EYoK6Guc5KIclhgFDlGc4;MultipleActiveResultSets=true" providerName="System.Data.SqlClient" />
|
||||
</connectionStrings>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.1"/>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.1" />
|
||||
</startup>
|
||||
<applicationSettings>
|
||||
<e2A_Client.Properties.Settings>
|
||||
@@ -21,4 +21,12 @@
|
||||
</setting>
|
||||
</e2A_Client.Properties.Settings>
|
||||
</applicationSettings>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.2.0.1" newVersion="4.2.0.1" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
</configuration>
|
||||
|
||||
@@ -8,12 +8,18 @@ namespace bnhtrade.Core.Data.AmazonMWS
|
||||
{
|
||||
public class CredentialMws
|
||||
{
|
||||
public string merchantId { get { return "A3RUYNKLWWM5KW"; } }
|
||||
public string marketPlaceId { get { return "A1F83G8C2ARO7P"; } } // Amazon.co.uk
|
||||
public string accessKeyId { get { return "AKIAJU45WSYVINEN45UA"; } }
|
||||
public string secretAccessKey { get { return "cpS3HnTYDIVxAPSxaJwCwUbeH6PGPnpij5Un5bWI"; } }
|
||||
public string applicationName { get { return "bnhtrade.Core"; } }
|
||||
public string applicationVersion { get { return "0.1"; } }
|
||||
public string serviceURL { get { return "https://mws.amazonservices.co.uk"; } }
|
||||
public string MerchantId { get { return "A3RUYNKLWWM5KW"; } }
|
||||
|
||||
public string MarketPlaceIdUK { get { return "A1F83G8C2ARO7P"; } } // Amazon.co.uk
|
||||
|
||||
public string AccessKeyId { get { return "AKIAJU45WSYVINEN45UA"; } }
|
||||
|
||||
public string SecretAccessKey { get { return "cpS3HnTYDIVxAPSxaJwCwUbeH6PGPnpij5Un5bWI"; } }
|
||||
|
||||
public string ApplicationName { get { return "bnhtrade.Core"; } }
|
||||
|
||||
public string ApplicationVersion { get { return "0.1"; } }
|
||||
|
||||
public string ServiceURL { get { return "https://mws.amazonservices.co.uk"; } }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace bnhtrade.Core.Data.AmazonMWS.FBAInbound
|
||||
return LastUpdatedBefore != null;
|
||||
}
|
||||
|
||||
public List<Model.AmazonFBAInbound.ShipmentItemInfo> GetByAmazonShipmentId(string amazonShipmentId)
|
||||
public List<Model.AmazonFba.ShipmentItemInfo> GetByAmazonShipmentId(string amazonShipmentId)
|
||||
{
|
||||
// checks
|
||||
if (amazonShipmentId.Length < 9)
|
||||
@@ -43,7 +43,7 @@ namespace bnhtrade.Core.Data.AmazonMWS.FBAInbound
|
||||
return ListInboundShipmentItemsGet(request);
|
||||
}
|
||||
|
||||
public List<Model.AmazonFBAInbound.ShipmentItemInfo> GetByDates(DateTime lastUpdatedAfter, DateTime lastUpdatedBefore)
|
||||
public List<Model.AmazonFba.ShipmentItemInfo> GetByDates(DateTime lastUpdatedAfter, DateTime lastUpdatedBefore)
|
||||
{
|
||||
//checks
|
||||
if (lastUpdatedAfter >= lastUpdatedBefore)
|
||||
@@ -61,7 +61,7 @@ namespace bnhtrade.Core.Data.AmazonMWS.FBAInbound
|
||||
return ListInboundShipmentItemsGet(request);
|
||||
}
|
||||
|
||||
private List<Model.AmazonFBAInbound.ShipmentItemInfo> ListInboundShipmentItemsGet(ListInboundShipmentItemsRequest request)
|
||||
private List<Model.AmazonFba.ShipmentItemInfo> ListInboundShipmentItemsGet(ListInboundShipmentItemsRequest request)
|
||||
{
|
||||
// variables
|
||||
int mwsPollFrequency = 500;
|
||||
@@ -72,7 +72,7 @@ namespace bnhtrade.Core.Data.AmazonMWS.FBAInbound
|
||||
if (!request.IsSetSellerId())
|
||||
{
|
||||
var cred = new AmazonMWS.CredentialMws();
|
||||
request.SellerId = cred.merchantId;
|
||||
request.SellerId = cred.MerchantId;
|
||||
}
|
||||
|
||||
// checks
|
||||
@@ -108,7 +108,7 @@ namespace bnhtrade.Core.Data.AmazonMWS.FBAInbound
|
||||
}
|
||||
|
||||
// create the return list
|
||||
var returnList = new List<Model.AmazonFBAInbound.ShipmentItemInfo>();
|
||||
var returnList = new List<Model.AmazonFba.ShipmentItemInfo>();
|
||||
|
||||
// check a result was returned, return empty list on no results
|
||||
if (!result.IsSetItemData())
|
||||
@@ -171,7 +171,7 @@ namespace bnhtrade.Core.Data.AmazonMWS.FBAInbound
|
||||
// load data set into returnList
|
||||
foreach (var item in infoList)
|
||||
{
|
||||
var returnItem = new Model.AmazonFBAInbound.ShipmentItemInfo();
|
||||
var returnItem = new Model.AmazonFba.ShipmentItemInfo();
|
||||
returnItem.AmazonShipmentId = item.ShipmentId;
|
||||
returnItem.SKUNumber = item.SellerSKU;
|
||||
returnItem.AmazonFNSKU = item.FulfillmentNetworkSKU;
|
||||
|
||||
@@ -14,31 +14,37 @@ namespace bnhtrade.Core.Data.AmazonMWS.FBAInbound
|
||||
/// List of Shipment Status' to return. Default is all status' returned.
|
||||
/// </summary>
|
||||
public List<string> ShipmentStatusList { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// List of Shipment Id to return.
|
||||
/// </summary>
|
||||
public List<string> ShipmentIdList { get; set; }
|
||||
|
||||
public DateTime LastUpdatedAfter { get; set; }
|
||||
|
||||
public DateTime LastUpdatedBefore { get; set; }
|
||||
|
||||
public bool IsSetShipmentStatusList()
|
||||
{
|
||||
return ShipmentStatusList != null;
|
||||
}
|
||||
|
||||
public bool IsSetShipmentIdList()
|
||||
{
|
||||
return ShipmentIdList != null;
|
||||
}
|
||||
|
||||
public bool IsSetLastUpdatedAfter()
|
||||
{
|
||||
return LastUpdatedAfter != null;
|
||||
}
|
||||
|
||||
public bool IsSetLastUpdatedBefore()
|
||||
{
|
||||
return LastUpdatedBefore != null;
|
||||
}
|
||||
|
||||
public List<Core.Model.AmazonFBAInbound.ShipmentInfo> GetShipmentInfo()
|
||||
public List<Core.Model.AmazonFba.ShipmentInfo> GetShipmentInfo()
|
||||
{
|
||||
// variables
|
||||
int mwsPollFrequency = 500; // restore rate of two requests every second
|
||||
@@ -72,7 +78,7 @@ namespace bnhtrade.Core.Data.AmazonMWS.FBAInbound
|
||||
var request = new ListInboundShipmentsRequest();
|
||||
|
||||
var cred = new AmazonMWS.CredentialMws();
|
||||
request.SellerId = cred.merchantId;
|
||||
request.SellerId = cred.MerchantId;
|
||||
|
||||
// add shipment status to request
|
||||
if (!IsSetShipmentStatusList() && !IsSetShipmentIdList())
|
||||
@@ -204,12 +210,12 @@ namespace bnhtrade.Core.Data.AmazonMWS.FBAInbound
|
||||
}
|
||||
|
||||
// build return value
|
||||
var returnItem = new List<Core.Model.AmazonFBAInbound.ShipmentInfo>();
|
||||
var returnItem = new List<Core.Model.AmazonFba.ShipmentInfo>();
|
||||
//var lastUpdated = infoList.
|
||||
foreach( InboundShipmentInfo item in infoList)
|
||||
{
|
||||
var listItem = new Core.Model.AmazonFBAInbound.ShipmentInfo();
|
||||
listItem.AmazonShipmentId = item.ShipmentId;
|
||||
var listItem = new Core.Model.AmazonFba.ShipmentInfo();
|
||||
listItem.FbaShipmentId = item.ShipmentId;
|
||||
listItem.DestinationFulfillmentCenterId = item.DestinationFulfillmentCenterId;
|
||||
listItem.ShipmentName = item.ShipmentName;
|
||||
listItem.ShipmentStatus = item.ShipmentStatus;
|
||||
|
||||
135
src/bnhtrade.Core/Data/AmazonMWS/Feeds/GetFeedSubmissions.cs
Normal file
135
src/bnhtrade.Core/Data/AmazonMWS/Feeds/GetFeedSubmissions.cs
Normal file
@@ -0,0 +1,135 @@
|
||||
using MarketplaceWebService;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.AmazonMWS.Feeds
|
||||
{
|
||||
public class GetFeedSubmissions
|
||||
{
|
||||
private Logic.Log.LogEvent logEvent = new Logic.Log.LogEvent();
|
||||
|
||||
public List<string> FeedSubmissionIdList { get; set; } = new List<string>();
|
||||
|
||||
public int MaxCount { get; set; } = 100;
|
||||
|
||||
public List<MarketplaceWebService.Model.FeedSubmissionInfo> Invoke()
|
||||
{
|
||||
//build the request
|
||||
var cred = new AmazonMWS.CredentialMws();
|
||||
var request = new MarketplaceWebService.Model.GetFeedSubmissionListRequest();
|
||||
request.MaxCount = MaxCount;
|
||||
request.Merchant = cred.MerchantId;
|
||||
|
||||
if (FeedSubmissionIdList.Any())
|
||||
{
|
||||
var idList = new MarketplaceWebService.Model.IdList();
|
||||
idList.Id = FeedSubmissionIdList;
|
||||
request.FeedSubmissionIdList = idList;
|
||||
}
|
||||
|
||||
string error = "GetFeedSubmissionList failed: ";
|
||||
string errorLong = null;
|
||||
int i = 0;
|
||||
int loopMax = 100;
|
||||
|
||||
try
|
||||
{
|
||||
var service = new Data.AmazonMWS.Service().MarketPlaceWeb;
|
||||
|
||||
// set the return list
|
||||
var feedInfoList = new List<MarketplaceWebService.Model.FeedSubmissionInfo>();
|
||||
|
||||
string nextToken = null;
|
||||
while (i < loopMax)
|
||||
{
|
||||
i++;
|
||||
try
|
||||
{
|
||||
if (nextToken == null)
|
||||
{
|
||||
var responseList = service.GetFeedSubmissionList(request);
|
||||
if (responseList.IsSetGetFeedSubmissionListResult())
|
||||
{
|
||||
var getFeedListResult = responseList.GetFeedSubmissionListResult;
|
||||
feedInfoList = getFeedListResult.FeedSubmissionInfo;
|
||||
if (getFeedListResult.HasNext)
|
||||
{
|
||||
nextToken = getFeedListResult.NextToken;
|
||||
}
|
||||
else
|
||||
{
|
||||
return feedInfoList;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errorLong = responseList.ToXML();
|
||||
throw new Exception("FeedSubmissionListResult was not set");
|
||||
}
|
||||
if (nextToken == null)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
var requestToken = new MarketplaceWebService.Model.GetFeedSubmissionListByNextTokenRequest();
|
||||
requestToken.NextToken = nextToken;
|
||||
requestToken.Merchant = cred.MerchantId;
|
||||
|
||||
var responseList = service.GetFeedSubmissionListByNextToken(requestToken);
|
||||
if (responseList.IsSetGetFeedSubmissionListByNextTokenResult())
|
||||
{
|
||||
var getFeedListResult = responseList.GetFeedSubmissionListByNextTokenResult;
|
||||
feedInfoList.AddRange(getFeedListResult.FeedSubmissionInfo);
|
||||
if (getFeedListResult.HasNext)
|
||||
{
|
||||
nextToken = getFeedListResult.NextToken;
|
||||
}
|
||||
else
|
||||
{
|
||||
return feedInfoList;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errorLong = responseList.ToXML();
|
||||
throw new Exception("FeedSubmissionListResult was not set");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (MarketplaceWebServiceException ex) when (ex.ErrorCode == "RequestThrottled")
|
||||
{
|
||||
if (nextToken == null) { MiscFunction.MwsThrottleWait(60); } // 10 intial requests, 1 restore every 45 seconds
|
||||
else { MiscFunction.MwsThrottleWait(5); } // 30 intial requests, 1 restore every 2 seconds
|
||||
}
|
||||
catch (MarketplaceWebServiceException ex)
|
||||
{
|
||||
errorLong = "Caught Exception: " + ex.Message +
|
||||
"\r\nResponse Status Code: " + ex.StatusCode +
|
||||
"\r\nError Code: " + ex.ErrorCode +
|
||||
"\r\nError Type: " + ex.ErrorType +
|
||||
"\r\nRequest ID: " + ex.RequestId +
|
||||
"\r\nResponseHeaderMetadata: " + ex.ResponseHeaderMetadata +
|
||||
"\r\nXML:\r\n" + ex.XML;
|
||||
|
||||
throw new Exception("MarketplaceWebServiceException");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
error = error + ex.Message;
|
||||
}
|
||||
|
||||
// should never get here
|
||||
if (i == loopMax)
|
||||
error += "Timeout";
|
||||
|
||||
logEvent.LogError(error, errorLong);
|
||||
throw new Exception(error);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
120
src/bnhtrade.Core/Data/AmazonMWS/Feeds/SubmitFeed.cs
Normal file
120
src/bnhtrade.Core/Data/AmazonMWS/Feeds/SubmitFeed.cs
Normal file
@@ -0,0 +1,120 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using MarketplaceWebService;
|
||||
using bnhtrade.Core.Logic;
|
||||
|
||||
namespace bnhtrade.Core.Data.AmazonMWS.Feeds
|
||||
{
|
||||
public class SubmitFeed
|
||||
{
|
||||
private Logic.Log.LogEvent logEvent = new Logic.Log.LogEvent();
|
||||
|
||||
public bool FeedSubmissionRecived { get; set; } = false;
|
||||
|
||||
public SubmitFeed(Model.Export.AmazonFeedSubmission feedSubmission)
|
||||
{
|
||||
FeedSubmissionRecived = false;
|
||||
|
||||
var cred = new CredentialMws();
|
||||
var config = new MarketplaceWebService.MarketplaceWebServiceConfig();
|
||||
config.ServiceURL = cred.ServiceURL;
|
||||
|
||||
|
||||
var marketPlaceList = new MarketplaceWebService.Model.IdList();
|
||||
marketPlaceList.Id = new List<string> { cred.MarketPlaceIdUK };
|
||||
|
||||
var request = new MarketplaceWebService.Model.SubmitFeedRequest();
|
||||
request.MarketplaceIdList = marketPlaceList;
|
||||
request.Merchant = cred.MerchantId;
|
||||
request.FeedContent = feedSubmission.File.FileData;
|
||||
request.FeedType = feedSubmission.FeedType;
|
||||
request.ContentMD5 = feedSubmission.File.FileMD5base64;
|
||||
request.FeedContent.Position = 0;
|
||||
|
||||
var service = new Data.AmazonMWS.Service().MarketPlaceWeb;
|
||||
|
||||
bool repeat = true;
|
||||
var response = new MarketplaceWebService.Model.SubmitFeedResponse();
|
||||
|
||||
// try for a response
|
||||
while (repeat)
|
||||
{
|
||||
try
|
||||
{
|
||||
response = service.SubmitFeed(request);
|
||||
repeat = false;
|
||||
}
|
||||
catch (MarketplaceWebServiceException ex) when (ex.ErrorCode == "RequestThrottled")
|
||||
{
|
||||
MiscFunction.MwsThrottleWait(150); // 15 inital requests, restore 1 every 2 minutes
|
||||
}
|
||||
catch (MarketplaceWebService.MarketplaceWebServiceException ex)
|
||||
{
|
||||
string errorLong = "Caught Exception: " + ex.Message + Environment.NewLine
|
||||
+ "Response Status Code: " + ex.StatusCode + Environment.NewLine
|
||||
+ "Error Code: " + ex.ErrorCode + Environment.NewLine
|
||||
+ "Error Type: " + ex.ErrorType + Environment.NewLine
|
||||
+ "Request ID: " + ex.RequestId + Environment.NewLine
|
||||
+ "XML: " + Environment.NewLine + ex.XML + Environment.NewLine
|
||||
+ "ResponseHeaderMetadata: " + ex.ResponseHeaderMetadata + Environment.NewLine;
|
||||
|
||||
logEvent.LogError("Unhandled MarketplaceWebServiceException while running InvokeSubmitFeed", errorLong);
|
||||
throw new Exception("Unhandled MarketplaceWebServiceException while running InvokeSubmitFeed");
|
||||
}
|
||||
}
|
||||
|
||||
// test the response
|
||||
if (response.IsSetSubmitFeedResult())
|
||||
{
|
||||
MarketplaceWebService.Model.SubmitFeedResult submitFeedResult = response.SubmitFeedResult;
|
||||
|
||||
if (submitFeedResult.IsSetFeedSubmissionInfo())
|
||||
{
|
||||
MarketplaceWebService.Model.FeedSubmissionInfo feedSubmissionInfo = submitFeedResult.FeedSubmissionInfo;
|
||||
if (feedSubmissionInfo.IsSetFeedSubmissionId())
|
||||
{
|
||||
feedSubmission.FeedSubmissionId = feedSubmissionInfo.FeedSubmissionId;
|
||||
FeedSubmissionRecived = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
logEvent.LogError("Response from MWS SubmitFeed did not contain a 'FeedSubmissionId'", submitFeedResult.ToString());
|
||||
return;
|
||||
}
|
||||
if (feedSubmissionInfo.IsSetFeedProcessingStatus())
|
||||
{
|
||||
feedSubmission.FeedProcessingStatus = feedSubmissionInfo.FeedProcessingStatus;
|
||||
}
|
||||
if (feedSubmissionInfo.IsSetCompletedProcessingDate())
|
||||
{
|
||||
feedSubmission.CompletedProcessingDate = DateTime.SpecifyKind(feedSubmissionInfo.CompletedProcessingDate, DateTimeKind.Utc);
|
||||
}
|
||||
if (feedSubmissionInfo.IsSetStartedProcessingDate())
|
||||
{
|
||||
feedSubmission.StartedProcessingDate = DateTime.SpecifyKind(feedSubmissionInfo.StartedProcessingDate, DateTimeKind.Utc);
|
||||
}
|
||||
if (feedSubmissionInfo.IsSetSubmittedDate())
|
||||
{
|
||||
if (feedSubmissionInfo.SubmittedDate != null)
|
||||
{
|
||||
feedSubmission.SubmittedDate = DateTime.SpecifyKind(DateTime.Parse(feedSubmissionInfo.SubmittedDate), DateTimeKind.Utc);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logEvent.LogError("Response from MWS SubmitFeed did not contain a 'FeedSubmissionInfo'", response.ToXML());
|
||||
throw new Exception("Request FeedSubmissionInfo not set."); // no idea what to do here, what happened, has it been submitted?
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logEvent.LogError("Response from MWS SubmitFeed did not contain a 'SubmitFeedResult'", response.ToXML());
|
||||
throw new Exception("Request SubmitFeedResult not set."); // no idea what to do here, what happened, has it been submitted?
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,17 +25,16 @@ namespace bnhtrade.Core.Data.AmazonMWS
|
||||
{
|
||||
var cred = new AmazonMWS.CredentialMws();
|
||||
|
||||
this.merchantId = cred.merchantId;
|
||||
this.marketplaceId = cred.marketPlaceId;
|
||||
this.accessKeyId = cred.accessKeyId;
|
||||
this.secretAccessKey = cred.secretAccessKey;
|
||||
this.applicationName = cred.applicationName;
|
||||
this.applicationVersion = cred.applicationVersion;
|
||||
this.serviceURL = cred.serviceURL;
|
||||
this.merchantId = cred.MerchantId;
|
||||
this.marketplaceId = cred.MarketPlaceIdUK;
|
||||
this.accessKeyId = cred.AccessKeyId;
|
||||
this.secretAccessKey = cred.SecretAccessKey;
|
||||
this.applicationName = cred.ApplicationName;
|
||||
this.applicationVersion = cred.ApplicationVersion;
|
||||
this.serviceURL = cred.ServiceURL;
|
||||
}
|
||||
|
||||
public MarketplaceWebService.MarketplaceWebService MarketPlaceWeb
|
||||
|
||||
{
|
||||
get
|
||||
{
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Account
|
||||
{
|
||||
public class CreateInvoiceLineItem : Connection
|
||||
{
|
||||
public CreateInvoiceLineItem(string sqlConnectionString) : base(sqlConnectionString)
|
||||
{
|
||||
}
|
||||
|
||||
public int CreateDefault(string itemCode)
|
||||
{
|
||||
using (var conn = new SqlConnection(sqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
INSERT INTO tblAccountInvoiceLineItem ( ItemName, ItemCode )
|
||||
OUTPUT INSERTED.AccountInvoiceLineItemID
|
||||
VALUES ( @itemName, @itemCode )
|
||||
", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@itemName", itemCode);
|
||||
cmd.Parameters.AddWithValue("@itemCode", itemCode);
|
||||
|
||||
object obj = cmd.ExecuteScalar();
|
||||
|
||||
if (obj == null || obj == DBNull.Value)
|
||||
{
|
||||
throw new Exception("Error inserting new defalt invoice line item into database");
|
||||
}
|
||||
|
||||
return (int)obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,62 +9,34 @@ namespace bnhtrade.Core.Data.Database.Account
|
||||
{
|
||||
public class ReadAccountCode : Connection
|
||||
{
|
||||
private bool allRetrived;
|
||||
private Dictionary<int, Model.Account.AccountCode> cache;
|
||||
protected ReadAccountCode(string sqlConnectionString) : base(sqlConnectionString)
|
||||
private Data.Database.WhereBuilder sqlWhere = new WhereBuilder();
|
||||
private List<Model.Account.AccountCode> resultList;
|
||||
|
||||
public ReadAccountCode(string sqlConnectionString) : base(sqlConnectionString)
|
||||
{
|
||||
allRetrived = false;
|
||||
cache = new Dictionary<int, Model.Account.AccountCode>();
|
||||
}
|
||||
protected void ClearCache()
|
||||
{
|
||||
allRetrived = false;
|
||||
cache.Clear();
|
||||
}
|
||||
public List<Model.Account.AccountCode> GetAll()
|
||||
{
|
||||
if (allRetrived == false)
|
||||
{
|
||||
UpdateCache(-1);
|
||||
allRetrived = true;
|
||||
}
|
||||
|
||||
var returnList = new List<Model.Account.AccountCode>();
|
||||
foreach (var item in cache)
|
||||
public List<Model.Account.AccountCode> All()
|
||||
{
|
||||
returnList.Add(item.Value);
|
||||
Innit();
|
||||
return Execute(null, null);
|
||||
}
|
||||
|
||||
return returnList;
|
||||
}
|
||||
public Model.Account.AccountCode GetByAccountCode(int accountCode)
|
||||
public List<Model.Account.AccountCode> ByAccountCode(List<int> accountCodeList)
|
||||
{
|
||||
if (cache.ContainsKey(accountCode))
|
||||
{
|
||||
return cache[accountCode];
|
||||
}
|
||||
else if (allRetrived)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateCache(accountCode);
|
||||
if (cache.ContainsKey(accountCode))
|
||||
{
|
||||
return cache[accountCode];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
protected void UpdateCache(int accountCode = -1)
|
||||
{
|
||||
var dicCache = new Dictionary<int, Model.Account.AccountCode>();
|
||||
Innit();
|
||||
|
||||
bool whereClause = false;
|
||||
if (accountCodeList == null || !accountCodeList.Any())
|
||||
{
|
||||
return resultList;
|
||||
}
|
||||
|
||||
sqlWhere.In("tblAccountChartOf.AccountCode", accountCodeList, " WHERE ");
|
||||
return Execute(sqlWhere.SqlWhereString, sqlWhere.ParameterList);
|
||||
}
|
||||
|
||||
private List<Model.Account.AccountCode> Execute(string sqlWhere, Dictionary<string, object> parameters)
|
||||
{
|
||||
//build sql query
|
||||
string sqlString = @"
|
||||
SELECT tblAccountChartOf.AccountChartOfID
|
||||
@@ -74,13 +46,8 @@ namespace bnhtrade.Core.Data.Database.Account
|
||||
,tblAccountChartOfType.AccountChartOfType
|
||||
,tblAccountChartOfType.BasicType
|
||||
FROM tblAccountChartOf
|
||||
INNER JOIN tblAccountChartOfType ON tblAccountChartOf.AccountChartOfTypeID = tblAccountChartOfType.AccountChartOfTypeID";
|
||||
if (accountCode > -1)
|
||||
{
|
||||
whereClause = true;
|
||||
sqlString = sqlString + @"
|
||||
WHERE (((tblAccountChartOf.AccountCode) = @accountCode))";
|
||||
}
|
||||
INNER JOIN tblAccountChartOfType ON tblAccountChartOf.AccountChartOfTypeID = tblAccountChartOfType.AccountChartOfTypeID
|
||||
" + sqlWhere;
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(sqlConnectionString))
|
||||
{
|
||||
@@ -88,9 +55,12 @@ namespace bnhtrade.Core.Data.Database.Account
|
||||
|
||||
using (SqlCommand cmd = new SqlCommand(sqlString, conn))
|
||||
{
|
||||
if (whereClause)
|
||||
if (parameters != null)
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@accountCode", accountCode);
|
||||
foreach (var parameter in parameters)
|
||||
{
|
||||
cmd.Parameters.AddWithValue(parameter.Key, parameter.Value);
|
||||
}
|
||||
}
|
||||
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
@@ -108,30 +78,19 @@ namespace bnhtrade.Core.Data.Database.Account
|
||||
result.Type = reader.GetString(4);
|
||||
result.BasicType = reader.GetString(5);
|
||||
|
||||
if (whereClause)
|
||||
resultList.Add(result);
|
||||
}
|
||||
}
|
||||
|
||||
return resultList;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Innit()
|
||||
{
|
||||
if (cache.ContainsKey(result.AccountCodeId))
|
||||
{
|
||||
cache.Remove(result.AccountCodeId);
|
||||
}
|
||||
cache.Add(result.AccountCodeId, result);
|
||||
}
|
||||
else
|
||||
{
|
||||
dicCache.Add(result.AccountCodeId, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// update cache
|
||||
if (!whereClause)
|
||||
{
|
||||
cache.Clear();
|
||||
allRetrived = true;
|
||||
cache = dicCache;
|
||||
}
|
||||
resultList = new List<Model.Account.AccountCode>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
113
src/bnhtrade.Core/Data/Database/Account/ReadInvoiceLineItem.cs
Normal file
113
src/bnhtrade.Core/Data/Database/Account/ReadInvoiceLineItem.cs
Normal file
@@ -0,0 +1,113 @@
|
||||
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.Data.Database.Account
|
||||
{
|
||||
public class ReadInvoiceLineItem : Connection
|
||||
{
|
||||
public ReadInvoiceLineItem(string sqlConnectionString) : base(sqlConnectionString)
|
||||
{
|
||||
Innit();
|
||||
}
|
||||
|
||||
public Dictionary<string, int> AccountCodeList { get; private set; }
|
||||
|
||||
public Dictionary<string, string> TaxCodeList { get; private set; }
|
||||
|
||||
private void Innit()
|
||||
{
|
||||
AccountCodeList = new Dictionary<string, int>();
|
||||
TaxCodeList = new Dictionary<string, string>();
|
||||
}
|
||||
|
||||
public Model.Account.InvoiceLineItem ByItemCode(string itemCode)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(itemCode)) { return null; }
|
||||
|
||||
var result = ByItemCode(new List<string>{ itemCode });
|
||||
|
||||
if (!result.Any())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return result[itemCode];
|
||||
}
|
||||
}
|
||||
|
||||
public Dictionary<string, Model.Account.InvoiceLineItem> ByItemCode(List<string> itemCodeList)
|
||||
{
|
||||
Innit();
|
||||
var resultList = new Dictionary<string, Model.Account.InvoiceLineItem>();
|
||||
|
||||
if (itemCodeList == null || !itemCodeList.Any())
|
||||
{ return resultList; }
|
||||
|
||||
string sql = @"
|
||||
SELECT tblAccountInvoiceLineItem.ItemCode
|
||||
,tblAccountInvoiceLineItem.ItemName
|
||||
,tblAccountInvoiceLineItem.ItemDescription
|
||||
,tblAccountInvoiceLineItem.IsNewReviewRequired
|
||||
,tblAccountInvoiceLineItem.InvoiceLineEntryEnable
|
||||
,tblAccountChartOf.AccountCode
|
||||
,tblAccountTaxCode.TaxCode
|
||||
FROM tblAccountInvoiceLineItem
|
||||
LEFT OUTER JOIN tblAccountTaxCode ON tblAccountInvoiceLineItem.AccountTaxCodeID_Default = tblAccountTaxCode.AccountTaxCodeID
|
||||
LEFT OUTER JOIN tblAccountChartOf ON tblAccountInvoiceLineItem.AccountChartOfID_Default = tblAccountChartOf.AccountChartOfID
|
||||
WHERE ";
|
||||
|
||||
var whereBuilder = new WhereBuilder();
|
||||
whereBuilder.In("tblAccountInvoiceLineItem.ItemCode", itemCodeList);
|
||||
sql += whereBuilder.SqlWhereString;
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(sqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
foreach (var param in whereBuilder.ParameterList)
|
||||
{
|
||||
cmd.Parameters.AddWithValue(param.Key, param.Value);
|
||||
}
|
||||
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (reader.HasRows)
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
var result = new Model.Account.InvoiceLineItem();
|
||||
|
||||
result.ItemCode = reader.GetString(0);
|
||||
result.Name = reader.GetString(1);
|
||||
if (!reader.IsDBNull(2)) { result.Description = reader.GetString(2); }
|
||||
result.IsNewReviewRequired = reader.GetBoolean(3);
|
||||
result.InvoiceLineEntryEnabled = reader.GetBoolean(4);
|
||||
|
||||
if (!reader.IsDBNull(5))
|
||||
{
|
||||
AccountCodeList.Add(result.ItemCode, reader.GetInt32(5));
|
||||
}
|
||||
if (!reader.IsDBNull(6))
|
||||
{
|
||||
TaxCodeList.Add(result.ItemCode, reader.GetString(6));
|
||||
}
|
||||
|
||||
resultList.Add(result.ItemCode, result);
|
||||
}
|
||||
}
|
||||
|
||||
return resultList;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,148 +0,0 @@
|
||||
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.Data.Database.Account
|
||||
{
|
||||
public class ReadInvoiceLineItemCode : Connection
|
||||
{
|
||||
public ReadInvoiceLineItemCode(string sqlConnectionString) : base (sqlConnectionString)
|
||||
{
|
||||
cacheLineItemByTablePk = new Dictionary<int, Model.Account.InvoiceLineItem>();
|
||||
cacheTablePkByItemCode = new Dictionary<string, int>();
|
||||
}
|
||||
|
||||
private Dictionary<int, Model.Account.InvoiceLineItem> cacheLineItemByTablePk;
|
||||
private Dictionary<string, int> cacheTablePkByItemCode;
|
||||
|
||||
public bool InsertNewOnNoMatch { get; set; } = false;
|
||||
|
||||
public string NewTypeTitle { get; } = "NEW TYPE";
|
||||
|
||||
public void CacheClear()
|
||||
{
|
||||
cacheLineItemByTablePk.Clear();
|
||||
cacheTablePkByItemCode.Clear();
|
||||
}
|
||||
|
||||
private void CacheRemove(int tablePk)
|
||||
{
|
||||
if (cacheLineItemByTablePk.ContainsKey(tablePk))
|
||||
{
|
||||
string itemCode = cacheLineItemByTablePk[tablePk].ItemCode;
|
||||
cacheLineItemByTablePk.Remove(tablePk);
|
||||
cacheTablePkByItemCode.Remove(itemCode);
|
||||
}
|
||||
}
|
||||
|
||||
public void CacheRemove(string itemCode)
|
||||
{
|
||||
if (cacheTablePkByItemCode.ContainsKey(itemCode))
|
||||
{
|
||||
CacheRemove(cacheTablePkByItemCode[itemCode]);
|
||||
}
|
||||
}
|
||||
|
||||
private void CacheUpdate(int tablePk, Model.Account.InvoiceLineItem lineItem)
|
||||
{
|
||||
if (cacheLineItemByTablePk.ContainsKey(tablePk))
|
||||
{
|
||||
CacheRemove(tablePk);
|
||||
}
|
||||
cacheLineItemByTablePk.Add(tablePk, lineItem);
|
||||
cacheTablePkByItemCode.Add(lineItem.ItemCode, tablePk);
|
||||
}
|
||||
|
||||
public Model.Account.InvoiceLineItem ByItemCode(string itemCode, bool forceCacheUpdate = false)
|
||||
{
|
||||
// check cache
|
||||
if (!forceCacheUpdate && cacheTablePkByItemCode.ContainsKey(itemCode))
|
||||
{
|
||||
return cacheLineItemByTablePk[cacheTablePkByItemCode[itemCode]];
|
||||
}
|
||||
|
||||
var returnObject = new Model.Account.InvoiceLineItem();
|
||||
returnObject.ItemCode = itemCode;
|
||||
|
||||
using (TransactionScope scopeSupress = new TransactionScope(TransactionScopeOption.Suppress))
|
||||
using (SqlConnection conn = new SqlConnection(sqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
SELECT tblExportAccountInvoiceLineType.ExportAccountInvoiceLineTypeID
|
||||
,tblExportAccountInvoiceLineType.TypeTitle
|
||||
,tblExportAccountInvoiceLineType.TypeDescription
|
||||
,tblExportAccountInvoiceLineType.IsNewReviewRequired
|
||||
,tblExportAccountInvoiceLineType.InvoiceLineEntryEnable
|
||||
,tblAccountChartOf.AccountCode
|
||||
,tblAccountTaxCode.TaxCode
|
||||
FROM (
|
||||
tblExportAccountInvoiceLineType LEFT JOIN tblAccountChartOf ON tblExportAccountInvoiceLineType.AccountChartOfID_Default = tblAccountChartOf.AccountChartOfID
|
||||
)
|
||||
LEFT JOIN tblAccountTaxCode ON tblExportAccountInvoiceLineType.AccountTaxCodeID_Default = tblAccountTaxCode.AccountTaxCodeID
|
||||
WHERE (((tblExportAccountInvoiceLineType.MatchString) = @matchString))
|
||||
", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@matchString", returnObject.ItemCode);
|
||||
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
int tablePk = reader.GetInt32(0);
|
||||
returnObject.Title = reader.GetString(1);
|
||||
if (!reader.IsDBNull(2)) { returnObject.Description = reader.GetString(2); }
|
||||
returnObject.IsNewReviewRequired = reader.GetBoolean(3);
|
||||
returnObject.InvoiceLineEntryEnabled = reader.GetBoolean(4);
|
||||
if (!reader.IsDBNull(5)) { returnObject.DefaultAccountCode = reader.GetInt32(5); }
|
||||
if (!reader.IsDBNull(6)) { returnObject.DefaultTaxCode = reader.GetString(6); }
|
||||
|
||||
// add to cache
|
||||
CacheUpdate(tablePk, returnObject);
|
||||
|
||||
// return object
|
||||
return returnObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// insert new and retrive new value, if required
|
||||
if (InsertNewOnNoMatch)
|
||||
{
|
||||
int tablePk = 0;
|
||||
returnObject.Title = NewTypeTitle;
|
||||
returnObject.ItemCode = itemCode;
|
||||
returnObject.IsNewReviewRequired = true;
|
||||
|
||||
using (SqlCommand insertCmd = new SqlCommand(@"
|
||||
INSERT INTO tblExportAccountInvoiceLineType ( TypeTitle, MatchString )
|
||||
OUTPUT INSERTED.ExportAccountInvoiceLineTypeID
|
||||
VALUES ( @typeTitle, @matchString )
|
||||
", conn))
|
||||
{
|
||||
insertCmd.Parameters.AddWithValue("@typeTitle", returnObject.Title);
|
||||
insertCmd.Parameters.AddWithValue("@matchString", returnObject.ItemCode);
|
||||
|
||||
tablePk = (int)insertCmd.ExecuteScalar();
|
||||
|
||||
scopeSupress.Complete();
|
||||
}
|
||||
// add to cache
|
||||
CacheUpdate(tablePk, returnObject);
|
||||
|
||||
// return object
|
||||
return returnObject;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,165 +9,32 @@ namespace bnhtrade.Core.Data.Database.Account
|
||||
{
|
||||
public class ReadTaxCode : Connection
|
||||
{
|
||||
private bool allRetrived;
|
||||
private Dictionary<string, Model.Account.TaxCode> cache;
|
||||
private Data.Database.WhereBuilder whereBuilder;
|
||||
|
||||
public ReadTaxCode(string sqlConnectionString) : base(sqlConnectionString)
|
||||
{
|
||||
allRetrived = false;
|
||||
cache = new Dictionary<string, Model.Account.TaxCode>();
|
||||
}
|
||||
private void ClearCache()
|
||||
{
|
||||
allRetrived = false;
|
||||
cache.Clear();
|
||||
}
|
||||
public List<Model.Account.TaxCode> GetAll()
|
||||
{
|
||||
if (allRetrived == false)
|
||||
{
|
||||
UpdateCache(null);
|
||||
allRetrived = true;
|
||||
whereBuilder = new WhereBuilder();
|
||||
}
|
||||
|
||||
var returnList = new List<Model.Account.TaxCode>();
|
||||
foreach (var item in cache)
|
||||
private List<Model.Account.TaxCodeInfo> Execute(string sqlWhere, Dictionary<string, object> parameters)
|
||||
{
|
||||
returnList.Add(item.Value);
|
||||
}
|
||||
var resultList = new List<Model.Account.TaxCodeInfo>();
|
||||
|
||||
return returnList;
|
||||
}
|
||||
public Dictionary<string, Model.Account.TaxCode> BySkuNumber(List<string> skuNumberList)
|
||||
{
|
||||
// check input list for items
|
||||
if (skuNumberList == null || !skuNumberList.Any())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// build SQL string
|
||||
string sqlString = @"
|
||||
SELECT
|
||||
tblSku.skuSkuNumber, tblAccountTaxCode.TaxCode
|
||||
FROM
|
||||
tblAccountTaxCode INNER JOIN tblSku ON tblAccountTaxCode.AccountTaxCodeID = tblSku.AccountTaxCodeID
|
||||
WHERE
|
||||
";
|
||||
|
||||
var parameterValueList = new List<Tuple<string, string>>();
|
||||
foreach (var item in skuNumberList)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(item))
|
||||
{
|
||||
int count = parameterValueList.Count;
|
||||
var parameterValue = new Tuple<string, string>("@parameter" + count, item);
|
||||
parameterValueList.Add(parameterValue);
|
||||
if (count == 0)
|
||||
{
|
||||
sqlString = sqlString + @"
|
||||
skuSkuNumber = " + parameterValue.Item1;
|
||||
}
|
||||
else
|
||||
{
|
||||
sqlString = sqlString + @"
|
||||
OR skuSkuNumber = " + parameterValue.Item1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (parameterValueList.Count == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// execute query and build result list
|
||||
var skuTaxCodeList = new List<Tuple<string, string>>();
|
||||
using (SqlConnection conn = new SqlConnection(sqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
using (SqlCommand cmd = new SqlCommand(sqlString, conn))
|
||||
{
|
||||
foreach (var item in parameterValueList)
|
||||
{
|
||||
cmd.Parameters.AddWithValue(item.Item1, item.Item2);
|
||||
}
|
||||
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (!reader.HasRows)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
while (reader.Read())
|
||||
{
|
||||
var skuTaxCode = new Tuple<string, string>(
|
||||
reader.GetString(0),
|
||||
reader.GetString(1)
|
||||
);
|
||||
skuTaxCodeList.Add(skuTaxCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// build dictionary of skuNumber to TaxCodeInfo
|
||||
var returnDictionary = new Dictionary<string, Model.Account.TaxCode>();
|
||||
foreach (var item in skuTaxCodeList)
|
||||
{
|
||||
returnDictionary.Add(item.Item1, GetByTaxCodeId(item.Item2));
|
||||
}
|
||||
|
||||
return returnDictionary;
|
||||
}
|
||||
}
|
||||
public Model.Account.TaxCode GetByTaxCodeId(string taxCode)
|
||||
{
|
||||
if (cache.ContainsKey(taxCode))
|
||||
{
|
||||
return cache[taxCode];
|
||||
}
|
||||
else if (allRetrived)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateCache(taxCode);
|
||||
if (cache.ContainsKey(taxCode))
|
||||
{
|
||||
return cache[taxCode];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
private void UpdateCache(string taxCode)
|
||||
{
|
||||
var dicCache = new Dictionary<string, Model.Account.TaxCode>();
|
||||
|
||||
bool whereClause = false;
|
||||
//build sql query
|
||||
string sqlString = @"
|
||||
SELECT
|
||||
TaxCode
|
||||
,TaxRateName
|
||||
,TaxRateMultiplierNet
|
||||
,TaxRateMultiplierGross
|
||||
,TaxCodeName
|
||||
,TaxCodeDescription
|
||||
,TaxRatePercent
|
||||
,IsMarginScheme
|
||||
,IsValidOnExpense
|
||||
,IsVailidOnIncome
|
||||
,Description
|
||||
,IsActive
|
||||
,TaxType
|
||||
FROM tblAccountTaxCode";
|
||||
if (!string.IsNullOrWhiteSpace(taxCode))
|
||||
{
|
||||
whereClause = true;
|
||||
sqlString = sqlString + @"
|
||||
WHERE TaxCode = @taxCode";
|
||||
}
|
||||
|
||||
sqlString += sqlWhere;
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(sqlConnectionString))
|
||||
{
|
||||
@@ -175,9 +42,9 @@ namespace bnhtrade.Core.Data.Database.Account
|
||||
|
||||
using (SqlCommand cmd = new SqlCommand(sqlString, conn))
|
||||
{
|
||||
if (whereClause)
|
||||
foreach (var paramter in parameters)
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@taxCode", taxCode);
|
||||
cmd.Parameters.AddWithValue(paramter.Key, paramter.Value);
|
||||
}
|
||||
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
@@ -186,42 +53,160 @@ namespace bnhtrade.Core.Data.Database.Account
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
var result = new Model.Account.TaxCode();
|
||||
string taxCodeId = reader.GetString(0);
|
||||
string name = reader.GetString(1);
|
||||
string description = null;
|
||||
if (!reader.IsDBNull(2)) { description = reader.GetString(2); }
|
||||
decimal rate = reader.GetDecimal(3);
|
||||
bool isMargin = reader.GetBoolean(4);
|
||||
bool isValidOnExpense = reader.GetBoolean(5);
|
||||
bool isValidOnIncome = reader.GetBoolean(6);
|
||||
bool isActive = reader.GetBoolean(7);
|
||||
string taxType = reader.GetString(8);
|
||||
|
||||
result.TaxCodeId = reader.GetString(0);
|
||||
result.TaxRateTitle = reader.GetString(1);
|
||||
result.NetAmountMultiplier = reader.GetDecimal(2);
|
||||
result.GrossAmountMultiplier = reader.GetDecimal(3);
|
||||
result.IsValidOnExpense = reader.GetBoolean(4);
|
||||
result.IsValidOnIncome = reader.GetBoolean(5);
|
||||
if (!reader.IsDBNull(6)) { result.TaxRateDescription = reader.GetString(6); }
|
||||
result.IsActive = reader.GetBoolean(7);
|
||||
result.TaxType = reader.GetString(8);
|
||||
var result = new Model.Account.TaxCodeInfo(
|
||||
taxCodeId,
|
||||
name,
|
||||
description,
|
||||
rate,
|
||||
isMargin,
|
||||
isValidOnExpense,
|
||||
isValidOnIncome,
|
||||
taxType,
|
||||
isActive);
|
||||
|
||||
if (whereClause)
|
||||
resultList.Add(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return resultList;
|
||||
}
|
||||
|
||||
public List<Model.Account.TaxCodeInfo> GetByTaxCode(List<string> taxcodeList)
|
||||
{
|
||||
if (cache.ContainsKey(result.TaxCodeId))
|
||||
var resultList = new List<Model.Account.TaxCodeInfo>();
|
||||
|
||||
if (taxcodeList == null || !taxcodeList.Any())
|
||||
{
|
||||
cache.Remove(result.TaxCodeId);
|
||||
return resultList;
|
||||
}
|
||||
cache.Add(result.TaxCodeId, result);
|
||||
|
||||
whereBuilder.Innit();
|
||||
whereBuilder.In("TaxCode", taxcodeList, "WHERE");
|
||||
|
||||
return Execute(whereBuilder.SqlWhereString, whereBuilder.ParameterList);
|
||||
}
|
||||
else
|
||||
|
||||
public List<Model.Account.TaxCodeInfo> GetAllActive()
|
||||
{
|
||||
dicCache.Add(result.TaxCodeId, result);
|
||||
string sqlWhere = @"
|
||||
WHERE IsActive=@isActive;";
|
||||
var parameters = new Dictionary<string, object>();
|
||||
parameters.Add("@isActive", true);
|
||||
|
||||
return Execute(sqlWhere, parameters);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// update cache
|
||||
if (!whereClause)
|
||||
|
||||
public Dictionary<string, string> GetTaxCodeBySkuNumber(List<string> skuNumberList)
|
||||
{
|
||||
cache.Clear();
|
||||
allRetrived = true;
|
||||
cache = dicCache;
|
||||
var resultList = new Dictionary<string, string>();
|
||||
|
||||
if (skuNumberList == null || !skuNumberList.Any())
|
||||
{
|
||||
return resultList;
|
||||
}
|
||||
|
||||
string sql = @"
|
||||
SELECT tblSku.skuSkuNumber
|
||||
,tblAccountTaxCode.TaxCode
|
||||
FROM tblSku
|
||||
INNER JOIN tblAccountTaxCode ON tblSku.AccountTaxCodeID = tblAccountTaxCode.AccountTaxCodeID ";
|
||||
|
||||
whereBuilder.Innit();
|
||||
whereBuilder.In("tblSku.skuSkuNumber", skuNumberList, "WHERE");
|
||||
|
||||
sql += whereBuilder.SqlWhereString;
|
||||
|
||||
using (var conn = new SqlConnection(sqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
using (var cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
foreach (var param in whereBuilder.ParameterList)
|
||||
{
|
||||
cmd.Parameters.AddWithValue(param.Key, param.Value);
|
||||
}
|
||||
|
||||
using (var reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (!reader.HasRows)
|
||||
{
|
||||
return resultList;
|
||||
}
|
||||
|
||||
while (reader.Read())
|
||||
{
|
||||
resultList.Add(reader.GetString(0), reader.GetString(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return resultList;
|
||||
}
|
||||
|
||||
public Dictionary<string, string> GetTaxCodeByInvoiceLineItemCode(List<string> lineItemCode)
|
||||
{
|
||||
var resultList = new Dictionary<string, string>();
|
||||
|
||||
if (lineItemCode == null || !lineItemCode.Any())
|
||||
{
|
||||
return resultList;
|
||||
}
|
||||
|
||||
string sql = @"
|
||||
SELECT tblAccountInvoiceLineItem.ItemCode
|
||||
,tblAccountTaxCode.TaxCode
|
||||
FROM tblAccountInvoiceLineItem
|
||||
LEFT OUTER JOIN tblAccountTaxCode ON tblAccountInvoiceLineItem.AccountTaxCodeID_Default = tblAccountTaxCode.AccountTaxCodeID
|
||||
";
|
||||
|
||||
whereBuilder.Innit();
|
||||
whereBuilder.In("tblAccountInvoiceLineItem.ItemCode", lineItemCode, "WHERE");
|
||||
|
||||
sql += whereBuilder.SqlWhereString;
|
||||
|
||||
using (var conn = new SqlConnection(sqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
using (var cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
foreach (var param in whereBuilder.ParameterList)
|
||||
{
|
||||
cmd.Parameters.AddWithValue(param.Key, param.Value);
|
||||
}
|
||||
|
||||
using (var reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (!reader.HasRows)
|
||||
{
|
||||
return resultList;
|
||||
}
|
||||
|
||||
while (reader.Read())
|
||||
{
|
||||
if (reader.IsDBNull(1)) { resultList.Add(reader.GetString(0), null); }
|
||||
else { resultList.Add(reader.GetString(0), reader.GetString(1)); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return resultList;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
148
src/bnhtrade.Core/Data/Database/AmazonFba/ReadShipmentInfo.cs
Normal file
148
src/bnhtrade.Core/Data/Database/AmazonFba/ReadShipmentInfo.cs
Normal file
@@ -0,0 +1,148 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Dapper;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.AmazonShipment
|
||||
{
|
||||
public class ReadShipmentInfo : Connection
|
||||
{
|
||||
private List<string> shipmentIdList;
|
||||
|
||||
public ReadShipmentInfo(string sqlConnectionString) : base(sqlConnectionString)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return active shipments only. Default is false.
|
||||
/// </summary>
|
||||
public bool ReturnOnlyActiveShipments { get; set; } = false;
|
||||
|
||||
private bool IsSetFbaShipmentIdList
|
||||
{
|
||||
get
|
||||
{
|
||||
if (FbaShipmentIdList == null || !FbaShipmentIdList.Any()) { return false; }
|
||||
else { return true; }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filter results by Amazon's shipment Id.
|
||||
/// </summary>
|
||||
private List<string> FbaShipmentIdList
|
||||
{
|
||||
get { return shipmentIdList; }
|
||||
set
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
// clean list
|
||||
shipmentIdList = new List<string>();
|
||||
foreach (string item in value)
|
||||
{
|
||||
if (item.Length > 0)
|
||||
{
|
||||
shipmentIdList.Add(item);
|
||||
}
|
||||
}
|
||||
if (!FbaShipmentIdList.Any())
|
||||
{
|
||||
shipmentIdList = null;
|
||||
throw new Exception("Invalid shipment Id set");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Model.AmazonFba.ShipmentInfo HeaderByFbaShipmentId(string fbaShipmentId)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(fbaShipmentId))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var list = new List<string> { fbaShipmentId };
|
||||
var result = HeaderByFbaShipmentId(list);
|
||||
if (result.Any())
|
||||
{
|
||||
return result[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public List<Model.AmazonFba.ShipmentInfo> HeaderByFbaShipmentId(List<string> fbaShipmentIdList)
|
||||
{
|
||||
FbaShipmentIdList = fbaShipmentIdList;
|
||||
|
||||
if (IsSetFbaShipmentIdList)
|
||||
{
|
||||
string sql = @"
|
||||
AND tblAmazonShipment.ShipmentId IN @shipmentId ";
|
||||
|
||||
var parameters = new DynamicParameters();
|
||||
parameters.Add("@shipmentId", FbaShipmentIdList);
|
||||
|
||||
return HeaderInfo(sql, parameters);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new List<Model.AmazonFba.ShipmentInfo>();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrives table primary key 'AmazonShipmentID' for tblAmazonShipment
|
||||
/// </summary>
|
||||
/// <param name="amazonShipmentId">Amazon's inbound FBA shipment Id.</param>
|
||||
/// <returns>Primary key or -1 if match isn't found.</returns>
|
||||
private List<Model.AmazonFba.ShipmentInfo> HeaderInfo(string sqlWhere, DynamicParameters parameters)
|
||||
{
|
||||
// build the sql string
|
||||
string sql = @"
|
||||
SELECT tblAmazonShipment.AmazonShipmentID
|
||||
,tblAmazonShipment.ShipmentName
|
||||
,tblAmazonShipment.ShipmentId AS FbaShipmentId
|
||||
,tblAmazonShipment.CenterId
|
||||
,tblAmazonShipment.ShipmentStatus
|
||||
,tblAmazonShipment.LastUpdated
|
||||
,tblAmazonShipment.IsClosed
|
||||
,tblStockStatus.StockStatusID AS ShipmentStockStatusId
|
||||
,tblStockStatus.StockStatus AS ShipmentStockStatus
|
||||
FROM tblAmazonShipment
|
||||
LEFT OUTER JOIN tblStockStatus ON tblAmazonShipment.ShipmentStockStatusID = tblStockStatus.StockStatusID
|
||||
WHERE 1=1 ";
|
||||
|
||||
sql += sqlWhere;
|
||||
|
||||
if (ReturnOnlyActiveShipments)
|
||||
{
|
||||
sql = sql + @"
|
||||
AND IsClosed = 0";
|
||||
}
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(sqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
var result = conn.Query<Model.AmazonFba.ShipmentInfo>(sql, parameters).ToList();
|
||||
|
||||
// set datetime kind
|
||||
for (int i = 0; i < result.Count; i++)
|
||||
{
|
||||
if (result[i].IsSetLastUpdated())
|
||||
{
|
||||
result[i].LastUpdated = DateTime.SpecifyKind(result[i].LastUpdated, DateTimeKind.Utc);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,14 +5,18 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.FBAInbound
|
||||
namespace bnhtrade.Core.Data.Database.AmazonShipment
|
||||
{
|
||||
public class GetShipmentPrimaryKey : Connection
|
||||
public class ReadShipmentPrimaryKey : Connection
|
||||
{
|
||||
private bool enableCache = false;
|
||||
private Dictionary<string, int> shipmentPKByAmazonShipmentIdDic;
|
||||
private Dictionary<int, string> amazonShipmentIdByShipmentPKDic;
|
||||
public GetShipmentPrimaryKey(string sqlConnectionString) : base(sqlConnectionString) { }
|
||||
|
||||
public ReadShipmentPrimaryKey(string sqlConnectionString) : base(sqlConnectionString)
|
||||
{
|
||||
}
|
||||
|
||||
public bool CacheEnabled
|
||||
{
|
||||
get { return enableCache; }
|
||||
@@ -30,6 +34,7 @@ namespace bnhtrade.Core.Data.Database.FBAInbound
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ClearCache()
|
||||
{
|
||||
if (CacheEnabled)
|
||||
@@ -38,6 +43,7 @@ namespace bnhtrade.Core.Data.Database.FBAInbound
|
||||
amazonShipmentIdByShipmentPKDic.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
private void DeleteCachedShipmentPK(int shipmentPrimaryKey)
|
||||
{
|
||||
if (CacheEnabled)
|
||||
@@ -50,6 +56,7 @@ namespace bnhtrade.Core.Data.Database.FBAInbound
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrives table primary key 'AmazonShipmentID' for tblAmazonShipment
|
||||
/// </summary>
|
||||
@@ -99,6 +106,7 @@ namespace bnhtrade.Core.Data.Database.FBAInbound
|
||||
UpdateCache(shipmentPK, amazonShipmentId);
|
||||
return shipmentPK;
|
||||
}
|
||||
|
||||
private void UpdateCache(int shipmentPK, string amazonShipmentId)
|
||||
{
|
||||
if (CacheEnabled)
|
||||
@@ -6,20 +6,24 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Transactions;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.FBAInbound
|
||||
namespace bnhtrade.Core.Data.Database.AmazonShipment
|
||||
{
|
||||
public class SetShipmentInfo : Connection
|
||||
{
|
||||
private GetShipmentPrimaryKey getPK;
|
||||
private Data.Database.SKU.GetSkuId skuIdLoopkup;
|
||||
public SetShipmentInfo(string sqlConnectionString) : base(sqlConnectionString) { }
|
||||
private GetShipmentPrimaryKey GetPK
|
||||
private ReadShipmentPrimaryKey getPK;
|
||||
private Data.Database.Sku.GetSkuId skuIdLoopkup;
|
||||
|
||||
public SetShipmentInfo(string sqlConnectionString) : base(sqlConnectionString)
|
||||
{
|
||||
}
|
||||
|
||||
private ReadShipmentPrimaryKey GetPK
|
||||
{
|
||||
get
|
||||
{
|
||||
if (getPK == null)
|
||||
{
|
||||
getPK = new GetShipmentPrimaryKey(sqlConnectionString);
|
||||
getPK = new ReadShipmentPrimaryKey(sqlConnectionString);
|
||||
}
|
||||
return getPK;
|
||||
}
|
||||
@@ -28,18 +32,20 @@ namespace bnhtrade.Core.Data.Database.FBAInbound
|
||||
getPK = value;
|
||||
}
|
||||
}
|
||||
private Data.Database.SKU.GetSkuId SkuIdLoopkup
|
||||
|
||||
private Data.Database.Sku.GetSkuId SkuIdLoopkup
|
||||
{
|
||||
get
|
||||
{
|
||||
if (skuIdLoopkup == null)
|
||||
{
|
||||
skuIdLoopkup = new SKU.GetSkuId(sqlConnectionString);
|
||||
skuIdLoopkup = new Sku.GetSkuId(sqlConnectionString);
|
||||
}
|
||||
return skuIdLoopkup;
|
||||
}
|
||||
}
|
||||
public void Excecute(Model.AmazonFBAInbound.ShipmentInfo info)
|
||||
|
||||
public void Excecute(Model.AmazonFba.ShipmentInfo info)
|
||||
{
|
||||
using (var scope = new TransactionScope())
|
||||
{
|
||||
@@ -54,7 +60,7 @@ namespace bnhtrade.Core.Data.Database.FBAInbound
|
||||
}
|
||||
|
||||
// get tablePK
|
||||
int shipmentPK = GetPK.ByAmazonShipmentId(info.AmazonShipmentId);
|
||||
int shipmentPK = GetPK.ByAmazonShipmentId(info.FbaShipmentId);
|
||||
|
||||
// add or update shipment header info
|
||||
if (shipmentPK == -1)
|
||||
@@ -106,7 +112,7 @@ namespace bnhtrade.Core.Data.Database.FBAInbound
|
||||
}
|
||||
}
|
||||
|
||||
public void ExcecuteByList(List<Model.AmazonFBAInbound.ShipmentInfo> infoList)
|
||||
public void ExcecuteByList(List<Model.AmazonFba.ShipmentInfo> infoList)
|
||||
{
|
||||
using (var scope = new TransactionScope())
|
||||
{
|
||||
@@ -138,7 +144,7 @@ namespace bnhtrade.Core.Data.Database.FBAInbound
|
||||
}
|
||||
}
|
||||
|
||||
private int InsertShipmentHeaderInfo(Model.AmazonFBAInbound.ShipmentInfo info)
|
||||
private int InsertShipmentHeaderInfo(Model.AmazonFba.ShipmentInfo info)
|
||||
{
|
||||
if (!info.IsSetAll())
|
||||
{
|
||||
@@ -149,7 +155,7 @@ namespace bnhtrade.Core.Data.Database.FBAInbound
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
if (GetPK.ByAmazonShipmentId(info.AmazonShipmentId) != -1)
|
||||
if (GetPK.ByAmazonShipmentId(info.FbaShipmentId) != -1)
|
||||
{
|
||||
throw new Exception("Shipment insert failed, shipment with same Amazon Id already exists.");
|
||||
}
|
||||
@@ -189,10 +195,10 @@ namespace bnhtrade.Core.Data.Database.FBAInbound
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@amazonShipmentCount", sequenceNumber);
|
||||
cmd.Parameters.AddWithValue("@shipmentName", info.ShipmentName);
|
||||
cmd.Parameters.AddWithValue("@shipmentId", info.AmazonShipmentId);
|
||||
cmd.Parameters.AddWithValue("@shipmentId", info.FbaShipmentId);
|
||||
cmd.Parameters.AddWithValue("@centerId", info.DestinationFulfillmentCenterId);
|
||||
cmd.Parameters.AddWithValue("@shipmentStatus", info.ShipmentStatus);
|
||||
cmd.Parameters.AddWithValue("@lastUpdated", info.LastUpdatedUtc);
|
||||
cmd.Parameters.AddWithValue("@lastUpdated", info.LastUpdated.ToUniversalTime());
|
||||
cmd.Parameters.AddWithValue("@isClosed", info.ShipmentIsClosed);
|
||||
|
||||
int tablePk = (int)cmd.ExecuteScalar();
|
||||
@@ -203,9 +209,9 @@ namespace bnhtrade.Core.Data.Database.FBAInbound
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateShipmentHeaderInfo(Model.AmazonFBAInbound.ShipmentInfo info)
|
||||
private void UpdateShipmentHeaderInfo(Model.AmazonFba.ShipmentInfo info)
|
||||
{
|
||||
int tablePK = GetPK.ByAmazonShipmentId(info.AmazonShipmentId);
|
||||
int tablePK = GetPK.ByAmazonShipmentId(info.FbaShipmentId);
|
||||
if (tablePK == -1)
|
||||
{
|
||||
throw new Exception("Shipment insert failed, shipment with same Amazon Id already exists.");
|
||||
@@ -229,7 +235,7 @@ namespace bnhtrade.Core.Data.Database.FBAInbound
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@shipmentName", info.ShipmentName);
|
||||
cmd.Parameters.AddWithValue("@shipmentStatus", info.ShipmentStatus);
|
||||
cmd.Parameters.AddWithValue("@lastUpdated", info.LastUpdatedUtc);
|
||||
cmd.Parameters.AddWithValue("@lastUpdated", info.LastUpdated.ToUniversalTime());
|
||||
cmd.Parameters.AddWithValue("@isClosed", info.ShipmentIsClosed);
|
||||
cmd.Parameters.AddWithValue("@tablePK", tablePK);
|
||||
|
||||
@@ -10,11 +10,14 @@ namespace bnhtrade.Core.Data.Database
|
||||
public class Connection
|
||||
{
|
||||
protected readonly string sqlConnectionString;
|
||||
|
||||
public Connection(string sqlConnectionString)
|
||||
{
|
||||
// setup sql parameters
|
||||
if (sqlConnectionString.Length == 0)
|
||||
{ throw new Exception("Zero length sql connectionstring passed"); }
|
||||
if (string.IsNullOrWhiteSpace(sqlConnectionString))
|
||||
{
|
||||
throw new Exception("Zero length sql connection string passed");
|
||||
}
|
||||
this.sqlConnectionString = sqlConnectionString;
|
||||
}
|
||||
}
|
||||
|
||||
16
src/bnhtrade.Core/Data/Database/Constants.cs
Normal file
16
src/bnhtrade.Core/Data/Database/Constants.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database
|
||||
{
|
||||
public static class Constants
|
||||
{
|
||||
public static int GetProductConditionIdNew()
|
||||
{
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Export
|
||||
{
|
||||
public class CreateAmazonFeedSubmission : Connection
|
||||
{
|
||||
public CreateAmazonFeedSubmission (string sqlConnectionString) : base(sqlConnectionString)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public int Execute(string feedType, Model.Data.DatabaseFileStream fileStreamData)
|
||||
{
|
||||
// write to db
|
||||
int id = 0;
|
||||
var result = new Model.Export.AmazonFeedSubmission();
|
||||
using (var conn = new SqlConnection(sqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
using (var cmd = new SqlCommand(@"
|
||||
INSERT INTO tblExportAmazonFeedSubmission (
|
||||
FileData
|
||||
,FileExtention
|
||||
,FileSize
|
||||
,FileMD5base64
|
||||
,ExportAmazonFeedSubmissionTypeID
|
||||
,ExportAmazonFeedSubmissionStatusID )
|
||||
OUTPUT
|
||||
INSERTED.ExportAmazonFeedSubmissionID
|
||||
,INSERTED.FileGUID
|
||||
VALUES (
|
||||
@fileData
|
||||
,@fileExtention
|
||||
,@fileSize
|
||||
,@fileMD5base64
|
||||
,(SELECT ExportAmazonFeedSubmissionTypeID
|
||||
FROM tblExportAmazonFeedSubmissionType
|
||||
WHERE FeedType = @feedType )
|
||||
,(SELECT ExportAmazonFeedSubmissionStatusID
|
||||
FROM tblExportAmazonFeedSubmissionStatus
|
||||
WHERE FeedProcessingStatus = 'New' )
|
||||
)
|
||||
", conn))
|
||||
{
|
||||
fileStreamData.FileData.Position = 0;
|
||||
cmd.Parameters.AddWithValue("@fileData", fileStreamData.FileData.ToArray());
|
||||
cmd.Parameters.AddWithValue("@fileExtention", fileStreamData.FileExtention);
|
||||
cmd.Parameters.AddWithValue("@fileSize", fileStreamData.FileSize);
|
||||
cmd.Parameters.AddWithValue("@fileMD5base64", fileStreamData.FileMD5base64);
|
||||
cmd.Parameters.AddWithValue("@feedType", feedType);
|
||||
|
||||
using (var reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (!reader.HasRows)
|
||||
throw new Exception("Insert returned no rows");
|
||||
|
||||
reader.Read();
|
||||
id = reader.GetInt32(0);
|
||||
fileStreamData.FileGUID = reader.GetGuid(1);
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,88 +10,15 @@ namespace bnhtrade.Core.Data.Database.Export
|
||||
{
|
||||
public class CreateSalesInvoice : Connection
|
||||
{
|
||||
private Logic.Log.LogEvent log = new Logic.Log.LogEvent();
|
||||
|
||||
public CreateSalesInvoice(string sqlConnectionString) : base(sqlConnectionString)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void SaveInvoice(List<Model.Account.SalesInvoice> invoiceList)
|
||||
public void Execute(List<Model.Account.SalesInvoice> invoiceList)
|
||||
{
|
||||
using (TransactionScope scope = new TransactionScope())
|
||||
{
|
||||
// get table pks for invoice type line and fill in invoice line details
|
||||
var readItemCode = new Data.Database.Account.ReadInvoiceLineItemCode(sqlConnectionString);
|
||||
readItemCode.InsertNewOnNoMatch = true;
|
||||
bool newTypeFound = false;
|
||||
bool newTypeTitleFound = false;
|
||||
for (int i = 0; i < invoiceList.Count(); i++)
|
||||
{
|
||||
for (int j = 0; j < invoiceList[i].InvoiceLineList.Count(); j++)
|
||||
{
|
||||
var itemCodeInfo = readItemCode.ByItemCode(invoiceList[i].InvoiceLineList[j].ItemCode);
|
||||
if (itemCodeInfo.InvoiceLineEntryEnabled == false)
|
||||
{
|
||||
invoiceList[i].InvoiceAmount = invoiceList[i].InvoiceAmount - invoiceList[i].InvoiceLineList[j].GrossTotalAmount;
|
||||
invoiceList[i].InvoiceLineList.RemoveAt(j);
|
||||
j = j - 1;
|
||||
continue;
|
||||
}
|
||||
else if (itemCodeInfo.IsNewReviewRequired)
|
||||
{
|
||||
newTypeFound = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (itemCodeInfo.Title == readItemCode.NewTypeTitle)
|
||||
{ newTypeTitleFound = true; }
|
||||
else
|
||||
{
|
||||
invoiceList[i].InvoiceLineList[j].AccountCode = itemCodeInfo.DefaultAccountCode;
|
||||
invoiceList[i].InvoiceLineList[j].TaxCode = itemCodeInfo.DefaultTaxCode;
|
||||
invoiceList[i].InvoiceLineList[j].Description = itemCodeInfo.Title;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (newTypeFound || newTypeTitleFound)
|
||||
{
|
||||
if (newTypeFound)
|
||||
{
|
||||
log.LogError("New line ItemCode found. Add item code default values and then try again.");
|
||||
}
|
||||
if (newTypeTitleFound)
|
||||
{
|
||||
log.LogError("ItemCode found with the incomplete title '" + readItemCode.NewTypeTitle + "'. Update title and then try again.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// add temp invoice numbers to invoices
|
||||
var sequence = new Programmability.Sequence(sqlConnectionString);
|
||||
for (int i = 0; i < invoiceList.Count(); i++)
|
||||
{
|
||||
if (invoiceList[i].InvoiceNumberIsSet)
|
||||
{
|
||||
var log = new Logic.Log.LogEvent();
|
||||
log.LogError("Unexpected invoice number found.");
|
||||
return;
|
||||
}
|
||||
invoiceList[i].InvoiceNumber = "_tmp" + sequence.GetNext("ExportTempInvoiceNumber").ToString("00000000");
|
||||
}
|
||||
|
||||
// validate the list of invoices
|
||||
var validateInvoice = new Logic.Account.ValidateSalesInvoice();
|
||||
validateInvoice.InvoiceLineDescriptionIsRequired = false;
|
||||
validateInvoice.IsValidInvoice(invoiceList);
|
||||
if (validateInvoice.ErrorListIsSet)
|
||||
{
|
||||
log.LogError("Invalid Sales invoice(s) found during Amazon Settlement process. See extended info.", validateInvoice.ErrorListToString());
|
||||
return;
|
||||
}
|
||||
validateInvoice = null;
|
||||
|
||||
using (SqlConnection sqlConn = new SqlConnection(sqlConnectionString))
|
||||
{
|
||||
sqlConn.Open();
|
||||
@@ -134,7 +61,7 @@ namespace bnhtrade.Core.Data.Database.Export
|
||||
cmd.Parameters.AddWithValue("@currencyCode", invoiceList[i].InvoiceCurrencyCode);
|
||||
cmd.Parameters.AddWithValue("@markComplete", false);
|
||||
cmd.Parameters.AddWithValue("@invoiceNumber", invoiceList[i].InvoiceNumber);
|
||||
cmd.Parameters.AddWithValue("@invoiceAmount", invoiceList[i].InvoiceAmount);
|
||||
cmd.Parameters.AddWithValue("@invoiceAmount", invoiceList[i].InvoiceTotalAmount);
|
||||
|
||||
invoiceId = (int)cmd.ExecuteScalar();
|
||||
}
|
||||
@@ -145,7 +72,7 @@ namespace bnhtrade.Core.Data.Database.Export
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
INSERT INTO tblExportAccountInvoiceLine (
|
||||
ExportAccountInvoiceID
|
||||
,ExportAccountInvoiceLineTypeID
|
||||
,AccountInvoiceLineItemID
|
||||
,NetAmount
|
||||
,AccountChartOfID
|
||||
,TaxAmount
|
||||
@@ -155,9 +82,9 @@ namespace bnhtrade.Core.Data.Database.Export
|
||||
VALUES (
|
||||
@invoiceId
|
||||
,(
|
||||
SELECT ExportAccountInvoiceLineTypeID
|
||||
FROM tblExportAccountInvoiceLineType
|
||||
WHERE MatchString = @itemCode
|
||||
SELECT AccountInvoiceLineItemID
|
||||
FROM tblAccountInvoiceLineItem
|
||||
WHERE ItemCode = @itemCode
|
||||
)
|
||||
,@netAmount
|
||||
,(
|
||||
@@ -176,10 +103,10 @@ namespace bnhtrade.Core.Data.Database.Export
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@invoiceID", invoiceId);
|
||||
cmd.Parameters.AddWithValue("@itemCode", invoiceList[i].InvoiceLineList[j].ItemCode);
|
||||
cmd.Parameters.AddWithValue("@netAmount", invoiceList[i].InvoiceLineList[j].TotalNetAmount);
|
||||
cmd.Parameters.AddWithValue("@accountCode", invoiceList[i].InvoiceLineList[j].AccountCode);
|
||||
cmd.Parameters.AddWithValue("@netAmount", invoiceList[i].InvoiceLineList[j].UnitAmount);
|
||||
cmd.Parameters.AddWithValue("@accountCode", invoiceList[i].InvoiceLineList[j].AccountCode.AccountCodeId);
|
||||
cmd.Parameters.AddWithValue("@taxAmount", invoiceList[i].InvoiceLineList[j].TaxAmount);
|
||||
cmd.Parameters.AddWithValue("@taxCode", invoiceList[i].InvoiceLineList[j].TaxCode);
|
||||
cmd.Parameters.AddWithValue("@taxCode", invoiceList[i].InvoiceLineList[j].TaxCode.TaxCode);
|
||||
|
||||
int lineId = (int)cmd.ExecuteScalar();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Dapper;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Export
|
||||
{
|
||||
public class ReadAmazonFeedSubmission : Connection
|
||||
{
|
||||
public ReadAmazonFeedSubmission(string sqlConnectionString) : base(sqlConnectionString)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public bool RetriveFile { get; set; } = false;
|
||||
|
||||
public List<Model.Export.AmazonFeedSubmission> ByAmazonFeedSubmissionId(List<string> submissionId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public List<Model.Export.AmazonFeedSubmission> GetOpenFeeds()
|
||||
{
|
||||
string sql = @"
|
||||
WHERE tblExportAmazonFeedSubmissionStatus.FeedComplete = @feedComplete
|
||||
AND FeedSubmissionId IS NOT NULL;";
|
||||
|
||||
var parameters = new Dictionary<string, object> { { "@feedComplete", false } };
|
||||
|
||||
return Execute(sql, parameters);
|
||||
}
|
||||
|
||||
private List<Model.Export.AmazonFeedSubmission> Execute(string sqlWhereClause, Dictionary<string, object> parameters)
|
||||
{
|
||||
var returnList = new List<Model.Export.AmazonFeedSubmission>();
|
||||
|
||||
// build the sql string
|
||||
string sql = @"
|
||||
SELECT tblExportAmazonFeedSubmissionType.FeedType
|
||||
,tblExportAmazonFeedSubmission.FeedSubmissionId
|
||||
,tblExportAmazonFeedSubmissionStatus.FeedProcessingStatus
|
||||
,tblExportAmazonFeedSubmission.SubmittedDate
|
||||
,tblExportAmazonFeedSubmission.StartedProcessingDate
|
||||
,tblExportAmazonFeedSubmission.CompletedProcessingDate";
|
||||
|
||||
if (RetriveFile)
|
||||
sql += @"
|
||||
,tblExportAmazonFeedSubmission.FileGUID
|
||||
,tblExportAmazonFeedSubmission.FileData
|
||||
,tblExportAmazonFeedSubmission.FileExtention
|
||||
,tblExportAmazonFeedSubmission.FileSize
|
||||
,tblExportAmazonFeedSubmission.FileMD5base64";
|
||||
|
||||
sql += @"
|
||||
FROM tblExportAmazonFeedSubmission
|
||||
INNER JOIN tblExportAmazonFeedSubmissionStatus
|
||||
ON tblExportAmazonFeedSubmission.ExportAmazonFeedSubmissionStatusID
|
||||
= tblExportAmazonFeedSubmissionStatus.ExportAmazonFeedSubmissionStatusID
|
||||
INNER JOIN tblExportAmazonFeedSubmissionType
|
||||
ON tblExportAmazonFeedSubmission.ExportAmazonFeedSubmissionTypeID
|
||||
= tblExportAmazonFeedSubmissionType.ExportAmazonFeedSubmissionTypeID";
|
||||
|
||||
sql += sqlWhereClause;
|
||||
|
||||
using (var conn = new SqlConnection(sqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
using (var cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
if (parameters != null || !parameters.Any())
|
||||
{
|
||||
foreach(var parameter in parameters)
|
||||
{
|
||||
cmd.Parameters.AddWithValue(parameter.Key, parameter.Value);
|
||||
}
|
||||
}
|
||||
|
||||
using (var reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (!reader.HasRows)
|
||||
return returnList;
|
||||
|
||||
while (reader.Read())
|
||||
{
|
||||
var submission = new Model.Export.AmazonFeedSubmission();
|
||||
|
||||
if (!reader.IsDBNull(0))
|
||||
submission.FeedType = reader.GetString(0);
|
||||
if (!reader.IsDBNull(1))
|
||||
submission.FeedSubmissionId = reader.GetString(1);
|
||||
if (!reader.IsDBNull(2))
|
||||
submission.FeedProcessingStatus = reader.GetString(2);
|
||||
if (!reader.IsDBNull(3))
|
||||
submission.SubmittedDate = DateTime.SpecifyKind(reader.GetDateTime(3), DateTimeKind.Utc);
|
||||
if (!reader.IsDBNull(4))
|
||||
submission.StartedProcessingDate = DateTime.SpecifyKind(reader.GetDateTime(4), DateTimeKind.Utc);
|
||||
if (!reader.IsDBNull(5))
|
||||
submission.CompletedProcessingDate = DateTime.SpecifyKind(reader.GetDateTime(5), DateTimeKind.Utc);
|
||||
|
||||
if (RetriveFile)
|
||||
{
|
||||
var file = new Model.Data.DatabaseFileStream();
|
||||
|
||||
file.FileGUID = reader.GetGuid(6);
|
||||
byte[] fileData = (byte[])reader[7];
|
||||
file.FileData = new System.IO.MemoryStream(fileData);
|
||||
file.FileExtention = reader.GetString(8);
|
||||
file.FileSize = reader.GetInt32(9);
|
||||
file.FileMD5base64 = reader.GetString(10);
|
||||
|
||||
submission.File = file;
|
||||
}
|
||||
returnList.Add(submission);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnList;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Export
|
||||
{
|
||||
public class UpdateAmazonFeedSubmission : Connection
|
||||
{
|
||||
public UpdateAmazonFeedSubmission(string sqlConnectionString) : base(sqlConnectionString)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void AddAmazonFeedId(int exportAmazonFeedSubmissionID, string amazonFeedId)
|
||||
{
|
||||
using (var conn = new SqlConnection(sqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
using (var cmd = new SqlCommand(@"
|
||||
SELECT COUNT (ExportAmazonFeedSubmissionID)
|
||||
FROM tblExportAmazonFeedSubmission
|
||||
WHERE FeedSubmissionId = @amazonFeedId", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@amazonFeedId", amazonFeedId);
|
||||
|
||||
int i = (int)cmd.ExecuteScalar();
|
||||
|
||||
if (i > 0)
|
||||
throw new Exception("Amazon submission Id already exists in table");
|
||||
}
|
||||
|
||||
using (var cmd = new SqlCommand(@"
|
||||
UPDATE tblExportAmazonFeedSubmission
|
||||
SET FeedSubmissionId = @amazonFeedId
|
||||
WHERE ExportAmazonFeedSubmissionID=@exportAmazonFeedSubmissionID", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@amazonFeedId", amazonFeedId);
|
||||
cmd.Parameters.AddWithValue("@exportAmazonFeedSubmissionID", exportAmazonFeedSubmissionID);
|
||||
|
||||
int i = cmd.ExecuteNonQuery();
|
||||
|
||||
if (i == 0)
|
||||
throw new Exception("Error updating table.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateStatusInfo(Model.Export.AmazonFeedSubmission feedSubmission)
|
||||
{
|
||||
UpdateStatusInfo(new List<Model.Export.AmazonFeedSubmission> { feedSubmission });
|
||||
}
|
||||
|
||||
public void UpdateStatusInfo(List<Model.Export.AmazonFeedSubmission> feedSubmissionList)
|
||||
{
|
||||
if (feedSubmissionList == null || !feedSubmissionList.Any())
|
||||
return;
|
||||
|
||||
using (var conn = new SqlConnection(sqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
for (int i = 0; i < feedSubmissionList.Count; i++)
|
||||
{
|
||||
if (!feedSubmissionList[i].IsSetFeedSubmissionId)
|
||||
throw new Exception("Amazon Feed Submission Id required");
|
||||
|
||||
if (!feedSubmissionList[i].IsSetFeedProcessingStatus)
|
||||
throw new Exception("Amazon Feed stauts required");
|
||||
|
||||
string sql = @"
|
||||
UPDATE tblExportAmazonFeedSubmission
|
||||
SET ExportAmazonFeedSubmissionStatusID =
|
||||
(SELECT ExportAmazonFeedSubmissionStatusID
|
||||
FROM tblExportAmazonFeedSubmissionStatus
|
||||
WHERE FeedProcessingStatus = @feedProcessingStatus )
|
||||
,SubmittedDate = @submittedDate
|
||||
,StartedProcessingDate = @startedProcessingDate
|
||||
,CompletedProcessingDate = @completedProcessingDate
|
||||
WHERE FeedSubmissionId = @feedSubmissionId;";
|
||||
|
||||
using (var cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@feedSubmissionId", feedSubmissionList[i].FeedSubmissionId);
|
||||
cmd.Parameters.AddWithValue("@feedProcessingStatus", feedSubmissionList[i].FeedProcessingStatus);
|
||||
|
||||
if (!feedSubmissionList[i].IsSetSubmittedDate) { cmd.Parameters.AddWithValue("@submittedDate", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@submittedDate", feedSubmissionList[i].SubmittedDate.ToUniversalTime()); }
|
||||
|
||||
if (!feedSubmissionList[i].IsSetStartedProcessingDate) { cmd.Parameters.AddWithValue("@startedProcessingDate", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@startedProcessingDate", feedSubmissionList[i].StartedProcessingDate.ToUniversalTime()); }
|
||||
|
||||
if (!feedSubmissionList[i].IsSetCompletedProcessingDate) { cmd.Parameters.AddWithValue("@completedProcessingDate", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@completedProcessingDate", feedSubmissionList[i].CompletedProcessingDate.ToUniversalTime()); }
|
||||
|
||||
int j = cmd.ExecuteNonQuery();
|
||||
|
||||
if (j == 0)
|
||||
throw new Exception("Error updating table.");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,157 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.FBAInbound
|
||||
{
|
||||
public class GetShipmentHeaderInfo : Connection
|
||||
{
|
||||
private List<string> shipmentIdList;
|
||||
public GetShipmentHeaderInfo(string sqlConnectionString) : base(sqlConnectionString) { }
|
||||
/// <summary>
|
||||
/// Return active shipments only. Default is false.
|
||||
/// </summary>
|
||||
public bool ActiveShipments { get; set; } = false;
|
||||
public bool IsSetActiveShipments { get { return true; } }
|
||||
public bool IsSetShipmentIdList
|
||||
{
|
||||
get
|
||||
{
|
||||
if (ShipmentIdList == null || !ShipmentIdList.Any()) { return false; }
|
||||
else { return true; }
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Filter results by Amazon's shipment Id.
|
||||
/// </summary>
|
||||
public List<string> ShipmentIdList
|
||||
{
|
||||
get { return shipmentIdList; }
|
||||
set
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
// clean list
|
||||
shipmentIdList = new List<string>();
|
||||
foreach (string item in value)
|
||||
{
|
||||
if (item.Length > 0)
|
||||
{
|
||||
shipmentIdList.Add(item);
|
||||
}
|
||||
}
|
||||
if (!ShipmentIdList.Any())
|
||||
{
|
||||
shipmentIdList = null;
|
||||
throw new Exception("Invalid shipment Id set");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Retrives table primary key 'AmazonShipmentID' for tblAmazonShipment
|
||||
/// </summary>
|
||||
/// <param name="amazonShipmentId">Amazon's inbound FBA shipment Id.</param>
|
||||
/// <returns>Primary key or -1 if match isn't found.</returns>
|
||||
public List<Model.AmazonFBAInbound.ShipmentInfo> Execute()
|
||||
{
|
||||
// build the sql string
|
||||
int countShipId = 0;
|
||||
string sqlString = @"
|
||||
SELECT
|
||||
AmazonShipmentID
|
||||
,ShipmentName
|
||||
,ShipmentId
|
||||
,CenterId
|
||||
,ShipmentStatus
|
||||
,LastUpdated
|
||||
,IsClosed
|
||||
FROM
|
||||
tblAmazonShipment
|
||||
WHERE
|
||||
1 = 1";
|
||||
if (ActiveShipments)
|
||||
{
|
||||
sqlString = sqlString + @"
|
||||
AND IsClosed = 0";
|
||||
}
|
||||
var dicShipIdByParameterString = new Dictionary<string, string>();
|
||||
if (IsSetShipmentIdList)
|
||||
{
|
||||
foreach (string item in ShipmentIdList)
|
||||
{
|
||||
countShipId = countShipId + 1;
|
||||
string parameterString = "@shipmentId" + countShipId;
|
||||
dicShipIdByParameterString.Add(parameterString, item);
|
||||
if (countShipId == 1)
|
||||
{
|
||||
sqlString = sqlString + @"
|
||||
AND ( ShipmentId = " + parameterString;
|
||||
}
|
||||
else
|
||||
{
|
||||
sqlString = sqlString + @"
|
||||
OR ShipmentId = " + parameterString;
|
||||
}
|
||||
}
|
||||
if (countShipId > 0)
|
||||
{
|
||||
sqlString = sqlString + " )";
|
||||
}
|
||||
}
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(sqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
using (SqlCommand cmd = new SqlCommand(sqlString, conn))
|
||||
{
|
||||
// add shipId parameters
|
||||
if (ShipmentIdList.Any())
|
||||
{
|
||||
foreach (var item in dicShipIdByParameterString)
|
||||
{
|
||||
cmd.Parameters.AddWithValue(item.Key, item.Value);
|
||||
}
|
||||
}
|
||||
|
||||
using (var reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (!reader.HasRows)
|
||||
{
|
||||
// no records
|
||||
return null;
|
||||
}
|
||||
|
||||
var infoList = new List<Model.AmazonFBAInbound.ShipmentInfo>();
|
||||
while (reader.Read())
|
||||
{
|
||||
var info = new Model.AmazonFBAInbound.ShipmentInfo();
|
||||
|
||||
int tablePK = reader.GetInt32(0);
|
||||
info.ShipmentName = reader.GetString(1);
|
||||
info.AmazonShipmentId = reader.GetString(2);
|
||||
info.DestinationFulfillmentCenterId = reader.GetString(3);
|
||||
info.ShipmentStatus = reader.GetString(4);
|
||||
info.LastUpdatedUtc = reader.GetDateTime(5);
|
||||
bool dbIsClosed = reader.GetBoolean(6);
|
||||
|
||||
// db consistancy check
|
||||
if (dbIsClosed != info.ShipmentIsClosed)
|
||||
{
|
||||
throw new Exception("Data inconstitancy in database: check shipment IsClosed where AmazonShipmentID=" + tablePK);
|
||||
}
|
||||
|
||||
// update cache
|
||||
infoList.Add(info);
|
||||
}
|
||||
return infoList;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Import
|
||||
{
|
||||
public class ReadFbaInventoryAge : Connection
|
||||
{
|
||||
public ReadFbaInventoryAge(string sqlConnectionString): base(sqlConnectionString)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public (int MinAge, int MaxAge)? BySkuNumber(string skuNumber, string orderChannel)
|
||||
{
|
||||
int minAge = 0;
|
||||
int maxAge = 0;
|
||||
|
||||
using (var conn = new SqlConnection(sqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
using (var cmd03 = new SqlCommand(@"
|
||||
SELECT [snapshot-date]
|
||||
,[inv-age-0-to-90-days]
|
||||
,[inv-age-91-to-180-days]
|
||||
,[inv-age-181-to-270-days]
|
||||
,[inv-age-271-to-365-days]
|
||||
,[inv-age-365-plus-days]
|
||||
FROM tblImportFbaInventoryAgeReport
|
||||
WHERE sku = @skuNumber AND marketplace = @orderChannel
|
||||
", conn))
|
||||
{
|
||||
cmd03.Parameters.AddWithValue("@skuNumber", skuNumber);
|
||||
cmd03.Parameters.AddWithValue("@orderChannel", orderChannel);
|
||||
|
||||
using (var reader03 = cmd03.ExecuteReader())
|
||||
{
|
||||
if (reader03.Read())
|
||||
{
|
||||
// final min age
|
||||
if (reader03.GetInt32(1) > 0) { minAge = 1; }
|
||||
else
|
||||
{
|
||||
if (reader03.GetInt32(2) > 0) { minAge = 91; }
|
||||
else
|
||||
{
|
||||
if (reader03.GetInt32(3) > 0) { minAge = 181; }
|
||||
else
|
||||
{
|
||||
if (reader03.GetInt32(4) > 0) { minAge = 271; }
|
||||
else
|
||||
{
|
||||
if (reader03.GetInt32(5) > 0) { minAge = 366; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//find max age
|
||||
if (reader03.GetInt32(5) > 0) { maxAge = 2147483647; }
|
||||
else
|
||||
{
|
||||
if (reader03.GetInt32(4) > 0) { maxAge = 365; }
|
||||
else
|
||||
{
|
||||
if (reader03.GetInt32(3) > 0) { maxAge = 270; }
|
||||
else
|
||||
{
|
||||
if (reader03.GetInt32(2) > 0) { maxAge = 180; }
|
||||
else
|
||||
{
|
||||
if (reader03.GetInt32(1) > 0) { maxAge = 90; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return (minAge, maxAge);
|
||||
}
|
||||
}
|
||||
}
|
||||
117
src/bnhtrade.Core/Data/Database/Import/ReadFbaSaleShipment.cs
Normal file
117
src/bnhtrade.Core/Data/Database/Import/ReadFbaSaleShipment.cs
Normal file
@@ -0,0 +1,117 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Dapper;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Import
|
||||
{
|
||||
public class ReadFbaSaleShipment : Connection
|
||||
{
|
||||
public ReadFbaSaleShipment(string sqlConnectionString): base(sqlConnectionString)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public Dictionary<string, decimal> GetMaxSalePrice(List<string> skuNumber, int timePeriodDay)
|
||||
{
|
||||
var returnList = new Dictionary<string, decimal>();
|
||||
|
||||
if (skuNumber == null || !skuNumber.Any())
|
||||
{
|
||||
return returnList;
|
||||
}
|
||||
|
||||
string sql = @"
|
||||
SELECT sku
|
||||
,Max(ISNULL([tblImportFbaSaleShipment].[item-price], 0) + ISNULL([tblImportFbaSaleShipment].[item-tax], 0)) AS Expr1
|
||||
FROM tblImportFbaSaleShipment
|
||||
WHERE (
|
||||
(sku IN (";
|
||||
|
||||
for (int i = 0; i < skuNumber.Count; i++)
|
||||
{
|
||||
if (!(i + 1 == skuNumber.Count))
|
||||
{
|
||||
sql += "@skuNumber" + i + ", ";
|
||||
}
|
||||
else
|
||||
{
|
||||
sql += "@skuNumber" + i + "))";
|
||||
}
|
||||
}
|
||||
|
||||
sql += @"
|
||||
AND ((tblImportFbaSaleShipment.[shipment-date]) >= @shipDateFilter)
|
||||
)
|
||||
GROUP BY sku;";
|
||||
|
||||
using (var conn = new SqlConnection(sqlConnectionString))
|
||||
{
|
||||
using (var cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
for (int i = 0; i < skuNumber.Count; i++)
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@skuNumber" + i, skuNumber[i]);
|
||||
}
|
||||
cmd.Parameters.AddWithValue("@shipDateFilter", DateTime.Today.AddDays(timePeriodDay * -1));
|
||||
|
||||
using (var reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (!reader.HasRows)
|
||||
{
|
||||
return returnList;
|
||||
}
|
||||
|
||||
while (reader.Read())
|
||||
{
|
||||
decimal price = reader.GetDecimal(1);
|
||||
if (price > 0)
|
||||
{
|
||||
returnList.Add(reader.GetString(0), price);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnList;
|
||||
}
|
||||
|
||||
public Dictionary<string, int> GetSaleCount(List<string> skuNumber, DateTime periodStart, DateTime periodEnd)
|
||||
{
|
||||
var returnList = new Dictionary<string, int>();
|
||||
|
||||
if (skuNumber == null || !skuNumber.Any())
|
||||
{
|
||||
return returnList;
|
||||
}
|
||||
|
||||
string sql = @"
|
||||
SELECT sku
|
||||
,Count(1) AS CountOfSku
|
||||
FROM tblImportFbaSaleShipment
|
||||
WHERE (
|
||||
(sku IN @skuNumber)
|
||||
AND (
|
||||
(tblImportFbaSaleShipment.[shipment-date] >= @periodStart)
|
||||
AND tblImportFbaSaleShipment.[shipment-date] <= @periodEnd
|
||||
)
|
||||
)
|
||||
GROUP BY sku;";
|
||||
|
||||
using (var conn = new SqlConnection(sqlConnectionString))
|
||||
{
|
||||
var param = new DynamicParameters();
|
||||
param.Add("@skuNumber", skuNumber);
|
||||
param.Add("@periodStart", periodStart.ToUniversalTime());
|
||||
param.Add("@periodEnd", periodEnd.ToUniversalTime());
|
||||
|
||||
return conn.Query(sql, param).ToDictionary(
|
||||
row => (string)row.sku,
|
||||
row => (int)row.CountOfSku);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Product
|
||||
{
|
||||
public class CreateCompetitivePrice : Connection
|
||||
{
|
||||
public CreateCompetitivePrice(string sqlConnectionString) : base(sqlConnectionString)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public int ProductCompetitivePriceSet(int productId, int conditionId, decimal price, bool isBuyBoxPrice, DateTime? priceDate = null)
|
||||
{
|
||||
DateTime dt = new DateTime();
|
||||
if (priceDate == null || priceDate == default(DateTime))
|
||||
{
|
||||
dt = DateTime.Now;
|
||||
}
|
||||
else
|
||||
{
|
||||
dt = (DateTime)priceDate;
|
||||
}
|
||||
|
||||
if (priceDate.Value.Kind == DateTimeKind.Unspecified)
|
||||
{
|
||||
throw new Exception("Unspecified DateTimeKind");
|
||||
}
|
||||
|
||||
using (SqlConnection sqlConn = new SqlConnection(sqlConnectionString))
|
||||
{
|
||||
sqlConn.Open();
|
||||
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
UPDATE Table1
|
||||
SET (
|
||||
CompetitivePrice = @price
|
||||
,IsBuyBoxPrice = @isBuyBoxPrice
|
||||
)
|
||||
OUTPUT INSERTED.ProductPriceCompetitiveID
|
||||
WHERE ProductID = @productId
|
||||
AND SkuConditionID = @conditionId
|
||||
AND PriceDate = @priceDate
|
||||
|
||||
IF @@ROWCOUNT = 0
|
||||
INSERT INTO tblProductPriceCompetitive (
|
||||
ProductID
|
||||
,SkuConditionID
|
||||
,CompetitivePrice
|
||||
,PriceDate
|
||||
,IsBuyBoxPrice
|
||||
)
|
||||
OUTPUT INSERTED.ProductPriceCompetitiveID
|
||||
VALUES (
|
||||
@productId
|
||||
,@conditionId
|
||||
,@price
|
||||
,@priceDate
|
||||
,@isBuyBoxPrice
|
||||
);"
|
||||
, sqlConn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@productId", productId);
|
||||
cmd.Parameters.AddWithValue("@conditionId", conditionId);
|
||||
cmd.Parameters.AddWithValue("@price", price);
|
||||
cmd.Parameters.AddWithValue("@priceDate", dt.ToUniversalTime());
|
||||
cmd.Parameters.AddWithValue("@isBuyBoxPrice", isBuyBoxPrice);
|
||||
|
||||
return (int)cmd.ExecuteScalar();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
131
src/bnhtrade.Core/Data/Database/Product/ReadCompetitivePrice.cs
Normal file
131
src/bnhtrade.Core/Data/Database/Product/ReadCompetitivePrice.cs
Normal file
@@ -0,0 +1,131 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Dapper;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Product
|
||||
{
|
||||
public class ReadCompetitivePrice : Connection
|
||||
{
|
||||
public ReadCompetitivePrice(string sqlConnectionString) : base(sqlConnectionString)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public List<Model.Product.CompetitivePrice> Execute(List<(int productId, int conditionId)> productIdAndConditionId)
|
||||
{
|
||||
int maxParameterCount = 2100;
|
||||
int parameterPerPrice = 2;
|
||||
int maxQuery = (int)decimal.Round(maxParameterCount / parameterPerPrice) - 1;
|
||||
|
||||
var resultList = new List<Model.Product.CompetitivePrice>();
|
||||
|
||||
if (productIdAndConditionId == null)
|
||||
{
|
||||
return resultList;
|
||||
}
|
||||
|
||||
if (productIdAndConditionId.Count == 0)
|
||||
{
|
||||
return resultList;
|
||||
}
|
||||
|
||||
if (productIdAndConditionId.Count <= maxQuery)
|
||||
{
|
||||
return ExecuteSub(productIdAndConditionId);
|
||||
}
|
||||
else
|
||||
{
|
||||
var partialList = new List<(int productId, int conditionId)>();
|
||||
int queryCount = 0;
|
||||
|
||||
for (int i= 0; i < productIdAndConditionId.Count; i++)
|
||||
{
|
||||
queryCount++;
|
||||
partialList.Add(productIdAndConditionId[i]);
|
||||
if (queryCount == maxQuery)
|
||||
{
|
||||
resultList.AddRange(ExecuteSub(partialList));
|
||||
partialList = new List<(int productId, int conditionId)>();
|
||||
queryCount = 0;
|
||||
}
|
||||
}
|
||||
if (queryCount > 0)
|
||||
{
|
||||
resultList.AddRange(ExecuteSub(partialList));
|
||||
}
|
||||
return resultList;
|
||||
}
|
||||
}
|
||||
|
||||
private List<Model.Product.CompetitivePrice> ExecuteSub(List<(int productId, int conditionId)> productIdAndConditionId)
|
||||
{
|
||||
var resultList = new List<Model.Product.CompetitivePrice>();
|
||||
|
||||
// build the sql string
|
||||
string sql = @"
|
||||
SELECT t.CompetitivePrice, t.PriceDate, t.ProductID, t.SkuConditionID
|
||||
FROM tblProductPriceCompetitive AS t INNER JOIN (SELECT ProductID, SkuConditionID, Max(PriceDate) AS MaxOfPriceDate
|
||||
FROM tblProductPriceCompetitive ";
|
||||
|
||||
for(int i = 0; i < productIdAndConditionId.Count; i++)
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
sql += @"
|
||||
WHERE (ProductID=@productId" + i + " AND SkuConditionID=@conditionId" + i + ")";
|
||||
}
|
||||
else
|
||||
{
|
||||
sql += @"
|
||||
OR (ProductID=@productId" + i + " AND SkuConditionID=@conditionId" + i + ")";
|
||||
}
|
||||
}
|
||||
sql += @"
|
||||
GROUP BY ProductID , SkuConditionID) AS a
|
||||
ON (t.PriceDate = a.MaxOfPriceDate)
|
||||
AND (t.ProductID = a.ProductID)
|
||||
AND (t.SkuConditionID = a.SkuConditionID)";
|
||||
|
||||
|
||||
using (SqlConnection sqlConn = new SqlConnection(sqlConnectionString))
|
||||
{
|
||||
sqlConn.Open();
|
||||
|
||||
using (SqlCommand cmd = new SqlCommand(sql, sqlConn))
|
||||
{
|
||||
for (int i = 0; i < productIdAndConditionId.Count; i++)
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@productId" + i, productIdAndConditionId[i].productId);
|
||||
cmd.Parameters.AddWithValue("@conditionId" + i, productIdAndConditionId[i].conditionId);
|
||||
}
|
||||
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (!reader.HasRows)
|
||||
{
|
||||
return resultList;
|
||||
}
|
||||
|
||||
while (reader.Read())
|
||||
{
|
||||
var result = new Model.Product.CompetitivePrice();
|
||||
|
||||
result.ConditionId = reader.GetInt32(3);
|
||||
result.Price = reader.GetDecimal(0);
|
||||
result.PriceDatetime = DateTime.SpecifyKind(reader.GetDateTime(1), DateTimeKind.Utc);
|
||||
result.ProductId = reader.GetInt32(2);
|
||||
result.PriceIsEstimated = false;
|
||||
|
||||
resultList.Add(result);
|
||||
}
|
||||
return resultList;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.SKU
|
||||
namespace bnhtrade.Core.Data.Database.Sku
|
||||
{
|
||||
public class GetSkuId
|
||||
{
|
||||
|
||||
@@ -5,7 +5,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.SKU
|
||||
namespace bnhtrade.Core.Data.Database.Sku
|
||||
{
|
||||
class GetSku : Connection
|
||||
{
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Data.SqlClient;
|
||||
using System.Transactions;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Sku.Price
|
||||
{
|
||||
public class CreatePricingDetail : Connection
|
||||
{
|
||||
public CreatePricingDetail(string sqlConnectionString) : base(sqlConnectionString)
|
||||
{
|
||||
}
|
||||
|
||||
public void Executue(List<Model.Sku.Price.PriceInfo> newInfo)
|
||||
{
|
||||
if (newInfo == null || !newInfo.Any())
|
||||
{ return; }
|
||||
|
||||
using (var scope = new TransactionScope())
|
||||
using (var conn = new SqlConnection(sqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
// write new item to table
|
||||
for (int i = 0; i < newInfo.Count(); i++)
|
||||
{
|
||||
string sql = @"
|
||||
INSERT INTO tblSkuPriceType (
|
||||
SkuID
|
||||
,[OrderChannelID]
|
||||
,[PriceInfoTimeStamp]
|
||||
,[OrderChannelQuantity]
|
||||
,[UnitPurchaseCost]
|
||||
,[UnitMinPriceProfit]
|
||||
,[UnitMinPriceCost]
|
||||
,[UnitMinPriceDestory]
|
||||
,[InventoryAgeMin]
|
||||
,[InventoryAgeMax]
|
||||
,[SkuPriceTypeID]
|
||||
,[CompetitivePrice]
|
||||
,[MinPrice]
|
||||
,[MaxPrice]
|
||||
,[RepriceIncrement]
|
||||
,[ReviewRequired]
|
||||
)
|
||||
VALUES (
|
||||
(SELECT skuSkuID FROM tblSku WHERE skuSkuNumber=@skuNumber)
|
||||
,(SELECT OrderChannelID FROM tblOrderChannel WHERE OrderChannel=@orderChannel)
|
||||
,@priceInfoTimeStamp
|
||||
,@orderChannelQuantity
|
||||
,@unitPurchaseCost
|
||||
,@unitMinPriceProfit
|
||||
,@unitMinPriceCost
|
||||
,@unitMinPriceDestory
|
||||
,@inventoryAgeMin
|
||||
,@inventoryAgeMax
|
||||
,@skuPriceTypeID
|
||||
,@competitivePrice
|
||||
,@minPrice
|
||||
,@maxPrice
|
||||
,@repriceIncrement
|
||||
,@reviewRequired
|
||||
);";
|
||||
|
||||
using (var cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@skuNumber", newInfo[i].SkuNumber);
|
||||
cmd.Parameters.AddWithValue("@orderChannel", newInfo[i].OrderChannel);
|
||||
cmd.Parameters.AddWithValue("@priceInfoTimeStamp", newInfo[i].PriceInfoTimeStamp);
|
||||
cmd.Parameters.AddWithValue("@orderChannelQuantity", newInfo[i].OrderChannelQuantity);
|
||||
cmd.Parameters.AddWithValue("@unitPurchaseCost", newInfo[i].UnitPurchaseCost);
|
||||
cmd.Parameters.AddWithValue("@unitMinPriceProfit", newInfo[i].UnitMinPriceProfit);
|
||||
cmd.Parameters.AddWithValue("@unitMinPriceCost", newInfo[i].UnitMinPriceCost);
|
||||
cmd.Parameters.AddWithValue("@unitMinPriceDestory", newInfo[i].UnitMinPriceDestory);
|
||||
cmd.Parameters.AddWithValue("@inventoryAgeMin", newInfo[i].InventoryAgeMin);
|
||||
cmd.Parameters.AddWithValue("@inventoryAgeMax", newInfo[i].InventoryAgeMax);
|
||||
cmd.Parameters.AddWithValue("@skuPriceTypeID", newInfo[i].PriceTypeId);
|
||||
cmd.Parameters.AddWithValue("@competitivePrice", newInfo[i].CompetitivePrice);
|
||||
cmd.Parameters.AddWithValue("@minPrice", newInfo[i].MinPrice);
|
||||
cmd.Parameters.AddWithValue("@maxPrice", newInfo[i].MaxPrice);
|
||||
cmd.Parameters.AddWithValue("@repriceIncrement", newInfo[i].RepriceIncrement);
|
||||
cmd.Parameters.AddWithValue("@reviewRequired", newInfo[i].ReviewRequired);
|
||||
|
||||
int j = cmd.ExecuteNonQuery();
|
||||
|
||||
if (j < 1)
|
||||
{
|
||||
throw new Exception("Failed database insert statement");
|
||||
}
|
||||
}
|
||||
}
|
||||
scope.Complete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
98
src/bnhtrade.Core/Data/Database/SKU/Price/ReadParameter.cs
Normal file
98
src/bnhtrade.Core/Data/Database/SKU/Price/ReadParameter.cs
Normal file
@@ -0,0 +1,98 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Dapper;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Sku.Price
|
||||
{
|
||||
public class ReadParameter : Connection
|
||||
{
|
||||
public ReadParameter(string sqlConnectionString) : base(sqlConnectionString)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public List<Model.Sku.Price.SkuPriceParameter> Execute()
|
||||
{
|
||||
string stringSql = @"
|
||||
SELECT
|
||||
b.SkuID AS SkuId
|
||||
,b.SkuTotalQuantity AS TotalQuantity
|
||||
,b.SkuTotalCost AS TotalCost
|
||||
,b.SkuAvgUnitCost AS UnitCostAverage
|
||||
,tblSku.skuSkuNumber AS SkuNumber
|
||||
,tblSku.skuProductID AS ProductId
|
||||
,tblSku.skuSkuConditionID AS ConditionId
|
||||
,tblSku.AccountTaxCodeID AS TaxCodeId
|
||||
,tblProductCategory.ProfitMinPercent AS ProfitMargin
|
||||
,tblProductCategory.ProfitMinAmount AS PriceMinProfit
|
||||
,(tblAmazonFeeEstimate.ReferralFee / tblAmazonFeeEstimate.PriceToEstimateFeeListingPrice) As AgentFeeMargin
|
||||
,(tblAmazonFeeEstimate.VariableClosingFee + tblAmazonFeeEstimate.PerItemFee + tblAmazonFeeEstimate.FBAFee + tblAmazonFeeEstimate.OtherFee_Exception) AS AgentFeeFixed
|
||||
,tblAccountTaxCode.TaxRateMultiplierGross AS VatMargin
|
||||
,tblAccountTaxCode.TaxRateName AS TaxRateName
|
||||
,tblSkuCondition.IsFixedPrice AS IsFixedPrice
|
||||
,tblSkuCondition.CompetitivePriceMultiplierNew
|
||||
FROM
|
||||
(((((
|
||||
SELECT
|
||||
a.SkuID,
|
||||
Sum(a.SumOfQuantity) AS SkuTotalQuantity,
|
||||
Sum(a.QuanityTimesUnitCost) AS SkuTotalCost,
|
||||
Sum(a.QuanityTimesUnitCost)/Sum(a.SumOfQuantity) AS SkuAvgUnitCost
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
tblStock.SkuID,
|
||||
Sum(tblStockJournalPost.Quantity) AS SumOfQuantity,
|
||||
tblStockJournal.StockID, tblAccountStockCost.AmountUnit,
|
||||
Sum([tblStockJournalPost].[Quantity])*[tblAccountStockCost].[AmountUnit] AS QuanityTimesUnitCost
|
||||
FROM
|
||||
(((tblStockJournalPost
|
||||
INNER JOIN tblStockStatus
|
||||
ON tblStockJournalPost.StockStatusID = tblStockStatus.StockStatusID)
|
||||
INNER JOIN tblStockJournal ON tblStockJournalPost.StockJournalID = tblStockJournal.StockJournalID)
|
||||
INNER JOIN tblAccountStockCost ON tblStockJournal.StockID = tblAccountStockCost.StockID)
|
||||
INNER JOIN tblStock ON tblAccountStockCost.StockID = tblStock.StockID
|
||||
WHERE
|
||||
tblStockStatus.StockStatusTypeID=3
|
||||
OR tblStockStatus.StockStatusTypeID=4
|
||||
GROUP BY
|
||||
tblStockJournal.StockID,
|
||||
tblAccountStockCost.AmountUnit,
|
||||
tblStock.SkuID
|
||||
HAVING
|
||||
Sum(tblStockJournalPost.Quantity)>0
|
||||
) a
|
||||
GROUP BY
|
||||
a.SkuID
|
||||
) b
|
||||
INNER JOIN tblSku ON b.SkuID = tblSku.skuSkuID)
|
||||
INNER JOIN tblProduct ON tblSku.skuProductID = tblProduct.prdProductID)
|
||||
LEFT JOIN tblAmazonFeeEstimate ON tblProduct.prdProductID = tblAmazonFeeEstimate.ProductIdentifier )
|
||||
INNER JOIN tblProductCategory ON tblProduct.ProductCategoryID = tblProductCategory.ProductCategoryID)
|
||||
INNER JOIN tblAccountTaxCode ON tblSku.AccountTaxCodeID = tblAccountTaxCode.AccountTaxCodeID
|
||||
INNER JOIN tblSkuCondition ON tblSku.skuSkuConditionID = tblSkuCondition.scnSkuConditionID
|
||||
";
|
||||
|
||||
using (var conn = new SqlConnection(sqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
var invPricing = conn.Query<Model.Sku.Price.SkuPriceParameter>(stringSql).ToList();
|
||||
|
||||
if (invPricing != null || invPricing.Any())
|
||||
{
|
||||
return invPricing;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Dapper;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Sku.Price
|
||||
{
|
||||
public class ReadPricingDetail : Connection
|
||||
{
|
||||
public ReadPricingDetail(string sqlConnectionString) : base(sqlConnectionString)
|
||||
{
|
||||
|
||||
}
|
||||
public Dictionary<string, Model.Sku.Price.PriceInfo> ReadDictionary(List<string> skuNumberList, string orderChannel)
|
||||
{
|
||||
var dic = new Dictionary<string, Model.Sku.Price.PriceInfo>();
|
||||
var list = Read(skuNumberList, orderChannel);
|
||||
|
||||
for (int i = 0; i < list.Count; i++)
|
||||
{
|
||||
dic.Add(list[i].SkuNumber, list[i]);
|
||||
}
|
||||
return dic;
|
||||
}
|
||||
|
||||
public List<Model.Sku.Price.PriceInfo> Read(List<string> skuNumberList, string orderChannel)
|
||||
{
|
||||
using (var conn = new SqlConnection(sqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
string sql = @"
|
||||
SELECT tblSku.skuSkuNumber AS SkuNumber
|
||||
,tblOrderChannel.OrderChannel
|
||||
,tblSkuPrice.PriceInfoTimeStamp
|
||||
,tblSkuPrice.OrderChannelQuantity
|
||||
,tblSkuPrice.UnitPurchaseCost
|
||||
,tblSkuPrice.UnitMinPriceProfit
|
||||
,tblSkuPrice.UnitMinPriceCost
|
||||
,tblSkuPrice.UnitMinPriceDestory
|
||||
,tblSkuPrice.InventoryAgeMin
|
||||
,tblSkuPrice.InventoryAgeMax
|
||||
,tblSkuPrice.CompetitivePrice
|
||||
,tblSkuPrice.MinPrice
|
||||
,tblSkuPrice.MaxPrice
|
||||
,tblSkuPrice.RepriceIncrement
|
||||
,tblSkuPrice.ReviewRequired
|
||||
,tblSkuPriceType.SkuPriceTypeID
|
||||
,tblSkuPriceType.TypeTitle
|
||||
FROM tblSkuPrice
|
||||
INNER JOIN tblSkuPriceType ON tblSkuPrice.SkuPriceTypeID = tblSkuPriceType.SkuPriceTypeID
|
||||
INNER JOIN tblSku ON tblSkuPrice.SkuID = tblSku.skuSkuID
|
||||
INNER JOIN tblOrderChannel ON tblSkuPrice.OrderChannelID = tblOrderChannel.OrderChannelID
|
||||
WHERE tblSku.skuSkuNumber IN @skuNumber
|
||||
AND (tblOrderChannel.OrderChannel = @orderChannel);";
|
||||
|
||||
var parameters = new DynamicParameters();
|
||||
parameters.Add("@skuNumber", skuNumberList);
|
||||
parameters.Add("@orderChannel", orderChannel);
|
||||
|
||||
return conn.Query<Model.Sku.Price.PriceInfo>(sql, parameters).ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
51
src/bnhtrade.Core/Data/Database/SKU/ReadSkuConditionInfo.cs
Normal file
51
src/bnhtrade.Core/Data/Database/SKU/ReadSkuConditionInfo.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Dapper;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Sku
|
||||
{
|
||||
public class ReadSkuConditionInfo : Connection
|
||||
{
|
||||
public ReadSkuConditionInfo(string sqlConnectionString): base(sqlConnectionString)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public List<Model.Sku.SkuConditionInfo> Read(List<int> conditionIdList)
|
||||
{
|
||||
string sql = @"
|
||||
SELECT scnSkuConditionID AS SkuConditionId
|
||||
,scnTitleShort AS TitleShort
|
||||
,scnSkuNumberSuffix AS SkuConditionNumber
|
||||
,BaseType AS AmazonBaseType
|
||||
,IsFixedPrice
|
||||
,CompetitivePriceMultiplierNew AS CompetitivePriceMultiplier
|
||||
,scnRepricerStrategy AS RepricerStrategy
|
||||
,scnAmazonIdentifier AS AmazonIdentifier
|
||||
,scnConditionNoteDefault AS ConditionNoteDefault
|
||||
,scnDescription AS Description
|
||||
FROM tblSkuCondition";
|
||||
|
||||
if (conditionIdList != null || !conditionIdList.Any())
|
||||
{
|
||||
sql += @"
|
||||
WHERE scnSkuConditionID IN @conditionIdList
|
||||
";
|
||||
}
|
||||
|
||||
using (var conn = new SqlConnection(sqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
var paramter = new DynamicParameters();
|
||||
paramter.Add("@conditionIdList", conditionIdList);
|
||||
|
||||
return conn.Query<Model.Sku.SkuConditionInfo>(sql, paramter).ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Stock
|
||||
{
|
||||
public class CreateSkuTransaction : Connection
|
||||
{
|
||||
public CreateSkuTransaction(string sqlConnectionString) : base(sqlConnectionString)
|
||||
{
|
||||
}
|
||||
|
||||
public void Create(Model.Stock.SkuTransaction skuTransaction)
|
||||
{
|
||||
using (var conn = new SqlConnection(sqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
INSERT INTO tblStockSkuTransaction (
|
||||
TransactionDate
|
||||
,StockSkuTransactionTypeID
|
||||
,ForeignKey
|
||||
,Reference
|
||||
,Detail
|
||||
,SkuID
|
||||
,Quantity
|
||||
,IsProcessed
|
||||
,StockJournalID
|
||||
)
|
||||
OUTPUT INSERTED.StockSkuTransactionID
|
||||
VALUES (
|
||||
@transactionDate
|
||||
,@stockSkuTransactionTypeID
|
||||
,@foreignKey
|
||||
,@reference
|
||||
,@Detail
|
||||
,(
|
||||
SELECT skuSkuID
|
||||
FROM tblSku
|
||||
WHERE skuSkuNumber = @skuNumber
|
||||
)
|
||||
,@quantity
|
||||
,@isProcessed
|
||||
,@stockJournalID
|
||||
)
|
||||
", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@transactionDate", skuTransaction.TransactionDate.ToUniversalTime());
|
||||
cmd.Parameters.AddWithValue("@stockSkuTransactionTypeID", skuTransaction.SkuTransactionTypeId);
|
||||
if (!skuTransaction.IsSetForeignKey) { cmd.Parameters.AddWithValue("@foreignKey", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@foreignKey", skuTransaction.ForeignKey); }
|
||||
if (!skuTransaction.IsSetReference) { cmd.Parameters.AddWithValue("@reference", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@reference", skuTransaction.Reference); }
|
||||
if (!skuTransaction.IsSetDetail) { cmd.Parameters.AddWithValue("@detail", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@detail", skuTransaction.Detail); }
|
||||
cmd.Parameters.AddWithValue("@skuNumber", skuTransaction.SkuNumber);
|
||||
cmd.Parameters.AddWithValue("@quantity", skuTransaction.Quantity);
|
||||
cmd.Parameters.AddWithValue("@isProcessed", skuTransaction.IsProcessed);
|
||||
if (!skuTransaction.IsSetStockJournalId) { cmd.Parameters.AddWithValue("@stockJournalID", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@stockJournalID", skuTransaction.StockJournalId); }
|
||||
|
||||
object obj = cmd.ExecuteScalar();
|
||||
|
||||
if (obj == null || obj == DBNull.Value)
|
||||
{
|
||||
throw new Exception("Sku Reconcile Transaction insert failed");
|
||||
}
|
||||
|
||||
skuTransaction.SkuTransactionId = (int)obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Stock
|
||||
{
|
||||
public class DeleteSkuTransaction : Connection
|
||||
{
|
||||
public DeleteSkuTransaction (string sqlConnectionString): base(sqlConnectionString)
|
||||
{
|
||||
}
|
||||
|
||||
public void ByTransactionId(int skuReconcileId)
|
||||
{
|
||||
using (var conn = new SqlConnection(sqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
DELETE FROM tblStockSkuTransaction WHERE StockSkuTransactionID = @transactionId
|
||||
", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@transactionId", skuReconcileId);
|
||||
|
||||
if (cmd.ExecuteNonQuery() < 1)
|
||||
{
|
||||
throw new Exception("Delete sku transaction effected no records");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
104
src/bnhtrade.Core/Data/Database/Stock/ReadSkuTransaction.cs
Normal file
104
src/bnhtrade.Core/Data/Database/Stock/ReadSkuTransaction.cs
Normal file
@@ -0,0 +1,104 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Dapper;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Stock
|
||||
{
|
||||
public class ReadSkuTransaction : Connection
|
||||
{
|
||||
public ReadSkuTransaction(string sqlConnectionString) : base(sqlConnectionString)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public int? GetJournalId(int skuTransactionId)
|
||||
{
|
||||
using (var conn = new SqlConnection(sqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
using (var cmd = new SqlCommand(@"
|
||||
SELECT StockJournalID FROM tblStockSkuTransaction WHERE StockSkuTransactionID=@transactionId
|
||||
", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@transactionId", skuTransactionId);
|
||||
|
||||
object obj = cmd.ExecuteScalar();
|
||||
|
||||
if (obj == null || obj == DBNull.Value)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (int)obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<Model.Stock.SkuTransaction> GetUnreconciled()
|
||||
{
|
||||
// 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.
|
||||
// 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>();
|
||||
|
||||
string sql = @"
|
||||
SELECT tblStockSkuTransaction.StockSkuTransactionID AS SkuTransactionId
|
||||
,tblStockSkuTransaction.TransactionDate
|
||||
,tblStockSkuTransaction.StockSkuTransactionTypeID AS SkuTransactionTypeId
|
||||
,tblStockSkuTransaction.ForeignKey
|
||||
,tblStockSkuTransaction.Reference
|
||||
,tblStockSkuTransaction.Detail
|
||||
,tblStockSkuTransaction.Quantity
|
||||
,tblStockSkuTransaction.IsProcessed
|
||||
,tblStockSkuTransaction.StockJournalID AS StockJournalId
|
||||
,tblStockSkuTransactionType.TypeTitle AS SkuTransactionTypeName
|
||||
,tblSku.skuSkuNumber AS SkuNumber
|
||||
,tblStockSkuTransaction.SkuID
|
||||
FROM tblStockSkuTransaction
|
||||
INNER JOIN tblStockSkuTransactionType ON tblStockSkuTransaction.StockSkuTransactionTypeID = tblStockSkuTransactionType.StockSkuTransactionTypeID
|
||||
INNER JOIN tblSku ON tblStockSkuTransaction.SkuID = tblSku.skuSkuID ";
|
||||
|
||||
sql += sqlWhere;
|
||||
|
||||
sql += @"
|
||||
ORDER BY tblStockSkuTransaction.TransactionDate ASC, tblStockSkuTransaction.StockSkuTransactionID DESC;";
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(sqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
resultList = conn.Query<Model.Stock.SkuTransaction>(sql, parameters).ToList();
|
||||
}
|
||||
|
||||
// set datetime kind
|
||||
for (int i = 0; i < resultList.Count; i++)
|
||||
{
|
||||
if (resultList[i].IsSetTransactionDate)
|
||||
{
|
||||
resultList[i].TransactionDate = DateTime.SpecifyKind(resultList[i].TransactionDate, DateTimeKind.Utc);
|
||||
}
|
||||
}
|
||||
|
||||
return resultList;
|
||||
}
|
||||
}
|
||||
}
|
||||
153
src/bnhtrade.Core/Data/Database/Stock/ReadSkuTransactionType.cs
Normal file
153
src/bnhtrade.Core/Data/Database/Stock/ReadSkuTransactionType.cs
Normal file
@@ -0,0 +1,153 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Dapper;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Stock
|
||||
{
|
||||
public class ReadSkuTransactionType : Connection
|
||||
{
|
||||
public ReadSkuTransactionType(string sqlConnectionString) : base(sqlConnectionString)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Depriciated, delete when not required by other code
|
||||
/// </summary>
|
||||
/// <param name="sqlConnectionString"></param>
|
||||
/// <param name="typeCode"></param>
|
||||
/// <returns></returns>
|
||||
public int GetTypeId(string typeCode)
|
||||
{
|
||||
/* GetStockTransactionTypeId return meanings
|
||||
* >0 use the as the TypeId when inserting transaction
|
||||
* 0 Skip transpose, type doesn't exist or is new (not reviewed yet)
|
||||
* -1 Type import/transpose is disabled, IsProcessed=TRUE StockTransactionID=NULL */
|
||||
|
||||
// old optional parameters
|
||||
// , bool onNewReturnId = false, bool onNewDisableInsert = false
|
||||
|
||||
if (typeCode.Length == 0)
|
||||
{
|
||||
throw new Exception("Empty match string passed to method");
|
||||
}
|
||||
using (SqlConnection sqlConn = new SqlConnection(sqlConnectionString))
|
||||
{
|
||||
sqlConn.Open();
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
SELECT
|
||||
StockSkuTransactionTypeID,
|
||||
IsNewReviewRequired,
|
||||
TransactionImportEnabled
|
||||
FROM
|
||||
tblStockSkuTransactionType
|
||||
WHERE
|
||||
TypeCode=@typeCode;
|
||||
", sqlConn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@typeCode", typeCode);
|
||||
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
int index01 = reader.GetOrdinal("StockSkuTransactionTypeID");
|
||||
int index02 = reader.GetOrdinal("IsNewReviewRequired");
|
||||
int index03 = reader.GetOrdinal("TransactionImportEnabled");
|
||||
|
||||
int transactionTypeId = reader.GetInt32(index01);
|
||||
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;
|
||||
}
|
||||
else if (importEnabled == false)
|
||||
{
|
||||
// mark IsProcessed=true and leave transactionId=null
|
||||
return -1;
|
||||
}
|
||||
else if (transactionTypeId > 0)
|
||||
{
|
||||
|
||||
return transactionTypeId;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Sku TransactionTypeId lookup method failed, is one of the 'enabled' boolean on table set to null?");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<Model.Stock.SkuTransactionType> Execute(string sqlWhere, DynamicParameters param)
|
||||
{
|
||||
string sql = @"
|
||||
SELECT tblStockSkuTransactionType.StockSkuTransactionTypeID AS TypeId
|
||||
,tblStockSkuTransactionType.TypeName
|
||||
,tblStockSkuTransactionType.TypeCode
|
||||
,tblStockSkuTransactionType.TypeDescription
|
||||
,tblStockSkuTransactionType.StockJournalTypeID
|
||||
,tblStockSkuTransactionType.TransactionForeignKeyName
|
||||
,tblStockSkuTransactionType.TransactionReferenceType
|
||||
,tblStockSkuTransactionType.IsNewReviewRequired
|
||||
,tblStockSkuTransactionType.TransactionImportEnabled
|
||||
,tblStockSkuTransactionType.StockJournalEntryEnabled
|
||||
,tblStockSkuTransactionType.DebitStockStatusID
|
||||
,tblStockSkuTransactionType.CreditStockStatusID
|
||||
,tblStockSkuTransactionType.StatusBalanceCheckRequired
|
||||
,tblStockSkuTransactionType.FilterStockOnDateTime
|
||||
,tblStockSkuTransactionType.FirstInFirstOut
|
||||
,tblStockSkuTransactionType.RecordCreated
|
||||
,CreditStatus.StockStatus AS CreditStockStatus
|
||||
,DebitStatus.StockStatus AS DebitStockStatus
|
||||
FROM tblStockStatus AS DebitStatus
|
||||
RIGHT OUTER JOIN tblStockSkuTransactionType ON DebitStatus.StockStatusID = tblStockSkuTransactionType.DebitStockStatusID
|
||||
LEFT OUTER JOIN tblStockStatus AS CreditStatus ON tblStockSkuTransactionType.CreditStockStatusID = CreditStatus.StockStatusID
|
||||
";
|
||||
|
||||
sql += sqlWhere;
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(sqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
return conn.Query<Model.Stock.SkuTransactionType>(sql, param).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
public List<Model.Stock.SkuTransactionType> ByTypeCode(List<string> typeCode)
|
||||
{
|
||||
string sqlWhere = @"
|
||||
WHERE TypeCode IN @typeCode ";
|
||||
|
||||
var param = new DynamicParameters();
|
||||
param.Add("@typeCode", typeCode);
|
||||
|
||||
return Execute(sqlWhere, param);
|
||||
}
|
||||
|
||||
public List<Model.Stock.SkuTransactionType> ByTypeName(List<string> typeName)
|
||||
{
|
||||
string sqlWhere = @"
|
||||
WHERE TypeName IN @typeName ";
|
||||
|
||||
var param = new DynamicParameters();
|
||||
param.Add("@typeName", typeName);
|
||||
|
||||
return Execute(sqlWhere, param);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
198
src/bnhtrade.Core/Data/Database/Stock/UpdateSkuTransaction.cs
Normal file
198
src/bnhtrade.Core/Data/Database/Stock/UpdateSkuTransaction.cs
Normal file
@@ -0,0 +1,198 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Stock
|
||||
{
|
||||
public class UpdateSkuTransaction : Connection
|
||||
{
|
||||
private string err = "Database UpdateSkuTransaction: ";
|
||||
|
||||
public UpdateSkuTransaction(string sqlConnectionString) : base(sqlConnectionString)
|
||||
{
|
||||
}
|
||||
|
||||
public void Update(int skuTransactionId, bool isProcessed)
|
||||
{
|
||||
using (var conn = new SqlConnection(sqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
UPDATE tblStockSkuTransaction
|
||||
SET IsProcessed=@isProcessed
|
||||
WHERE StockSkuTransactionID=@transactionId
|
||||
", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@isProcessed", isProcessed);
|
||||
cmd.Parameters.AddWithValue("@transactionId", skuTransactionId);
|
||||
|
||||
int effected = cmd.ExecuteNonQuery();
|
||||
|
||||
if (effected < 1)
|
||||
{
|
||||
throw new Exception(err += "Sku Transaction IsProcessed update failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update the StockJournalID field. Will also set the IsProcessed value base on input.
|
||||
/// </summary>
|
||||
/// <param name="skuTransactionId">Sku Transaction Id</param>
|
||||
/// <param name="stockJournalId">Stock Journal Id or null to unset</param>
|
||||
public void Update(int skuTransactionId, int? stockJournalId)
|
||||
{
|
||||
string sql = @"
|
||||
UPDATE tblStockSkuTransaction
|
||||
SET IsProcessed = @isProcessed
|
||||
,StockJournalID = @stockJournalID
|
||||
WHERE StockSkuTransactionID = @transactionId;";
|
||||
|
||||
using (var conn = new SqlConnection(sqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
if (stockJournalId == null) { cmd.Parameters.AddWithValue("@stockJournalID", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@stockJournalID", (int)stockJournalId); }
|
||||
if (stockJournalId == null) { cmd.Parameters.AddWithValue("@isProcessed", false); }
|
||||
else { cmd.Parameters.AddWithValue("@isProcessed", true); }
|
||||
cmd.Parameters.AddWithValue("@transactionId", skuTransactionId);
|
||||
|
||||
int effected = cmd.ExecuteNonQuery();
|
||||
|
||||
if (effected < 1)
|
||||
{
|
||||
throw new Exception(err += "Sku Transaction StockJournalID update failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Update(int skuTransactionId, int quantity, bool isProcessed)
|
||||
{
|
||||
string sql = @"
|
||||
UPDATE tblStockSkuTransaction
|
||||
SET IsProcessed = @isProcessed
|
||||
,Quantity = @quantity
|
||||
WHERE StockSkuTransactionID = @transactionId;";
|
||||
|
||||
using (var conn = new SqlConnection(sqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@isProcessed", isProcessed);
|
||||
cmd.Parameters.AddWithValue("@quantity", quantity);
|
||||
cmd.Parameters.AddWithValue("@transactionId", skuTransactionId);
|
||||
|
||||
int effected = cmd.ExecuteNonQuery();
|
||||
|
||||
if (effected < 1)
|
||||
{
|
||||
throw new Exception(err += "Sku Transaction quantity and isprocessed update failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update the StockJournalID field. Will also set the IsProcessed value base on input.
|
||||
/// </summary>
|
||||
/// <param name="skuTransactionId">Sku Transaction Id</param>
|
||||
/// <param name="quantity">Sku Transaction quantity. Set to null to leave database value unchanged.</param>
|
||||
/// <param name="stockJournalId">Stock Journal Id</param>
|
||||
public void Update(int skuTransactionId, int? quantity, int stockJournalId)
|
||||
{
|
||||
string sql = @"
|
||||
UPDATE tblStockSkuTransaction
|
||||
SET IsProcessed = @isProcessed
|
||||
,StockJournalID = @stockJournalID ";
|
||||
|
||||
if (quantity != null)
|
||||
{
|
||||
sql += @"
|
||||
,Quantity = @quantity ";
|
||||
}
|
||||
|
||||
sql += @"
|
||||
WHERE StockSkuTransactionID = @transactionId;";
|
||||
|
||||
using (var conn = new SqlConnection(sqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
if (quantity != null) { cmd.Parameters.AddWithValue("@quantity", (int)quantity); }
|
||||
cmd.Parameters.AddWithValue("@isProcessed", true);
|
||||
cmd.Parameters.AddWithValue("@stockJournalID", stockJournalId);
|
||||
cmd.Parameters.AddWithValue("@transactionId", skuTransactionId);
|
||||
|
||||
int effected = cmd.ExecuteNonQuery();
|
||||
|
||||
if (effected < 1)
|
||||
{
|
||||
throw new Exception(err += "Sku Transaction IsProcessed update failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Update(Model.Stock.SkuTransaction skuTransaction)
|
||||
{
|
||||
using (var conn = new SqlConnection())
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
UPDATE tblStockSkuTransaction
|
||||
SET TransactionDate = @transactionDate
|
||||
,StockSkuTransactionTypeID = @stockSkuTransactionTypeID
|
||||
,ForeignKey = @foreignKey
|
||||
,Reference = @reference
|
||||
,Detail = @Detail
|
||||
,SkuID = (
|
||||
SELECT skuSkuID
|
||||
FROM tblSku
|
||||
WHERE skuSkuNumber = @skuNumber
|
||||
)
|
||||
,Quantity = @quantity
|
||||
,IsProcessed = @isProcessed
|
||||
,StockJournalID = @stockJournalID
|
||||
WHERE StockSkuTransactionID = @transactionId
|
||||
", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@transactionDate", skuTransaction.TransactionDate.ToUniversalTime());
|
||||
cmd.Parameters.AddWithValue("@stockSkuTransactionTypeID", skuTransaction.SkuTransactionTypeId);
|
||||
if (!skuTransaction.IsSetForeignKey) { cmd.Parameters.AddWithValue("@foreignKey", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@foreignKey", skuTransaction.ForeignKey); }
|
||||
if (!skuTransaction.IsSetReference) { cmd.Parameters.AddWithValue("@reference", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@reference", skuTransaction.Reference); }
|
||||
if (!skuTransaction.IsSetDetail) { cmd.Parameters.AddWithValue("@detail", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@detail", skuTransaction.Detail); }
|
||||
cmd.Parameters.AddWithValue("@skuNumber", skuTransaction.SkuNumber);
|
||||
cmd.Parameters.AddWithValue("@quantity", skuTransaction.Quantity);
|
||||
cmd.Parameters.AddWithValue("@isProcessed", skuTransaction.IsProcessed);
|
||||
if (!skuTransaction.IsSetStockJournalId) { cmd.Parameters.AddWithValue("@stockJournalID", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@stockJournalID", skuTransaction.StockJournalId); }
|
||||
cmd.Parameters.AddWithValue("@transactionId", skuTransaction.SkuTransactionId);
|
||||
|
||||
int effected = cmd.ExecuteNonQuery();
|
||||
|
||||
if (effected < 1)
|
||||
{
|
||||
throw new Exception(err += "stockSkuTransaction IsProcessed update failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
94
src/bnhtrade.Core/Data/Database/WhereBuilder.cs
Normal file
94
src/bnhtrade.Core/Data/Database/WhereBuilder.cs
Normal file
@@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database
|
||||
{
|
||||
public class WhereBuilder
|
||||
{
|
||||
private int parameterCount;
|
||||
|
||||
public WhereBuilder()
|
||||
{
|
||||
Innit();
|
||||
}
|
||||
|
||||
public string SqlWhereString { get; private set; }
|
||||
|
||||
public Dictionary<string, object> ParameterList { get; private set; }
|
||||
|
||||
public void Innit()
|
||||
{
|
||||
SqlWhereString = null;
|
||||
ParameterList = new Dictionary<string, object>();
|
||||
parameterCount = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to create a string for an SQL where condition 'In' statement
|
||||
/// </summary>
|
||||
/// <param name="columnReference">Name of the column to used to for the condition statement</param>
|
||||
/// <param name="orValueList">List of values to test in condition statement</param>
|
||||
/// <param name="wherePrefix">Optional string to prefix to the returned result</param>
|
||||
public void In(string columnReference, List<string> orValueList, string wherePrefix = null)
|
||||
{
|
||||
Innit();
|
||||
|
||||
if (orValueList == null || !orValueList.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string sqlWhere = @"
|
||||
";
|
||||
|
||||
if (wherePrefix != null)
|
||||
{
|
||||
sqlWhere += wherePrefix;
|
||||
}
|
||||
|
||||
sqlWhere += " " + columnReference + " IN ( ";
|
||||
|
||||
var paramters = new Dictionary<string, object>();
|
||||
int listCount = orValueList.Count();
|
||||
for (int i = 0; i < listCount; i++, parameterCount++)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
sqlWhere += ", ";
|
||||
}
|
||||
|
||||
string param = "@parameter" + parameterCount;
|
||||
sqlWhere += param;
|
||||
paramters.Add(param, orValueList[i]);
|
||||
}
|
||||
sqlWhere += " )";
|
||||
|
||||
SqlWhereString = sqlWhere;
|
||||
ParameterList = paramters;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to create a string for an SQL where condition 'In' statement
|
||||
/// </summary>
|
||||
/// <param name="columnReference">Name of the column to used to for the condition statement</param>
|
||||
/// <param name="orValueList">List of values to test in condition statement</param>
|
||||
/// <param name="wherePrefix">Optional string to prefix to the returned result</param>
|
||||
public void In(string columnReference, List<int> orValueList, string wherePrefix = null)
|
||||
{
|
||||
var stringList = new List<string>();
|
||||
|
||||
if (orValueList != null || !orValueList.Any())
|
||||
{
|
||||
foreach (int value in orValueList)
|
||||
{
|
||||
stringList.Add(value.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
In(columnReference, stringList, wherePrefix);
|
||||
}
|
||||
}
|
||||
}
|
||||
19
src/bnhtrade.Core/Extensions.cs
Normal file
19
src/bnhtrade.Core/Extensions.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core
|
||||
{
|
||||
static class Extensions
|
||||
{
|
||||
public static bool In<T>(this T item, params T[] items)
|
||||
{
|
||||
if (items == null)
|
||||
throw new ArgumentNullException("items");
|
||||
|
||||
return items.Equals(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
83
src/bnhtrade.Core/Logic/Account/GetAccountCodeInfo.cs
Normal file
83
src/bnhtrade.Core/Logic/Account/GetAccountCodeInfo.cs
Normal file
@@ -0,0 +1,83 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Logic.Account
|
||||
{
|
||||
public class GetAccountCodeInfo
|
||||
{
|
||||
private string sqlConnectionString;
|
||||
private Data.Database.Account.ReadAccountCode readAccountCode;
|
||||
private Dictionary<int, Model.Account.AccountCode> cache;
|
||||
|
||||
public GetAccountCodeInfo(string sqlConnectionString)
|
||||
{
|
||||
this.sqlConnectionString = sqlConnectionString;
|
||||
readAccountCode = new Data.Database.Account.ReadAccountCode(sqlConnectionString);
|
||||
cache = new Dictionary<int, Model.Account.AccountCode>();
|
||||
}
|
||||
|
||||
public void CacheClear()
|
||||
{
|
||||
cache.Clear();
|
||||
}
|
||||
|
||||
public void CacheFill()
|
||||
{
|
||||
CacheClear();
|
||||
|
||||
var resultList = readAccountCode.All();
|
||||
foreach (var result in resultList)
|
||||
{
|
||||
cache.Add(result.AccountCodeId, result);
|
||||
}
|
||||
}
|
||||
|
||||
public void CacheFill(List<int> accountCodeList, bool forceDbRead = false)
|
||||
{
|
||||
if (accountCodeList == null || !accountCodeList.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var accountCodeQueryList = new List<int>();
|
||||
foreach (var code in accountCodeList.Distinct().ToList())
|
||||
{
|
||||
if (forceDbRead)
|
||||
{
|
||||
cache.Remove(code);
|
||||
accountCodeQueryList.Add(code);
|
||||
}
|
||||
else if (!cache.ContainsKey(code))
|
||||
{
|
||||
accountCodeQueryList.Add(code);
|
||||
}
|
||||
}
|
||||
|
||||
// get db list
|
||||
var dbList = readAccountCode.ByAccountCode(accountCodeQueryList);
|
||||
|
||||
// add to cache
|
||||
foreach (var item in dbList)
|
||||
{
|
||||
cache.Add(item.AccountCodeId, item);
|
||||
}
|
||||
}
|
||||
|
||||
public Model.Account.AccountCode ByAccountCode(int accountCode, bool forceDbRead = false)
|
||||
{
|
||||
CacheFill(new List<int> { accountCode }, forceDbRead);
|
||||
|
||||
if (cache.ContainsKey(accountCode))
|
||||
{
|
||||
return cache[accountCode];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
164
src/bnhtrade.Core/Logic/Account/GetInvoiceLineItem.cs
Normal file
164
src/bnhtrade.Core/Logic/Account/GetInvoiceLineItem.cs
Normal file
@@ -0,0 +1,164 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Logic.Account
|
||||
{
|
||||
public class GetInvoiceLineItem
|
||||
{
|
||||
string sqlConnectionString;
|
||||
private Dictionary<string, Model.Account.InvoiceLineItem> cache;
|
||||
private Data.Database.Account.ReadInvoiceLineItem dbRead;
|
||||
private Logic.Log.LogEvent log = new Logic.Log.LogEvent();
|
||||
private Logic.Account.GetTaxCodeInfo getTaxCode;
|
||||
private Logic.Account.GetAccountCodeInfo getAccountCode;
|
||||
|
||||
public GetInvoiceLineItem(string sqlConnectionString)
|
||||
{
|
||||
this.sqlConnectionString = sqlConnectionString;
|
||||
CacheInnit();
|
||||
dbRead = new Data.Database.Account.ReadInvoiceLineItem(sqlConnectionString);
|
||||
getAccountCode = new GetAccountCodeInfo(sqlConnectionString);
|
||||
getTaxCode = new GetTaxCodeInfo(sqlConnectionString);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create new 'default' line item code when a requested item code is not found.
|
||||
/// </summary>
|
||||
public bool InsertNewOnNoMatch { get; set; } = false;
|
||||
|
||||
public void CacheInnit()
|
||||
{
|
||||
cache = new Dictionary<string, Model.Account.InvoiceLineItem>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prefill cache in one SQL call, saves multiple SQL calls.
|
||||
/// </summary>
|
||||
/// <param name="itemCodeList">List of item codes to lookup from database</param>
|
||||
/// <param name="forceDbRead">Forces a database read (does not read cache)</param>
|
||||
public void CacheFill(List<string> itemCodeList, bool forceDbRead = false)
|
||||
{
|
||||
if (itemCodeList == null || !itemCodeList.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var itemCodeQueryList = new List<string>();
|
||||
foreach (var itemCode in itemCodeList)
|
||||
{
|
||||
if (forceDbRead)
|
||||
{
|
||||
cache.Remove(itemCode);
|
||||
itemCodeQueryList.Add(itemCode);
|
||||
}
|
||||
else if (!cache.ContainsKey(itemCode))
|
||||
{
|
||||
itemCodeQueryList.Add(itemCode);
|
||||
}
|
||||
}
|
||||
|
||||
// query database
|
||||
var resultList = dbRead.ByItemCode(itemCodeQueryList);
|
||||
|
||||
// fill account & tax codes cache
|
||||
getAccountCode.CacheFill(dbRead.AccountCodeList.Values.ToList(), forceDbRead);
|
||||
getTaxCode.CacheFill(dbRead.TaxCodeList.Values.ToList(), forceDbRead);
|
||||
|
||||
// build final itemcode object and add to cache
|
||||
foreach (var result in resultList.Values)
|
||||
{
|
||||
if (dbRead.AccountCodeList.ContainsKey(result.ItemCode))
|
||||
{
|
||||
result.DefaultAccountCode = getAccountCode.ByAccountCode(dbRead.AccountCodeList[result.ItemCode]);
|
||||
}
|
||||
|
||||
if (dbRead.TaxCodeList.ContainsKey(result.ItemCode))
|
||||
{
|
||||
result.DefaultTaxCode = getTaxCode.GetByTaxCode(dbRead.TaxCodeList[result.ItemCode]);
|
||||
}
|
||||
|
||||
cache.Add(result.ItemCode, result);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates new 'default' item code entry. The item code and title are set the same and will require updating.
|
||||
/// </summary>
|
||||
/// <param name="itemCode">Item code string</param>
|
||||
/// <returns></returns>
|
||||
public Model.Account.InvoiceLineItem CreateDefault(string itemCode)
|
||||
{
|
||||
new Data.Database.Account.CreateInvoiceLineItem(sqlConnectionString).CreateDefault(itemCode);
|
||||
var item = dbRead.ByItemCode(itemCode);
|
||||
cache.Add(item.ItemCode, item);
|
||||
return item;
|
||||
}
|
||||
|
||||
public Model.Account.InvoiceLineItem ByItemCode(string itemCode, bool forceDbRead = false)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(itemCode))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
CacheFill(new List<string> { itemCode }, forceDbRead);
|
||||
|
||||
Model.Account.InvoiceLineItem item = null;
|
||||
if (cache.ContainsKey(itemCode))
|
||||
{
|
||||
item = cache[itemCode];
|
||||
|
||||
// check title
|
||||
if (!item.IsNewReviewRequired && item.Name == item.ItemCode)
|
||||
{
|
||||
throw new Exception
|
||||
("ItemCode found with the incomplete title. Update title and then try again.");
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
if (!InsertNewOnNoMatch)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return CreateDefault(itemCode);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if ItemCode has Invoice line entry enabled
|
||||
/// </summary>
|
||||
/// <param name="itemCode">Item code</param>
|
||||
/// <param name="forceDbRead">Forces a database read (does not read cache)</param>
|
||||
/// <returns></returns>
|
||||
public bool InvoiceLineEntryEnabled(string itemCode, bool forceDbRead = false)
|
||||
{
|
||||
var item = ByItemCode(itemCode, forceDbRead);
|
||||
if (item == null)
|
||||
throw new Exception("Invalid item code");
|
||||
return item.InvoiceLineEntryEnabled;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if ItemCode is new (default) and a review id required
|
||||
/// </summary>
|
||||
/// <param name="itemCode">Item code</param>
|
||||
/// <param name="forceDbRead">Forces a database read (does not read cache)</param>
|
||||
/// <returns></returns>
|
||||
public bool IsNewReviewRequired(string itemCode, bool forceDbRead = false)
|
||||
{
|
||||
var item = ByItemCode(itemCode, forceDbRead);
|
||||
if (item == null)
|
||||
{
|
||||
throw new Exception("Invalid item code");
|
||||
}
|
||||
return item.IsNewReviewRequired;
|
||||
}
|
||||
}
|
||||
}
|
||||
141
src/bnhtrade.Core/Logic/Account/GetTaxCodeInfo.cs
Normal file
141
src/bnhtrade.Core/Logic/Account/GetTaxCodeInfo.cs
Normal file
@@ -0,0 +1,141 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Logic.Account
|
||||
{
|
||||
public class GetTaxCodeInfo
|
||||
{
|
||||
string sqlConnectionString;
|
||||
private bool allRetrived;
|
||||
private Dictionary<string, Model.Account.TaxCodeInfo> cache;
|
||||
private Dictionary<string, Model.Account.TaxCodeInfo> cacheInvoiceItem;
|
||||
private Data.Database.Account.ReadTaxCode dbRead;
|
||||
|
||||
public GetTaxCodeInfo(string sqlConnectionString)
|
||||
{
|
||||
this.sqlConnectionString = sqlConnectionString;
|
||||
allRetrived = false;
|
||||
CacheClear();
|
||||
dbRead = new Data.Database.Account.ReadTaxCode(sqlConnectionString);
|
||||
}
|
||||
|
||||
private void CacheClear()
|
||||
{
|
||||
cache = new Dictionary<string, Model.Account.TaxCodeInfo>();
|
||||
cacheInvoiceItem = new Dictionary<string, Model.Account.TaxCodeInfo>();
|
||||
}
|
||||
|
||||
public void CacheFill()
|
||||
{
|
||||
CacheClear();
|
||||
|
||||
var list = dbRead.GetAllActive();
|
||||
foreach (var item in list)
|
||||
{
|
||||
cache.Add(item.TaxCode, item);
|
||||
}
|
||||
}
|
||||
|
||||
public void CacheFill(List<string> taxCodeList, bool forceDbRead = false)
|
||||
{
|
||||
if (taxCodeList == null || !taxCodeList.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var taxCodeQueryList = new List<string>();
|
||||
foreach (var code in taxCodeList.Distinct().ToList())
|
||||
{
|
||||
if (forceDbRead)
|
||||
{
|
||||
cache.Remove(code);
|
||||
taxCodeQueryList.Add(code);
|
||||
}
|
||||
else if (!cache.ContainsKey(code))
|
||||
{
|
||||
taxCodeQueryList.Add(code);
|
||||
}
|
||||
}
|
||||
|
||||
// get db list
|
||||
var dbList = dbRead.GetByTaxCode(taxCodeQueryList);
|
||||
|
||||
// add to cache
|
||||
foreach (var item in dbList)
|
||||
{
|
||||
cache.Add(item.TaxCode, item);
|
||||
}
|
||||
}
|
||||
|
||||
public List<Model.Account.TaxCodeInfo> GetAllActive()
|
||||
{
|
||||
CacheFill();
|
||||
return cache.Values.ToList();
|
||||
}
|
||||
|
||||
public Model.Account.TaxCodeInfo GetByTaxCode(string taxCode, bool forceDbRead = false)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(taxCode))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
CacheFill(new List<string> { taxCode }, forceDbRead);
|
||||
|
||||
if (cache.ContainsKey(taxCode))
|
||||
{
|
||||
return cache[taxCode];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets list of Tax Code Info for a given list of Sku Numbers
|
||||
/// </summary>
|
||||
/// <param name="skuNumberList">List of SKU numbers</param>
|
||||
/// <returns>Dictionary, key is SkuNumber and value is Tax Code Info</returns>
|
||||
public Dictionary<string, Model.Account.TaxCodeInfo> GetBySkuNumber(List<string> skuNumberList)
|
||||
{
|
||||
var returnList = new Dictionary<string, Model.Account.TaxCodeInfo>();
|
||||
|
||||
if (skuNumberList == null || !skuNumberList.Any())
|
||||
{
|
||||
return returnList;
|
||||
}
|
||||
|
||||
// remove any duplicates
|
||||
var cleanSkuList = skuNumberList.Distinct().ToList();
|
||||
|
||||
// get db list
|
||||
var dbList = dbRead.GetTaxCodeBySkuNumber(skuNumberList);
|
||||
|
||||
if (!dbList.Any()) { return returnList; }
|
||||
|
||||
// charge the cache
|
||||
dbRead.GetAllActive();
|
||||
|
||||
// build dictionary
|
||||
foreach (var item in dbList)
|
||||
{
|
||||
var taxInfo = GetByTaxCode(item.Value);
|
||||
if (taxInfo != null)
|
||||
{
|
||||
returnList.Add(item.Key, taxInfo);
|
||||
}
|
||||
}
|
||||
|
||||
return returnList;
|
||||
}
|
||||
|
||||
public Dictionary<string, Model.Account.TaxCodeInfo> Get(List<Model.Account.InvoiceLineItem> invoiceLineList)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
86
src/bnhtrade.Core/Logic/Account/TaxCalculation.cs
Normal file
86
src/bnhtrade.Core/Logic/Account/TaxCalculation.cs
Normal file
@@ -0,0 +1,86 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Logic.Account
|
||||
{
|
||||
public class TaxCalculation
|
||||
{
|
||||
public decimal GetGrossAmount(decimal netAmount, decimal taxPercent)
|
||||
{
|
||||
return netAmount * (1 + (taxPercent / 100));
|
||||
}
|
||||
|
||||
public decimal GetGrossAmount(decimal netAmount, Model.Account.TaxCodeInfo taxCodeInfo)
|
||||
{
|
||||
return GetGrossAmount(netAmount, taxCodeInfo.TaxRate);
|
||||
}
|
||||
|
||||
public decimal GetNetAmount(decimal grossAmount, decimal taxPercent)
|
||||
{
|
||||
return grossAmount / (1 + (taxPercent / 100));
|
||||
}
|
||||
|
||||
public decimal GetNetAmount(decimal grossAmount, Model.Account.TaxCodeInfo taxCodeInfo)
|
||||
{
|
||||
return GetNetAmount(grossAmount, taxCodeInfo.TaxRate);
|
||||
}
|
||||
|
||||
public decimal GetTaxAmount(decimal amount, bool amountIsTaxInclusive, decimal taxPercent)
|
||||
{
|
||||
if (amountIsTaxInclusive)
|
||||
{
|
||||
return amount - GetNetAmount(amount, taxPercent);
|
||||
}
|
||||
else
|
||||
{
|
||||
return amount * (taxPercent / 100);
|
||||
}
|
||||
}
|
||||
|
||||
public decimal GetTaxAmount(decimal amount, bool amountIsTaxInclusive, Model.Account.TaxCodeInfo taxCodeInfo)
|
||||
{
|
||||
return GetTaxAmount(amount, amountIsTaxInclusive, taxCodeInfo.TaxRate);
|
||||
}
|
||||
|
||||
public decimal GetMarginTaxRate(DateTime transactionDate)
|
||||
{
|
||||
decimal vatRate = 0;
|
||||
if (transactionDate >= new DateTime(2011, 01, 04))
|
||||
{
|
||||
vatRate = 20;
|
||||
}
|
||||
else
|
||||
{
|
||||
// more coding required
|
||||
throw new Exception("Transaction is outside the current margin scheme date scope");
|
||||
}
|
||||
return vatRate;
|
||||
}
|
||||
|
||||
public decimal GetMarginTaxAmount(decimal marginAmount, DateTime transactionDate)
|
||||
{
|
||||
decimal vatRate = GetMarginTaxRate(transactionDate);
|
||||
|
||||
return GetTaxAmount(marginAmount, true, vatRate);
|
||||
}
|
||||
|
||||
public decimal GetMarginTaxAmount(decimal purchasePrice, decimal salePrice, DateTime transactionDate)
|
||||
{
|
||||
return GetMarginTaxAmount(salePrice - purchasePrice, transactionDate);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value to multiply margin (sale - purchase price) by to find margin scheme tax amount
|
||||
/// </summary>
|
||||
/// <param name="transactionDate">Date of transaction</param>
|
||||
/// <returns>Value between 0 and 1</returns>
|
||||
public decimal GetMarginMultiplier(DateTime transactionDate)
|
||||
{
|
||||
decimal vatRate = GetMarginTaxRate(transactionDate);
|
||||
return vatRate / (vatRate + 100);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,267 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Logic.Account
|
||||
{
|
||||
public abstract class ValidateInvoice : Validate
|
||||
{
|
||||
protected Account.ValidateAccountCode validateAccountCode = new Account.ValidateAccountCode();
|
||||
protected Account.ValidateCurrencyCode validateCurrencyCode = new Account.ValidateCurrencyCode();
|
||||
protected Account.ValidateTaxCode validateTaxCode = new ValidateTaxCode();
|
||||
protected Logic.Utilities.StringCheck stringCheck = new Logic.Utilities.StringCheck();
|
||||
|
||||
public bool InvoiceNumberIsRequired { get; set; } = true;
|
||||
public bool InvoiceLineDescriptionIsRequired { get; set; } = true;
|
||||
|
||||
public new void Innit()
|
||||
{
|
||||
base.Innit();
|
||||
validateAccountCode.Innit();
|
||||
validateCurrencyCode.Innit();
|
||||
validateTaxCode.Innit();
|
||||
stringCheck.Innit();
|
||||
}
|
||||
|
||||
protected bool IsValidInvoice(Model.Account.IInvoice invoice)
|
||||
{
|
||||
return IsValidInvoice(new List<Model.Account.IInvoice> { invoice });
|
||||
}
|
||||
|
||||
protected bool IsValidInvoice(List<Model.Account.IInvoice> invoiceList)
|
||||
{
|
||||
Innit();
|
||||
|
||||
if (invoiceList == null || !invoiceList.Any())
|
||||
{
|
||||
ErrorListAdd("Invoice list is null or empty.");
|
||||
return false;
|
||||
}
|
||||
|
||||
var tempErrorList = new List<string>();
|
||||
for (int i = 0; i < invoiceList.Count(); i++)
|
||||
{
|
||||
Innit();
|
||||
|
||||
// check header info
|
||||
if (invoiceList[i].ContactNameIsSet) { IsValidInvoiceContact(invoiceList[i].ContactName); }
|
||||
else { ErrorListAdd("'Contact Name' is a required value"); }
|
||||
|
||||
if (invoiceList[i].InvoiceAmountIsSet)
|
||||
{
|
||||
if (!invoiceList[i].IsCreditNoteIsSet)
|
||||
{ ErrorListAdd("'Is Credit Note' is a required value"); }
|
||||
else
|
||||
{
|
||||
if (invoiceList[i].IsCreditNote && invoiceList[i].InvoiceAmount > 0)
|
||||
{ ErrorListAdd("Credit Note amount cannot be greater than zero"); }
|
||||
else if (!invoiceList[i].IsCreditNote && invoiceList[i].InvoiceAmount < 0)
|
||||
{ ErrorListAdd("Invoice amount cannot be less than zero"); }
|
||||
}
|
||||
}
|
||||
else { ErrorListAdd("'Invoice Amount' is a required value"); }
|
||||
|
||||
if (invoiceList[i].InvoiceCurrencyCodeIsSet) { IsValidInvoiceCurrency(invoiceList[i].InvoiceCurrencyCode); }
|
||||
else { ErrorListAdd("'Invoice Currency Code' is a required value"); }
|
||||
|
||||
if (invoiceList[i].InvoiceDateIsSet) { IsValidInvoiceDate(invoiceList[i].InvoiceDate); }
|
||||
else { ErrorListAdd("'Invoice Date' is a required value"); }
|
||||
|
||||
if (!invoiceList[i].InvoiceDateKindIsSet) { ErrorListAdd("'Invoice Date Kind' is a required value"); }
|
||||
|
||||
if (invoiceList[i].InvoiceDueDateIsSet) { IsValidInvoiceDueDate(invoiceList[i].InvoiceDueDate); }
|
||||
|
||||
if (invoiceList[i].InvoiceNumberIsSet)
|
||||
{ IsValidInvoiceNumber(invoiceList[i].InvoiceNumber); }
|
||||
else
|
||||
{
|
||||
if (InvoiceNumberIsRequired) { ErrorListAdd("'Invoice Number' is a required value"); }
|
||||
}
|
||||
|
||||
if (invoiceList[i].InvoiceReferenceIsSet) { IsValidInvoiceReference(invoiceList[i].InvoiceReference); }
|
||||
else { ErrorListAdd("'Invoice Reference' is a required value"); }
|
||||
|
||||
if (!invoiceList[i].IsCreditNoteIsSet) { ErrorListAdd("'Invoice Reference' is a required value"); }
|
||||
|
||||
|
||||
// loop though lines and check and sum totals
|
||||
if (!invoiceList[i].InvoiceLineListIsSet)
|
||||
{ ErrorListAdd("Invoice is required to have lines."); }
|
||||
else
|
||||
{
|
||||
decimal lineTotal = 0;
|
||||
for (int j = 0; j < invoiceList[i].InvoiceLineList.Count(); j++)
|
||||
{
|
||||
if (!invoiceList[i].InvoiceLineList[j].AccountCodeIsSet) { ErrorListAdd("Line 'Account Code' is a required value"); }
|
||||
else { IsValidInvoiceLineAccount(invoiceList[i].InvoiceLineList[j].AccountCode); }
|
||||
|
||||
if (!invoiceList[i].InvoiceLineList[j].DescriptionIsSet)
|
||||
{
|
||||
if (InvoiceLineDescriptionIsRequired) { ErrorListAdd("Line 'Description' is a required value"); }
|
||||
}
|
||||
else { IsValidInvoiceLineDescription(invoiceList[i].InvoiceLineList[j].Description); }
|
||||
|
||||
if (!invoiceList[i].InvoiceLineList[j].GrossTotalAmountIsSet) { ErrorListAdd("Line 'Gross Total Amount' is a required value"); }
|
||||
|
||||
if (!invoiceList[i].InvoiceLineList[j].ItemCodeIsSet) { ErrorListAdd("Line 'Item Code' is a required value"); }
|
||||
else { IsValidLineItemCode(invoiceList[i].InvoiceLineList[j].ItemCode); }
|
||||
|
||||
if (!invoiceList[i].InvoiceLineList[j].QuantityIsSet) { ErrorListAdd("Line 'Quantity' is a required value"); }
|
||||
|
||||
if (!invoiceList[i].InvoiceLineList[j].TaxAmountIsSet) { ErrorListAdd("Line 'Tax Amount' is a required value"); }
|
||||
|
||||
if (!invoiceList[i].InvoiceLineList[j].TaxCodeIsSet) { ErrorListAdd("Line 'Tax Code' is a required value"); }
|
||||
else { IsValidLineTaxCode(invoiceList[i].InvoiceLineList[j].TaxCode); }
|
||||
|
||||
if (!invoiceList[i].InvoiceLineList[j].TotalNetAmountIsSet) { ErrorListAdd("Line 'Total Net Amount' is a required value"); }
|
||||
|
||||
if ((invoiceList[i].InvoiceLineList[j].TaxAmount
|
||||
+ invoiceList[i].InvoiceLineList[j].TaxAmountAdjust
|
||||
+ invoiceList[i].InvoiceLineList[j].TotalNetAmount) != invoiceList[i].InvoiceLineList[j].GrossTotalAmount)
|
||||
{ ErrorListAdd("Incorrect invoice line total (gross) amount."); }
|
||||
|
||||
lineTotal = lineTotal + invoiceList[i].InvoiceLineList[j].GrossTotalAmount;
|
||||
}
|
||||
|
||||
// check totals
|
||||
if (invoiceList[i].InvoiceAmountIsSet && (invoiceList[i].InvoiceAmount != lineTotal))
|
||||
{ ErrorListAdd("Invoice line total does not match invoice total amount."); }
|
||||
}
|
||||
tempErrorList.AddRange(ErrorList.Select(x => "[Inv" + i + "] " + x).ToList());
|
||||
}
|
||||
|
||||
Innit();
|
||||
ErrorListAdd(tempErrorList);
|
||||
|
||||
if (ErrorListIsSet) { return false; }
|
||||
else { return true; }
|
||||
}
|
||||
|
||||
protected bool IsValidInvoiceLineAccount(int accountCode)
|
||||
{
|
||||
validateAccountCode.Innit();
|
||||
if (!validateAccountCode.IsValidAccountCodeId(accountCode))
|
||||
{
|
||||
ErrorListAdd(validateAccountCode.ErrorList.Select(x => "Invalid invoice line account code: " + x).ToList());
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{ return true; }
|
||||
}
|
||||
|
||||
protected bool IsValidInvoiceLineDescription(string lineDescription)
|
||||
{
|
||||
int maxLength = 150;
|
||||
stringCheck.Innit();
|
||||
if (!stringCheck.MaxLength(lineDescription, maxLength))
|
||||
{
|
||||
ErrorListAdd(stringCheck.ErrorList.Select(x => "Invalid invoice line description: " + x).ToList());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected bool IsValidInvoiceContact(string contactName)
|
||||
{
|
||||
int maxlength = 150;
|
||||
stringCheck.Innit();
|
||||
if (!stringCheck.MaxLength(contactName, maxlength))
|
||||
{
|
||||
ErrorListAdd(stringCheck.ErrorList.Select(x => "Invalid invoice nontact name: " + x).ToList());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected bool IsValidInvoiceDate(DateTime invoiceDate)
|
||||
{
|
||||
if (invoiceDate.Kind != DateTimeKind.Utc)
|
||||
{
|
||||
ErrorListAdd(@"Invalid date/time, UTC kind required.");
|
||||
return false;
|
||||
}
|
||||
else if (invoiceDate == default(DateTime))
|
||||
{
|
||||
ErrorListAdd("Date and time is default value.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected bool IsValidInvoiceDueDate(DateTime invoiceDueDate)
|
||||
{
|
||||
if (invoiceDueDate.Kind != DateTimeKind.Utc)
|
||||
{
|
||||
ErrorListAdd(@"Invalid date/time, UTC kind required.");
|
||||
return false;
|
||||
}
|
||||
else if (invoiceDueDate == default(DateTime))
|
||||
{
|
||||
ErrorListAdd("Date and time is default value.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected bool IsValidInvoiceCurrency(string currencyCode)
|
||||
{
|
||||
validateCurrencyCode.Innit();
|
||||
if (!validateCurrencyCode.IsValidCurrencyCode(currencyCode))
|
||||
{
|
||||
ErrorListAdd(validateCurrencyCode.ErrorList.Select(x => "Invalid invoice currency code: " + x).ToList());
|
||||
return false;
|
||||
}
|
||||
else { return true; }
|
||||
}
|
||||
|
||||
protected bool IsValidInvoiceNumber(string invoiceNumber)
|
||||
{
|
||||
int maxlength = 64;
|
||||
stringCheck.Innit();
|
||||
if (!stringCheck.MaxLength(invoiceNumber, maxlength))
|
||||
{
|
||||
ErrorListAdd(stringCheck.ErrorList.Select(x => "Invalid invoice number: " + x).ToList());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected bool IsValidInvoiceReference(string invoiceReference)
|
||||
{
|
||||
int maxlength = 50;
|
||||
stringCheck.Innit();
|
||||
if (!stringCheck.MaxLength(invoiceReference, maxlength))
|
||||
{
|
||||
ErrorListAdd(stringCheck.ErrorList.Select(x => "Invalid invoice reference: " + x).ToList());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected bool IsValidLineItemCode(string itemCode)
|
||||
{
|
||||
int maxlength = 250;
|
||||
stringCheck.Innit();
|
||||
if (!stringCheck.MaxLength(itemCode, maxlength))
|
||||
{
|
||||
ErrorListAdd(stringCheck.ErrorList.Select(x => "Invalid invoice line item code: " + x).ToList());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected bool IsValidLineTaxCode(string taxCode)
|
||||
{
|
||||
validateTaxCode.Innit();
|
||||
if (validateTaxCode.IsValidTaxCodeId(taxCode))
|
||||
{ return true; }
|
||||
else
|
||||
{
|
||||
ErrorListAdd(validateTaxCode.ErrorList.Select(x => "Invalid invoice line " + x).ToList());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Logic.Account
|
||||
{
|
||||
public class ValidateSalesInvoice : ValidateInvoice
|
||||
{
|
||||
public ValidateSalesInvoice()
|
||||
{
|
||||
int propertyCount = new Model.Account.SalesInvoice().GetType().GetProperties().Count();
|
||||
if (propertyCount != 20)
|
||||
{ throw new Exception("Model.Account.SalesInvoice property count has altered. Validate class requires an update."); }
|
||||
|
||||
propertyCount = new Model.Account.SalesInvoice.InvoiceLine().GetType().GetProperties().Count();
|
||||
if (propertyCount != 18)
|
||||
{ throw new Exception("Model.Account.SalesInvoice property count has altered. Validate class requires an update."); }
|
||||
}
|
||||
|
||||
public bool IsValidInvoice(Model.Account.SalesInvoice invoice)
|
||||
{
|
||||
return IsValidInvoice(new List<Model.Account.SalesInvoice> { invoice });
|
||||
}
|
||||
|
||||
public bool IsValidInvoice(List<Model.Account.SalesInvoice> invoiceList)
|
||||
{
|
||||
var interfaceList = invoiceList.Cast<Model.Account.IInvoice>().ToList();
|
||||
|
||||
return IsValidInvoice(interfaceList);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,145 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Logic.Account
|
||||
{
|
||||
public class ValidateTaxCode : Validate
|
||||
{
|
||||
private Logic.Utilities.StringCheck stringCheck = new Logic.Utilities.StringCheck();
|
||||
|
||||
public new void Innit()
|
||||
{
|
||||
base.Innit();
|
||||
stringCheck.Innit();
|
||||
}
|
||||
public bool IsValidGrossAmountMultiplier(decimal multiplier)
|
||||
{
|
||||
if (multiplier >= 0 && multiplier <= 1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrorListAdd( "Gross multiplier must be equal to, or between, 0 and 1.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public bool IsValidNetAmountMultiplier(decimal multiplier)
|
||||
{
|
||||
if (multiplier >= 0 && multiplier <= 1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrorListAdd("Net multiplier must not be less than 0 or greater than 1.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public bool IsValidOnExpense(Model.Account.TaxCode taxInfo)
|
||||
{
|
||||
if (taxInfo.IsValidOnExpense || taxInfo.IsSetIsValidOnIncome)
|
||||
{
|
||||
if (taxInfo.IsSetIsValidOnExpense)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrorListAdd("Is Valid On Expense has not been set.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrorListAdd("Either 'IsValidOnExpense' or 'IsSetIsValidOnSale' must be set to true.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public bool IsValidOnIncome(Model.Account.TaxCode taxInfo)
|
||||
{
|
||||
if (taxInfo.IsValidOnExpense || taxInfo.IsSetIsValidOnIncome)
|
||||
{
|
||||
if (taxInfo.IsSetIsValidOnIncome)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrorListAdd("Is Valid On Income has not been set.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrorListAdd("Either 'IsValidOnPurchase' or 'IsSetIsValidOnSale' must be set to true.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public bool IsValidTaxCodeId(string taxCodeId)
|
||||
{
|
||||
if (!stringCheck.IsAlphaNumeric(taxCodeId, true))
|
||||
{
|
||||
ErrorListAdd(stringCheck.ErrorList.Select(x => "Invalid Tax Code: " + x).ToList());
|
||||
return false;
|
||||
}
|
||||
if (taxCodeId.Length != 4)
|
||||
{
|
||||
ErrorListAdd("Invalid Tax Code: Length does not equal 4 charaters.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public bool IsValidTaxRateDescription(string description)
|
||||
{
|
||||
if (stringCheck.MaxLength(description, 250, true))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrorListAdd(stringCheck.ErrorList.Select(x => "Invalid Tax Rate Description: " + x).ToList());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public bool IsValidTaxRateTitle(string title)
|
||||
{
|
||||
if (stringCheck.MaxLength(title, 50, false))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrorListAdd(stringCheck.ErrorList.Select(x => "Invalid Tax Rate Title: " + x).ToList());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public bool IsValidTaxRateTitleShort(string title)
|
||||
{
|
||||
if (stringCheck.MaxLength(title, 50, false))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrorListAdd(stringCheck.ErrorList.Select(x => "Invalid Tax Rate Title Short: " + x).ToList());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public bool IsValidTaxType(string taxType)
|
||||
{
|
||||
if (stringCheck.MaxLength(taxType, 50, false))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrorListAdd(stringCheck.ErrorList.Select(x => "Invalid Tax Rate Type: " + x).ToList());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -36,33 +36,32 @@ namespace bnhtrade.Core.Logic.AmazonFBAInbound
|
||||
shipmentRequest.LastUpdatedAfter = dateTimeAfter.AddDays(-14);
|
||||
shipmentRequest.LastUpdatedBefore = dateTimeBefore;
|
||||
|
||||
List<Model.AmazonFBAInbound.ShipmentInfo> shipmentInfoList = shipmentRequest.GetShipmentInfo();
|
||||
List<Model.AmazonFba.ShipmentInfo> shipmentInfoList = shipmentRequest.GetShipmentInfo();
|
||||
|
||||
// build list of shipments returned from mws
|
||||
var dicShipExistsInDb = new Dictionary<string, bool>();
|
||||
foreach (var item in shipmentInfoList)
|
||||
{
|
||||
dicShipExistsInDb.Add(item.AmazonShipmentId, false);
|
||||
dicShipExistsInDb.Add(item.FbaShipmentId, false);
|
||||
}
|
||||
|
||||
// build list of shipmentId that do not exist in database
|
||||
int complete = 0;
|
||||
using (TransactionScope scope = new TransactionScope())
|
||||
{
|
||||
List<Model.AmazonFBAInbound.ShipmentInfo> newShipmentInfoList = null;
|
||||
List<Model.AmazonFba.ShipmentInfo> newShipmentInfoList = null;
|
||||
if (dicShipExistsInDb.Any())
|
||||
{
|
||||
var newShipmentId = new List<string>();
|
||||
|
||||
// query db for shipment header info
|
||||
var requestHeader = new Data.Database.FBAInbound.GetShipmentHeaderInfo(sqlConnectionString);
|
||||
requestHeader.ShipmentIdList = dicShipExistsInDb.Keys.ToList();
|
||||
var resultHeader = requestHeader.Execute();
|
||||
var resultHeader = new Data.Database.AmazonShipment.ReadShipmentInfo(sqlConnectionString)
|
||||
.HeaderByFbaShipmentId(dicShipExistsInDb.Keys.ToList());
|
||||
|
||||
// compare db and mws result
|
||||
foreach (var item in resultHeader)
|
||||
{
|
||||
dicShipExistsInDb[item.AmazonShipmentId] = true;
|
||||
dicShipExistsInDb[item.FbaShipmentId] = true;
|
||||
}
|
||||
foreach (var item in dicShipExistsInDb)
|
||||
{
|
||||
@@ -81,7 +80,7 @@ namespace bnhtrade.Core.Logic.AmazonFBAInbound
|
||||
foreach (var item in newShipmentInfoList)
|
||||
{
|
||||
var shipmentItemInfoRequest = new Data.AmazonMWS.FBAInbound.ListInboundShipmentItems();
|
||||
item.ShipmentItemInfoList = shipmentItemInfoRequest.GetByAmazonShipmentId(item.AmazonShipmentId);
|
||||
item.ShipmentItemInfoList = shipmentItemInfoRequest.GetByAmazonShipmentId(item.FbaShipmentId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,10 +90,10 @@ namespace bnhtrade.Core.Logic.AmazonFBAInbound
|
||||
foreach (var item in newShipmentInfoList)
|
||||
{
|
||||
// add the update date
|
||||
item.LastUpdatedUtc = dateTimeBefore;
|
||||
item.LastUpdated = dateTimeBefore;
|
||||
|
||||
// write to db
|
||||
var dbWrite = new Data.Database.FBAInbound.SetShipmentInfo(sqlConnectionString);
|
||||
var dbWrite = new Data.Database.AmazonShipment.SetShipmentInfo(sqlConnectionString);
|
||||
dbWrite.Excecute(item);
|
||||
complete = complete + 1;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,8 @@ namespace bnhtrade.Core.Logic.Export
|
||||
public class AmazonSettlement
|
||||
{
|
||||
private string sqlConnectionString;
|
||||
private Dictionary<string, Model.Account.TaxCode> taxCodeBySkuNumer;
|
||||
private Logic.Log.LogEvent log = new Logic.Log.LogEvent();
|
||||
private List<string> lineItemCodeList = new List<string>();
|
||||
|
||||
public AmazonSettlement(string sqlConnectionString)
|
||||
{
|
||||
@@ -21,12 +22,11 @@ namespace bnhtrade.Core.Logic.Export
|
||||
public void ToInvoice()
|
||||
{
|
||||
var console = new UI.Console.Update();
|
||||
var log = new Logic.Log.LogEvent();
|
||||
log.LogInformation("Starting processing of Amazon settlement data into export invoice table...");
|
||||
|
||||
// check settlement reports consistancy
|
||||
var consistencyCheck = new Data.Database.Consistency.ImportAmazonSettlement(sqlConnectionString).PeriodDateGaps();
|
||||
if (consistencyCheck == false )
|
||||
if (consistencyCheck == false)
|
||||
{ return; }
|
||||
|
||||
// get list of unprocssed settlement reports to export
|
||||
@@ -65,38 +65,34 @@ namespace bnhtrade.Core.Logic.Export
|
||||
}
|
||||
|
||||
// validate settlelments
|
||||
var validate = new Logic.Import.ValidateAmazonSettlement();
|
||||
var validate = new Logic.Validate.AmazonSettlement();
|
||||
for (int i = 0; i < settlementList.Count(); i++)
|
||||
{
|
||||
if (!validate.IsValid(settlementList[i]))
|
||||
{
|
||||
log.LogError("Error procesing Amazon Settlement data for export.", validate.ErrorListToString());
|
||||
log.LogError("Error procesing Amazon Settlement data for export.", validate.ValidationResultListToString());
|
||||
}
|
||||
}
|
||||
if (validate.ErrorListIsSet) { return; }
|
||||
if (validate.IsValidResult == false) { return; }
|
||||
|
||||
// get dictionary of sku-number to taxcodeId
|
||||
Console.Write("\rBuilding SKU list... ");
|
||||
var dicSkuNumberToTaxCodeId = new Dictionary<string, string>();
|
||||
for (int i = 0; i < settlementList.Count(); i++)
|
||||
var skuList = new List<string>();
|
||||
foreach (var settlement in settlementList)
|
||||
{
|
||||
if (settlementList[i].SettlementLineListIsSet)
|
||||
if (settlement.SettlementLineListIsSet)
|
||||
{
|
||||
for (int j = 0; j < settlementList[i].SettlementLineList.Count(); j++)
|
||||
foreach (var line in settlement.SettlementLineList)
|
||||
{
|
||||
if (settlementList[i].SettlementLineList[j].SkuIsSet
|
||||
&& !string.IsNullOrWhiteSpace(settlementList[i].SettlementLineList[j].Sku))
|
||||
if (line.SkuIsSet
|
||||
&& !string.IsNullOrWhiteSpace(line.Sku))
|
||||
{
|
||||
if (!dicSkuNumberToTaxCodeId.ContainsKey(settlementList[i].SettlementLineList[j].Sku))
|
||||
{
|
||||
dicSkuNumberToTaxCodeId.Add(settlementList[i].SettlementLineList[j].Sku, null);
|
||||
skuList.Add(line.Sku);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var readTaxCode = new Data.Database.Account.ReadTaxCode(sqlConnectionString);
|
||||
taxCodeBySkuNumer = readTaxCode.BySkuNumber(dicSkuNumberToTaxCodeId.Keys.ToList());
|
||||
var taxCodeBySkuNumer = new Logic.Account.GetTaxCodeInfo(sqlConnectionString).GetBySkuNumber(skuList);
|
||||
|
||||
// loop through each settlement and build list of invoices to export
|
||||
Console.Write("\rBuilding invoices to export... ");
|
||||
@@ -117,7 +113,7 @@ namespace bnhtrade.Core.Logic.Export
|
||||
var itemCodeTotal = new Dictionary<string, decimal>();
|
||||
foreach (var line in month)
|
||||
{
|
||||
string itemCode = BuildLineItemCode(line.Sku, line.TransactionType, line.AmountType, line.AmountDescription);
|
||||
string itemCode = BuildLineItemCode(taxCodeBySkuNumer, line.Sku, line.TransactionType, line.AmountType, line.AmountDescription);
|
||||
if (itemCodeTotal.ContainsKey(itemCode))
|
||||
{
|
||||
itemCodeTotal[itemCode] += line.Amount;
|
||||
@@ -137,13 +133,12 @@ namespace bnhtrade.Core.Logic.Export
|
||||
decimal lineTaxTotal = 0m;
|
||||
foreach (var item in itemCodeTotal)
|
||||
{
|
||||
var line = new Model.Account.SalesInvoice.InvoiceLine();
|
||||
var line = new Model.Account.SalesInvoice.InvoiceLine(invoice.UnitAmountIsTaxExclusive);
|
||||
line.ItemCode = item.Key;
|
||||
line.TotalNetAmount = item.Value;
|
||||
lineNetTotal += item.Value;
|
||||
line.TaxAmount = 0;
|
||||
lineTaxTotal += 0;
|
||||
line.Quantity = 1;
|
||||
line.UnitAmount = item.Value;
|
||||
lineNetTotal += item.Value;
|
||||
lineTaxTotal += 0;
|
||||
invoice.InvoiceLineList.Add(line);
|
||||
}
|
||||
|
||||
@@ -153,11 +148,10 @@ namespace bnhtrade.Core.Logic.Export
|
||||
{ invoice.InvoiceDate = settlementList[i].EndDate; }
|
||||
else
|
||||
{ invoice.InvoiceDate = new DateTime(month.Key.Year, month.Key.Month, 1, 0, 0, 0, DateTimeKind.Utc).AddMonths(1).AddDays(-1); }
|
||||
invoice.InvoiceDateKind = DateTimeKind.Utc;
|
||||
invoice.InvoiceDueDate = settlementList[i].DepositDate;
|
||||
invoice.InvoiceReference = settlementList[i].SettlementId;
|
||||
invoice.InvoiceAmount = lineNetTotal + lineTaxTotal;
|
||||
if (invoice.InvoiceAmount < 0) { invoice.IsCreditNote = true; }
|
||||
invoice.InvoiceTotalAmount = lineNetTotal + lineTaxTotal;
|
||||
if (invoice.InvoiceTotalAmount < 0) { invoice.IsCreditNote = true; }
|
||||
else { invoice.IsCreditNote = false; }
|
||||
|
||||
// invoice complete, add to list
|
||||
@@ -174,11 +168,11 @@ namespace bnhtrade.Core.Logic.Export
|
||||
{
|
||||
if (invoiceTotal.ContainsKey(invoiceList[i].InvoiceReference))
|
||||
{
|
||||
invoiceTotal[invoiceList[i].InvoiceReference] += invoiceList[i].InvoiceAmount;
|
||||
invoiceTotal[invoiceList[i].InvoiceReference] += invoiceList[i].InvoiceTotalAmount.GetValueOrDefault();
|
||||
}
|
||||
else
|
||||
{
|
||||
invoiceTotal.Add(invoiceList[i].InvoiceReference, invoiceList[i].InvoiceAmount);
|
||||
invoiceTotal.Add(invoiceList[i].InvoiceReference, invoiceList[i].InvoiceTotalAmount.GetValueOrDefault());
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < settlementList.Count(); i++)
|
||||
@@ -194,8 +188,65 @@ namespace bnhtrade.Core.Logic.Export
|
||||
return;
|
||||
}
|
||||
|
||||
// postfix invoices spanning multiple months with -n
|
||||
if (invoiceList.Count() > 1)
|
||||
// add invoice item code data to lines
|
||||
// also clean invoices of any disabled lines (remove lines and possibly invoices)
|
||||
var getLineItemInfo = new Logic.Account.GetInvoiceLineItem(sqlConnectionString);
|
||||
getLineItemInfo.InsertNewOnNoMatch = true;
|
||||
getLineItemInfo.CacheFill(lineItemCodeList);
|
||||
bool newTypeFound = false;
|
||||
|
||||
for (int i = 0; i < invoiceList.Count(); i++)
|
||||
{
|
||||
for (int j = 0; j < invoiceList[i].InvoiceLineList.Count(); j++)
|
||||
{
|
||||
var itemCode = getLineItemInfo.ByItemCode(invoiceList[i].InvoiceLineList[j].ItemCode);
|
||||
// error! itemCode should never be null
|
||||
if (itemCode == null)
|
||||
{
|
||||
throw new Exception("Item code is null");
|
||||
}
|
||||
// flag new type and throw exception further on
|
||||
else if (itemCode.IsNewReviewRequired)
|
||||
{
|
||||
newTypeFound = true;
|
||||
}
|
||||
// clean invoices of any disabled lines (remove lines and possibly invoices)
|
||||
else if (itemCode.InvoiceLineEntryEnabled == false)
|
||||
{
|
||||
// remove line
|
||||
invoiceList[i].InvoiceTotalAmount = invoiceList[i].InvoiceTotalAmount - invoiceList[i].InvoiceLineList[j].LineTotalAmount;
|
||||
invoiceList[i].InvoiceLineList.RemoveAt(j);
|
||||
j = j - 1;
|
||||
|
||||
// remove invoice?
|
||||
if (invoiceList[i].InvoiceLineList.Count == 0)
|
||||
{
|
||||
invoiceList.RemoveAt(i);
|
||||
i = i - 1;
|
||||
}
|
||||
}
|
||||
// get here add info to lines
|
||||
else
|
||||
{
|
||||
invoiceList[i].InvoiceLineList[j].AccountCode = itemCode.DefaultAccountCode;
|
||||
invoiceList[i].InvoiceLineList[j].Description = itemCode.Name;
|
||||
invoiceList[i].InvoiceLineList[j].ItemCode = itemCode.ItemCode;
|
||||
invoiceList[i].InvoiceLineList[j].TaxCode = itemCode.DefaultTaxCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (newTypeFound)
|
||||
{
|
||||
if (newTypeFound)
|
||||
{
|
||||
throw new Exception("New line ItemCode found. Add item code default values and then try again.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// postfix invoices references that span multiple months with -n
|
||||
if (invoiceList.Count > 1)
|
||||
{
|
||||
string lastRef = invoiceList[0].InvoiceReference;
|
||||
int countRef = 1;
|
||||
@@ -215,7 +266,7 @@ namespace bnhtrade.Core.Logic.Export
|
||||
if (countRef > 2)
|
||||
{
|
||||
log.LogError(
|
||||
countRef + " total numner of export invoices created from Amazon Settlement Id" + lastRef + "."
|
||||
countRef + " invoices where created from Amazon Settlement Id" + lastRef + "."
|
||||
, "Settlement period appears to span more 3 months or more. Whilst this is possible, it is unsual. Confirm his is correct.");
|
||||
}
|
||||
|
||||
@@ -230,8 +281,12 @@ namespace bnhtrade.Core.Logic.Export
|
||||
{
|
||||
try
|
||||
{
|
||||
var saveInv = new Logic.Export.SalesInvoice(sqlConnectionString);
|
||||
// add temp invoice numbers
|
||||
saveInv.AddTempInvoiceNumber(invoiceList, true);
|
||||
|
||||
// write to the database (gets validated there)
|
||||
new Data.Database.Export.CreateSalesInvoice(sqlConnectionString).SaveInvoice(invoiceList);
|
||||
saveInv.SaveSalesInvoice(invoiceList);
|
||||
|
||||
// set settlements to isprocessed
|
||||
new Data.Database.Import.UpdateAmazonSettlement(sqlConnectionString).SetIsProcessedTrue(settlementIdList);
|
||||
@@ -241,15 +296,16 @@ namespace bnhtrade.Core.Logic.Export
|
||||
catch (Exception ex)
|
||||
{
|
||||
scope.Dispose();
|
||||
log.LogError(ex.Message);
|
||||
log.LogError("Exeception caught while writing Amazon settlement invoices to DB. Changes were rolled back."
|
||||
, ex.Message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
Console.Write("\r");
|
||||
log.LogInformation("\rFinished processing of Amazon settlement data. " + invoiceList.Count() + " invoices created from "+ settlementIdList.Count() + " Amazon settlement reports.");
|
||||
log.LogInformation("\rFinished processing of Amazon settlement data. " + invoiceList.Count() + " invoices created from " + settlementIdList.Count() + " Amazon settlement reports.");
|
||||
}
|
||||
|
||||
private string BuildLineItemCode(string skuNumber, string transactionType, string amountType, string amountDescription)
|
||||
private string BuildLineItemCode(Dictionary<string, Model.Account.TaxCodeInfo> taxCodeBySkuNumer, string skuNumber, string transactionType, string amountType, string amountDescription)
|
||||
{
|
||||
// build the match string
|
||||
// NB special case for global accounting sale and refunds (also note Goodlwill is included) and sku's where tax is included
|
||||
@@ -264,13 +320,18 @@ namespace bnhtrade.Core.Logic.Export
|
||||
{
|
||||
if (taxCodeBySkuNumer.ContainsKey(skuNumber))
|
||||
{
|
||||
matchString = matchString + "<TaxCode=" + taxCodeBySkuNumer[skuNumber].TaxCodeId + ">";
|
||||
matchString = matchString + "<TaxCode=" + taxCodeBySkuNumer[skuNumber].TaxCode + ">";
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Sku#" + skuNumber + " tax info not found in dictionary list.");
|
||||
}
|
||||
}
|
||||
|
||||
// add to list of generated line item codes
|
||||
lineItemCodeList.Add(matchString);
|
||||
|
||||
// return value
|
||||
return matchString;
|
||||
}
|
||||
}
|
||||
|
||||
124
src/bnhtrade.Core/Logic/Export/AmazonSubmitFile.cs
Normal file
124
src/bnhtrade.Core/Logic/Export/AmazonSubmitFile.cs
Normal file
@@ -0,0 +1,124 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Transactions;
|
||||
|
||||
namespace bnhtrade.Core.Logic.Export
|
||||
{
|
||||
public class AmazonSubmitFile
|
||||
{
|
||||
private string sqlConnectionString;
|
||||
private Logic.Utilities.StringCheck stringCheck = new Logic.Utilities.StringCheck();
|
||||
private Log.LogEvent log = new Log.LogEvent();
|
||||
|
||||
public AmazonSubmitFile(string sqlConnectionString)
|
||||
{
|
||||
this.sqlConnectionString = sqlConnectionString;
|
||||
}
|
||||
|
||||
public void SubmitInventoryLoader(MemoryStream stream)
|
||||
{
|
||||
Model.Export.AmazonFeedSubmission result;
|
||||
int queueId = QueueInventoryLoader(stream, out result);
|
||||
SubmitQueuedFeedSubmission(queueId, result);
|
||||
}
|
||||
|
||||
public void SubmitInventoryLoader(MemoryStream stream, out Model.Export.AmazonFeedSubmission result)
|
||||
{
|
||||
int queueId = QueueInventoryLoader(stream, out result);
|
||||
SubmitQueuedFeedSubmission(queueId, result);
|
||||
}
|
||||
|
||||
public int QueueInventoryLoader(MemoryStream stream)
|
||||
{
|
||||
Model.Export.AmazonFeedSubmission result;
|
||||
return QueueFeedSubbmission("_POST_FLAT_FILE_INVLOADER_DATA_", "txt", stream, out result);
|
||||
}
|
||||
|
||||
public int QueueInventoryLoader(MemoryStream stream, out Model.Export.AmazonFeedSubmission result)
|
||||
{
|
||||
// write file database
|
||||
return QueueFeedSubbmission("_POST_FLAT_FILE_INVLOADER_DATA_", "txt", stream, out result);
|
||||
}
|
||||
|
||||
private int QueueFeedSubbmission(string feedType, string fileExtention, MemoryStream stream, out Model.Export.AmazonFeedSubmission result)
|
||||
{
|
||||
// construct file object
|
||||
var fileInfo = new Model.Data.DatabaseFileStream();
|
||||
fileInfo.FileExtention = fileExtention;
|
||||
fileInfo.FileData = stream;
|
||||
fileInfo.FileMD5base64 = new Logic.Utilities.CalculateMD5().Base64(stream);
|
||||
|
||||
long longSize = stream.Length;
|
||||
if (longSize > 2147483647)
|
||||
throw new Exception("File size over 2.15 GB");
|
||||
fileInfo.FileSize = (int)longSize;
|
||||
|
||||
// save to database
|
||||
int queueId = 0;
|
||||
using (var scope = new TransactionScope())
|
||||
{
|
||||
queueId = new Data.Database.Export.CreateAmazonFeedSubmission(sqlConnectionString).Execute(feedType, fileInfo);
|
||||
|
||||
// validate the result
|
||||
var validateResults = new List<ValidationResult>();
|
||||
|
||||
bool isValid = Validator.TryValidateObject(
|
||||
fileInfo,
|
||||
new ValidationContext(fileInfo, null, null),
|
||||
validateResults);
|
||||
|
||||
if (isValid == false)
|
||||
{
|
||||
string error = "Create Database Amazon Feed Submission cancelled. Object validation failed.";
|
||||
new Log.LogEvent().LogError(error, string.Join(Environment.NewLine, validateResults));
|
||||
scope.Dispose();
|
||||
throw new Exception(error);
|
||||
}
|
||||
scope.Complete();
|
||||
}
|
||||
|
||||
// create feed object
|
||||
result = new Model.Export.AmazonFeedSubmission();
|
||||
result.FeedType = feedType;
|
||||
result.File = fileInfo;
|
||||
|
||||
return queueId;
|
||||
}
|
||||
|
||||
// private, only to be used where you're sure feedSubmission matches DB and you don't want to call info from DB (large file)
|
||||
private void SubmitQueuedFeedSubmission(int queueId, Model.Export.AmazonFeedSubmission feedSubmission)
|
||||
{
|
||||
// upload to mws
|
||||
var feedSubmitt = new Data.AmazonMWS.Feeds.SubmitFeed(feedSubmission);
|
||||
|
||||
if (!feedSubmitt.FeedSubmissionRecived)
|
||||
{
|
||||
// failed do something here
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
// set the amazon feed Id
|
||||
var dbUpdate = new Data.Database.Export.UpdateAmazonFeedSubmission(sqlConnectionString);
|
||||
dbUpdate.AddAmazonFeedId(queueId, feedSubmission.FeedSubmissionId);
|
||||
|
||||
// update progress info
|
||||
dbUpdate.UpdateStatusInfo(feedSubmission);
|
||||
}
|
||||
|
||||
private void SubmitQueuedFeedSubmission(int queueId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private void SubmitQueuedFeedSubmission()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
59
src/bnhtrade.Core/Logic/Export/AmazonSubmitFileStatus.cs
Normal file
59
src/bnhtrade.Core/Logic/Export/AmazonSubmitFileStatus.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Logic.Export
|
||||
{
|
||||
public class AmazonSubmitFileStatus
|
||||
{
|
||||
private string sqlConnectionString;
|
||||
private bnhtrade.Core.Logic.Log.LogEvent log = new Log.LogEvent();
|
||||
|
||||
public AmazonSubmitFileStatus(string sqlConnectionString)
|
||||
{
|
||||
this.sqlConnectionString = sqlConnectionString;
|
||||
}
|
||||
|
||||
public void UpdateStatusInfo()
|
||||
{
|
||||
var openList = new Data.Database.Export.ReadAmazonFeedSubmission(sqlConnectionString).GetOpenFeeds();
|
||||
if (openList.Count == 0)
|
||||
return;
|
||||
|
||||
var getStatus = new Data.AmazonMWS.Feeds.GetFeedSubmissions();
|
||||
getStatus.FeedSubmissionIdList = openList.Select(x => x.FeedSubmissionId).ToList();
|
||||
var currentStatus = getStatus.Invoke();
|
||||
|
||||
for (int i = 0; i < openList.Count; i++)
|
||||
{
|
||||
bool found = false;
|
||||
for (int j = 0; j < currentStatus.Count; j++)
|
||||
{
|
||||
if (openList[i].FeedSubmissionId == currentStatus[j].FeedSubmissionId)
|
||||
{
|
||||
found = true;
|
||||
|
||||
openList[i].FeedProcessingStatus = currentStatus[j].FeedProcessingStatus;
|
||||
if (currentStatus[j].IsSetCompletedProcessingDate())
|
||||
openList[i].CompletedProcessingDate = currentStatus[j].CompletedProcessingDate;
|
||||
if (currentStatus[j].IsSetStartedProcessingDate())
|
||||
openList[i].StartedProcessingDate = currentStatus[j].StartedProcessingDate;
|
||||
if (currentStatus[j].IsSetSubmittedDate())
|
||||
openList[i].SubmittedDate = DateTime.Parse(currentStatus[j].SubmittedDate);
|
||||
}
|
||||
}
|
||||
if (found == false)
|
||||
{
|
||||
log.LogError("FeedSubmissionId '" + openList[i].FeedSubmissionId + "' exists in database but was not returned by Amazon MWS when queried.");
|
||||
openList.RemoveAt(i);
|
||||
i = i - 1;
|
||||
}
|
||||
}
|
||||
|
||||
// update the database
|
||||
new Data.Database.Export.UpdateAmazonFeedSubmission(sqlConnectionString).UpdateStatusInfo(openList);
|
||||
}
|
||||
}
|
||||
}
|
||||
53
src/bnhtrade.Core/Logic/Export/SalesInvoice.cs
Normal file
53
src/bnhtrade.Core/Logic/Export/SalesInvoice.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Logic.Export
|
||||
{
|
||||
public class SalesInvoice
|
||||
{
|
||||
private string sqlConnectionString;
|
||||
private Logic.Log.LogEvent log = new Log.LogEvent();
|
||||
|
||||
public SalesInvoice(string sqlConnectionString)
|
||||
{
|
||||
this.sqlConnectionString = sqlConnectionString;
|
||||
}
|
||||
|
||||
public string GetNextTempInvoiceNumber()
|
||||
{
|
||||
var sequence = new Data.Database.Programmability.Sequence(sqlConnectionString);
|
||||
return "_tmp" + sequence.GetNext("ExportTempInvoiceNumber").ToString("00000000");
|
||||
}
|
||||
|
||||
public void AddTempInvoiceNumber(IEnumerable<Model.Account.IInvoice> invoiceList, bool overwriteExisting)
|
||||
{
|
||||
for (int i = 0; i < invoiceList.Count(); i++)
|
||||
{
|
||||
if (invoiceList.ElementAt(i).InvoiceNumber != null && overwriteExisting == false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
invoiceList.ElementAt(i).InvoiceNumber = GetNextTempInvoiceNumber();
|
||||
}
|
||||
}
|
||||
|
||||
public void SaveSalesInvoice(List<Model.Account.SalesInvoice> invoiceList)
|
||||
{
|
||||
// validate the list of invoices
|
||||
var validateInvoice = new Logic.Validate.SalesInvoice();
|
||||
validateInvoice.IsValidExportInvoice(invoiceList);
|
||||
if (validateInvoice.IsValidResult == false)
|
||||
{
|
||||
log.LogError("Invalid Sales invoice(s) found. See extended info.", validateInvoice.ValidationResultListToString());
|
||||
return;
|
||||
}
|
||||
validateInvoice = null;
|
||||
|
||||
// save to database
|
||||
new Data.Database.Export.CreateSalesInvoice(sqlConnectionString).Execute(invoiceList);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,134 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Logic.Export
|
||||
{
|
||||
class ValidateSalesInvoice : Logic.Account.ValidateInvoice
|
||||
{
|
||||
//public bool IsValidInvoice(Model.Export.SetSalesInvoice invoice)
|
||||
//{
|
||||
// ErrorMessage = null;
|
||||
|
||||
// var baseInvoice = CopyInvoiceToBase(invoice);
|
||||
// if (!base.IsValidInvoice(baseInvoice))
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// // check each match string only appears once
|
||||
// var dicLookup = new Dictionary<string, string>();
|
||||
// foreach (var line in invoice.InvoiceLineList)
|
||||
// {
|
||||
// if (dicLookup.ContainsKey(line.LineTypeMatchString))
|
||||
// {
|
||||
// ErrorMessage = "'Line type match string' duplication.";
|
||||
// return false;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// dicLookup.Add(line.LineTypeMatchString, null);
|
||||
// }
|
||||
// }
|
||||
|
||||
// return true;
|
||||
//}
|
||||
//public bool IsValidInvoiceHeader(Model.Export.SetSalesInvoice invoice)
|
||||
//{
|
||||
// ErrorMessage = null;
|
||||
|
||||
// var baseInvoice = CopyInvoiceHeaderToBase(invoice);
|
||||
// if (base.IsValidInvoiceHeader(baseInvoice))
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
//}
|
||||
//public bool IsValidInvoiceLine(Model.Export.SetSalesInvoiceLine invoiceLine)
|
||||
//{
|
||||
// ErrorMessage = null;
|
||||
|
||||
// var baseLine = CopyInvoiceLineToBase(invoiceLine);
|
||||
// if (!IsValidLineTypeMatchString(invoiceLine.LineTypeMatchString)
|
||||
// || !base.IsValidInvoiceLine(baseLine))
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// return true;
|
||||
//}
|
||||
//public bool IsValidLineTypeMatchString(string matchString)
|
||||
//{
|
||||
// ErrorMessage = null;
|
||||
// var stringCheck = new Logic.Utilities.StringCheck();
|
||||
// if (!stringCheck.MaxLength(matchString, 250))
|
||||
// {
|
||||
// ErrorMessage = "Invalid Line Type Match String: " + stringCheck.ErrorMessage;
|
||||
// return false;
|
||||
// }
|
||||
// return true;
|
||||
//}
|
||||
//private Model.Account.SalesInvoice CopyInvoiceToBase(Model.Export.SetSalesInvoice invoice)
|
||||
//{
|
||||
// var baseInvoice = CopyInvoiceHeaderToBase(invoice);
|
||||
// if (invoice.IsSetInvoiceLineList)
|
||||
// {
|
||||
// var baseLineList = new List<Model.Account.SalesInvoiceLine>();
|
||||
// foreach (var line in invoice.InvoiceLineList)
|
||||
// {
|
||||
// baseLineList.Add(CopyInvoiceLineToBase(line));
|
||||
// }
|
||||
// baseInvoice.InvoiceLineList = baseLineList;
|
||||
// }
|
||||
// return baseInvoice;
|
||||
//}
|
||||
|
||||
//private Model.Account.SalesInvoice CopyInvoiceHeaderToBase(Model.Export.SetSalesInvoice invoice)
|
||||
//{
|
||||
// var baseInvoice = new Model.Account.SalesInvoice();
|
||||
|
||||
// if (invoice.IsSetContactName)
|
||||
// { baseInvoice.ContactName = invoice.ContactName; }
|
||||
// if (invoice.IsSetInvoiceAmount)
|
||||
// { baseInvoice.InvoiceAmount = invoice.InvoiceAmount; }
|
||||
// if (invoice.IsSetInvoiceCurrencyCode)
|
||||
// { baseInvoice.InvoiceCurrencyCode = invoice.InvoiceCurrencyCode; }
|
||||
// if (invoice.IsSetInvoiceDate)
|
||||
// { baseInvoice.InvoiceDate = invoice.InvoiceDate; }
|
||||
// if (invoice.IsSetInvoiceNumber)
|
||||
// { baseInvoice.InvoiceNumber = invoice.InvoiceNumber; }
|
||||
// if (invoice.IsSetInvoiceReference)
|
||||
// { baseInvoice.InvoiceReference = invoice.InvoiceReference; }
|
||||
// if (invoice.IsSetIsComplete)
|
||||
// { baseInvoice.IsComplete = invoice.IsComplete; }
|
||||
|
||||
// return baseInvoice;
|
||||
//}
|
||||
//private Model.Account.SalesInvoiceLine CopyInvoiceLineToBase(Model.Export.SetSalesInvoiceLine invoiceLine)
|
||||
//{
|
||||
// var baseLine = new Model.Account.SalesInvoiceLine();
|
||||
|
||||
// if (invoiceLine.IsSetAccountCode)
|
||||
// { baseLine.AccountCode = invoiceLine.AccountCode; }
|
||||
|
||||
// // something missing here ??????
|
||||
|
||||
// if (invoiceLine.IsSetDescription)
|
||||
// { baseLine.Description = invoiceLine.Description; }
|
||||
// if (invoiceLine.IsSetNetAmount)
|
||||
// { baseLine.TotalNetAmount = invoiceLine.NetAmount; }
|
||||
|
||||
// // tax adjustment to set ??????????
|
||||
|
||||
// if (invoiceLine.IsSetTaxCode)
|
||||
// { baseLine.TaxCode = invoiceLine.TaxCode; }
|
||||
|
||||
// return baseLine;
|
||||
//}
|
||||
}
|
||||
}
|
||||
261
src/bnhtrade.Core/Logic/Product/GetCompetitivePrice.cs
Normal file
261
src/bnhtrade.Core/Logic/Product/GetCompetitivePrice.cs
Normal file
@@ -0,0 +1,261 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Logic.Product
|
||||
{
|
||||
public class GetCompetitivePrice
|
||||
{
|
||||
private Dictionary<string, Model.Product.CompetitivePrice> competitivePrices;
|
||||
private int newConditionId = Data.Database.Constants.GetProductConditionIdNew();
|
||||
private string sqlConnectionString;
|
||||
private Data.Database.Product.ReadCompetitivePrice read;
|
||||
private List<string> productIdList;
|
||||
private List<string> conditionIdList;
|
||||
private Data.Database.Product.ReadCompetitivePrice dbRead;
|
||||
private Dictionary<int, decimal> newConditionMultipier;
|
||||
|
||||
public GetCompetitivePrice(string sqlConnectionString)
|
||||
{
|
||||
this.sqlConnectionString = sqlConnectionString;
|
||||
dbRead = new Data.Database.Product.ReadCompetitivePrice(sqlConnectionString);
|
||||
newConditionMultipier = new Dictionary<int, decimal>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If a competitive price for a used condition is not found, return an estimated figure.
|
||||
/// </summary>
|
||||
public bool EstimatePrice { get; set; } = false;
|
||||
|
||||
public int DistinctRequestCount { get; private set; } = 0;
|
||||
|
||||
public int DistinctResponceCount { get; private set; } = 0;
|
||||
|
||||
public void Innit()
|
||||
{
|
||||
DistinctRequestCount = 0;
|
||||
DistinctResponceCount = 0;
|
||||
}
|
||||
|
||||
public Dictionary<string, Model.Product.CompetitivePrice> Execute(List<Model.Sku.Price.SkuPriceParameter> skuParamList)
|
||||
{
|
||||
var requestList = new List<(int ProductId, int ConditionId)>();
|
||||
for (int i = 0; i < skuParamList.Count; i++)
|
||||
{
|
||||
requestList.Add((skuParamList[i].ProductId, skuParamList[i].ConditionId));
|
||||
}
|
||||
var result = Execute(requestList);
|
||||
|
||||
// build return list
|
||||
var returnList = new Dictionary<string, Model.Product.CompetitivePrice>();
|
||||
for (int i = 0; i < skuParamList.Count; i++)
|
||||
{
|
||||
// skip?
|
||||
if (returnList.ContainsKey(skuParamList[i].SkuNumber))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// make a match
|
||||
for (int j = 0; j < result.Count; j++)
|
||||
{
|
||||
if (skuParamList[i].ProductId == result[j].ProductId && skuParamList[i].ConditionId == result[j].ConditionId)
|
||||
{
|
||||
returnList.Add(skuParamList[i].SkuNumber, result[j].Clone());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnList;
|
||||
}
|
||||
|
||||
public List<Model.Product.CompetitivePrice> Execute(List<(int ProductId, int ConditionId)> requestList)
|
||||
{
|
||||
Innit();
|
||||
|
||||
var result = new List<Model.Product.CompetitivePrice>();
|
||||
|
||||
if (requestList == null || !requestList.Any())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
// build distinct list
|
||||
var distinctRequestList = new List<(int productId, int conditionId)>();
|
||||
for (int i = 0; i < requestList.Count; i++)
|
||||
{
|
||||
// filter values already requested
|
||||
bool distinct = true;
|
||||
for (int j = 0; j < distinctRequestList.Count; j++)
|
||||
{
|
||||
if (requestList[i].ProductId == distinctRequestList[j].productId
|
||||
&& requestList[i].ConditionId == distinctRequestList[j].conditionId)
|
||||
{
|
||||
distinct = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (distinct)
|
||||
{ distinctRequestList.Add((requestList[i].ProductId, requestList[i].ConditionId)); }
|
||||
}
|
||||
|
||||
DistinctRequestCount = distinctRequestList.Count();
|
||||
var dbResult = dbRead.Execute(distinctRequestList);
|
||||
|
||||
// only contiue if estimated values are retured
|
||||
if (DistinctRequestCount == dbResult.Count || !EstimatePrice)
|
||||
{
|
||||
DistinctResponceCount = dbResult.Count;
|
||||
return result;
|
||||
}
|
||||
|
||||
// build estimated list
|
||||
var estimatedRequestList = new List<(int productId, int conditionId)>();
|
||||
//var conditionMultipier = new Dictionary<int, decimal>();
|
||||
for (int i = 0; i < distinctRequestList.Count; i++)
|
||||
{
|
||||
bool request = true;
|
||||
// check if db returned record
|
||||
for (int j = 0; j < dbResult.Count; j++)
|
||||
{
|
||||
if (distinctRequestList[i].productId == dbResult[j].ProductId
|
||||
&& distinctRequestList[i].conditionId == dbResult[j].ConditionId)
|
||||
{
|
||||
request = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// check if 'new' condition price has already been retrived
|
||||
if (request)
|
||||
{
|
||||
for (int j = 0; j < dbResult.Count; j++)
|
||||
{
|
||||
if (distinctRequestList[i].productId == dbResult[j].ProductId
|
||||
&& dbResult[j].ConditionId == newConditionId)
|
||||
{
|
||||
request = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// add to request lists
|
||||
if (request)
|
||||
{
|
||||
estimatedRequestList.Add((distinctRequestList[i].productId, newConditionId));
|
||||
if (!newConditionMultipier.ContainsKey(distinctRequestList[i].conditionId))
|
||||
{
|
||||
newConditionMultipier.Add(distinctRequestList[i].conditionId, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dbResult.AddRange(dbRead.Execute(estimatedRequestList));
|
||||
UpdateConditionMultipers();
|
||||
|
||||
// build a new return list
|
||||
var newResult = new List<Model.Product.CompetitivePrice>();
|
||||
var noMatchList = new List<(int productId, int conditionId)>();
|
||||
for (int i = 0; i < distinctRequestList.Count; i++)
|
||||
{
|
||||
// add exact matches
|
||||
bool noMatch = true;
|
||||
for (int j = 0; j < dbResult.Count; j++)
|
||||
{
|
||||
if (distinctRequestList[i].productId == dbResult[j].ProductId
|
||||
&& distinctRequestList[i].conditionId == dbResult[j].ConditionId)
|
||||
{
|
||||
noMatch = false;
|
||||
newResult.Add(dbResult[j]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// add estimated matches
|
||||
if (noMatch)
|
||||
{
|
||||
for (int j = 0; j < dbResult.Count; j++)
|
||||
{
|
||||
if (distinctRequestList[i].productId == dbResult[j].ProductId
|
||||
&& dbResult[j].ConditionId == newConditionId)
|
||||
{
|
||||
if (!newConditionMultipier.ContainsKey(distinctRequestList[i].conditionId))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var clone = dbResult[j].Clone();
|
||||
clone.ConditionId = distinctRequestList[i].conditionId;
|
||||
clone.Price = decimal.Round(clone.Price * newConditionMultipier[distinctRequestList[i].conditionId], 2);
|
||||
clone.PriceIsEstimated = true;
|
||||
|
||||
newResult.Add(clone);
|
||||
noMatch = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (noMatch)
|
||||
{
|
||||
noMatchList.Add(distinctRequestList[i]);
|
||||
}
|
||||
}
|
||||
|
||||
DistinctResponceCount = newResult.Count;
|
||||
return newResult;
|
||||
}
|
||||
|
||||
public Model.Product.CompetitivePrice Execute(int productId, int conditionId)
|
||||
{
|
||||
Innit();
|
||||
DistinctRequestCount = 1;
|
||||
var result = dbRead.Execute(new List<(int, int)> { (productId, conditionId) });
|
||||
|
||||
if (!result.Any())
|
||||
{
|
||||
DistinctResponceCount = 0;
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
DistinctResponceCount = 1;
|
||||
return result.First();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateConditionMultipers()
|
||||
{
|
||||
var conditionInfo = new List<Model.Sku.SkuConditionInfo>();
|
||||
|
||||
if (newConditionMultipier.Any())
|
||||
{
|
||||
conditionInfo = new Logic.Sku.GetSkuConditionInfo(sqlConnectionString)
|
||||
.GetByConditionId(newConditionMultipier.Keys.ToList());
|
||||
}
|
||||
else
|
||||
{
|
||||
conditionInfo = new Logic.Sku.GetSkuConditionInfo(sqlConnectionString).GetAll();
|
||||
}
|
||||
|
||||
for(int i = 0; i < conditionInfo.Count; i++)
|
||||
{
|
||||
if (newConditionMultipier.ContainsKey(conditionInfo[i].SkuConditionId))
|
||||
{
|
||||
newConditionMultipier[conditionInfo[i].SkuConditionId] = conditionInfo[i].CompetitivePriceMultiplier;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Condition Id mismatch");
|
||||
}
|
||||
}
|
||||
|
||||
// check all multipilers have been set
|
||||
for (int i = 0; i < newConditionMultipier.Count; i++)
|
||||
{
|
||||
if (newConditionMultipier.ElementAt(i).Value <= 0)
|
||||
{
|
||||
throw new Exception("Invalid price multiplier");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
30
src/bnhtrade.Core/Logic/Sku/GetSkuConditionInfo.cs
Normal file
30
src/bnhtrade.Core/Logic/Sku/GetSkuConditionInfo.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Logic.Sku
|
||||
{
|
||||
public class GetSkuConditionInfo
|
||||
{
|
||||
private string sqlConnectionString;
|
||||
private Data.Database.Sku.ReadSkuConditionInfo dbRead;
|
||||
|
||||
public GetSkuConditionInfo(string sqlConnectionString)
|
||||
{
|
||||
this.sqlConnectionString = sqlConnectionString;
|
||||
dbRead = new Data.Database.Sku.ReadSkuConditionInfo(sqlConnectionString);
|
||||
}
|
||||
|
||||
public List<Model.Sku.SkuConditionInfo> GetAll()
|
||||
{
|
||||
return dbRead.Read(new List<int>());
|
||||
}
|
||||
|
||||
public List<Model.Sku.SkuConditionInfo> GetByConditionId(List<int> conditionIdList)
|
||||
{
|
||||
return dbRead.Read(conditionIdList);
|
||||
}
|
||||
}
|
||||
}
|
||||
386
src/bnhtrade.Core/Logic/Sku/Price/FbaPricing.cs
Normal file
386
src/bnhtrade.Core/Logic/Sku/Price/FbaPricing.cs
Normal file
@@ -0,0 +1,386 @@
|
||||
using CsvHelper;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Transactions;
|
||||
|
||||
namespace bnhtrade.Core.Logic.Sku.Price
|
||||
{
|
||||
public class FbaPricing
|
||||
{
|
||||
private string sqlConnectionString;
|
||||
private bnhtrade.Core.Logic.Log.LogEvent log = new Log.LogEvent();
|
||||
string err = "FbaPricing Error: ";
|
||||
private string marginSchemeTaxCode = "T190";
|
||||
int repriceHoldOnSalePeriod = 14; // days
|
||||
private int newConditionId = Data.Database.Constants.GetProductConditionIdNew();
|
||||
private List<Model.Sku.Price.SkuPriceParameter> skuInfo;
|
||||
private Dictionary<string, Model.Product.CompetitivePrice> competitivePrices;
|
||||
DateTime crTimeStamp = DateTime.UtcNow;
|
||||
private int repriceIncrementDivisor = 60;
|
||||
private Dictionary<string, int> saleCountInPeriod = new Dictionary<string, int>();
|
||||
private Logic.Account.TaxCalculation taxCalc;
|
||||
private decimal marginSchemeMargin;
|
||||
|
||||
public FbaPricing(string sqlConnectionString)
|
||||
{
|
||||
this.sqlConnectionString = sqlConnectionString;
|
||||
taxCalc = new Account.TaxCalculation();
|
||||
crTimeStamp = DateTime.UtcNow;
|
||||
marginSchemeMargin = taxCalc.GetMarginMultiplier(crTimeStamp);
|
||||
}
|
||||
|
||||
public void Update(bool overrideDayCheck = false)
|
||||
{
|
||||
using (var scope = new TransactionScope())
|
||||
{
|
||||
string orderChannel = "Amazon.co.uk"; // may in future enable other order channels
|
||||
|
||||
// need to add some cheks up here for last stock reconcilliation
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// get current sku base pricing details (stock quantity, competative price, VAT info, etc.)
|
||||
skuInfo = new Data.Database.Sku.Price.ReadParameter(sqlConnectionString).Execute();
|
||||
if (skuInfo == null || !skuInfo.Any())
|
||||
{
|
||||
throw new Exception("Querying the database returned no records.");
|
||||
}
|
||||
|
||||
// create lists that we'll add to during lopp
|
||||
var loader = new List<Model.Export.AmazonIventoryLoaderFile>();
|
||||
var crDictionary = new Dictionary<string, Model.Sku.Price.PriceInfo>();
|
||||
|
||||
// open needed classes
|
||||
var readAge = new Data.Database.Import.ReadFbaInventoryAge(sqlConnectionString);
|
||||
|
||||
// get current db pricing
|
||||
var dbDictionary = new Data.Database.Sku.Price.ReadPricingDetail(sqlConnectionString).ReadDictionary(skuInfo.Select(o => o.SkuNumber).ToList(), orderChannel);
|
||||
|
||||
// get required competivie prices
|
||||
var readComp = new Logic.Product.GetCompetitivePrice(sqlConnectionString);
|
||||
readComp.EstimatePrice = true;
|
||||
var compPrices = readComp.Execute(skuInfo);
|
||||
|
||||
// loop through skus returnd from stock query
|
||||
for (int i = 0; i < skuInfo.Count(); i++)
|
||||
{
|
||||
string skuNumber = skuInfo[i].SkuNumber;
|
||||
|
||||
var cr = new Model.Sku.Price.PriceInfo();
|
||||
|
||||
if (!overrideDayCheck && dbDictionary.Count > 0 && !OkayToReprice(dbDictionary[skuNumber].PriceInfoTimeStamp))
|
||||
{ continue; }
|
||||
|
||||
// load in values from skuInfo
|
||||
cr.PriceTypeId = 1;
|
||||
cr.ReviewRequired = false;
|
||||
cr.OrderChannel = orderChannel;
|
||||
cr.OrderChannelQuantity = skuInfo[i].TotalQuantity;
|
||||
cr.PriceInfoTimeStamp = crTimeStamp;
|
||||
cr.SkuNumber = skuInfo[i].SkuNumber;
|
||||
|
||||
// get inventory age range
|
||||
var invAge = readAge.BySkuNumber(skuInfo[i].SkuNumber, orderChannel);
|
||||
if (invAge == null)
|
||||
{
|
||||
// this means lost stock, or unreconciled inventory... need to pause these skus else the price could decrease without it being on sale
|
||||
err += "No records returned from tblImportFbaInventoryAgeReport for skuID=" + skuInfo[i].SkuId;
|
||||
log.LogError(err);
|
||||
throw new Exception(err);
|
||||
}
|
||||
cr.InventoryAgeMin = invAge.Value.MinAge;
|
||||
cr.InventoryAgeMax = invAge.Value.MaxAge;
|
||||
|
||||
// get minimum prices
|
||||
cr.UnitMinPriceCost = GetMinPriceCost(i);
|
||||
cr.UnitMinPriceProfit = GetMinPriceProfit(i);
|
||||
cr.UnitPurchaseCost = skuInfo[i].UnitCostAverage;
|
||||
|
||||
// set competitive price
|
||||
if (compPrices.ContainsKey(skuInfo[i].SkuNumber))
|
||||
{
|
||||
cr.CompetitivePrice = compPrices[skuInfo[i].SkuNumber].Price;
|
||||
cr.CompetitivePriceIsEstimated = compPrices[skuInfo[i].SkuNumber].PriceIsEstimated;
|
||||
}
|
||||
else
|
||||
{
|
||||
cr.CompetitivePrice = cr.UnitMinPriceProfit + (cr.UnitMinPriceProfit / 2);
|
||||
cr.CompetitivePriceIsEstimated = true;
|
||||
}
|
||||
|
||||
// set min max price
|
||||
cr.RepriceIncrement = cr.CompetitivePrice / repriceIncrementDivisor;
|
||||
|
||||
if (dbDictionary.ContainsKey(skuNumber))
|
||||
{
|
||||
// sales wihtin period, therefore hold price
|
||||
if (GetSaleCountInPeriod(i) > 0)
|
||||
{
|
||||
cr.MaxPrice = dbDictionary[skuNumber].MaxPrice;
|
||||
cr.MinPrice = dbDictionary[skuNumber].MinPrice;
|
||||
cr.RepriceIncrement = dbDictionary[skuNumber].RepriceIncrement;
|
||||
}
|
||||
// else reduce
|
||||
else
|
||||
{
|
||||
if (dbDictionary[skuNumber].MaxPrice < dbDictionary[skuNumber].MinPrice)
|
||||
{
|
||||
err += "Max price lower than min price";
|
||||
log.LogError(err);
|
||||
throw new Exception(err);
|
||||
}
|
||||
// redue both prices together
|
||||
else if (dbDictionary[skuNumber].MaxPrice == dbDictionary[skuNumber].MinPrice)
|
||||
{
|
||||
cr.MaxPrice = dbDictionary[skuNumber].MaxPrice - cr.RepriceIncrement;
|
||||
cr.MinPrice = cr.MaxPrice;
|
||||
}
|
||||
// reduce only max until it hits the min
|
||||
else
|
||||
{
|
||||
cr.MaxPrice = dbDictionary[skuNumber].MaxPrice - cr.RepriceIncrement;
|
||||
if (cr.MaxPrice < dbDictionary[skuNumber].MinPrice)
|
||||
{
|
||||
cr.MinPrice = cr.MaxPrice;
|
||||
}
|
||||
else
|
||||
{
|
||||
cr.MinPrice = dbDictionary[skuNumber].MinPrice;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// new value
|
||||
cr.MaxPrice = cr.CompetitivePrice * 1.2m;
|
||||
cr.MinPrice = cr.CompetitivePrice * 1m;
|
||||
}
|
||||
|
||||
// check on min price
|
||||
cr.UnitMinPriceDestory = GetMinPriceDestroy(i);
|
||||
if (cr.MaxPrice < cr.UnitMinPriceDestory) { cr.MaxPrice = cr.UnitMinPriceDestory; }
|
||||
if (cr.MinPrice < cr.UnitMinPriceDestory) { cr.MinPrice = cr.UnitMinPriceDestory; }
|
||||
|
||||
// add values to inventory loader list
|
||||
var item = new Model.Export.AmazonIventoryLoaderFile();
|
||||
item.Sku = skuInfo[i].SkuNumber;
|
||||
item.Price = cr.MaxPrice;
|
||||
item.MinimumAllowedPrice = cr.MinPrice;
|
||||
item.MaximumAllowedPrice = cr.MaxPrice;
|
||||
item.SetFulfillmentCenterId(true);
|
||||
loader.Add(item);
|
||||
|
||||
// save current prices to dictionary
|
||||
if (crDictionary.ContainsKey(skuNumber))
|
||||
{
|
||||
err += "Multiple SkuId found in data";
|
||||
log.LogError(err);
|
||||
throw new Exception(err);
|
||||
}
|
||||
crDictionary.Add(skuNumber, cr);
|
||||
}
|
||||
// finish loop
|
||||
|
||||
// validate and save values to database
|
||||
var validate = new Core.Logic.Validate.SkuPriceInfo();
|
||||
if (!validate.IsValidDatabaseCreate(crDictionary.Values.ToList()))
|
||||
{
|
||||
err += "Database object create validation failed";
|
||||
log.LogError(err, validate.ValidationResultListToString());
|
||||
throw new Exception(err);
|
||||
}
|
||||
|
||||
new Data.Database.Sku.Price.CreatePricingDetail(sqlConnectionString).Executue(crDictionary.Values.ToList());
|
||||
|
||||
// create and upload inventory loader file to amazon
|
||||
var exportList = new List<Model.Export.AmazonIventoryLoaderFile>();
|
||||
foreach (var item in crDictionary.Values)
|
||||
{
|
||||
var listItem = new Model.Export.AmazonIventoryLoaderFile();
|
||||
listItem.Sku = item.SkuNumber;
|
||||
listItem.MinimumAllowedPrice = item.MinPrice;
|
||||
listItem.MaximumAllowedPrice = item.MaxPrice;
|
||||
listItem.Price = item.MaxPrice;
|
||||
listItem.SetFulfillmentCenterId(true);
|
||||
exportList.Add(listItem);
|
||||
}
|
||||
|
||||
// validate
|
||||
var vaildateInvLoader = new Validate.AmazonIventoryLoaderFile();
|
||||
if (!vaildateInvLoader.IsValidFbaPricing(exportList))
|
||||
{
|
||||
err += "Inventory loader object validation failed";
|
||||
log.LogError(err, vaildateInvLoader.ValidationResultListToString());
|
||||
throw new Exception(err);
|
||||
}
|
||||
|
||||
// create file stream
|
||||
var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.CurrentCulture);
|
||||
config.Delimiter = "\t";
|
||||
config.Encoding = Encoding.UTF8;
|
||||
|
||||
var stream = new MemoryStream();
|
||||
using (var writer = new StreamWriter(stream, Encoding.UTF8))
|
||||
using (var csv = new CsvWriter(writer, config))
|
||||
{
|
||||
csv.WriteRecords(exportList);
|
||||
}
|
||||
|
||||
// submit file to database and amazon mws
|
||||
var submit = new Logic.Export.AmazonSubmitFile(sqlConnectionString);
|
||||
|
||||
return;
|
||||
|
||||
submit.SubmitInventoryLoader(stream);
|
||||
|
||||
scope.Complete();
|
||||
}
|
||||
}
|
||||
|
||||
private bool OkayToReprice(DateTime lastPriceUpdate)
|
||||
{
|
||||
if (lastPriceUpdate == default(DateTime))
|
||||
{
|
||||
err += "Invalid, datetime is default.";
|
||||
log.LogError(err);
|
||||
throw new Exception(err);
|
||||
}
|
||||
|
||||
bool update = false;
|
||||
lastPriceUpdate = new DateTime(lastPriceUpdate.Year, lastPriceUpdate.Month, lastPriceUpdate.Day);
|
||||
DateTime today = new DateTime(crTimeStamp.Year, crTimeStamp.Month, crTimeStamp.Day);
|
||||
|
||||
// will only update once on tue, wed or thurs each week.
|
||||
if (today.DayOfWeek == DayOfWeek.Tuesday || today.DayOfWeek == DayOfWeek.Wednesday || today.DayOfWeek == DayOfWeek.Thursday)
|
||||
{
|
||||
if (today > lastPriceUpdate.AddDays(3))
|
||||
{
|
||||
update = true;
|
||||
}
|
||||
}
|
||||
|
||||
return update;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the minimum sale price to break even.
|
||||
/// </summary>
|
||||
/// <param name="i"></param>
|
||||
/// <returns></returns>
|
||||
private decimal GetMinPriceCost(int i)
|
||||
{
|
||||
decimal costPrice = skuInfo[i].UnitCostAverage;
|
||||
decimal agentFeeFixed = skuInfo[i].AgentFeeFixed;
|
||||
decimal agentFeeMargin = skuInfo[i].AgentFeeMargin;
|
||||
decimal vatMargin = skuInfo[i].VatMargin;
|
||||
|
||||
decimal price = 0;
|
||||
|
||||
if (skuInfo[i].TaxCode == marginSchemeTaxCode)
|
||||
{
|
||||
price = (costPrice + agentFeeFixed - (costPrice * marginSchemeMargin))
|
||||
/ (1 - agentFeeMargin - marginSchemeMargin);
|
||||
}
|
||||
else
|
||||
{
|
||||
price = (costPrice + agentFeeFixed)
|
||||
/ (1 - agentFeeMargin - vatMargin);
|
||||
}
|
||||
price = decimal.Round(price, 2);
|
||||
return price;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the minimum sale price to achieve required profit margin.
|
||||
/// </summary>
|
||||
/// <param name="i"></param>
|
||||
/// <returns>Minimum price in decimal</returns>
|
||||
private decimal GetMinPriceProfit(int i)
|
||||
{
|
||||
decimal costPrice = skuInfo[i].UnitCostAverage;
|
||||
decimal minProfit = skuInfo[i].PriceMinProfit;
|
||||
decimal profitMargin = skuInfo[i].ProfitMargin;
|
||||
decimal agentFeeFixed = skuInfo[i].AgentFeeFixed;
|
||||
decimal agentFeeMargin = skuInfo[i].AgentFeeMargin;
|
||||
decimal vatMargin = skuInfo[i].VatMargin;
|
||||
|
||||
decimal price = 0;
|
||||
|
||||
if (skuInfo[i].TaxCode == marginSchemeTaxCode) // taxcodeinfo now has ismarginscheme boolean
|
||||
{
|
||||
price = (costPrice + agentFeeFixed - (costPrice * marginSchemeMargin))
|
||||
/ (1 - profitMargin - agentFeeMargin - marginSchemeMargin);
|
||||
}
|
||||
else
|
||||
{
|
||||
price = (costPrice + agentFeeFixed)
|
||||
/ (1 - profitMargin - agentFeeMargin - vatMargin);
|
||||
}
|
||||
price = decimal.Round(price, 2);
|
||||
|
||||
// if profit margin is less than min required, redo using min value (not percent)
|
||||
if (price < minProfit)
|
||||
{
|
||||
if (skuInfo[i].TaxCode == marginSchemeTaxCode)
|
||||
{
|
||||
price = (minProfit + costPrice + agentFeeFixed - (costPrice * marginSchemeMargin))
|
||||
/ (1 - agentFeeMargin - marginSchemeMargin);
|
||||
}
|
||||
else
|
||||
{
|
||||
price = (minProfit + costPrice + agentFeeFixed)
|
||||
/ (1 - agentFeeMargin - vatMargin);
|
||||
}
|
||||
}
|
||||
price = decimal.Round(price, 2);
|
||||
return price;
|
||||
}
|
||||
|
||||
private decimal GetMinPriceDestroy(int i)
|
||||
{
|
||||
decimal agentFeeFixed = skuInfo[i].AgentFeeFixed;
|
||||
decimal agentFeeMargin = skuInfo[i].AgentFeeMargin;
|
||||
decimal vatMargin = skuInfo[i].VatMargin;
|
||||
|
||||
decimal price = 0;
|
||||
|
||||
if (skuInfo[i].TaxCode == marginSchemeTaxCode)
|
||||
{
|
||||
price = (agentFeeFixed) / (1 - agentFeeMargin);
|
||||
}
|
||||
else
|
||||
{
|
||||
price = (agentFeeFixed) / (1 - agentFeeMargin - vatMargin);
|
||||
}
|
||||
price = decimal.Round(price, 2);
|
||||
return price;
|
||||
}
|
||||
|
||||
private int GetSaleCountInPeriod(int i)
|
||||
{
|
||||
if (!saleCountInPeriod.Any())
|
||||
{
|
||||
saleCountInPeriod = new Data.Database.Import.ReadFbaSaleShipment(sqlConnectionString)
|
||||
.GetSaleCount(skuInfo.Select(x => x.SkuNumber).ToList(), DateTime.Now.AddDays(repriceHoldOnSalePeriod * -1), DateTime.Now);
|
||||
}
|
||||
if (saleCountInPeriod.ContainsKey(skuInfo[i].SkuNumber))
|
||||
{
|
||||
return saleCountInPeriod[skuInfo[i].SkuNumber];
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
787
src/bnhtrade.Core/Logic/Sku/Price/UpdateRepricingValues.cs
Normal file
787
src/bnhtrade.Core/Logic/Sku/Price/UpdateRepricingValues.cs
Normal file
@@ -0,0 +1,787 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Data.SqlClient;
|
||||
using System.Transactions;
|
||||
|
||||
namespace bnhtrade.Core.Logic.Sku.Price
|
||||
{
|
||||
public class UpdateRepricingValues
|
||||
{
|
||||
//public void Update(string sqlConnectionString, bool skipReportUpdate = false)
|
||||
//{
|
||||
// // need to add some cheks up here for last amazon reports import dates
|
||||
|
||||
|
||||
|
||||
// /*
|
||||
// * Quite complex this one, order of business
|
||||
// *
|
||||
// * Stage 1 - Stock Ledger Query reporting FBA stock (loop through this table)
|
||||
// * Stage 1 - Read current values from SkuPrice tabel into variables
|
||||
// * Stage 2 - Get/Set current MIN Price type 'crPriceMin_SkuPriceType'
|
||||
// * Stage 3 - Set MIN Price, based off type
|
||||
// * Stage 4 - Get/Set current MAX Price type 'crPriceMin_SkuPriceType'
|
||||
// * Stage 5 - Set MAX Price, based off type
|
||||
// * Stage 6 - Final check before db update
|
||||
// * Stage 7 - Update main/history table
|
||||
// */
|
||||
|
||||
// DateTime crTimeStamp = DateTime.UtcNow;
|
||||
// int orderChannelId = 2; // may in future enable other order channels
|
||||
|
||||
// // refers to max price movements
|
||||
// decimal repriceDecreaseIncrement = 0.03m; // 3% each week
|
||||
// int repriceDecreasePeriod = 7; // days
|
||||
// int repriceHoldOnSalePeriod = 14; // days
|
||||
// decimal repriceIncreaseIncrement = repriceDecreaseIncrement; // increases price if max sale price is within % of max price
|
||||
// decimal repriceIncreaseOnStockSold = 0.3m; // percent of total qty sold over sale hold period
|
||||
|
||||
// // add a check up here to test for any ASINs that do not have an estimated fee
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// // maybe add a constistancy check here (double entries in table (sku and order channel combination)
|
||||
|
||||
|
||||
// using (var conn = new SqlConnection(sqlConnectionString))
|
||||
// {
|
||||
// // loop through table
|
||||
// using (var cmd01 = new SqlCommand("needs deleteing", conn))
|
||||
// {
|
||||
// using (var reader01 = cmd01.ExecuteReader())
|
||||
// {
|
||||
// var skuPricing = new Data.Database.Sku.Price.ReadParameter(sqlConnectionString).Execute();
|
||||
|
||||
// if (skuPricing == null)
|
||||
// {
|
||||
// throw new Exception("Querying the database returned no records.");
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// new Data.Database.Sku.Price.UpdateSkuPriceIsProcessed(sqlConnectionString).Update();
|
||||
// }
|
||||
|
||||
// using (var scope = new TransactionScope())
|
||||
// using (var scopeConn = new SqlConnection(sqlConnectionString))
|
||||
// {
|
||||
// scopeConn.Open();
|
||||
|
||||
// foreach (var sku in skuPricing)
|
||||
// {
|
||||
// // switches
|
||||
// bool insertRequired = false; // skuId does not already exist in table
|
||||
// bool updateRequired = false; // skuId exists and an edit is required
|
||||
// bool resetMaxBaseAndMultiplier = false; // Quantity is moving from 0 to >0, lookup/update some values is required
|
||||
|
||||
// // current (cr) variables
|
||||
// var cr = new Model.Sku.Price.DetailResponce();
|
||||
|
||||
// cr.OrderChannelQuantity = sku.TotalQuantity;
|
||||
// cr.UnitAvgCost = sku.UnitCostAverage;
|
||||
|
||||
|
||||
// // Stage 1
|
||||
// // get db values from inventory table
|
||||
// var db = new Data.Database.Sku.Price.ReadPricingDetail(sqlConnectionString).Read(sku.SkuId, orderChannelId);
|
||||
// if (db == null)
|
||||
// {
|
||||
// insertRequired = true;
|
||||
// db = new Model.Sku.Price.DetailResponce();
|
||||
|
||||
// // if this is null alot of the following code can be skipped, wip
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// }
|
||||
|
||||
// // STAGE 2
|
||||
// // SKU current stock details (i.e. quantity, cost per unit, inventory age, etc.)
|
||||
|
||||
// // get inventory age range
|
||||
// var invAge = new Data.Database.Import.ReadFbaInventoryAge(sqlConnectionString).BySkuId(sku.SkuId, db.OrderChannelId);
|
||||
|
||||
// if (invAge == null)
|
||||
// {
|
||||
// throw new Exception("No records returned from tblImportFbaInventoryAgeReport for skuID=" + sku.SkuId);
|
||||
// }
|
||||
// cr.InventoryAgeMin = invAge.Value.MinAge;
|
||||
// cr.InventoryAgeMax = invAge.Value.MaxAge;
|
||||
|
||||
|
||||
// // STAGE 3
|
||||
// // Get/Set Min Price SkukPriceTypeID
|
||||
// // Do not change the 'crPriceMin_SkuPriceType' value after this stage
|
||||
|
||||
// //
|
||||
// //bool setMinToAuto = true;
|
||||
// cr.PriceMin_SkuPriceType = 0;
|
||||
// switch (db.PriceMin_SkuPriceType)
|
||||
// {
|
||||
// // Out of Stock
|
||||
// case 0:
|
||||
// if (cr.OrderChannelQuantity > 0)
|
||||
// { cr.PriceMin_SkuPriceType = 1; }
|
||||
// break;
|
||||
|
||||
// //Auto
|
||||
// case 1:
|
||||
// cr.PriceMin_SkuPriceType = db.PriceMin_SkuPriceType;
|
||||
// break;
|
||||
|
||||
// // Fixed SKU price
|
||||
// case 2:
|
||||
// cr.PriceMin_SkuPriceType = db.PriceMin_SkuPriceType;
|
||||
// break;
|
||||
|
||||
// // Manual Price, Permanent
|
||||
// case 100:
|
||||
// cr.PriceMin_SkuPriceType = db.PriceMin_SkuPriceType;
|
||||
// break;
|
||||
|
||||
// // Manual Price, Inv Age Range Includes
|
||||
// case 110:
|
||||
// if (db.PriceMinStoredInt >= cr.InventoryAgeMin && db.PriceMinStoredInt <= cr.InventoryAgeMax)
|
||||
// { cr.PriceMin_SkuPriceType = db.PriceMin_SkuPriceType; }
|
||||
// else { cr.PriceMin_SkuPriceType = 1; }
|
||||
// break;
|
||||
|
||||
// // Manual Price, Inv Age Range Less Than
|
||||
// case 111:
|
||||
// if (cr.InventoryAgeMax < db.PriceMinStoredInt)
|
||||
// { cr.PriceMin_SkuPriceType = db.PriceMin_SkuPriceType; }
|
||||
// else { cr.PriceMin_SkuPriceType = 1; }
|
||||
// break;
|
||||
|
||||
// // Manual Price, Inv Age Range Greater Than
|
||||
// case 112:
|
||||
// if (cr.InventoryAgeMin > db.PriceMinStoredInt)
|
||||
// { cr.PriceMin_SkuPriceType = db.PriceMin_SkuPriceType; }
|
||||
// else { cr.PriceMin_SkuPriceType = 1; }
|
||||
// break;
|
||||
|
||||
// // Manual Price, Inv Quanity is Less than
|
||||
// case 120:
|
||||
// if (cr.OrderChannelQuantity < db.PriceMinStoredInt)
|
||||
// { cr.PriceMin_SkuPriceType = db.PriceMin_SkuPriceType; }
|
||||
// else { cr.PriceMin_SkuPriceType = 1; }
|
||||
// break;
|
||||
|
||||
// // Manual Price, Inv Quanity is Greater than
|
||||
// case 121:
|
||||
// if (cr.OrderChannelQuantity > db.PriceMinStoredInt)
|
||||
// { cr.PriceMin_SkuPriceType = db.PriceMin_SkuPriceType; }
|
||||
// else { cr.PriceMin_SkuPriceType = 1; }
|
||||
// break;
|
||||
|
||||
// // Manual Price, Inv Quanity is Equal to
|
||||
// case 122:
|
||||
// if (cr.OrderChannelQuantity == db.PriceMinStoredInt)
|
||||
// { cr.PriceMin_SkuPriceType = db.PriceMin_SkuPriceType; }
|
||||
// else { cr.PriceMin_SkuPriceType = 1; }
|
||||
// break;
|
||||
|
||||
// // Manual Price, Inv Quanity is Equal to
|
||||
// case 123:
|
||||
// if (cr.OrderChannelQuantity != db.PriceMinStoredInt)
|
||||
// { cr.PriceMin_SkuPriceType = db.PriceMin_SkuPriceType; }
|
||||
// else { cr.PriceMin_SkuPriceType = 1; }
|
||||
// break;
|
||||
|
||||
// default:
|
||||
// // review of some sort required
|
||||
// if (db.PriceMin_SkuPriceType >= 200 && db.PriceMin_SkuPriceType < 225)
|
||||
// {
|
||||
// cr.PriceMin_SkuPriceType = db.PriceMin_SkuPriceType;
|
||||
// cr.ReviewRequired = true;
|
||||
// }
|
||||
// // error type
|
||||
// else if (db.PriceMin_SkuPriceType >= 225 && db.PriceMin_SkuPriceType < 256)
|
||||
// {
|
||||
// cr.PriceMin_SkuPriceType = db.PriceMin_SkuPriceType;
|
||||
// }
|
||||
// // unhandled id type
|
||||
// else
|
||||
// {
|
||||
// cr.PriceMin_SkuPriceType = 255;
|
||||
// cr.ReviewRequired = true;
|
||||
// }
|
||||
// break;
|
||||
// }
|
||||
|
||||
// // Check manual enteries are present, if they are required
|
||||
// if ((db.RequireAmountManual && db.PriceMinAmountManual == null) || (db.RequireStordedInt && db.PriceMinStoredInt == null))
|
||||
// {
|
||||
// cr.PriceMin_SkuPriceType = 253;
|
||||
// cr.ReviewRequired = true;
|
||||
// }
|
||||
|
||||
// // Stage 4
|
||||
// // Set MIN Price
|
||||
|
||||
// // calculate the min 'auto' sku price & tax
|
||||
// decimal crProfitMinAmount;
|
||||
// decimal crPriceMinCalculatedTax;
|
||||
|
||||
// if (sku.TaxRateName == "MS" || sku.TaxRateName == "GA")
|
||||
// {
|
||||
// cr.PriceMinAmountAuto = (5m * cr.UnitAvgCost + 6m * sku.AgentFeeFixed) / (-6m * sku.ProfitMargin - 6m * sku.AmazonMargin + 5m);
|
||||
// crPriceMinCalculatedTax = (cr.PriceMinAmountAuto - cr.UnitAvgCost) * (1 / 6);
|
||||
// crProfitMinAmount = cr.PriceMinAmountAuto * sku.ProfitMargin;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// cr.PriceMinAmountAuto = (cr.UnitAvgCost + sku.AgentFeeFixed) / (1 - (sku.ProfitMargin + sku.AmazonMargin + sku.VatMargin));
|
||||
// crPriceMinCalculatedTax = cr.PriceMinAmountAuto * sku.VatMargin;
|
||||
// crProfitMinAmount = cr.PriceMinAmountAuto * sku.ProfitMargin;
|
||||
// }
|
||||
|
||||
// // if profit margin is less than min required, redo
|
||||
// if (crProfitMinAmount < sku.PriceMinProfit)
|
||||
// {
|
||||
// if (sku.TaxRateName == "MS" || sku.TaxRateName == "GA")
|
||||
// {
|
||||
// cr.PriceMinAmountAuto = (6m * sku.PriceMinProfit + 5m * cr.UnitAvgCost + 6m * sku.AgentFeeFixed) / (-6m * sku.AmazonMargin + 5m);
|
||||
// crPriceMinCalculatedTax = (cr.PriceMinAmountAuto - cr.UnitAvgCost) * (1 / 6);
|
||||
// crProfitMinAmount = cr.PriceMinAmountAuto * sku.ProfitMargin;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// cr.PriceMinAmountAuto = (cr.UnitAvgCost + sku.AgentFeeFixed + sku.PriceMinProfit) / (1 - (sku.AgentFeeMargin + sku.VatMargin));
|
||||
// crPriceMinCalculatedTax = cr.PriceMinAmountAuto * sku.VatMargin;
|
||||
// crProfitMinAmount = cr.PriceMinAmountAuto * sku.ProfitMargin;
|
||||
// }
|
||||
// }
|
||||
|
||||
// // Calculate current final MIN price values
|
||||
// if (cr.PriceMin_SkuPriceType == 1)
|
||||
// {
|
||||
// cr.PriceMinAmountFinal = cr.PriceMinAmountAuto;
|
||||
// cr.PriceMinAmountFinalFee = (cr.PriceMinAmountFinal * sku.AgentFeeMargin) + sku.AgentFeeFixed;
|
||||
// cr.PriceMinAmountFinalTax = crPriceMinCalculatedTax;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// cr.PriceMinAmountFinal = (decimal)db.PriceMinAmountManual;
|
||||
// cr.PriceMinAmountFinalFee = ((decimal)db.PriceMinAmountManual * sku.AgentFeeMargin) + sku.AgentFeeFixed;
|
||||
// if (sku.TaxRateName == "MS" || sku.TaxRateName == "GA")
|
||||
// {
|
||||
// cr.PriceMinAmountFinalTax = ((decimal)db.PriceMinAmountManual - cr.UnitAvgCost) * (1 / 6);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// cr.PriceMinAmountFinalTax = cr.PriceMinAmountAuto * sku.VatMargin;
|
||||
// }
|
||||
// }
|
||||
|
||||
// // STAGE 5
|
||||
// // Get/Set MAX Price SkukPriceTypeID
|
||||
// // Do not change the 'cr.PriceMax_SkuPriceType' value after this stage
|
||||
|
||||
// cr.PriceMax_SkuPriceType = 0;
|
||||
// switch (db.PriceMax_SkuPriceType)
|
||||
// {
|
||||
// // Out of Stock
|
||||
// case 0:
|
||||
// if (cr.OrderChannelQuantity > 0)
|
||||
// { cr.PriceMax_SkuPriceType = 1; }
|
||||
// break;
|
||||
|
||||
// // Auto
|
||||
// case 1:
|
||||
// cr.PriceMax_SkuPriceType = db.PriceMax_SkuPriceType;
|
||||
// break;
|
||||
|
||||
// // Fixed SKU price
|
||||
// case 2:
|
||||
// cr.PriceMax_SkuPriceType = db.PriceMax_SkuPriceType;
|
||||
// break;
|
||||
|
||||
// // Manual Price, Permanent
|
||||
// case 100:
|
||||
// cr.PriceMax_SkuPriceType = db.PriceMax_SkuPriceType;
|
||||
// break;
|
||||
|
||||
// // Manual Price, Inv Age Range Includes
|
||||
// case 110:
|
||||
// if (db.PriceMaxStoredInt >= cr.InventoryAgeMin && db.PriceMaxStoredInt <= cr.InventoryAgeMax)
|
||||
// { cr.PriceMax_SkuPriceType = db.PriceMax_SkuPriceType; }
|
||||
// else { cr.PriceMax_SkuPriceType = 1; }
|
||||
// break;
|
||||
|
||||
// // Manual Price, Inv Age Range Less Than
|
||||
// case 111:
|
||||
// if (cr.InventoryAgeMax < db.PriceMaxStoredInt)
|
||||
// { cr.PriceMax_SkuPriceType = db.PriceMax_SkuPriceType; }
|
||||
// else { cr.PriceMax_SkuPriceType = 1; }
|
||||
// break;
|
||||
|
||||
// // Manual Price, Inv Age Range Greater Than
|
||||
// case 112:
|
||||
// if (cr.InventoryAgeMin > db.PriceMaxStoredInt)
|
||||
// { cr.PriceMax_SkuPriceType = db.PriceMax_SkuPriceType; }
|
||||
// else { cr.PriceMax_SkuPriceType = 1; }
|
||||
// break;
|
||||
|
||||
// // Manual Price, Inv Quanity is Less than
|
||||
// case 120:
|
||||
// if (cr.OrderChannelQuantity < db.PriceMaxStoredInt)
|
||||
// { cr.PriceMax_SkuPriceType = db.PriceMax_SkuPriceType; }
|
||||
// else { cr.PriceMax_SkuPriceType = 1; }
|
||||
// break;
|
||||
|
||||
// // Manual Price, Inv Quanity is Greater than
|
||||
// case 121:
|
||||
// if (cr.OrderChannelQuantity > db.PriceMaxStoredInt)
|
||||
// { cr.PriceMax_SkuPriceType = db.PriceMax_SkuPriceType; }
|
||||
// else { cr.PriceMax_SkuPriceType = 1; }
|
||||
// break;
|
||||
|
||||
// // Manual Price, Inv Quanity is Equal to
|
||||
// case 122:
|
||||
// if (cr.OrderChannelQuantity == db.PriceMaxStoredInt)
|
||||
// { cr.PriceMax_SkuPriceType = db.PriceMax_SkuPriceType; }
|
||||
// else { cr.PriceMax_SkuPriceType = 1; }
|
||||
// break;
|
||||
|
||||
// // Manual Price, Inv Quanity is Not Equal to
|
||||
// case 123:
|
||||
// if (cr.OrderChannelQuantity == db.PriceMaxStoredInt)
|
||||
// { cr.PriceMax_SkuPriceType = db.PriceMax_SkuPriceType; }
|
||||
// else { cr.PriceMax_SkuPriceType = 1; }
|
||||
// break;
|
||||
|
||||
// default:
|
||||
// // review of some sort required
|
||||
// if (db.PriceMax_SkuPriceType >= 200 && db.PriceMax_SkuPriceType < 225)
|
||||
// {
|
||||
// cr.PriceMax_SkuPriceType = db.PriceMax_SkuPriceType;
|
||||
// cr.ReviewRequired = true;
|
||||
// }
|
||||
// // error type
|
||||
// else if (db.PriceMax_SkuPriceType >= 225 && db.PriceMax_SkuPriceType < 256)
|
||||
// {
|
||||
// cr.PriceMax_SkuPriceType = db.PriceMax_SkuPriceType;
|
||||
// }
|
||||
// // unhandled id type
|
||||
// else
|
||||
// {
|
||||
// cr.PriceMax_SkuPriceType = 255;
|
||||
// cr.ReviewRequired = true;
|
||||
// }
|
||||
// break;
|
||||
// }
|
||||
|
||||
// // Check manual enteried are present, if they are required
|
||||
// if ((db.RequireAmountManualMax && db.PriceMaxAmountManual == null) || (db.RequireStordedIntMax && db.PriceMaxStoredInt == null))
|
||||
// {
|
||||
// cr.PriceMax_SkuPriceType = 253;
|
||||
// cr.ReviewRequired = true;
|
||||
// }
|
||||
|
||||
// // STAGE 6
|
||||
// // Set MAX Price
|
||||
|
||||
// // CASE: Reset MAX-Price base & multiplier values (new record or switching back to auto)
|
||||
// if (insertRequired || (cr.PriceMax_SkuPriceType == 1 && db.PriceMax_SkuPriceType != 1))
|
||||
// {
|
||||
// // get competative price and apply multiplier
|
||||
// bool usedForceNew = false;
|
||||
// var request = new bnhtrade.Core.Product.ProductQuery();
|
||||
// var compPrice = request.ProductCompetitivePriceGet(sqlConnectionString, sku.ProductId, sku.ConditionId);
|
||||
// if (compPrice.price == null || compPrice.priceDate == null)
|
||||
// {
|
||||
// if (sku.ConditionId != 10)
|
||||
// {
|
||||
// usedForceNew = true;
|
||||
// compPrice = request.ProductCompetitivePriceGet(sqlConnectionString, sku.ProductId, 10);
|
||||
// }
|
||||
// if (compPrice.price == null || compPrice.priceDate == null)
|
||||
// {
|
||||
// cr.PriceMax_SkuPriceType = 254;
|
||||
// cr.ReviewRequired = true;
|
||||
// }
|
||||
// }
|
||||
|
||||
// cr.PriceMaxAmountAutoBase = compPrice.price ?? 0;
|
||||
// if (usedForceNew)
|
||||
// {
|
||||
// cr.PriceMaxAmountAutoMultiplier = sku.CompetitivePriceMultiplierNew;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// cr.PriceMaxAmountAutoMultiplier = sku.CompetitivePriceMultiplierMatch;
|
||||
// }
|
||||
|
||||
// // transfer manual values, if required
|
||||
// if (insertRequired == false)
|
||||
// {
|
||||
// cr.PriceMaxAmountManual = db.PriceMaxAmountManual;
|
||||
// cr.PriceMaxStoredInt = db.PriceMaxStoredInt;
|
||||
// }
|
||||
|
||||
// // set final max value
|
||||
// cr.PriceMaxAmountFinal = cr.PriceMaxAmountAutoBase * cr.PriceMaxAmountAutoMultiplier;
|
||||
// }
|
||||
|
||||
// // already on auto, adjust existing value, if required
|
||||
// else if (db.PriceMax_SkuPriceType == 1)
|
||||
// {
|
||||
// // get last sale date
|
||||
// int shipmentsInSaleHoldPeriod = 0;
|
||||
// // works from last unit ship-date, not the preferred order-date
|
||||
// // TODO: this could be better when other parts of application get more info
|
||||
// DateTime shipDateFilter = crTimeStamp.AddDays(repriceHoldOnSalePeriod * -1);
|
||||
// shipDateFilter = new DateTime(shipDateFilter.Year, shipDateFilter.Month, shipDateFilter.Day);
|
||||
// using (var cmd04 = new SqlCommand(@"
|
||||
// SELECT COUNT(tblImportFbaSaleShipment.ImportFbaSaleShipmentID) AS RecordCount
|
||||
// FROM tblImportFbaSaleShipment
|
||||
// INNER JOIN tblSku ON tblImportFbaSaleShipment.sku = tblSku.skuSkuNumber
|
||||
// WHERE (tblSku.skuSkuID = @skuID)
|
||||
// AND (tblImportFbaSaleShipment.[shipment-date] >= @shipDateFilter)
|
||||
// ", conn))
|
||||
// {
|
||||
// cmd04.Parameters.AddWithValue("@skuID", sku.SkuId);
|
||||
// cmd04.Parameters.AddWithValue("@shipDateFilter", shipDateFilter);
|
||||
|
||||
// shipmentsInSaleHoldPeriod = (int)cmd04.ExecuteScalar();
|
||||
// }
|
||||
// // get max item sale price during period
|
||||
// decimal maxSalePrice = 0;
|
||||
// if (shipmentsInSaleHoldPeriod > 0)
|
||||
// {
|
||||
// using (var cmd05 = new SqlCommand(@"
|
||||
// SELECT Max(ISNULL([tblImportFbaSaleShipment].[item-price], 0) + ISNULL([tblImportFbaSaleShipment].[item-tax], 0)) AS Expr1
|
||||
// FROM tblImportFbaSaleShipment
|
||||
// INNER JOIN tblSku ON tblImportFbaSaleShipment.sku = tblSku.skuSkuNumber
|
||||
// WHERE (
|
||||
// ((tblSku.skuSkuID) = @skuID)
|
||||
// AND ((tblImportFbaSaleShipment.[shipment-date]) >= @shipDateFilter)
|
||||
// )
|
||||
// ", conn))
|
||||
// {
|
||||
// cmd05.Parameters.AddWithValue("@skuID", sku.SkuId);
|
||||
// cmd05.Parameters.AddWithValue("@shipDateFilter", shipDateFilter);
|
||||
|
||||
// maxSalePrice = (decimal)cmd05.ExecuteScalar();
|
||||
// }
|
||||
// }
|
||||
|
||||
// DateTime updateDate = new DateTime(db.PriceCreated.Year, db.PriceCreated.Month, db.PriceCreated.Day);
|
||||
// updateDate = updateDate.AddDays(repriceDecreasePeriod);
|
||||
|
||||
// // decrease maxx price
|
||||
// if (crTimeStamp >= updateDate && shipmentsInSaleHoldPeriod == 0)
|
||||
// {
|
||||
// cr.PriceMaxAmountAutoBase = db.PriceMaxAmountAutoBase;
|
||||
// cr.PriceMaxAmountAutoMultiplier = db.PriceMaxAmountAutoMultiplier - repriceDecreaseIncrement;
|
||||
// cr.PriceMaxAmountManual = db.PriceMaxAmountManual;
|
||||
// cr.PriceMaxStoredInt = db.PriceMaxStoredInt;
|
||||
// cr.PriceMaxAmountFinal = cr.PriceMaxAmountAutoBase * cr.PriceMaxAmountAutoMultiplier;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// // increase price
|
||||
// if (maxSalePrice >= (db.PriceMaxAmountAutoBase * (db.PriceMaxAmountAutoMultiplier - repriceIncreaseIncrement)))
|
||||
// {
|
||||
// cr.PriceMaxAmountAutoBase = db.PriceMaxAmountAutoBase;
|
||||
// cr.PriceMaxAmountAutoMultiplier = db.PriceMaxAmountAutoMultiplier + repriceIncreaseIncrement;
|
||||
// cr.PriceMaxAmountManual = db.PriceMaxAmountManual;
|
||||
// cr.PriceMaxStoredInt = db.PriceMaxStoredInt;
|
||||
// cr.PriceMaxAmountFinal = cr.PriceMaxAmountAutoBase * cr.PriceMaxAmountAutoMultiplier;
|
||||
// }
|
||||
// // remain same
|
||||
// else
|
||||
// {
|
||||
// cr.PriceMaxAmountAutoBase = db.PriceMaxAmountAutoBase;
|
||||
// cr.PriceMaxAmountAutoMultiplier = db.PriceMaxAmountAutoMultiplier;
|
||||
// cr.PriceMaxAmountManual = db.PriceMaxAmountManual;
|
||||
// cr.PriceMaxStoredInt = db.PriceMaxStoredInt;
|
||||
// cr.PriceMaxAmountFinal = cr.PriceMaxAmountAutoBase * cr.PriceMaxAmountAutoMultiplier;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// // STAGE 7
|
||||
// // Checks before update
|
||||
|
||||
// // max < min
|
||||
// if (cr.PriceMaxAmountFinal < cr.PriceMinAmountFinal)
|
||||
// {
|
||||
// // on auto, set max to min value and update base multipier to reflect new value
|
||||
// if (cr.PriceMax_SkuPriceType == 1)
|
||||
// {
|
||||
// cr.PriceMaxAmountFinal = cr.PriceMinAmountFinal;
|
||||
// cr.PriceMaxAmountAutoMultiplier = cr.PriceMinAmountFinal / cr.PriceMaxAmountAutoBase;
|
||||
// }
|
||||
// else if (cr.PriceMax_SkuPriceType > 0 && cr.PriceMax_SkuPriceType < 200)
|
||||
// {
|
||||
// cr.PriceMax_SkuPriceType = 252;
|
||||
// cr.ReviewRequired = true;
|
||||
// }
|
||||
// }
|
||||
|
||||
// // this should be last check
|
||||
// // check for zero values (where there should not be any) -- this could be a life saver i.e. selling item for £0.00
|
||||
// if (cr.PriceMinAmountFinal * cr.PriceMaxAmountFinal == 0)
|
||||
// {
|
||||
// cr.PriceMax_SkuPriceType = 251;
|
||||
// cr.ReviewRequired = true;
|
||||
// }
|
||||
|
||||
// // STAGE 8
|
||||
// // Update main/history tables, if required
|
||||
// // round decimals for db comarison
|
||||
// cr.UnitAvgCost = decimal.Round(cr.UnitAvgCost, 2);
|
||||
// cr.PriceMinAmountAuto = decimal.Round(cr.PriceMinAmountAuto, 2);
|
||||
// cr.PriceMinAmountFinalFee = decimal.Round(cr.PriceMinAmountFinalFee, 2);
|
||||
// cr.PriceMinAmountFinalTax = decimal.Round(cr.PriceMinAmountFinalTax, 2);
|
||||
// cr.PriceMinAmountFinal = decimal.Round(cr.PriceMinAmountFinal, 2);
|
||||
// cr.PriceMaxAmountAutoMultiplier = decimal.Round(cr.PriceMaxAmountAutoMultiplier, 8);
|
||||
// cr.PriceMaxAmountFinal = decimal.Round(cr.PriceMaxAmountFinal, 2);
|
||||
|
||||
// if (insertRequired == false &&
|
||||
// (
|
||||
// db.OrderChannelQuantity != cr.OrderChannelQuantity ||
|
||||
// db.UnitAvgCost != cr.UnitAvgCost ||
|
||||
// db.InventoryAgeMin != cr.InventoryAgeMin ||
|
||||
// db.InventoryAgeMax != cr.InventoryAgeMax ||
|
||||
// db.PriceMin_SkuPriceType != cr.PriceMin_SkuPriceType ||
|
||||
// db.PriceMinAmountAuto != cr.PriceMinAmountAuto ||
|
||||
// db.PriceMinAmountFinalFee != cr.PriceMinAmountFinalFee ||
|
||||
// db.PriceMinAmountFinalTax != cr.PriceMinAmountFinalTax ||
|
||||
// db.PriceMinAmountFinal != cr.PriceMinAmountFinal ||
|
||||
// db.PriceMax_SkuPriceType != cr.PriceMax_SkuPriceType ||
|
||||
// db.PriceMaxAmountAutoBase != cr.PriceMaxAmountAutoBase ||
|
||||
// db.PriceMaxAmountAutoMultiplier != cr.PriceMaxAmountAutoMultiplier ||
|
||||
// db.PriceMaxAmountFinal != cr.PriceMaxAmountFinal ||
|
||||
// db.ReviewRequired != cr.ReviewRequired
|
||||
// )
|
||||
// )
|
||||
// {
|
||||
// updateRequired = true;
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// // insert old data to history table
|
||||
// if (updateRequired)
|
||||
// {
|
||||
// using (var cmd06 = new SqlCommand(@"
|
||||
// INSERT INTO tblSkuPriceHistory (
|
||||
// SkuID
|
||||
// ,OrderChannelID
|
||||
// ,OrderChannelQuantity
|
||||
// ,UnitAvgCost
|
||||
// ,InventoryAgeMin
|
||||
// ,InventoryAgeMax
|
||||
// ,PriceMin_SkuPriceType
|
||||
// ,PriceMinAmountAuto
|
||||
// ,PriceMinAmountManual
|
||||
// ,PriceMinStoredInt
|
||||
// ,PriceMinAmountFinalFee
|
||||
// ,PriceMinAmountFinalTax
|
||||
// ,PriceMinAmountFinal
|
||||
// ,PriceMax_SkuPriceType
|
||||
// ,PriceMaxAmountAutoBase
|
||||
// ,PriceMaxAmountAutoMultiplier
|
||||
// ,PriceMaxAmountManual
|
||||
// ,PriceMaxStoredInt
|
||||
// ,PriceMaxAmountFinal
|
||||
// ,RecordModified
|
||||
// ,ReviewRequired
|
||||
// )
|
||||
// VALUES (
|
||||
// @skuID
|
||||
// ,@dbOrderChannelID
|
||||
// ,@dbOrderChannelQuantity
|
||||
// ,@dbUnitAvgCost
|
||||
// ,@dbInventoryAgeMin
|
||||
// ,@dbInventoryAgeMax
|
||||
// ,@dbPriceMin_SkuPriceType
|
||||
// ,@dbPriceMinAmountAuto
|
||||
// ,@dbPriceMinAmountManual
|
||||
// ,@dbPriceMinStoredInt
|
||||
// ,@dbPriceMinAmountFinalFee
|
||||
// ,@dbPriceMinAmountFinalTax
|
||||
// ,@dbPriceMinAmountFinal
|
||||
// ,@dbPriceMax_SkuPriceType
|
||||
// ,@dbPriceMaxAmountAutoBase
|
||||
// ,@dbPriceMaxAmountAutoMultiplier
|
||||
// ,@dbPriceMaxAmountManual
|
||||
// ,@dbPriceMaxStoredInt
|
||||
// ,@dbPriceMaxAmountFinal
|
||||
// ,@dbRecordModified
|
||||
// ,@dbReviewRequired
|
||||
// )
|
||||
// ", scopeConn))
|
||||
// {
|
||||
// cmd06.Parameters.AddWithValue("@skuID", sku.SkuId);
|
||||
// cmd06.Parameters.AddWithValue("@dbOrderChannelID", db.OrderChannelId);
|
||||
// cmd06.Parameters.AddWithValue("@dbOrderChannelQuantity", db.OrderChannelQuantity);
|
||||
// cmd06.Parameters.AddWithValue("@dbUnitAvgCost", db.UnitAvgCost);
|
||||
// cmd06.Parameters.AddWithValue("@dbInventoryAgeMin", db.InventoryAgeMin);
|
||||
// cmd06.Parameters.AddWithValue("@dbInventoryAgeMax", db.InventoryAgeMax);
|
||||
// cmd06.Parameters.AddWithValue("@dbPriceMin_SkuPriceType", db.PriceMin_SkuPriceType);
|
||||
// cmd06.Parameters.AddWithValue("@dbPriceMinAmountAuto", db.PriceMinAmountAuto);
|
||||
// cmd06.Parameters.AddWithValue("@dbPriceMinAmountManual", db.PriceMinAmountManual);
|
||||
// cmd06.Parameters.AddWithValue("@dbPriceMinStoredInt", db.PriceMinStoredInt);
|
||||
// cmd06.Parameters.AddWithValue("@dbPriceMinAmountFinalFee", db.PriceMinAmountFinalFee);
|
||||
// cmd06.Parameters.AddWithValue("@dbPriceMinAmountFinalTax", db.PriceMinAmountFinalTax);
|
||||
// cmd06.Parameters.AddWithValue("@dbPriceMinAmountFinal", db.PriceMinAmountFinal);
|
||||
// cmd06.Parameters.AddWithValue("@dbPriceMax_SkuPriceType", db.PriceMax_SkuPriceType);
|
||||
// cmd06.Parameters.AddWithValue("@dbPriceMaxAmountAutoBase", db.PriceMaxAmountAutoBase);
|
||||
// cmd06.Parameters.AddWithValue("@dbPriceMaxAmountAutoMultiplier", db.PriceMaxAmountAutoMultiplier);
|
||||
// cmd06.Parameters.AddWithValue("@dbPriceMaxAmountManual", db.PriceMaxAmountManual);
|
||||
// cmd06.Parameters.AddWithValue("@dbPriceMaxStoredInt", db.PriceMaxStoredInt);
|
||||
// cmd06.Parameters.AddWithValue("@dbPriceMaxAmountFinal", db.PriceMaxAmountFinal);
|
||||
// cmd06.Parameters.AddWithValue("@dbRecordModified", db.PriceCreated);
|
||||
// cmd06.Parameters.AddWithValue("@dbReviewRequired", db.ReviewRequired);
|
||||
|
||||
// int count = cmd06.ExecuteNonQuery();
|
||||
// }
|
||||
// }
|
||||
|
||||
// // delete existing data in current table
|
||||
// if (updateRequired)
|
||||
// {
|
||||
// using (var cmd07 = new SqlCommand(@"
|
||||
// DELETE FROM tblSkuPriceHistory
|
||||
// WHERE SkuID = @skuID AND OrderChannelID = @dbOrderChannelID
|
||||
// ", scopeConn))
|
||||
// {
|
||||
// cmd07.Parameters.AddWithValue("@skuID", sku.SkuId);
|
||||
// cmd07.Parameters.AddWithValue("@dbOrderChannelID", db.OrderChannelId);
|
||||
|
||||
// int count = cmd07.ExecuteNonQuery();
|
||||
// }
|
||||
// }
|
||||
|
||||
// // insert new data into current table
|
||||
// if (updateRequired || insertRequired)
|
||||
// {
|
||||
// using (var cmd06 = new SqlCommand(@"
|
||||
// INSERT INTO tblSkuPrice (
|
||||
// SkuID
|
||||
// ,OrderChannelID
|
||||
// ,OrderChannelQuantity
|
||||
// ,UnitAvgCost
|
||||
// ,InventoryAgeMin
|
||||
// ,InventoryAgeMax
|
||||
// ,PriceMin_SkuPriceType
|
||||
// ,PriceMinAmountAuto
|
||||
// ,PriceMinAmountManual
|
||||
// ,PriceMinStoredInt
|
||||
// ,PriceMinAmountFinalFee
|
||||
// ,PriceMinAmountFinalTax
|
||||
// ,PriceMinAmountFinal
|
||||
// ,PriceMax_SkuPriceType
|
||||
// ,PriceMaxAmountAutoBase
|
||||
// ,PriceMaxAmountAutoMultiplier
|
||||
// ,PriceMaxAmountManual
|
||||
// ,PriceMaxStoredInt
|
||||
// ,PriceMaxAmountFinal
|
||||
// ,RecordModified
|
||||
// ,ReviewRequired
|
||||
// )
|
||||
// VALUES (
|
||||
// @skuID
|
||||
// ,@crOrderChannelID
|
||||
// ,@crOrderChannelQuantity
|
||||
// ,@crUnitAvgCost
|
||||
// ,@crInventoryAgeMin
|
||||
// ,@crInventoryAgeMax
|
||||
// ,@crPriceMin_SkuPriceType
|
||||
// ,@crPriceMinAmountAuto
|
||||
// ,@crPriceMinAmountManual
|
||||
// ,@crPriceMinStoredInt
|
||||
// ,@crPriceMinAmountFinalFee
|
||||
// ,@crPriceMinAmountFinalTax
|
||||
// ,@crPriceMinAmountFinal
|
||||
// ,@crPriceMax_SkuPriceType
|
||||
// ,@crPriceMaxAmountAutoBase
|
||||
// ,@crPriceMaxAmountAutoMultiplier
|
||||
// ,@crPriceMaxAmountManual
|
||||
// ,@crPriceMaxStoredInt
|
||||
// ,@crPriceMaxAmountFinal
|
||||
// ,@crRecordModified
|
||||
// ,@crReviewRequired
|
||||
// )
|
||||
// ", scopeConn))
|
||||
// {
|
||||
// cmd06.Parameters.AddWithValue("@skuID", sku.SkuId);
|
||||
// cmd06.Parameters.AddWithValue("@crOrderChannelID", db.OrderChannelId);
|
||||
// cmd06.Parameters.AddWithValue("@crOrderChannelQuantity", cr.OrderChannelQuantity);
|
||||
// cmd06.Parameters.AddWithValue("@crUnitAvgCost", cr.UnitAvgCost);
|
||||
// cmd06.Parameters.AddWithValue("@crInventoryAgeMin", cr.InventoryAgeMin);
|
||||
// cmd06.Parameters.AddWithValue("@crInventoryAgeMax", cr.InventoryAgeMax);
|
||||
// cmd06.Parameters.AddWithValue("@crPriceMin_SkuPriceType", cr.PriceMin_SkuPriceType);
|
||||
// cmd06.Parameters.AddWithValue("@crPriceMinAmountAuto", cr.PriceMinAmountAuto);
|
||||
// cmd06.Parameters.AddWithValue("@crPriceMinAmountManual", cr.PriceMinAmountManual);
|
||||
// cmd06.Parameters.AddWithValue("@crPriceMinStoredInt", cr.PriceMinStoredInt);
|
||||
// cmd06.Parameters.AddWithValue("@crPriceMinAmountFinalFee", cr.PriceMinAmountFinalFee);
|
||||
// cmd06.Parameters.AddWithValue("@crPriceMinAmountFinalTax", cr.PriceMinAmountFinalTax);
|
||||
// cmd06.Parameters.AddWithValue("@crPriceMinAmountFinal", cr.PriceMinAmountFinal);
|
||||
// cmd06.Parameters.AddWithValue("@crPriceMax_SkuPriceType", cr.PriceMax_SkuPriceType);
|
||||
// cmd06.Parameters.AddWithValue("@crPriceMaxAmountAutoBase", cr.PriceMaxAmountAutoBase);
|
||||
// cmd06.Parameters.AddWithValue("@crPriceMaxAmountAutoMultiplier", cr.PriceMaxAmountAutoMultiplier);
|
||||
// cmd06.Parameters.AddWithValue("@crPriceMaxAmountManual", cr.PriceMaxAmountManual);
|
||||
// cmd06.Parameters.AddWithValue("@crPriceMaxStoredInt", cr.PriceMaxStoredInt);
|
||||
// cmd06.Parameters.AddWithValue("@crPriceMaxAmountFinal", cr.PriceMaxAmountFinal);
|
||||
// cmd06.Parameters.AddWithValue("@crRecordModified", cr.PriceCreated);
|
||||
// cmd06.Parameters.AddWithValue("@crReviewRequired", cr.ReviewRequired);
|
||||
|
||||
// int count = cmd06.ExecuteNonQuery();
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// } // drop out of query while loop here
|
||||
|
||||
// // set any records that are not IsProcessed=TRUE to no quantity (i.e. by type) and quantity
|
||||
// // or... do I copy record to history and delete <------- THIS
|
||||
|
||||
|
||||
// // also, should add check, cross reference inventory age table against stock ledger results to highlight sku where I reckon
|
||||
// // qty is zero and amazon is >0
|
||||
|
||||
|
||||
// scope.Complete();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
}
|
||||
}
|
||||
86
src/bnhtrade.Core/Logic/Stock/Reallocate.cs
Normal file
86
src/bnhtrade.Core/Logic/Stock/Reallocate.cs
Normal file
@@ -0,0 +1,86 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Transactions;
|
||||
|
||||
namespace bnhtrade.Core.Logic.Stock
|
||||
{
|
||||
public class Reallocate
|
||||
{
|
||||
private string sqlConnectionString;
|
||||
|
||||
public Reallocate(string sqlConnectionString)
|
||||
{
|
||||
this.sqlConnectionString = sqlConnectionString;
|
||||
}
|
||||
|
||||
public int StockReallocateByStockId(int journalTypeId, int stockId, int quantity, int debitStatusId, int creditStatusId,
|
||||
DateTime entryDate = default(DateTime))
|
||||
{
|
||||
if (entryDate == default(DateTime))
|
||||
{
|
||||
entryDate = DateTime.Now;
|
||||
}
|
||||
|
||||
// create the list
|
||||
var posts = new List<(int statusId, int quantity)>();
|
||||
posts.Add((debitStatusId, quantity));
|
||||
posts.Add((creditStatusId, (quantity * -1)));
|
||||
|
||||
// execute
|
||||
return Core.Stock.StockJournal.StockJournalInsert(sqlConnectionString, journalTypeId, stockId, posts, entryDate, false);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Feed an skuId and quantity into function and the stock will be reallocated
|
||||
/// </summary>
|
||||
public List<(int StockJournalId, int Quantity)> StockReallocateBySkuNumber(int journalTypeId, string skuNumber, int quantity, int debitStatusId, int creditStatusId,
|
||||
bool firstInFirstOut = true, DateTime entryDate = default(DateTime), bool reallocatePartialQuantity = false)
|
||||
{
|
||||
var returnList = new List<(int StockJournalId, int Quantity)>();
|
||||
|
||||
List<Tuple<int, DateTime, int>> list = Core.Stock.StockJournal.GetStockStatusBalanceBySkuNumber(sqlConnectionString, skuNumber, creditStatusId, entryDate, firstInFirstOut);
|
||||
|
||||
if (list == null || !list.Any())
|
||||
{
|
||||
return returnList;
|
||||
}
|
||||
|
||||
// quantity check
|
||||
int avaiableQuantity = 0;
|
||||
foreach (Tuple<int, DateTime, int> item in list)
|
||||
{
|
||||
avaiableQuantity = avaiableQuantity + item.Item3;
|
||||
}
|
||||
if (avaiableQuantity < quantity && reallocatePartialQuantity == false)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// make the changes
|
||||
using (TransactionScope scope = new TransactionScope())
|
||||
{
|
||||
foreach (Tuple<int, DateTime, int> item in list)
|
||||
{
|
||||
if (quantity > item.Item3)
|
||||
{
|
||||
int tempInt = StockReallocateByStockId(journalTypeId, item.Item1, item.Item3, debitStatusId, creditStatusId, entryDate);
|
||||
quantity = quantity - item.Item3;
|
||||
returnList.Add((tempInt, item.Item3));
|
||||
}
|
||||
else
|
||||
{
|
||||
int tempInt = StockReallocateByStockId(journalTypeId, item.Item1, quantity, debitStatusId, creditStatusId, entryDate);
|
||||
returnList.Add((tempInt, quantity));
|
||||
break;
|
||||
}
|
||||
}
|
||||
scope.Complete();
|
||||
return returnList;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
167
src/bnhtrade.Core/Logic/Stock/SkuTransactionPersistance.cs
Normal file
167
src/bnhtrade.Core/Logic/Stock/SkuTransactionPersistance.cs
Normal file
@@ -0,0 +1,167 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Transactions;
|
||||
|
||||
namespace bnhtrade.Core.Logic.Stock
|
||||
{
|
||||
public class SkuTransactionPersistance
|
||||
{
|
||||
private string err = "Sku Transaction Persistance Error; ";
|
||||
private string sqlConnectionString;
|
||||
private Data.Database.Stock.DeleteSkuTransaction dbSkuTransDelete;
|
||||
private Data.Database.Stock.CreateSkuTransaction dbSkuTransCreate;
|
||||
private Data.Database.Stock.ReadSkuTransaction dbSkuTransRead;
|
||||
private Data.Database.Stock.UpdateSkuTransaction dbSkuTransUpdate;
|
||||
private Logic.Validate.SkuTransaction validateSkuTrans;
|
||||
private Logic.Log.LogEvent log;
|
||||
|
||||
public SkuTransactionPersistance(string sqlConnectionString)
|
||||
{
|
||||
this.sqlConnectionString = sqlConnectionString;
|
||||
log = new Log.LogEvent();
|
||||
}
|
||||
|
||||
private Data.Database.Stock.DeleteSkuTransaction DatabaseSkuTransDelete(bool forceNew = false)
|
||||
{
|
||||
if (dbSkuTransDelete == null || forceNew)
|
||||
{
|
||||
dbSkuTransDelete = new Data.Database.Stock.DeleteSkuTransaction(sqlConnectionString);
|
||||
}
|
||||
return dbSkuTransDelete;
|
||||
}
|
||||
|
||||
private Data.Database.Stock.CreateSkuTransaction DatabaseSkuTransInsert(bool forceNew = false)
|
||||
{
|
||||
if (dbSkuTransCreate == null || forceNew)
|
||||
{
|
||||
dbSkuTransCreate = new Data.Database.Stock.CreateSkuTransaction(sqlConnectionString);
|
||||
}
|
||||
return dbSkuTransCreate;
|
||||
}
|
||||
|
||||
private Data.Database.Stock.ReadSkuTransaction DatabaseSkuTransRead(bool forceNew = false)
|
||||
{
|
||||
if (dbSkuTransRead == null || forceNew)
|
||||
{
|
||||
dbSkuTransRead = new Data.Database.Stock.ReadSkuTransaction(sqlConnectionString);
|
||||
}
|
||||
return dbSkuTransRead;
|
||||
}
|
||||
|
||||
private Data.Database.Stock.UpdateSkuTransaction DatabaseSkuTransUpdate(bool forceNew = false)
|
||||
{
|
||||
if (dbSkuTransUpdate == null || forceNew)
|
||||
{
|
||||
dbSkuTransUpdate = new Data.Database.Stock.UpdateSkuTransaction(sqlConnectionString);
|
||||
}
|
||||
return dbSkuTransUpdate;
|
||||
}
|
||||
|
||||
private Logic.Validate.SkuTransaction Validate()
|
||||
{
|
||||
if (validateSkuTrans == null)
|
||||
{
|
||||
validateSkuTrans = new Validate.SkuTransaction();
|
||||
}
|
||||
return validateSkuTrans;
|
||||
}
|
||||
|
||||
public void Delete(int skuTransactionId)
|
||||
{
|
||||
using (var scope = new TransactionScope())
|
||||
{
|
||||
try
|
||||
{
|
||||
// is there a journal entry attached?
|
||||
int? journalId = DatabaseSkuTransRead().GetJournalId(skuTransactionId);
|
||||
if (journalId != null)
|
||||
{
|
||||
Core.Stock.StockJournal.StockJournalDelete(sqlConnectionString, (int)journalId);
|
||||
}
|
||||
|
||||
DatabaseSkuTransDelete().ByTransactionId(skuTransactionId);
|
||||
scope.Complete();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
scope.Dispose();
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void DeleteJournalEntry(int skuTransactionId)
|
||||
{
|
||||
using (var scope = new TransactionScope())
|
||||
{
|
||||
try
|
||||
{
|
||||
// is there a journal entry attached?
|
||||
int? journalId = DatabaseSkuTransRead().GetJournalId(skuTransactionId);
|
||||
if (journalId != null)
|
||||
{
|
||||
DatabaseSkuTransUpdate().Update(skuTransactionId, null);
|
||||
Core.Stock.StockJournal.StockJournalDelete(sqlConnectionString, (int)journalId);
|
||||
}
|
||||
scope.Complete();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
scope.Dispose();
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Create(Model.Stock.SkuTransaction skuTransaction)
|
||||
{
|
||||
if (skuTransaction == null)
|
||||
{
|
||||
throw new Exception(err + "Object was null");
|
||||
}
|
||||
|
||||
Validate().Innit();
|
||||
if (!Validate().DatabaseInsert(skuTransaction))
|
||||
{
|
||||
log.LogWarning(err + "Validation failed", Validate().ValidationResultListToString());
|
||||
throw new Exception(err + "Validation failed");
|
||||
}
|
||||
|
||||
// write to database
|
||||
DatabaseSkuTransInsert().Create(skuTransaction);
|
||||
}
|
||||
|
||||
public void Update(Model.Stock.SkuTransaction skuTransaction)
|
||||
{
|
||||
if (skuTransaction == null)
|
||||
{
|
||||
throw new Exception(err + "Object was null");
|
||||
}
|
||||
|
||||
Validate().Innit();
|
||||
if (!Validate().DatabaseUpdate(skuTransaction))
|
||||
{
|
||||
log.LogWarning(err + "Validation failed", Validate().ValidationResultListToString());
|
||||
throw new Exception(err + "Validation failed");
|
||||
}
|
||||
|
||||
using (var scope = new TransactionScope())
|
||||
{
|
||||
// is there an existing journal id that is changing
|
||||
int? journalId = DatabaseSkuTransRead().GetJournalId(skuTransaction.SkuTransactionId);
|
||||
if (journalId != null && skuTransaction.IsSetStockJournalId)
|
||||
{
|
||||
if (journalId != skuTransaction.StockJournalId)
|
||||
{
|
||||
DeleteJournalEntry(skuTransaction.SkuTransactionId);
|
||||
}
|
||||
}
|
||||
dbSkuTransUpdate.Update(skuTransaction);
|
||||
scope.Complete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
398
src/bnhtrade.Core/Logic/Stock/SkuTransactionReconcile.cs
Normal file
398
src/bnhtrade.Core/Logic/Stock/SkuTransactionReconcile.cs
Normal file
@@ -0,0 +1,398 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Transactions;
|
||||
|
||||
namespace bnhtrade.Core.Logic.Stock
|
||||
{
|
||||
public class SkuTransactionReconcile
|
||||
{
|
||||
private string sqlConnectionString;
|
||||
private Data.Database.AmazonShipment.ReadShipmentInfo readShipmentInfo;
|
||||
private Logic.Stock.SkuTransactionPersistance dbSkuTransaction;
|
||||
private Logic.Stock.SkuTransactionTypePersistance dbSkuTransactionType;
|
||||
private Logic.Validate.SkuTransaction validateSkuTrans;
|
||||
private Logic.Stock.Reallocate stockReallocate;
|
||||
private Logic.Log.LogEvent logEvent;
|
||||
private string err = "Reconcile Sku Transaction Exception: ";
|
||||
|
||||
public SkuTransactionReconcile(string sqlConnectionString)
|
||||
{
|
||||
Innit();
|
||||
this.sqlConnectionString = sqlConnectionString;
|
||||
dbSkuTransaction = new SkuTransactionPersistance(sqlConnectionString);
|
||||
dbSkuTransactionType = new SkuTransactionTypePersistance(sqlConnectionString);
|
||||
readShipmentInfo = new Data.Database.AmazonShipment.ReadShipmentInfo(sqlConnectionString);
|
||||
validateSkuTrans = new Validate.SkuTransaction();
|
||||
stockReallocate = new Logic.Stock.Reallocate(sqlConnectionString);
|
||||
logEvent = new Log.LogEvent();
|
||||
}
|
||||
|
||||
public int ItemsCompleted { get; private set; }
|
||||
|
||||
public int ItemsRemaining { get; private set; }
|
||||
|
||||
public DateTime LastItemDateTime { get; private set; }
|
||||
|
||||
public string ProgressMessage { get; private set; }
|
||||
|
||||
public bool ReconciliationComplete { get; private set; }
|
||||
|
||||
public int CurrentTransactionId { get; private set; }
|
||||
|
||||
public int CurrentTransactionTypeId { get; private set; }
|
||||
|
||||
public Model.Stock.SkuTransaction CurrentSkuTransaction { get; private set; }
|
||||
|
||||
private void Innit()
|
||||
{
|
||||
ItemsCompleted = 0;
|
||||
ItemsRemaining = 0;
|
||||
LastItemDateTime = default(DateTime);
|
||||
ProgressMessage = null;
|
||||
ReconciliationComplete = false;
|
||||
CurrentTransactionId = 0;
|
||||
CurrentTransactionTypeId = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Iterates through the stock transaction table and inserts stock journal entries, where applicable
|
||||
/// N.B. This function does not make allowances for status' that can create stock (i.e. if a status does not have stock available, this function will halt processing rows)
|
||||
/// </summary>
|
||||
/// <param name="updateTransactions">Download and process Amazon reports before starting process</param>
|
||||
/// <returns></returns>
|
||||
public void ReconcileStockTransactions(bool updateTransactions)
|
||||
{
|
||||
Innit();
|
||||
string currentMethodName = nameof(ReconcileStockTransactions);
|
||||
|
||||
// ensure import table have been processed into transaction table without exception
|
||||
if (updateTransactions == true)
|
||||
{
|
||||
try
|
||||
{
|
||||
var preCheck = new bnhtrade.Core.Stock.StockReconciliation();
|
||||
preCheck.ProcessFbaStockImportData(sqlConnectionString);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ProgressMessage = "Precheck failed: " + ex.Message;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
logEvent.LogInformation("Starting ReconcileStockTransactions()");
|
||||
int recordSkip = 0;
|
||||
|
||||
ProcessLostAndFound();
|
||||
|
||||
// get list of sku transactions to reconcile
|
||||
var transList = new Data.Database.Stock.ReadSkuTransaction(sqlConnectionString).GetUnreconciled();
|
||||
ItemsRemaining = transList.Count;
|
||||
ItemsCompleted = 0;
|
||||
|
||||
try
|
||||
{
|
||||
// loop through transaction list
|
||||
for (int i = 0; i < transList.Count; i++)
|
||||
{
|
||||
using (var scope = new TransactionScope())
|
||||
{
|
||||
|
||||
Console.Write("\rProcessing record: {0} ({1} skipped)", (i + 1 + recordSkip), recordSkip);
|
||||
|
||||
// setup return values
|
||||
CurrentSkuTransaction = transList[i];
|
||||
CurrentTransactionId = transList[i].SkuTransactionId;
|
||||
CurrentTransactionTypeId = transList[i].SkuTransactionTypeId;
|
||||
LastItemDateTime = transList[i].TransactionDate;
|
||||
|
||||
// load type into variable
|
||||
var transType = dbSkuTransactionType.GetByTypeName(transList[i].SkuTransactionTypeName);
|
||||
|
||||
// stop if a new transactiontype is encountered
|
||||
if (transType.IsNewReviewRequired)
|
||||
{
|
||||
ProgressMessage = "New 'Transaction-Type' encountered";
|
||||
//Console.Write("\r");
|
||||
//MiscFunction.EventLogInsert(errMessage, 1);
|
||||
goto Stop;
|
||||
}
|
||||
|
||||
// set debit/credit status' for special cases (i.e. NULL or 0 debit/credit ids in stockTransactionType table)
|
||||
if (transType.StockJournalEntryEnabled == true && (transType.DebitStockStatusId == 0 || transType.CreditStockStatusId == 0))
|
||||
{
|
||||
// FBA Shipment Receipt +ve
|
||||
if (transType.TypeCode == "<AmazonReport><_GET_FBA_FULFILLMENT_INVENTORY_RECEIPTS_DATA_><+ve>"
|
||||
|| transType.TypeCode == "<AmazonReport><_GET_FBA_FULFILLMENT_INVENTORY_RECEIPTS_DATA_><-ve>")
|
||||
{
|
||||
var shipmentInfo = readShipmentInfo.HeaderByFbaShipmentId(transList[i].Reference);
|
||||
|
||||
if (shipmentInfo.IsSetShipmentStockStatusId())
|
||||
{
|
||||
// +ve shipment receipt
|
||||
if (transType.CreditStockStatusId == 0 && transType.DebitStockStatusId > 0)
|
||||
{ transType.CreditStockStatusId = shipmentInfo.ShipmentStockStatusId; }
|
||||
|
||||
// -ve shipment receipt
|
||||
else if (transType.DebitStockStatusId == 0 && transType.CreditStockStatusId > 0)
|
||||
{ transType.DebitStockStatusId = shipmentInfo.ShipmentStockStatusId; }
|
||||
|
||||
// something went wrong, raise error
|
||||
else
|
||||
{
|
||||
ProgressMessage = "Unable to retrive FBA shipment location/status from tblAmazonShipment for Amazon shipment '" + shipmentInfo.FbaShipmentId + "'.";
|
||||
recordSkip = recordSkip + 1;
|
||||
goto Stop;
|
||||
}
|
||||
}
|
||||
}
|
||||
// something went wrong, raise error
|
||||
else
|
||||
{
|
||||
ProgressMessage = "Coding required. Unhandled special case Transaction-Type encountered (Transaction-Type debit or credit is set to 0).";
|
||||
recordSkip = recordSkip + 1;
|
||||
goto Stop;
|
||||
}
|
||||
}
|
||||
|
||||
// make the changes
|
||||
if (transType.StockJournalEntryEnabled == false)
|
||||
{
|
||||
transList[i].IsProcessed = true;
|
||||
dbSkuTransaction.Update(transList[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
var list = new List<(int StockJournalId, int Quantity)>();
|
||||
if (transType.FilterStockOnDateTime)
|
||||
{
|
||||
list = stockReallocate.StockReallocateBySkuNumber(
|
||||
transType.StockJournalTypeId,
|
||||
transList[i].SkuNumber,
|
||||
transList[i].Quantity,
|
||||
transType.DebitStockStatusId,
|
||||
transType.CreditStockStatusId,
|
||||
transType.FirstInFirstOut,
|
||||
transList[i].TransactionDate,
|
||||
false);
|
||||
}
|
||||
else
|
||||
{
|
||||
list = stockReallocate.StockReallocateBySkuNumber(
|
||||
transType.StockJournalTypeId,
|
||||
transList[i].SkuNumber,
|
||||
transList[i].Quantity,
|
||||
transType.DebitStockStatusId,
|
||||
transType.CreditStockStatusId,
|
||||
transType.FirstInFirstOut,
|
||||
DateTime.UtcNow,
|
||||
false);
|
||||
}
|
||||
|
||||
// insufficient balance available
|
||||
if (list == null || !list.Any())
|
||||
{
|
||||
// in special case (found inventory), continue
|
||||
if (transType.TypeCode.Contains("<AmazonReport><_GET_FBA_FULFILLMENT_INVENTORY_ADJUSTMENTS_DATA_><F>"))
|
||||
{
|
||||
continue;// <--------------------------------------------------------------------------------------------------- is this the soruce of the bug?
|
||||
}
|
||||
else
|
||||
{
|
||||
ProgressMessage = "Insurficent status/location balance to relocate stock";
|
||||
recordSkip = recordSkip + 1;
|
||||
goto Stop;
|
||||
}
|
||||
}
|
||||
|
||||
// fail safe
|
||||
int qtyAllocated = list.Sum(c => c.Quantity);
|
||||
if (qtyAllocated > transList[i].Quantity)
|
||||
{
|
||||
throw new Exception(
|
||||
currentMethodName + ": StockReallocateBySkuId() returned greater quantity than passed to function"
|
||||
+ transList[i].SkuTransactionId);
|
||||
}
|
||||
|
||||
// update sku transaction table
|
||||
int qtyRemain = qtyAllocated;
|
||||
var newRecordList = new List<Model.Stock.SkuTransaction>();
|
||||
for (int j = 0; j <= list.Count; j++)
|
||||
{
|
||||
// update existing record
|
||||
if (j == 0)
|
||||
{
|
||||
transList[i].Quantity = (short)list[j].Quantity;
|
||||
transList[i].StockJournalId = list[j].StockJournalId;
|
||||
transList[i].IsProcessed = true;
|
||||
|
||||
dbSkuTransaction.Update(transList[i]);
|
||||
}
|
||||
// new record
|
||||
else if (j < list.Count)
|
||||
{
|
||||
var newRecord = transList[i].Clone();
|
||||
newRecord.Quantity = (short)list[j].Quantity;
|
||||
newRecord.IsProcessed = true;
|
||||
newRecord.StockJournalId = list[j].StockJournalId;
|
||||
newRecordList.Add(newRecord);
|
||||
}
|
||||
// new record, unallocated quantity
|
||||
else if (qtyRemain > 0)
|
||||
{
|
||||
var newRecord = transList[i].Clone();
|
||||
newRecord.Quantity = (short)qtyRemain;
|
||||
newRecord.IsProcessed = false;
|
||||
newRecordList.Add(newRecord);
|
||||
}
|
||||
|
||||
if (j < list.Count)
|
||||
{
|
||||
qtyRemain = qtyRemain - list[j].Quantity;
|
||||
}
|
||||
}
|
||||
// add new transactions to table
|
||||
for (int j = 0; j < newRecordList.Count; j++)
|
||||
{
|
||||
dbSkuTransaction.Create(newRecordList[j]);
|
||||
}
|
||||
}
|
||||
ItemsCompleted++;
|
||||
ItemsRemaining++;
|
||||
scope.Complete();
|
||||
}
|
||||
// end of scope
|
||||
}
|
||||
// end of loop
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.Write("\r");
|
||||
ProgressMessage = ex.Message;
|
||||
return;
|
||||
}
|
||||
|
||||
Stop:
|
||||
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;
|
||||
ProgressMessage = "Operation complete.";
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public void ProcessLostAndFound()
|
||||
{
|
||||
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
|
||||
// lost, therefore should not be entered into journal as lost)
|
||||
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>";
|
||||
|
||||
for (int i = 0; i < transList.Count; i++)
|
||||
{
|
||||
var transType = dbSkuTransactionType.GetByTypeName(transList[i].SkuTransactionTypeName);
|
||||
|
||||
if (transType.TypeCode == found && !transList[i].IsProcessed)
|
||||
{
|
||||
string sku = transList[i].SkuNumber;
|
||||
int foundQty = transList[i].Quantity;
|
||||
int foundQtyUnAllocated = foundQty;
|
||||
|
||||
//loop though list and find matching missing
|
||||
for (int j = 0; j < transList.Count; j++)
|
||||
{
|
||||
// we have a match
|
||||
if (transList[j].SkuNumber == sku && !transList[j].IsProcessed && transType.TypeCode == lost)
|
||||
{
|
||||
// split transaction and break
|
||||
if (foundQtyUnAllocated - transList[j].Quantity < 0)
|
||||
{
|
||||
// create and validate clone
|
||||
var clone = transList[j].Clone();
|
||||
clone.Quantity = (short)foundQtyUnAllocated;
|
||||
clone.IsProcessed = true;
|
||||
|
||||
// modifiy and validate existing record
|
||||
transList[j].IsProcessed = false;
|
||||
transList[j].Quantity = (short)(transList[j].Quantity - foundQtyUnAllocated);
|
||||
foundQtyUnAllocated = 0;
|
||||
|
||||
// submitt to database
|
||||
dbSkuTransaction.Create(clone);
|
||||
dbSkuTransaction.Update(transList[j]);
|
||||
}
|
||||
// set as isprocessed and continue
|
||||
else
|
||||
{
|
||||
foundQtyUnAllocated = foundQtyUnAllocated - transList[j].Quantity;
|
||||
transList[j].IsProcessed = true;
|
||||
|
||||
dbSkuTransaction.Update(transList[j]);
|
||||
}
|
||||
|
||||
// break?
|
||||
if (foundQtyUnAllocated == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update the found record
|
||||
if (foundQty != foundQtyUnAllocated)
|
||||
{
|
||||
// set isprocess = true
|
||||
if (foundQtyUnAllocated == 0)
|
||||
{
|
||||
transList[i].IsProcessed = true;
|
||||
dbSkuTransaction.Update(transList[i]);
|
||||
}
|
||||
// split record
|
||||
else if (foundQtyUnAllocated > 0)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
|
||||
// create clone
|
||||
var clone = transList[i].Clone();
|
||||
clone.Quantity -= (short)foundQtyUnAllocated;
|
||||
clone.IsProcessed = true;
|
||||
|
||||
// modifiy and validate existing record
|
||||
transList[i].IsProcessed = false;
|
||||
transList[i].Quantity -= (short)foundQtyUnAllocated;
|
||||
foundQtyUnAllocated = 0;
|
||||
|
||||
// submitt to database
|
||||
dbSkuTransaction.Create(clone);
|
||||
dbSkuTransaction.Update(transList[i]);
|
||||
}
|
||||
// this shouldn't happen
|
||||
else
|
||||
{
|
||||
throw new Exception("Quantity unallocated is negative number");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
scope.Complete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Logic.Stock
|
||||
{
|
||||
public class SkuTransactionTypePersistance
|
||||
{
|
||||
private string sqlConnectionString;
|
||||
private List<Model.Stock.SkuTransactionType> cache;
|
||||
private Data.Database.Stock.ReadSkuTransactionType dbRead;
|
||||
|
||||
public SkuTransactionTypePersistance(string sqlConnectionString)
|
||||
{
|
||||
this.sqlConnectionString = sqlConnectionString;
|
||||
dbRead = new Data.Database.Stock.ReadSkuTransactionType(sqlConnectionString);
|
||||
InnitCache();
|
||||
}
|
||||
|
||||
public void InnitCache()
|
||||
{
|
||||
cache = new List<Model.Stock.SkuTransactionType>();
|
||||
}
|
||||
|
||||
public Model.Stock.SkuTransactionType GetByTypeCode(string typeCode, bool clearCache = false)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(typeCode))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (clearCache)
|
||||
{
|
||||
InnitCache();
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < cache.Count; i++)
|
||||
{
|
||||
if (cache[i].TypeCode == typeCode)
|
||||
{
|
||||
return cache[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var result = dbRead.ByTypeCode(new List<string> { typeCode });
|
||||
|
||||
if (result.Any())
|
||||
{
|
||||
cache.Add(result[0]);
|
||||
return result[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Model.Stock.SkuTransactionType GetByTypeName(string typeName, bool clearCache = false)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(typeName))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (clearCache)
|
||||
{
|
||||
InnitCache();
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < cache.Count; i++)
|
||||
{
|
||||
if (cache[i].TypeName == typeName)
|
||||
{
|
||||
return cache[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var result = dbRead.ByTypeName(new List<string> { typeName });
|
||||
|
||||
if (result.Any())
|
||||
{
|
||||
cache.Add(result[0]);
|
||||
return result[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
31
src/bnhtrade.Core/Logic/Utilities/CalculateMD5.cs
Normal file
31
src/bnhtrade.Core/Logic/Utilities/CalculateMD5.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Logic.Utilities
|
||||
{
|
||||
public class CalculateMD5
|
||||
{
|
||||
public string Base64(Stream stream)
|
||||
{
|
||||
stream.Position = 0;
|
||||
|
||||
MD5CryptoServiceProvider provider = new MD5CryptoServiceProvider();
|
||||
byte[] hash = provider.ComputeHash(stream);
|
||||
string returnvalue = Convert.ToBase64String(hash);
|
||||
return returnvalue;
|
||||
}
|
||||
|
||||
public string Base64(byte[] byteArray)
|
||||
{
|
||||
MD5CryptoServiceProvider provider = new MD5CryptoServiceProvider();
|
||||
byte[] hash = provider.ComputeHash(byteArray);
|
||||
string returnvalue = Convert.ToBase64String(hash);
|
||||
return returnvalue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,18 +6,18 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Logic.Utilities
|
||||
{
|
||||
public class DateTimeCheck : Validate
|
||||
public class DateTimeCheck : Validate.Validate
|
||||
{
|
||||
public bool IsUtc(DateTime dateTimeToCheck)
|
||||
{
|
||||
if (dateTimeToCheck == default(DateTime))
|
||||
{
|
||||
ErrorListAdd( "DateTime value set to default.");
|
||||
ValidationResultAdd( "DateTime value set to default.");
|
||||
return false;
|
||||
}
|
||||
if (dateTimeToCheck.Kind != DateTimeKind.Utc)
|
||||
{
|
||||
ErrorListAdd("DateTime not set to UTC kind.");
|
||||
ValidationResultAdd("DateTime not set to UTC kind.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -26,12 +26,12 @@ namespace bnhtrade.Core.Logic.Utilities
|
||||
{
|
||||
if (dateTimeToCheck == default(DateTime))
|
||||
{
|
||||
ErrorListAdd("DateTime value set to default.");
|
||||
ValidationResultAdd("DateTime value set to default.");
|
||||
return false;
|
||||
}
|
||||
if (dateTimeToCheck.Kind != DateTimeKind.Local)
|
||||
{
|
||||
ErrorListAdd("DateTime not set to Local kind.");
|
||||
ValidationResultAdd("DateTime not set to Local kind.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
23
src/bnhtrade.Core/Logic/Utilities/DateTimeParse.cs
Normal file
23
src/bnhtrade.Core/Logic/Utilities/DateTimeParse.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Logic.Utilities
|
||||
{
|
||||
public class DateTimeParse
|
||||
{
|
||||
public DateTime ParseMwsReportDateTime(string reportDateTime)
|
||||
{
|
||||
string isoDateTime =
|
||||
reportDateTime.Substring(6, 4) + "-" +
|
||||
reportDateTime.Substring(3, 2) + "-" +
|
||||
reportDateTime.Substring(0, 2) + "T" +
|
||||
reportDateTime.Substring(11, 2) + ":" +
|
||||
reportDateTime.Substring(14, 2) + ":" +
|
||||
reportDateTime.Substring(17, 2) + "Z";
|
||||
return DateTime.Parse(isoDateTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Logic.Utilities
|
||||
{
|
||||
public class DecimalCheck : Validate
|
||||
public class DecimalCheck : Validate.Validate
|
||||
{
|
||||
/// <summary>
|
||||
/// Finds total number of digits in a decimal number, does not include decimal point.
|
||||
@@ -36,13 +36,13 @@ namespace bnhtrade.Core.Logic.Utilities
|
||||
int precision = GetPrecision(decimalToCheck);
|
||||
if (precision > 2)
|
||||
{
|
||||
ErrorListAdd("Decimal precision overload");
|
||||
ValidationResultAdd("Decimal precision overload");
|
||||
return false;
|
||||
}
|
||||
int length = GetLength(decimalToCheck);
|
||||
if (length > 9)
|
||||
{
|
||||
ErrorListAdd("Decimal length overload");
|
||||
ValidationResultAdd("Decimal length overload");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -6,7 +6,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Logic.Utilities
|
||||
{
|
||||
public class StringCheck : Validate
|
||||
public class StringCheck : Validate.Validate
|
||||
{
|
||||
public bool AllowEmpty { get; set; } = false;
|
||||
public bool AllowWhiteSpace { get; set; } = false;
|
||||
@@ -22,7 +22,7 @@ namespace bnhtrade.Core.Logic.Utilities
|
||||
{
|
||||
if (!allowNull)
|
||||
{
|
||||
ErrorListAdd("String is null");
|
||||
ValidationResultAdd("String is null");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -35,12 +35,12 @@ namespace bnhtrade.Core.Logic.Utilities
|
||||
{
|
||||
if ((c >= 'a' && c <= 'z') && upperCaseOnly)
|
||||
{
|
||||
ErrorListAdd("String contains lower case numerical charater(s).");
|
||||
ValidationResultAdd("String contains lower case numerical charater(s).");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrorListAdd("String contains non-alpha charater(s).");
|
||||
ValidationResultAdd("String contains non-alpha charater(s).");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -54,7 +54,7 @@ namespace bnhtrade.Core.Logic.Utilities
|
||||
{
|
||||
if (!allowNull)
|
||||
{
|
||||
ErrorListAdd("String is null");
|
||||
ValidationResultAdd("String is null");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -68,12 +68,12 @@ namespace bnhtrade.Core.Logic.Utilities
|
||||
{
|
||||
if ((c >= 'a' && c <= 'z') && upperCaseOnly)
|
||||
{
|
||||
ErrorListAdd("String contains lower case numerical charater(s).");
|
||||
ValidationResultAdd("String contains lower case numerical charater(s).");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrorListAdd("String contains non-alphanumeric charater(s).");
|
||||
ValidationResultAdd("String contains non-alphanumeric charater(s).");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -87,7 +87,7 @@ namespace bnhtrade.Core.Logic.Utilities
|
||||
{
|
||||
if (allowNull == false)
|
||||
{
|
||||
ErrorListAdd("String is null");
|
||||
ValidationResultAdd("String is null");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -97,7 +97,7 @@ namespace bnhtrade.Core.Logic.Utilities
|
||||
{
|
||||
if (c < '0' || c > '9')
|
||||
{
|
||||
ErrorListAdd("String contains non-numeric charater(s).");
|
||||
ValidationResultAdd("String contains non-numeric charater(s).");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -114,7 +114,7 @@ namespace bnhtrade.Core.Logic.Utilities
|
||||
int length = stringToCheck.Length;
|
||||
if (length != stringLength)
|
||||
{
|
||||
ErrorListAdd("String length (" + length + ") does not equal " + stringLength + " charaters.");
|
||||
ValidationResultAdd("String length (" + length + ") does not equal " + stringLength + " charaters.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -131,7 +131,7 @@ namespace bnhtrade.Core.Logic.Utilities
|
||||
int length = stringToCheck.Length;
|
||||
if (length > maxLength)
|
||||
{
|
||||
ErrorListAdd("String length (" + length + ") is greater than " + maxLength + " charaters.");
|
||||
ValidationResultAdd("String length (" + length + ") is greater than " + maxLength + " charaters.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -147,7 +147,7 @@ namespace bnhtrade.Core.Logic.Utilities
|
||||
int length = stringToCheck.Length;
|
||||
if (length <= minLength)
|
||||
{
|
||||
ErrorListAdd("String length (" + length + ") is less than " + minLength + " charaters.");
|
||||
ValidationResultAdd("String length (" + length + ") is less than " + minLength + " charaters.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -161,7 +161,7 @@ namespace bnhtrade.Core.Logic.Utilities
|
||||
{
|
||||
if (!allowNull)
|
||||
{
|
||||
ErrorListAdd("String is null, empty or white space.");
|
||||
ValidationResultAdd("String is null, empty or white space.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -169,7 +169,7 @@ namespace bnhtrade.Core.Logic.Utilities
|
||||
{
|
||||
if (!AllowEmpty)
|
||||
{
|
||||
ErrorListAdd("String is empty.");
|
||||
ValidationResultAdd("String is empty.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -177,7 +177,7 @@ namespace bnhtrade.Core.Logic.Utilities
|
||||
{
|
||||
if (!AllowWhiteSpace)
|
||||
{
|
||||
ErrorListAdd("String is white space.");
|
||||
ValidationResultAdd("String is white space.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Logic
|
||||
{
|
||||
public abstract class Validate
|
||||
{
|
||||
private List<string> errorList = new List<string>();
|
||||
|
||||
public List<string> ErrorList
|
||||
{
|
||||
get { return errorList; }
|
||||
}
|
||||
|
||||
public bool ErrorListIsSet
|
||||
{
|
||||
get
|
||||
{
|
||||
if (errorList == null || !errorList.Any()) { return false; }
|
||||
else { return true; }
|
||||
}
|
||||
}
|
||||
|
||||
protected void ErrorListAdd(string errorString)
|
||||
{
|
||||
this.errorList.Add(errorString);
|
||||
}
|
||||
|
||||
protected void ErrorListAdd(List<string> errorList)
|
||||
{
|
||||
this.errorList.AddRange(errorList);
|
||||
}
|
||||
|
||||
public string ErrorListToString()
|
||||
{
|
||||
if (ErrorListIsSet)
|
||||
{
|
||||
StringBuilder result = new StringBuilder();
|
||||
for (int i = 0; i < ErrorList.Count; i++)
|
||||
{
|
||||
result.AppendLine(ErrorList[i]);
|
||||
}
|
||||
return result.ToString();
|
||||
}
|
||||
else { return null; }
|
||||
}
|
||||
|
||||
public void Innit()
|
||||
{
|
||||
this.errorList = new List<string>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,9 +4,9 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Logic.Account
|
||||
namespace bnhtrade.Core.Logic.Validate
|
||||
{
|
||||
public class ValidateAccountCode : Validate
|
||||
public class AccountCode : Validate
|
||||
{
|
||||
private Logic.Utilities.StringCheck stringCheck = new Logic.Utilities.StringCheck();
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace bnhtrade.Core.Logic.Account
|
||||
{ return true; }
|
||||
else
|
||||
{
|
||||
ErrorListAdd("Invalid account code.");
|
||||
ValidationResultAdd("Invalid account code.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -33,7 +33,7 @@ namespace bnhtrade.Core.Logic.Account
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrorListAdd(stringCheck.ErrorList);
|
||||
ValidationResultAdd(stringCheck.ValidationResult);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -45,7 +45,7 @@ namespace bnhtrade.Core.Logic.Account
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrorListAdd(stringCheck.ErrorList);
|
||||
ValidationResultAdd(stringCheck.ValidationResult);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -57,7 +57,7 @@ namespace bnhtrade.Core.Logic.Account
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrorListAdd(stringCheck.ErrorList);
|
||||
ValidationResultAdd(stringCheck.ValidationResult);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -69,7 +69,7 @@ namespace bnhtrade.Core.Logic.Account
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrorListAdd(stringCheck.ErrorList);
|
||||
ValidationResultAdd(stringCheck.ValidationResult);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
21
src/bnhtrade.Core/Logic/Validate/AmazonIventoryLoaderFile.cs
Normal file
21
src/bnhtrade.Core/Logic/Validate/AmazonIventoryLoaderFile.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Logic.Validate
|
||||
{
|
||||
public class AmazonIventoryLoaderFile : Validate
|
||||
{
|
||||
public bool IsValidFbaPricing(IEnumerable<Model.Export.AmazonIventoryLoaderFile> exportList)
|
||||
{
|
||||
if (!IsValid(exportList))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return IsValidResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,16 +4,16 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Logic.Import
|
||||
namespace bnhtrade.Core.Logic.Validate
|
||||
{
|
||||
public class ValidateAmazonSettlement : Validate
|
||||
public class AmazonSettlement : Validate
|
||||
{
|
||||
protected Utilities.StringCheck stringCheck = new Utilities.StringCheck();
|
||||
protected Utilities.DateTimeCheck timeCheck = new Utilities.DateTimeCheck();
|
||||
protected Account.ValidateCurrencyCode currencyCheck = new Account.ValidateCurrencyCode();
|
||||
protected Logic.Validate.CurrencyCode currencyCheck = new Logic.Validate.CurrencyCode();
|
||||
protected Utilities.DecimalCheck decimalCheck = new Utilities.DecimalCheck();
|
||||
|
||||
public ValidateAmazonSettlement() : base()
|
||||
public AmazonSettlement() : base()
|
||||
{
|
||||
|
||||
}
|
||||
@@ -40,38 +40,38 @@ namespace bnhtrade.Core.Logic.Import
|
||||
|
||||
for (int i = 0; i < settlementList.Count; i++)
|
||||
{
|
||||
if (!settlementList[i].CurrencyCodeIsSet) { ErrorListAdd("CurrencyCode is a required value."); }
|
||||
if (!settlementList[i].CurrencyCodeIsSet) { ValidationResultAdd("CurrencyCode is a required value."); }
|
||||
else { IsValidCurrencyCode(settlementList[i].CurrencyCode); }
|
||||
|
||||
if (!settlementList[i].DepositDateIsSet) { ErrorListAdd("DepositDate is a required value."); }
|
||||
if (!settlementList[i].DepositDateIsSet) { ValidationResultAdd("DepositDate is a required value."); }
|
||||
else { IsValidDepositDate(settlementList[i].DepositDate); }
|
||||
|
||||
if (!settlementList[i].EndDateIsSet) { ErrorListAdd("EndDate is a required value."); }
|
||||
if (!settlementList[i].EndDateIsSet) { ValidationResultAdd("EndDate is a required value."); }
|
||||
else { IsValidEndDate(settlementList[i].EndDate); }
|
||||
|
||||
if (!settlementList[i].IsProcessedIsSet) { ErrorListAdd("IsProcessed is a required value."); }
|
||||
if (!settlementList[i].IsProcessedIsSet) { ValidationResultAdd("IsProcessed is a required value."); }
|
||||
else { IsValidIsProcessed(settlementList[i].IsProcessed); }
|
||||
|
||||
if (!settlementList[i].MarketPlaceNameIsSet)
|
||||
{
|
||||
if (ValidateMarketPlaceName) { ErrorListAdd("MarketPlaceName is a required value."); }
|
||||
if (ValidateMarketPlaceName) { ValidationResultAdd("MarketPlaceName is a required value."); }
|
||||
}
|
||||
else { IsValidMarketPlaceName(settlementList[i].MarketPlaceName); }
|
||||
|
||||
if (!settlementList[i].SettlementIdIsSet) { ErrorListAdd("SettlementId is a required value."); }
|
||||
if (!settlementList[i].SettlementIdIsSet) { ValidationResultAdd("SettlementId is a required value."); }
|
||||
else { IsValidSettlementId(settlementList[i].SettlementId); }
|
||||
|
||||
if (!settlementList[i].StartDateIsSet) { ErrorListAdd("StartDate is a required value."); }
|
||||
if (!settlementList[i].StartDateIsSet) { ValidationResultAdd("StartDate is a required value."); }
|
||||
else { IsValidStartDate(settlementList[i].StartDate); }
|
||||
|
||||
if (!settlementList[i].TotalAmountIsSet) { ErrorListAdd("TotalAmount is a required value."); }
|
||||
if (!settlementList[i].TotalAmountIsSet) { ValidationResultAdd("TotalAmount is a required value."); }
|
||||
else { IsValidTotalAmount(settlementList[i].TotalAmount); }
|
||||
|
||||
|
||||
// check line list
|
||||
if (!settlementList[i].SettlementLineListIsSet)
|
||||
{
|
||||
ErrorListAdd("Settlement line list is null or empty");
|
||||
ValidationResultAdd("Settlement line list is null or empty");
|
||||
continue;
|
||||
}
|
||||
else
|
||||
@@ -88,14 +88,13 @@ namespace bnhtrade.Core.Logic.Import
|
||||
// check totals
|
||||
if (lineSum != settlementList[i].TotalAmount)
|
||||
{
|
||||
ErrorListAdd("Settlement header total (" + settlementList[i].TotalAmount +
|
||||
ValidationResultAdd("Settlement header total (" + settlementList[i].TotalAmount +
|
||||
") does not match line total (" + lineSum + ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ErrorListIsSet) { return false; }
|
||||
else { return true; }
|
||||
return IsValidResult;
|
||||
}
|
||||
|
||||
public bool IsValid(Model.Import.AmazonSettlement.SettlementLine settlementLine)
|
||||
@@ -111,7 +110,7 @@ namespace bnhtrade.Core.Logic.Import
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrorListAdd("Amount is a required value.");
|
||||
ValidationResultAdd("Amount is a required value.");
|
||||
}
|
||||
|
||||
|
||||
@@ -121,7 +120,7 @@ namespace bnhtrade.Core.Logic.Import
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrorListAdd("Amount Description is a required value.");
|
||||
ValidationResultAdd("Amount Description is a required value.");
|
||||
}
|
||||
|
||||
|
||||
@@ -131,7 +130,7 @@ namespace bnhtrade.Core.Logic.Import
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrorListAdd("Amount Type is a required value.");
|
||||
ValidationResultAdd("Amount Type is a required value.");
|
||||
}
|
||||
|
||||
|
||||
@@ -141,7 +140,7 @@ namespace bnhtrade.Core.Logic.Import
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrorListAdd("Currency Code is a required value.");
|
||||
ValidationResultAdd("Currency Code is a required value.");
|
||||
}
|
||||
|
||||
|
||||
@@ -161,7 +160,7 @@ namespace bnhtrade.Core.Logic.Import
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrorListAdd("Is Processed is a required value.");
|
||||
ValidationResultAdd("Is Processed is a required value.");
|
||||
}
|
||||
|
||||
|
||||
@@ -201,7 +200,7 @@ namespace bnhtrade.Core.Logic.Import
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrorListAdd("Posted DateTime is a required value.");
|
||||
ValidationResultAdd("Posted DateTime is a required value.");
|
||||
}
|
||||
|
||||
if (settlementLine.PromotionIdIsSet)
|
||||
@@ -230,23 +229,22 @@ namespace bnhtrade.Core.Logic.Import
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrorListAdd("Transaction Type is a required value.");
|
||||
ValidationResultAdd("Transaction Type is a required value.");
|
||||
}
|
||||
|
||||
if (ErrorListIsSet) { return false; }
|
||||
else { return true; }
|
||||
return IsValidResult;
|
||||
}
|
||||
|
||||
public bool IsValidSettlementId(string settlementId)
|
||||
{
|
||||
if (!stringCheck.IsNumeric(settlementId))
|
||||
{
|
||||
ErrorListAdd(stringCheck.ErrorList.Select(x => "Invalid settlement Id: " + x).ToList());
|
||||
ValidationResultAdd(stringCheck.ValidationResult.Select(x => "Invalid settlement Id: " + x).ToList());
|
||||
return false;
|
||||
}
|
||||
if (!stringCheck.MaxLength(settlementId, 50))
|
||||
{
|
||||
ErrorListAdd(stringCheck.ErrorList.Select(x => "Invalid settlement Id: " + x).ToList());
|
||||
ValidationResultAdd(stringCheck.ValidationResult.Select(x => "Invalid settlement Id: " + x).ToList());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -261,7 +259,7 @@ namespace bnhtrade.Core.Logic.Import
|
||||
{
|
||||
if (!stringCheck.MaxLength(marketPlaceName, 50, true))
|
||||
{
|
||||
ErrorListAdd("Invalid market place name.");
|
||||
ValidationResultAdd("Invalid market place name.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -271,7 +269,7 @@ namespace bnhtrade.Core.Logic.Import
|
||||
{
|
||||
if (!timeCheck.IsUtc(startDate))
|
||||
{
|
||||
ErrorListAdd(timeCheck.ErrorList.Select(x => "Invalid StartDate: " + x).ToList());
|
||||
ValidationResultAdd(timeCheck.ValidationResult.Select(x => "Invalid StartDate: " + x).ToList());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -281,7 +279,7 @@ namespace bnhtrade.Core.Logic.Import
|
||||
{
|
||||
if (!timeCheck.IsUtc(endDate))
|
||||
{
|
||||
ErrorListAdd(timeCheck.ErrorList.Select(x => "Invalid EndDate: " + x).ToList());
|
||||
ValidationResultAdd(timeCheck.ValidationResult.Select(x => "Invalid EndDate: " + x).ToList());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -291,7 +289,7 @@ namespace bnhtrade.Core.Logic.Import
|
||||
{
|
||||
if (!timeCheck.IsUtc(depositDate))
|
||||
{
|
||||
ErrorListAdd(timeCheck.ErrorList.Select(x => "Invalid DepositDate: " + x).ToList());
|
||||
ValidationResultAdd(timeCheck.ValidationResult.Select(x => "Invalid DepositDate: " + x).ToList());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -301,7 +299,7 @@ namespace bnhtrade.Core.Logic.Import
|
||||
{
|
||||
if (!decimalCheck.SqlLength92(totalAmount))
|
||||
{
|
||||
ErrorListAdd(decimalCheck.ErrorList.Select(x => "Total Amount Invalid: " + x).ToList());
|
||||
ValidationResultAdd(decimalCheck.ValidationResult.Select(x => "Total Amount Invalid: " + x).ToList());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -311,7 +309,7 @@ namespace bnhtrade.Core.Logic.Import
|
||||
{
|
||||
if (!currencyCheck.IsValidCurrencyCode(currencyCode))
|
||||
{
|
||||
ErrorListAdd(currencyCheck.ErrorList.Select(x => "Total Amount CurrencyCode: " + x).ToList());
|
||||
ValidationResultAdd(currencyCheck.ValidationResult.Select(x => "Total Amount CurrencyCode: " + x).ToList());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -338,7 +336,7 @@ namespace bnhtrade.Core.Logic.Import
|
||||
{
|
||||
if (!stringCheck.MaxLength(transactionType, 50))
|
||||
{
|
||||
ErrorListAdd(stringCheck.ErrorList.Select(x => "Invalid transaction type: " + x).ToList());
|
||||
ValidationResultAdd(stringCheck.ValidationResult.Select(x => "Invalid transaction type: " + x).ToList());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -347,7 +345,7 @@ namespace bnhtrade.Core.Logic.Import
|
||||
{
|
||||
if (!stringCheck.MaxLength(orderId, 50, true))
|
||||
{
|
||||
ErrorListAdd(stringCheck.ErrorList.Select(x => "Invalid order id: " + x).ToList());
|
||||
ValidationResultAdd(stringCheck.ValidationResult.Select(x => "Invalid order id: " + x).ToList());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -356,7 +354,7 @@ namespace bnhtrade.Core.Logic.Import
|
||||
{
|
||||
if (!stringCheck.MaxLength(merchantOrderId, 50, true))
|
||||
{
|
||||
ErrorListAdd(stringCheck.ErrorList.Select(x => "Invalid merchant order id: " + x).ToList());
|
||||
ValidationResultAdd(stringCheck.ValidationResult.Select(x => "Invalid merchant order id: " + x).ToList());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -365,7 +363,7 @@ namespace bnhtrade.Core.Logic.Import
|
||||
{
|
||||
if (!stringCheck.MaxLength(adjustmentId, 50, true))
|
||||
{
|
||||
ErrorListAdd(stringCheck.ErrorList.Select(x => "Invalid adjustment id: " + x).ToList());
|
||||
ValidationResultAdd(stringCheck.ValidationResult.Select(x => "Invalid adjustment id: " + x).ToList());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -374,7 +372,7 @@ namespace bnhtrade.Core.Logic.Import
|
||||
{
|
||||
if (!stringCheck.MaxLength(shipmentId, 50, true))
|
||||
{
|
||||
ErrorListAdd(stringCheck.ErrorList.Select(x => "Invalid shipment id: " + x).ToList());
|
||||
ValidationResultAdd(stringCheck.ValidationResult.Select(x => "Invalid shipment id: " + x).ToList());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -383,7 +381,7 @@ namespace bnhtrade.Core.Logic.Import
|
||||
{
|
||||
if (!stringCheck.MaxLength(amountType, 50))
|
||||
{
|
||||
ErrorListAdd(stringCheck.ErrorList.Select(x => "Invalid amount type: " + x).ToList());
|
||||
ValidationResultAdd(stringCheck.ValidationResult.Select(x => "Invalid amount type: " + x).ToList());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -392,7 +390,7 @@ namespace bnhtrade.Core.Logic.Import
|
||||
{
|
||||
if (!stringCheck.MaxLength(amountDescription, 100))
|
||||
{
|
||||
ErrorListAdd(stringCheck.ErrorList.Select(x => "Invalid amount description: " + x).ToList());
|
||||
ValidationResultAdd(stringCheck.ValidationResult.Select(x => "Invalid amount description: " + x).ToList());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -401,7 +399,7 @@ namespace bnhtrade.Core.Logic.Import
|
||||
{
|
||||
if (!decimalCheck.SqlLength92(amount))
|
||||
{
|
||||
ErrorListAdd(decimalCheck.ErrorList.Select(x => "Invalid amount: " + x).ToList());
|
||||
ValidationResultAdd(decimalCheck.ValidationResult.Select(x => "Invalid amount: " + x).ToList());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -410,7 +408,7 @@ namespace bnhtrade.Core.Logic.Import
|
||||
{
|
||||
if (!currencyCheck.IsValidCurrencyCode(currenyCode))
|
||||
{
|
||||
ErrorListAdd(currencyCheck.ErrorList.Select(x => "Invalid curreny code: " + x).ToList());
|
||||
ValidationResultAdd(currencyCheck.ValidationResult.Select(x => "Invalid curreny code: " + x).ToList());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -419,7 +417,7 @@ namespace bnhtrade.Core.Logic.Import
|
||||
{
|
||||
if (!stringCheck.MaxLength(fulfillmentId, 50, true))
|
||||
{
|
||||
ErrorListAdd(stringCheck.ErrorList.Select(x => "Invalid fulfillment Id: " + x).ToList());
|
||||
ValidationResultAdd(stringCheck.ValidationResult.Select(x => "Invalid fulfillment Id: " + x).ToList());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -429,7 +427,7 @@ namespace bnhtrade.Core.Logic.Import
|
||||
var timeCheck = new Logic.Utilities.DateTimeCheck();
|
||||
if (!timeCheck.IsUtc(postDateTime))
|
||||
{
|
||||
ErrorListAdd(@"Invalid post date/time, not set to UTC kind.");
|
||||
ValidationResultAdd(@"Invalid post date/time, not set to UTC kind.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -438,7 +436,7 @@ namespace bnhtrade.Core.Logic.Import
|
||||
{
|
||||
if (!stringCheck.MaxLength(orderItemCode, 50, true))
|
||||
{
|
||||
ErrorListAdd(stringCheck.ErrorList.Select(x => "Invalid order item code: " + x).ToList());
|
||||
ValidationResultAdd(stringCheck.ValidationResult.Select(x => "Invalid order item code: " + x).ToList());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -447,7 +445,7 @@ namespace bnhtrade.Core.Logic.Import
|
||||
{
|
||||
if (!stringCheck.MaxLength(merchantOrderItemId, 50, true))
|
||||
{
|
||||
ErrorListAdd(stringCheck.ErrorList.Select(x => "Invalid merchant order item id: " + x).ToList());
|
||||
ValidationResultAdd(stringCheck.ValidationResult.Select(x => "Invalid merchant order item id: " + x).ToList());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -456,7 +454,7 @@ namespace bnhtrade.Core.Logic.Import
|
||||
{
|
||||
if (!stringCheck.MaxLength(merchantAdjustmentItemId, 50, true))
|
||||
{
|
||||
ErrorListAdd(stringCheck.ErrorList.Select(x => "Invalid merchant adjustment item id: " + x).ToList());
|
||||
ValidationResultAdd(stringCheck.ValidationResult.Select(x => "Invalid merchant adjustment item id: " + x).ToList());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -465,7 +463,7 @@ namespace bnhtrade.Core.Logic.Import
|
||||
{
|
||||
if (!stringCheck.MaxLength(skuNumber, 50, true))
|
||||
{
|
||||
ErrorListAdd(stringCheck.ErrorList.Select(x => "Invalid sku number: " + x).ToList());
|
||||
ValidationResultAdd(stringCheck.ValidationResult.Select(x => "Invalid sku number: " + x).ToList());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -478,7 +476,7 @@ namespace bnhtrade.Core.Logic.Import
|
||||
{
|
||||
if (!stringCheck.MaxLength(promotionId, 50, true))
|
||||
{
|
||||
ErrorListAdd(stringCheck.ErrorList.Select(x => "Invalid promotion id: " + x).ToList());
|
||||
ValidationResultAdd(stringCheck.ValidationResult.Select(x => "Invalid promotion id: " + x).ToList());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -491,7 +489,7 @@ namespace bnhtrade.Core.Logic.Import
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrorListAdd("Export account invoice line id cannot be less than 1");
|
||||
ValidationResultAdd("Export account invoice line id cannot be less than 1");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -5,9 +5,9 @@ using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Logic.Account
|
||||
namespace bnhtrade.Core.Logic.Validate
|
||||
{
|
||||
public class ValidateCurrencyCode : Validate
|
||||
public class CurrencyCode : Validate
|
||||
{
|
||||
private Logic.Utilities.StringCheck stringCheck = new Logic.Utilities.StringCheck();
|
||||
public new void Innit()
|
||||
@@ -23,7 +23,7 @@ namespace bnhtrade.Core.Logic.Account
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrorListAdd(stringCheck.ErrorList);
|
||||
ValidationResultAdd(stringCheck.ValidationResult);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
43
src/bnhtrade.Core/Logic/Validate/SalesInvoice.cs
Normal file
43
src/bnhtrade.Core/Logic/Validate/SalesInvoice.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Logic.Validate
|
||||
{
|
||||
public class SalesInvoice : Logic.Validate.Validate
|
||||
{
|
||||
public SalesInvoice()
|
||||
{
|
||||
}
|
||||
|
||||
public bool IsValidExportInvoice(IEnumerable<Model.Account.Invoice> invoiceList)
|
||||
{
|
||||
if (!IsValid(invoiceList))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (var invoice in invoiceList)
|
||||
{
|
||||
if (invoice.UnitAmountIsTaxExclusive == false)
|
||||
{
|
||||
ValidationResultAdd("Tax inclusive line unit amounts are not supported");
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (var invoiceLine in invoice.InvoiceLineList)
|
||||
{
|
||||
if (invoiceLine.Quantity != 1)
|
||||
{
|
||||
ValidationResultAdd("Quantities greater than 1 are not supported");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return IsValidResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
29
src/bnhtrade.Core/Logic/Validate/SkuPriceInfo.cs
Normal file
29
src/bnhtrade.Core/Logic/Validate/SkuPriceInfo.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Logic.Validate
|
||||
{
|
||||
public class SkuPriceInfo : Validate
|
||||
{
|
||||
public SkuPriceInfo()
|
||||
{
|
||||
Innit();
|
||||
}
|
||||
|
||||
public bool IsValidDatabaseCreate(List<Model.Sku.Price.PriceInfo> priceInfoList)
|
||||
{
|
||||
Innit();
|
||||
|
||||
if (!IsValid(priceInfoList))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return IsValidResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
44
src/bnhtrade.Core/Logic/Validate/SkuTransaction.cs
Normal file
44
src/bnhtrade.Core/Logic/Validate/SkuTransaction.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Logic.Validate
|
||||
{
|
||||
public class SkuTransaction : Validate
|
||||
{
|
||||
public bool DatabaseUpdate(Model.Stock.SkuTransaction skuTransaction)
|
||||
{
|
||||
return IsValid(new List<Model.Stock.SkuTransaction> { skuTransaction });
|
||||
}
|
||||
|
||||
public bool DatabaseUpdate(List<Model.Stock.SkuTransaction> skuTransactionList)
|
||||
{
|
||||
if (!IsValid(skuTransactionList))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < skuTransactionList.Count; i++)
|
||||
{
|
||||
if (!skuTransactionList[i].IsSetSkuTransactionId)
|
||||
{
|
||||
ValidationResultAdd("StockTransactionId is required");
|
||||
}
|
||||
}
|
||||
|
||||
return IsValidResult;
|
||||
}
|
||||
|
||||
public bool DatabaseInsert(Model.Stock.SkuTransaction skuTransaction)
|
||||
{
|
||||
return IsValid(new List<Model.Stock.SkuTransaction> { skuTransaction });
|
||||
}
|
||||
|
||||
public bool DatabaseInsert(List<Model.Stock.SkuTransaction> skuTransactionList)
|
||||
{
|
||||
return IsValid(skuTransactionList);
|
||||
}
|
||||
}
|
||||
}
|
||||
17
src/bnhtrade.Core/Logic/Validate/TaxCodeInfo.cs
Normal file
17
src/bnhtrade.Core/Logic/Validate/TaxCodeInfo.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Logic.Validate
|
||||
{
|
||||
public class TaxCodeInfo : Validate
|
||||
{
|
||||
public bool IsValidPresistanceGet(Model.Account.TaxCodeInfo taxCodeInfo)
|
||||
{
|
||||
return IsValid(taxCodeInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
94
src/bnhtrade.Core/Logic/Validate/Validate.cs
Normal file
94
src/bnhtrade.Core/Logic/Validate/Validate.cs
Normal file
@@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace bnhtrade.Core.Logic.Validate
|
||||
{
|
||||
public abstract class Validate
|
||||
{
|
||||
public List<ValidationResult> ValidationResult { get; set; } = new List<ValidationResult>();
|
||||
|
||||
public bool IsValidResult
|
||||
{
|
||||
get
|
||||
{
|
||||
if (ValidationResult.Any()) { return false; }
|
||||
else { return true; }
|
||||
}
|
||||
}
|
||||
|
||||
public void Innit()
|
||||
{
|
||||
ValidationResult = new List<ValidationResult>();
|
||||
}
|
||||
|
||||
protected bool IsValid(IValidatableObject validatableObject)
|
||||
{
|
||||
if (validatableObject == null)
|
||||
{
|
||||
ValidationResult.Add(new ValidationResult("Validatable object is null"));
|
||||
return false;
|
||||
}
|
||||
|
||||
var validationContext = new ValidationContext(validatableObject);
|
||||
ValidationResult.AddRange(validatableObject.Validate(validationContext));
|
||||
return IsValidResult;
|
||||
}
|
||||
|
||||
protected bool IsValid(IEnumerable<IValidatableObject> validatableObjectList)
|
||||
{
|
||||
if (validatableObjectList == null || !validatableObjectList.Any())
|
||||
{
|
||||
ValidationResult.Add(new ValidationResult("Validatable object list is empty or null"));
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (var validatableObject in validatableObjectList)
|
||||
{
|
||||
if (!IsValid(validatableObject)) { return false; }
|
||||
}
|
||||
|
||||
return IsValidResult;
|
||||
}
|
||||
|
||||
protected void ValidationResultAdd(string result)
|
||||
{
|
||||
ValidationResult.Add(new ValidationResult(result));
|
||||
}
|
||||
|
||||
protected void ValidationResultAdd(List<string> result)
|
||||
{
|
||||
foreach (var item in result)
|
||||
{
|
||||
ValidationResultAdd(item);
|
||||
}
|
||||
}
|
||||
|
||||
protected void ValidationResultAdd(ValidationResult result)
|
||||
{
|
||||
ValidationResult.Add(result);
|
||||
}
|
||||
|
||||
protected void ValidationResultAdd(List<ValidationResult> result)
|
||||
{
|
||||
ValidationResult.AddRange(result);
|
||||
}
|
||||
|
||||
public string ValidationResultListToString()
|
||||
{
|
||||
if (IsValidResult == false)
|
||||
{
|
||||
StringBuilder result = new StringBuilder();
|
||||
for (int i = 0; i < ValidationResult.Count; i++)
|
||||
{
|
||||
result.AppendLine(ValidationResult[i].ErrorMessage);
|
||||
}
|
||||
return result.ToString();
|
||||
}
|
||||
else { return null; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,58 +1,86 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Model.Account
|
||||
{
|
||||
public class AccountCode
|
||||
public class AccountCode : IValidatableObject
|
||||
{
|
||||
private int? accountCodeId;
|
||||
|
||||
[Required(), Range(1, int.MaxValue)]
|
||||
public int AccountCodeId
|
||||
{
|
||||
get { return (int)accountCodeId; }
|
||||
set { accountCodeId = value; }
|
||||
}
|
||||
|
||||
[Required(), MaxLength(150)]
|
||||
public string Title
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[MaxLength(500)]
|
||||
public string Description
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Required(), MaxLength(50)]
|
||||
public string Type
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Required(), MaxLength(50)]
|
||||
public string BasicType
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public bool IsSetAccountCodeId
|
||||
{
|
||||
get { return accountCodeId != null; }
|
||||
}
|
||||
|
||||
public bool IsSetTitle
|
||||
{
|
||||
get { return Title != null; }
|
||||
}
|
||||
|
||||
public bool IsSetDescription
|
||||
{
|
||||
get { return Description != null; }
|
||||
}
|
||||
|
||||
public bool IsSetType
|
||||
{
|
||||
get { return Type != null; }
|
||||
}
|
||||
|
||||
public bool IsSetBasicType
|
||||
{
|
||||
get { return BasicType != null; }
|
||||
}
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
var resultList = new List<ValidationResult>();
|
||||
|
||||
if (!IsSetAccountCodeId)
|
||||
{
|
||||
resultList.Add(new ValidationResult("Account Code is not set"));
|
||||
}
|
||||
|
||||
return resultList;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
@@ -8,6 +9,10 @@ namespace bnhtrade.Core.Model.Account
|
||||
{
|
||||
public interface IInvoice : IInvoiceHeader
|
||||
{
|
||||
decimal InvoiceNetAmount { get; }
|
||||
|
||||
decimal InvoiceTaxAmount { get; }
|
||||
|
||||
List<Invoice.InvoiceLine> InvoiceLineList { get; set; }
|
||||
|
||||
bool InvoiceLineListIsSet { get; }
|
||||
@@ -17,163 +22,231 @@ namespace bnhtrade.Core.Model.Account
|
||||
{
|
||||
string ItemCode { get; set; }
|
||||
|
||||
bool ItemCodeIsSet { get; }
|
||||
|
||||
bool DescriptionIsSet { get; }
|
||||
|
||||
string Description { get; set; }
|
||||
|
||||
int Quantity { get; set; }
|
||||
decimal? Quantity { get; set; }
|
||||
|
||||
bool QuantityIsSet { get; }
|
||||
decimal? UnitAmount { get; set; }
|
||||
|
||||
decimal TotalNetAmount { get; set; }
|
||||
Model.Account.AccountCode AccountCode { get; set; }
|
||||
|
||||
bool TotalNetAmountIsSet { get; }
|
||||
Model.Account.TaxCodeInfo TaxCode { get; set; }
|
||||
|
||||
bool AccountCodeIsSet { get; }
|
||||
decimal? TaxAmountAdjust { get; set; }
|
||||
|
||||
int AccountCode { get; set; }
|
||||
decimal? TaxAmount { get; }
|
||||
|
||||
bool TaxCodeIsSet { get; }
|
||||
|
||||
string TaxCode { get; set; }
|
||||
|
||||
decimal TaxAmountAdjust { get; set; }
|
||||
|
||||
bool TaxAmountAdjustIsSet { get; }
|
||||
|
||||
decimal TaxAmount { get; }
|
||||
|
||||
bool TaxAmountIsSet { get; }
|
||||
|
||||
decimal GrossTotalAmount { get; }
|
||||
|
||||
bool GrossTotalAmountIsSet { get; }
|
||||
decimal LineTotalAmount { get; }
|
||||
}
|
||||
|
||||
|
||||
public abstract class Invoice : InvoiceHeader, IInvoice
|
||||
{
|
||||
private bool unitAmountIsTaxExclusive = true;
|
||||
|
||||
public decimal InvoiceNetAmount { get; }
|
||||
|
||||
public decimal InvoiceTaxAmount { get; }
|
||||
|
||||
public bool UnitAmountIsTaxExclusive
|
||||
{
|
||||
get { return unitAmountIsTaxExclusive; }
|
||||
set
|
||||
{
|
||||
unitAmountIsTaxExclusive = value;
|
||||
if (InvoiceLineList != null)
|
||||
{
|
||||
for (int i = 0; i < InvoiceLineList.Count; i++)
|
||||
{
|
||||
InvoiceLineList[i].UnitAmountIsTaxExclusive = unitAmountIsTaxExclusive;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<InvoiceLine> InvoiceLineList { get; set; } = new List<InvoiceLine>();
|
||||
|
||||
public bool InvoiceLineListIsSet
|
||||
{
|
||||
get
|
||||
{
|
||||
if (InvoiceLineList == null || !InvoiceLineList.Any())
|
||||
{ return false; }
|
||||
else
|
||||
{ return true; }
|
||||
if (InvoiceLineList == null || !InvoiceLineList.Any()) { return false; }
|
||||
else { return true; }
|
||||
}
|
||||
}
|
||||
|
||||
public class InvoiceLine : IInvoiceLine
|
||||
public class InvoiceLine : IInvoiceLine, IValidatableObject
|
||||
{
|
||||
private int? accountCode;
|
||||
private decimal? netAmount;
|
||||
private decimal? taxAmount;
|
||||
private decimal? unitAmount;
|
||||
private Model.Account.TaxCodeInfo taxCode;
|
||||
private decimal? taxAmountAdjust;
|
||||
private int? quantity;
|
||||
private decimal? discount;
|
||||
private decimal? quantity;
|
||||
|
||||
public string ItemCode
|
||||
public InvoiceLine(bool unitAmountIsTaxExclusive)
|
||||
{
|
||||
UnitAmountIsTaxExclusive = unitAmountIsTaxExclusive;
|
||||
}
|
||||
|
||||
public string ItemCode { get; set; }
|
||||
|
||||
public string Description { get; set; }
|
||||
|
||||
[Required(), Range(0, 9999999.99)]
|
||||
public decimal? Quantity
|
||||
{
|
||||
get { return quantity; }
|
||||
set
|
||||
{
|
||||
if (value == null) { quantity = null; }
|
||||
else { quantity = decimal.Round((decimal)value, 4, MidpointRounding.AwayFromZero); }
|
||||
}
|
||||
}
|
||||
|
||||
[Required()]
|
||||
public decimal? UnitAmount
|
||||
{
|
||||
get { return unitAmount; }
|
||||
set
|
||||
{
|
||||
if (value == null) { unitAmount = null; }
|
||||
else { unitAmount = decimal.Round(value.GetValueOrDefault(), 4, MidpointRounding.AwayFromZero); }
|
||||
}
|
||||
}
|
||||
|
||||
public bool UnitAmountIsTaxExclusive { get; set; }
|
||||
|
||||
[Required()]
|
||||
public Model.Account.AccountCode AccountCode
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public bool ItemCodeIsSet
|
||||
[Required()]
|
||||
public Model.Account.TaxCodeInfo TaxCode
|
||||
{
|
||||
get { return ItemCode != null; }
|
||||
get { return taxCode; }
|
||||
set
|
||||
{
|
||||
if (value == null || TaxCode == null || value.TaxCode != taxCode.TaxCode)
|
||||
{
|
||||
TaxAmountAdjust = 0;
|
||||
}
|
||||
|
||||
public string Description
|
||||
{
|
||||
get;
|
||||
set;
|
||||
taxCode = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool DescriptionIsSet
|
||||
[Required()]
|
||||
public decimal? TaxAmount
|
||||
{
|
||||
get { return Description != null; }
|
||||
get
|
||||
{
|
||||
return TaxAmountAdjust + GetCalculatedTax();
|
||||
}
|
||||
}
|
||||
|
||||
public int Quantity
|
||||
public decimal? TaxAmountAdjust
|
||||
{
|
||||
get { return (int)quantity.GetValueOrDefault(); }
|
||||
set { quantity = value; }
|
||||
get { return taxAmountAdjust; }
|
||||
set
|
||||
{
|
||||
if (value == null) { taxAmountAdjust = null; }
|
||||
else { taxAmountAdjust = decimal.Round((decimal)value, 2, MidpointRounding.AwayFromZero); }
|
||||
}
|
||||
}
|
||||
|
||||
public bool QuantityIsSet
|
||||
public decimal LineTotalAmount
|
||||
{
|
||||
get { return quantity != null; }
|
||||
get
|
||||
{
|
||||
if (CanCalculateLine())
|
||||
{
|
||||
return ((decimal)Quantity * (decimal)UnitAmount) + (decimal)TaxAmount;
|
||||
}
|
||||
else { return 0; }
|
||||
}
|
||||
}
|
||||
|
||||
public decimal TotalNetAmount
|
||||
private bool CanCalculateLine()
|
||||
{
|
||||
get { return (decimal)netAmount.GetValueOrDefault(); }
|
||||
set { netAmount = value; }
|
||||
if (Quantity == null || UnitAmount == null || TaxCode == null) { return false; }
|
||||
else { return true; }
|
||||
}
|
||||
|
||||
public bool TotalNetAmountIsSet
|
||||
private decimal GetCalculatedTax()
|
||||
{
|
||||
get { return netAmount != null; }
|
||||
decimal calculatedTax = 0;
|
||||
if (CanCalculateLine())
|
||||
{
|
||||
if (UnitAmountIsTaxExclusive)
|
||||
{
|
||||
calculatedTax = ((decimal)Quantity * (decimal)UnitAmount) * (TaxCode.TaxRate / 100);
|
||||
}
|
||||
else
|
||||
{
|
||||
calculatedTax = ((decimal)Quantity * (decimal)UnitAmount) * (TaxCode.TaxRate / (100 + TaxCode.TaxRate));
|
||||
}
|
||||
return decimal.Round(calculatedTax, 2, MidpointRounding.AwayFromZero);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public int AccountCode
|
||||
public void SetTaxAmountAdjust(decimal lineTaxAmount)
|
||||
{
|
||||
get { return (int)accountCode.GetValueOrDefault(); }
|
||||
set { accountCode = value; }
|
||||
decimal adjustedAmount = lineTaxAmount - GetCalculatedTax();
|
||||
if (adjustedAmount == 0) { TaxAmountAdjust = null; }
|
||||
else { TaxAmountAdjust = adjustedAmount; }
|
||||
}
|
||||
|
||||
public bool AccountCodeIsSet
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
get { return accountCode != null; }
|
||||
throw new NotImplementedException();
|
||||
|
||||
var resultList = new List<ValidationResult>();
|
||||
|
||||
if (TaxAmount > LineTotalAmount / 2)
|
||||
{
|
||||
resultList.Add(new ValidationResult("Line tax amount is greater than net amount"));
|
||||
}
|
||||
|
||||
public string TaxCode
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
}
|
||||
|
||||
public bool TaxCodeIsSet
|
||||
public new IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
get { return TaxCode != null; }
|
||||
var subResult = base.Validate(validationContext);
|
||||
var resultList = new List<ValidationResult>();
|
||||
resultList.AddRange(subResult);
|
||||
|
||||
|
||||
// loop though lines and check sum totals
|
||||
if (!InvoiceLineListIsSet)
|
||||
{
|
||||
resultList.Add(new ValidationResult("No lines set on Invoice"));
|
||||
}
|
||||
else
|
||||
{
|
||||
decimal lineTotal = 0;
|
||||
foreach (var line in InvoiceLineList)
|
||||
{
|
||||
lineTotal += line.LineTotalAmount;
|
||||
|
||||
if (UnitAmountIsTaxExclusive != line.UnitAmountIsTaxExclusive)
|
||||
{
|
||||
resultList.Add(new ValidationResult("Invalid UnitAmountIsTaxExclusive"));
|
||||
}
|
||||
}
|
||||
|
||||
public decimal TaxAmount
|
||||
{
|
||||
get { return (decimal)taxAmount.GetValueOrDefault(); }
|
||||
set { taxAmount = decimal.Round(value, 2); }
|
||||
// check totals
|
||||
if (InvoiceTotalAmount != lineTotal)
|
||||
{ resultList.Add(new ValidationResult("Invoice line total does not equal invoice total")); }
|
||||
}
|
||||
|
||||
public bool TaxAmountIsSet
|
||||
{
|
||||
get { return taxAmount != null; }
|
||||
}
|
||||
|
||||
public decimal TaxAmountAdjust
|
||||
{
|
||||
get { return (decimal)taxAmountAdjust.GetValueOrDefault(); }
|
||||
set { taxAmountAdjust = decimal.Round(value, 2); }
|
||||
}
|
||||
|
||||
public bool TaxAmountAdjustIsSet
|
||||
{
|
||||
get { return taxAmountAdjust != null; }
|
||||
}
|
||||
|
||||
public decimal GrossTotalAmount
|
||||
{
|
||||
get { return (decimal)netAmount.GetValueOrDefault() + TaxAmount; }
|
||||
}
|
||||
|
||||
public bool GrossTotalAmountIsSet
|
||||
{
|
||||
get { return (TotalNetAmountIsSet && TaxAmountIsSet); }
|
||||
}
|
||||
return resultList;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
@@ -9,31 +10,24 @@ namespace bnhtrade.Core.Model.Account
|
||||
public interface IInvoiceHeader
|
||||
{
|
||||
string ContactName { get; set; }
|
||||
bool ContactNameIsSet { get; }
|
||||
decimal InvoiceAmount { get; set; }
|
||||
bool InvoiceAmountIsSet { get; }
|
||||
|
||||
decimal? InvoiceTotalAmount { get; set; }
|
||||
|
||||
string InvoiceCurrencyCode { get; set; }
|
||||
bool InvoiceCurrencyCodeIsSet { get; }
|
||||
DateTime InvoiceDate { get; set; }
|
||||
bool InvoiceDateIsSet { get; }
|
||||
DateTime InvoiceDueDate { get; set; }
|
||||
bool InvoiceDueDateIsSet { get; }
|
||||
DateTimeKind InvoiceDateKind { get; set; }
|
||||
bool InvoiceDateKindIsSet { get; }
|
||||
|
||||
DateTime? InvoiceDate { get; set; }
|
||||
|
||||
DateTime? InvoiceDueDate { get; set; }
|
||||
|
||||
string InvoiceNumber { get; set; }
|
||||
bool InvoiceNumberIsSet { get; }
|
||||
|
||||
string InvoiceReference { get; set; }
|
||||
bool InvoiceReferenceIsSet { get; }
|
||||
|
||||
bool IsCreditNote { get; set; }
|
||||
bool IsCreditNoteIsSet { get; }
|
||||
}
|
||||
|
||||
public abstract class InvoiceHeader : IInvoiceHeader
|
||||
public abstract class InvoiceHeader :IInvoiceHeader, IValidatableObject
|
||||
{
|
||||
private string invoiceCurrencyCode;
|
||||
private DateTime? invoiceDate;
|
||||
private DateTime? invoiceDueDate;
|
||||
private DateTimeKind? invoiceDateKind = DateTimeKind.Utc;
|
||||
private decimal? invoiceAmount;
|
||||
|
||||
public InvoiceHeader()
|
||||
@@ -41,95 +35,51 @@ namespace bnhtrade.Core.Model.Account
|
||||
IsCreditNote = false;
|
||||
}
|
||||
|
||||
[Required()]
|
||||
public string ContactName { get; set; }
|
||||
|
||||
public bool ContactNameIsSet
|
||||
{
|
||||
get { return ContactName != null; }
|
||||
}
|
||||
[Required()]
|
||||
public DateTime? InvoiceDate { get; set; }
|
||||
|
||||
public DateTime InvoiceDate
|
||||
{
|
||||
get { return (DateTime)invoiceDate.GetValueOrDefault(); }
|
||||
set { invoiceDate = value; }
|
||||
}
|
||||
[Required()]
|
||||
public DateTime? InvoiceDueDate { get; set; }
|
||||
|
||||
public bool InvoiceDateIsSet
|
||||
{
|
||||
get { return invoiceDate != null; }
|
||||
}
|
||||
|
||||
public DateTime InvoiceDueDate
|
||||
{
|
||||
get { return (DateTime)invoiceDueDate.GetValueOrDefault(); }
|
||||
set { invoiceDueDate = value; }
|
||||
}
|
||||
|
||||
public bool InvoiceDueDateIsSet
|
||||
{
|
||||
get { return invoiceDueDate != null; }
|
||||
}
|
||||
|
||||
public DateTimeKind InvoiceDateKind
|
||||
{
|
||||
get { return (DateTimeKind)invoiceDateKind; }
|
||||
set { invoiceDateKind = value; }
|
||||
}
|
||||
|
||||
public bool InvoiceDateKindIsSet
|
||||
{
|
||||
get { return invoiceDateKind != null; }
|
||||
}
|
||||
|
||||
public string InvoiceCurrencyCode
|
||||
{
|
||||
get { return invoiceCurrencyCode; }
|
||||
set
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
invoiceCurrencyCode = value.ToUpper();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool InvoiceCurrencyCodeIsSet
|
||||
{
|
||||
get { return InvoiceCurrencyCode != null; }
|
||||
}
|
||||
[Required(), MinLength(3), MaxLength(3)]
|
||||
public string InvoiceCurrencyCode { get; set; }
|
||||
|
||||
[Required()]
|
||||
public string InvoiceNumber { get; set; }
|
||||
|
||||
public bool InvoiceNumberIsSet
|
||||
{
|
||||
get { return InvoiceNumber != null; }
|
||||
}
|
||||
|
||||
public string InvoiceReference { get; set; }
|
||||
|
||||
public bool InvoiceReferenceIsSet
|
||||
{
|
||||
get { return InvoiceReference != null; }
|
||||
}
|
||||
|
||||
public decimal InvoiceAmount
|
||||
[Required()]
|
||||
public decimal? InvoiceTotalAmount
|
||||
{
|
||||
get { return (decimal)invoiceAmount; }
|
||||
set { invoiceAmount = value; }
|
||||
set
|
||||
{
|
||||
if (value == null) { invoiceAmount = null; }
|
||||
else { invoiceAmount = decimal.Round((decimal)value, 2, MidpointRounding.AwayFromZero); }
|
||||
}
|
||||
}
|
||||
|
||||
public bool InvoiceAmountIsSet
|
||||
[Required()]
|
||||
public bool IsCreditNote { get; set; }
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
get { return invoiceAmount != null; }
|
||||
var resultList = new List<ValidationResult>();
|
||||
|
||||
if (IsCreditNote && InvoiceTotalAmount > 0)
|
||||
{
|
||||
resultList.Add(new ValidationResult("Credit Note amount cannot be greater than zero"));
|
||||
}
|
||||
public bool IsCreditNote
|
||||
else if (!IsCreditNote && InvoiceTotalAmount < 0)
|
||||
{
|
||||
get;
|
||||
set;
|
||||
resultList.Add(new ValidationResult("Invoice amount cannot be less than zero"));
|
||||
}
|
||||
public bool IsCreditNoteIsSet
|
||||
{
|
||||
get { return true; }
|
||||
|
||||
return resultList;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,47 +1,70 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Model.Account
|
||||
{
|
||||
public class InvoiceLineItem
|
||||
public class InvoiceLineItem : IValidatableObject
|
||||
{
|
||||
[Required()]
|
||||
public string ItemCode
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
public string Title
|
||||
|
||||
[Required()]
|
||||
public string Name
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public string Description
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Required()]
|
||||
public bool IsNewReviewRequired
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Required()]
|
||||
public bool InvoiceLineEntryEnabled
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
public int DefaultAccountCode
|
||||
|
||||
[Required()]
|
||||
public Model.Account.AccountCode DefaultAccountCode
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
public string DefaultTaxCode
|
||||
|
||||
[Required()]
|
||||
public Model.Account.TaxCodeInfo DefaultTaxCode
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
var resultList = new List<ValidationResult>();
|
||||
|
||||
resultList.AddRange(DefaultAccountCode.Validate(validationContext));
|
||||
resultList.AddRange(DefaultTaxCode.Validate(validationContext));
|
||||
|
||||
return resultList;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Model.Account
|
||||
{
|
||||
public class TaxCode
|
||||
{
|
||||
private decimal? netAmountMultiplier = null;
|
||||
private decimal? grossAmountMultiplier = null;
|
||||
private bool? isActive = null;
|
||||
private bool? isValidOnExpense = null;
|
||||
private bool? isValidOnIncome = null;
|
||||
|
||||
public string TaxCodeId { get; set; }
|
||||
public string TaxRateDescription { get; set; }
|
||||
public string TaxRateTitle { get; set; }
|
||||
public string TaxType { get; set; }
|
||||
public decimal NetAmountMultiplier
|
||||
{
|
||||
get { return (decimal)netAmountMultiplier; }
|
||||
set { netAmountMultiplier = value; }
|
||||
}
|
||||
public decimal GrossAmountMultiplier
|
||||
{
|
||||
get { return (decimal)grossAmountMultiplier; }
|
||||
set { grossAmountMultiplier = value; }
|
||||
}
|
||||
public bool IsActive
|
||||
{
|
||||
get { return (bool)isActive; }
|
||||
set { isActive = value; }
|
||||
}
|
||||
public bool IsSetAll
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsSetGrossAmountMultiplier
|
||||
&& IsSetIsActive
|
||||
&& IsSetIsValidOnExpense
|
||||
&& IsSetIsValidOnIncome
|
||||
&& IsSetNetAmountMultiplier
|
||||
&& IsSetTaxCodeId
|
||||
&& IsSetTaxRateTitle
|
||||
&& IsSetTaxRateDescription
|
||||
)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else { return false; }
|
||||
}
|
||||
}
|
||||
public bool IsSetGrossAmountMultiplier
|
||||
{
|
||||
get { return grossAmountMultiplier != null; }
|
||||
}
|
||||
public bool IsSetIsActive
|
||||
{
|
||||
get { return isActive != null; }
|
||||
}
|
||||
public bool IsSetIsValidOnExpense
|
||||
{
|
||||
get { return isValidOnExpense != null; }
|
||||
}
|
||||
public bool IsSetIsValidOnIncome
|
||||
{
|
||||
get { return isValidOnIncome != null; }
|
||||
}
|
||||
public bool IsSetNetAmountMultiplier
|
||||
{
|
||||
get { return netAmountMultiplier != null; }
|
||||
}
|
||||
public bool IsSetTaxCodeId
|
||||
{
|
||||
get { return TaxCodeId != null; }
|
||||
}
|
||||
public bool IsSetTaxRateTitle
|
||||
{
|
||||
get { return TaxRateTitle != null; }
|
||||
}
|
||||
public bool IsSetTaxRateDescription
|
||||
{
|
||||
get { return TaxRateDescription != null; }
|
||||
}
|
||||
public bool IsSetTaxType
|
||||
{
|
||||
get { return TaxType != null; }
|
||||
}
|
||||
public bool IsValidOnExpense
|
||||
{
|
||||
get { return (bool)isValidOnExpense; }
|
||||
set { isValidOnExpense = value; }
|
||||
}
|
||||
public bool IsValidOnIncome
|
||||
{
|
||||
get { return (bool)isValidOnIncome; }
|
||||
set { isValidOnIncome = value; }
|
||||
}
|
||||
}
|
||||
}
|
||||
72
src/bnhtrade.Core/Model/Account/TaxCodeInfo.cs
Normal file
72
src/bnhtrade.Core/Model/Account/TaxCodeInfo.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Model.Account
|
||||
{
|
||||
public class TaxCodeInfo : IValidatableObject
|
||||
{
|
||||
public TaxCodeInfo(string taxCodeId, string title, string description, decimal taxRatePercent, bool isMarginSchemeRate,
|
||||
bool isValidOnExpense, bool isValidOnIncome, string taxType, bool isActive)
|
||||
{
|
||||
if (TaxRate < 0)
|
||||
{
|
||||
throw new Exception("Tax rate is less than zero");
|
||||
}
|
||||
|
||||
if (TaxRate >= 100)
|
||||
{
|
||||
// 100% rate has been used where the line total is all tax
|
||||
// you need to do somemore coding when this facility is required
|
||||
throw new Exception("Tax rate is >= 100%");
|
||||
}
|
||||
|
||||
TaxCode = taxCodeId;
|
||||
TaxCodeDescription = description;
|
||||
TaxRate = taxRatePercent;
|
||||
IsMarginScheme = isMarginSchemeRate;
|
||||
TaxCodeName = title;
|
||||
TaxType = taxType;
|
||||
IsActive = isActive;
|
||||
IsValidOnExpense = isValidOnExpense;
|
||||
IsValidOnIncome = isValidOnIncome;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unique identifier
|
||||
/// </summary>
|
||||
[Required()]
|
||||
public string TaxCode { get; private set; }
|
||||
|
||||
[Required()]
|
||||
public string TaxCodeName { get; private set; }
|
||||
|
||||
public string TaxCodeDescription { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Tax rate as a percentage
|
||||
/// </summary>
|
||||
[Required(), Range(0, 100)]
|
||||
public decimal TaxRate { get; private set; }
|
||||
|
||||
public bool IsMarginScheme { get; private set; }
|
||||
|
||||
[Required()]
|
||||
public string TaxType { get; private set; }
|
||||
|
||||
public bool IsValidOnExpense { get; private set; }
|
||||
|
||||
public bool IsValidOnIncome { get; private set; }
|
||||
|
||||
public bool IsActive { get; private set; }
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
var resultList = new List<ValidationResult>();
|
||||
return resultList;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Model.AmazonFBAInbound
|
||||
namespace bnhtrade.Core.Model.AmazonFba
|
||||
{
|
||||
public class ShipmentInfo
|
||||
{
|
||||
@@ -13,9 +13,12 @@ namespace bnhtrade.Core.Model.AmazonFBAInbound
|
||||
private string shipmentStatus;
|
||||
private DateTime lastUpdatedUtc;
|
||||
private Dictionary<string, bool> shipmentStatusToIsClosed;
|
||||
private int? shipmentStockStatusId = null;
|
||||
|
||||
public string FbaShipmentId { get; set; }
|
||||
|
||||
public string AmazonShipmentId { get; set; }
|
||||
public string ShipmentName { get; set; }
|
||||
|
||||
public string DestinationFulfillmentCenterId
|
||||
{
|
||||
get { return destinationFulfillmentCenterId; }
|
||||
@@ -31,6 +34,7 @@ namespace bnhtrade.Core.Model.AmazonFBAInbound
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string ShipmentStatus
|
||||
{
|
||||
get
|
||||
@@ -47,7 +51,16 @@ namespace bnhtrade.Core.Model.AmazonFBAInbound
|
||||
shipmentStatus = status;
|
||||
}
|
||||
}
|
||||
public DateTime LastUpdatedUtc
|
||||
|
||||
public string ShipmentStockStatus { get; set; }
|
||||
|
||||
public int ShipmentStockStatusId
|
||||
{
|
||||
get { return shipmentStockStatusId.GetValueOrDefault(); }
|
||||
set { shipmentStockStatusId = value; }
|
||||
}
|
||||
|
||||
public DateTime LastUpdated
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -58,6 +71,7 @@ namespace bnhtrade.Core.Model.AmazonFBAInbound
|
||||
lastUpdatedUtc = DateTime.SpecifyKind(value, DateTimeKind.Utc);
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShipmentIsClosed
|
||||
{
|
||||
get
|
||||
@@ -72,6 +86,7 @@ namespace bnhtrade.Core.Model.AmazonFBAInbound
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<ShipmentItemInfo> ShipmentItemInfoList
|
||||
{
|
||||
get { return shipmentItemInfoList; }
|
||||
@@ -84,7 +99,7 @@ namespace bnhtrade.Core.Model.AmazonFBAInbound
|
||||
if (!item.IsSetAll())
|
||||
{ throw new Exception("Infomation missing from Shipment Item list"); }
|
||||
|
||||
if (item.AmazonShipmentId != AmazonShipmentId)
|
||||
if (item.AmazonShipmentId != FbaShipmentId)
|
||||
{ throw new Exception("Amazon shipment id in item list does not match header information."); }
|
||||
|
||||
if (skuCheck.ContainsKey(item.SKUNumber))
|
||||
@@ -104,6 +119,7 @@ namespace bnhtrade.Core.Model.AmazonFBAInbound
|
||||
shipmentItemInfoList = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsSetAll()
|
||||
{
|
||||
if (IsSetAllHeaderInfo() && IsSetListShipmentItemInfo())
|
||||
@@ -115,6 +131,7 @@ namespace bnhtrade.Core.Model.AmazonFBAInbound
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsSetAllHeaderInfo()
|
||||
{
|
||||
if (IsSetAmazonShipmentId()
|
||||
@@ -131,35 +148,52 @@ namespace bnhtrade.Core.Model.AmazonFBAInbound
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsSetAmazonShipmentId()
|
||||
{
|
||||
return AmazonShipmentId != null;
|
||||
return FbaShipmentId != null;
|
||||
}
|
||||
|
||||
public bool IsSetShipmentName()
|
||||
{
|
||||
return ShipmentName != null;
|
||||
}
|
||||
|
||||
public bool IsSetDestinationFulfillmentCenterId()
|
||||
{
|
||||
return DestinationFulfillmentCenterId != null;
|
||||
}
|
||||
|
||||
public bool IsSetLastUpdated()
|
||||
{
|
||||
return LastUpdatedUtc != default(DateTime);
|
||||
return LastUpdated != default(DateTime);
|
||||
}
|
||||
|
||||
public bool IsSetListShipmentItemInfo()
|
||||
{
|
||||
return ShipmentItemInfoList != null;
|
||||
}
|
||||
|
||||
public bool IsSetShipmentIsClosed()
|
||||
{
|
||||
return ShipmentStatus != null;
|
||||
}
|
||||
|
||||
public bool IsSetShipmentStatus()
|
||||
{
|
||||
return ShipmentStatus != null;
|
||||
}
|
||||
|
||||
public bool IsSetShipmentStockStatus()
|
||||
{
|
||||
return ShipmentStockStatus != null;
|
||||
}
|
||||
|
||||
public bool IsSetShipmentStockStatusId()
|
||||
{
|
||||
return shipmentStockStatusId != null;
|
||||
}
|
||||
|
||||
public ShipmentInfo()
|
||||
{
|
||||
shipmentStatusToIsClosed = new Dictionary<string, bool>();
|
||||
@@ -4,7 +4,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Model.AmazonFBAInbound
|
||||
namespace bnhtrade.Core.Model.AmazonFba
|
||||
{
|
||||
public class ShipmentItemInfo
|
||||
{
|
||||
@@ -18,14 +18,17 @@ namespace bnhtrade.Core.Model.AmazonFBAInbound
|
||||
/// Gets and sets the AmazonShipmentId property.
|
||||
/// </summary>
|
||||
public string AmazonShipmentId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the SKUNumber property.
|
||||
/// </summary>
|
||||
public string SKUNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the FulfillmentNetworkSKU property.
|
||||
/// </summary>
|
||||
public string AmazonFNSKU { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the QuantityAllocated property.
|
||||
/// </summary>
|
||||
@@ -34,6 +37,7 @@ namespace bnhtrade.Core.Model.AmazonFBAInbound
|
||||
get { return quantityAllocated; }
|
||||
set { quantityAllocated = value; isSetQuantityAllocated = true; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets and sets the QuantityReceived property.
|
||||
/// </summary>
|
||||
@@ -59,22 +63,27 @@ namespace bnhtrade.Core.Model.AmazonFBAInbound
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsSetAmazonShipmentId()
|
||||
{
|
||||
return AmazonShipmentId != null;
|
||||
}
|
||||
|
||||
public bool IsSetSKUNumber()
|
||||
{
|
||||
return SKUNumber != null;
|
||||
}
|
||||
|
||||
public bool IsSetFulfillmentNetworkSKU()
|
||||
{
|
||||
return AmazonFNSKU != null;
|
||||
}
|
||||
|
||||
public bool IsSetQuantityAllocated()
|
||||
{
|
||||
return isSetQuantityAllocated;
|
||||
}
|
||||
|
||||
public bool IsSetQuantityReceived()
|
||||
{
|
||||
return isSetQuantityReceived;
|
||||
98
src/bnhtrade.Core/Model/Data/DatabaseFileStream.cs
Normal file
98
src/bnhtrade.Core/Model/Data/DatabaseFileStream.cs
Normal file
@@ -0,0 +1,98 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Model.Data
|
||||
{
|
||||
public class DatabaseFileStream : IDisposable, IValidatableObject
|
||||
{
|
||||
[Required()]
|
||||
public Guid FileGUID { get; set; }
|
||||
|
||||
[Required()]
|
||||
public MemoryStream FileData { get; set; }
|
||||
|
||||
public bool IsSetFileData
|
||||
{
|
||||
get { return FileData != null; }
|
||||
}
|
||||
|
||||
[Required(), StringLength(3, MinimumLength = 3)]
|
||||
public string FileExtention { get; set; }
|
||||
|
||||
[Required(), Range(1, 2147483647)]
|
||||
public int FileSize { get; set; }
|
||||
|
||||
[Required(), StringLength(24, MinimumLength = 24)]
|
||||
public string FileMD5base64 { get; set; }
|
||||
|
||||
public string CalculateContentMD5(MemoryStream stream)
|
||||
{
|
||||
MD5CryptoServiceProvider provider = new MD5CryptoServiceProvider();
|
||||
byte[] hash = provider.ComputeHash(stream);
|
||||
return Convert.ToBase64String(hash);
|
||||
}
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
var resultList = new List<ValidationResult>();
|
||||
|
||||
if (IsSetFileData && FileData.Length == 0)
|
||||
{
|
||||
var validate = new ValidationResult("Stream is empty");
|
||||
resultList.Add(validate);
|
||||
}
|
||||
if (IsSetFileData && FileMD5base64 != new Logic.Utilities.CalculateMD5().Base64(FileData))
|
||||
{
|
||||
var validate = new ValidationResult("Calculated file MD5 hash does not match.");
|
||||
resultList.Add(validate);
|
||||
}
|
||||
|
||||
return resultList;
|
||||
}
|
||||
|
||||
#region IDisposable Support
|
||||
private bool disposedValue = false; // To detect redundant calls
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!disposedValue)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
// TODO: dispose managed state (managed objects).
|
||||
if (FileData != null)
|
||||
FileData.Dispose();
|
||||
}
|
||||
|
||||
// TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
|
||||
// TODO: set large fields to null.
|
||||
|
||||
disposedValue = true;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
|
||||
//~AmazonFeedSubmission()
|
||||
//{
|
||||
// // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
|
||||
// Dispose(false);
|
||||
//}
|
||||
|
||||
// This code added to correctly implement the disposable pattern.
|
||||
public void Dispose()
|
||||
{
|
||||
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
|
||||
Dispose(true);
|
||||
// TODO: uncomment the following line if the finalizer is overridden above.
|
||||
// GC.SuppressFinalize(this);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
124
src/bnhtrade.Core/Model/Export/AmazonFeedSubmission.cs
Normal file
124
src/bnhtrade.Core/Model/Export/AmazonFeedSubmission.cs
Normal file
@@ -0,0 +1,124 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Model.Export
|
||||
{
|
||||
public class AmazonFeedSubmission : IValidatableObject
|
||||
{
|
||||
//private int? exportAmazonFeedSubmissionId;
|
||||
private DateTime? submittedDate;
|
||||
private DateTime? startedProcessingDate;
|
||||
private DateTime? completedProcessingDate;
|
||||
|
||||
//public int ExportAmazonFeedSubmissionID
|
||||
//{
|
||||
// get { return exportAmazonFeedSubmissionId.GetValueOrDefault(); }
|
||||
// set { exportAmazonFeedSubmissionId = value; }
|
||||
//}
|
||||
|
||||
//public bool IsSetExportAmazonFeedSubmissionID
|
||||
//{
|
||||
// get { return exportAmazonFeedSubmissionId != null; }
|
||||
//}
|
||||
|
||||
[Required()]
|
||||
public string FeedType { get; set; }
|
||||
|
||||
public bool IsSetFeedType
|
||||
{
|
||||
get { return !string.IsNullOrWhiteSpace(FeedType); }
|
||||
}
|
||||
|
||||
[Required()]
|
||||
public string FeedSubmissionId { get; set; }
|
||||
|
||||
public bool IsSetFeedSubmissionId
|
||||
{
|
||||
get { return !string.IsNullOrWhiteSpace(FeedSubmissionId); }
|
||||
}
|
||||
|
||||
public DateTime SubmittedDate
|
||||
{
|
||||
get { return submittedDate.GetValueOrDefault(); }
|
||||
set { submittedDate = value; }
|
||||
}
|
||||
|
||||
public bool IsSetSubmittedDate
|
||||
{
|
||||
get { return submittedDate != null; }
|
||||
}
|
||||
|
||||
public string FeedProcessingStatus { get; set; }
|
||||
|
||||
public bool IsSetFeedProcessingStatus
|
||||
{
|
||||
get { return !string.IsNullOrWhiteSpace(FeedProcessingStatus); }
|
||||
}
|
||||
|
||||
public DateTime StartedProcessingDate
|
||||
{
|
||||
get { return startedProcessingDate.GetValueOrDefault(); }
|
||||
set { startedProcessingDate = value; }
|
||||
}
|
||||
|
||||
public bool IsSetStartedProcessingDate
|
||||
{
|
||||
get { return startedProcessingDate != null; }
|
||||
}
|
||||
|
||||
public DateTime CompletedProcessingDate
|
||||
{
|
||||
get { return completedProcessingDate.GetValueOrDefault(); }
|
||||
set { completedProcessingDate = value; }
|
||||
}
|
||||
|
||||
public bool IsSetCompletedProcessingDate
|
||||
{
|
||||
get { return completedProcessingDate != null; }
|
||||
}
|
||||
|
||||
public Model.Data.DatabaseFileStream File { get; set; }
|
||||
|
||||
public bool FileIsSet
|
||||
{
|
||||
get { return File != null; }
|
||||
}
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
var results = new List<ValidationResult>();
|
||||
|
||||
if (IsSetSubmittedDate && SubmittedDate == default(DateTime))
|
||||
results.Add(new ValidationResult("Submitted Date is systen default"));
|
||||
if (IsSetStartedProcessingDate && StartedProcessingDate == default(DateTime))
|
||||
results.Add(new ValidationResult("Started Processing Date is systen default"));
|
||||
if (IsSetCompletedProcessingDate && CompletedProcessingDate == default(DateTime))
|
||||
results.Add(new ValidationResult("Completed Processing Date is systen default"));
|
||||
|
||||
if (IsSetFeedProcessingStatus)
|
||||
{
|
||||
if (FeedProcessingStatus != "_DONE_" || FeedProcessingStatus != "_SUBMITTED_" || FeedProcessingStatus != "_IN_PROGRESS_" ||
|
||||
FeedProcessingStatus != "_UNCONFIRMED_" || FeedProcessingStatus != "_CANCELLED_" || FeedProcessingStatus != "_IN_SAFETY_NET_" ||
|
||||
FeedProcessingStatus != "_AWAITING_ASYNCHRONOUS_REPLY_")
|
||||
{
|
||||
results.Add(new ValidationResult("Invalid Feed Processing Status '" + FeedProcessingStatus + "'"));
|
||||
}
|
||||
}
|
||||
|
||||
if (FileIsSet)
|
||||
{
|
||||
Validator.TryValidateObject(
|
||||
File,
|
||||
new ValidationContext(File, null, null),
|
||||
results);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
||||
}
|
||||
136
src/bnhtrade.Core/Model/Export/AmazonIventoryLoaderFile.cs
Normal file
136
src/bnhtrade.Core/Model/Export/AmazonIventoryLoaderFile.cs
Normal file
@@ -0,0 +1,136 @@
|
||||
using CsvHelper.Configuration.Attributes;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Model.Export
|
||||
{
|
||||
public class AmazonIventoryLoaderFile : IValidatableObject
|
||||
{
|
||||
private bool isSetSetFulfillmentCenterId = false;
|
||||
|
||||
[Required()]
|
||||
[Name("sku")]
|
||||
public string Sku { get; set; }
|
||||
|
||||
[Name("product-id")]
|
||||
public string ProductId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// One of the following: 1=ASIN, 2=ISBN, 3=UPC, 4=EAN
|
||||
/// </summary>
|
||||
[Name("product-id-type")]
|
||||
[Range(1,4)]
|
||||
public int? ProductIdType { get; set; }
|
||||
|
||||
[Name("price")]
|
||||
[Range(0, double.MaxValue)]
|
||||
public decimal? Price { get; set; }
|
||||
|
||||
[Name("minimum-seller-allowed-price")]
|
||||
[Range(0, double.MaxValue)]
|
||||
public decimal? MinimumAllowedPrice { get; set; }
|
||||
|
||||
[Name("maximum-seller-allowed-price")]
|
||||
[Range(0, double.MaxValue)]
|
||||
public decimal? MaximumAllowedPrice { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 11=New, 1=Used Like New, 2=Used Very Good, 3=Used Good, 4=Used Acceptable,
|
||||
/// 5=Collectible Like New, 6=Collectible Very Good, 7=Collectible Good, 8=Collectible Acceptable, 9=Not used
|
||||
/// </summary>
|
||||
[Name("item-condition")]
|
||||
[Range(1,11)]
|
||||
public int? ItemCondition { get; set; }
|
||||
|
||||
[Name("quantity")]
|
||||
public int? Quantity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// a = update/add, d = delete, x = delete completely from system
|
||||
/// </summary>
|
||||
[MaxLength(1)]
|
||||
[Name("add-delete")]
|
||||
public string AddDelete { get; set; }
|
||||
|
||||
[Name("will-ship-internationally")]
|
||||
[BooleanTrueValues("y")]
|
||||
[BooleanFalseValues("n")]
|
||||
public bool? WillShipInternationally { get; set; }
|
||||
|
||||
[Name("expedited-shipping")]
|
||||
public string ExpeditedShipping { get; set; }
|
||||
|
||||
[Name("standard-plus")]
|
||||
public string StandardPlus { get; set; }
|
||||
|
||||
[MaxLength(2000)]
|
||||
[Name("item-note")]
|
||||
public string ItemNote { get; set; }
|
||||
|
||||
[Name("fulfillment-center-id")]
|
||||
public string FulfillmentCenterId { get; private set; }
|
||||
|
||||
[Name("merchant-shipping-group-name")]
|
||||
public string MerchantShippingGroupName { get; set; }
|
||||
|
||||
public void SetFulfillmentCenterId(bool IsFba)
|
||||
{
|
||||
isSetSetFulfillmentCenterId = true;
|
||||
if (IsFba)
|
||||
{
|
||||
FulfillmentCenterId = "AMAZON_EU";
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
var results = new List<ValidationResult>();
|
||||
|
||||
if (isSetSetFulfillmentCenterId == false)
|
||||
{
|
||||
results.Add(new ValidationResult("FulfillmentCenterId is not set."));
|
||||
}
|
||||
|
||||
if (ItemCondition.GetValueOrDefault() == 9 || ItemCondition.GetValueOrDefault() == 10)
|
||||
{
|
||||
results.Add(new ValidationResult("Invalid Item Condition id"));
|
||||
}
|
||||
|
||||
if (AddDelete != null && (AddDelete != "a" || AddDelete != "d" || AddDelete != "x"))
|
||||
{
|
||||
results.Add(new ValidationResult("Invalid AddDelete"));
|
||||
}
|
||||
|
||||
if (MaximumAllowedPrice != null || MinimumAllowedPrice != null)
|
||||
{
|
||||
if (MaximumAllowedPrice == null)
|
||||
{
|
||||
results.Add(new ValidationResult("If setting MinimumAllowedPrice, the MaximumAllowedPrice must also be set."));
|
||||
}
|
||||
|
||||
if (MinimumAllowedPrice == null)
|
||||
{
|
||||
results.Add(new ValidationResult("If setting MaximumAllowedPrice, the MinimumAllowedPrice must also be set."));
|
||||
}
|
||||
|
||||
if (Price == null)
|
||||
{
|
||||
results.Add(new ValidationResult("If setting MaximumAllowedPrice or MinimumAllowedPrice the Price must also be set."));
|
||||
}
|
||||
else if (MaximumAllowedPrice != null && MinimumAllowedPrice != null)
|
||||
{
|
||||
if (Price < MinimumAllowedPrice || Price > MaximumAllowedPrice)
|
||||
{
|
||||
results.Add(new ValidationResult("Price is ouside the bounds set by the MaximumAllowedPrice and MinimumAllowedPrice."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
||||
}
|
||||
53
src/bnhtrade.Core/Model/Product/CompetitivePrice.cs
Normal file
53
src/bnhtrade.Core/Model/Product/CompetitivePrice.cs
Normal 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.Product
|
||||
{
|
||||
public class CompetitivePrice
|
||||
{
|
||||
private bool? priceIsEstimated;
|
||||
private decimal? price = null;
|
||||
|
||||
public int ProductId { get; set; }
|
||||
|
||||
public int ConditionId { get; set; }
|
||||
|
||||
public decimal Price
|
||||
{
|
||||
get { return price.GetValueOrDefault(); }
|
||||
set { price = value; }
|
||||
}
|
||||
|
||||
public bool PriceIsSet
|
||||
{
|
||||
get { return price != null; }
|
||||
}
|
||||
|
||||
public DateTime PriceDatetime { get; set; }
|
||||
|
||||
public bool PriceIsEstimated
|
||||
{
|
||||
get { return priceIsEstimated.GetValueOrDefault(); }
|
||||
set { priceIsEstimated = value; }
|
||||
}
|
||||
|
||||
public bool PriceIsEstimatedIsSet
|
||||
{
|
||||
get { return priceIsEstimated != null; }
|
||||
}
|
||||
|
||||
public CompetitivePrice Clone()
|
||||
{
|
||||
var clone = new CompetitivePrice();
|
||||
clone.ConditionId = ConditionId;
|
||||
if (PriceIsSet) { clone.Price = Price; }
|
||||
clone.PriceDatetime = PriceDatetime;
|
||||
if (PriceIsEstimatedIsSet) { clone.priceIsEstimated = PriceIsEstimated; }
|
||||
clone.ProductId = ProductId;
|
||||
return clone;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,60 +9,95 @@ namespace bnhtrade.Core.Model.Sku
|
||||
public class Sku
|
||||
{
|
||||
private bool? isActive;
|
||||
public string ConditionModelPlaceholder
|
||||
private int? conditionId;
|
||||
private int? productId;
|
||||
|
||||
public int ConditionId
|
||||
{
|
||||
get { return conditionId.GetValueOrDefault(); }
|
||||
set { conditionId = value; }
|
||||
}
|
||||
|
||||
public bool ConditionIdIsSet
|
||||
{
|
||||
get { return conditionId != null; }
|
||||
}
|
||||
|
||||
public string ConditionTitle
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
public string ProductModelPlaceholder
|
||||
|
||||
public bool ConditionTitleIsSet
|
||||
{
|
||||
get { return ConditionTitle != null; }
|
||||
}
|
||||
|
||||
public int ProductId
|
||||
{
|
||||
get { return productId.GetValueOrDefault(); }
|
||||
set { productId = value; }
|
||||
}
|
||||
|
||||
public bool ProductIdIsSet
|
||||
{
|
||||
get { return productId != null; }
|
||||
}
|
||||
|
||||
public string ProductTitle
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public bool ProductTitleIsSet
|
||||
{
|
||||
get { return ProductTitle != null; }
|
||||
}
|
||||
|
||||
public string SkuNumber
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
public Account.TaxCode TaxCode
|
||||
|
||||
public bool SkuNumberIsSet
|
||||
{
|
||||
get { return SkuNumber != null; }
|
||||
}
|
||||
|
||||
public string TaxCode
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public bool TaxCodeIsSet
|
||||
{
|
||||
get { return TaxCode != null; }
|
||||
}
|
||||
|
||||
public string AmazonFNSKU
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public bool AmazonFNSKUIsSet
|
||||
{
|
||||
get { return AmazonFNSKU != null; }
|
||||
}
|
||||
|
||||
public bool IsActive
|
||||
{
|
||||
get { return (bool)isActive; }
|
||||
set { isActive = value; }
|
||||
}
|
||||
public bool IsSetConditionModelPlaceholder
|
||||
{
|
||||
get { return ConditionModelPlaceholder != null; }
|
||||
}
|
||||
public bool IsSetProductModelPlaceholder
|
||||
{
|
||||
get { return ProductModelPlaceholder != null; }
|
||||
}
|
||||
public bool IsSetSkuNumber
|
||||
{
|
||||
get { return SkuNumber != null; }
|
||||
}
|
||||
public bool IsSetTaxCode
|
||||
{
|
||||
get { return TaxCode != null; }
|
||||
}
|
||||
public bool IsSetAmazonFNSKU
|
||||
{
|
||||
get { return AmazonFNSKU != null; }
|
||||
}
|
||||
public bool IsSetIsActive
|
||||
|
||||
public bool IsActiveIsSet
|
||||
{
|
||||
get { return isActive != null; }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
35
src/bnhtrade.Core/Model/SKU/SkuConditionInfo.cs
Normal file
35
src/bnhtrade.Core/Model/SKU/SkuConditionInfo.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Model.Sku
|
||||
{
|
||||
public class SkuConditionInfo
|
||||
{
|
||||
public int SkuConditionId { get; set; }
|
||||
|
||||
public string SkuConditionNumber { get; set; }
|
||||
|
||||
public string TitleShort { get; set; }
|
||||
|
||||
public string Description { get; set; }
|
||||
|
||||
public bool IsFixedPrice { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Can be used to estimate a competitve price from 'New' condition competitive price
|
||||
/// </summary>
|
||||
public decimal CompetitivePriceMultiplier { get; set; }
|
||||
|
||||
public string AmazonBaseType { get; set; }
|
||||
|
||||
public int AmazonIdentifier { get; set; }
|
||||
|
||||
public string ConditionNoteDefault { get; set; }
|
||||
|
||||
public string RepricerStrategy { get; set; }
|
||||
}
|
||||
}
|
||||
41
src/bnhtrade.Core/Model/Sku/Price/DetailRequest.cs
Normal file
41
src/bnhtrade.Core/Model/Sku/Price/DetailRequest.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Model.Sku.Price
|
||||
{
|
||||
public class DetailRequest
|
||||
{
|
||||
public int SkuId { get; set; }
|
||||
|
||||
public int OrderChannelId { get; set; }
|
||||
|
||||
public int OrderChannelQuantity { get; set; }
|
||||
|
||||
public decimal OrderChannelFeeFixed { get; set; }
|
||||
|
||||
public decimal OrderChannelFeeMargin { get; set; }
|
||||
|
||||
public decimal UnitAvgCost { get; set; }
|
||||
|
||||
public int InventoryAgeMin { get; set; }
|
||||
|
||||
public int InventoryAgeMax { get; set; }
|
||||
|
||||
public int PriceMin_SkuPriceType { get; set; }
|
||||
|
||||
public decimal? PriceMinAmountManual { get; set; }
|
||||
|
||||
public int? PriceMinStoredInt { get; set; }
|
||||
|
||||
public int PriceMax_SkuPriceType { get; set; }
|
||||
|
||||
public bool PriceMaxBaseMultipilerReset { get; set; } = false;
|
||||
|
||||
public decimal? PriceMaxAmountManual { get; set; }
|
||||
|
||||
public int? PriceMaxStoredInt { get; set; }
|
||||
}
|
||||
}
|
||||
71
src/bnhtrade.Core/Model/Sku/Price/DetailResponce.cs
Normal file
71
src/bnhtrade.Core/Model/Sku/Price/DetailResponce.cs
Normal file
@@ -0,0 +1,71 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Model.Sku.Price
|
||||
{
|
||||
public class DetailResponce
|
||||
{
|
||||
public int SkuId { get; set; }
|
||||
|
||||
public int OrderChannelId { get; set; }
|
||||
|
||||
public int OrderChannelQuantity { get; set; }
|
||||
|
||||
public decimal UnitAvgCost { get; set; }
|
||||
|
||||
public int InventoryAgeMin { get; set; }
|
||||
|
||||
public int InventoryAgeMax { get; set; }
|
||||
|
||||
public int PriceMin_SkuPriceType { get; set; }
|
||||
|
||||
public decimal PriceMinAmountAuto { get; set; }
|
||||
|
||||
public decimal? PriceMinAmountManual { get; set; }
|
||||
|
||||
public int? PriceMinStoredInt { get; set; }
|
||||
|
||||
public decimal PriceMinAmountFinalFee { get; set; }
|
||||
|
||||
public decimal PriceMinAmountFinalTax { get; set; }
|
||||
|
||||
public decimal PriceMinAmountFinal { get; set; }
|
||||
|
||||
public int PriceMax_SkuPriceType { get; set; }
|
||||
|
||||
public decimal PriceMaxAmountAutoBase { get; set; }
|
||||
|
||||
public decimal PriceMaxAmountAutoMultiplier { get; set; }
|
||||
|
||||
public DateTime PriceMaxAmountAutoModified { get; set; }
|
||||
|
||||
public decimal? PriceMaxAmountManual { get; set; }
|
||||
|
||||
public int? PriceMaxStoredInt { get; set; }
|
||||
|
||||
public decimal PriceMaxAmountFinal { get; set; }
|
||||
|
||||
public DateTime PriceCreated { get; set; }
|
||||
|
||||
public string TypeTitle { get; set; }
|
||||
|
||||
public bool ReviewRequired
|
||||
{
|
||||
get
|
||||
{
|
||||
if (TypeTitle.Substring(0, 15) == "Review Required")
|
||||
{ return true; }
|
||||
else
|
||||
{ return false; }
|
||||
}
|
||||
}
|
||||
|
||||
public bool RequireAmountManual { get; set; }
|
||||
|
||||
public bool RequireStordedInt { get; set; }
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user