mirror of
https://github.com/stokebob/bnhtrade.git
synced 2026-05-18 19:48:23 +00:00
Compare commits
80 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6151652b9f | |||
| db9a2b9ccc | |||
| 8e8c4138e3 | |||
| f921e79671 | |||
| db8eafe571 | |||
| b2bcb72469 | |||
| 80dfc2a9d7 | |||
| c28d2c6060 | |||
| ecf48ba8b4 | |||
| 2d751ebf80 | |||
| afd4bae10e | |||
| be9944f066 | |||
| 7a28e2cc66 | |||
| 97b945e0cb | |||
| ee487db21f | |||
| d4170d2b80 | |||
| e2af1e4f99 | |||
| eb959dd6e2 | |||
| c0f7f1a476 | |||
| 8c3b00c75c | |||
| 479acecdbc | |||
| 5cd653d700 | |||
| 5900a6e6e4 | |||
| 29f9fae508 | |||
| 8bbf885a48 | |||
| 332a25aec8 | |||
| 0fe8bbd91b | |||
| 413ca43cfe | |||
| 14d5b78d44 | |||
| 325d6d3bcd | |||
| 25c84525c2 | |||
| d8454bc031 | |||
| a3af86db46 | |||
| 30174290cf | |||
| cb54dc364c | |||
| ea0a52b2a0 | |||
| 8e7cd00b74 | |||
| 7465940d48 | |||
| c8689e3bba | |||
| 5446c995d2 | |||
| f9b38a98b1 | |||
| 7a12b49b44 | |||
| a0c669f1d4 | |||
| a865abb788 | |||
| 1c7ed5da93 | |||
| 0fb45b8090 | |||
| fb058fc22f | |||
| a56a97031a | |||
| 960579b0b2 | |||
| c2082acf8e | |||
| daa4e91e81 | |||
| 97fff18e7e | |||
| b790a7b642 | |||
| 270eebca9a | |||
| 91ef9acc78 | |||
| 2f919d7b5a | |||
| f8452d274a | |||
| c1e6da7a6f | |||
| f1d7119306 | |||
| a7bc00e73a | |||
| e054278cdd | |||
| d8ebd29c47 | |||
| b266e1cde0 | |||
| ddd2b62743 | |||
| cc2534a3e1 | |||
| f95c1d7508 | |||
| 39ab7922d4 | |||
| 8cd27646cd | |||
| dcd32b76fa | |||
| 9ec07b8703 | |||
| aeef35b57c | |||
| 738f87f988 | |||
| d6b198777f | |||
| 3a53350f85 | |||
| 43d61c2ef8 | |||
| 56647c7648 | |||
| 7e50da21e7 | |||
| bed529e1c8 | |||
| a342f8adc6 | |||
| 116aedb897 |
+4
-1
@@ -1,6 +1,8 @@
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
*.local.config
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
@@ -260,4 +262,5 @@ paket-files/
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
*.pyc
|
||||
/src/bnhtrade.ScheduledTasks/app.local.config
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
[submodule "lib/test"]
|
||||
path = lib/test
|
||||
url = https://github.com/abuzuhri/Amazon-SP-API-CSharp
|
||||
[submodule "src/Amazon-SP-API-CSharp"]
|
||||
path = src/Amazon-SP-API-CSharp
|
||||
url = https://github.com/abuzuhri/Amazon-SP-API-CSharp
|
||||
@@ -1 +0,0 @@
|
||||
Build outputs go here. Doing a build.cmd/build.sh generates artifacts here (nupkgs, dlls, pdbs, etc.)
|
||||
+14
-12
@@ -1,20 +1,18 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.27428.2037
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.9.34728.123
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{CF330C30-8231-4D54-B60C-FF0644713502}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
build\bnhtrade.ComTypeLib.RegAsmInstall.bat = build\bnhtrade.ComTypeLib.RegAsmInstall.bat
|
||||
build\bnhtrade.ComTypeLib.RegAsmRefresh.bat = build\bnhtrade.ComTypeLib.RegAsmRefresh.bat
|
||||
build\bnhtrade.ComTypeLib.RegAsmUninstall.bat = build\bnhtrade.ComTypeLib.RegAsmUninstall.bat
|
||||
EndProjectSection
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{CF330C30-8231-4D54-B60C-FF0644713502}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "bnhtrade.ScheduledTasks", "src\bnhtrade.ScheduledTasks\bnhtrade.ScheduledTasks.csproj", "{5D6E1D66-3901-4340-95C6-EE65051AB623}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "bnhtrade.ScheduledTasks", "src\bnhtrade.ScheduledTasks\bnhtrade.ScheduledTasks.csproj", "{5D6E1D66-3901-4340-95C6-EE65051AB623}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "bnhtrade.Core", "src\bnhtrade.Core\bnhtrade.Core.csproj", "{339D7413-3DA7-46EA-A55C-255A9A6B95EB}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "bnhtrade.Core", "src\bnhtrade.Core\bnhtrade.Core.csproj", "{339D7413-3DA7-46EA-A55C-255A9A6B95EB}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "bnhtrade.ComTypeLib", "src\bnhtrade.ComTypeLib\bnhtrade.ComTypeLib.csproj", "{C3405E9D-B47A-4569-B6A3-BC9E7AA71EE5}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "bnhtrade.ComTypeLib", "src\bnhtrade.ComTypeLib\bnhtrade.ComTypeLib.csproj", "{C3405E9D-B47A-4569-B6A3-BC9E7AA71EE5}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "lib", "lib", "{3D90C0F5-02E7-44E5-A89D-F5E217C6602F}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "bnhtrade.gui", "src\bnhtrade.gui\bnhtrade.gui.csproj", "{92788EE6-6B75-45BE-A0F3-9E4F51CDEB3F}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
@@ -34,6 +32,10 @@ Global
|
||||
{C3405E9D-B47A-4569-B6A3-BC9E7AA71EE5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C3405E9D-B47A-4569-B6A3-BC9E7AA71EE5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C3405E9D-B47A-4569-B6A3-BC9E7AA71EE5}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{92788EE6-6B75-45BE-A0F3-9E4F51CDEB3F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{92788EE6-6B75-45BE-A0F3-9E4F51CDEB3F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{92788EE6-6B75-45BE-A0F3-9E4F51CDEB3F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{92788EE6-6B75-45BE-A0F3-9E4F51CDEB3F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
Build customizations (custom msbuild files/psake/fake/albacore/etc) scripts
|
||||
@@ -1,28 +0,0 @@
|
||||
@set batchpath=%~dp0
|
||||
@set dllpath=%batchpath%
|
||||
::bnhtrade Database Client\bin\Release\
|
||||
|
||||
@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"
|
||||
|
||||
@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"
|
||||
|
||||
@c:
|
||||
@cd\Windows\Microsoft.NET\Framework\v4.*
|
||||
rem regasm.exe /codebase /tlb "bnhtrade.Core.dll"
|
||||
regasm.exe /codebase /tlb "bnhtradeCOM.dll"
|
||||
rem regasm.exe /codebase /tlb "ABrain.AmazonMWS.dll"
|
||||
|
||||
@cd\Windows\Microsoft.NET\Framework64\v4.*
|
||||
rem regasm.exe /codebase /tlb "bnhtrade.Core.dll"
|
||||
regasm.exe /codebase /tlb "bnhtradeCOM.dll"
|
||||
rem regasm.exe /codebase /tlb "ABrain.AmazonMWS.dll"
|
||||
|
||||
@echo.
|
||||
@echo Finished running regasm install script.
|
||||
@echo.
|
||||
@rem if no arguments passed, pause
|
||||
@IF "%~1"=="" @pause
|
||||
@@ -1,7 +0,0 @@
|
||||
@set mypath=%~dp0
|
||||
|
||||
call "%mypath%bnhtrade.ComTypeLib.RegAsmUninstall.bat" nopause
|
||||
call "%mypath%bnhtrade.ComTypeLib.RegAsmInstall.bat" nopause
|
||||
@echo Completed regasm refresh
|
||||
@echo.
|
||||
@pause
|
||||
@@ -1,29 +0,0 @@
|
||||
@c:
|
||||
@cd\Windows\Microsoft.NET\Framework\v4.*
|
||||
rem regasm.exe /u "%SYSTEMROOT%\System32\bnhtrade.Core.dll"
|
||||
regasm.exe /u "%SYSTEMROOT%\System32\bnhtradeCOM.dll"
|
||||
rem regasm.exe /u "%SYSTEMROOT%\System32\ABrain.AmazonMWS.dll"
|
||||
@cd\Windows\Microsoft.NET\Framework64\v4.*
|
||||
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.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\ABrain.AmazonMWS.tlb"
|
||||
|
||||
@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\ABrain.AmazonMWS.tlb"
|
||||
|
||||
@echo.
|
||||
@echo Finished running regasm uninstall script.
|
||||
@rem if no arguments passed, pause
|
||||
@echo.
|
||||
@IF "%~1"=="" @pause
|
||||
@@ -1 +0,0 @@
|
||||
Documentation stuff, markdown files, help files etc.
|
||||
@@ -1 +0,0 @@
|
||||
Things that can NEVER exist in a nuget package
|
||||
@@ -35,27 +35,26 @@ namespace bnhtrade.ComTypeLib
|
||||
public int AccountJournalInsert(ConnectionCredential sqlConnCred, int journalTypeId, DateTime entryDate,
|
||||
string currencyCode, [MarshalAs(UnmanagedType.Currency)] decimal amount, int debitAccountId = 0, int creditAccountId = 0, bool lockEntry = false)
|
||||
{
|
||||
return Core.Account.AccountQuery.AccountJournalInsert(sqlConnCred.ConnectionString, journalTypeId, entryDate,
|
||||
return new Core.Logic.Account.AccountJournalService().JournalInsert(journalTypeId, entryDate,
|
||||
currencyCode, amount, debitAccountId, creditAccountId, lockEntry);
|
||||
}
|
||||
|
||||
public bool AccountJournalDelete(ConnectionCredential sqlConnCred, int accountJournalId)
|
||||
{
|
||||
return Core.Account.AccountQuery.AccountJournalDelete(sqlConnCred.ConnectionString, accountJournalId);
|
||||
return new Core.Logic.Account.AccountJournalService().DeleteJournal(accountJournalId);
|
||||
}
|
||||
|
||||
[return: MarshalAs(UnmanagedType.Currency)]
|
||||
public decimal CurrencyConvertToGbp(ConnectionCredential sqlConnCred, string currencyCode,
|
||||
[MarshalAs(UnmanagedType.Currency)] decimal amount, DateTime conversionDate)
|
||||
{
|
||||
return Core.Account.AccountQuery.CurrencyConvertToGbp(sqlConnCred.ConnectionString, currencyCode, amount, conversionDate);
|
||||
return new Core.Logic.Account.CurrencyService().CurrencyConvertToGbp(currencyCode, amount, conversionDate);
|
||||
}
|
||||
|
||||
public int CurrencyExchangeRateInsert(ConnectionCredential sqlConnCred, int exchangeRateSource, string currencyCode,
|
||||
[MarshalAs(UnmanagedType.Currency)] decimal currencyUnitsPerGbp, DateTime periodStart, DateTime periodEnd, bool checkOverride = false)
|
||||
{
|
||||
return Core.Account.AccountQuery.CurrencyExchangeRateInsert(sqlConnCred.ConnectionString, exchangeRateSource, currencyCode,
|
||||
currencyUnitsPerGbp, periodStart, periodEnd, checkOverride);
|
||||
throw new Exception("This function has been retired, now handled by nightly routines");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ using System.Runtime.InteropServices;
|
||||
namespace bnhtrade.ComTypeLib.Credential
|
||||
{
|
||||
[ComVisible(true)]
|
||||
[Guid("33376d64-a9aa-41e5-b2e7-59f332f020f2")]
|
||||
[Guid("dd956394-0622-49fa-8c26-1ec82e70d03d")]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
|
||||
public interface IConnectionCredential
|
||||
{
|
||||
@@ -15,7 +15,7 @@ namespace bnhtrade.ComTypeLib.Credential
|
||||
|
||||
[ComVisible(true)]
|
||||
[ClassInterface(ClassInterfaceType.None)]
|
||||
[Guid("24310731-61ad-4f77-92cf-018f5aaacf32")]
|
||||
[Guid("de81b703-8d55-4dbc-a561-2317a9068a6f")]
|
||||
[ProgId("bnhtrade.ConnectionCredential")]
|
||||
public class ConnectionCredential : IConnectionCredential
|
||||
{
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using bnhtrade.ComTypeLib.Credential;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Core.EbayQuery;
|
||||
using System.IO;
|
||||
using bnhtrade.Core.EbayQuery;
|
||||
|
||||
namespace bnhtrade.ComTypeLib.Ebay
|
||||
{
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<ClearOutputDirectory>True</ClearOutputDirectory>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<!-- ILRepack -->
|
||||
<Target Name="ILRepacker" AfterTargets="Build">
|
||||
<ItemGroup>
|
||||
<InputAssemblies Include="$(OutputPath)*.dll" />
|
||||
<!--ILRepack started complaining it can't resolve CSVHelper when building the project, hence the line below-->
|
||||
<!--It's a hack, and will need updating when CSVHelper is updated, but I can't figure it out-->
|
||||
<!--InputAssemblies Include="C:\Users\Bobbie\.nuget\packages\csvhelper\33.0.1\lib\net8.0\CsvHelper.dll"/-->
|
||||
</ItemGroup>
|
||||
|
||||
<ILRepack
|
||||
AllowDuplicateResources="false"
|
||||
DebugInfo="true"
|
||||
Internalize="true"
|
||||
InternalizeExclude="$(AssemblyName).dll"
|
||||
InputAssemblies="@(InputAssemblies)"
|
||||
OutputFile="$(TargetPath)"
|
||||
Parallel="true"
|
||||
TargetKind="Dll"
|
||||
LibraryPath="$(OutputPath)"
|
||||
/>
|
||||
</Target>
|
||||
<!-- /ILRepack -->
|
||||
</Project>
|
||||
@@ -1,4 +1,5 @@
|
||||
using bnhtrade.ComTypeLib.Credential;
|
||||
using bnhtrade.Core.Test.Account;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -13,12 +14,8 @@ namespace bnhtrade.ComTypeLib
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
|
||||
public interface IProduct
|
||||
{
|
||||
string ReturnStringValue(string stringValue);
|
||||
|
||||
double ReturnDateValueAsDouble(string stringValue);
|
||||
|
||||
int ProductGetProductIdByCatId(int catId, ConnectionCredential sqlConnCred);
|
||||
|
||||
string ProductCompetitivePriceGet(int productId, int conditionId, ConnectionCredential sqlConnCred);
|
||||
|
||||
int ProductCompetitivePriceSet(int productId, int conditionId, [MarshalAs(UnmanagedType.Currency)] decimal price, bool isBuyBoxPrice, DateTime priceDate, ConnectionCredential sqlConnCred);
|
||||
@@ -32,60 +29,41 @@ namespace bnhtrade.ComTypeLib
|
||||
[ProgId("bnhtrade.Product")]
|
||||
public class Product : IProduct
|
||||
{
|
||||
[ComVisible(false)]
|
||||
[return: MarshalAs(UnmanagedType.BStr)]
|
||||
public string ReturnStringValue(string stringValue)
|
||||
{
|
||||
return "kj;lk1";
|
||||
}
|
||||
|
||||
[ComVisible(false)]
|
||||
public double ReturnDateValueAsDouble(string stringValue)
|
||||
{
|
||||
DateTime theTimeNow = DateTime.UtcNow;
|
||||
return theTimeNow.ToOADate();
|
||||
// back in vba use the CDate(return) function to convert the double
|
||||
// vba Date --> c# DateTime works without marshalling
|
||||
}
|
||||
|
||||
public int ProductGetProductIdByCatId(int catId, ConnectionCredential sqlConnCred)
|
||||
{
|
||||
var request = new Core.Product.ProductQuery();
|
||||
int? result = request.ProductGetProductIdByCatId(sqlConnCred.ConnectionString, catId);
|
||||
if (result == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return result.Value;
|
||||
}
|
||||
// vba Date --> c# DateTime works without marshalling.
|
||||
}
|
||||
|
||||
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().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()
|
||||
.ProductCompetitivePriceSet(productId, conditionId, price, isBuyBoxPrice, priceDateLocal);
|
||||
}
|
||||
|
||||
public void ProductUpdateAmazonEstimateFee(ConnectionCredential sqlConnCred, object inputList)
|
||||
{
|
||||
// get com object in string array
|
||||
var inputTuple = new List<(string asin, decimal priceToEstimate)>();
|
||||
//var inputTuple = new Dictionary<string, decimal>();
|
||||
var inputTuple = new List<(string asin, decimal listingPrice)>();
|
||||
var getArray = new Utility.LoadComObjextIntoStringArray();
|
||||
string[] stringArray = getArray.LoadComObjectIntoStringArray(inputList);
|
||||
|
||||
@@ -96,16 +74,13 @@ namespace bnhtrade.ComTypeLib
|
||||
{
|
||||
throw new Exception("Split function failed on line: " + item);
|
||||
}
|
||||
var tempTuple = (split[0], decimal.Parse(split[1]));
|
||||
inputTuple.Add(tempTuple);
|
||||
var asin = split[0];
|
||||
var listingPrice = decimal.Parse(split[1]);
|
||||
var t = (asin, listingPrice);
|
||||
inputTuple.Add(t);
|
||||
}
|
||||
|
||||
Core.Product.ProductQuery.ProductUpdateAmazonEstimateFee(sqlConnCred.ConnectionString, inputTuple);
|
||||
new Core.Logic.Product.AmazonEstimateFee().UpdateDatabase(inputTuple);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,36 +1,13 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("bnhtrade COM Type Library")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("bnhtrade")]
|
||||
[assembly: AssemblyProduct("bnhtradeCOMAsm")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2019")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
[assembly: ComVisible(true)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("c3405e9d-b47a-4569-b6a3-bc9e7aa71ee5")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
|
||||
@@ -35,33 +35,30 @@ namespace bnhtrade.ComTypeLib.Purchase
|
||||
string currencyCode, [MarshalAs(UnmanagedType.Currency)] decimal amountNet,
|
||||
DateTime entryDate)
|
||||
{
|
||||
Core.Purchase.PurchaseQuery.WIP_PurchaseLineTransactionNetInsert(sqlConnCred.ConnectionString,
|
||||
purchaseLineId, currencyCode, amountNet, entryDate);
|
||||
new Core.Logic.Purchase.PurchaseService().WIP_PurchaseLineTransactionNetInsert(purchaseLineId, currencyCode, amountNet, entryDate);
|
||||
}
|
||||
|
||||
public void PurchaseLineTransactionNetUpdate(ConnectionCredential sqlConnCred, int accountJouranlId,
|
||||
string currencyCode, [MarshalAs(UnmanagedType.Currency)] decimal amountNet, int debitAccountId)
|
||||
{
|
||||
Core.Purchase.PurchaseQuery.WIP_PurchaseLineTransactionNetUpdate(sqlConnCred.ConnectionString,
|
||||
accountJouranlId, currencyCode, amountNet, debitAccountId);
|
||||
new Core.Logic.Purchase.PurchaseService().WIP_PurchaseLineTransactionNetUpdate(accountJouranlId, currencyCode, amountNet, debitAccountId);
|
||||
}
|
||||
|
||||
public void PurchaseLineTransactionDelete(ConnectionCredential sqlConnCred, int purchaseLineId, int accountJournalId)
|
||||
{
|
||||
Core.Purchase.PurchaseQuery.WIP_PurchaseLineTransactionDelete(sqlConnCred.ConnectionString, purchaseLineId, accountJournalId);
|
||||
new Core.Logic.Purchase.PurchaseService().WIP_PurchaseLineTransactionDelete(purchaseLineId, accountJournalId);
|
||||
}
|
||||
|
||||
public int PurchaseLineTransactionStockInsert(ConnectionCredential sqlConnCred, int accountJournalId,
|
||||
string currencyCode, [MarshalAs(UnmanagedType.Currency)] decimal amount, int quantity, int productId, int conditionId,
|
||||
int accountTaxCodeId, int stockDebitStatusId)
|
||||
{
|
||||
return Core.Stock.StockCreate.WIP_StockInsertPurchase(sqlConnCred.ConnectionString, productId, conditionId, accountTaxCodeId, accountJournalId, quantity, stockDebitStatusId);
|
||||
return new Core.Logic.Inventory.StockService().WIP_StockInsertPurchase(productId, conditionId, accountTaxCodeId, accountJournalId, quantity, stockDebitStatusId);
|
||||
}
|
||||
|
||||
public void PurchaseLineTransactionStockDelete(ConnectionCredential sqlConnCred, int stockId)
|
||||
{
|
||||
Core.Stock.StockCreate.WIP_StockDeletePurchase(sqlConnCred.ConnectionString, stockId);
|
||||
new Core.Logic.Inventory.StockService().WIP_StockDeletePurchase(stockId);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
To setup on new computer:
|
||||
|
||||
1. Add the app.local.config to the users ..\AppData\Local\bnhtrade\ folder (create the bnhtrade folder)
|
||||
|
||||
2. CLone bnhtrade solution from the repo
|
||||
|
||||
3. Build bnhtradeCOM project
|
||||
|
||||
4. Register the COM host for COM. With an elevated prompt, navigate to the build directory and run "regsvr32 bnhtradeCOM.comhost.dll"
|
||||
|
||||
5.
|
||||
@@ -27,7 +27,11 @@ namespace bnhtrade.ComTypeLib
|
||||
|
||||
object ReconcileStockTransactions(ConnectionCredential sqlConnCred);
|
||||
|
||||
void UnReconcileSkuTransaction(ConnectionCredential sqlConnCred, int skuTransactionId);
|
||||
|
||||
bool StockJournalConsistencyCheck(ConnectionCredential sqlConnCred, int stockId);
|
||||
|
||||
void SkuTransactionAdd(ConnectionCredential sqlConnCred, int quantity, string skuNumber, string transactionTypeCode, DateTime transactionDate);
|
||||
}
|
||||
|
||||
[ComVisible(true)]
|
||||
@@ -39,42 +43,43 @@ namespace bnhtrade.ComTypeLib
|
||||
{
|
||||
public int StockInsertPurchase(ConnectionCredential sqlConnCred, int productId, int conditionId, int accountTaxCodeId, int accountJournalId, int quantity, int statusDebitId)
|
||||
{
|
||||
return Core.Stock.StockCreate.WIP_StockInsertPurchase(sqlConnCred.ConnectionString, productId, conditionId, accountTaxCodeId, accountJournalId, quantity, statusDebitId);
|
||||
return new Core.Logic.Inventory.StockService().WIP_StockInsertPurchase(productId, conditionId, accountTaxCodeId, accountJournalId, quantity, statusDebitId);
|
||||
}
|
||||
|
||||
public int StockInsertOwnerIntroduced(ConnectionCredential sqlConnCred, [MarshalAs(UnmanagedType.Currency)] decimal amount, int quantity, int productId, int conditionId, int accountTaxCodeId, DateTime entryDate, int debitStatusId)
|
||||
{
|
||||
return Core.Stock.StockCreate.WIP_StockInsertOwnerIntroduced(sqlConnCred.ConnectionString, amount, quantity, productId, conditionId, accountTaxCodeId, entryDate, debitStatusId);
|
||||
return new Core.Logic.Inventory.StockService().WIP_StockInsertOwnerIntroduced(amount, quantity, productId, conditionId, accountTaxCodeId, entryDate, debitStatusId);
|
||||
}
|
||||
|
||||
public void StockDeletePurchase(ConnectionCredential sqlConnCred, int stockId)
|
||||
{
|
||||
Core.Stock.StockCreate.WIP_StockDeletePurchase(sqlConnCred.ConnectionString, stockId);
|
||||
new Core.Logic.Inventory.StockService().WIP_StockDeletePurchase(stockId);
|
||||
}
|
||||
|
||||
public void StockDeleteOwnerIntroduced(ConnectionCredential sqlConnCred, int stockId)
|
||||
{
|
||||
Core.Stock.StockCreate.WIP_StockDeleteOwnerIntroduced(sqlConnCred.ConnectionString, stockId);
|
||||
new Core.Logic.Inventory.StockService().WIP_StockDeleteOwnerIntroduced(stockId);
|
||||
}
|
||||
|
||||
public int StockReallocate(ConnectionCredential sqlConnCred, int stockId, int quantity, int debitStatusId, int creditStatusId, DateTime entryDate)
|
||||
{
|
||||
entryDate = DateTime.SpecifyKind(entryDate, DateTimeKind.Utc);
|
||||
|
||||
return Core.Stock.StockJournal.StockReallocateByStockId(sqlConnCred.ConnectionString, 4, stockId, quantity, debitStatusId, creditStatusId, entryDate);
|
||||
return new Core.Logic.Stock.StatusReallocate().ByStockId(entryDate, 4, stockId, quantity, debitStatusId, creditStatusId);
|
||||
}
|
||||
|
||||
public void StockJournalDelete(ConnectionCredential sqlConnCred, int stockJournalId)
|
||||
{
|
||||
Core.Stock.StockJournal.StockJournalDelete(sqlConnCred.ConnectionString, stockJournalId);
|
||||
new Core.Logic.Inventory.StockJournalService().StockJournalDelete(stockJournalId);
|
||||
}
|
||||
|
||||
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();
|
||||
result.ReconcileStockTransactions(false);
|
||||
|
||||
//ReconcileStockTransactionsResult returnObject = new ReconcileStockTransactionsResult();
|
||||
|
||||
@@ -106,20 +111,39 @@ 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.CurrentTransactionTypeCode;
|
||||
returnArray[4] = result.LastItemDateTime;
|
||||
returnArray[5] = result.ItemsCompleted;
|
||||
returnArray[6] = result.ItemsRemaining;
|
||||
return returnArray;
|
||||
|
||||
//return returnObject;
|
||||
}
|
||||
|
||||
public void UnReconcileSkuTransaction(ConnectionCredential sqlConnCred, int skuTransactionId)
|
||||
{
|
||||
new Core.Logic.Stock.SkuTransactionReconcile().UnReconcileTransaction(skuTransactionId);
|
||||
}
|
||||
|
||||
public bool StockJournalConsistencyCheck(ConnectionCredential sqlConnCred, int stockId)
|
||||
{
|
||||
return Core.Stock.StockJournal.WIP_StockJournalConsistencyCheck(sqlConnCred.ConnectionString, stockId, null);
|
||||
return new Core.Logic.Inventory.StockJournalService().WIP_StockJournalConsistencyCheck(stockId, null);
|
||||
}
|
||||
|
||||
public void SkuTransactionAdd(ConnectionCredential sqlConnCred, int quantity, string skuNumber, string transactionTypeCode, DateTime transactionDate)
|
||||
{
|
||||
var trans = new bnhtrade.Core.Model.Stock.SkuTransactionCreate(
|
||||
transactionDate
|
||||
, transactionTypeCode
|
||||
, null
|
||||
, null
|
||||
, null
|
||||
, skuNumber
|
||||
, quantity
|
||||
);
|
||||
|
||||
new bnhtrade.Core.Logic.Stock.SkuTransactionCrud().Create(trans);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
@set batchpath=%~dp0
|
||||
@set filename=bnhtradeCOM.dll
|
||||
@set sourcepath="%batchpath%%filename%"
|
||||
@set destpath="%LOCALAPPDATA%\bnhtrade\%filename%"
|
||||
|
||||
@copy /y %sourcepath% %destpath%
|
||||
|
||||
@cd\Windows\Microsoft.NET\Framework64\v4.*
|
||||
regasm.exe /codebase /tlb %destpath%
|
||||
|
||||
@cd\Windows\Microsoft.NET\Framework\v4.*
|
||||
regasm.exe /codebase /tlb %destpath%
|
||||
|
||||
@echo.
|
||||
@echo Finished running regasm install script.
|
||||
@echo.
|
||||
@rem if no arguments passed, pause
|
||||
@IF "%~1"=="" @pause
|
||||
@@ -0,0 +1,7 @@
|
||||
@set mypath=%~dp0
|
||||
|
||||
call "%mypath%RegAsmUninstall.bat" nopause
|
||||
call "%mypath%RegAsmInstall.bat" nopause
|
||||
@echo Completed regasm refresh
|
||||
@echo.
|
||||
@pause
|
||||
@@ -0,0 +1,16 @@
|
||||
@set filename=bnhtradeCOM.dll
|
||||
@set dllpath="%LOCALAPPDATA%\bnhtrade\%filename%"
|
||||
|
||||
|
||||
@c:
|
||||
@cd\Windows\Microsoft.NET\Framework64\v4.*
|
||||
regasm.exe /u %dllpath%
|
||||
|
||||
@cd\Windows\Microsoft.NET\Framework\v4.*
|
||||
regasm.exe /u %dllpath%
|
||||
|
||||
@echo.
|
||||
@echo Finished running regasm uninstall script.
|
||||
@rem if no arguments passed, pause
|
||||
@echo.
|
||||
@IF "%~1"=="" @pause
|
||||
@@ -0,0 +1,103 @@
|
||||
<?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>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-13.0.0.0" newVersion="13.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.Bcl.AsyncInterfaces" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="RestSharp" publicKeyToken="598062e77f915f75" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-106.13.0.0" newVersion="106.13.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.ComponentModel.Annotations" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.2.1.0" newVersion="4.2.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.1.2" newVersion="4.0.1.2" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Text.Json" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-8.0.0.3" newVersion="8.0.0.3" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.IdentityModel.Abstractions" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-7.5.1.0" newVersion="7.5.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Security.Cryptography.ProtectedData" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Security.AccessControl" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.1" newVersion="6.0.0.1" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Diagnostics.DiagnosticSource" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-8.0.0.1" newVersion="8.0.0.1" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Text.Encodings.Web" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.Identity.Client" publicKeyToken="0a613f4dd989e8ae" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.60.3.0" newVersion="4.60.3.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Azure.Core" publicKeyToken="92742159e12e44c8" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-1.39.0.0" newVersion="1.39.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Azure.Identity" publicKeyToken="92742159e12e44c8" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-1.11.3.0" newVersion="1.11.3.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.IdentityModel.Protocols.OpenIdConnect" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-7.5.1.0" newVersion="7.5.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.IdentityModel.Protocols" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-7.5.1.0" newVersion="7.5.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.IdentityModel.Tokens" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-7.5.1.0" newVersion="7.5.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.IdentityModel.Tokens.Jwt" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-7.5.1.0" newVersion="7.5.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.IdentityModel.JsonWebTokens" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-7.5.1.0" newVersion="7.5.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.IdentityModel.Logging" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-7.5.1.0" newVersion="7.5.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Memory.Data" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" /></startup></configuration>
|
||||
@@ -1,74 +1,51 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{C3405E9D-B47A-4569-B6A3-BC9E7AA71EE5}</ProjectGuid>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>bnhtrade.ComTypeLib</RootNamespace>
|
||||
<AssemblyName>bnhtradeCOM</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.1</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
<TargetFrameworkProfile />
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<!--Added the line below to copy all dll from .nuget folder to build output folder-->
|
||||
<!--CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies-->
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<!--https://learn.microsoft.com/en-us/dotnet/core/native-interop/expose-components-to-com#register-the-com-host-for-com-->
|
||||
<EnableComHosting>true</EnableComHosting>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ComHostTypeLibrary Include="bnhtradeCOM.tlb" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>..\..\artifiacts\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<OutputPath>..\..\bin\$(AssemblyName)\Debug\</OutputPath>
|
||||
<CodeAnalysisRuleSet>SecurityRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\..\artifiacts\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<OutputPath>..\..\bin\$(AssemblyName)\Release\</OutputPath>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<RegisterForComInterop>false</RegisterForComInterop>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<RunPostBuildEvent>Always</RunPostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
<ProjectReference Include="..\bnhtrade.Core\bnhtrade.Core.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Account\Account.cs" />
|
||||
<Compile Include="Credential\ConnectionCredential.cs" />
|
||||
<Compile Include="Ebay\EbayListing.cs" />
|
||||
<Compile Include="Product\Product.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Purchase\PurchaseLine.cs" />
|
||||
<Compile Include="Stock\Stock.cs" />
|
||||
<Compile Include="Utility\LoadComObjextIntoStringArray.cs" />
|
||||
<PackageReference Include="CsvHelper" Version="33.0.1" />
|
||||
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\bnhtrade.Core\bnhtrade.Core.csproj">
|
||||
<Project>{339d7413-3da7-46ea-a55c-255a9a6b95eb}</Project>
|
||||
<Name>bnhtrade.Core</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup />
|
||||
<PropertyGroup>
|
||||
<PreBuildEvent>
|
||||
</PreBuildEvent>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>copy "$(SolutionDir)build\bnhtrade.ComTypeLib.RegAsmInstall.bat" "$(TargetDir)bnhtrade.ComTypeLib.RegAsmInstall.bat"
|
||||
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>
|
||||
<AssemblyTitle>bnhtrade COM Type Library</AssemblyTitle>
|
||||
<Company>bnhtrade</Company>
|
||||
<Product>bnhtradeCOMAsm</Product>
|
||||
<Copyright>Copyright © 2019</Copyright>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
<FileVersion>1.0.0.0</FileVersion>
|
||||
</PropertyGroup>
|
||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
||||
<Exec Command="copy "$(ProjectDir)_RegAsmInstall.bat" "$(TargetDir)"
copy "$(ProjectDir)_RegAsmRefresh.bat" "$(TargetDir)"
copy "$(ProjectDir)_RegAsmUninstall.bat" "$(TargetDir)"" />
|
||||
</Target>
|
||||
</Project>
|
||||
+103
-16
@@ -1,24 +1,111 @@
|
||||
<?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"/>
|
||||
</connectionStrings>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.1"/>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
|
||||
</startup>
|
||||
<applicationSettings>
|
||||
<e2A_Client.Properties.Settings>
|
||||
<setting name="DocArchivePath" serializeAs="String">
|
||||
<value>%USERPROFILE%\Desktop\e2A_Client\Archive\</value>
|
||||
</setting>
|
||||
<setting name="DocProcessingPath" serializeAs="String">
|
||||
<value>%USERPROFILE%\Desktop\e2A_Client\Processing\</value>
|
||||
</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>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-13.0.0.0" newVersion="13.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.Bcl.AsyncInterfaces" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="RestSharp" publicKeyToken="598062e77f915f75" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-106.13.0.0" newVersion="106.13.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.ComponentModel.Annotations" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.2.1.0" newVersion="4.2.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.1.2" newVersion="4.0.1.2" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Text.Json" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-8.0.0.3" newVersion="8.0.0.3" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.IdentityModel.Abstractions" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-7.5.1.0" newVersion="7.5.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Security.Cryptography.ProtectedData" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Security.AccessControl" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.1" newVersion="6.0.0.1" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Diagnostics.DiagnosticSource" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-8.0.0.1" newVersion="8.0.0.1" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Text.Encodings.Web" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.Identity.Client" publicKeyToken="0a613f4dd989e8ae" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.60.3.0" newVersion="4.60.3.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Azure.Core" publicKeyToken="92742159e12e44c8" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-1.39.0.0" newVersion="1.39.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Azure.Identity" publicKeyToken="92742159e12e44c8" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-1.11.3.0" newVersion="1.11.3.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.IdentityModel.Protocols.OpenIdConnect" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-7.5.1.0" newVersion="7.5.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.IdentityModel.Protocols" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-7.5.1.0" newVersion="7.5.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.IdentityModel.Tokens" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-7.5.1.0" newVersion="7.5.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.IdentityModel.Tokens.Jwt" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-7.5.1.0" newVersion="7.5.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.IdentityModel.JsonWebTokens" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-7.5.1.0" newVersion="7.5.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.IdentityModel.Logging" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-7.5.1.0" newVersion="7.5.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Memory.Data" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
</configuration>
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core
|
||||
{
|
||||
public class Config
|
||||
{
|
||||
public string GetAppDataPath()
|
||||
{
|
||||
string path = null;
|
||||
if (OperatingSystem.IsWindows())
|
||||
{
|
||||
path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)
|
||||
+ @"\bnhtrade\";
|
||||
}
|
||||
else if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS())
|
||||
{
|
||||
path = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)
|
||||
+ "/.bnhtrade/";
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new PlatformNotSupportedException("Unsupported operating system");
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// return the directory path for temp files, just add file name onto end
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static string GetTempFileDirectoryPath()
|
||||
{
|
||||
string directoryPath = Path.GetTempPath()
|
||||
+ "_" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
|
||||
System.IO.Directory.CreateDirectory(directoryPath);
|
||||
return directoryPath;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns configuration file from local users directory
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
internal Configuration GetConfiguration()
|
||||
{
|
||||
string path = new bnhtrade.Core.Config().GetAppDataPath();
|
||||
string configFileName = "app.local.config";
|
||||
|
||||
ExeConfigurationFileMap configMap = new ExeConfigurationFileMap();
|
||||
configMap.ExeConfigFilename = path + configFileName;
|
||||
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(configMap, ConfigurationUserLevel.None);
|
||||
|
||||
return config;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
using bnhtrade.Core.Data.Amazon.SellingPartnerAPI;
|
||||
using FikaAmazonAPI;
|
||||
using FikaAmazonAPI.Parameter.FbaInventory;
|
||||
using FikaAmazonAPI.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Amazon.FbaInventory
|
||||
{
|
||||
public class GetFbaInventoryInfo
|
||||
{
|
||||
private AmazonConnection amznConn = new SpApiConnection().Connection;
|
||||
|
||||
public List<string> MarketPlaceIds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// True to return inventory summaries with additional summarized inventory details and quantities.
|
||||
/// Otherwise, returns inventory summaries only (the default value).
|
||||
/// </summary>
|
||||
public bool WithDetails { get; set; }
|
||||
|
||||
public GetFbaInventoryInfo()
|
||||
{
|
||||
}
|
||||
|
||||
public Dictionary<string, string> GetFnsku(List<string> skuList)
|
||||
{
|
||||
var returnList = new Dictionary<string, string>();
|
||||
var result = GetInventorySummaries(skuList);
|
||||
|
||||
foreach (var list in result)
|
||||
{
|
||||
foreach(var item in list)
|
||||
{
|
||||
returnList.Add(item.SellerSku, item.FnSku);
|
||||
}
|
||||
}
|
||||
|
||||
return returnList;
|
||||
}
|
||||
|
||||
private List<FikaAmazonAPI.AmazonSpApiSDK.Models.FbaInventory.InventorySummaries> GetInventorySummaries(List<string> skuList, DateTime? startDateTime = null)
|
||||
{
|
||||
var returnList = new List<FikaAmazonAPI.AmazonSpApiSDK.Models.FbaInventory.InventorySummaries>();
|
||||
|
||||
// max of 50 sku in one call
|
||||
int i = 0;
|
||||
int total = skuList.Count;
|
||||
var skuRequestList = new List<string>();
|
||||
foreach (string sku in skuList)
|
||||
{
|
||||
i++;
|
||||
skuRequestList.Add(sku);
|
||||
|
||||
if (i == total || i % 50 == 0)
|
||||
{
|
||||
var parameters = new ParameterGetInventorySummaries();
|
||||
//parameters.details = WithDetails;
|
||||
parameters.granularityType = FikaAmazonAPI.AmazonSpApiSDK.Models.FbaInventory.Granularity.GranularityTypeEnum.Marketplace;
|
||||
parameters.granularityId = new Data.Amazon.SellingPartnerAPI.Defaults().MarketPlaceIdAsString();
|
||||
parameters.marketplaceIds = MarketPlaceIds;
|
||||
//parameters.startDateTime = startDateTime;
|
||||
parameters.sellerSkus = skuRequestList;
|
||||
|
||||
var lkdsjflds = amznConn.FbaInventory.GetInventorySummaries(parameters);
|
||||
returnList.AddRange(lkdsjflds);
|
||||
|
||||
skuRequestList = new List<string>();
|
||||
}
|
||||
}
|
||||
|
||||
return returnList;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using bnhtrade.Core.Data.Amazon.SellingPartnerAPI;
|
||||
using FikaAmazonAPI;
|
||||
using FikaAmazonAPI.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static FikaAmazonAPI.Utils.Constants;
|
||||
|
||||
namespace bnhtrade.Core.Data.Amazon.Feeds
|
||||
{
|
||||
public class GetFeed
|
||||
{
|
||||
private AmazonConnection amznConn = new SpApiConnection().Connection;
|
||||
|
||||
public void GetFeeds(string feedId)
|
||||
{
|
||||
var param = new FikaAmazonAPI.Parameter.Feed.ParameterGetFeed();
|
||||
param.pageSize = 100;
|
||||
param.processingStatuses = ProcessingStatuses.DONE;
|
||||
param.feedTypes = new List<FeedType> { FeedType.POST_PRODUCT_PRICING_DATA };
|
||||
|
||||
var result = amznConn.Feed.GetFeeds(param);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,450 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using FikaAmazonAPI;
|
||||
using FikaAmazonAPI.AmazonSpApiSDK.Models.Feeds;
|
||||
using FikaAmazonAPI.ConstructFeed;
|
||||
using FikaAmazonAPI.ConstructFeed.Messages;
|
||||
using FikaAmazonAPI.Utils;
|
||||
using static FikaAmazonAPI.ConstructFeed.BaseXML;
|
||||
using static FikaAmazonAPI.Utils.Constants;
|
||||
|
||||
|
||||
namespace bnhtrade.Core.Data.Amazon.Feeds
|
||||
{
|
||||
public class SampleFeeds
|
||||
{
|
||||
AmazonConnection amazonConnection;
|
||||
public SampleFeeds(AmazonConnection amazonConnection)
|
||||
{
|
||||
this.amazonConnection = amazonConnection;
|
||||
}
|
||||
|
||||
public void CallFlatfile()
|
||||
{
|
||||
string text = System.IO.File.ReadAllText(@"C:\Users\tareq\Downloads\Beispiel_Upload.txt");
|
||||
|
||||
var feedresultTXT = amazonConnection.Feed.SubmitFeed(text
|
||||
, FeedType.POST_FLAT_FILE_INVLOADER_DATA
|
||||
, new List<string>() { MarketPlace.UnitedArabEmirates.ID }
|
||||
, null
|
||||
, ContentType.TXT);
|
||||
|
||||
|
||||
string pathURL = string.Empty;
|
||||
while (pathURL == string.Empty)
|
||||
{
|
||||
Thread.Sleep(1000 * 30);
|
||||
var feedOutput = amazonConnection.Feed.GetFeed(feedresultTXT);
|
||||
if (feedOutput.ProcessingStatus == FikaAmazonAPI.AmazonSpApiSDK.Models.Feeds.Feed.ProcessingStatusEnum.DONE)
|
||||
{
|
||||
var outPut = amazonConnection.Feed.GetFeedDocument(feedOutput.ResultFeedDocumentId);
|
||||
|
||||
pathURL = outPut.Url;
|
||||
}
|
||||
}
|
||||
}
|
||||
public void GetFeeds()
|
||||
{
|
||||
|
||||
var data = amazonConnection.Feed.GetFeeds(new FikaAmazonAPI.Parameter.Feed.ParameterGetFeed()
|
||||
{
|
||||
processingStatuses = ProcessingStatuses.DONE,
|
||||
pageSize = 100,
|
||||
feedTypes = new List<FeedType> { FeedType.POST_PRODUCT_PRICING_DATA },
|
||||
createdSince = DateTime.UtcNow.AddDays(-6),
|
||||
createdUntil = DateTime.UtcNow.AddDays(-1),
|
||||
marketplaceIds = new List<string> { MarketPlace.UnitedArabEmirates.ID }
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public void CreateFeedDocument()
|
||||
{
|
||||
|
||||
var data = amazonConnection.Feed.CreateFeedDocument(ContentType.XML);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void GetFeedDocument()
|
||||
{
|
||||
|
||||
var data2 = amazonConnection.Feed.GetFeedDocument("amzn1.tortuga.3.92d8fd38-6ccf-49be-979f-6dc27375ea3e.T2DF7HINJ0NRA2");
|
||||
}
|
||||
|
||||
public void GetFeed()
|
||||
{
|
||||
|
||||
var data2 = amazonConnection.Feed.GetFeed("194146018872");
|
||||
}
|
||||
|
||||
public void CancelFeed()
|
||||
{
|
||||
|
||||
var data2 = amazonConnection.Feed.CancelFeed("194146018872");
|
||||
}
|
||||
|
||||
public void SubmitFeedInventory()
|
||||
{
|
||||
ConstructFeedService createDocument = new ConstructFeedService("A3J37AJU4O9RHK", "1.02");
|
||||
var list = new List<InventoryMessage>();
|
||||
list.Add(new InventoryMessage()
|
||||
{
|
||||
SKU = "API.853038006021.20789.1001",
|
||||
Quantity = 1
|
||||
});
|
||||
createDocument.AddInventoryMessage(list);
|
||||
var xml = createDocument.GetXML();
|
||||
|
||||
var feedID = amazonConnection.Feed.SubmitFeed(xml, FeedType.POST_INVENTORY_AVAILABILITY_DATA);
|
||||
GetFeedDetails(feedID);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// UnderTest
|
||||
/// </summary>
|
||||
public void SubmitFeedAddProductMessage(string ASIN, string SKU)
|
||||
{
|
||||
ConstructFeedService createDocument = new ConstructFeedService(amazonConnection.GetCurrentSellerID, "1.02");
|
||||
|
||||
var list = new List<ProductMessage>();
|
||||
list.Add(new ProductMessage()
|
||||
{
|
||||
SKU = SKU,
|
||||
|
||||
StandardProductID = new FikaAmazonAPI.ConstructFeed.Messages.StandardProductID()
|
||||
{
|
||||
Type = "ASIN",
|
||||
Value = ASIN
|
||||
}
|
||||
});
|
||||
createDocument.AddProductMessage(list, OperationType.Update);
|
||||
var xml = createDocument.GetXML();
|
||||
|
||||
var feedID = amazonConnection.Feed.SubmitFeed(xml, FeedType.POST_PRODUCT_DATA);
|
||||
|
||||
GetFeedDetails(feedID);
|
||||
}
|
||||
|
||||
public void SubmitFeedDeleteAddProductMessage()
|
||||
{
|
||||
ConstructFeedService createDocument = new ConstructFeedService("A3J37AJU4O9RHK", "1.02");
|
||||
|
||||
var list = new List<ProductMessage>();
|
||||
list.Add(new ProductMessage()
|
||||
{
|
||||
SKU = "8432225129778...."
|
||||
});
|
||||
createDocument.AddProductMessage(list, OperationType.Delete);
|
||||
var xml = createDocument.GetXML();
|
||||
|
||||
var feedID = amazonConnection.Feed.SubmitFeedContent(xml, FeedType.POST_PRODUCT_DATA);
|
||||
|
||||
GetFeedDetails(feedID);
|
||||
}
|
||||
public void AddOfferMessageMessage()
|
||||
{
|
||||
ConstructFeedService createDocument = new ConstructFeedService("A3J37AJU4O9RHK", "1.02");
|
||||
|
||||
var list = new List<OfferMessage>();
|
||||
list.Add(new OfferMessage()
|
||||
{
|
||||
SKU = "4049639414402_b"
|
||||
});
|
||||
createDocument.AddOfferMessage(list, OperationType.Delete);
|
||||
var xml = createDocument.GetXML();
|
||||
|
||||
var feedID = amazonConnection.Feed.SubmitFeed(xml, FeedType.POST_PRODUCT_DATA);
|
||||
|
||||
GetFeedDetails(feedID);
|
||||
}
|
||||
|
||||
public void SubmitFeedPRICING(decimal price, string SKU)
|
||||
{
|
||||
|
||||
ConstructFeedService createDocument = new ConstructFeedService(amazonConnection.GetCurrentSellerID, "1.02");
|
||||
|
||||
var list = new List<PriceMessage>();
|
||||
list.Add(new PriceMessage()
|
||||
{
|
||||
SKU = SKU,
|
||||
StandardPrice = new StandardPrice()
|
||||
{
|
||||
currency = amazonConnection.GetCurrentMarketplace.CurrencyCode.ToString(),
|
||||
Value = price
|
||||
}
|
||||
});
|
||||
createDocument.AddPriceMessage(list);
|
||||
|
||||
var xml = createDocument.GetXML();
|
||||
|
||||
var feedID = amazonConnection.Feed.SubmitFeed(xml, FeedType.POST_PRODUCT_PRICING_DATA);
|
||||
|
||||
GetFeedDetails(feedID);
|
||||
|
||||
}
|
||||
|
||||
public async void SubmitFeedPricingWithSalePrice(string sku, decimal price, decimal salePrice, DateTime startDate, DateTime endDate)
|
||||
{
|
||||
var currencyCode = amazonConnection.GetCurrentMarketplace.CurrencyCode.ToString();
|
||||
|
||||
var createDocument = new ConstructFeedService("A3J37AJU4O9RHK", "1.02");
|
||||
|
||||
var list = new List<PriceMessage>();
|
||||
list.Add(new PriceMessage
|
||||
{
|
||||
SKU = sku,
|
||||
StandardPrice = new StandardPrice
|
||||
{
|
||||
currency = currencyCode,
|
||||
Value = price
|
||||
},
|
||||
Sale = new Sale
|
||||
{
|
||||
SalePrice = new StandardPrice
|
||||
{
|
||||
currency = currencyCode,
|
||||
Value = salePrice
|
||||
},
|
||||
StartDate = startDate.ToUniversalTime().ToString("yyyy-MM-dd'T'HH:mm:ss.fffK"),
|
||||
EndDate = endDate.ToUniversalTime().ToString("yyyy-MM-dd'T'HH:mm:ss.fffK")
|
||||
}
|
||||
});
|
||||
createDocument.AddPriceMessage(list);
|
||||
|
||||
var xml = createDocument.GetXML();
|
||||
|
||||
var feedId = await amazonConnection.Feed.SubmitFeedAsync(xml, FeedType.POST_PRODUCT_PRICING_DATA);
|
||||
|
||||
GetFeedDetails(feedId);
|
||||
}
|
||||
|
||||
|
||||
public void SubmitFeedSale(decimal price, string SKU)
|
||||
{
|
||||
|
||||
ConstructFeedService createDocument = new ConstructFeedService("A3J37AJU4O9RHK", "1.02");
|
||||
|
||||
var list = new List<PriceMessage>();
|
||||
list.Add(new PriceMessage()
|
||||
{
|
||||
SKU = SKU,
|
||||
StandardPrice = new StandardPrice()
|
||||
{
|
||||
currency = amazonConnection.GetCurrentMarketplace.CurrencyCode.ToString(),
|
||||
Value = price
|
||||
},
|
||||
Sale = new Sale()
|
||||
{
|
||||
StartDate = DateTime.UtcNow.AddDays(+1).ToString("yyyy-MM-dd'T'HH:mm:ss.fffK"),
|
||||
EndDate = DateTime.UtcNow.AddDays(+2).ToString("yyyy-MM-dd'T'HH:mm:ss.fffK"),
|
||||
SalePrice = new StandardPrice()
|
||||
{
|
||||
currency = amazonConnection.GetCurrentMarketplace.CurrencyCode.ToString(),
|
||||
Value = price
|
||||
}
|
||||
}
|
||||
});
|
||||
createDocument.AddPriceMessage(list);
|
||||
|
||||
var xml = createDocument.GetXML();
|
||||
|
||||
var feedID = amazonConnection.Feed.SubmitFeed(xml, FeedType.POST_PRODUCT_PRICING_DATA);
|
||||
|
||||
GetFeedDetails(feedID);
|
||||
|
||||
}
|
||||
|
||||
public void FeebPostOrderFullfillment()
|
||||
{
|
||||
ConstructFeedService createDocument = new ConstructFeedService("{sellerId}", "1.02");
|
||||
|
||||
var list = new List<OrderFulfillmentMessage>();
|
||||
|
||||
list.Add(new OrderFulfillmentMessage()
|
||||
{
|
||||
AmazonOrderID = "{orderId}",
|
||||
FulfillmentDate = DateTime.Now.ToString("yyyy-MM-dd'T'HH:mm:ss.fffK"),
|
||||
FulfillmentData = new FulfillmentData()
|
||||
{
|
||||
CarrierName = "Correos Express",
|
||||
ShippingMethod = "ePaq",
|
||||
ShipperTrackingNumber = "{trackingNumber}"
|
||||
}
|
||||
});
|
||||
createDocument.AddOrderFulfillmentMessage(list);
|
||||
|
||||
var xml = createDocument.GetXML();
|
||||
|
||||
var feedID = amazonConnection.Feed.SubmitFeed(xml, FeedType.POST_ORDER_FULFILLMENT_DATA);
|
||||
|
||||
|
||||
GetFeedDetails(feedID);
|
||||
}
|
||||
|
||||
public void SubmitFeedOrderAcknowledgement()
|
||||
{
|
||||
ConstructFeedService createDocument = new ConstructFeedService("{sellerId}", "1.02");
|
||||
var list = new List<OrderAcknowledgementMessage>();
|
||||
list.Add(new OrderAcknowledgementMessage()
|
||||
{
|
||||
AmazonOrderID = "AMZ1234567890123",
|
||||
MerchantOrderID = "12345678",
|
||||
StatusCode = OrderAcknowledgementStatusCode.Success,
|
||||
Item = new List<OrderAcknowledgementItem>() {
|
||||
new OrderAcknowledgementItem() {
|
||||
AmazonOrderItemCode = "52986411826454",
|
||||
MerchantOrderItemID = "1"
|
||||
}
|
||||
}
|
||||
});
|
||||
createDocument.AddOrderAcknowledgementMessage(list);
|
||||
var xml = createDocument.GetXML();
|
||||
|
||||
var feedID = amazonConnection.Feed.SubmitFeed(xml, FeedType.POST_ORDER_ACKNOWLEDGEMENT_DATA);
|
||||
GetFeedDetails(feedID);
|
||||
}
|
||||
|
||||
public void SubmitFeedOrderAdjustment()
|
||||
{
|
||||
ConstructFeedService createDocument = new ConstructFeedService("{sellerId}", "1.02");
|
||||
var list = new List<OrderAdjustmentMessage>();
|
||||
list.Add(new OrderAdjustmentMessage()
|
||||
{
|
||||
AmazonOrderID = "AMZ1234567890123",
|
||||
ActionType = AdjustmentActionType.Refund,
|
||||
AdjustedItem = new List<AdjustedItem>() {
|
||||
new AdjustedItem() {
|
||||
AmazonOrderItemCode = "52986411826454",
|
||||
AdjustmentReason = AdjustmentReason.CustomerCancel,
|
||||
DirectPaymentAdjustments = new List<DirectPaymentAdjustments>()
|
||||
{
|
||||
new DirectPaymentAdjustments()
|
||||
{
|
||||
Component = new List<DirectPaymentAdjustmentsComponent>()
|
||||
{
|
||||
new DirectPaymentAdjustmentsComponent() {
|
||||
DirectPaymentType = "Credit Card Refund",
|
||||
Amount = new CurrencyAmount() {
|
||||
Value = 10.50M,
|
||||
currency = amazonConnection.GetCurrentMarketplace.CurrencyCode
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
createDocument.AddOrderAdjustmentMessage(list);
|
||||
var xml = createDocument.GetXML();
|
||||
|
||||
var feedID = amazonConnection.Feed.SubmitFeed(xml, FeedType.POST_PAYMENT_ADJUSTMENT_DATA);
|
||||
GetFeedDetails(feedID);
|
||||
}
|
||||
|
||||
public void CartonContentsRequestFeed()
|
||||
{
|
||||
ConstructFeedService createDocument2 = new ConstructFeedService("{SellerID}", "1.02");
|
||||
|
||||
var list22 = new List<CartonContentsRequest>();
|
||||
list22.Add(new CartonContentsRequest()
|
||||
{
|
||||
ShipmentId = "FBA123456",
|
||||
Carton = new List<Carton> {
|
||||
new Carton() {
|
||||
CartonId="1",
|
||||
Item=new List<CartonItem>(){
|
||||
new CartonItem() {
|
||||
QuantityInCase=1,
|
||||
QuantityShipped=1,
|
||||
SKU="7004"
|
||||
}
|
||||
}
|
||||
},
|
||||
new Carton() {
|
||||
CartonId="2",
|
||||
Item=new List<CartonItem>(){
|
||||
new CartonItem() {
|
||||
QuantityInCase=12,
|
||||
QuantityShipped=12,
|
||||
SKU="4051",
|
||||
ExpirationDate=DateTime.Now,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
createDocument2.AddCartonContentsRequest(list22);
|
||||
|
||||
var xml222 = createDocument2.GetXML();
|
||||
|
||||
var feedID = amazonConnection.Feed.SubmitFeed(xml222, FeedType.POST_FBA_INBOUND_CARTON_CONTENTS);
|
||||
GetFeedDetails(feedID);
|
||||
}
|
||||
|
||||
public void SubmitFeedEasyShipDocument()
|
||||
{
|
||||
ConstructFeedService createDocument = new ConstructFeedService("{sellerId}", "1.02");
|
||||
var list = new List<EasyShipDocumentMessage>();
|
||||
list.Add(new EasyShipDocumentMessage()
|
||||
{
|
||||
AmazonOrderID = "AMZ1234567890123",
|
||||
DocumentTypes = new List<EasyShipDocumentType>() {
|
||||
EasyShipDocumentType.ShippingLabel
|
||||
}
|
||||
});
|
||||
createDocument.AddEasyShipDocumentMessage(list);
|
||||
var xml = createDocument.GetXML();
|
||||
|
||||
var feedID = amazonConnection.Feed.SubmitFeed(xml, FeedType.POST_EASYSHIP_DOCUMENTS);
|
||||
GetFeedDetails(feedID);
|
||||
}
|
||||
|
||||
public void GetFeedDetails(string feedID)
|
||||
{
|
||||
string ResultFeedDocumentId = string.Empty;
|
||||
while (string.IsNullOrEmpty(ResultFeedDocumentId))
|
||||
{
|
||||
var feedOutput = amazonConnection.Feed.GetFeed(feedID);
|
||||
if (feedOutput.ProcessingStatus == Feed.ProcessingStatusEnum.DONE)
|
||||
{
|
||||
var outPut = amazonConnection.Feed.GetFeedDocument(feedOutput.ResultFeedDocumentId);
|
||||
|
||||
var reportOutput = outPut.Url;
|
||||
|
||||
var processingReport = amazonConnection.Feed.GetFeedDocumentProcessingReport(outPut);
|
||||
|
||||
DisplayProcessingReportMessage(processingReport);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(feedOutput.ProcessingStatus == Feed.ProcessingStatusEnum.INPROGRESS ||
|
||||
feedOutput.ProcessingStatus == Feed.ProcessingStatusEnum.INQUEUE))
|
||||
break;
|
||||
else Thread.Sleep(10000);
|
||||
}
|
||||
}
|
||||
private void DisplayProcessingReportMessage(ProcessingReportMessage processingReport)
|
||||
{
|
||||
Console.WriteLine("MessagesProcessed=" + processingReport.ProcessingSummary.MessagesProcessed);
|
||||
Console.WriteLine("MessagesSuccessful= " + processingReport.ProcessingSummary.MessagesSuccessful);
|
||||
Console.WriteLine("MessagesWithError=" + processingReport.ProcessingSummary.MessagesWithError);
|
||||
Console.WriteLine("MessagesWithWarning=" + processingReport.ProcessingSummary.MessagesWithWarning);
|
||||
|
||||
if (processingReport.Result != null && processingReport.Result.Count > 0)
|
||||
{
|
||||
foreach (var itm in processingReport.Result)
|
||||
{
|
||||
Console.WriteLine("ResultDescription=" + (itm.AdditionalInfo?.SKU ?? string.Empty) + " > " + itm.ResultDescription);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
using bnhtrade.Core.Data.Amazon.SellingPartnerAPI;
|
||||
using FikaAmazonAPI;
|
||||
using FikaAmazonAPI.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using static FikaAmazonAPI.Utils.Constants;
|
||||
|
||||
namespace bnhtrade.Core.Data.Amazon.Feeds
|
||||
{
|
||||
class SubmittFeed
|
||||
{
|
||||
private AmazonConnection amznConn = new SpApiConnection().Connection;
|
||||
private Logic.Log.LogEvent logEvent = new Logic.Log.LogEvent();
|
||||
|
||||
public bool FeedSubmissionRecived { get; set; } = false;
|
||||
|
||||
// make these functions only accept a database object
|
||||
public SubmittFeed()
|
||||
{
|
||||
}
|
||||
|
||||
public Model.Export.AmazonFeedSubmission FlatFileInvLoaderData(System.IO.MemoryStream filestream)
|
||||
{
|
||||
return Post("POST_FLAT_FILE_INVLOADER_DATA", filestream, "TXT");
|
||||
}
|
||||
|
||||
private Model.Export.AmazonFeedSubmission Post(string feedType, System.IO.MemoryStream filestream, string fileExtension)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
|
||||
if (filestream.Length == 0) { throw new Exception("Filestreeam is empty"); }
|
||||
if (string.IsNullOrEmpty(fileExtension)) { throw new Exception("Filestreeam is empty"); }
|
||||
|
||||
var feedresultTXT = amznConn.Feed.SubmitFeed(filestream.ToString()
|
||||
, GetFeedType(feedType)
|
||||
, new List<string>() { amznConn.GetCurrentMarketplace.ID }
|
||||
, null
|
||||
, ContentType.TXT);
|
||||
|
||||
string pathURL = string.Empty;
|
||||
while (pathURL == string.Empty)
|
||||
{
|
||||
Thread.Sleep(1000 * 30);
|
||||
var feedOutput = amznConn.Feed.GetFeed(feedresultTXT);
|
||||
if (feedOutput.ProcessingStatus == FikaAmazonAPI.AmazonSpApiSDK.Models.Feeds.Feed.ProcessingStatusEnum.DONE)
|
||||
{
|
||||
var outPut = amznConn.Feed.GetFeedDocument(feedOutput.ResultFeedDocumentId);
|
||||
|
||||
pathURL = outPut.Url;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private FeedType GetFeedType(string feedTypeText)
|
||||
{
|
||||
// add more here as needed
|
||||
if (feedTypeText == "POST_FLAT_FILE_INVLOADER_DATA")
|
||||
{ return FeedType.POST_FLAT_FILE_INVLOADER_DATA; }
|
||||
else
|
||||
{ throw new NotImplementedException("Need to implement feed type for " + feedTypeText); }
|
||||
}
|
||||
|
||||
public void SubmitFeed(Model.Export.AmazonFeedSubmission feedSubmission)
|
||||
{
|
||||
FeedSubmissionRecived = false;
|
||||
|
||||
if (feedSubmission.FileIsSet == false) { throw new Exception("Filestreeam is empty"); }
|
||||
|
||||
// get feed type
|
||||
var feedType = GetFeedType(feedSubmission.FeedType);
|
||||
|
||||
string text = feedSubmission.File.FileData.ToString();
|
||||
|
||||
var feedresultTXT = amznConn.Feed.SubmitFeed(text
|
||||
, feedType
|
||||
, new List<string>() { amznConn.GetCurrentMarketplace.ID }
|
||||
, null
|
||||
, ContentType.TXT);
|
||||
|
||||
var result = new FikaAmazonAPI.AmazonSpApiSDK.Models.Feeds.FeedDocument();
|
||||
int sleepTime = (1000 * 25);
|
||||
int retryCount = 0;
|
||||
int retryTimeout = 20;
|
||||
UI.Console.Wait("Feed:" + feedType + " submitted to Amazon, awaiting status check.", 5000);
|
||||
while (retryCount <= retryTimeout)
|
||||
{
|
||||
var feedOutput = amznConn.Feed.GetFeed(feedresultTXT);
|
||||
if (feedOutput.ProcessingStatus == FikaAmazonAPI.AmazonSpApiSDK.Models.Feeds.Feed.ProcessingStatusEnum.DONE)
|
||||
{
|
||||
result = amznConn.Feed.GetFeedDocument(feedOutput.ResultFeedDocumentId);
|
||||
break;
|
||||
}
|
||||
retryCount++;
|
||||
UI.Console.Wait("Feed: " + feedType + ", Processing status: " + feedOutput.ProcessingStatus + ", Retry: " + retryCount + " of "+ retryTimeout, sleepTime);
|
||||
}
|
||||
|
||||
// retry timeout
|
||||
if (retryCount > retryTimeout)
|
||||
{
|
||||
logEvent.LogError("Feed submission timeout. Feedtype:" + feedType + " FeedSubmissionId:" + feedSubmission.FeedSubmissionId);
|
||||
return;
|
||||
}
|
||||
|
||||
// get and do somehting with this
|
||||
string pathURL = string.Empty;
|
||||
pathURL = result.Url;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
using bnhtrade.Core.Data.Amazon.SellingPartnerAPI;
|
||||
using FikaAmazonAPI;
|
||||
using FikaAmazonAPI.AmazonSpApiSDK.Models.FulfillmentInbound;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Amazon.FulFillmentInbound
|
||||
{
|
||||
public class CreateInboundShipmentPlan
|
||||
{
|
||||
private AmazonConnection amznConn = new SpApiConnection().Connection;
|
||||
|
||||
public CreateInboundShipmentPlan()
|
||||
{
|
||||
}
|
||||
|
||||
public void CreatePlan(List<bnhtrade.Core.Model.AmazonFba.ShippingPlanItem> itemList)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
// complete, but not tested (need to do something with the result)
|
||||
|
||||
var request = new FikaAmazonAPI.AmazonSpApiSDK.Models.FulfillmentInbound.CreateInboundShipmentPlanRequest();
|
||||
request.LabelPrepPreference = FikaAmazonAPI.AmazonSpApiSDK.Models.FulfillmentInbound.LabelPrepPreference.SELLERLABEL;
|
||||
request.ShipFromAddress.Name = ConfigurationManager.AppSettings["AmazonFbaShipFrom.Name"];
|
||||
request.ShipFromAddress.AddressLine1 = ConfigurationManager.AppSettings["AmazonFbaShipFrom.AddressLine1"];
|
||||
request.ShipFromAddress.AddressLine2 = ConfigurationManager.AppSettings["AmazonFbaShipFrom.AddressLine2"];
|
||||
//request.ShipFromAddress.DistrictOrCounty = null; // not required
|
||||
request.ShipFromAddress.City = ConfigurationManager.AppSettings["AmazonFbaShipFrom.City"];
|
||||
request.ShipFromAddress.StateOrProvinceCode = ConfigurationManager.AppSettings["AmazonFbaShipFrom.StateOrProvinceCode"]; //required
|
||||
request.ShipFromAddress.PostalCode = ConfigurationManager.AppSettings["AmazonFbaShipFrom.PostalCode"];
|
||||
request.ShipFromAddress.CountryCode = ConfigurationManager.AppSettings["AmazonFbaShipFrom.CountryCode"];
|
||||
request.ShipToCountryCode = ConfigurationManager.AppSettings["AmazonFbaShipFrom.CountryCode"];
|
||||
|
||||
// add item list
|
||||
request.InboundShipmentPlanRequestItems = TransposeItemList(itemList);
|
||||
|
||||
var result = amznConn.FulFillmentInbound.CreateInboundShipmentPlan(request);
|
||||
}
|
||||
|
||||
private InboundShipmentPlanRequestItemList TransposeItemList(List<bnhtrade.Core.Model.AmazonFba.ShippingPlanItem> itemList)
|
||||
{
|
||||
var returnList = new InboundShipmentPlanRequestItemList();
|
||||
|
||||
foreach(var item in itemList)
|
||||
{
|
||||
var requestItem = new InboundShipmentPlanRequestItem();
|
||||
|
||||
requestItem.SellerSKU = item.SkuNumber;
|
||||
requestItem.ASIN = item.ASIN;
|
||||
if (Enum.TryParse(item.Condition, out Condition myStatus)) { requestItem.Condition = myStatus; }
|
||||
else { throw new Exception("Unable to parse string '" + item.Condition + "' to ENUM"); }
|
||||
requestItem.Quantity = item.Quantity;
|
||||
//requestItem.QuantityInCase;
|
||||
//requestItem.PrepDetailsList;
|
||||
|
||||
returnList.Add(requestItem);
|
||||
}
|
||||
|
||||
return returnList;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
using bnhtrade.Core.Data.Amazon.SellingPartnerAPI;
|
||||
using FikaAmazonAPI;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Amazon.FulFillmentInbound
|
||||
{
|
||||
public class GetShipmentItems
|
||||
{
|
||||
private AmazonConnection amznConn = new SpApiConnection().Connection;
|
||||
|
||||
public GetShipmentItems()
|
||||
{
|
||||
}
|
||||
|
||||
public List<Model.AmazonFba.ShipmentItemInfo> GetByDateRange(DateTime utcDateTimeAfter, DateTime utcDateTimeBefore)
|
||||
{
|
||||
var result = new List<Model.AmazonFba.ShipmentItemInfo>();
|
||||
|
||||
// build the request
|
||||
var parameter = new FikaAmazonAPI.Parameter.FulFillmentInbound.ParameterGetShipmentItems();
|
||||
parameter.MarketplaceId = amznConn.GetCurrentMarketplace.ID;
|
||||
parameter.QueryType = FikaAmazonAPI.Utils.Constants.QueryType.DATE_RANGE;
|
||||
parameter.LastUpdatedAfter = utcDateTimeAfter;
|
||||
parameter.LastUpdatedBefore = utcDateTimeBefore;
|
||||
|
||||
var apiResult = amznConn.FulFillmentInbound.GetShipmentItems(parameter);
|
||||
AppendNextToken(ref apiResult);
|
||||
return TransposeModel(apiResult);
|
||||
}
|
||||
|
||||
public List<Model.AmazonFba.ShipmentItemInfo> GetByShipmentId(string shipmentId)
|
||||
{
|
||||
var result = new List<Model.AmazonFba.ShipmentItemInfo>();
|
||||
if (string.IsNullOrEmpty(shipmentId)) { return result; }
|
||||
|
||||
// build the request
|
||||
//var parameter = new FikaAmazonAPI.Parameter.FulFillmentInbound.ParameterGetShipmentItems();
|
||||
//parameter.MarketplaceId = marketPlaceId;
|
||||
//parameter.QueryType = FikaAmazonAPI.Utils.Constants.QueryType.SHIPMENT;
|
||||
//parameter.ShipmentId = shipmentId;
|
||||
|
||||
var apiResult = amznConn.FulFillmentInbound.GetShipmentItemsByShipmentId(shipmentId);
|
||||
AppendNextToken(ref apiResult);
|
||||
return TransposeModel(apiResult);
|
||||
}
|
||||
|
||||
// checks for next-token, if true appends additional data to the ShipmentData
|
||||
private void AppendNextToken(ref FikaAmazonAPI.AmazonSpApiSDK.Models.FulfillmentInbound.InboundShipmentItemList shipmentList)
|
||||
{
|
||||
while (!string.IsNullOrEmpty(shipmentList.NextToken))
|
||||
{
|
||||
// build the request
|
||||
var parameter = new FikaAmazonAPI.Parameter.FulFillmentInbound.ParameterGetShipmentItems();
|
||||
parameter.MarketplaceId = amznConn.GetCurrentMarketplace.ID;
|
||||
parameter.QueryType = FikaAmazonAPI.Utils.Constants.QueryType.NEXT_TOKEN;
|
||||
parameter.NextToken = shipmentList.NextToken;
|
||||
|
||||
var result = amznConn.FulFillmentInbound.GetShipmentItems(parameter);
|
||||
|
||||
shipmentList.AddRange(result);
|
||||
shipmentList.NextToken = result.NextToken;
|
||||
}
|
||||
}
|
||||
|
||||
private void AppendNextToken(ref FikaAmazonAPI.AmazonSpApiSDK.Models.FulfillmentInbound.GetShipmentItemsResult shipmentList)
|
||||
{
|
||||
while (!string.IsNullOrEmpty(shipmentList.NextToken))
|
||||
{
|
||||
// build the request
|
||||
var parameter = new FikaAmazonAPI.Parameter.FulFillmentInbound.ParameterGetShipmentItems();
|
||||
parameter.MarketplaceId = amznConn.GetCurrentMarketplace.ID;
|
||||
parameter.QueryType = FikaAmazonAPI.Utils.Constants.QueryType.NEXT_TOKEN;
|
||||
parameter.NextToken = shipmentList.NextToken;
|
||||
|
||||
var result = amznConn.FulFillmentInbound.GetShipmentItems(parameter);
|
||||
|
||||
shipmentList.ItemData.AddRange(result);
|
||||
shipmentList.NextToken = result.NextToken;
|
||||
}
|
||||
}
|
||||
|
||||
private List<Model.AmazonFba.ShipmentItemInfo> TransposeModel(FikaAmazonAPI.AmazonSpApiSDK.Models.FulfillmentInbound.InboundShipmentItemList shipmentResult)
|
||||
{
|
||||
var returnList = new List<Model.AmazonFba.ShipmentItemInfo>();
|
||||
|
||||
for (var i = 0; i < shipmentResult.Count; i++)
|
||||
{
|
||||
var item = new Model.AmazonFba.ShipmentItemInfo();
|
||||
|
||||
// under new SP-API there are more details to be used, if needed
|
||||
item.AmazonFNSKU = shipmentResult[i].FulfillmentNetworkSKU;
|
||||
item.AmazonShipmentId = shipmentResult[i].ShipmentId;
|
||||
item.QuantityAllocated = shipmentResult[i].QuantityShipped.GetValueOrDefault();
|
||||
item.QuantityReceived = shipmentResult[i].QuantityReceived.GetValueOrDefault();
|
||||
item.SKUNumber = shipmentResult[i].SellerSKU;
|
||||
|
||||
returnList.Add(item);
|
||||
}
|
||||
|
||||
return returnList;
|
||||
}
|
||||
|
||||
private List<Model.AmazonFba.ShipmentItemInfo> TransposeModel(FikaAmazonAPI.AmazonSpApiSDK.Models.FulfillmentInbound.GetShipmentItemsResult shipmentResult)
|
||||
{
|
||||
var returnList = new List<Model.AmazonFba.ShipmentItemInfo>();
|
||||
|
||||
for (var i = 0; i < shipmentResult.ItemData.Count; i++)
|
||||
{
|
||||
var item = new Model.AmazonFba.ShipmentItemInfo();
|
||||
|
||||
// under new SP-API there are more details to be used, if needed
|
||||
item.AmazonFNSKU = shipmentResult.ItemData[i].FulfillmentNetworkSKU;
|
||||
item.AmazonShipmentId = shipmentResult.ItemData[i].ShipmentId;
|
||||
item.QuantityAllocated = shipmentResult.ItemData[i].QuantityShipped.GetValueOrDefault();
|
||||
item.QuantityReceived = shipmentResult.ItemData[i].QuantityReceived.GetValueOrDefault();
|
||||
item.SKUNumber = shipmentResult.ItemData[i].SellerSKU;
|
||||
|
||||
returnList.Add(item);
|
||||
}
|
||||
|
||||
return returnList;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
using bnhtrade.Core.Data.Amazon.SellingPartnerAPI;
|
||||
using FikaAmazonAPI;
|
||||
using FikaAmazonAPI.AmazonSpApiSDK.Models.FulfillmentInbound;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Amazon.FulFillmentInbound
|
||||
{
|
||||
public class GetShipments
|
||||
{
|
||||
private AmazonConnection amznConn = new SpApiConnection().Connection;
|
||||
|
||||
public GetShipments()
|
||||
{
|
||||
}
|
||||
|
||||
public List<Model.AmazonFba.ShipmentInfo> GetByDateRange(DateTime utcDateTimeAfter, DateTime utcDateTimeBefore)
|
||||
{
|
||||
// At least one of the ShipmentStatusList and ShipmentIdList must be provided
|
||||
|
||||
var result = new List<Model.AmazonFba.ShipmentInfo>();
|
||||
|
||||
// build the request
|
||||
var parameter = new FikaAmazonAPI.Parameter.FulFillmentInbound.ParameterGetShipments();
|
||||
parameter.MarketplaceId = amznConn.GetCurrentMarketplace.ID;
|
||||
parameter.QueryType = FikaAmazonAPI.Utils.Constants.QueryType.DATE_RANGE;
|
||||
parameter.LastUpdatedAfter = utcDateTimeAfter;
|
||||
parameter.LastUpdatedBefore = utcDateTimeBefore;
|
||||
AddShipmentStatusList(ref parameter);
|
||||
|
||||
var apiResult = amznConn.FulFillmentInbound.GetShipments(parameter);
|
||||
AppendNextToken(ref apiResult);
|
||||
return TransposeModel(apiResult);
|
||||
}
|
||||
|
||||
public List<Model.AmazonFba.ShipmentInfo> GetByShipmentIdList(List<string> shipmentIdList)
|
||||
{
|
||||
var result = new List<Model.AmazonFba.ShipmentInfo>();
|
||||
|
||||
// build the request
|
||||
var parameter = new FikaAmazonAPI.Parameter.FulFillmentInbound.ParameterGetShipments();
|
||||
parameter.MarketplaceId = amznConn.GetCurrentMarketplace.ID;
|
||||
parameter.QueryType = FikaAmazonAPI.Utils.Constants.QueryType.SHIPMENT;
|
||||
parameter.ShipmentIdList = shipmentIdList;
|
||||
|
||||
var apiResult = amznConn.FulFillmentInbound.GetShipments(parameter);
|
||||
AppendNextToken(ref apiResult);
|
||||
return TransposeModel(apiResult);
|
||||
}
|
||||
|
||||
private void AddShipmentStatusList(ref FikaAmazonAPI.Parameter.FulFillmentInbound.ParameterGetShipments parameters)
|
||||
{
|
||||
var list = new List<ShipmentStatus>();
|
||||
list.Add(ShipmentStatus.CANCELLED);
|
||||
list.Add(ShipmentStatus.CHECKED_IN);
|
||||
list.Add(ShipmentStatus.CLOSED);
|
||||
list.Add(ShipmentStatus.DELETED);
|
||||
list.Add(ShipmentStatus.DELIVERED);
|
||||
list.Add(ShipmentStatus.ERROR);
|
||||
list.Add(ShipmentStatus.IN_TRANSIT);
|
||||
list.Add(ShipmentStatus.READY_TO_SHIP);
|
||||
list.Add(ShipmentStatus.RECEIVING);
|
||||
list.Add(ShipmentStatus.SHIPPED);
|
||||
list.Add(ShipmentStatus.WORKING);
|
||||
|
||||
parameters.ShipmentStatusList = list;
|
||||
}
|
||||
|
||||
// checks for next-token, if true appends additional data to the ShipmentData
|
||||
private void AppendNextToken(ref FikaAmazonAPI.AmazonSpApiSDK.Models.FulfillmentInbound.GetShipmentsResult shipmentList)
|
||||
{
|
||||
while (!string.IsNullOrEmpty(shipmentList.NextToken))
|
||||
{
|
||||
// build the request
|
||||
var parameter = new FikaAmazonAPI.Parameter.FulFillmentInbound.ParameterGetShipments();
|
||||
parameter.MarketplaceId = amznConn.GetCurrentMarketplace.ID;
|
||||
parameter.QueryType = FikaAmazonAPI.Utils.Constants.QueryType.NEXT_TOKEN;
|
||||
parameter.NextToken = shipmentList.NextToken;
|
||||
|
||||
var result = amznConn.FulFillmentInbound.GetShipments(parameter);
|
||||
|
||||
shipmentList.ShipmentData.AddRange(result.ShipmentData);
|
||||
shipmentList.NextToken = result.NextToken;
|
||||
}
|
||||
}
|
||||
|
||||
// transposes return api object data to my model
|
||||
private List<Model.AmazonFba.ShipmentInfo> TransposeModel(FikaAmazonAPI.AmazonSpApiSDK.Models.FulfillmentInbound.GetShipmentsResult shipmentResult)
|
||||
{
|
||||
var returnList = new List<Model.AmazonFba.ShipmentInfo>();
|
||||
|
||||
for (var i = 0; i < shipmentResult.ShipmentData.Count; i++)
|
||||
{
|
||||
var item = new Model.AmazonFba.ShipmentInfo();
|
||||
|
||||
item.FbaShipmentId = shipmentResult.ShipmentData[i].ShipmentId;
|
||||
item.DestinationFulfillmentCenterId = shipmentResult.ShipmentData[i].DestinationFulfillmentCenterId;
|
||||
item.ShipmentName = shipmentResult.ShipmentData[i].ShipmentName;
|
||||
item.ShipmentStatus = shipmentResult.ShipmentData[i].ShipmentStatus.ToString();
|
||||
|
||||
returnList.Add(item);
|
||||
}
|
||||
|
||||
return returnList;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
//using MarketplaceWebServiceProducts.Model;
|
||||
using bnhtrade.Core.Data.Amazon.SellingPartnerAPI;
|
||||
using FikaAmazonAPI;
|
||||
using FikaAmazonAPI.AmazonSpApiSDK.Models.ProductFees;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Amazon.ProductFee
|
||||
{
|
||||
public class GetFeeEstimate
|
||||
{
|
||||
private Logic.Log.LogEvent log = new Logic.Log.LogEvent();
|
||||
private AmazonConnection amznConn = new SpApiConnection().Connection;
|
||||
|
||||
public string CurrencyCode { get; set; } = "GBP";
|
||||
|
||||
public string MarketPlaceId { get; set; }
|
||||
|
||||
public GetFeeEstimate()
|
||||
{
|
||||
}
|
||||
|
||||
public Model.Amazon.ProductFeeEstimate GetFba(string asin, int productId, decimal listingPrice)
|
||||
{
|
||||
var returnObj = new Model.Amazon.ProductFeeEstimate();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(asin))
|
||||
{
|
||||
throw new Exception("ASIN given to GetFeeEstimate is null or whitespace.");
|
||||
}
|
||||
|
||||
var listingPriceObj = new MoneyType(CurrencyCode, listingPrice);
|
||||
var priceToEstimateFees = new PriceToEstimateFees(listingPriceObj);
|
||||
|
||||
// create the request and get a response
|
||||
var request = new FeesEstimateRequest(MarketPlaceId, true, priceToEstimateFees, productId.ToString());
|
||||
var result = amznConn.ProductFee.GetMyFeesEstimateForASIN(asin, request);
|
||||
|
||||
if (result.FeesEstimateIdentifier.IdValue != asin)
|
||||
throw new Exception("returned ud value does not match ASIN");
|
||||
returnObj.Asin = asin;
|
||||
returnObj.ProductId = int.Parse(result.FeesEstimateIdentifier.SellerInputIdentifier);
|
||||
|
||||
// test for error
|
||||
if (result.Error != null)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("ASIN: " + asin);
|
||||
sb.AppendLine("Error Code: " + result.Error.Code);
|
||||
if (result.Error.Detail != null)
|
||||
{ sb.AppendLine("Detail: " + result.Error.Detail); }
|
||||
if (result.Error.Message != null)
|
||||
{ sb.AppendLine("Message: " + result.Error.Message); }
|
||||
if (result.Error.Type != null)
|
||||
{ sb.AppendLine("Type: " + result.Error.Type); }
|
||||
|
||||
log.LogError("Error running GetProductEstimateFee for ASIN:" + asin + ", further details attached.", sb.ToString());
|
||||
throw new Exception("ProductFeeEstimate error, check logs for further details");
|
||||
}
|
||||
|
||||
returnObj.IsAmazonFulfilled = result.FeesEstimateIdentifier.IsAmazonFulfilled.Value;
|
||||
returnObj.TimeOfFeeEstimation = result.FeesEstimate.TimeOfFeesEstimation.Value;
|
||||
returnObj.TotalFeeEstimate = result.FeesEstimate.TotalFeesEstimate.Amount.Value;
|
||||
returnObj.CurrencyCode = result.FeesEstimate.TotalFeesEstimate.CurrencyCode;
|
||||
returnObj.PriceToEstimateFeeListingPrice = result.FeesEstimateIdentifier.PriceToEstimateFees.ListingPrice.Amount.Value;
|
||||
returnObj.PriceToEstimateFeeShipping = 0;
|
||||
if (result.FeesEstimateIdentifier.PriceToEstimateFees.Shipping != null)
|
||||
returnObj.PriceToEstimateFeeShipping = result.FeesEstimateIdentifier.PriceToEstimateFees.Shipping.Amount.Value;
|
||||
returnObj.PriceToEstimateFeePoints = 0;
|
||||
if (result.FeesEstimateIdentifier.PriceToEstimateFees.Points != null)
|
||||
returnObj.PriceToEstimateFeePoints = result.FeesEstimateIdentifier.PriceToEstimateFees.Points.PointsMonetaryValue.Amount.Value;
|
||||
|
||||
returnObj.ReferralFee = 0m;
|
||||
returnObj.VariableClosingFee = 0m;
|
||||
returnObj.FulfillmentFees = 0m;
|
||||
returnObj.PerItemFee = 0m;
|
||||
returnObj.OtherFee_Exception = 0m;
|
||||
|
||||
FeeDetailList feeDetailList = result.FeesEstimate.FeeDetailList;
|
||||
List<FeeDetail> feeDetail = feeDetailList;
|
||||
foreach (FeeDetail feeDetailItem in feeDetail)
|
||||
{
|
||||
if (feeDetailItem.FeeType == "AmazonReferralFee" || feeDetailItem.FeeType == "ReferralFee")
|
||||
{ returnObj.ReferralFee = (decimal)feeDetailItem.FinalFee.Amount; }
|
||||
else if (feeDetailItem.FeeType == "VariableClosingFee")
|
||||
{ returnObj.VariableClosingFee = (decimal)feeDetailItem.FinalFee.Amount; }
|
||||
else if (feeDetailItem.FeeType == "PerItemFee")
|
||||
{ returnObj.PerItemFee = (decimal)feeDetailItem.FinalFee.Amount; }
|
||||
else if (feeDetailItem.FeeType == "FBAFees" || feeDetailItem.FeeType == "FulfillmentFees")
|
||||
{ returnObj.FulfillmentFees = (decimal)feeDetailItem.FinalFee.Amount; }
|
||||
else
|
||||
{ returnObj.OtherFee_Exception = returnObj.OtherFee_Exception + (decimal)feeDetailItem.FinalFee.Amount; }
|
||||
}
|
||||
|
||||
return returnObj;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
using bnhtrade.Core.Data.Amazon.SellingPartnerAPI;
|
||||
using FikaAmazonAPI;
|
||||
using FikaAmazonAPI.AmazonSpApiSDK.Models.ProductPricing;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Amazon.ProductPricing
|
||||
{
|
||||
public class GetCompetitivePricing
|
||||
{
|
||||
private AmazonConnection amznConn = new SpApiConnection().Connection;
|
||||
|
||||
public string MarketPlaceId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets Amazon Buy Box price for a given product. Will return no price if page does not have buy box
|
||||
/// </summary>
|
||||
public GetCompetitivePricing()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrives current Buy Box price (+ additional info) for a given ASIN
|
||||
/// </summary>
|
||||
/// <param name="asin">Amazon ASIN product reference</param>
|
||||
/// <returns></returns>
|
||||
public Model.Amazon.ProductCompetitivePrice ByAsin(string asin)
|
||||
{
|
||||
var result = Execute(new List<string> { asin }, false);
|
||||
if (result.Any()) { return result[0]; }
|
||||
else { return null; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrives current Buy Box price (+ additional info) for a given ASIN
|
||||
/// </summary>
|
||||
/// <param name="asin">Amazon ASIN product reference</param>
|
||||
/// <returns></returns>
|
||||
public List<Model.Amazon.ProductCompetitivePrice> ByAsin(List<string> asinList)
|
||||
{
|
||||
return Execute(asinList, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ideally use ASIN
|
||||
/// </summary>
|
||||
/// <param name="skuList"></param>
|
||||
/// <returns></returns>
|
||||
private Model.Amazon.ProductCompetitivePrice BySku(string sku)
|
||||
{
|
||||
var result = Execute(new List<string> { sku }, true);
|
||||
if (result.Any()) { return result[0]; }
|
||||
else { return null; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ideally use ASIN
|
||||
/// </summary>
|
||||
/// <param name="skuList"></param>
|
||||
/// <returns></returns>
|
||||
private List<Model.Amazon.ProductCompetitivePrice> BySku(List<string> skuList)
|
||||
{
|
||||
return Execute(skuList, true);
|
||||
}
|
||||
|
||||
private List<Model.Amazon.ProductCompetitivePrice> Execute(List<string> itemList, bool isSkuList)
|
||||
{
|
||||
var apiList = new List<Price>();
|
||||
|
||||
// max of 20 items in one call
|
||||
int i = 0;
|
||||
int total = itemList.Count;
|
||||
var itemRequestList = new List<string>();
|
||||
foreach (string sku in itemList)
|
||||
{
|
||||
i++;
|
||||
itemRequestList.Add(sku);
|
||||
|
||||
if (i == total || i % 20 == 0)
|
||||
{
|
||||
var parameter = new FikaAmazonAPI.Parameter.ProductPricing.ParameterGetCompetitivePricing();
|
||||
if (isSkuList) { parameter.Skus = itemRequestList; }
|
||||
else { parameter.Asins = itemRequestList; }
|
||||
parameter.MarketplaceId = MarketPlaceId;
|
||||
|
||||
apiList.AddRange(amznConn.ProductPricing.GetCompetitivePricing(parameter));
|
||||
itemRequestList = new List<string>();
|
||||
}
|
||||
}
|
||||
|
||||
return TransposeData(apiList);
|
||||
}
|
||||
|
||||
private List<Model.Amazon.ProductCompetitivePrice> TransposeData(IList<Price> spapiList)
|
||||
{
|
||||
var returnList = new List<Model.Amazon.ProductCompetitivePrice>();
|
||||
|
||||
foreach (var item in spapiList)
|
||||
{
|
||||
string asin = item.ASIN;
|
||||
decimal competitivePrice;
|
||||
bool competitivePriceIsSet;
|
||||
bool isBuyBox;
|
||||
bool buyBoxBelongsToRequester;
|
||||
int offersCountNew = 0;
|
||||
int offersCountUsed = 0;
|
||||
|
||||
if (item.Product.CompetitivePricing.CompetitivePrices.Count == 0)
|
||||
{
|
||||
competitivePrice = 0;
|
||||
competitivePriceIsSet = false;
|
||||
isBuyBox = false;
|
||||
buyBoxBelongsToRequester = false;
|
||||
}
|
||||
else if (item.Product.CompetitivePricing.CompetitivePrices.Count == 1)
|
||||
{
|
||||
if (item.Product.CompetitivePricing.CompetitivePrices[0].Condition != "New")
|
||||
throw new Exception("Condition returned is not new");
|
||||
|
||||
competitivePrice = item.Product.CompetitivePricing.CompetitivePrices[0].Price.LandedPrice.Amount.Value;
|
||||
competitivePriceIsSet = true;
|
||||
isBuyBox = true;
|
||||
buyBoxBelongsToRequester = item.Product.CompetitivePricing.CompetitivePrices[0].BelongsToRequester.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("More than one competitive price returned");
|
||||
}
|
||||
|
||||
// get quanities
|
||||
foreach (var offer in item.Product.CompetitivePricing.NumberOfOfferListings)
|
||||
{
|
||||
if (offer.Condition == "New") { offersCountNew = offer.Count.Value; }
|
||||
if (offer.Condition == "Used") { offersCountUsed = offer.Count.Value; }
|
||||
}
|
||||
|
||||
// add to list
|
||||
var returnItem = new Model.Amazon.ProductCompetitivePrice(
|
||||
asin
|
||||
, competitivePrice
|
||||
, competitivePriceIsSet
|
||||
, isBuyBox
|
||||
, buyBoxBelongsToRequester
|
||||
, offersCountNew
|
||||
, offersCountUsed);
|
||||
returnList.Add(returnItem);
|
||||
}
|
||||
|
||||
return returnList;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static FikaAmazonAPI.Utils.Constants;
|
||||
|
||||
namespace bnhtrade.Core.Data.Amazon.Report
|
||||
{
|
||||
public class FbaCustomerReturn : ReportLogic
|
||||
{
|
||||
public FbaCustomerReturn() : base(ReportTypes.GET_FBA_FULFILLMENT_CUSTOMER_RETURNS_DATA)
|
||||
{
|
||||
}
|
||||
|
||||
public void GetReport(DateTime startTime, DateTime endTime)
|
||||
{
|
||||
int maxRange = 0; // there doesn't appear to be any limit on time span
|
||||
|
||||
DownloadTimePeriodReport(startTime, endTime, maxRange);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static FikaAmazonAPI.Utils.Constants;
|
||||
|
||||
namespace bnhtrade.Core.Data.Amazon.Report
|
||||
{
|
||||
public class FbaInventory : ReportLogic
|
||||
{
|
||||
public FbaInventory() : base (ReportTypes.GET_FBA_MYI_ALL_INVENTORY_DATA)
|
||||
{
|
||||
}
|
||||
|
||||
public void GetReport(int reportMaxAge = 30)
|
||||
{
|
||||
// Amazon will throttle (return 'FATAL' error) when requesting this report twice within 15 minutes
|
||||
|
||||
DownloadReport(reportMaxAge);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static FikaAmazonAPI.Utils.Constants;
|
||||
|
||||
namespace bnhtrade.Core.Data.Amazon.Report
|
||||
{
|
||||
public class FbaInventoryAdustment : ReportLogic
|
||||
{
|
||||
public FbaInventoryAdustment() : base(ReportTypes.GET_FBA_FULFILLMENT_INVENTORY_ADJUSTMENTS_DATA)
|
||||
{
|
||||
throw new Exception("report has been depreciated https://developer-docs.amazon.com/sp-api/docs/sp-api-deprecations");
|
||||
}
|
||||
|
||||
public void GetReport(DateTime startTime, DateTime endTime)
|
||||
{
|
||||
DownloadTimePeriodReport(startTime, endTime, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static FikaAmazonAPI.Utils.Constants;
|
||||
|
||||
namespace bnhtrade.Core.Data.Amazon.Report
|
||||
{
|
||||
public class FbaInventoryAge : ReportLogic
|
||||
{
|
||||
public FbaInventoryAge() : base(ReportTypes.GET_FBA_INVENTORY_AGED_DATA)
|
||||
{
|
||||
throw new Exception("report has been depreciated https://developer-docs.amazon.com/sp-api/docs/sp-api-deprecations");
|
||||
}
|
||||
|
||||
public new void GetReport(int reportMaxAge = 30)
|
||||
{
|
||||
throw new Exception("GET_FBA_INVENTORY_AGED_DATA report has been retired since 22/06/2022 and replaced by GET_FBA_INVENTORY_PLANNING_DATA");
|
||||
|
||||
//DownloadSnapshotReport(reportMaxAge);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
using CsvHelper;
|
||||
using FikaAmazonAPI.AmazonSpApiSDK.Models.FulfillmentOutbound;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using static FikaAmazonAPI.Utils.Constants;
|
||||
using System.Linq;
|
||||
using CsvHelper.Configuration;
|
||||
|
||||
namespace bnhtrade.Core.Data.Amazon.Report
|
||||
{
|
||||
public class FbaInventoryLedgerDetailed : ReportLogic
|
||||
{
|
||||
List<Model.Import.AmazonFbaInventoryLedgerDetail> resultList = null;
|
||||
|
||||
/// <summary>
|
||||
/// Get report will download the file to local storage. Use this to transpose the data to a model class.
|
||||
/// </summary>
|
||||
public List<Model.Import.AmazonFbaInventoryLedgerDetail> ResultList
|
||||
{
|
||||
get
|
||||
{
|
||||
if (resultList == null)
|
||||
{
|
||||
TransposeFileToClass();
|
||||
}
|
||||
return resultList;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsSetResultList
|
||||
{
|
||||
get { return IsSetReportFilePath; }
|
||||
}
|
||||
|
||||
public FbaInventoryLedgerDetailed() : base(ReportTypes.GET_LEDGER_DETAIL_VIEW_DATA)
|
||||
{
|
||||
}
|
||||
|
||||
public new void Init()
|
||||
{
|
||||
base.Init();
|
||||
resultList = null;
|
||||
}
|
||||
|
||||
public void GetReport(DateTime utcDataStartTime, DateTime utcDataEndTime)
|
||||
{
|
||||
// 18 months max historical transactions for report
|
||||
DownloadTimePeriodReport(utcDataStartTime, utcDataEndTime, 0, 547);
|
||||
}
|
||||
|
||||
private void TransposeFileToClass()
|
||||
{
|
||||
var transposeResult = new List<Model.Import.AmazonFbaInventoryLedgerDetail>();
|
||||
|
||||
if (IsSetReportFilePath == false)
|
||||
{
|
||||
resultList = transposeResult;
|
||||
}
|
||||
else
|
||||
{
|
||||
using (var reader = new StreamReader(ReportFilePath))
|
||||
{
|
||||
// setup csvhelper
|
||||
var config = new CsvConfiguration(CultureInfo.InvariantCulture)
|
||||
{
|
||||
Delimiter = "\t",
|
||||
};
|
||||
|
||||
using (var csvreader = new CsvReader(reader, config))
|
||||
{
|
||||
// check header count
|
||||
csvreader.Read();
|
||||
csvreader.ReadHeader();
|
||||
int columns = csvreader.HeaderRecord.Count();
|
||||
if (columns < 15)
|
||||
throw new Exception("Malformed report 'GET_LEDGER_DETAIL_VIEW_DATA' does not have enough headers");
|
||||
if (columns > 15)
|
||||
log.LogError("New column in 'GET_LEDGER_DETAIL_VIEW_DATA'");
|
||||
|
||||
// transpose the data
|
||||
transposeResult = csvreader.GetRecords<Model.Import.AmazonFbaInventoryLedgerDetail>().ToList();
|
||||
resultList = transposeResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static FikaAmazonAPI.Utils.Constants;
|
||||
|
||||
namespace bnhtrade.Core.Data.Amazon.Report
|
||||
{
|
||||
public class FbaInventoryReceipt : ReportLogic
|
||||
{
|
||||
/*
|
||||
* Not able to uniquley define each row in flat file and check for duplicate in DB
|
||||
* therefore, do not download report date range that has already been imported, as records will be duplicated
|
||||
*
|
||||
* Due to a MWS bug, MWS can/will include some records that are before the specified date range. As mws report is updated once daily,
|
||||
* it is safe to omitt lines < startDate when parsing/inserting lines into db (as these will have been previously imported)
|
||||
*/
|
||||
|
||||
public FbaInventoryReceipt() : base(ReportTypes.GET_FBA_FULFILLMENT_INVENTORY_RECEIPTS_DATA)
|
||||
{
|
||||
throw new Exception("report has been depreciated https://developer-docs.amazon.com/sp-api/docs/sp-api-deprecations");
|
||||
}
|
||||
|
||||
public void GetReport(DateTime startTime, DateTime endTime)
|
||||
{
|
||||
DownloadTimePeriodReport(startTime, endTime, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static FikaAmazonAPI.Utils.Constants;
|
||||
|
||||
namespace bnhtrade.Core.Data.Amazon.Report
|
||||
{
|
||||
public class FbaReimbursement : ReportLogic
|
||||
{
|
||||
public FbaReimbursement() : base(ReportTypes.GET_FBA_REIMBURSEMENTS_DATA)
|
||||
{
|
||||
}
|
||||
|
||||
public void GetReport(DateTime startTime, DateTime endTime)
|
||||
{
|
||||
DownloadTimePeriodReport(startTime, endTime, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static FikaAmazonAPI.Utils.Constants;
|
||||
|
||||
namespace bnhtrade.Core.Data.Amazon.Report
|
||||
{
|
||||
public class FbaRemovalOrder : ReportLogic
|
||||
{
|
||||
public FbaRemovalOrder() : base(ReportTypes.GET_FBA_FULFILLMENT_REMOVAL_ORDER_DETAIL_DATA)
|
||||
{
|
||||
}
|
||||
|
||||
public void GetReport(DateTime startTime, DateTime endTime)
|
||||
{
|
||||
DownloadTimePeriodReport(startTime, endTime, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static FikaAmazonAPI.Utils.Constants;
|
||||
|
||||
namespace bnhtrade.Core.Data.Amazon.Report
|
||||
{
|
||||
public class FbaSaleShipment : ReportLogic
|
||||
{
|
||||
//public FbaSaleShipment() : base(ReportTypes.GET_FBA_FULFILLMENT_CUSTOMER_SHIPMENT_SALES_DATA)
|
||||
public FbaSaleShipment() : base(ReportTypes.GET_AMAZON_FULFILLED_SHIPMENTS_DATA_GENERAL)
|
||||
{
|
||||
}
|
||||
|
||||
public void GetReport(DateTime startTime, DateTime endTime)
|
||||
{
|
||||
DownloadTimePeriodReport(startTime, endTime, 30);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,423 @@
|
||||
using bnhtrade.Core.Data.Amazon.SellingPartnerAPI;
|
||||
using FikaAmazonAPI;
|
||||
using FikaAmazonAPI.AmazonSpApiSDK.Models.Reports;
|
||||
using FikaAmazonAPI.Parameter.Report;
|
||||
using FikaAmazonAPI.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using static FikaAmazonAPI.Utils.Constants;
|
||||
|
||||
namespace bnhtrade.Core.Data.Amazon.Report
|
||||
{
|
||||
public class ReportLogic
|
||||
{
|
||||
public enum ProcessingStatus
|
||||
{
|
||||
NULL,
|
||||
INQUEUE,
|
||||
INPROGRESS,
|
||||
CANCELLED,
|
||||
DONE,
|
||||
FATAL
|
||||
}
|
||||
|
||||
private bool _isSetReportProcessingStatus = false;
|
||||
private AmazonConnection amznConn = new SpApiConnection().Connection;
|
||||
private FikaAmazonAPI.AmazonSpApiSDK.Models.Reports.Report report = new FikaAmazonAPI.AmazonSpApiSDK.Models.Reports.Report();
|
||||
private ReportTypes reportType;
|
||||
protected Logic.Log.LogEvent log = new Logic.Log.LogEvent();
|
||||
|
||||
public ProcessingStatus ReportProcessingStatus { get; private set; }
|
||||
|
||||
public bool IsSetReportProcessingStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
if (ReportProcessingStatus == ProcessingStatus.NULL)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public DateTime? ReportCreatedTime
|
||||
{
|
||||
get
|
||||
{
|
||||
if (report == null) { return null; }
|
||||
else { return report.CreatedTime; }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The report has completed, but there is no data (and hence no file) to download.
|
||||
/// </summary>
|
||||
public bool ReportDoneNoData { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// File path the the local location of the file
|
||||
/// </summary>
|
||||
public string ReportFilePath { get; private set; }
|
||||
|
||||
private FikaAmazonAPI.Utils.MarketplaceIds MarketPlaceIds { get; set; }
|
||||
|
||||
public bool IsSetReportFilePath
|
||||
{
|
||||
get { return !string.IsNullOrWhiteSpace(ReportFilePath); }
|
||||
}
|
||||
|
||||
public ReportLogic(ReportTypes reportType)
|
||||
{
|
||||
this.reportType = reportType;
|
||||
this.MarketPlaceIds = new MarketplaceIds();
|
||||
this.MarketPlaceIds.Add(amznConn.GetCurrentMarketplace.ID);
|
||||
Init();
|
||||
}
|
||||
|
||||
protected void Init()
|
||||
{
|
||||
ReportDoneNoData = false;
|
||||
ReportFilePath = null;
|
||||
report = null;
|
||||
ReportProcessingStatus = ProcessingStatus.NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Return a list of report that are currently available filtered parameters set in class
|
||||
/// </summary>
|
||||
/// <returns>report list</returns>
|
||||
protected IList<FikaAmazonAPI.AmazonSpApiSDK.Models.Reports.Report> ListAvailableReports()
|
||||
{
|
||||
var parameters = new ParameterReportList();
|
||||
parameters.reportTypes = new List<ReportTypes>() { reportType };
|
||||
parameters.marketplaceIds.Add(amznConn.GetCurrentMarketplace.ID);
|
||||
|
||||
// request from amazon
|
||||
return amznConn.Reports.GetReports(parameters);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// For reports that require a start and end period to report over.
|
||||
/// </summary>
|
||||
/// <param name="utcDataStartTime"></param>
|
||||
/// <param name="utcDataEndTime"></param>
|
||||
/// <param name="maxDateRangeDays">The max time in days between the start and end date time</param>
|
||||
/// <param name="maxDataAgeDays">The max time that Amazon retains the data for, in days</param>
|
||||
/// <exception cref="Exception"></exception>
|
||||
protected void DownloadTimePeriodReport(DateTime utcDataStartTime, DateTime utcDataEndTime, int maxDateRangeDays, int maxDataAgeDays = 0)
|
||||
{
|
||||
if (utcDataStartTime.Kind != DateTimeKind.Utc || utcDataEndTime.Kind != DateTimeKind.Utc)
|
||||
throw new Exception("Report period time has to be set to UTC");
|
||||
|
||||
if (maxDateRangeDays > 0 && (utcDataEndTime - utcDataStartTime).TotalDays > maxDateRangeDays)
|
||||
throw new Exception("Date range for report is greater than the maximum allowable");
|
||||
|
||||
if (maxDataAgeDays < 0)
|
||||
{
|
||||
throw new Exception("Max data age in days cannot be less than zero");
|
||||
}
|
||||
//else if(maxDataAgeDays > 0)
|
||||
//{
|
||||
// if (utcDataStartTime < DateTime.UtcNow.AddDays(maxDataAgeDays * -1))
|
||||
// {
|
||||
// throw new Exception("Max historical data for " + reportType.ToString() + " is " + maxDataAgeDays + " days");
|
||||
// }
|
||||
//}
|
||||
|
||||
var specification = new ParameterCreateReportSpecification();
|
||||
specification.marketplaceIds = this.MarketPlaceIds;
|
||||
specification.reportType = reportType;
|
||||
specification.dataStartTime = utcDataStartTime;
|
||||
specification.dataEndTime = utcDataEndTime;
|
||||
|
||||
DownloadReport(specification, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use this to download reports that do not have a time period element, they are as things stand now.
|
||||
/// </summary>
|
||||
/// <param name="snapshotMaxAge">In minutes, the minimum time between report requests. Amazon will return 'FATAL' if a report is re-requested in too short a time period </param>
|
||||
protected void DownloadReport(int snapshotMaxAge)
|
||||
{
|
||||
var specification = new ParameterCreateReportSpecification();
|
||||
specification.marketplaceIds = this.MarketPlaceIds;
|
||||
specification.reportType = reportType;
|
||||
|
||||
DownloadReport(specification, true, snapshotMaxAge);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The main body of the class, where the all the work is done
|
||||
/// </summary>
|
||||
/// <param name="specification">the specification built by the supporting methods</param>
|
||||
/// <param name="isSnapshotReport">ie not a time period report, but an 'as things stand now' report</param>
|
||||
/// <param name="snapshotMaxAge">time in minutes</param>
|
||||
/// <exception cref="Exception"></exception>
|
||||
private void DownloadReport(ParameterCreateReportSpecification specification, bool isSnapshotReport, int snapshotMaxAge = 0)
|
||||
{
|
||||
log.LogInformation("Starting report requesting from Amazon SP-API for " + specification.reportType.ToString());
|
||||
// Amazon create report is throttled to 1 report every 15 minutes
|
||||
Init();
|
||||
|
||||
// check for existing report with same specification
|
||||
string reportId = ExistingReportCheck(specification);
|
||||
|
||||
// no matching report? then create one
|
||||
if (reportId == null)
|
||||
{ reportId = amznConn.Reports.CreateReport(specification); }
|
||||
|
||||
WaitWhileProcessing(reportId);
|
||||
|
||||
// some real time report will return 'fatal' if the report has already recently been requested, test for this
|
||||
if (isSnapshotReport && report.ProcessingStatus == FikaAmazonAPI.AmazonSpApiSDK.Models.Reports.Report.ProcessingStatusEnum.FATAL)
|
||||
{
|
||||
bool aSuitableReportExists = SnapshotReportThrottleHanderler(ref reportId, specification, snapshotMaxAge);
|
||||
if (aSuitableReportExists == true)
|
||||
{
|
||||
log.LogWarning("Create amazon report returned 'FATAL' due to a report with the same parameters already existing, requesting the existing report");
|
||||
WaitWhileProcessing(reportId);
|
||||
}
|
||||
}
|
||||
|
||||
DownloadReport(reportId);
|
||||
}
|
||||
|
||||
protected void DownloadByReportId(string reportId)
|
||||
{
|
||||
Init();
|
||||
DownloadReport(reportId);
|
||||
}
|
||||
|
||||
private void DownloadReport(string reportId)
|
||||
{
|
||||
if (report == null)
|
||||
{
|
||||
WaitWhileProcessing(reportId);
|
||||
}
|
||||
|
||||
// test for processing status
|
||||
if (report.ProcessingStatus == FikaAmazonAPI.AmazonSpApiSDK.Models.Reports.Report.ProcessingStatusEnum.DONE)
|
||||
{
|
||||
ReportProcessingStatus = ProcessingStatus.DONE;
|
||||
|
||||
log.LogInformation("Report proccessing status is 'DONE' (ReportId:" + report.ReportId + ").");
|
||||
|
||||
if (string.IsNullOrEmpty(report.ReportDocumentId))
|
||||
throw new Exception("Report processing done, yet there's no report document. Write code to handle this");
|
||||
}
|
||||
else if (report.ProcessingStatus == FikaAmazonAPI.AmazonSpApiSDK.Models.Reports.Report.ProcessingStatusEnum.CANCELLED)
|
||||
{
|
||||
ReportProcessingStatus = ProcessingStatus.CANCELLED;
|
||||
// From SPAPI Documentation: The report was cancelled. There are two ways a report can be cancelled:
|
||||
// an explicit cancellation request before the report starts processing, or an automatic cancellation
|
||||
// if there is no data to return.
|
||||
log.Initialise();
|
||||
log.LogInformation("ReportID:" + reportId + " returned 'CANCELLED', if a cancel request hasn't been made then there is no data in the report.");
|
||||
ReportDoneNoData = true;
|
||||
return;
|
||||
}
|
||||
else if (report.ProcessingStatus == FikaAmazonAPI.AmazonSpApiSDK.Models.Reports.Report.ProcessingStatusEnum.FATAL)
|
||||
{
|
||||
ReportProcessingStatus = ProcessingStatus.FATAL;
|
||||
// AMazon does sometime return a file with information as to why fatal was returned contained within, test for this
|
||||
if (string.IsNullOrEmpty(report.ReportDocumentId))
|
||||
{
|
||||
log.LogError("ReportID:" + reportId + " returned 'FATAL', no further information was recived.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// if we get here, onto downloading the file
|
||||
if (string.IsNullOrEmpty(report.ReportDocumentId))
|
||||
throw new Exception("ReportDocumentId field is null or empty.");
|
||||
|
||||
// as file url expires after 5 minutes, request it just before download
|
||||
UI.Console.WriteLine("Requesting download url for Amazon report (ReportId:" + reportId + ").");
|
||||
var amazonFileInfo = amznConn.Reports.GetReportDocument(report.ReportDocumentId);
|
||||
|
||||
// download report from url
|
||||
log.LogInformation("Downloading Amazon report #" + reportId, "Report Document ID: " + amazonFileInfo.ReportDocumentId);
|
||||
byte[] response = null;
|
||||
using (var webClient = new System.Net.WebClient())
|
||||
{
|
||||
response = webClient.DownloadData(amazonFileInfo.Url);
|
||||
}
|
||||
|
||||
|
||||
// decrypt report
|
||||
UI.Console.WriteLine("Processing download (ReportId:" + reportId + ").");
|
||||
if (amazonFileInfo.EncryptionDetails != null)
|
||||
{
|
||||
UI.Console.WriteLine("Decrypting report ReportId:" + reportId + ").", false);
|
||||
|
||||
byte[] key = Encoding.ASCII.GetBytes(amazonFileInfo.EncryptionDetails.Key);
|
||||
byte[] iv = Encoding.ASCII.GetBytes(amazonFileInfo.EncryptionDetails.InitializationVector);
|
||||
response = Logic.Utilities.File.DecryptByte(key, iv, response);
|
||||
}
|
||||
|
||||
// decompress
|
||||
if (amazonFileInfo.CompressionAlgorithm != null)
|
||||
{
|
||||
UI.Console.WriteLine("Decompressing report ReportId:" + reportId + ").", false);
|
||||
response = Logic.Utilities.File.Decompress(response);
|
||||
}
|
||||
|
||||
string reportString = Encoding.ASCII.GetString(response);
|
||||
|
||||
// if fatal returned, give file contents in log
|
||||
if (report.ProcessingStatus == FikaAmazonAPI.AmazonSpApiSDK.Models.Reports.Report.ProcessingStatusEnum.FATAL)
|
||||
{
|
||||
log.LogError("Downloading reportId:" + report.ReportId + " returned 'FATAL'. See long detail for further details", reportString);
|
||||
return;
|
||||
}
|
||||
|
||||
// save to file
|
||||
string dirPath = Config.GetTempFileDirectoryPath() + @"\SP-API-Reports\";
|
||||
System.IO.Directory.CreateDirectory(dirPath);
|
||||
string reportFilePath = dirPath + report.ReportType.ToString() + " reportId_" + reportId + ".txt";
|
||||
System.IO.File.WriteAllText(reportFilePath, reportString);
|
||||
log.LogInformation("Amazon report #" + reportId + " sucessfully saved to disk.");
|
||||
this.ReportFilePath = reportFilePath;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// If a duplicate report has been recently requested, Amazon may return 'FATAL'. This method tests for, and attempts to retrive the duplicate report that is causing the error.
|
||||
/// </summary>
|
||||
/// <param name="report">Report to test for throttled response</param>
|
||||
/// <param name="specification">The specification that created to throttle report.</param>
|
||||
private bool SnapshotReportThrottleHanderler(ref string reportId, ParameterCreateReportSpecification specification, int snapshotMaxAgeMinutes)
|
||||
{
|
||||
if (report.ProcessingStatus != FikaAmazonAPI.AmazonSpApiSDK.Models.Reports.Report.ProcessingStatusEnum.FATAL)
|
||||
throw new Exception("Incorrect use of class, processing status must be fatal");
|
||||
|
||||
if (snapshotMaxAgeMinutes <= 0)
|
||||
{
|
||||
// report not avaiable
|
||||
throw new Exception( reportType.ToString() + " report not avaibale for requested timeframe");
|
||||
}
|
||||
|
||||
// search for valid reports with required timeframe
|
||||
var parameters = new ParameterReportList();
|
||||
parameters.reportTypes = new List<ReportTypes> { specification.reportType };
|
||||
parameters.createdSince = report.CreatedTime.Value.AddMinutes(-snapshotMaxAgeMinutes);
|
||||
parameters.marketplaceIds = specification.marketplaceIds;
|
||||
var reports = amznConn.Reports.GetReports(parameters);
|
||||
|
||||
if (reports == null || !reports.Any())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (var item in reports)
|
||||
{
|
||||
if (item.ProcessingStatus != FikaAmazonAPI.AmazonSpApiSDK.Models.Reports.Report.ProcessingStatusEnum.DONE
|
||||
|| item.ProcessingStatus != FikaAmazonAPI.AmazonSpApiSDK.Models.Reports.Report.ProcessingStatusEnum.INPROGRESS
|
||||
|| item.ProcessingStatus != FikaAmazonAPI.AmazonSpApiSDK.Models.Reports.Report.ProcessingStatusEnum.INQUEUE)
|
||||
{
|
||||
log.LogInformation("Amazon declinded requested report:" + item.ReportType.ToString() + " as another with same parameters already existes, substituting reportId " + reportId + " for " + item.ReportId);
|
||||
reportId = item.ReportId;
|
||||
report = item;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private string ExistingReportCheck(ParameterCreateReportSpecification specification)
|
||||
{
|
||||
// amazon may return 'fatal' due to report already existing and/or report request matches an recent existing request
|
||||
|
||||
// search for valid reports with required timeframe
|
||||
var parameters = new ParameterReportList();
|
||||
parameters.reportTypes = new List<ReportTypes> { specification.reportType };
|
||||
parameters.marketplaceIds = specification.marketplaceIds;
|
||||
var reportList = amznConn.Reports.GetReports(parameters);
|
||||
|
||||
// list is ordered with the most recent first
|
||||
foreach (var item in reportList)
|
||||
{
|
||||
if (item.ProcessingStatus == FikaAmazonAPI.AmazonSpApiSDK.Models.Reports.Report.ProcessingStatusEnum.DONE
|
||||
|| item.ProcessingStatus == FikaAmazonAPI.AmazonSpApiSDK.Models.Reports.Report.ProcessingStatusEnum.INPROGRESS
|
||||
|| item.ProcessingStatus == FikaAmazonAPI.AmazonSpApiSDK.Models.Reports.Report.ProcessingStatusEnum.INQUEUE)
|
||||
{
|
||||
if(item.DataStartTime == specification.dataStartTime
|
||||
&& item.DataEndTime == specification.dataEndTime)
|
||||
{
|
||||
return item.ReportId;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void WaitWhileProcessing(string reportId)
|
||||
{
|
||||
// set accordingly
|
||||
int waitPeriodIncrement = (1000 * 10);
|
||||
int waitPeriodIncrementMax = (1000 * 60);
|
||||
int waitPeriod = 0;
|
||||
int waitPeriodTotal = 0;
|
||||
int waitPeriodTotalTimeout = (1000 * 1200); // 20 minutes
|
||||
|
||||
while (waitPeriodTotal < waitPeriodTotalTimeout)
|
||||
{
|
||||
report = amznConn.Reports.GetReport(reportId);
|
||||
|
||||
if (report.ProcessingStatus == FikaAmazonAPI.AmazonSpApiSDK.Models.Reports.Report.ProcessingStatusEnum.INQUEUE)
|
||||
{
|
||||
ReportProcessingStatus = ProcessingStatus.INQUEUE;
|
||||
}
|
||||
|
||||
else if (report.ProcessingStatus == FikaAmazonAPI.AmazonSpApiSDK.Models.Reports.Report.ProcessingStatusEnum.INPROGRESS)
|
||||
{
|
||||
ReportProcessingStatus = ProcessingStatus.INPROGRESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
waitPeriod = waitPeriod + waitPeriodIncrement;
|
||||
if (waitPeriod > waitPeriodIncrementMax)
|
||||
waitPeriod = waitPeriodIncrementMax;
|
||||
|
||||
UI.Console.Wait("Report processing status " + ReportProcessingStatus + ". Check in {0} seconds...", waitPeriod);
|
||||
|
||||
waitPeriodTotal = waitPeriodTotal + waitPeriod;
|
||||
}
|
||||
throw new Exception("Amazon report processing for reportId:" + report.ReportId + " timeout after " + (waitPeriodTotal / 60000) + " minutes.");
|
||||
}
|
||||
|
||||
private void LogReportError(FikaAmazonAPI.AmazonSpApiSDK.Models.Reports.Report report, string errorTitle)
|
||||
{
|
||||
log.Initialise();
|
||||
log.LogError(errorTitle,
|
||||
"ReportType: " + report.ReportType + "\r\n"
|
||||
+ "ReportId: " + report.ReportId + "\r\n"
|
||||
+ "MarketplaceIds: " + report.MarketplaceIds + "\r\n"
|
||||
+ "CreatedTime: " + report.CreatedTime + "\r\n"
|
||||
+ "ReportScheduleId: " + report.ReportScheduleId + "\r\n"
|
||||
+ "ReportDocumentId: " + report.ReportDocumentId + "\r\n"
|
||||
+ "DataStartTime: " + report.DataStartTime + "\r\n"
|
||||
+ "DataEndTime: " + report.DataEndTime + "\r\n"
|
||||
+ "ProcessingStartTime: " + report.ProcessingStartTime + "\r\n"
|
||||
+ "ProcessingEndTime: " + report.ProcessingEndTime + "\r\n"
|
||||
+ "ProcessingStatus: " + report.ProcessingStatus + "\r\n"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using bnhtrade.Core.Data.Amazon.SellingPartnerAPI;
|
||||
using FikaAmazonAPI;
|
||||
using FikaAmazonAPI.Parameter.Report;
|
||||
using FikaAmazonAPI.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static FikaAmazonAPI.Utils.Constants;
|
||||
|
||||
namespace bnhtrade.Core.Data.Amazon.Report
|
||||
{
|
||||
public class SettlementReport : ReportLogic
|
||||
{
|
||||
public SettlementReport () : base(ReportTypes.GET_V2_SETTLEMENT_REPORT_DATA_FLAT_FILE_V2)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of reportId (not settlement report Id) for settlement reports available on the amazon api
|
||||
/// </summary>
|
||||
/// <returns>ReportId list</returns>
|
||||
public List<string> ListAvaliableReports()
|
||||
{
|
||||
UI.Console.WriteLine("Requesting list of avaliable settlement reports form Amazon SP-API");
|
||||
var reportList = ListAvailableReports();
|
||||
|
||||
var reportIdList = new List<string>();
|
||||
foreach (var report in reportList)
|
||||
{
|
||||
reportIdList.Add(report.ReportId);
|
||||
}
|
||||
|
||||
UI.Console.WriteLine(reportIdList.Count().ToString() + " Settlement reports avaible on Amazon SP-API");
|
||||
return reportIdList;
|
||||
}
|
||||
|
||||
public string GetReportFile(string reportId)
|
||||
{
|
||||
DownloadByReportId(reportId);
|
||||
return ReportFilePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using FikaAmazonAPI.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Amazon.SellingPartnerAPI
|
||||
{
|
||||
public class Defaults
|
||||
{
|
||||
public MarketPlace MarketPlaceId()
|
||||
{
|
||||
return MarketPlace.GetMarketPlaceByID(MarketPlaceIdAsString());
|
||||
}
|
||||
public string MarketPlaceIdAsString()
|
||||
{
|
||||
var config = new Config().GetConfiguration();
|
||||
return config.AppSettings.Settings["SpapiMarketplaceId"].Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,318 @@
|
||||
//using System;
|
||||
//using System.Collections.Generic;
|
||||
//using System.IO;
|
||||
//using System.Text;
|
||||
|
||||
//namespace bnhtrade.Core.Data.Amazon.SellingPartnerAPI.Services
|
||||
//{
|
||||
// public class ReportService : RequestService
|
||||
// {
|
||||
// private Dictionary<string, RestSharp.RestResponse<FikaAmazonAPI.AmazonSpApiSDK.Models.Reports.Report>> reportList;
|
||||
// private Dictionary<string, string> filePath;
|
||||
// private bool fatalEncounter = false;
|
||||
// protected Logic.Log.LogEvent log = new Logic.Log.LogEvent();
|
||||
// private int reportRequestCount = 0;
|
||||
|
||||
// public ReportService() : base(new AmazonCredential())
|
||||
// {
|
||||
// Innit();
|
||||
// }
|
||||
|
||||
// public ReportService(AmazonCredential amazonCredential) : base(amazonCredential)
|
||||
// {
|
||||
// Innit();
|
||||
// }
|
||||
|
||||
// public void Innit()
|
||||
// {
|
||||
// reportList = new Dictionary<string, RestSharp.RestResponse<FikaAmazonAPI.AmazonSpApiSDK.Models.Reports.Report>>();
|
||||
// filePath = new Dictionary<string, string>();
|
||||
// }
|
||||
|
||||
// public FikaAmazonAPI.AmazonSpApiSDK.Models.Reports.Report GetReport(string reportId, bool forceRequery = false)
|
||||
// {
|
||||
// // Rate limit: 2.0 requests per second, 15 burst
|
||||
// int rateLimitMilliseconds = 500;
|
||||
|
||||
// if (reportList.ContainsKey(reportId))
|
||||
// {
|
||||
// if (forceRequery)
|
||||
// {
|
||||
// reportList.Remove(reportId);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// return reportList[reportId].Data;
|
||||
// }
|
||||
// }
|
||||
|
||||
// // request report form amaozn
|
||||
// if (reportRequestCount == 0)
|
||||
// {
|
||||
// UI.Console.WriteLine("Requesting report from amazon SPAPI (ReportId:" + reportId + ").");
|
||||
// reportRequestCount = reportRequestCount + 1;
|
||||
// }
|
||||
|
||||
// CreateAuthorizedRequest(ReportApiUrls.GetReport(reportId), RestSharp.Method.Get);
|
||||
// var response = ExecuteRequestWithHttpInfo<SDK.Models.Reports.Report>(rateLimitMilliseconds);
|
||||
|
||||
// if (response == null)
|
||||
// { return null; }
|
||||
|
||||
// reportList.Add(response.Data.ReportId, response);
|
||||
// return response.Data;
|
||||
// }
|
||||
|
||||
// public List<SDK.Models.Reports.Report> GetReports(ParameterReportList parameterReportList)
|
||||
// {
|
||||
// var parameters = parameterReportList.getParameters();
|
||||
|
||||
// CreateAuthorizedRequest(ReportApiUrls.GetReports, RestSharp.Method.Get, parameters);
|
||||
// var response = ExecuteRequest<GetReportsResponseV00>();
|
||||
// parameterReportList.nextToken = response.NextToken;
|
||||
// var list = response.Reports;
|
||||
|
||||
// while (!string.IsNullOrEmpty(parameterReportList.nextToken))
|
||||
// {
|
||||
// var nextTokenResponse = GetReportsByNextToken(parameterReportList);
|
||||
// list.AddRange(nextTokenResponse.Reports);
|
||||
// parameterReportList.nextToken = nextTokenResponse.NextToken;
|
||||
// }
|
||||
// return list;
|
||||
// }
|
||||
|
||||
// public bool CancelReport(string reportId)
|
||||
// {
|
||||
|
||||
// CreateAuthorizedRequest(ReportApiUrls.CancelReport(reportId), RestSharp.Method.Delete);
|
||||
// var response = ExecuteRequest<CancelReportResponse>();
|
||||
// if (response != null && response.Errors != null)
|
||||
// return false;
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// public ReportScheduleList GetReportSchedules(ParameterReportSchedules parametersSchedules)
|
||||
// {
|
||||
// var parameters = parametersSchedules.getParameters();
|
||||
// CreateAuthorizedRequest(ReportApiUrls.GetReportSchedules, RestSharp.Method.Get, parameters);
|
||||
// var response = ExecuteRequest<GetReportSchedulesResponseV00>();
|
||||
// if (response != null && response.ReportSchedules != null)
|
||||
// return response.ReportSchedules;
|
||||
// return null;
|
||||
// }
|
||||
|
||||
// private GetReportsResponseV00 GetReportsByNextToken(ParameterReportList parameterReportList)
|
||||
// {
|
||||
// var parameterReportListNew = new ParameterReportList();
|
||||
// parameterReportListNew.nextToken = parameterReportList.nextToken;
|
||||
// var parameters = parameterReportListNew.getParameters();
|
||||
|
||||
// CreateAuthorizedRequest(ReportApiUrls.GetReports, RestSharp.Method.Get, parameters);
|
||||
// var response = ExecuteRequest<GetReportsResponseV00>();
|
||||
// return response;
|
||||
// }
|
||||
|
||||
// public string CreateReport(ParameterCreateReportSpecification createReportSpecification)
|
||||
// {
|
||||
// CreateAuthorizedRequest(ReportApiUrls.CreateReport, RestSharp.Method.Post, null, createReportSpecification);
|
||||
// var response = ExecuteRequest<SDK.Models.Reports.CreateReportResult>();
|
||||
|
||||
// if (response == null)
|
||||
// return null;
|
||||
|
||||
// string reportId = response.ReportId;
|
||||
|
||||
// return response.ReportId;
|
||||
// }
|
||||
|
||||
// public string CreateReportSchedule(ParameterCreateReportScheduleSpecification createReportScheduleSpecification)
|
||||
// {
|
||||
// CreateAuthorizedRequest(ReportApiUrls.CreateReportSchedule, RestSharp.Method.Post, null, createReportScheduleSpecification);
|
||||
// var response = ExecuteRequest<CreateReportScheduleResult>();
|
||||
|
||||
// if (response == null)
|
||||
// return null;
|
||||
|
||||
|
||||
// return response.ReportScheduleId;
|
||||
// }
|
||||
|
||||
// public ReportSchedule GetReportSchedule(string reportScheduleId)
|
||||
// {
|
||||
|
||||
// CreateAuthorizedRequest(ReportApiUrls.GetReportSchedule(reportScheduleId), RestSharp.Method.Get);
|
||||
// var response = ExecuteRequest<ReportSchedule>();
|
||||
// if (response != null)
|
||||
// return response;
|
||||
// return null;
|
||||
// }
|
||||
|
||||
// public ReportDocument GetReportDocument(string reportDocumentId, IParameterBasedPII ParameterBasedPII = null)
|
||||
// {
|
||||
// CreateAuthorizedRequest(ReportApiUrls.GetReportDocument(reportDocumentId), RestSharp.Method.Get, parameter: ParameterBasedPII);
|
||||
// var response = ExecuteRequest<ReportDocument>();
|
||||
// if (response != null)
|
||||
// return response;
|
||||
// return null;
|
||||
// }
|
||||
|
||||
// public bool WaitForReportProcessing(SDK.Models.Reports.Report report)
|
||||
// {
|
||||
// // wait for report processing loop
|
||||
// int checkCount = 0;
|
||||
// int checkRequency = 10000;
|
||||
|
||||
// while (true)
|
||||
// {
|
||||
// checkCount++;
|
||||
// if (checkCount > 60)
|
||||
// {
|
||||
// throw new Exception("GetReport timedout requesting reportId:" + report.ReportId + ".");
|
||||
// }
|
||||
|
||||
// if (report.ProcessingStatus == SDK.Models.Reports.Report.ProcessingStatusEnum.DONE)
|
||||
// {
|
||||
// UI.Console.WriteLine("Report proccessing status is 'DONE' (ReportId:" + report.ReportId + ").");
|
||||
// return true;
|
||||
// }
|
||||
// else if (report.ProcessingStatus == SDK.Models.Reports.Report.ProcessingStatusEnum.INPROGRESS)
|
||||
// {
|
||||
// // wait for 10 seconds between chacks
|
||||
// UI.Console.Wait("Report processing 'In Progress'. Updating in {0} seconds...", checkRequency);
|
||||
// report = GetReport(report.ReportId, true);
|
||||
// }
|
||||
// else if (report.ProcessingStatus == SDK.Models.Reports.Report.ProcessingStatusEnum.INQUEUE)
|
||||
// {
|
||||
// // wait for 10 seconds between chacks
|
||||
// UI.Console.Wait("Report processing 'In Queue'. Updating in {0} seconds...", checkRequency);
|
||||
// report = GetReport(report.ReportId, true);
|
||||
// }
|
||||
// else if (report.ProcessingStatus == SDK.Models.Reports.Report.ProcessingStatusEnum.CANCELLED)
|
||||
// {
|
||||
// // when report has been cancelled by client or amazon (no data)
|
||||
// return false;
|
||||
// }
|
||||
// else if (report.ProcessingStatus == SDK.Models.Reports.Report.ProcessingStatusEnum.FATAL)
|
||||
// {
|
||||
// // some report requests will return a 'FATAL' if they have already been requsted recently (15 minutes).
|
||||
// return false;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// throw new Exception("New ReportProcessingStatusEnum '" + report.ProcessingStatus + "' "
|
||||
// + " found for reportid:" + report.ReportId);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// Retrives file containing Amazon SP-API report
|
||||
// /// </summary>
|
||||
// /// <param name="reportId">Amazon SP-API unique report id</param>
|
||||
// /// <returns>File path for report</returns>
|
||||
// public string GetReportFile(string reportId)
|
||||
// {
|
||||
// if (string.IsNullOrWhiteSpace(reportId))
|
||||
// {
|
||||
// throw new Exception("invalid Report ID");
|
||||
// }
|
||||
|
||||
// // check for cached filepath
|
||||
// if (!filePath.ContainsKey(reportId))
|
||||
// {
|
||||
// var report = GetReport(reportId); // this can return null, need to deal with this
|
||||
|
||||
// if (WaitForReportProcessing(report))
|
||||
// {
|
||||
// // download report from url
|
||||
// string reportFilePath = GetFile(reportId);
|
||||
// filePath.Add(reportId, reportFilePath);
|
||||
// return reportFilePath;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// return null;
|
||||
// }
|
||||
// }
|
||||
|
||||
// return filePath[reportId];
|
||||
// }
|
||||
|
||||
// private string GetFile(string reportId)
|
||||
// {
|
||||
// // fatal error and reportDoument Id check
|
||||
// if (fatalEncounter)
|
||||
// {
|
||||
// if (string.IsNullOrWhiteSpace(reportList[reportId].Data.ReportDocumentId))
|
||||
// {
|
||||
// log.LogError("Fatal error from Amazon SPAPI when requesting reportId:" + reportId
|
||||
// , "The reason for the fatal error is unknown, no document was available for further information.");
|
||||
|
||||
// return "FATAL";
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// log.LogError("Fatal error from Amazon SPAPI when requesting reportId:" + reportId
|
||||
// , "The report was aborted due to a fatal error and a reportDocumentId is present. Check reportDocumentId as it may explain why the report processing ended.");
|
||||
// }
|
||||
// fatalEncounter = false;
|
||||
// }
|
||||
|
||||
// // as file url expires after 5 minutes, request just before download
|
||||
// UI.Console.WriteLine("Requesting download url for Amazon report (ReportId:" + reportId + ").");
|
||||
// var amazonFileInfo = GetReportDocument(reportList[reportId].Data.ReportDocumentId);
|
||||
|
||||
// // download report from url
|
||||
// log.LogInformation("Downloading Amazon report #" + reportId, "Report Document ID: " + amazonFileInfo.ReportDocumentId);
|
||||
// var response = new byte[0];
|
||||
// using (var webClient = new System.Net.WebClient())
|
||||
// {
|
||||
// response = webClient.DownloadData(amazonFileInfo.Url);
|
||||
// }
|
||||
|
||||
// string report = null;
|
||||
|
||||
// // decrypt report
|
||||
// UI.Console.WriteLine("Processing download (ReportId:" + reportId + ").");
|
||||
// if (amazonFileInfo.EncryptionDetails != null)
|
||||
// {
|
||||
// byte[] key = Encoding.ASCII.GetBytes(amazonFileInfo.EncryptionDetails.Key);
|
||||
// byte[] iv = Encoding.ASCII.GetBytes(amazonFileInfo.EncryptionDetails.InitializationVector);
|
||||
// report = Logic.Utilities.File.DecryptString(key, iv, response);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// report = Encoding.ASCII.GetString(response);
|
||||
// }
|
||||
|
||||
// // decompress
|
||||
// if (amazonFileInfo.CompressionAlgorithm != null)
|
||||
// {
|
||||
// report = Logic.Utilities.File.Decompress(report);
|
||||
// }
|
||||
|
||||
// // save to file
|
||||
// string reportFilePath = MiscFunction.GetTempFilePath(reportId + ".txt");
|
||||
// System.IO.File.WriteAllText(reportFilePath, report);
|
||||
// log.LogInformation("Amazon report #" + reportId + " sucessfully saved to disk.");
|
||||
// return reportFilePath;
|
||||
// }
|
||||
|
||||
// public bool CancelReportSchedule(string reportScheduleId)
|
||||
// {
|
||||
|
||||
// CreateAuthorizedRequest(ReportApiUrls.CancelReportSchedule(reportScheduleId), RestSharp.Method.Delete);
|
||||
// var response = ExecuteRequest<CancelReportScheduleResponse>();
|
||||
// if (response != null && response.Errors != null)
|
||||
// return false;
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// protected void SleepForRateLimit(IList<RestSharp.Parameter> headers)
|
||||
// {
|
||||
// // get report has limit rate 0.0222 per second (1 every 45 seconds) and a burst of 10
|
||||
// int defaultTime = 46000;
|
||||
// SleepForRateLimit(headers, defaultTime);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,53 @@
|
||||
using FikaAmazonAPI;
|
||||
using FikaAmazonAPI.Utils;
|
||||
using FikaAmazonAPI.AmazonSpApiSDK.Models.Token;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static FikaAmazonAPI.AmazonSpApiSDK.Services.EnvironemntManager;
|
||||
|
||||
namespace bnhtrade.Core.Data.Amazon.SellingPartnerAPI
|
||||
{
|
||||
class SpApiConnection
|
||||
{
|
||||
public AmazonConnection Connection { get; private set; }
|
||||
//public MarketPlace MarketPlace { get; private set; }
|
||||
//public string MarketPlaceId { get; private set; }
|
||||
|
||||
public SpApiConnection()
|
||||
{
|
||||
InnitConnection();
|
||||
}
|
||||
|
||||
private void InnitConnection()
|
||||
{
|
||||
// attempt to create credential object from app.local.config
|
||||
var credential = new FikaAmazonAPI.AmazonCredential();
|
||||
var config = new Config().GetConfiguration();
|
||||
try
|
||||
{
|
||||
string dataSource = config.AppSettings.Settings["DbDataSource"].Value;
|
||||
|
||||
credential = new FikaAmazonAPI.AmazonCredential();
|
||||
//credential.AccessKey = config.AppSettings.Settings["SpapiAccessKey"].Value;
|
||||
//credential.SecretKey = config.AppSettings.Settings["SpapiSecretKey"].Value;
|
||||
//credential.RoleArn = config.AppSettings.Settings["SpapiRoleArn"].Value;
|
||||
credential.ClientId = config.AppSettings.Settings["SpapiClientId"].Value;
|
||||
credential.ClientSecret = config.AppSettings.Settings["SpapiClientSecret"].Value;
|
||||
credential.RefreshToken = config.AppSettings.Settings["SpapiRefreshToken"].Value;
|
||||
credential.MarketPlaceID = config.AppSettings.Settings["SpapiMarketplaceId"].Value;
|
||||
//credential.IsDebugMode = true;
|
||||
credential.MaxThrottledRetryCount = 3;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception("Unable to retirve Amazon SP API credentials: " + ex.Message);
|
||||
}
|
||||
|
||||
this.Connection = new AmazonConnection(credential);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml;
|
||||
|
||||
namespace bnhtrade.Core.Data.Amazon.SellingPartnerAPI.Utils
|
||||
{
|
||||
public class CurrentDateTime
|
||||
{
|
||||
public DateTime GetUtc()
|
||||
{
|
||||
var xmlDoc = new XmlDocument();
|
||||
xmlDoc.Load("https://mws.amazonservices.com/");
|
||||
DateTime returnTime = default(DateTime);
|
||||
|
||||
XmlNodeList elemList = xmlDoc.GetElementsByTagName("Timestamp");
|
||||
for (int i = 0; i < elemList.Count; i++)
|
||||
{
|
||||
string attrVal = elemList[i].Attributes["timestamp"].Value;
|
||||
if (!string.IsNullOrWhiteSpace(attrVal))
|
||||
{
|
||||
returnTime = DateTime.SpecifyKind(DateTime.Parse(attrVal), DateTimeKind.Utc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (returnTime == default(DateTime))
|
||||
{
|
||||
throw new Exception("Error requesting time from Amazon");
|
||||
}
|
||||
|
||||
returnTime = returnTime.AddTicks(-(returnTime.Ticks % TimeSpan.TicksPerSecond));
|
||||
|
||||
return returnTime;
|
||||
}
|
||||
|
||||
public DateTime GetLocal()
|
||||
{
|
||||
return GetUtc().ToLocalTime();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Account
|
||||
{
|
||||
internal class ReadContact : Connection
|
||||
{
|
||||
private bnhtrade.Core.Data.Database.SqlWhereBuilder sqlBuilder;
|
||||
|
||||
public List<int> ContactIdList { get; set; }
|
||||
|
||||
public ReadContact()
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
sqlBuilder = new SqlWhereBuilder();
|
||||
ContactIdList = new List<int>();
|
||||
}
|
||||
|
||||
public Dictionary<int, Model.Account.Contact> Read()
|
||||
{
|
||||
var returnList = new Dictionary<int, Model.Account.Contact>();
|
||||
sqlBuilder.Init();
|
||||
|
||||
//build sql query
|
||||
string sql = @"
|
||||
SELECT [ContactID]
|
||||
,[ContactName]
|
||||
,[PaypalName]
|
||||
,[PaypalEmail]
|
||||
,[EbayUsername]
|
||||
,[EbayEmail]
|
||||
,[RecordCreated]
|
||||
,[RecordModified]
|
||||
FROM [e2A].[dbo].[tblContact]
|
||||
WHERE 1=1 ";
|
||||
|
||||
// build the where statments
|
||||
if (ContactIdList.Any())
|
||||
{
|
||||
sqlBuilder.In("[ContactID]", ContactIdList, "AND");
|
||||
}
|
||||
|
||||
// append where string to the sql
|
||||
if (sqlBuilder.IsSetSqlWhereString)
|
||||
{
|
||||
sql = sql + sqlBuilder.SqlWhereString;
|
||||
}
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
sqlBuilder.AddParametersToSqlCommand(cmd);
|
||||
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (reader.HasRows)
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
int contactId = reader.GetInt32(0);
|
||||
string contactName = null;
|
||||
if (!reader.IsDBNull(1)) { contactName = reader.GetString(1); }
|
||||
string paypalName = null;
|
||||
if (!reader.IsDBNull(2)) { paypalName = reader.GetString(2); }
|
||||
string paypalEmail = null;
|
||||
if (!reader.IsDBNull(3)) { paypalEmail = reader.GetString(3); }
|
||||
string ebayUsername = null;
|
||||
if (!reader.IsDBNull(4)) { ebayUsername = reader.GetString(4); }
|
||||
string ebayEmail = null;
|
||||
if (!reader.IsDBNull(5)) { ebayEmail = reader.GetString(5); }
|
||||
DateTime recordCreated = DateTime.SpecifyKind(reader.GetDateTime(6), DateTimeKind.Utc);
|
||||
DateTime? recordModified = null;
|
||||
if (!reader.IsDBNull(7)) { recordModified = DateTime.SpecifyKind(reader.GetDateTime(7), DateTimeKind.Utc); }
|
||||
|
||||
var contact = new Model.Account.Contact();
|
||||
contact.ContactId = contactId;
|
||||
contact.ContantName = contactName;
|
||||
contact.ContactPaypalName = paypalName;
|
||||
contact.ContactPaypalEmail = paypalEmail;
|
||||
contact.ContactEbayName = ebayUsername;
|
||||
contact.ContactEbayEmail = ebayEmail;
|
||||
contact.Created = recordCreated;
|
||||
contact.Modified = recordModified;
|
||||
|
||||
returnList.Add(contactId, contact);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnList;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Amazon
|
||||
{
|
||||
public class FeeEstimate : Connection
|
||||
{
|
||||
/// <summary>
|
||||
/// Update the tblAmazonFeeEstimate table (a new record will be created if it does not already exist to update)
|
||||
/// </summary>
|
||||
/// <param name="feeEstimate">Record to be updated/inserted into database</param>
|
||||
public void UpdateProductFeeEstimate(Model.Amazon.ProductFeeEstimate feeEstimate)
|
||||
{
|
||||
using (SqlConnection sqlConn = new SqlConnection(SqlConnectionString))
|
||||
{
|
||||
sqlConn.Open();
|
||||
|
||||
using (SqlCommand sqlCommand = new SqlCommand(@"
|
||||
UPDATE tblAmazonFeeEstimate SET
|
||||
ProductIdentifier=@productIdentifier, IsAmazonFulfilled=@isAmazonFulfilled, TimeOfFeeEstimation=@timeOfFeeEstimation,
|
||||
TotalFeeEstimate=@totalFeeEstimate, PriceToEstimateFeeListingPrice=@priceToEstimateFeeListingPrice,
|
||||
PriceToEstimateFeeShipping=@priceToEstimateFeeShipping, PriceToEstimateFeePoints=@priceToEstimateFeePoints,
|
||||
ReferralFee=@referralFee, VariableClosingFee=@variableClosingFee, PerItemFee=@perItemFee, FBAFee=@fbaFee,
|
||||
OtherFee_Exception=@otherFee_Exception, currencyCode=CurrencyCode
|
||||
WHERE AmazonASIN=@asin
|
||||
IF @@ROWCOUNT = 0
|
||||
INSERT INTO tblAmazonFeeEstimate ( AmazonASIN,
|
||||
ProductIdentifier, IsAmazonFulfilled, TimeOfFeeEstimation, TotalFeeEstimate, PriceToEstimateFeeListingPrice,
|
||||
PriceToEstimateFeeShipping, PriceToEstimateFeePoints, ReferralFee, VariableClosingFee, PerItemFee, FBAFee,
|
||||
OtherFee_Exception, CurrencyCode
|
||||
) VALUES ( @asin,
|
||||
@productIdentifier, @isAmazonFulfilled, @timeOfFeeEstimation, @totalFeeEstimate, @priceToEstimateFeeListingPrice,
|
||||
@priceToEstimateFeeShipping, @priceToEstimateFeePoints, @referralFee, @variableClosingFee, @perItemFee, @fbaFee,
|
||||
@otherFee_Exception, @currencyCode
|
||||
)
|
||||
", sqlConn))
|
||||
{
|
||||
sqlCommand.Parameters.AddWithValue("@asin", feeEstimate.Asin);
|
||||
sqlCommand.Parameters.AddWithValue("@productIdentifier", feeEstimate.ProductId);
|
||||
sqlCommand.Parameters.AddWithValue("@isAmazonFulfilled", feeEstimate.IsAmazonFulfilled);
|
||||
sqlCommand.Parameters.AddWithValue("@timeOfFeeEstimation", feeEstimate.TimeOfFeeEstimation);
|
||||
sqlCommand.Parameters.AddWithValue("@totalFeeEstimate", feeEstimate.TotalFeeEstimate);
|
||||
sqlCommand.Parameters.AddWithValue("@priceToEstimateFeeListingPrice", feeEstimate.PriceToEstimateFeeListingPrice);
|
||||
sqlCommand.Parameters.AddWithValue("@priceToEstimateFeeShipping", feeEstimate.PriceToEstimateFeeShipping);
|
||||
sqlCommand.Parameters.AddWithValue("@priceToEstimateFeePoints", feeEstimate.PriceToEstimateFeePoints);
|
||||
sqlCommand.Parameters.AddWithValue("@referralFee", feeEstimate.ReferralFee);
|
||||
sqlCommand.Parameters.AddWithValue("@variableClosingFee", feeEstimate.VariableClosingFee);
|
||||
sqlCommand.Parameters.AddWithValue("@perItemFee", feeEstimate.PerItemFee);
|
||||
sqlCommand.Parameters.AddWithValue("@fbaFee", feeEstimate.FulfillmentFees);
|
||||
sqlCommand.Parameters.AddWithValue("@otherFee_Exception", feeEstimate.OtherFee_Exception);
|
||||
sqlCommand.Parameters.AddWithValue("@currencyCode", feeEstimate.CurrencyCode);
|
||||
|
||||
sqlCommand.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.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()
|
||||
{
|
||||
}
|
||||
|
||||
/// <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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.AmazonShipment
|
||||
{
|
||||
public class ReadShipmentPrimaryKey : Connection
|
||||
{
|
||||
private bool enableCache = false;
|
||||
private Dictionary<string, int> shipmentPKByAmazonShipmentIdDic;
|
||||
private Dictionary<int, string> amazonShipmentIdByShipmentPKDic;
|
||||
|
||||
public ReadShipmentPrimaryKey()
|
||||
{
|
||||
}
|
||||
|
||||
public bool CacheEnabled
|
||||
{
|
||||
get { return enableCache; }
|
||||
set
|
||||
{
|
||||
if (value && enableCache == false)
|
||||
{
|
||||
shipmentPKByAmazonShipmentIdDic = new Dictionary<string, int>();
|
||||
amazonShipmentIdByShipmentPKDic = new Dictionary<int, string>();
|
||||
}
|
||||
else
|
||||
{
|
||||
shipmentPKByAmazonShipmentIdDic = null;
|
||||
amazonShipmentIdByShipmentPKDic = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ClearCache()
|
||||
{
|
||||
if (CacheEnabled)
|
||||
{
|
||||
shipmentPKByAmazonShipmentIdDic.Clear();
|
||||
amazonShipmentIdByShipmentPKDic.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
private void DeleteCachedShipmentPK(int shipmentPrimaryKey)
|
||||
{
|
||||
if (CacheEnabled)
|
||||
{
|
||||
if (amazonShipmentIdByShipmentPKDic.ContainsKey(shipmentPrimaryKey))
|
||||
{
|
||||
string amazonShipmentId = amazonShipmentIdByShipmentPKDic[shipmentPrimaryKey];
|
||||
shipmentPKByAmazonShipmentIdDic.Remove(amazonShipmentId);
|
||||
amazonShipmentIdByShipmentPKDic.Remove(shipmentPrimaryKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrives table primary key 'AmazonShipmentID' for tblAmazonShipment
|
||||
/// </summary>
|
||||
/// <param name="amazonShipmentId">Amazon's inbound FBA shipment Id.</param>
|
||||
/// <param name="forceDBQuery">Forces a database query when cache is enabled.</param>
|
||||
/// <returns>Primary key or -1 if match isn't found.</returns>
|
||||
public int ByAmazonShipmentId(string amazonShipmentId, bool forceDBQuery = false)
|
||||
{
|
||||
if (amazonShipmentId.Length < 5)
|
||||
{
|
||||
throw new Exception("Incorrect Amazon shipment if supplied '" + amazonShipmentId + "'");
|
||||
}
|
||||
|
||||
// first, query class dictionary before sql call
|
||||
if (CacheEnabled
|
||||
&& forceDBQuery == false
|
||||
&& shipmentPKByAmazonShipmentIdDic.ContainsKey(amazonShipmentId))
|
||||
{
|
||||
return shipmentPKByAmazonShipmentIdDic[amazonShipmentId];
|
||||
}
|
||||
|
||||
int shipmentPK = -1;
|
||||
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
SELECT AmazonShipmentID
|
||||
FROM tblAmazonShipment
|
||||
WHERE (((tblAmazonShipment.ShipmentId)=@amazonShipmentId));
|
||||
", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@amazonShipmentId", amazonShipmentId);
|
||||
|
||||
object obj = cmd.ExecuteScalar();
|
||||
|
||||
if (obj == null || obj == DBNull.Value)
|
||||
{
|
||||
return shipmentPK;
|
||||
}
|
||||
else
|
||||
{
|
||||
shipmentPK = (int)obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
UpdateCache(shipmentPK, amazonShipmentId);
|
||||
return shipmentPK;
|
||||
}
|
||||
|
||||
private void UpdateCache(int shipmentPK, string amazonShipmentId)
|
||||
{
|
||||
if (CacheEnabled)
|
||||
{
|
||||
DeleteCachedShipmentPK(shipmentPK);
|
||||
|
||||
shipmentPKByAmazonShipmentIdDic.Add(amazonShipmentId, shipmentPK);
|
||||
amazonShipmentIdByShipmentPKDic.Add(shipmentPK, amazonShipmentId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,252 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Transactions;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.AmazonShipment
|
||||
{
|
||||
public class SetShipmentInfo : Connection
|
||||
{
|
||||
private ReadShipmentPrimaryKey getPK;
|
||||
private Data.Database.Sku.GetSkuId skuIdLoopkup;
|
||||
|
||||
public SetShipmentInfo()
|
||||
{
|
||||
}
|
||||
|
||||
private ReadShipmentPrimaryKey GetPK
|
||||
{
|
||||
get
|
||||
{
|
||||
if (getPK == null)
|
||||
{
|
||||
getPK = new ReadShipmentPrimaryKey();
|
||||
}
|
||||
return getPK;
|
||||
}
|
||||
set
|
||||
{
|
||||
getPK = value;
|
||||
}
|
||||
}
|
||||
|
||||
private Data.Database.Sku.GetSkuId SkuIdLoopkup
|
||||
{
|
||||
get
|
||||
{
|
||||
if (skuIdLoopkup == null)
|
||||
{
|
||||
skuIdLoopkup = new Sku.GetSkuId();
|
||||
}
|
||||
return skuIdLoopkup;
|
||||
}
|
||||
}
|
||||
|
||||
public void Excecute(Model.AmazonFba.ShipmentInfo info)
|
||||
{
|
||||
using (var scope = new TransactionScope())
|
||||
{
|
||||
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
// input checks
|
||||
if (!info.IsSetAll())
|
||||
{
|
||||
throw new Exception("Insurficent ShipmentInfo parameters.");
|
||||
}
|
||||
|
||||
// get tablePK
|
||||
int shipmentPK = GetPK.ByAmazonShipmentId(info.FbaShipmentId);
|
||||
|
||||
// add or update shipment header info
|
||||
if (shipmentPK == -1)
|
||||
{
|
||||
shipmentPK = InsertShipmentHeaderInfo(info);
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateShipmentHeaderInfo(info);
|
||||
DeleteShipmentItems(shipmentPK);
|
||||
}
|
||||
|
||||
// insert new shipment item info
|
||||
foreach (var item in info.ShipmentItemInfoList)
|
||||
{
|
||||
int skuId = SkuIdLoopkup.BySKUNumber(item.SKUNumber);
|
||||
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
INSERT INTO tblAmazonShipmentItem (
|
||||
AmazonShipmentID
|
||||
,SkuID
|
||||
,QuantityAllocated
|
||||
,QuantityReceived
|
||||
)
|
||||
VALUES (
|
||||
@amazonShipmentID
|
||||
,@skuID
|
||||
,@quantityAllocated
|
||||
,@quantityReceived
|
||||
)
|
||||
", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@amazonShipmentID", shipmentPK);
|
||||
cmd.Parameters.AddWithValue("@skuID", skuId);
|
||||
cmd.Parameters.AddWithValue("@quantityAllocated", item.QuantityAllocated);
|
||||
cmd.Parameters.AddWithValue("@quantityReceived", item.QuantityReceived);
|
||||
|
||||
int effected = (int)cmd.ExecuteNonQuery();
|
||||
|
||||
if (effected == 0)
|
||||
{
|
||||
throw new Exception("Error, no tblAmazonShipment was not updated.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
scope.Complete();
|
||||
}
|
||||
}
|
||||
|
||||
public void ExcecuteByList(List<Model.AmazonFba.ShipmentInfo> infoList)
|
||||
{
|
||||
using (var scope = new TransactionScope())
|
||||
{
|
||||
foreach (var item in infoList)
|
||||
{
|
||||
Excecute(item);
|
||||
}
|
||||
scope.Complete();
|
||||
}
|
||||
}
|
||||
|
||||
private void DeleteShipmentItems(int shipmentId)
|
||||
{
|
||||
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
DELETE FROM
|
||||
tblAmazonShipmentItem
|
||||
WHERE
|
||||
AmazonShipmentId = @shipmentId
|
||||
", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@shipmentId", shipmentId);
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int InsertShipmentHeaderInfo(Model.AmazonFba.ShipmentInfo info)
|
||||
{
|
||||
if (!info.IsSetAll())
|
||||
{
|
||||
throw new Exception("Unsuficent properties set in Shipment Header Info.");
|
||||
}
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
if (GetPK.ByAmazonShipmentId(info.FbaShipmentId) != -1)
|
||||
{
|
||||
throw new Exception("Shipment insert failed, shipment with same Amazon Id already exists.");
|
||||
}
|
||||
|
||||
// get next shipment Number in sequence and create shipment name
|
||||
int sequenceNumber;
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
SELECT NEXT VALUE FOR dbo.ShipmentCountSequence AS SequenceNumber
|
||||
", conn))
|
||||
{
|
||||
sequenceNumber = (int)cmd.ExecuteScalar();
|
||||
}
|
||||
// info.ShipmentName = "FBA_Shipment_" + sequenceNumber.ToString().PadLeft(4, '0') + "_" + info.DestinationFulfillmentCenterId;
|
||||
|
||||
// make the insert
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
INSERT INTO tblAmazonShipment (
|
||||
AmazonShipmentCount
|
||||
,ShipmentName
|
||||
,ShipmentId
|
||||
,CenterId
|
||||
,ShipmentStatus
|
||||
,LastUpdated
|
||||
,IsClosed
|
||||
)
|
||||
OUTPUT INSERTED.AmazonShipmentID
|
||||
VALUES (
|
||||
@amazonShipmentCount
|
||||
,@shipmentName
|
||||
,@shipmentId
|
||||
,@centerId
|
||||
,@shipmentStatus
|
||||
,@lastUpdated
|
||||
,@isClosed
|
||||
)
|
||||
", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@amazonShipmentCount", sequenceNumber);
|
||||
cmd.Parameters.AddWithValue("@shipmentName", info.ShipmentName);
|
||||
cmd.Parameters.AddWithValue("@shipmentId", info.FbaShipmentId);
|
||||
cmd.Parameters.AddWithValue("@centerId", info.DestinationFulfillmentCenterId);
|
||||
cmd.Parameters.AddWithValue("@shipmentStatus", info.ShipmentStatus);
|
||||
cmd.Parameters.AddWithValue("@lastUpdated", info.LastUpdated.ToUniversalTime());
|
||||
cmd.Parameters.AddWithValue("@isClosed", info.ShipmentIsClosed);
|
||||
|
||||
int tablePk = (int)cmd.ExecuteScalar();
|
||||
|
||||
// update cache and return
|
||||
return tablePk;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateShipmentHeaderInfo(Model.AmazonFba.ShipmentInfo info)
|
||||
{
|
||||
int tablePK = GetPK.ByAmazonShipmentId(info.FbaShipmentId);
|
||||
if (tablePK == -1)
|
||||
{
|
||||
throw new Exception("Shipment insert failed, shipment with same Amazon Id already exists.");
|
||||
}
|
||||
|
||||
// make the update
|
||||
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
UPDATE tblAmazonShipment
|
||||
SET
|
||||
ShipmentName = @shipmentName
|
||||
,ShipmentStatus = @shipmentStatus
|
||||
,LastUpdated = @lastUpdated
|
||||
,IsClosed = @isClosed
|
||||
WHERE
|
||||
AmazonShipmentID = @tablePK
|
||||
", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@shipmentName", info.ShipmentName);
|
||||
cmd.Parameters.AddWithValue("@shipmentStatus", info.ShipmentStatus);
|
||||
cmd.Parameters.AddWithValue("@lastUpdated", info.LastUpdated.ToUniversalTime());
|
||||
cmd.Parameters.AddWithValue("@isClosed", info.ShipmentIsClosed);
|
||||
cmd.Parameters.AddWithValue("@tablePK", tablePK);
|
||||
|
||||
int count = cmd.ExecuteNonQuery();
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
throw new Exception("No records updated");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
using System;
|
||||
using System.Configuration;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database
|
||||
{
|
||||
public class Connection
|
||||
{
|
||||
//protected readonly string SqlConnectionString;
|
||||
private Model.Credentials.bnhtradeDB _dbCredentials;
|
||||
|
||||
protected string SqlConnectionString
|
||||
{
|
||||
get { return _dbCredentials.ConnectionString; }
|
||||
}
|
||||
|
||||
public Connection()
|
||||
{
|
||||
var config = new Config().GetConfiguration();
|
||||
|
||||
// attempt to retrive credentials from app.local.config
|
||||
try
|
||||
{
|
||||
string dataSource = config.AppSettings.Settings["DbDataSource"].Value;
|
||||
string userId = config.AppSettings.Settings["DbUserId"].Value;
|
||||
string pass = config.AppSettings.Settings["DbUserPassword"].Value;
|
||||
|
||||
// check
|
||||
if (string.IsNullOrEmpty(dataSource))
|
||||
{
|
||||
throw new ArgumentException("Could not retrive 'DbDataSource' from config file");
|
||||
}
|
||||
else if (string.IsNullOrEmpty(userId))
|
||||
{
|
||||
throw new ArgumentException("Could not retrive 'DbUserId' from config file");
|
||||
}
|
||||
else if (string.IsNullOrEmpty(pass))
|
||||
{
|
||||
throw new ArgumentException("Could not retrive 'DbUserPassword' from config file");
|
||||
}
|
||||
|
||||
var dbCredentials = new bnhtrade.Core.Model.Credentials.bnhtradeDB(dataSource, userId, pass);
|
||||
this._dbCredentials = dbCredentials;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception("Unable to retirve DB credentials: " + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private void ConnectionOld()
|
||||
{
|
||||
// attempt to retrive credentials from app.local.config
|
||||
try
|
||||
{
|
||||
string dataSource = ConfigurationManager.AppSettings["DbDataSource"];
|
||||
string userId = ConfigurationManager.AppSettings["DbUserId"];
|
||||
string pass = ConfigurationManager.AppSettings["DbUserPassword"];
|
||||
|
||||
// check
|
||||
if (string.IsNullOrEmpty(dataSource))
|
||||
{
|
||||
throw new ArgumentException("Could not retrive 'DbDataSource' from config file");
|
||||
}
|
||||
else if (string.IsNullOrEmpty(userId))
|
||||
{
|
||||
throw new ArgumentException("Could not retrive 'DbUserId' from config file");
|
||||
}
|
||||
else if (string.IsNullOrEmpty(pass))
|
||||
{
|
||||
throw new ArgumentException("Could not retrive 'DbUserPassword' from config file");
|
||||
}
|
||||
|
||||
var dbCredentials = new bnhtrade.Core.Model.Credentials.bnhtradeDB(dataSource, userId, pass);
|
||||
this._dbCredentials = dbCredentials;
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
throw new Exception("Unable to retirve DB credentials: " + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public Connection(Model.Credentials.bnhtradeDB dbCredentials)
|
||||
{
|
||||
// setup sql parameters
|
||||
if (dbCredentials == null)
|
||||
{
|
||||
throw new Exception("DB credentials object is null");
|
||||
}
|
||||
this._dbCredentials = dbCredentials;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
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
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the date bnhtrade started trading, UK time (datetime kind unspecified).
|
||||
/// </summary>
|
||||
/// <returns>The UK date and time the business started (datetime kind unspecified)</returns>
|
||||
public static DateTime GetBusinessStartUk()
|
||||
{
|
||||
return new Logic.Utilities.DateTime().ConvertUtcToUk(GetBusinessStartUtc());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the date bnhtrade started trading, as UTC time
|
||||
/// </summary>
|
||||
/// <returns>The UTC date and time the business started (datetime kind UTC)</returns>
|
||||
public static DateTime GetBusinessStartUtc()
|
||||
{
|
||||
DateTime businessStart = new DateTime(2014, 08, 31, 23, 00, 00); // 2014-09-01 uk date time
|
||||
return DateTime.SpecifyKind(businessStart, DateTimeKind.Utc);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static string GetMarginSchemeTaxCode()
|
||||
{
|
||||
return "T190";
|
||||
}
|
||||
|
||||
public static string GetOrderChannelAmazonUk()
|
||||
{
|
||||
return "Amazon.co.uk";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the sql table ID for a condition type
|
||||
/// </summary>
|
||||
public enum SkuCondition
|
||||
{
|
||||
New = 10,
|
||||
LikeNew = 11,
|
||||
VeryGood = 12,
|
||||
Good = 13,
|
||||
Acceptable = 14,
|
||||
// add the rest as needed
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the sql table ID for a Stock Journal Type
|
||||
/// </summary>
|
||||
public enum StockJournalType
|
||||
{
|
||||
SkuReconciliationFbaReceipt = 6,
|
||||
SkuReconciliationFbaShipment = 7,
|
||||
SkuReconciliationFbaAdjustment = 8,
|
||||
SkuReconciliationFbaCustomerReturn = 9,
|
||||
SkuReconciliationFbaVendorReturn = 10,
|
||||
SkuReconciliationFbaReimbursement = 11,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the sql table ID for a stock status
|
||||
/// </summary>
|
||||
public enum StockStatus
|
||||
{
|
||||
FbaFulfillable = 15,
|
||||
FbaSold = 12,
|
||||
ReservedGarageStock = 16,
|
||||
Reserved = 11,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the sql table ID for a stock status type
|
||||
/// </summary>
|
||||
public enum StockStatusType
|
||||
{
|
||||
FbaInventoryActive = 3,
|
||||
FbaShipment = 4,
|
||||
FbaShippingPlan = 5,
|
||||
// add the rest as needed
|
||||
}
|
||||
|
||||
public enum OrderChannel
|
||||
{
|
||||
US = 1,
|
||||
UK = 2,
|
||||
De = 3,
|
||||
Fr = 4,
|
||||
It = 5,
|
||||
Es = 6,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Export
|
||||
{
|
||||
internal class AmazonFeedSubmissionInsert : Connection
|
||||
{
|
||||
public AmazonFeedSubmissionInsert ()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Dapper;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Export
|
||||
{
|
||||
internal class AmazonFeedSubmissionRead : Connection
|
||||
{
|
||||
public AmazonFeedSubmissionRead()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
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 Microsoft.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Export
|
||||
{
|
||||
internal class AmazonFeedSubmissionUpdate : Connection
|
||||
{
|
||||
public AmazonFeedSubmissionUpdate()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
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.");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,244 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Import
|
||||
{
|
||||
public class AmazonFbaCustomerReturn : Connection
|
||||
{
|
||||
Logic.Log.LogEvent log = new Logic.Log.LogEvent();
|
||||
|
||||
public AmazonFbaCustomerReturn()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public bool UpdateByFlatFile(string filePath)
|
||||
{
|
||||
SqlConnection sqlConn;
|
||||
SqlTransaction trans;
|
||||
try
|
||||
{
|
||||
using (sqlConn = new SqlConnection(SqlConnectionString))
|
||||
{
|
||||
sqlConn.Open();
|
||||
using (trans = sqlConn.BeginTransaction())
|
||||
using (var reader = new StreamReader(filePath))
|
||||
{
|
||||
//read file one line at a time and insert data into table if required
|
||||
int lineNumber = 1;
|
||||
int lineErrorSkip = 0;
|
||||
int lineDuplicateSkip = 0;
|
||||
|
||||
// read header and retrive information
|
||||
string headerRow = reader.ReadLine();
|
||||
string[] headers = headerRow.Split('\t');
|
||||
|
||||
int columnCount = headers.Length;
|
||||
|
||||
int index01 = Array.IndexOf(headers, "return-date");
|
||||
int index02 = Array.IndexOf(headers, "order-id");
|
||||
int index03 = Array.IndexOf(headers, "sku");
|
||||
int index04 = Array.IndexOf(headers, "asin");
|
||||
int index05 = Array.IndexOf(headers, "fnsku");
|
||||
int index06 = Array.IndexOf(headers, "quantity");
|
||||
int index07 = Array.IndexOf(headers, "fulfillment-center-id");
|
||||
int index08 = Array.IndexOf(headers, "detailed-disposition");
|
||||
int index09 = Array.IndexOf(headers, "reason");
|
||||
int index10 = Array.IndexOf(headers, "status");
|
||||
int index11 = Array.IndexOf(headers, "license-plate-number");
|
||||
int index12 = Array.IndexOf(headers, "customer-comments");
|
||||
|
||||
string fileRow;
|
||||
while ((fileRow = reader.ReadLine()) != null)
|
||||
{
|
||||
lineNumber = lineNumber + 1;
|
||||
Console.Write("\rParsing record: " + lineNumber);
|
||||
//split line into array
|
||||
string[] items = fileRow.Split('\t');
|
||||
if (items.Length != columnCount)
|
||||
{
|
||||
// skip line
|
||||
lineErrorSkip = lineErrorSkip + 1;
|
||||
log.LogWarning(
|
||||
"Line #" + lineNumber + " skipped due to no enough element in row.",
|
||||
filePath
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
//read values
|
||||
string returnDate = items[index01];
|
||||
string orderId = items[index02];
|
||||
string sku = items[index03];
|
||||
string asin = items[index04];
|
||||
string fnsku = items[index05];
|
||||
string quantity = items[index06];
|
||||
string fulfillmentCenterId = items[index07];
|
||||
string detailedDisposition = items[index08];
|
||||
string reason = items[index09];
|
||||
string status = items[index10];
|
||||
string licensePlateNumber = items[index11];
|
||||
string customerComments = items[index12];
|
||||
|
||||
// check number of times line conbination appears in file
|
||||
int fileCount = 0;
|
||||
int dbCount = 0;
|
||||
using (var dupReader = new StreamReader(filePath))
|
||||
{
|
||||
dupReader.ReadLine(); // read header row
|
||||
string dupFileRow;
|
||||
while ((dupFileRow = dupReader.ReadLine()) != null)
|
||||
{
|
||||
string[] dupItems = dupFileRow.Split('\t');
|
||||
if (dupItems.Length != columnCount)
|
||||
{
|
||||
// skip
|
||||
}
|
||||
else
|
||||
{
|
||||
if (items[index01] == dupItems[index01] &&
|
||||
items[index02] == dupItems[index02] &&
|
||||
items[index05] == dupItems[index05] &&
|
||||
items[index11] == dupItems[index11])
|
||||
{
|
||||
// count will always find at least one (itself)
|
||||
fileCount = fileCount + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//check for duplicate line in db
|
||||
using (SqlCommand cmd = new SqlCommand(
|
||||
"SELECT COUNT(ImportFbaCustomerReturnID) FROM tblImportFbaCustomerReturn " +
|
||||
"WHERE [return-date]=@returnDate AND [order-id]=@orderId AND [fnsku]=@fnsku " +
|
||||
"AND ([license-plate-number]=@licensePlateNumber OR [license-plate-number] IS NULL) ;"
|
||||
, sqlConn, trans))
|
||||
{
|
||||
if (returnDate == "") { cmd.Parameters.AddWithValue("@returnDate", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@returnDate", DateTime.Parse(returnDate).ToUniversalTime()); }
|
||||
if (orderId == "") { cmd.Parameters.AddWithValue("@orderId", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@orderId", orderId); }
|
||||
if (fnsku == "") { cmd.Parameters.AddWithValue("@fnsku", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@fnsku", fnsku); }
|
||||
if (licensePlateNumber == "") { cmd.Parameters.AddWithValue("@licensePlateNumber", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@licensePlateNumber", licensePlateNumber); }
|
||||
|
||||
dbCount = (int)cmd.ExecuteScalar();
|
||||
}
|
||||
|
||||
if (fileCount <= dbCount)
|
||||
{
|
||||
//skip
|
||||
lineDuplicateSkip = lineDuplicateSkip + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
//insert report items
|
||||
using (SqlCommand insertCmd = new SqlCommand(
|
||||
"INSERT INTO tblImportFbaCustomerReturn ( " +
|
||||
"[return-date], [order-id], sku, asin, fnsku, " +
|
||||
"quantity, [fulfillment-center-id], [detailed-disposition], reason, status, " +
|
||||
"[license-plate-number], [customer-comments] ) " +
|
||||
"VALUES ( " +
|
||||
"@returnDate, @orderId, @sku, @asin, @fnsku, " +
|
||||
"@quantity, @fulfillmentCenterId, @detailedDisposition, @reason, @status, " +
|
||||
"@licensePlateNumber, @customerComments );"
|
||||
, sqlConn, trans))
|
||||
{
|
||||
// add parameters
|
||||
if (returnDate == "") { insertCmd.Parameters.AddWithValue("@returnDate", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@returnDate", DateTime.Parse(returnDate).ToUniversalTime()); }
|
||||
if (orderId == "") { insertCmd.Parameters.AddWithValue("@orderId", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@orderId", orderId); }
|
||||
if (sku == "") { insertCmd.Parameters.AddWithValue("@sku", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@sku", sku); }
|
||||
if (asin == "") { insertCmd.Parameters.AddWithValue("@asin", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@asin", asin); }
|
||||
if (fnsku == "") { insertCmd.Parameters.AddWithValue("@fnsku", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@fnsku", fnsku); }
|
||||
if (quantity == "") { insertCmd.Parameters.AddWithValue("@quantity", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@quantity", int.Parse(quantity)); }
|
||||
if (fulfillmentCenterId == "") { insertCmd.Parameters.AddWithValue("@fulfillmentCenterId", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@fulfillmentCenterId", fulfillmentCenterId); }
|
||||
if (detailedDisposition == "") { insertCmd.Parameters.AddWithValue("@detailedDisposition", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@detailedDisposition", detailedDisposition); }
|
||||
if (reason == "") { insertCmd.Parameters.AddWithValue("@reason", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@reason", reason); }
|
||||
if (status == "") { insertCmd.Parameters.AddWithValue("@status", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@status", status); }
|
||||
if (licensePlateNumber == "") { insertCmd.Parameters.AddWithValue("@licensePlateNumber", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@licensePlateNumber", licensePlateNumber); }
|
||||
if (customerComments == "") { insertCmd.Parameters.AddWithValue("@customerComments", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@customerComments", customerComments); }
|
||||
|
||||
insertCmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
trans.Commit();
|
||||
Console.Write("\r");
|
||||
log.LogInformation((lineNumber - (1 + lineErrorSkip + lineDuplicateSkip)) + " total new items inserted, " + lineDuplicateSkip + " duplicates were skipped.");
|
||||
if (lineErrorSkip > 0)
|
||||
{
|
||||
log.LogWarning(lineErrorSkip + " total line(s) where skipped due to insufficent number of cells on row");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.LogError("Error running FbaInventoryReceiptReportImport, no records were commited",
|
||||
ex.ToString() + "\r\nTraceMessage:\r\n" + MiscFunction.TraceMessage()
|
||||
);
|
||||
|
||||
throw ex;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public DateTime ReadRecentDate()
|
||||
{
|
||||
DateTime lastRecordDate;
|
||||
SqlConnection sqlConn;
|
||||
try
|
||||
{
|
||||
using (sqlConn = new SqlConnection(SqlConnectionString))
|
||||
{
|
||||
sqlConn.Open();
|
||||
using (SqlCommand cmd = new SqlCommand(
|
||||
"SELECT Max([return-date]) AS MaxDate FROM tblImportFbaCustomerReturn;"
|
||||
, sqlConn))
|
||||
{
|
||||
if (cmd.ExecuteScalar() == DBNull.Value)
|
||||
{
|
||||
// use first month started selling on Amazon
|
||||
lastRecordDate = lastRecordDate = Constants.GetBusinessStartUtc();
|
||||
}
|
||||
else
|
||||
{
|
||||
lastRecordDate = ((DateTime)cmd.ExecuteScalar());
|
||||
lastRecordDate = DateTime.SpecifyKind(lastRecordDate, DateTimeKind.Utc);
|
||||
}
|
||||
|
||||
return lastRecordDate;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.LogError("Error running GetFbaReturnsReport, no records were commited",
|
||||
ex.ToString() + "\r\nTraceMessage:\r\n" + MiscFunction.TraceMessage()
|
||||
);
|
||||
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,242 @@
|
||||
using System;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System.IO;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Import
|
||||
{
|
||||
public class AmazonFbaInventoryAdjustment : Connection
|
||||
{
|
||||
private Logic.Log.LogEvent log = new Logic.Log.LogEvent();
|
||||
|
||||
public AmazonFbaInventoryAdjustment()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public bool InsertByFlatFile(string filePath)
|
||||
{
|
||||
SqlConnection sqlConn;
|
||||
SqlTransaction trans;
|
||||
try
|
||||
{
|
||||
using (sqlConn = new SqlConnection(SqlConnectionString))
|
||||
{
|
||||
sqlConn.Open();
|
||||
using (trans = sqlConn.BeginTransaction())
|
||||
using (var reader = new StreamReader(filePath))
|
||||
{
|
||||
//read file one line at a time and insert data into table if required
|
||||
int lineNumber = 1;
|
||||
int lineErrorSkip = 0;
|
||||
int lineDuplicateSkip = 0;
|
||||
|
||||
// read header and retrive information
|
||||
string headerRow = reader.ReadLine();
|
||||
string[] headers = headerRow.Split('\t');
|
||||
|
||||
int columnCount = headers.Length;
|
||||
|
||||
int index01 = Array.IndexOf(headers, "adjusted-date");
|
||||
int index02 = Array.IndexOf(headers, "transaction-item-id");
|
||||
int index03 = Array.IndexOf(headers, "fnsku");
|
||||
int index04 = Array.IndexOf(headers, "sku");
|
||||
int index05 = Array.IndexOf(headers, "product-name");
|
||||
int index06 = Array.IndexOf(headers, "fulfillment-center-id");
|
||||
int index07 = Array.IndexOf(headers, "quantity");
|
||||
int index08 = Array.IndexOf(headers, "reason");
|
||||
int index09 = Array.IndexOf(headers, "disposition");
|
||||
|
||||
string fileRow;
|
||||
while ((fileRow = reader.ReadLine()) != null)
|
||||
{
|
||||
lineNumber = lineNumber + 1;
|
||||
Console.Write("\rParsing record: " + lineNumber);
|
||||
//split line into array
|
||||
string[] items = fileRow.Split('\t');
|
||||
if (items.Length != columnCount)
|
||||
{
|
||||
// skip line
|
||||
lineErrorSkip = lineErrorSkip + 1;
|
||||
log.LogWarning(
|
||||
"Line #" + lineNumber + " skipped due to no enough element in row.",
|
||||
filePath
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
//read values
|
||||
string adjustmentDate = items[index01];
|
||||
string transactionItemId = items[index02];
|
||||
string fnsku = items[index03];
|
||||
string sku = items[index04];
|
||||
string fulfillmentCenterId = items[index06];
|
||||
string quantity = items[index07];
|
||||
string reason = items[index08];
|
||||
string disposition = items[index09];
|
||||
|
||||
// check number of times line combination appears in file
|
||||
// don't think is a nesseary step, the transactionItemId is a unique identifier, I'm 99% sure
|
||||
int fileCount = 0;
|
||||
int dbCount = 0;
|
||||
using (var dupReader = new StreamReader(filePath))
|
||||
{
|
||||
dupReader.ReadLine(); // read header row
|
||||
string dupFileRow;
|
||||
while ((dupFileRow = dupReader.ReadLine()) != null)
|
||||
{
|
||||
string[] dupItems = dupFileRow.Split('\t');
|
||||
if (dupItems.Length != columnCount)
|
||||
{
|
||||
// skip
|
||||
}
|
||||
else
|
||||
{
|
||||
if (items[index01] == dupItems[index01] &&
|
||||
items[index02] == dupItems[index02] &&
|
||||
items[index03] == dupItems[index03] &&
|
||||
items[index06] == dupItems[index06] &&
|
||||
items[index08] == dupItems[index08] &&
|
||||
items[index09] == dupItems[index09]
|
||||
)
|
||||
{
|
||||
// count will always find at least one (itself)
|
||||
fileCount = fileCount + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//check for duplicate line in db
|
||||
|
||||
//using (SqlCommand cmd = new SqlCommand(
|
||||
// "SELECT COUNT(ImportFbaInventoryAdjustmentReportID) FROM tblImportFbaInventoryAdjustmentReport " +
|
||||
// "WHERE [adjusted-date]=@adjustmentDate AND [transaction-item-id]=@transactionItemId AND [fnsku]=@fnsku " +
|
||||
// " AND [fulfillment-center-id]=@fulfillmentCenterId AND [reason]=@reason AND [disposition]=@disposition;"
|
||||
// , sqlConn, trans))
|
||||
//{
|
||||
// if (adjustmentDate == "") { cmd.Parameters.AddWithValue("@adjustmentDate", DBNull.Value); }
|
||||
// else { cmd.Parameters.AddWithValue("@adjustmentDate", DateTime.Parse(adjustmentDate).ToUniversalTime()); }
|
||||
// if (transactionItemId == "") { cmd.Parameters.AddWithValue("@transactionItemId", DBNull.Value); }
|
||||
// else { cmd.Parameters.AddWithValue("@transactionItemId", transactionItemId); }
|
||||
// if (fnsku == "") { cmd.Parameters.AddWithValue("@fnsku", DBNull.Value); }
|
||||
// else { cmd.Parameters.AddWithValue("@fnsku", fnsku); }
|
||||
// if (fulfillmentCenterId == "") { cmd.Parameters.AddWithValue("@fulfillmentCenterId", DBNull.Value); }
|
||||
// else { cmd.Parameters.AddWithValue("@fulfillmentCenterId", fulfillmentCenterId); }
|
||||
// if (reason == "") { cmd.Parameters.AddWithValue("@reason", DBNull.Value); }
|
||||
// else { cmd.Parameters.AddWithValue("@reason", reason); }
|
||||
// if (disposition == "") { cmd.Parameters.AddWithValue("@disposition", DBNull.Value); }
|
||||
// else { cmd.Parameters.AddWithValue("@disposition", disposition); }
|
||||
|
||||
// dbCount = (int)cmd.ExecuteScalar();
|
||||
//}
|
||||
using (SqlCommand cmd = new SqlCommand(
|
||||
"SELECT COUNT(ImportFbaInventoryAdjustmentReportID) FROM tblImportFbaInventoryAdjustmentReport " +
|
||||
"WHERE [transaction-item-id]=@transactionItemId;"
|
||||
, sqlConn, trans))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@transactionItemId", transactionItemId);
|
||||
|
||||
dbCount = (int)cmd.ExecuteScalar();
|
||||
}
|
||||
|
||||
|
||||
if (fileCount <= dbCount)
|
||||
{
|
||||
//skip
|
||||
lineDuplicateSkip = lineDuplicateSkip + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
//insert report items
|
||||
using (SqlCommand insertCmd = new SqlCommand(
|
||||
"INSERT INTO tblImportFbaInventoryAdjustmentReport ( " +
|
||||
"[adjusted-date], [transaction-item-id], fnsku, sku, " +
|
||||
"[fulfillment-center-id], quantity, reason, disposition ) " +
|
||||
"VALUES ( " +
|
||||
"@adjustmentDate, @transactionItemId, @fnsku, @sku, " +
|
||||
"@fulfillmentCenterId, @quantity, @reason, @disposition );"
|
||||
, sqlConn, trans))
|
||||
{
|
||||
// add parameters
|
||||
if (adjustmentDate == "") { insertCmd.Parameters.AddWithValue("@adjustmentDate", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@adjustmentDate", DateTime.Parse(adjustmentDate).ToUniversalTime()); }
|
||||
if (transactionItemId == "") { insertCmd.Parameters.AddWithValue("@transactionItemId", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@transactionItemId", transactionItemId); }
|
||||
if (fnsku == "") { insertCmd.Parameters.AddWithValue("@fnsku", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@fnsku", fnsku); }
|
||||
if (sku == "") { insertCmd.Parameters.AddWithValue("@sku", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@sku", sku); }
|
||||
if (fulfillmentCenterId == "") { insertCmd.Parameters.AddWithValue("@fulfillmentCenterId", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@fulfillmentCenterId", fulfillmentCenterId); }
|
||||
if (quantity == "") { insertCmd.Parameters.AddWithValue("@quantity", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@quantity", int.Parse(quantity)); }
|
||||
if (reason == "") { insertCmd.Parameters.AddWithValue("@reason", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@reason", reason); }
|
||||
if (disposition == "") { insertCmd.Parameters.AddWithValue("@disposition", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@disposition", disposition); }
|
||||
|
||||
insertCmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
trans.Commit();
|
||||
Console.Write("\r");
|
||||
log.LogInformation((lineNumber - (1 + lineErrorSkip + lineDuplicateSkip)) + " total new items inserted, " + lineDuplicateSkip + " duplicates were skipped.");
|
||||
if (lineErrorSkip > 0)
|
||||
{
|
||||
log.LogError(lineErrorSkip + " total line(s) where skipped due to insufficent number of cells on row");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.LogError("Error running ImportFbaAdustmentReport method, no records were commited",
|
||||
ex.ToString() + "\r\nTraceMessage:\r\n" + MiscFunction.TraceMessage()
|
||||
);
|
||||
|
||||
throw ex;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public DateTime ReadRecentDate()
|
||||
{
|
||||
DateTime lastRecordDate;
|
||||
SqlConnection sqlConn;
|
||||
try
|
||||
{
|
||||
using (sqlConn = new SqlConnection(SqlConnectionString))
|
||||
{
|
||||
sqlConn.Open();
|
||||
using (SqlCommand cmd = new SqlCommand(
|
||||
"SELECT Max([adjusted-date]) AS MaxDate FROM tblImportFbaInventoryAdjustmentReport;"
|
||||
, sqlConn))
|
||||
{
|
||||
if (cmd.ExecuteScalar() == DBNull.Value)
|
||||
{
|
||||
// use first month started selling on Amazon
|
||||
lastRecordDate = lastRecordDate = Constants.GetBusinessStartUtc();
|
||||
}
|
||||
else
|
||||
{
|
||||
lastRecordDate = ((DateTime)cmd.ExecuteScalar());
|
||||
lastRecordDate = DateTime.SpecifyKind(lastRecordDate, DateTimeKind.Utc);
|
||||
}
|
||||
|
||||
return lastRecordDate;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.LogError("Error running GetFbaAdustmentData, no records were commited",
|
||||
ex.ToString() + "\r\nTraceMessage:\r\n" + MiscFunction.TraceMessage()
|
||||
);
|
||||
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,299 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Transactions;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Import
|
||||
{
|
||||
public class AmazonFbaInventoryAgeData : Connection
|
||||
{
|
||||
private Logic.Log.LogEvent log = new Logic.Log.LogEvent();
|
||||
|
||||
public AmazonFbaInventoryAgeData()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void InsertByFlatFile(string filePath)
|
||||
{
|
||||
SqlConnection sqlConn;
|
||||
try
|
||||
{
|
||||
using (TransactionScope scope = new TransactionScope())
|
||||
{
|
||||
using (sqlConn = new SqlConnection(SqlConnectionString))
|
||||
{
|
||||
sqlConn.Open();
|
||||
//clear table data
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
DELETE FROM tblImportFbaInventoryAgeReport;
|
||||
", sqlConn))
|
||||
{
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
using (var reader = new StreamReader(filePath))
|
||||
{
|
||||
//read file one line at a time and insert data into table if required
|
||||
int lineNumber = 1;
|
||||
int lineErrorSkip = 0;
|
||||
int lineNoStockSkip = 0;
|
||||
|
||||
// read header and retrive information
|
||||
string headerRow = reader.ReadLine();
|
||||
string[] headers = headerRow.Split('\t');
|
||||
|
||||
int columnCount = headers.Length;
|
||||
|
||||
if (columnCount != 38)
|
||||
{
|
||||
throw new Exception("Chnages found to 'Fba Inventory Age Data' flatfile structure");
|
||||
}
|
||||
|
||||
int index01 = Array.IndexOf(headers, "snapshot-date");
|
||||
int index02 = Array.IndexOf(headers, "marketplace");
|
||||
int index03 = Array.IndexOf(headers, "sku");
|
||||
int index04 = Array.IndexOf(headers, "fnsku");
|
||||
int index05 = Array.IndexOf(headers, "asin");
|
||||
int index06 = Array.IndexOf(headers, "product-name");
|
||||
int index07 = Array.IndexOf(headers, "condition");
|
||||
int index08 = Array.IndexOf(headers, "avaliable-quantity(sellable)");
|
||||
int index09 = Array.IndexOf(headers, "qty-with-removals-in-progress");
|
||||
int index10 = Array.IndexOf(headers, "inv-age-0-to-90-days");
|
||||
int index11 = Array.IndexOf(headers, "inv-age-91-to-180-days");
|
||||
int index12 = Array.IndexOf(headers, "inv-age-181-to-270-days");
|
||||
int index13 = Array.IndexOf(headers, "inv-age-271-to-365-days");
|
||||
int index14 = Array.IndexOf(headers, "inv-age-365-plus-days");
|
||||
int index15 = Array.IndexOf(headers, "currency");
|
||||
int index16 = Array.IndexOf(headers, "qty-to-be-charged-ltsf-6-mo");
|
||||
int index17 = Array.IndexOf(headers, "projected-ltsf-6-mo");
|
||||
int index18 = Array.IndexOf(headers, "qty-to-be-charged-ltsf-12-mo");
|
||||
int index19 = Array.IndexOf(headers, "projected-ltsf-12-mo");
|
||||
int index20 = Array.IndexOf(headers, "units-shipped-last-7-days");
|
||||
int index21 = Array.IndexOf(headers, "units-shipped-last-30-days");
|
||||
int index22 = Array.IndexOf(headers, "units-shipped-last-60-days");
|
||||
int index23 = Array.IndexOf(headers, "units-shipped-last-90-days");
|
||||
int index24 = Array.IndexOf(headers, "alert");
|
||||
int index25 = Array.IndexOf(headers, "your-price");
|
||||
int index26 = Array.IndexOf(headers, "sales_price");
|
||||
int index27 = Array.IndexOf(headers, "lowest_price_new");
|
||||
int index28 = Array.IndexOf(headers, "lowest_price_used");
|
||||
int index29 = Array.IndexOf(headers, "Recommended action");
|
||||
int index30 = Array.IndexOf(headers, "Healthy Inventory Level");
|
||||
int index31 = Array.IndexOf(headers, "Recommended sales price");
|
||||
int index32 = Array.IndexOf(headers, "Recommended sale duration (days)");
|
||||
int index33 = Array.IndexOf(headers, "Recommended Removal Quantity");
|
||||
int index34 = Array.IndexOf(headers, "estimated-cost-savings-of-recommended-actions");
|
||||
int index35 = Array.IndexOf(headers, "sell-through");
|
||||
|
||||
string fileRow;
|
||||
while ((fileRow = reader.ReadLine()) != null)
|
||||
{
|
||||
lineNumber = lineNumber + 1;
|
||||
Console.Write("\rParsing record: " + lineNumber);
|
||||
//split line into array
|
||||
string[] items = fileRow.Split('\t');
|
||||
if (items.Length != columnCount)
|
||||
{
|
||||
// skip line
|
||||
lineErrorSkip = lineErrorSkip + 1;
|
||||
log.LogWarning(
|
||||
"Line #" + lineNumber + " skipped due to no enough element in row.",
|
||||
filePath
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
//read values
|
||||
string snapshotDate = items[index01];
|
||||
string marketplace = items[index02];
|
||||
string sku = items[index03];
|
||||
string fnsku = items[index04];
|
||||
string asin = items[index05];
|
||||
string productName = items[index06];
|
||||
string condition = items[index07];
|
||||
string avaliableQuantity = items[index08];
|
||||
string qtyWithRemovalsInProgress = items[index09];
|
||||
string invAge0To90Days = items[index10];
|
||||
string invAge91To180Days = items[index11];
|
||||
string invAge181To270Days = items[index12];
|
||||
string invAge271To365Days = items[index13];
|
||||
string invAge365PlusDays = items[index14];
|
||||
string currency = items[index15];
|
||||
string qtyToBeChargedLtsf6Mo = items[index16];
|
||||
string projectedLtsf6Mo = Regex.Replace(items[index17], "[^.0-9]", ""); // strip currency code prefix
|
||||
string qtyToBeChargedLtsf12Mo = items[index18];
|
||||
string projectedLtsf12Mo = Regex.Replace(items[index19], "[^.0-9]", ""); // strip currency code prefix
|
||||
string unitsShippedLast7Days = items[index20];
|
||||
string unitsShippedLast30Days = items[index21];
|
||||
string unitsShippedLast60Days = items[index22];
|
||||
string unitsShippedLast90Days = items[index23];
|
||||
string alert = items[index24];
|
||||
string yourPrice = Regex.Replace(items[index25], "[^.0-9]", ""); // strip currency code prefix
|
||||
string salesPrice = Regex.Replace(items[index26], "[^.0-9]", ""); // strip currency code prefix
|
||||
string lowestPriceNew = Regex.Replace(items[index27], "[^.0-9]", ""); // strip currency code prefix
|
||||
string lowestPriceUsed = Regex.Replace(items[index28], "[^.0-9]", ""); // strip currency code prefix
|
||||
string recommendedAction = items[index29];
|
||||
string healthyInventoryLevel = items[index30];
|
||||
string recommendedSalesPrice = Regex.Replace(items[index31], "[^.0-9]", ""); // strip currency code prefix
|
||||
string recommendedSaleDuration = items[index32];
|
||||
string recommendedRemovalQuantity = items[index33];
|
||||
string estimatedCostSavingsOfRecommendedActions = items[index34];
|
||||
string sellThrough = items[index35];
|
||||
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
INSERT INTO tblImportFbaInventoryAgeReport(
|
||||
[snapshot-date], marketplace, sku, fnsku, asin, [product-name], condition, [avaliable-quantity(sellable)],
|
||||
[qty-with-removals-in-progress], [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], currency, [qty-to-be-charged-ltsf-6-mo], [projected-ltsf-6-mo],
|
||||
[qty-to-be-charged-ltsf-12-mo], [projected-ltsf-12-mo], [units-shipped-last-7-days], [units-shipped-last-30-days],
|
||||
[units-shipped-last-60-days], [units-shipped-last-90-days], alert, [your-price], sales_price, lowest_price_new,
|
||||
lowest_price_used, [Recommended action], [Healthy Inventory Level], [Recommended sales price],
|
||||
[Recommended sale duration (days)], [Recommended Removal Quantity], [estimated-cost-savings-of-recommended-actions],
|
||||
[sell-through] )
|
||||
VALUES (
|
||||
@snapshotDate, @marketplace, @sku, @fnsku, @asin, @productName, @condition, @avaliableQuantity,
|
||||
@qtyWithRemovalsInProgress, @invAge0To90Days, @invAge91To180Days, @invAge181To270Days, @invAge271To365Days, @invAge365PlusDays, @currency, @qtyToBeChargedLtsf6Mo,
|
||||
@projectedLtsf6Mo, @qtyToBeChargedLtsf12Mo, @projectedLtsf12Mo, @unitsShippedLast7Days, @unitsShippedLast30Days, @unitsShippedLast60Days, @unitsShippedLast90Days, @alert,
|
||||
@yourPrice, @salesPrice, @lowestPriceNew, @lowestPriceUsed, @recommendedAction, @healthyInventoryLevel, @recommendedSalesPrice,
|
||||
@recommendedSaleDuration, @recommendedRemovalQuantity, @estimatedCostSavingsOfRecommendedActions,
|
||||
@sellThrough );
|
||||
", sqlConn))
|
||||
{
|
||||
// add parameters
|
||||
if (snapshotDate.Length == 0) { cmd.Parameters.AddWithValue("@snapshotDate", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@snapshotDate", DateTime.Parse(snapshotDate).ToUniversalTime()); }
|
||||
|
||||
if (marketplace.Length == 0) { cmd.Parameters.AddWithValue("@marketplace", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@marketplace", marketplace); }
|
||||
|
||||
if (sku.Length == 0) { cmd.Parameters.AddWithValue("@sku", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@sku", sku); }
|
||||
|
||||
if (fnsku.Length == 0) { cmd.Parameters.AddWithValue("@fnsku", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@fnsku", fnsku); }
|
||||
|
||||
if (asin.Length == 0) { cmd.Parameters.AddWithValue("@asin", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@asin", asin); }
|
||||
|
||||
if (productName.Length == 0) { cmd.Parameters.AddWithValue("@productName", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@productName", productName); }
|
||||
|
||||
if (condition.Length == 0) { cmd.Parameters.AddWithValue("@condition", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@condition", condition); }
|
||||
|
||||
if (avaliableQuantity.Length == 0) { cmd.Parameters.AddWithValue("@avaliableQuantity", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@avaliableQuantity", int.Parse(avaliableQuantity)); }
|
||||
|
||||
if (qtyWithRemovalsInProgress.Length == 0) { cmd.Parameters.AddWithValue("@qtyWithRemovalsInProgress", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@qtyWithRemovalsInProgress", int.Parse(qtyWithRemovalsInProgress)); }
|
||||
|
||||
if (invAge0To90Days.Length == 0) { cmd.Parameters.AddWithValue("@invAge0To90Days", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@invAge0To90Days", int.Parse(invAge0To90Days)); }
|
||||
|
||||
if (invAge91To180Days.Length == 0) { cmd.Parameters.AddWithValue("@invAge91To180Days", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@invAge91To180Days", int.Parse(invAge91To180Days)); }
|
||||
|
||||
if (invAge181To270Days.Length == 0) { cmd.Parameters.AddWithValue("@invAge181To270Days", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@invAge181To270Days", int.Parse(invAge181To270Days)); }
|
||||
|
||||
if (invAge271To365Days.Length == 0) { cmd.Parameters.AddWithValue("@invAge271To365Days", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@invAge271To365Days", int.Parse(invAge271To365Days)); }
|
||||
|
||||
if (invAge365PlusDays.Length == 0) { cmd.Parameters.AddWithValue("@invAge365PlusDays", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@invAge365PlusDays", int.Parse(invAge365PlusDays)); }
|
||||
|
||||
if (currency.Length == 0) { cmd.Parameters.AddWithValue("@currency", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@currency", currency); }
|
||||
|
||||
if (qtyToBeChargedLtsf6Mo.Length == 0) { cmd.Parameters.AddWithValue("@qtyToBeChargedLtsf6Mo", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@qtyToBeChargedLtsf6Mo", int.Parse(qtyToBeChargedLtsf6Mo)); }
|
||||
|
||||
if (projectedLtsf6Mo.Length == 0) { cmd.Parameters.AddWithValue("@projectedLtsf6Mo", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@projectedLtsf6Mo", decimal.Parse(projectedLtsf6Mo)); }
|
||||
|
||||
if (qtyToBeChargedLtsf12Mo.Length == 0) { cmd.Parameters.AddWithValue("@qtyToBeChargedLtsf12Mo", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@qtyToBeChargedLtsf12Mo", int.Parse(qtyToBeChargedLtsf12Mo)); }
|
||||
|
||||
if (projectedLtsf12Mo.Length == 0) { cmd.Parameters.AddWithValue("@projectedLtsf12Mo", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@projectedLtsf12Mo", decimal.Parse(projectedLtsf12Mo)); }
|
||||
|
||||
if (unitsShippedLast7Days.Length == 0) { cmd.Parameters.AddWithValue("@unitsShippedLast7Days", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@unitsShippedLast7Days", int.Parse(unitsShippedLast7Days)); }
|
||||
|
||||
if (unitsShippedLast30Days.Length == 0) { cmd.Parameters.AddWithValue("@unitsShippedLast30Days", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@unitsShippedLast30Days", int.Parse(unitsShippedLast30Days)); }
|
||||
|
||||
if (unitsShippedLast60Days.Length == 0) { cmd.Parameters.AddWithValue("@unitsShippedLast60Days", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@unitsShippedLast60Days", int.Parse(unitsShippedLast60Days)); }
|
||||
|
||||
if (unitsShippedLast90Days.Length == 0) { cmd.Parameters.AddWithValue("@unitsShippedLast90Days", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@unitsShippedLast90Days", int.Parse(unitsShippedLast90Days)); }
|
||||
|
||||
if (alert.Length == 0) { cmd.Parameters.AddWithValue("@alert", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@alert", alert); }
|
||||
|
||||
if (yourPrice.Length == 0) { cmd.Parameters.AddWithValue("@yourPrice", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@yourPrice", decimal.Parse(yourPrice)); }
|
||||
|
||||
if (salesPrice.Length == 0) { cmd.Parameters.AddWithValue("@salesPrice", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@salesPrice", decimal.Parse(salesPrice)); }
|
||||
|
||||
if (lowestPriceNew.Length == 0) { cmd.Parameters.AddWithValue("@lowestPriceNew", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@lowestPriceNew", decimal.Parse(lowestPriceNew)); }
|
||||
|
||||
if (lowestPriceUsed.Length == 0) { cmd.Parameters.AddWithValue("@lowestPriceUsed", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@lowestPriceUsed", decimal.Parse(lowestPriceUsed)); }
|
||||
|
||||
if (recommendedAction.Length == 0) { cmd.Parameters.AddWithValue("@recommendedAction", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@recommendedAction", recommendedAction); }
|
||||
|
||||
if (healthyInventoryLevel.Length == 0) { cmd.Parameters.AddWithValue("@healthyInventoryLevel", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@healthyInventoryLevel", int.Parse(healthyInventoryLevel)); }
|
||||
|
||||
if (recommendedSalesPrice.Length == 0) { cmd.Parameters.AddWithValue("@recommendedSalesPrice", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@recommendedSalesPrice", decimal.Parse(recommendedSalesPrice)); }
|
||||
|
||||
if (recommendedSaleDuration.Length == 0) { cmd.Parameters.AddWithValue("@recommendedSaleDuration", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@recommendedSaleDuration", int.Parse(recommendedSaleDuration)); }
|
||||
|
||||
if (recommendedRemovalQuantity.Length == 0) { cmd.Parameters.AddWithValue("@recommendedRemovalQuantity", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@recommendedRemovalQuantity", int.Parse(recommendedRemovalQuantity)); }
|
||||
|
||||
if (estimatedCostSavingsOfRecommendedActions.Length == 0) { cmd.Parameters.AddWithValue("@estimatedCostSavingsOfRemoval", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@estimatedCostSavingsOfRecommendedActions", decimal.Parse(estimatedCostSavingsOfRecommendedActions)); }
|
||||
|
||||
if (sellThrough.Length == 0) { cmd.Parameters.AddWithValue("@sellThrough", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@sellThrough", decimal.Parse(sellThrough)); }
|
||||
|
||||
// execute the query
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
Console.Write("\r");
|
||||
log.LogInformation(
|
||||
"Operation complete. " + lineNumber + " items processes. " + (lineNumber - lineErrorSkip - lineNoStockSkip) + " total new items inserted, "
|
||||
+ lineNoStockSkip + " 'No Stock' records were skipped.");
|
||||
if (lineErrorSkip > 0)
|
||||
{
|
||||
log.LogError(lineErrorSkip + " total line(s) where skipped due to insufficent number of cells on row");
|
||||
}
|
||||
}
|
||||
}
|
||||
scope.Complete();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.LogError("Something went wrong during import, check details for more.", ex.ToString());
|
||||
Console.WriteLine(ex.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Import
|
||||
{
|
||||
public class AmazonFbaInventoryAgeRead : Connection
|
||||
{
|
||||
public AmazonFbaInventoryAgeRead()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,195 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Transactions;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Import
|
||||
{
|
||||
public class AmazonFbaInventoryData : Connection
|
||||
{
|
||||
Logic.Log.LogEvent log = new Logic.Log.LogEvent();
|
||||
|
||||
public AmazonFbaInventoryData()
|
||||
{
|
||||
}
|
||||
|
||||
public void InsertByFlatFile(string filePath)
|
||||
{
|
||||
SqlConnection sqlConn;
|
||||
try
|
||||
{
|
||||
using (TransactionScope scope = new TransactionScope())
|
||||
{
|
||||
using (sqlConn = new SqlConnection(SqlConnectionString))
|
||||
{
|
||||
sqlConn.Open();
|
||||
//clear table data
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
DELETE FROM tblImportFbaManageInventory;
|
||||
", sqlConn))
|
||||
{
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
using (var reader = new StreamReader(filePath))
|
||||
{
|
||||
//read file one line at a time and insert data into table if required
|
||||
int lineNumber = 1;
|
||||
int lineErrorSkip = 0;
|
||||
int lineNoStockSkip = 0;
|
||||
|
||||
// read header and retrive information
|
||||
string headerRow = reader.ReadLine();
|
||||
string[] headers = headerRow.Split('\t');
|
||||
|
||||
int columnCount = headers.Length;
|
||||
|
||||
int index01 = Array.IndexOf(headers, "sku");
|
||||
int index02 = Array.IndexOf(headers, "fnsku");
|
||||
int index03 = Array.IndexOf(headers, "asin");
|
||||
int index04 = Array.IndexOf(headers, "product-name");
|
||||
int index05 = Array.IndexOf(headers, "condition");
|
||||
int index06 = Array.IndexOf(headers, "your-price");
|
||||
int index07 = Array.IndexOf(headers, "mfn-listing-exists");
|
||||
int index08 = Array.IndexOf(headers, "mfn-fulfillable-quantity");
|
||||
int index09 = Array.IndexOf(headers, "afn-listing-exists");
|
||||
int index10 = Array.IndexOf(headers, "afn-warehouse-quantity");
|
||||
int index11 = Array.IndexOf(headers, "afn-fulfillable-quantity");
|
||||
int index12 = Array.IndexOf(headers, "afn-unsellable-quantity");
|
||||
int index13 = Array.IndexOf(headers, "afn-reserved-quantity");
|
||||
int index14 = Array.IndexOf(headers, "afn-total-quantity");
|
||||
int index15 = Array.IndexOf(headers, "per-unit-volume");
|
||||
int index16 = Array.IndexOf(headers, "afn-inbound-working-quantity");
|
||||
int index17 = Array.IndexOf(headers, "afn-inbound-shipped-quantity");
|
||||
int index18 = Array.IndexOf(headers, "afn-inbound-receiving-quantity");
|
||||
|
||||
string fileRow;
|
||||
while ((fileRow = reader.ReadLine()) != null)
|
||||
{
|
||||
lineNumber = lineNumber + 1;
|
||||
Console.Write("\rParsing record: " + lineNumber);
|
||||
//split line into array
|
||||
string[] items = fileRow.Split('\t');
|
||||
if (items.Length != columnCount)
|
||||
{
|
||||
// skip line
|
||||
lineErrorSkip = lineErrorSkip + 1;
|
||||
log.LogWarning(
|
||||
"Line #" + lineNumber + " skipped due to no enough element in row.",
|
||||
filePath
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
// only import sku with stock
|
||||
// afnTotalQuantity includes fba stock and inbound shipments
|
||||
string afnTotalQuantity = items[index14];
|
||||
//if (int.Parse(afnTotalQuantity) == 0)
|
||||
//{
|
||||
// lineNoStockSkip = lineNoStockSkip + 1;
|
||||
// continue;
|
||||
//}
|
||||
|
||||
//read values
|
||||
string sku = items[index01];
|
||||
string fnsku = items[index02];
|
||||
string asin = items[index03];
|
||||
string productName = items[index04];
|
||||
string condition = items[index05];
|
||||
string yourPrice = items[index06];
|
||||
string mfnListingExists = items[index07];
|
||||
string mfnFulfillableQuantity = items[index08];
|
||||
string afnListingExists = items[index09];
|
||||
string afnWarehouseQuantity = items[index10];
|
||||
string afnFulfillableQuantity = items[index11];
|
||||
string afnUnsellableQuantity = items[index12];
|
||||
string afnReservedQuantity = items[index13];
|
||||
string perUnitVolume = items[index15];
|
||||
string afnInboundWorkingQuantity = items[index16];
|
||||
string afnInboundShippedQuantity = items[index17];
|
||||
string afnInboundReceivingQuantity = items[index18];
|
||||
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
INSERT INTO tblImportFbaManageInventory(
|
||||
sku, fnsku, asin, [product-name], condition, [your-price], [mfn-listing-exists], [mfn-fulfillable-quantity],
|
||||
[afn-listing-exists], [afn-warehouse-quantity], [afn-fulfillable-quantity], [afn-unsellable-quantity],
|
||||
[afn-reserved-quantity], [afn-total-quantity], [per-unit-volume], [afn-inbound-working-quantity],
|
||||
[afn-inbound-shipped-quantity], [afn-inbound-receiving-quantity] )
|
||||
VALUES (
|
||||
@sku, @fnsku, @asin, @productName, @condition, @yourPrice, @mfnListingExists, @mfnFulfillableQuantity,
|
||||
@afnListingExists, @afnWarehouseQuantity, @afnFulfillableQuantity, @afnUnsellableQuantity,
|
||||
@afnReservedQuantity, @afnTotalQuantity, @perUnitVolume, @afnInboundWorkingQuantity,
|
||||
@afnInboundShippedQuantity, @afnInboundReceivingQuantity );
|
||||
", sqlConn))
|
||||
{
|
||||
// add parameters
|
||||
cmd.Parameters.AddWithValue("@sku", sku);
|
||||
|
||||
if (fnsku.Length == 0) { cmd.Parameters.AddWithValue("@fnsku", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@fnsku", fnsku); }
|
||||
if (asin.Length == 0) { cmd.Parameters.AddWithValue("@asin", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@asin", asin); }
|
||||
if (productName.Length == 0) { cmd.Parameters.AddWithValue("@productName", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@productName", productName); }
|
||||
if (condition.Length == 0) { cmd.Parameters.AddWithValue("@condition", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@condition", condition); }
|
||||
if (yourPrice.Length == 0) { cmd.Parameters.AddWithValue("@yourPrice", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@yourPrice", decimal.Parse(yourPrice)); }
|
||||
if (mfnListingExists.Length == 0) { cmd.Parameters.AddWithValue("@mfnListingExists", DBNull.Value); }
|
||||
else if (mfnListingExists == "Yes") { cmd.Parameters.AddWithValue("@mfnListingExists", true); }
|
||||
else { cmd.Parameters.AddWithValue("@mfnListingExists", false); }
|
||||
if (mfnFulfillableQuantity.Length == 0) { cmd.Parameters.AddWithValue("@mfnFulfillableQuantity", 0); }
|
||||
else { cmd.Parameters.AddWithValue("@mfnFulfillableQuantity", int.Parse(mfnFulfillableQuantity)); }
|
||||
if (afnListingExists.Length == 0) { cmd.Parameters.AddWithValue("@afnListingExists", DBNull.Value); }
|
||||
else if (afnListingExists == "Yes") { cmd.Parameters.AddWithValue("@afnListingExists", true); }
|
||||
else { cmd.Parameters.AddWithValue("@afnListingExists", false); }
|
||||
if (afnWarehouseQuantity.Length == 0) { cmd.Parameters.AddWithValue("@afnWarehouseQuantity", 0); }
|
||||
else { cmd.Parameters.AddWithValue("@afnWarehouseQuantity", int.Parse(afnWarehouseQuantity)); }
|
||||
if (afnFulfillableQuantity.Length == 0) { cmd.Parameters.AddWithValue("@afnFulfillableQuantity", 0); }
|
||||
else { cmd.Parameters.AddWithValue("@afnFulfillableQuantity", int.Parse(afnFulfillableQuantity)); }
|
||||
if (afnUnsellableQuantity.Length == 0) { cmd.Parameters.AddWithValue("@afnUnsellableQuantity", 0); }
|
||||
else { cmd.Parameters.AddWithValue("@afnUnsellableQuantity", int.Parse(afnUnsellableQuantity)); }
|
||||
if (afnReservedQuantity.Length == 0) { cmd.Parameters.AddWithValue("@afnReservedQuantity", 0); }
|
||||
else { cmd.Parameters.AddWithValue("@afnReservedQuantity", int.Parse(afnReservedQuantity)); }
|
||||
if (afnTotalQuantity.Length == 0) { cmd.Parameters.AddWithValue("@afnTotalQuantity", 0); }
|
||||
else { cmd.Parameters.AddWithValue("@afnTotalQuantity", int.Parse(afnTotalQuantity)); }
|
||||
if (perUnitVolume.Length == 0) { cmd.Parameters.AddWithValue("@perUnitVolume", 0); }
|
||||
else { cmd.Parameters.AddWithValue("@perUnitVolume", decimal.Parse(perUnitVolume)); }
|
||||
if (afnInboundWorkingQuantity.Length == 0) { cmd.Parameters.AddWithValue("@afnInboundWorkingQuantity", 0); }
|
||||
else { cmd.Parameters.AddWithValue("@afnInboundWorkingQuantity", int.Parse(afnInboundWorkingQuantity)); }
|
||||
if (afnInboundShippedQuantity.Length == 0) { cmd.Parameters.AddWithValue("@afnInboundShippedQuantity", 0); }
|
||||
else { cmd.Parameters.AddWithValue("@afnInboundShippedQuantity", int.Parse(afnInboundShippedQuantity)); }
|
||||
if (afnInboundReceivingQuantity.Length == 0) { cmd.Parameters.AddWithValue("@afnInboundReceivingQuantity", 0); }
|
||||
else { cmd.Parameters.AddWithValue("@afnInboundReceivingQuantity", int.Parse(afnInboundReceivingQuantity)); }
|
||||
|
||||
|
||||
// execute the query
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
Console.Write("\r");
|
||||
log.LogInformation(
|
||||
"Operation complete. " + lineNumber + " items processes. " + (lineNumber - lineErrorSkip - lineNoStockSkip) + " total new items inserted, "
|
||||
+ lineNoStockSkip + " 'No Stock' records were skipped.");
|
||||
if (lineErrorSkip > 0)
|
||||
{
|
||||
log.LogError(lineErrorSkip + " total line(s) where skipped due to insufficent number of cells on row");
|
||||
}
|
||||
}
|
||||
}
|
||||
scope.Complete();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.LogError("Something went wrong during import, check details for more.", ex.ToString());
|
||||
Console.WriteLine(ex.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,256 @@
|
||||
using Amazon.Runtime.Internal.Transform;
|
||||
using bnhtrade.Core.Logic.Amazon.Fba;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.Eventing.Reader;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Import
|
||||
{
|
||||
public class AmazonFbaInventoryLedgerDetail : Connection
|
||||
{
|
||||
public AmazonFbaInventoryLedgerDetail()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public Dictionary<int, Model.Import.AmazonFbaInventoryLedgerDetail> Insert(List<Model.Import.AmazonFbaInventoryLedgerDetail> insertList)
|
||||
{
|
||||
var returnDict = new Dictionary<int, Model.Import.AmazonFbaInventoryLedgerDetail>();
|
||||
|
||||
if (insertList == null || insertList.Any() == false)
|
||||
return returnDict;
|
||||
|
||||
SqlConnection conn;
|
||||
SqlTransaction trans;
|
||||
|
||||
using (conn = new SqlConnection(SqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
using (trans = conn.BeginTransaction())
|
||||
{
|
||||
foreach (var item in insertList)
|
||||
{
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
INSERT INTO tblImportFbaInventoryLedgerDetail (
|
||||
FNSKU
|
||||
,ASIN
|
||||
,MSKU
|
||||
,Title
|
||||
,[Event Type]
|
||||
,[Reference ID]
|
||||
,Quantity
|
||||
,[Fulfillment Center]
|
||||
,Disposition
|
||||
,Reason
|
||||
,Country
|
||||
,[Reconciled Quantity]
|
||||
,[Unreconciled Quantity]
|
||||
,[Date and Time]
|
||||
)
|
||||
OUTPUT INSERTED.ImportFbaInventoryLedgerDetailID
|
||||
VALUES (
|
||||
@fnsku
|
||||
,@asin
|
||||
,@msku
|
||||
,@title
|
||||
,@eventType
|
||||
,@referenceid
|
||||
,@quantity
|
||||
,@fulfillmentCenter
|
||||
,@disposition
|
||||
,@reason
|
||||
,@country
|
||||
,@reconciledQuantity
|
||||
,@unreconciledQuantity
|
||||
,@dateAndTime
|
||||
)
|
||||
", conn, trans))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@fnsku", item.Fnsku);
|
||||
cmd.Parameters.AddWithValue("@asin", item.Asin);
|
||||
cmd.Parameters.AddWithValue("@msku", item.Msku);
|
||||
cmd.Parameters.AddWithValue("@title", item.Title);
|
||||
cmd.Parameters.AddWithValue("@eventType", item.EventType);
|
||||
cmd.Parameters.AddWithValue("@referenceid", item.ReferenceId);
|
||||
cmd.Parameters.AddWithValue("@quantity", item.Quantity);
|
||||
cmd.Parameters.AddWithValue("@fulfillmentCenter", item.FulfillmentCenter);
|
||||
cmd.Parameters.AddWithValue("@disposition", item.Disposition);
|
||||
cmd.Parameters.AddWithValue("@reason", item.Reason);
|
||||
cmd.Parameters.AddWithValue("@country", item.Country);
|
||||
if (item.ReconciledQuantity == null) { cmd.Parameters.AddWithValue("@reconciledQuantity", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@reconciledQuantity", item.ReconciledQuantity); }
|
||||
if (item.UnreconciledQuantity == null) { cmd.Parameters.AddWithValue("@unreconciledQuantity", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@unreconciledQuantity", item.UnreconciledQuantity); }
|
||||
cmd.Parameters.AddWithValue("@dateAndTime", item.DateAndTime);
|
||||
|
||||
|
||||
object obj = cmd.ExecuteScalar();
|
||||
|
||||
if (obj == null || obj == DBNull.Value)
|
||||
{
|
||||
throw new Exception("Error inserting new defalt invoice line item into database");
|
||||
}
|
||||
|
||||
returnDict.Add((int)obj, item);
|
||||
}
|
||||
}
|
||||
if (insertList.Count != returnDict.Count)
|
||||
throw new Exception("AmazonFbaInventoryLedgerDetail db insert failed, not all records could be commmitted. Transaction rolled back");
|
||||
trans.Commit();
|
||||
return returnDict;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrives the AmazonFbaInventoryLedgerDetail object from the database
|
||||
/// </summary>
|
||||
/// <param name="utcFrom">date time filter</param>
|
||||
/// <param name="utcTo">date time filter</param>
|
||||
/// <param name="isProcessed">isprocessed filter</param>
|
||||
/// <returns>dictionary key=AmazonFbaInventoryLedgerDetailIs, value=AmazonFbaInventoryLedgerDetail object</returns>
|
||||
public Dictionary<int, Model.Import.AmazonFbaInventoryLedgerDetail> Read(DateTime? utcFrom = null, DateTime? utcTo = null, bool? isProcessed = null)
|
||||
{
|
||||
var resultList = new Dictionary<int, Model.Import.AmazonFbaInventoryLedgerDetail>();
|
||||
|
||||
string sql = @"
|
||||
SELECT TOP (1000) [ImportFbaInventoryLedgerDetailId]
|
||||
,[FNSKU]
|
||||
,[ASIN]
|
||||
,[MSKU]
|
||||
,[Title]
|
||||
,[Event Type]
|
||||
,[Reference ID]
|
||||
,[Quantity]
|
||||
,[Fulfillment Center]
|
||||
,[Disposition]
|
||||
,[Reason]
|
||||
,[Country]
|
||||
,[Reconciled Quantity]
|
||||
,[Unreconciled Quantity]
|
||||
,[Date and Time]
|
||||
,[IsProcessed]
|
||||
,[StockSkuTransactionID]
|
||||
FROM [e2A].[dbo].[tblImportFbaInventoryLedgerDetail]
|
||||
WHERE 1=1";
|
||||
|
||||
if (utcFrom != null)
|
||||
sql = sql + " AND [Date and Time] >= @utcFrom";
|
||||
if (utcTo != null)
|
||||
sql = sql + " AND [Date and Time] <= @utcFrom";
|
||||
if (isProcessed != null)
|
||||
sql = sql + " AND [IsProcessed] = @isProcessed";
|
||||
|
||||
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
if (utcFrom != null)
|
||||
cmd.Parameters.AddWithValue("@utcFrom", utcFrom);
|
||||
if (utcTo != null)
|
||||
cmd.Parameters.AddWithValue("@utcFrom", utcTo);
|
||||
if (isProcessed != null)
|
||||
cmd.Parameters.AddWithValue("@isProcessed", isProcessed);
|
||||
|
||||
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (reader.HasRows)
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
var result = new Model.Import.AmazonFbaInventoryLedgerDetail();
|
||||
|
||||
result.Fnsku = reader.GetString(1);
|
||||
result.Asin = reader.GetString(2);
|
||||
result.Msku = reader.GetString(3);
|
||||
result.Title = reader.GetString(4);
|
||||
result.EventType = reader.GetString(5);
|
||||
if (!reader.IsDBNull(6))
|
||||
result.ReferenceId = reader.GetString(6);
|
||||
result.Quantity = reader.GetInt32(7);
|
||||
result.FulfillmentCenter = reader.GetString(8);
|
||||
result.Disposition = reader.GetString(9);
|
||||
if (!reader.IsDBNull(10))
|
||||
result.Reason = reader.GetString(10);
|
||||
result.Country = reader.GetString(11);
|
||||
if (!reader.IsDBNull(12))
|
||||
result.ReconciledQuantity = reader.GetInt32(12);
|
||||
if (!reader.IsDBNull(13))
|
||||
result.UnreconciledQuantity = reader.GetInt32(13);
|
||||
result.DateAndTime = DateTime.SpecifyKind(reader.GetDateTime(14), DateTimeKind.Utc);
|
||||
|
||||
resultList.Add(reader.GetInt32(0), result);
|
||||
}
|
||||
}
|
||||
return resultList;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the record as processed, where no entry has been made into the stock sku transaction table
|
||||
/// </summary>
|
||||
public void UpdateIsProcessed(int fbaInventoryLedgerDetailId, bool isProcessed)
|
||||
{
|
||||
UpdateIsProcessed(fbaInventoryLedgerDetailId, isProcessed, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the record as processed, and an entry has been made into the stock sku transaction table
|
||||
/// </summary>
|
||||
public void UpdateIsProcessed(int fbaInventoryLedgerDetailId, int stockSkuTransactionId)
|
||||
{
|
||||
UpdateIsProcessed(fbaInventoryLedgerDetailId, true, stockSkuTransactionId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use of the two methods above ensures that the transactionId can not be set when the isProcessed is false
|
||||
/// </summary>
|
||||
private void UpdateIsProcessed(int fbaInventoryLedgerDetailId, bool? isProcessed, int? stockSkuTransactionId)
|
||||
{
|
||||
string sql = @"
|
||||
UPDATE
|
||||
tblImportFbaInventoryLedgerDetail
|
||||
SET
|
||||
IsProcessed = @isProcessed
|
||||
, StockSkuTransactionID = @stockSkuTransactionId
|
||||
WHERE
|
||||
(ImportFbaInventoryLedgerDetailID = @fbaInventoryLedgerDetailId)";
|
||||
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
if (isProcessed == null) { cmd.Parameters.AddWithValue("@isProcessed", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@isProcessed", isProcessed); }
|
||||
|
||||
if (stockSkuTransactionId == null) { cmd.Parameters.AddWithValue("@stockSkuTransactionId", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@stockSkuTransactionId", stockSkuTransactionId); }
|
||||
|
||||
cmd.Parameters.AddWithValue("@fbaInventoryLedgerDetailId", fbaInventoryLedgerDetailId);
|
||||
|
||||
int i = cmd.ExecuteNonQuery();
|
||||
|
||||
if (i < 1)
|
||||
throw new Exception("No row were effected by the update operation");
|
||||
|
||||
if (i > 1)
|
||||
throw new Exception("Multiple rows were effected by the update operation");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Import
|
||||
{
|
||||
public class AmazonFbaInventoryReceipt : Connection
|
||||
{
|
||||
private Logic.Log.LogEvent log = new Logic.Log.LogEvent();
|
||||
|
||||
public AmazonFbaInventoryReceipt()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public bool InsertByFlatFile(string filePath, DateTime startDate)
|
||||
{
|
||||
SqlConnection sqlConn;
|
||||
SqlTransaction trans;
|
||||
try
|
||||
{
|
||||
using (sqlConn = new SqlConnection(SqlConnectionString))
|
||||
{
|
||||
sqlConn.Open();
|
||||
using (trans = sqlConn.BeginTransaction())
|
||||
using (var reader = new StreamReader(filePath))
|
||||
{
|
||||
//read file one line at a time and insert data into table if required
|
||||
int lineNumber = 1;
|
||||
int lineErrorSkip = 0;
|
||||
int lineOutsideScope = 0;
|
||||
|
||||
// read header and retrive information
|
||||
string headerRow = reader.ReadLine();
|
||||
string[] headers = headerRow.Split('\t');
|
||||
|
||||
int columnCount = headers.Length;
|
||||
|
||||
// create notification if amazon add extra headers
|
||||
if (columnCount > 7)
|
||||
{
|
||||
log.LogWarning(
|
||||
"Amazon have added a new column to their 'Fba Inventory Receipt' report, you may want to check this out."
|
||||
);
|
||||
}
|
||||
|
||||
int indexOfReceivedDate = Array.IndexOf(headers, "received-date");
|
||||
int indexOfFnsku = Array.IndexOf(headers, "fnsku");
|
||||
int indexOfSku = Array.IndexOf(headers, "sku");
|
||||
int indexOfProductName = Array.IndexOf(headers, "product-name");
|
||||
int indexOfQuantity = Array.IndexOf(headers, "quantity");
|
||||
int indexOfFbaShipmentId = Array.IndexOf(headers, "fba-shipment-id");
|
||||
int indexOfFulfillmentCenterId = Array.IndexOf(headers, "fulfillment-center-id");
|
||||
|
||||
string fileRow;
|
||||
while ((fileRow = reader.ReadLine()) != null)
|
||||
{
|
||||
lineNumber = lineNumber + 1;
|
||||
Console.Write("\rParsing record: " + lineNumber);
|
||||
//split line into array
|
||||
string[] items = fileRow.Split('\t');
|
||||
if (items.Length != columnCount)
|
||||
{
|
||||
// skip line
|
||||
lineErrorSkip = lineErrorSkip + 1;
|
||||
log.LogWarning(
|
||||
"Line #" + lineNumber + " skipped due to no enough element in row.",
|
||||
filePath
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
//read values
|
||||
DateTime receivedDate = DateTime.Parse(
|
||||
items[indexOfReceivedDate],
|
||||
CultureInfo.InvariantCulture,
|
||||
DateTimeStyles.AssumeUniversal);
|
||||
|
||||
//ensure line has recieved date <= startdate
|
||||
// due to mws bug, downloaded report can contain records outside of the requested scope
|
||||
if (receivedDate < startDate)
|
||||
{
|
||||
lineOutsideScope = lineOutsideScope + 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
string fnsku = items[indexOfFnsku];
|
||||
string sku = items[indexOfSku];
|
||||
int quantity = int.Parse(items[indexOfQuantity]);
|
||||
string fbaShipemntId = items[indexOfFbaShipmentId];
|
||||
string fulfillmentCenterId = items[indexOfFulfillmentCenterId];
|
||||
|
||||
//insert report items
|
||||
using (SqlCommand insertCmd = new SqlCommand(
|
||||
"INSERT INTO tblImportFbaInventoryReceiptReport ( " +
|
||||
"[received-date], [fnsku], [sku], [quantity], [fba-shipment-id], [fulfillment-center-id] ) " +
|
||||
"VALUES ( " +
|
||||
"@receivedDate, @fnsku, @sku, @quantity, @FbaShipmentId, @FulfillmentCenterId );"
|
||||
, sqlConn, trans))
|
||||
{
|
||||
// add parameters
|
||||
insertCmd.Parameters.AddWithValue("@receivedDate", receivedDate.ToUniversalTime());
|
||||
insertCmd.Parameters.AddWithValue("@fnsku", fnsku);
|
||||
insertCmd.Parameters.AddWithValue("@sku", sku);
|
||||
insertCmd.Parameters.AddWithValue("@quantity", quantity);
|
||||
insertCmd.Parameters.AddWithValue("@fbaShipmentId", fbaShipemntId);
|
||||
insertCmd.Parameters.AddWithValue("@fulfillmentCenterId", fulfillmentCenterId);
|
||||
|
||||
insertCmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
|
||||
////check for duplicate line in db
|
||||
//using (SqlCommand cmd = new SqlCommand(
|
||||
// "SELECT ImportFbaInventoryReceiptReportID FROM tblImportFbaInventoryReceiptReport " +
|
||||
// "WHERE [received-date]=@receivedDate AND [fnsku]=@fnsku AND [fba-shipment-id]=@fbaShipmentId AND [fulfillment-center-id]=@fulfillmentCenterId;"
|
||||
// , sqlConn, trans))
|
||||
//{
|
||||
// cmd.Parameters.AddWithValue("@receivedDate", receivedDate);
|
||||
// cmd.Parameters.AddWithValue("@fnsku", fnsku);
|
||||
// cmd.Parameters.AddWithValue("@fbaShipmentId", fbaShipemntId);
|
||||
// cmd.Parameters.AddWithValue("@fulfillmentCenterId", fulfillmentCenterId);
|
||||
|
||||
// using (SqlDataReader sqlReader = cmd.ExecuteReader())
|
||||
// {
|
||||
// if (sqlReader.HasRows == true)
|
||||
// {
|
||||
// lineDuplicateSkip = lineDuplicateSkip + 1;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// }
|
||||
// }
|
||||
|
||||
//}
|
||||
}
|
||||
}
|
||||
// only commit if records all complete with no errors -- ommiting duplcates relies on all records from one day being committed together
|
||||
trans.Commit();
|
||||
Console.Write("\r");
|
||||
log.LogInformation((lineNumber - (1 + lineErrorSkip + lineOutsideScope)) + " total report items inserted into db, " + lineOutsideScope + " item(s) outside of requested time scope where skipped.");
|
||||
if (lineErrorSkip > 0)
|
||||
{
|
||||
log.LogError(lineErrorSkip + " total line(s) where skipped due to insufficent number of cells on row");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.LogError("Error running FbaInventoryReceiptReportImport, no records were commited",
|
||||
ex.ToString() + "\r\nTraceMessage:\r\n" + MiscFunction.TraceMessage()
|
||||
);
|
||||
|
||||
throw ex;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public DateTime ReadRecentDate()
|
||||
{
|
||||
DateTime lastRecordDate;
|
||||
SqlConnection conn;
|
||||
try
|
||||
{
|
||||
using (conn = new SqlConnection(SqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
using (SqlCommand cmd = new SqlCommand(
|
||||
"SELECT Max([received-date]) AS MaxDate FROM tblImportFbaInventoryReceiptReport;"
|
||||
, conn))
|
||||
{
|
||||
if (cmd.ExecuteScalar() == DBNull.Value)
|
||||
{
|
||||
// use first month started selling on Amazon
|
||||
lastRecordDate = lastRecordDate = Constants.GetBusinessStartUtc();
|
||||
}
|
||||
else
|
||||
{
|
||||
lastRecordDate = ((DateTime)cmd.ExecuteScalar());
|
||||
lastRecordDate = DateTime.SpecifyKind(lastRecordDate, DateTimeKind.Utc);
|
||||
}
|
||||
|
||||
return lastRecordDate;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.LogError("Error running FbaInventoryReceiptReportImport, no records were commited",
|
||||
ex.ToString() + "\r\nTraceMessage:\r\n" + MiscFunction.TraceMessage()
|
||||
);
|
||||
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,407 @@
|
||||
using FikaAmazonAPI.AmazonSpApiSDK.Models.Finances;
|
||||
using FikaAmazonAPI.ConstructFeed.Messages;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.ConstrainedExecution;
|
||||
using System.Security.Policy;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
//using System.Web.UI.WebControls;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Import
|
||||
{
|
||||
public class AmazonFbaReimbursement : Connection
|
||||
{
|
||||
private Logic.Log.LogEvent log = new Logic.Log.LogEvent();
|
||||
|
||||
public AmazonFbaReimbursement()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public bool InsertByFlatFile(string filePath)
|
||||
{
|
||||
SqlConnection sqlConn;
|
||||
SqlTransaction trans;
|
||||
try
|
||||
{
|
||||
using (sqlConn = new SqlConnection(SqlConnectionString))
|
||||
{
|
||||
sqlConn.Open();
|
||||
using (trans = sqlConn.BeginTransaction())
|
||||
using (var reader = new StreamReader(filePath))
|
||||
{
|
||||
//read file one line at a time and insert data into table if required
|
||||
int lineNumber = 1;
|
||||
int lineErrorSkip = 0;
|
||||
int lineDuplicateSkip = 0;
|
||||
|
||||
// read header and retrive information
|
||||
string headerRow = reader.ReadLine();
|
||||
string[] headers = headerRow.Split('\t');
|
||||
|
||||
int columnCount = headers.Length;
|
||||
|
||||
int index01 = Array.IndexOf(headers, "approval-date");
|
||||
int index02 = Array.IndexOf(headers, "reimbursement-id");
|
||||
int index03 = Array.IndexOf(headers, "case-id");
|
||||
int index04 = Array.IndexOf(headers, "amazon-order-id");
|
||||
int index05 = Array.IndexOf(headers, "reason");
|
||||
int index06 = Array.IndexOf(headers, "sku");
|
||||
int index07 = Array.IndexOf(headers, "fnsku");
|
||||
int index08 = Array.IndexOf(headers, "asin");
|
||||
int index09 = Array.IndexOf(headers, "product-name");
|
||||
int index10 = Array.IndexOf(headers, "condition");
|
||||
int index11 = Array.IndexOf(headers, "currency-unit");
|
||||
int index12 = Array.IndexOf(headers, "amount-per-unit");
|
||||
int index13 = Array.IndexOf(headers, "amount-total");
|
||||
int index14 = Array.IndexOf(headers, "quantity-reimbursed-cash");
|
||||
int index15 = Array.IndexOf(headers, "quantity-reimbursed-inventory");
|
||||
int index16 = Array.IndexOf(headers, "quantity-reimbursed-total");
|
||||
|
||||
string fileRow;
|
||||
while ((fileRow = reader.ReadLine()) != null)
|
||||
{
|
||||
lineNumber = lineNumber + 1;
|
||||
Console.Write("\rParsing record: " + lineNumber);
|
||||
//split line into array
|
||||
string[] items = fileRow.Split('\t');
|
||||
if (items.Length != columnCount)
|
||||
{
|
||||
// skip line
|
||||
lineErrorSkip = lineErrorSkip + 1;
|
||||
log.LogWarning(
|
||||
"Line #" + lineNumber + " skipped due to no enough element in row.",
|
||||
filePath
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
//read values
|
||||
string approvalDate = items[index01];
|
||||
string reimbursementid = items[index02];
|
||||
string caseid = items[index03];
|
||||
string amazonOrderId = items[index04];
|
||||
string reason = items[index05];
|
||||
string sku = items[index06];
|
||||
string fnsku = items[index07];
|
||||
string asin = items[index08];
|
||||
string productName = items[index09];
|
||||
string condition = items[index10];
|
||||
string currencyUnit = items[index11];
|
||||
string amountPerUnit = items[index12];
|
||||
string amountTotal = items[index13];
|
||||
|
||||
int quantityReimbursedCash = 0;
|
||||
if (items[index14] != "")
|
||||
{ quantityReimbursedCash = int.Parse(items[index14]); }
|
||||
|
||||
int quantityReimbursedInventory = 0;
|
||||
if (items[index15] != "")
|
||||
{ quantityReimbursedInventory = int.Parse(items[index15]); }
|
||||
|
||||
int quantityReimbursedTotal = 0;
|
||||
if (items[index16] != "")
|
||||
{ quantityReimbursedTotal = int.Parse(items[index16]); }
|
||||
|
||||
// totals checks
|
||||
if (quantityReimbursedTotal == 0)
|
||||
{
|
||||
throw new Exception("Total Reimbursed total cannot be zero.");
|
||||
}
|
||||
if (quantityReimbursedCash + quantityReimbursedInventory != quantityReimbursedTotal)
|
||||
{
|
||||
throw new Exception("Reimbursed totals do not tally.");
|
||||
}
|
||||
|
||||
// check number of times line conbination appears in file
|
||||
int fileCount = 0;
|
||||
int dbCount = 0;
|
||||
using (var dupReader = new StreamReader(filePath))
|
||||
{
|
||||
dupReader.ReadLine(); // read header row
|
||||
string dupFileRow;
|
||||
while ((dupFileRow = dupReader.ReadLine()) != null)
|
||||
{
|
||||
string[] dupItems = dupFileRow.Split('\t');
|
||||
if (dupItems.Length != columnCount)
|
||||
{
|
||||
// skip
|
||||
}
|
||||
else
|
||||
{
|
||||
if (items[index01] == dupItems[index01] &&
|
||||
items[index02] == dupItems[index02] &&
|
||||
items[index03] == dupItems[index03] &&
|
||||
items[index04] == dupItems[index04] &&
|
||||
items[index05] == dupItems[index05] &&
|
||||
items[index07] == dupItems[index07] &&
|
||||
items[index13] == dupItems[index13]
|
||||
)
|
||||
{
|
||||
// count will always find at least one (itself)
|
||||
fileCount = fileCount + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//check for duplicate line in db
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
SELECT
|
||||
COUNT(ImportFbaReimbursementReportID) AS number
|
||||
FROM
|
||||
tblImportFbaReimbursementReport
|
||||
WHERE
|
||||
[reimbursement-id]=@reimbursementid
|
||||
AND ([case-id]=@caseid OR [case-id] IS NULL)
|
||||
AND ([amazon-order-id]=@amazonOrderId OR [amazon-order-id] IS NULL)
|
||||
AND reason=@reason AND fnsku=@fnsku
|
||||
AND [amount-total]=@amountTotal;
|
||||
", sqlConn, trans))
|
||||
{
|
||||
if (reimbursementid == "") { cmd.Parameters.AddWithValue("@reimbursementid", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@reimbursementid", reimbursementid); }
|
||||
if (caseid == "") { cmd.Parameters.AddWithValue("@caseid", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@caseid", caseid); }
|
||||
if (amazonOrderId == "") { cmd.Parameters.AddWithValue("@amazonOrderId", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@amazonOrderId", amazonOrderId); }
|
||||
if (reason == "") { cmd.Parameters.AddWithValue("@reason", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@reason", reason); }
|
||||
if (fnsku == "") { cmd.Parameters.AddWithValue("@fnsku", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@fnsku", fnsku); }
|
||||
if (amountTotal == "") { cmd.Parameters.AddWithValue("@amountTotal", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@amountTotal", decimal.Parse(amountTotal)); }
|
||||
|
||||
dbCount = (int)cmd.ExecuteScalar();
|
||||
}
|
||||
|
||||
if (fileCount <= dbCount)
|
||||
{
|
||||
//skip
|
||||
lineDuplicateSkip = lineDuplicateSkip + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
//insert report items
|
||||
using (SqlCommand insertCmd = new SqlCommand(
|
||||
"INSERT INTO tblImportFbaReimbursementReport ( " +
|
||||
"[approval-date], [reimbursement-id], [case-id], [amazon-order-id], reason, " +
|
||||
"sku, fnsku, asin, condition, [currency-unit], " +
|
||||
"[amount-per-unit], [amount-total], [quantity-reimbursed-cash], [quantity-reimbursed-inventory], [quantity-reimbursed-total] )" +
|
||||
"VALUES ( " +
|
||||
"@approvalDate, @reimbursementid, @caseid, @amazonOrderId, @reason, " +
|
||||
"@sku, @fnsku, @asin, @condition, @currencyUnit, " +
|
||||
"@amountPerUnit, @amountTotal, @quantityReimbursedCash, @quantityReimbursedInventory, @quantityReimbursedTotal );"
|
||||
, sqlConn, trans))
|
||||
{
|
||||
// add parameters
|
||||
if (approvalDate == "") { insertCmd.Parameters.AddWithValue("@approvalDate", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@approvalDate", DateTime.Parse(approvalDate).ToUniversalTime()); }
|
||||
if (reimbursementid == "") { insertCmd.Parameters.AddWithValue("@reimbursementid", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@reimbursementid", reimbursementid); }
|
||||
if (caseid == "") { insertCmd.Parameters.AddWithValue("@caseid", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@caseid", caseid); }
|
||||
if (amazonOrderId == "") { insertCmd.Parameters.AddWithValue("@amazonOrderId", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@amazonOrderId", amazonOrderId); }
|
||||
if (reason == "") { insertCmd.Parameters.AddWithValue("@reason", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@reason", reason); }
|
||||
if (sku == "") { insertCmd.Parameters.AddWithValue("@sku", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@sku", sku); }
|
||||
if (fnsku == "") { insertCmd.Parameters.AddWithValue("@fnsku", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@fnsku", fnsku); }
|
||||
if (asin == "") { insertCmd.Parameters.AddWithValue("@asin", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@asin", asin); }
|
||||
if (condition == "") { insertCmd.Parameters.AddWithValue("@condition", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@condition", condition); }
|
||||
if (currencyUnit == "") { insertCmd.Parameters.AddWithValue("@currencyUnit", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@currencyUnit", currencyUnit); }
|
||||
if (amountPerUnit == "") { insertCmd.Parameters.AddWithValue("@amountPerUnit", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@amountPerUnit", decimal.Parse(amountPerUnit)); }
|
||||
if (amountTotal == "") { insertCmd.Parameters.AddWithValue("@amountTotal", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@amountTotal", decimal.Parse(amountTotal)); }
|
||||
insertCmd.Parameters.AddWithValue("@quantityReimbursedCash", quantityReimbursedCash);
|
||||
insertCmd.Parameters.AddWithValue("@quantityReimbursedInventory", quantityReimbursedInventory);
|
||||
insertCmd.Parameters.AddWithValue("@quantityReimbursedTotal", quantityReimbursedTotal);
|
||||
|
||||
insertCmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
trans.Commit();
|
||||
Console.Write("\r");
|
||||
log.LogInformation((lineNumber - (1 + lineErrorSkip + lineDuplicateSkip)) + " total new items inserted, " + lineDuplicateSkip + " duplicates were skipped.");
|
||||
if (lineErrorSkip > 0)
|
||||
{
|
||||
log.LogError(lineErrorSkip + " total line(s) where skipped due to insufficent number of cells on row");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.LogError("Error running ImportFbaReimbursementReport method, no records were commited",
|
||||
ex.ToString() + "\r\nTraceMessage:\r\n" + MiscFunction.TraceMessage()
|
||||
);
|
||||
|
||||
throw ex;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public DateTime ReadRecentDate()
|
||||
{
|
||||
DateTime lastRecordDate;
|
||||
SqlConnection sqlConn;
|
||||
try
|
||||
{
|
||||
using (sqlConn = new SqlConnection(SqlConnectionString))
|
||||
{
|
||||
sqlConn.Open();
|
||||
using (SqlCommand cmd = new SqlCommand(
|
||||
"SELECT Max([approval-date]) AS MaxDate FROM tblImportFbaReimbursementReport;"
|
||||
, sqlConn))
|
||||
{
|
||||
if (cmd.ExecuteScalar() == DBNull.Value)
|
||||
{
|
||||
// use first month started selling on Amazon
|
||||
lastRecordDate = lastRecordDate = Constants.GetBusinessStartUtc();
|
||||
}
|
||||
else
|
||||
{
|
||||
lastRecordDate = ((DateTime)cmd.ExecuteScalar());
|
||||
lastRecordDate = DateTime.SpecifyKind(lastRecordDate, DateTimeKind.Utc);
|
||||
}
|
||||
|
||||
return lastRecordDate;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.LogError("Error running GetFbaReimbursementData, no records were commited",
|
||||
ex.ToString() + "\r\nTraceMessage:\r\n" + MiscFunction.TraceMessage()
|
||||
);
|
||||
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
public List<Model.Import.FbaReimbursementReport> Read(bool? isProcessed = null)
|
||||
{
|
||||
var returnList = new List<Model.Import.FbaReimbursementReport>();
|
||||
|
||||
string sql = @"
|
||||
SELECT
|
||||
[ImportFbaReimbursementReportID]
|
||||
,[approval-date]
|
||||
,[reimbursement-id]
|
||||
,[case-id]
|
||||
,[amazon-order-id]
|
||||
,[reason]
|
||||
,[sku]
|
||||
,[fnsku]
|
||||
,[asin]
|
||||
,[condition]
|
||||
,[currency-unit]
|
||||
,[amount-per-unit]
|
||||
,[amount-total]
|
||||
,[quantity-reimbursed-cash]
|
||||
,[quantity-reimbursed-inventory]
|
||||
,[quantity-reimbursed-total]
|
||||
,[IsProcessed]
|
||||
,[StockSkuTransactionID]
|
||||
FROM [tblImportFbaReimbursementReport]
|
||||
where (1=1) ";
|
||||
|
||||
if (isProcessed.HasValue)
|
||||
{
|
||||
if (isProcessed == true)
|
||||
{
|
||||
sql = sql + " AND (IsProcessed = 1) ";
|
||||
}
|
||||
else
|
||||
{
|
||||
sql = sql + " AND (IsProcessed = 0) ";
|
||||
}
|
||||
}
|
||||
|
||||
SqlConnection sqlConn;
|
||||
using (sqlConn = new SqlConnection(SqlConnectionString))
|
||||
{
|
||||
sqlConn.Open();
|
||||
using (SqlCommand cmd = new SqlCommand(sql, sqlConn))
|
||||
{
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
var item = new Model.Import.FbaReimbursementReport();
|
||||
|
||||
item.FbaReimbursementReportID = reader.GetInt32(0);
|
||||
item.ApprovalDate = DateTime.SpecifyKind(reader.GetDateTime(1), DateTimeKind.Utc);
|
||||
item.ReimbursementId = reader.GetString(2);
|
||||
if (!reader.IsDBNull(3)) { item.CaseId = reader.GetString(3); }
|
||||
if (!reader.IsDBNull(4)) { item.AmazonOrderId = reader.GetString(4); }
|
||||
item.Reason = reader.GetString(5);
|
||||
item.Sku = reader.GetString(6);
|
||||
item.Fnsku = reader.GetString(7);
|
||||
item.Asin = reader.GetString(8);
|
||||
item.Condition = reader.GetString(9);
|
||||
item.CurrencyUnit = reader.GetString(10);
|
||||
item.AmountPerUnit = reader.GetDecimal(11);
|
||||
item.AmountTotal = reader.GetDecimal(12);
|
||||
item.QuantityReimbursedCash = reader.GetInt32(13);
|
||||
item.QuantityReimbursedInventory = reader.GetInt32(14);
|
||||
item.QuantityReimbursedTotal = reader.GetInt32(15);
|
||||
item.IsProcessed = reader.GetBoolean(16);
|
||||
if (!reader.IsDBNull(17)) { item.StockSkuTransactionID = reader.GetInt32(17); }
|
||||
|
||||
returnList.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnList;
|
||||
}
|
||||
|
||||
public void UpdateIsProcessed(int fbaReimbursementReportID, bool isProcessed, int? stockSkuTransactionId)
|
||||
{
|
||||
// consistancy checks
|
||||
if (isProcessed == false && stockSkuTransactionId.HasValue)
|
||||
{
|
||||
throw new ArgumentException("Consistancy check error, incorrect argument combination passed to function");
|
||||
}
|
||||
|
||||
string sql = @"
|
||||
UPDATE
|
||||
tblImportFbaReimbursementReport
|
||||
SET
|
||||
IsProcessed=@isProcessed
|
||||
, StockSkuTransactionID=@transactionId
|
||||
WHERE
|
||||
ImportFbaReimbursementReportID=@importTableId;
|
||||
";
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@importTableId", fbaReimbursementReportID);
|
||||
cmd.Parameters.AddWithValue("@isProcessed", isProcessed);
|
||||
if (stockSkuTransactionId.HasValue) { cmd.Parameters.AddWithValue("@transactionId", stockSkuTransactionId); }
|
||||
else { cmd.Parameters.AddWithValue("@transactionId", DBNull.Value); }
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Import
|
||||
{
|
||||
public class AmazonFbaRemovalOrder : Connection
|
||||
{
|
||||
Logic.Log.LogEvent log = new Logic.Log.LogEvent();
|
||||
|
||||
public AmazonFbaRemovalOrder()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public bool InsertByFlatFile(string filePath)
|
||||
{
|
||||
SqlConnection sqlConn;
|
||||
SqlTransaction trans;
|
||||
try
|
||||
{
|
||||
using (sqlConn = new SqlConnection(SqlConnectionString))
|
||||
{
|
||||
sqlConn.Open();
|
||||
using (trans = sqlConn.BeginTransaction())
|
||||
using (var reader = new StreamReader(filePath))
|
||||
{
|
||||
//read file one line at a time and insert data into table if required
|
||||
int lineNumber = 1;
|
||||
int lineErrorSkip = 0;
|
||||
int lineUpdate = 0;
|
||||
|
||||
// read header and retrive information
|
||||
string headerRow = reader.ReadLine();
|
||||
string[] headers = headerRow.Split('\t');
|
||||
|
||||
int columnCount = headers.Length;
|
||||
|
||||
int index01 = Array.IndexOf(headers, "request-date");
|
||||
int index02 = Array.IndexOf(headers, "order-id");
|
||||
int index03 = Array.IndexOf(headers, "order-type");
|
||||
int index04 = Array.IndexOf(headers, "service-speed");
|
||||
int index05 = Array.IndexOf(headers, "order-status");
|
||||
int index06 = Array.IndexOf(headers, "last-updated-date");
|
||||
int index07 = Array.IndexOf(headers, "sku");
|
||||
int index08 = Array.IndexOf(headers, "fnsku");
|
||||
int index09 = Array.IndexOf(headers, "disposition");
|
||||
int index10 = Array.IndexOf(headers, "requested-quantity");
|
||||
int index11 = Array.IndexOf(headers, "cancelled-quantity");
|
||||
int index12 = Array.IndexOf(headers, "disposed-quantity");
|
||||
int index13 = Array.IndexOf(headers, "shipped-quantity");
|
||||
int index14 = Array.IndexOf(headers, "in-process-quantity");
|
||||
int index15 = Array.IndexOf(headers, "removal-fee");
|
||||
int index16 = Array.IndexOf(headers, "currency");
|
||||
|
||||
string fileRow;
|
||||
while ((fileRow = reader.ReadLine()) != null)
|
||||
{
|
||||
lineNumber = lineNumber + 1;
|
||||
Console.Write("\rParsing record: " + lineNumber);
|
||||
//split line into array
|
||||
string[] items = fileRow.Split('\t');
|
||||
if (items.Length != columnCount)
|
||||
{
|
||||
// skip line
|
||||
lineErrorSkip = lineErrorSkip + 1;
|
||||
log.LogWarning(
|
||||
"Line #" + lineNumber + " skipped due to no enough element in row.",
|
||||
filePath
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
//read values
|
||||
string requestDate = items[index01];
|
||||
string orderId = items[index02];
|
||||
string orderType = items[index03];
|
||||
string serviceSpeed = items[index04];
|
||||
string orderStatus = items[index05];
|
||||
string lastUpdatedDate = items[index06];
|
||||
string sku = items[index07];
|
||||
string fnsku = items[index08];
|
||||
string disposition = items[index09];
|
||||
string requestedQuantity = items[index10];
|
||||
string cancelledQuantity = items[index11];
|
||||
string disposedQuantity = items[index12];
|
||||
string shippedQuantity = items[index13];
|
||||
string inProcessQuantity = items[index14];
|
||||
string removalFee = items[index15];
|
||||
string currency = items[index16];
|
||||
|
||||
if (orderId == "") { continue; }
|
||||
int importTableId = 0;
|
||||
|
||||
//check for existing orderId
|
||||
using (SqlCommand cmd = new SqlCommand(
|
||||
"SELECT ImportFbaRemovalOrderReportID FROM tblImportFbaRemovalOrderReport WHERE [order-id]=@orderId AND fnsku=@fnsku AND disposition=@disposition;"
|
||||
, sqlConn, trans))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@orderId", orderId);
|
||||
cmd.Parameters.AddWithValue("@fnsku", fnsku);
|
||||
cmd.Parameters.AddWithValue("@disposition", disposition);
|
||||
importTableId = Convert.ToInt32(cmd.ExecuteScalar());
|
||||
}
|
||||
|
||||
string sqlQuery;
|
||||
if (importTableId > 0)
|
||||
{
|
||||
// update
|
||||
lineUpdate = lineUpdate + 1;
|
||||
sqlQuery =
|
||||
"UPDATE tblImportFbaRemovalOrderReport SET " +
|
||||
"[request-date]=@requestDate, [order-id]=@orderId, [order-type]=@orderType, [service-speed]=@serviceSpeed, " +
|
||||
"[order-status]=@orderStatus, [last-updated-date]=@lastUpdatedDate, sku=@sku, fnsku=@fnsku, " +
|
||||
"disposition=@disposition, [requested-quantity]=@requestedQuantity, [cancelled-quantity]=@cancelledQuantity, [disposed-quantity]=@disposedQuantity, " +
|
||||
"[shipped-quantity]=@shippedQuantity, [in-process-quantity]=@inProcessQuantity, [removal-fee]=@removalFee, currency=@currency " +
|
||||
"WHERE ImportFbaRemovalOrderReportID=@importTableId;";
|
||||
}
|
||||
else
|
||||
{
|
||||
// insert
|
||||
sqlQuery =
|
||||
"INSERT INTO tblImportFbaRemovalOrderReport ( " +
|
||||
"[request-date], [order-id], [order-type], [service-speed], [order-status], [last-updated-date], sku, fnsku, " +
|
||||
"disposition, [requested-quantity], [cancelled-quantity], [disposed-quantity], [shipped-quantity], [in-process-quantity], [removal-fee], currency ) " +
|
||||
"VALUES ( " +
|
||||
"@requestDate, @orderId, @orderType, @serviceSpeed, @orderStatus, @lastUpdatedDate, @sku, @fnsku, " +
|
||||
"@disposition, @requestedQuantity, @cancelledQuantity, @disposedQuantity, @shippedQuantity, @inProcessQuantity, @removalFee, @currency );";
|
||||
}
|
||||
|
||||
// make the update/insert
|
||||
using (SqlCommand cmd = new SqlCommand(sqlQuery, sqlConn, trans))
|
||||
{
|
||||
// add parameters
|
||||
cmd.Parameters.AddWithValue("@importTableId", importTableId);
|
||||
if (requestDate == "") { cmd.Parameters.AddWithValue("@requestDate", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@requestDate", DateTime.Parse(requestDate).ToUniversalTime()); }
|
||||
if (orderId == "") { cmd.Parameters.AddWithValue("@orderId", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@orderId", orderId); }
|
||||
if (orderType == "") { cmd.Parameters.AddWithValue("@orderType", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@orderType", orderType); }
|
||||
if (serviceSpeed == "") { cmd.Parameters.AddWithValue("@serviceSpeed", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@serviceSpeed", serviceSpeed); }
|
||||
if (orderStatus == "") { cmd.Parameters.AddWithValue("@orderStatus", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@orderStatus", orderStatus); }
|
||||
if (lastUpdatedDate == "") { cmd.Parameters.AddWithValue("@lastUpdatedDate", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@lastUpdatedDate", DateTime.Parse(lastUpdatedDate).ToUniversalTime()); }
|
||||
if (sku == "") { cmd.Parameters.AddWithValue("@sku", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@sku", sku); }
|
||||
if (fnsku == "") { cmd.Parameters.AddWithValue("@fnsku", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@fnsku", fnsku); }
|
||||
if (disposition == "") { cmd.Parameters.AddWithValue("@disposition", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@disposition", disposition); }
|
||||
if (requestedQuantity == "") { cmd.Parameters.AddWithValue("@requestedQuantity", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@requestedQuantity", int.Parse(requestedQuantity)); }
|
||||
if (cancelledQuantity == "") { cmd.Parameters.AddWithValue("@cancelledQuantity", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@cancelledQuantity", int.Parse(cancelledQuantity)); }
|
||||
if (disposedQuantity == "") { cmd.Parameters.AddWithValue("@disposedQuantity", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@disposedQuantity", int.Parse(disposedQuantity)); }
|
||||
if (shippedQuantity == "") { cmd.Parameters.AddWithValue("@shippedQuantity", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@shippedQuantity", int.Parse(shippedQuantity)); }
|
||||
if (inProcessQuantity == "") { cmd.Parameters.AddWithValue("@inProcessQuantity", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@inProcessQuantity", int.Parse(inProcessQuantity)); }
|
||||
if (removalFee == "") { cmd.Parameters.AddWithValue("@removalFee", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@removalFee", decimal.Parse(removalFee)); }
|
||||
if (currency == "") { cmd.Parameters.AddWithValue("@currency", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@currency", currency); }
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
trans.Commit();
|
||||
Console.Write("\r");
|
||||
log.LogInformation("ImportFbaRemovalOrderReport() " + (lineNumber - (1 + lineErrorSkip + lineUpdate)) + " records created, " + lineUpdate + " records updated.");
|
||||
if (lineErrorSkip > 0)
|
||||
{
|
||||
log.LogInformation(lineErrorSkip + " total line(s) where skipped due to insufficent number of cells on row");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.LogError("Error running ImportFbaRemovalOrderReport method, no records were commited",
|
||||
ex.ToString() + "\r\nTraceMessage:\r\n" + MiscFunction.TraceMessage()
|
||||
);
|
||||
|
||||
throw ex;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,623 @@
|
||||
using Dapper;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Import
|
||||
{
|
||||
public class AmazonFbaSaleShipment : Connection
|
||||
{
|
||||
private Logic.Log.LogEvent log = new Logic.Log.LogEvent();
|
||||
|
||||
public AmazonFbaSaleShipment()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// seems amazon have reduced the number of columns in the table significantly, probably due data protection. This is the
|
||||
// old one
|
||||
public bool InsertByFlatFile(string filePath)
|
||||
{
|
||||
SqlConnection sqlConn;
|
||||
SqlTransaction trans;
|
||||
|
||||
try
|
||||
{
|
||||
using (sqlConn = new SqlConnection(SqlConnectionString))
|
||||
{
|
||||
sqlConn.Open();
|
||||
using (trans = sqlConn.BeginTransaction())
|
||||
using (var reader = new StreamReader(filePath))
|
||||
{
|
||||
//read file one line at a time and insert data into table if required
|
||||
int lineNumber = 1;
|
||||
int lineErrorSkip = 0;
|
||||
int lineDuplicateSkip = 0;
|
||||
|
||||
// read header and retrive information
|
||||
string headerRow = reader.ReadLine();
|
||||
string[] headers = headerRow.Split('\t');
|
||||
|
||||
int columnCount = headers.Length;
|
||||
|
||||
int index01 = Array.IndexOf(headers, "amazon-order-id");
|
||||
int index02 = Array.IndexOf(headers, "merchant-order-id");
|
||||
int index03 = Array.IndexOf(headers, "shipment-id");
|
||||
int index04 = Array.IndexOf(headers, "shipment-item-id");
|
||||
int index05 = Array.IndexOf(headers, "amazon-order-item-id");
|
||||
int index06 = Array.IndexOf(headers, "merchant-order-item-id");
|
||||
int index07 = Array.IndexOf(headers, "purchase-date");
|
||||
int index08 = Array.IndexOf(headers, "payments-date");
|
||||
int index09 = Array.IndexOf(headers, "shipment-date");
|
||||
int index10 = Array.IndexOf(headers, "reporting-date");
|
||||
int index11 = Array.IndexOf(headers, "buyer-email");
|
||||
int index12 = Array.IndexOf(headers, "buyer-name");
|
||||
int index13 = Array.IndexOf(headers, "sku");
|
||||
int index14 = Array.IndexOf(headers, "quantity-shipped");
|
||||
int index15 = Array.IndexOf(headers, "currency");
|
||||
int index16 = Array.IndexOf(headers, "item-price");
|
||||
int index17 = Array.IndexOf(headers, "item-tax");
|
||||
int index18 = Array.IndexOf(headers, "shipping-price");
|
||||
int index19 = Array.IndexOf(headers, "shipping-tax");
|
||||
int index20 = Array.IndexOf(headers, "gift-wrap-price");
|
||||
int index21 = Array.IndexOf(headers, "gift-wrap-tax");
|
||||
int index22 = Array.IndexOf(headers, "recipient-name");
|
||||
int index23 = Array.IndexOf(headers, "ship-address-1");
|
||||
int index24 = Array.IndexOf(headers, "ship-address-2");
|
||||
int index25 = Array.IndexOf(headers, "ship-address-3");
|
||||
int index26 = Array.IndexOf(headers, "ship-city");
|
||||
int index27 = Array.IndexOf(headers, "ship-state");
|
||||
int index28 = Array.IndexOf(headers, "ship-postal-code");
|
||||
int index29 = Array.IndexOf(headers, "ship-country");
|
||||
int index30 = Array.IndexOf(headers, "ship-phone-number");
|
||||
int index31 = Array.IndexOf(headers, "bill-address-1");
|
||||
int index32 = Array.IndexOf(headers, "bill-address-2");
|
||||
int index33 = Array.IndexOf(headers, "bill-address-3");
|
||||
int index34 = Array.IndexOf(headers, "bill-city");
|
||||
int index35 = Array.IndexOf(headers, "bill-state");
|
||||
int index36 = Array.IndexOf(headers, "bill-postal-code");
|
||||
int index37 = Array.IndexOf(headers, "bill-country");
|
||||
int index38 = Array.IndexOf(headers, "item-promotion-discount");
|
||||
int index39 = Array.IndexOf(headers, "ship-promotion-discount");
|
||||
int index40 = Array.IndexOf(headers, "fulfillment-center-id");
|
||||
int index41 = Array.IndexOf(headers, "fulfillment-channel");
|
||||
int index42 = Array.IndexOf(headers, "sales-channel");
|
||||
|
||||
string fileRow;
|
||||
while ((fileRow = reader.ReadLine()) != null)
|
||||
{
|
||||
lineNumber = lineNumber + 1;
|
||||
Console.Write("\rParsing record: " + lineNumber);
|
||||
//split line into array
|
||||
string[] items = fileRow.Split('\t');
|
||||
if (items.Length != columnCount)
|
||||
{
|
||||
// skip line
|
||||
lineErrorSkip = lineErrorSkip + 1;
|
||||
log.LogWarning(
|
||||
"Line #" + lineNumber + " skipped due to no enough element in row.",
|
||||
filePath
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
//read values
|
||||
string amazonOrderId = items[index01];
|
||||
string merchantOrderid = items[index02];
|
||||
string shipmentId = items[index03];
|
||||
string shipmentItemId = items[index04];
|
||||
string amazonOrderItemId = items[index05];
|
||||
string merchantOrderItemId = items[index06];
|
||||
DateTime purchaseDate = DateTime.Parse(items[index07]);
|
||||
DateTime paymentsDate = DateTime.Parse(items[index08]);
|
||||
DateTime shipmentDate = DateTime.Parse(items[index09]);
|
||||
DateTime reportingDate = DateTime.Parse(items[index10]);
|
||||
string buyerEmail = items[index11];
|
||||
string buyerName = items[index12];
|
||||
string sku = items[index13];
|
||||
int quantityShipped = Int32.Parse(items[index14]);
|
||||
string currency = items[index15];
|
||||
decimal itemPrice = decimal.Parse(items[index16]);
|
||||
decimal itemTax = decimal.Parse(items[index17]);
|
||||
decimal shippingPrice = decimal.Parse(items[index18]);
|
||||
decimal shippingTax = decimal.Parse(items[index19]);
|
||||
decimal giftWrapPrice = decimal.Parse(items[index20]);
|
||||
decimal giftWrapTax = decimal.Parse(items[index21]);
|
||||
string recipientName = items[index22];
|
||||
string shipAddress1 = items[index23];
|
||||
string shipAddress2 = items[index24];
|
||||
string shipAddress3 = items[index25];
|
||||
string shipCity = items[index26];
|
||||
string shipState = items[index27];
|
||||
string shipPostalCode = items[index28];
|
||||
string shipCountry = items[index29];
|
||||
string shipPhoneNumber = items[index30];
|
||||
string billAddress1 = items[index31];
|
||||
string billAddress2 = items[index32];
|
||||
string billAddress3 = items[index33];
|
||||
string billCity = items[index34];
|
||||
string billState = items[index35];
|
||||
string billPostalCode = items[index36];
|
||||
string billCountry = items[index37];
|
||||
string itemPromotionDiscount = items[index38];
|
||||
string shipPromotionDiscount = items[index39];
|
||||
string fulfillmentCenterId = items[index40];
|
||||
string fulfillmentChannel = items[index41];
|
||||
string salesChannel = items[index42];
|
||||
|
||||
//check for duplicate line in db
|
||||
using (SqlCommand cmd = new SqlCommand(
|
||||
"SELECT ImportFbaSaleShipmentID FROM tblImportFbaSaleShipment " +
|
||||
"WHERE [shipment-item-id]=@shipmentItemId;"
|
||||
, sqlConn, trans))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@shipmentItemId", shipmentItemId);
|
||||
|
||||
using (SqlDataReader sqlReader = cmd.ExecuteReader())
|
||||
{
|
||||
if (sqlReader.Read())
|
||||
{
|
||||
lineDuplicateSkip = lineDuplicateSkip + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
//insert report items
|
||||
|
||||
//start transaction
|
||||
|
||||
|
||||
using (SqlCommand insertCmd = new SqlCommand(
|
||||
"INSERT INTO tblImportFbaSaleShipment ( " +
|
||||
"[amazon-order-id], [merchant-order-id], [shipment-id], [shipment-item-id], [amazon-order-item-id], " +
|
||||
"[merchant-order-item-id], [purchase-date], [payments-date], [shipment-date], [reporting-date], " +
|
||||
"[buyer-email], [buyer-name], sku, [quantity-shipped], currency, " +
|
||||
"[item-price], [item-tax], [shipping-price], [shipping-tax], [gift-wrap-price], " +
|
||||
"[gift-wrap-tax], [recipient-name], [ship-address-1], [ship-address-2], [ship-address-3], " +
|
||||
"[ship-city], [ship-state], [ship-postal-code], [ship-country], [ship-phone-number], " +
|
||||
"[bill-address-1], [bill-address-2], [bill-address-3], [bill-city], [bill-state], " +
|
||||
"[bill-postal-code], [bill-country], [item-promotion-discount], [ship-promotion-discount], [fulfillment-center-id], " +
|
||||
"[fulfillment-channel], [sales-channel] ) " +
|
||||
"VALUES ( " +
|
||||
"@amazonOrderId, @merchantOrderid, @shipmentId, @shipmentItemId, @amazonOrderItemId, " +
|
||||
"@merchantOrderItemId, @purchaseDate, @paymentsDate, @shipmentDate, @reportingDate, " +
|
||||
"@buyerEmail, @buyerName, @sku, @quantityShipped, @currency, " +
|
||||
"@itemPrice, @itemTax, @shippingPrice, @shippingTax, @giftWrapPrice, " +
|
||||
"@giftWrapTax, @recipientName, @shipAddress1, @shipAddress2, @shipAddress3, " +
|
||||
"@shipCity, @shipState, @shipPostalCode, @shipCountry, @shipPhoneNumber, " +
|
||||
"@billAddress1, @billAddress2, @billAddress3, @billCity, @billState, " +
|
||||
"@billPostalCode, @billCountry, @itemPromotionDiscount, @shipPromotionDiscount, @fulfillmentCenterId, " +
|
||||
"@fulfillmentChannel, @salesChannel );"
|
||||
, sqlConn, trans))
|
||||
{
|
||||
// add parameters
|
||||
if (amazonOrderId == "") { insertCmd.Parameters.AddWithValue("@amazonOrderId", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@amazonOrderId", amazonOrderId); }
|
||||
if (merchantOrderid == "") { insertCmd.Parameters.AddWithValue("@merchantOrderid", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@merchantOrderid", merchantOrderid); }
|
||||
if (shipmentId == "") { insertCmd.Parameters.AddWithValue("@shipmentId", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@shipmentId", shipmentId); }
|
||||
if (shipmentItemId == "") { insertCmd.Parameters.AddWithValue("@shipmentItemId", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@shipmentItemId", shipmentItemId); }
|
||||
if (amazonOrderItemId == "") { insertCmd.Parameters.AddWithValue("@amazonOrderItemId", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@amazonOrderItemId", amazonOrderItemId); }
|
||||
if (merchantOrderItemId == "") { insertCmd.Parameters.AddWithValue("@merchantOrderItemId", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@merchantOrderItemId", merchantOrderItemId); }
|
||||
if (purchaseDate == DateTime.MinValue) { insertCmd.Parameters.AddWithValue("@purchaseDate", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@purchaseDate", purchaseDate.ToUniversalTime()); }
|
||||
if (paymentsDate == DateTime.MinValue) { insertCmd.Parameters.AddWithValue("@paymentsDate", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@paymentsDate", paymentsDate.ToUniversalTime()); }
|
||||
if (shipmentDate == DateTime.MinValue) { insertCmd.Parameters.AddWithValue("@shipmentDate", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@shipmentDate", shipmentDate.ToUniversalTime()); }
|
||||
if (reportingDate == DateTime.MinValue) { insertCmd.Parameters.AddWithValue("@reportingDate", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@reportingDate", reportingDate.ToUniversalTime()); }
|
||||
if (buyerEmail == "") { insertCmd.Parameters.AddWithValue("@buyerEmail", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@buyerEmail", buyerEmail); }
|
||||
if (buyerName == "") { insertCmd.Parameters.AddWithValue("@buyerName", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@buyerName", buyerName); }
|
||||
if (sku == "") { insertCmd.Parameters.AddWithValue("@sku", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@sku", sku); }
|
||||
insertCmd.Parameters.AddWithValue("@quantityShipped", quantityShipped);
|
||||
if (currency == "") { insertCmd.Parameters.AddWithValue("@currency", DBNull.Value); }
|
||||
insertCmd.Parameters.AddWithValue("@currency", currency);
|
||||
insertCmd.Parameters.AddWithValue("@itemPrice", itemPrice);
|
||||
insertCmd.Parameters.AddWithValue("@itemTax", itemTax);
|
||||
insertCmd.Parameters.AddWithValue("@shippingPrice", shippingPrice);
|
||||
insertCmd.Parameters.AddWithValue("@shippingTax", shippingTax);
|
||||
insertCmd.Parameters.AddWithValue("@giftWrapPrice", giftWrapPrice);
|
||||
insertCmd.Parameters.AddWithValue("@giftWrapTax", giftWrapTax);
|
||||
if (recipientName == "") { insertCmd.Parameters.AddWithValue("@recipientName", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@recipientName", recipientName); }
|
||||
if (shipAddress1 == "") { insertCmd.Parameters.AddWithValue("@shipAddress1", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@shipAddress1", shipAddress1); }
|
||||
if (shipAddress2 == "") { insertCmd.Parameters.AddWithValue("@shipAddress2", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@shipAddress2", shipAddress2); }
|
||||
if (shipAddress3 == "") { insertCmd.Parameters.AddWithValue("@shipAddress3", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@shipAddress3", shipAddress3); }
|
||||
if (shipCity == "") { insertCmd.Parameters.AddWithValue("@shipCity", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@shipCity", shipCity); }
|
||||
if (shipState == "") { insertCmd.Parameters.AddWithValue("@shipState", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@shipState", shipState); }
|
||||
if (shipPostalCode == "") { insertCmd.Parameters.AddWithValue("@shipPostalCode", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@shipPostalCode", shipPostalCode); }
|
||||
if (shipCountry == "") { insertCmd.Parameters.AddWithValue("@shipCountry", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@shipCountry", shipCountry); }
|
||||
if (shipPhoneNumber == "") { insertCmd.Parameters.AddWithValue("@shipPhoneNumber", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@shipPhoneNumber", shipPhoneNumber); }
|
||||
if (billAddress1 == "") { insertCmd.Parameters.AddWithValue("@billAddress1", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@billAddress1", billAddress1); }
|
||||
if (billAddress2 == "") { insertCmd.Parameters.AddWithValue("@billAddress2", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@billAddress2", billAddress2); }
|
||||
if (billAddress3 == "") { insertCmd.Parameters.AddWithValue("@billAddress3", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@billAddress3", billAddress3); }
|
||||
if (billCity == "") { insertCmd.Parameters.AddWithValue("@billCity", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@billCity", billCity); }
|
||||
if (billState == "") { insertCmd.Parameters.AddWithValue("@billState", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@billState", billState); }
|
||||
if (billPostalCode == "") { insertCmd.Parameters.AddWithValue("@billPostalCode", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@billPostalCode", billPostalCode); }
|
||||
if (billCountry == "") { insertCmd.Parameters.AddWithValue("@billCountry", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@billCountry", billCountry); }
|
||||
if (itemPromotionDiscount == "") { insertCmd.Parameters.AddWithValue("@itemPromotionDiscount", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@itemPromotionDiscount", itemPromotionDiscount); }
|
||||
if (shipPromotionDiscount == "") { insertCmd.Parameters.AddWithValue("@shipPromotionDiscount", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@shipPromotionDiscount", shipPromotionDiscount); }
|
||||
if (fulfillmentCenterId == "") { insertCmd.Parameters.AddWithValue("@fulfillmentCenterId", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@fulfillmentCenterId", fulfillmentCenterId); }
|
||||
if (fulfillmentChannel == "") { insertCmd.Parameters.AddWithValue("@fulfillmentChannel", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@fulfillmentChannel", fulfillmentChannel); }
|
||||
if (salesChannel == "") { insertCmd.Parameters.AddWithValue("@salesChannel", DBNull.Value); }
|
||||
else { insertCmd.Parameters.AddWithValue("@salesChannel", salesChannel); }
|
||||
|
||||
insertCmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
trans.Commit();
|
||||
Console.Write("\r");
|
||||
log.LogInformation((lineNumber - (1 + lineErrorSkip + lineDuplicateSkip)) + " total new items inserted, " + lineDuplicateSkip + " duplicates were skipped.");
|
||||
if (lineErrorSkip > 0)
|
||||
{
|
||||
log.LogError(lineErrorSkip + " total line(s) where skipped due to insufficent number of cells on row");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.LogError("Error running FbaInventoryReceiptReportImport, no records were commited",
|
||||
ex.ToString() + "\r\nTraceMessage:\r\n" + MiscFunction.TraceMessage()
|
||||
);
|
||||
|
||||
throw ex;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//public bool InsertByFlatFileold(string filePath)
|
||||
//{
|
||||
// SqlConnection sqlConn;
|
||||
// SqlTransaction trans;
|
||||
// //try
|
||||
// //{
|
||||
// using (sqlConn = new SqlConnection(SqlConnectionString))
|
||||
// {
|
||||
// sqlConn.Open();
|
||||
// using (trans = sqlConn.BeginTransaction())
|
||||
// using (var reader = new StreamReader(filePath))
|
||||
// {
|
||||
// //read file one line at a time and insert data into table if required
|
||||
// int lineNumber = 1;
|
||||
// int lineErrorSkip = 0;
|
||||
// int lineDuplicateSkip = 0;
|
||||
|
||||
// // read header and retrive information
|
||||
// string headerRow = reader.ReadLine();
|
||||
// string[] headers = headerRow.Split('\t');
|
||||
|
||||
// int columnCount = headers.Length;
|
||||
|
||||
// int index01 = Array.IndexOf(headers, "amazon-order-id");
|
||||
// int index09 = Array.IndexOf(headers, "shipment-date");
|
||||
// int index13 = Array.IndexOf(headers, "sku");
|
||||
// int index14 = Array.IndexOf(headers, "quantity");
|
||||
// int index15 = Array.IndexOf(headers, "currency");
|
||||
// int index16 = Array.IndexOf(headers, "item-price-per-unit");
|
||||
// int index18 = Array.IndexOf(headers, "shipping-price");
|
||||
// int index20 = Array.IndexOf(headers, "gift-wrap-price");
|
||||
// int index26 = Array.IndexOf(headers, "ship-city");
|
||||
// int index27 = Array.IndexOf(headers, "ship-state");
|
||||
// int index28 = Array.IndexOf(headers, "ship-postal-code");
|
||||
// int index40 = Array.IndexOf(headers, "fulfillment-center-id");
|
||||
|
||||
// string fileRow;
|
||||
// while ((fileRow = reader.ReadLine()) != null)
|
||||
// {
|
||||
// lineNumber = lineNumber + 1;
|
||||
// Console.Write("\rParsing record: " + lineNumber);
|
||||
// //split line into array
|
||||
// string[] items = fileRow.Split('\t');
|
||||
// if (items.Length != columnCount)
|
||||
// {
|
||||
// // skip line
|
||||
// lineErrorSkip = lineErrorSkip + 1;
|
||||
// new Logic.Log.LogEvent().EventLogInsert(
|
||||
// "Line #" + lineNumber + " skipped due to no enough element in row.",
|
||||
// 2,
|
||||
// filePath
|
||||
// );
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// //read values
|
||||
// string amazonOrderId = items[index01];
|
||||
// DateTime shipmentDate = DateTime.Parse(items[index09]);
|
||||
// string sku = items[index13];
|
||||
// int quantityShipped = Int32.Parse(items[index14]);
|
||||
// string currency = items[index15];
|
||||
// decimal itemPrice = decimal.Parse(items[index16]);
|
||||
// decimal shippingPrice = decimal.Parse(items[index18]);
|
||||
// decimal giftWrapPrice = decimal.Parse(items[index20]);
|
||||
// string shipCity = items[index26];
|
||||
// string shipState = items[index27];
|
||||
// string shipPostalCode = items[index28];
|
||||
// string fulfillmentCenterId = items[index40];
|
||||
|
||||
// //check for duplicate line in db
|
||||
// using (SqlCommand cmd = new SqlCommand(
|
||||
// "SELECT ImportFbaSaleShipmentID FROM tblImportFbaSaleShipment " +
|
||||
// "WHERE [shipment-item-id]=@shipmentItemId;"
|
||||
// , sqlConn, trans))
|
||||
// {
|
||||
// cmd.Parameters.AddWithValue("@shipmentItemId", shipmentItemId);
|
||||
|
||||
// using (SqlDataReader sqlReader = cmd.ExecuteReader())
|
||||
// {
|
||||
// if (sqlReader.Read())
|
||||
// {
|
||||
// lineDuplicateSkip = lineDuplicateSkip + 1;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// //insert report items
|
||||
|
||||
// //start transaction
|
||||
|
||||
|
||||
// using (SqlCommand insertCmd = new SqlCommand(
|
||||
// "INSERT INTO tblImportFbaSaleShipment ( " +
|
||||
// "[amazon-order-id], [merchant-order-id], [shipment-id], [shipment-item-id], [amazon-order-item-id], " +
|
||||
// "[merchant-order-item-id], [purchase-date], [payments-date], [shipment-date], [reporting-date], " +
|
||||
// "[buyer-email], [buyer-name], sku, [quantity-shipped], currency, " +
|
||||
// "[item-price], [item-tax], [shipping-price], [shipping-tax], [gift-wrap-price], " +
|
||||
// "[gift-wrap-tax], [recipient-name], [ship-address-1], [ship-address-2], [ship-address-3], " +
|
||||
// "[ship-city], [ship-state], [ship-postal-code], [ship-country], [ship-phone-number], " +
|
||||
// "[bill-address-1], [bill-address-2], [bill-address-3], [bill-city], [bill-state], " +
|
||||
// "[bill-postal-code], [bill-country], [item-promotion-discount], [ship-promotion-discount], [fulfillment-center-id], " +
|
||||
// "[fulfillment-channel], [sales-channel] ) " +
|
||||
// "VALUES ( " +
|
||||
// "@amazonOrderId, @merchantOrderid, @shipmentId, @shipmentItemId, @amazonOrderItemId, " +
|
||||
// "@merchantOrderItemId, @purchaseDate, @paymentsDate, @shipmentDate, @reportingDate, " +
|
||||
// "@buyerEmail, @buyerName, @sku, @quantityShipped, @currency, " +
|
||||
// "@itemPrice, @itemTax, @shippingPrice, @shippingTax, @giftWrapPrice, " +
|
||||
// "@giftWrapTax, @recipientName, @shipAddress1, @shipAddress2, @shipAddress3, " +
|
||||
// "@shipCity, @shipState, @shipPostalCode, @shipCountry, @shipPhoneNumber, " +
|
||||
// "@billAddress1, @billAddress2, @billAddress3, @billCity, @billState, " +
|
||||
// "@billPostalCode, @billCountry, @itemPromotionDiscount, @shipPromotionDiscount, @fulfillmentCenterId, " +
|
||||
// "@fulfillmentChannel, @salesChannel );"
|
||||
// , sqlConn, trans))
|
||||
// {
|
||||
// // add parameters
|
||||
// if (amazonOrderId == "") { insertCmd.Parameters.AddWithValue("@amazonOrderId", DBNull.Value); }
|
||||
// else { insertCmd.Parameters.AddWithValue("@amazonOrderId", amazonOrderId); }
|
||||
// if (merchantOrderid == "") { insertCmd.Parameters.AddWithValue("@merchantOrderid", DBNull.Value); }
|
||||
// else { insertCmd.Parameters.AddWithValue("@merchantOrderid", merchantOrderid); }
|
||||
// if (shipmentId == "") { insertCmd.Parameters.AddWithValue("@shipmentId", DBNull.Value); }
|
||||
// else { insertCmd.Parameters.AddWithValue("@shipmentId", shipmentId); }
|
||||
// if (shipmentItemId == "") { insertCmd.Parameters.AddWithValue("@shipmentItemId", DBNull.Value); }
|
||||
// else { insertCmd.Parameters.AddWithValue("@shipmentItemId", shipmentItemId); }
|
||||
// if (amazonOrderItemId == "") { insertCmd.Parameters.AddWithValue("@amazonOrderItemId", DBNull.Value); }
|
||||
// else { insertCmd.Parameters.AddWithValue("@amazonOrderItemId", amazonOrderItemId); }
|
||||
// if (merchantOrderItemId == "") { insertCmd.Parameters.AddWithValue("@merchantOrderItemId", DBNull.Value); }
|
||||
// else { insertCmd.Parameters.AddWithValue("@merchantOrderItemId", merchantOrderItemId); }
|
||||
// if (purchaseDate == DateTime.MinValue) { insertCmd.Parameters.AddWithValue("@purchaseDate", DBNull.Value); }
|
||||
// else { insertCmd.Parameters.AddWithValue("@purchaseDate", purchaseDate.ToUniversalTime()); }
|
||||
// if (paymentsDate == DateTime.MinValue) { insertCmd.Parameters.AddWithValue("@paymentsDate", DBNull.Value); }
|
||||
// else { insertCmd.Parameters.AddWithValue("@paymentsDate", paymentsDate.ToUniversalTime()); }
|
||||
// if (shipmentDate == DateTime.MinValue) { insertCmd.Parameters.AddWithValue("@shipmentDate", DBNull.Value); }
|
||||
// else { insertCmd.Parameters.AddWithValue("@shipmentDate", shipmentDate.ToUniversalTime()); }
|
||||
// if (reportingDate == DateTime.MinValue) { insertCmd.Parameters.AddWithValue("@reportingDate", DBNull.Value); }
|
||||
// else { insertCmd.Parameters.AddWithValue("@reportingDate", reportingDate.ToUniversalTime()); }
|
||||
// if (buyerEmail == "") { insertCmd.Parameters.AddWithValue("@buyerEmail", DBNull.Value); }
|
||||
// else { insertCmd.Parameters.AddWithValue("@buyerEmail", buyerEmail); }
|
||||
// if (buyerName == "") { insertCmd.Parameters.AddWithValue("@buyerName", DBNull.Value); }
|
||||
// else { insertCmd.Parameters.AddWithValue("@buyerName", buyerName); }
|
||||
// if (sku == "") { insertCmd.Parameters.AddWithValue("@sku", DBNull.Value); }
|
||||
// else { insertCmd.Parameters.AddWithValue("@sku", sku); }
|
||||
// insertCmd.Parameters.AddWithValue("@quantityShipped", quantityShipped);
|
||||
// if (currency == "") { insertCmd.Parameters.AddWithValue("@currency", DBNull.Value); }
|
||||
// insertCmd.Parameters.AddWithValue("@currency", currency);
|
||||
// insertCmd.Parameters.AddWithValue("@itemPrice", itemPrice);
|
||||
// insertCmd.Parameters.AddWithValue("@itemTax", itemTax);
|
||||
// insertCmd.Parameters.AddWithValue("@shippingPrice", shippingPrice);
|
||||
// insertCmd.Parameters.AddWithValue("@shippingTax", shippingTax);
|
||||
// insertCmd.Parameters.AddWithValue("@giftWrapPrice", giftWrapPrice);
|
||||
// insertCmd.Parameters.AddWithValue("@giftWrapTax", giftWrapTax);
|
||||
// if (recipientName == "") { insertCmd.Parameters.AddWithValue("@recipientName", DBNull.Value); }
|
||||
// else { insertCmd.Parameters.AddWithValue("@recipientName", recipientName); }
|
||||
// if (shipAddress1 == "") { insertCmd.Parameters.AddWithValue("@shipAddress1", DBNull.Value); }
|
||||
// else { insertCmd.Parameters.AddWithValue("@shipAddress1", shipAddress1); }
|
||||
// if (shipAddress2 == "") { insertCmd.Parameters.AddWithValue("@shipAddress2", DBNull.Value); }
|
||||
// else { insertCmd.Parameters.AddWithValue("@shipAddress2", shipAddress2); }
|
||||
// if (shipAddress3 == "") { insertCmd.Parameters.AddWithValue("@shipAddress3", DBNull.Value); }
|
||||
// else { insertCmd.Parameters.AddWithValue("@shipAddress3", shipAddress3); }
|
||||
// if (shipCity == "") { insertCmd.Parameters.AddWithValue("@shipCity", DBNull.Value); }
|
||||
// else { insertCmd.Parameters.AddWithValue("@shipCity", shipCity); }
|
||||
// if (shipState == "") { insertCmd.Parameters.AddWithValue("@shipState", DBNull.Value); }
|
||||
// else { insertCmd.Parameters.AddWithValue("@shipState", shipState); }
|
||||
// if (shipPostalCode == "") { insertCmd.Parameters.AddWithValue("@shipPostalCode", DBNull.Value); }
|
||||
// else { insertCmd.Parameters.AddWithValue("@shipPostalCode", shipPostalCode); }
|
||||
// if (shipCountry == "") { insertCmd.Parameters.AddWithValue("@shipCountry", DBNull.Value); }
|
||||
// else { insertCmd.Parameters.AddWithValue("@shipCountry", shipCountry); }
|
||||
// if (shipPhoneNumber == "") { insertCmd.Parameters.AddWithValue("@shipPhoneNumber", DBNull.Value); }
|
||||
// else { insertCmd.Parameters.AddWithValue("@shipPhoneNumber", shipPhoneNumber); }
|
||||
// if (billAddress1 == "") { insertCmd.Parameters.AddWithValue("@billAddress1", DBNull.Value); }
|
||||
// else { insertCmd.Parameters.AddWithValue("@billAddress1", billAddress1); }
|
||||
// if (billAddress2 == "") { insertCmd.Parameters.AddWithValue("@billAddress2", DBNull.Value); }
|
||||
// else { insertCmd.Parameters.AddWithValue("@billAddress2", billAddress2); }
|
||||
// if (billAddress3 == "") { insertCmd.Parameters.AddWithValue("@billAddress3", DBNull.Value); }
|
||||
// else { insertCmd.Parameters.AddWithValue("@billAddress3", billAddress3); }
|
||||
// if (billCity == "") { insertCmd.Parameters.AddWithValue("@billCity", DBNull.Value); }
|
||||
// else { insertCmd.Parameters.AddWithValue("@billCity", billCity); }
|
||||
// if (billState == "") { insertCmd.Parameters.AddWithValue("@billState", DBNull.Value); }
|
||||
// else { insertCmd.Parameters.AddWithValue("@billState", billState); }
|
||||
// if (billPostalCode == "") { insertCmd.Parameters.AddWithValue("@billPostalCode", DBNull.Value); }
|
||||
// else { insertCmd.Parameters.AddWithValue("@billPostalCode", billPostalCode); }
|
||||
// if (billCountry == "") { insertCmd.Parameters.AddWithValue("@billCountry", DBNull.Value); }
|
||||
// else { insertCmd.Parameters.AddWithValue("@billCountry", billCountry); }
|
||||
// if (itemPromotionDiscount == "") { insertCmd.Parameters.AddWithValue("@itemPromotionDiscount", DBNull.Value); }
|
||||
// else { insertCmd.Parameters.AddWithValue("@itemPromotionDiscount", itemPromotionDiscount); }
|
||||
// if (shipPromotionDiscount == "") { insertCmd.Parameters.AddWithValue("@shipPromotionDiscount", DBNull.Value); }
|
||||
// else { insertCmd.Parameters.AddWithValue("@shipPromotionDiscount", shipPromotionDiscount); }
|
||||
// if (fulfillmentCenterId == "") { insertCmd.Parameters.AddWithValue("@fulfillmentCenterId", DBNull.Value); }
|
||||
// else { insertCmd.Parameters.AddWithValue("@fulfillmentCenterId", fulfillmentCenterId); }
|
||||
// if (fulfillmentChannel == "") { insertCmd.Parameters.AddWithValue("@fulfillmentChannel", DBNull.Value); }
|
||||
// else { insertCmd.Parameters.AddWithValue("@fulfillmentChannel", fulfillmentChannel); }
|
||||
// if (salesChannel == "") { insertCmd.Parameters.AddWithValue("@salesChannel", DBNull.Value); }
|
||||
// else { insertCmd.Parameters.AddWithValue("@salesChannel", salesChannel); }
|
||||
|
||||
// insertCmd.ExecuteNonQuery();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// trans.Commit();
|
||||
// Console.Write("\r");
|
||||
// new Logic.Log.LogEvent().EventLogInsert((lineNumber - (1 + lineErrorSkip + lineDuplicateSkip)) + " total new items inserted, " + lineDuplicateSkip + " duplicates were skipped.");
|
||||
// if (lineErrorSkip > 0)
|
||||
// {
|
||||
// new Logic.Log.LogEvent().EventLogInsert(lineErrorSkip + " total line(s) where skipped due to insufficent number of cells on row", 1);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// //}
|
||||
// //catch (Exception ex)
|
||||
// //{
|
||||
// // new Logic.Log.LogEvent().EventLogInsert("Error running FbaInventoryReceiptReportImport, no records were commited",
|
||||
// // 1,
|
||||
// // ex.ToString() + "\r\nTraceMessage:\r\n" + MiscFunction.TraceMessage()
|
||||
// // );
|
||||
|
||||
// // throw ex;
|
||||
// //}
|
||||
// return true;
|
||||
//}
|
||||
|
||||
public Dictionary<string, decimal> ReadMaxSalePrice(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> ReadSaleCount(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,136 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Log
|
||||
{
|
||||
public class DateTimeLog : Connection
|
||||
{
|
||||
public DateTimeLog()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Date and Time by a unique string.
|
||||
/// </summary>
|
||||
/// <param name="logDateTimeId">Unique string</param>
|
||||
/// <returns>UTC DateTime</returns>
|
||||
public DateTime GetDateTimeUtc(string logDateTimeId)
|
||||
{
|
||||
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
SELECT
|
||||
DateTimeUtc
|
||||
FROM
|
||||
tblLogDateTime
|
||||
WHERE
|
||||
LogDateTimeID = @logDateTimeID
|
||||
", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@logDateTimeID", logDateTimeId);
|
||||
|
||||
object obj = cmd.ExecuteScalar();
|
||||
|
||||
if (obj == null || obj == DBNull.Value)
|
||||
{
|
||||
throw new Exception("Id not found.");
|
||||
}
|
||||
else
|
||||
{
|
||||
DateTime returnDt = (DateTime)obj;
|
||||
return DateTime.SpecifyKind(returnDt, DateTimeKind.Utc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetDateTimeUtc(string logDateTimeID, DateTime utcDateTime)
|
||||
{
|
||||
if (utcDateTime.Kind != DateTimeKind.Utc)
|
||||
{
|
||||
throw new Exception("Datetime kind is not set to UTC");
|
||||
}
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
UPDATE tblLogDateTime
|
||||
SET
|
||||
DateTimeUtc = @utcDateTime
|
||||
,RecordModified = @recordModified
|
||||
WHERE
|
||||
LogDateTimeID = @logDateTimeID
|
||||
", conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@utcDateTime", utcDateTime.ToUniversalTime());
|
||||
cmd.Parameters.AddWithValue("@recordModified", DateTime.UtcNow.ToUniversalTime());
|
||||
cmd.Parameters.AddWithValue("@logDateTimeID", logDateTimeID);
|
||||
|
||||
int count = cmd.ExecuteNonQuery();
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
throw new Exception("Error, failed to update record.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void NewDateTimeUtc(string LogDateTimeId, DateTime utcDateTime, string comments = null)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(LogDateTimeId))
|
||||
{ throw new Exception("Invalid LogDateTimeID"); }
|
||||
|
||||
if (utcDateTime.Kind != DateTimeKind.Utc)
|
||||
{
|
||||
throw new Exception("Datetime kind is not set to UTC");
|
||||
}
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
INSERT INTO tblLogDateTime (
|
||||
LogDateTimeID
|
||||
,DateTimeUtc
|
||||
,Comments
|
||||
,RecordModified
|
||||
,RecordCreated
|
||||
)
|
||||
VALUES (
|
||||
@logDateTimeId
|
||||
,@utcDateTime
|
||||
,@comments
|
||||
,@recordModified
|
||||
,@recordCreated
|
||||
)
|
||||
", conn))
|
||||
{
|
||||
var nowTime = DateTime.UtcNow;
|
||||
cmd.Parameters.AddWithValue("@logDateTimeId", LogDateTimeId);
|
||||
cmd.Parameters.AddWithValue("@utcDateTime", utcDateTime.ToUniversalTime());
|
||||
if (string.IsNullOrWhiteSpace(comments)) { cmd.Parameters.AddWithValue("@comments", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@comments", comments); }
|
||||
cmd.Parameters.AddWithValue("@recordModified", nowTime.ToUniversalTime());
|
||||
cmd.Parameters.AddWithValue("@recordCreated", nowTime.ToUniversalTime());
|
||||
|
||||
int count = cmd.ExecuteNonQuery();
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
throw new Exception("Error updating, no records where effected.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Transactions;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Log
|
||||
{
|
||||
public class LogEvent : Connection
|
||||
{
|
||||
public LogEvent()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected void DatabaseLogInsert
|
||||
(string detailShort, int eventType, string detailLong, DateTime eventDateTime, bool consolePrint = true)
|
||||
{
|
||||
if (consolePrint)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(detailLong))
|
||||
{ UI.Console.WriteLine(detailShort); }
|
||||
else { UI.Console.WriteLine(detailShort + Environment.NewLine + detailLong); }
|
||||
}
|
||||
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
// need to remove this section once code has been rewritten, writing to console will be handled
|
||||
// in the business layer
|
||||
|
||||
// login credentials only allow insert on log table
|
||||
string userId = "Log_bnhtrade";
|
||||
string password = "52ya9dky55cniyynwro5e48mV9";
|
||||
string sqlConnectionString =
|
||||
"Data Source=SQL-Server;Initial Catalog=e2A;Persist Security Info=TRUE;User ID=" + userId +
|
||||
";Password=" + password + ";MultipleActiveResultSets=TRUE";
|
||||
|
||||
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Suppress))
|
||||
{
|
||||
using (SqlConnection sqlConn = new SqlConnection(sqlConnectionString))
|
||||
{
|
||||
sqlConn.Open();
|
||||
try
|
||||
{
|
||||
using (SqlCommand cmd = new SqlCommand(@"
|
||||
INSERT INTO tblLogEvent (
|
||||
EventDateTime
|
||||
,LogEventTypeID
|
||||
,LogEventSourceID
|
||||
,Detail
|
||||
,DetailLong
|
||||
)
|
||||
VALUES (
|
||||
@eventDateTime
|
||||
,@eventType
|
||||
,1
|
||||
,@detailShort
|
||||
,@detailLong
|
||||
)
|
||||
", sqlConn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@eventDateTime", eventDateTime);
|
||||
cmd.Parameters.AddWithValue("@eventType", eventType);
|
||||
cmd.Parameters.AddWithValue("@detailShort", detailShort);
|
||||
if (detailLong == null) { cmd.Parameters.AddWithValue("@detailLong", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@detailLong", detailLong); }
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
UI.Console.WriteLine("WTF!!!! Error with error logging, jobs foooked!");
|
||||
throw ex;
|
||||
}
|
||||
scope.Complete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Product
|
||||
{
|
||||
public class CreateCompetitivePrice : Connection
|
||||
{
|
||||
public CreateCompetitivePrice()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.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()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,215 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Product
|
||||
{
|
||||
public class ReadProduct : Connection
|
||||
{
|
||||
private List<string> filterByAsin;
|
||||
private List<int> filterByProductId;
|
||||
private Data.Database.SqlWhereBuilder sqlWhereBuilder = new SqlWhereBuilder();
|
||||
|
||||
public ReadProduct()
|
||||
{
|
||||
Innit();
|
||||
}
|
||||
|
||||
public List<string> FilterByAsin
|
||||
{
|
||||
get { return filterByAsin; }
|
||||
set
|
||||
{
|
||||
if (value == null) { filterByAsin = new List<string>(); }
|
||||
else { filterByAsin = value; }
|
||||
}
|
||||
}
|
||||
|
||||
public List<int> FilterByProductId
|
||||
{
|
||||
get { return filterByProductId; }
|
||||
set
|
||||
{
|
||||
if (value == null) { filterByProductId = new List<int>(); }
|
||||
else { filterByProductId = value; }
|
||||
}
|
||||
}
|
||||
|
||||
public void Innit()
|
||||
{
|
||||
FilterByProductId = new List<int>();
|
||||
FilterByAsin = new List<string>();
|
||||
}
|
||||
|
||||
public List<Model.Product.ProductInfo> ExecuteQuery()
|
||||
{
|
||||
var returnList = new List<Model.Product.ProductInfo>();
|
||||
|
||||
// build SQL string
|
||||
string sqlString = @"
|
||||
SELECT [prdProductID]
|
||||
,[prdTitle]
|
||||
,[TitleSuffix]
|
||||
,[ProductCategoryID]
|
||||
,[ProductCategorySubID]
|
||||
,[ReleaseDate]
|
||||
,[RecommendedRetailPrice]
|
||||
,[prdMaxPrice]
|
||||
,[prdAmazonASIN]
|
||||
,[Manufacturer]
|
||||
,[PackageWeightKilogram]
|
||||
,[PackageDimensionHeightMeter]
|
||||
,[PackageDimensionWidthMeter]
|
||||
,[PackageDimensionLengthMeter]
|
||||
,[CatId]
|
||||
,[ProductProcurementControlID]
|
||||
,[ManualCompetativePriceUpdate]
|
||||
,[prdAmazonBuyBoxActive]
|
||||
,[prdAmazonBuyBoxActiveUpdated]
|
||||
,[prdActive]
|
||||
,[prdRecordCreated]
|
||||
,[prdRecordModified]
|
||||
,[Draft]
|
||||
FROM [e2A].[dbo].[tblProduct]
|
||||
WHERE 1=1 ";
|
||||
|
||||
var sqlBuilder = new Database.SqlWhereBuilder();
|
||||
|
||||
if (FilterByProductId.Any())
|
||||
{
|
||||
sqlBuilder.In("prdProductID", FilterByProductId, "AND");
|
||||
sqlString = sqlString + sqlBuilder.SqlWhereString;
|
||||
}
|
||||
|
||||
if (FilterByAsin.Any())
|
||||
{
|
||||
sqlBuilder.In("prdAmazonASIN", FilterByAsin, "AND");
|
||||
sqlString = sqlString + sqlBuilder.SqlWhereString;
|
||||
}
|
||||
|
||||
// execute query and build result list
|
||||
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
using (SqlCommand cmd = new SqlCommand(sqlString, conn))
|
||||
{
|
||||
sqlBuilder.AddParametersToSqlCommand(cmd);
|
||||
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (!reader.HasRows)
|
||||
{
|
||||
return returnList;
|
||||
}
|
||||
|
||||
while (reader.Read())
|
||||
{
|
||||
// none nullable values
|
||||
string title = reader.GetString(1);
|
||||
int productCategoryId = reader.GetInt32(3);
|
||||
int productProcurementControlId = reader.GetInt32(15);
|
||||
|
||||
// create model
|
||||
var item = new Model.Product.ProductInfo(title, productCategoryId, productProcurementControlId);
|
||||
item.ProductID = reader.GetInt32(0);
|
||||
|
||||
// add nullable items to model
|
||||
if (!reader.IsDBNull(2))
|
||||
item.TitleSuffix = reader.GetString(2);
|
||||
if (!reader.IsDBNull(4))
|
||||
item.ProductCategorySubID = reader.GetInt32(4);
|
||||
if (!reader.IsDBNull(5))
|
||||
item.ReleaseDate = DateTime.SpecifyKind(reader.GetDateTime(5), DateTimeKind.Utc);
|
||||
if (!reader.IsDBNull(6))
|
||||
item.RecommendedRetailPrice = reader.GetDecimal(6);
|
||||
if (!reader.IsDBNull(7))
|
||||
item.MaxPrice = reader.GetDecimal(7);
|
||||
if (!reader.IsDBNull(8))
|
||||
item.AmazonASIN = reader.GetString(8);
|
||||
if (!reader.IsDBNull(9))
|
||||
item.Manufacturer = reader.GetString(9);
|
||||
if (!reader.IsDBNull(10))
|
||||
item.PackageWeightKilogram = reader.GetDecimal(10);
|
||||
if (!reader.IsDBNull(11) && !reader.IsDBNull(12) && !reader.IsDBNull(13))
|
||||
item.SetPackageDimension(reader.GetDecimal(11), reader.GetDecimal(12), reader.GetDecimal(13));
|
||||
if (!reader.IsDBNull(14))
|
||||
item.CatId = reader.GetInt32(14);
|
||||
if (!reader.IsDBNull(16))
|
||||
item.ManualCompetativePriceUpdate = reader.GetBoolean(16);
|
||||
if (!reader.IsDBNull(17))
|
||||
item.AmazonBuyBoxActive = reader.GetBoolean(17);
|
||||
if (!reader.IsDBNull(18))
|
||||
item.AmazonBuyBoxActiveUpdated = DateTime.SpecifyKind(reader.GetDateTime(18), DateTimeKind.Utc);
|
||||
if (!reader.IsDBNull(19))
|
||||
item.IsActive = reader.GetBoolean(19);
|
||||
if (!reader.IsDBNull(20))
|
||||
item.RecordCreated = DateTime.SpecifyKind(reader.GetDateTime(20), DateTimeKind.Utc);
|
||||
if (!reader.IsDBNull(21))
|
||||
item.RecordModified = DateTime.SpecifyKind(reader.GetDateTime(21), DateTimeKind.Utc);
|
||||
if (!reader.IsDBNull(22))
|
||||
item.IsDraft = reader.GetBoolean(22);
|
||||
|
||||
returnList.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return returnList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get product id by sku number
|
||||
/// </summary>
|
||||
/// <param name="skuNumberList">List of SKU numbers to query</param>
|
||||
/// <returns>Dictionary with SKU number as key and product id as value</returns>
|
||||
public Dictionary<string, int> ProductIdBySkuNumber(List<string> skuNumberList)
|
||||
{
|
||||
var returnList = new Dictionary<string, int>();
|
||||
|
||||
if (skuNumberList == null || !skuNumberList.Any())
|
||||
{
|
||||
return returnList;
|
||||
}
|
||||
|
||||
skuNumberList = skuNumberList.Distinct().ToList();
|
||||
|
||||
string sql = @"
|
||||
SELECT tblProduct.prdProductID
|
||||
,tblSku.skuSkuNumber
|
||||
FROM tblProduct
|
||||
INNER JOIN tblSku ON tblProduct.prdProductID = tblSku.skuProductID
|
||||
WHERE
|
||||
";
|
||||
|
||||
var sqlWhereBuilder = new Database.SqlWhereBuilder();
|
||||
sqlWhereBuilder.Init();
|
||||
sqlWhereBuilder.In("tblSku.skuSkuNumber", skuNumberList);
|
||||
sql += sqlWhereBuilder.SqlWhereString;
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
sqlWhereBuilder.AddParametersToSqlCommand(cmd);
|
||||
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
returnList.Add(reader.GetString(1), reader.GetInt32(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return returnList;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Product
|
||||
{
|
||||
class ReadProductId : Connection
|
||||
{
|
||||
public Dictionary<string, int> ProductIdByAsin(List<string> asinList)
|
||||
{
|
||||
var productIdList = new Dictionary<string, int>();
|
||||
if (asinList == null || !asinList.Any())
|
||||
return productIdList;
|
||||
|
||||
// build SQL string
|
||||
string sql =
|
||||
@"SELECT prdProductID, prdAmazonASIN
|
||||
FROM [e2A].[dbo].[tblProduct]
|
||||
WHERE ";
|
||||
|
||||
var sqlBuilder = new Database.SqlWhereBuilder();
|
||||
sqlBuilder.In("prdAmazonASIN", asinList);
|
||||
sql = sql + sqlBuilder.SqlWhereString;
|
||||
|
||||
// execute query and build result list
|
||||
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
sqlBuilder.AddParametersToSqlCommand(cmd);
|
||||
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
productIdList.Add(reader.GetString(1), reader.GetInt32(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return productIdList;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
using MarketplaceWebServiceProducts.Model;
|
||||
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 UpdateAmazonFeeEstimate : Connection
|
||||
{
|
||||
public UpdateAmazonFeeEstimate(string sqlConnectionString) : base(sqlConnectionString)
|
||||
{
|
||||
}
|
||||
|
||||
public void ByFeesEstimateResult(FeesEstimateResult updateItem)
|
||||
{
|
||||
ByFeesEstimateResult(new List<FeesEstimateResult> { updateItem });
|
||||
}
|
||||
|
||||
public void ByFeesEstimateResult(List<FeesEstimateResult> updateList)
|
||||
{
|
||||
foreach (var item in updateList)
|
||||
{
|
||||
bool isSellerSku = false;
|
||||
if (item.FeesEstimateIdentifier.IdType == "SellerSKU")
|
||||
{
|
||||
isSellerSku = true;
|
||||
}
|
||||
else if (item.FeesEstimateIdentifier.IdType != "ASIN")
|
||||
{
|
||||
// Amazon have updated API to include other identifiers?
|
||||
throw new Exception(
|
||||
"New FeesEstimateIdentifier encountered/unsupported of type '" + item.FeesEstimateIdentifier + "'.");
|
||||
}
|
||||
|
||||
string asin = item.FeesEstimateIdentifier.IdValue;
|
||||
bool isAmazonFulfilled = item.FeesEstimateIdentifier.IsAmazonFulfilled;
|
||||
DateTime timeOfFeeEstimation = item.FeesEstimate.TimeOfFeesEstimation;
|
||||
decimal totalFeeEstimate = item.FeesEstimate.TotalFeesEstimate.Amount;
|
||||
string currencyCode = item.FeesEstimate.TotalFeesEstimate.CurrencyCode;
|
||||
decimal priceToEstimateFeeListingPrice = item.FeesEstimateIdentifier.PriceToEstimateFees.ListingPrice.Amount;
|
||||
decimal priceToEstimateFeeShipping = 0;
|
||||
if (item.FeesEstimateIdentifier.PriceToEstimateFees.Shipping != null)
|
||||
{ priceToEstimateFeeShipping = item.FeesEstimateIdentifier.PriceToEstimateFees.Shipping.Amount; }
|
||||
decimal priceToEstimateFeePoints = 0;
|
||||
if (item.FeesEstimateIdentifier.PriceToEstimateFees.Points != null)
|
||||
{ priceToEstimateFeePoints = item.FeesEstimateIdentifier.PriceToEstimateFees.Points.PointsMonetaryValue.Amount; }
|
||||
|
||||
decimal referralFee = 0m;
|
||||
decimal variableClosingFee = 0m;
|
||||
decimal fulfillmentFees = 0m;
|
||||
decimal perItemFee = 0m;
|
||||
decimal otherFee_Exception = 0m;
|
||||
|
||||
FeeDetailList feeDetailList = item.FeesEstimate.FeeDetailList;
|
||||
List<FeeDetail> feeDetail = feeDetailList.FeeDetail;
|
||||
foreach (FeeDetail feeDetailItem in feeDetail)
|
||||
{
|
||||
if (feeDetailItem.FeeType == "AmazonReferralFee" || feeDetailItem.FeeType == "ReferralFee")
|
||||
{ referralFee = feeDetailItem.FinalFee.Amount; }
|
||||
else if (feeDetailItem.FeeType == "VariableClosingFee")
|
||||
{ variableClosingFee = feeDetailItem.FinalFee.Amount; }
|
||||
else if (feeDetailItem.FeeType == "PerItemFee")
|
||||
{ perItemFee = feeDetailItem.FinalFee.Amount; }
|
||||
else if (feeDetailItem.FeeType == "FBAFees" || feeDetailItem.FeeType == "FulfillmentFees")
|
||||
{ fulfillmentFees = feeDetailItem.FinalFee.Amount; }
|
||||
else
|
||||
{ otherFee_Exception = otherFee_Exception + feeDetailItem.FinalFee.Amount; }
|
||||
|
||||
}
|
||||
|
||||
// build sql statement
|
||||
string sqlProductId;
|
||||
if (isSellerSku)
|
||||
{
|
||||
sqlProductId = "(SELECT tblSku.skuProductID FROM tblSku INNER JOIN tblProduct ON tblSku.skuProductID = tblProduct.prdProductID WHERE tblProduct.prdAmazonASIN = @asin)";
|
||||
}
|
||||
else
|
||||
{
|
||||
sqlProductId = "(SELECT prdProductID FROM tblProduct WHERE prdAmazonASIN = @asin)";
|
||||
}
|
||||
|
||||
string sql = @"
|
||||
UPDATE tblAmazonFeeEstimate SET
|
||||
IsAmazonFulfilled=@isAmazonFulfilled, TimeOfFeeEstimation=@timeOfFeeEstimation,
|
||||
TotalFeeEstimate=@totalFeeEstimate, PriceToEstimateFeeListingPrice=@priceToEstimateFeeListingPrice,
|
||||
PriceToEstimateFeeShipping=@priceToEstimateFeeShipping, PriceToEstimateFeePoints=@priceToEstimateFeePoints,
|
||||
ReferralFee=@referralFee, VariableClosingFee=@variableClosingFee, PerItemFee=@perItemFee, FBAFee=@fbaFee,
|
||||
OtherFee_Exception=@otherFee_Exception, currencyCode=CurrencyCode
|
||||
WHERE ProductID = " + sqlProductId + @"
|
||||
IF @@ROWCOUNT = 0
|
||||
INSERT INTO tblAmazonFeeEstimate (
|
||||
ProductID, IsAmazonFulfilled, TimeOfFeeEstimation, TotalFeeEstimate, PriceToEstimateFeeListingPrice,
|
||||
PriceToEstimateFeeShipping, PriceToEstimateFeePoints, ReferralFee, VariableClosingFee, PerItemFee, FBAFee,
|
||||
OtherFee_Exception, CurrencyCode
|
||||
) VALUES (
|
||||
" + sqlProductId + @", @isAmazonFulfilled, @timeOfFeeEstimation, @totalFeeEstimate, @priceToEstimateFeeListingPrice,
|
||||
@priceToEstimateFeeShipping, @priceToEstimateFeePoints, @referralFee, @variableClosingFee, @perItemFee, @fbaFee,
|
||||
@otherFee_Exception, @currencyCode
|
||||
)
|
||||
";
|
||||
|
||||
using (SqlConnection sqlConn = new SqlConnection(sqlConnectionString))
|
||||
{
|
||||
sqlConn.Open();
|
||||
using (SqlCommand sqlCommand = new SqlCommand(sql, sqlConn))
|
||||
{
|
||||
sqlCommand.Parameters.AddWithValue("@asin", asin);
|
||||
sqlCommand.Parameters.AddWithValue("@isAmazonFulfilled", isAmazonFulfilled);
|
||||
sqlCommand.Parameters.AddWithValue("@timeOfFeeEstimation", timeOfFeeEstimation);
|
||||
sqlCommand.Parameters.AddWithValue("@totalFeeEstimate", totalFeeEstimate);
|
||||
sqlCommand.Parameters.AddWithValue("@priceToEstimateFeeListingPrice", priceToEstimateFeeListingPrice);
|
||||
sqlCommand.Parameters.AddWithValue("@priceToEstimateFeeShipping", priceToEstimateFeeShipping);
|
||||
sqlCommand.Parameters.AddWithValue("@priceToEstimateFeePoints", priceToEstimateFeePoints);
|
||||
sqlCommand.Parameters.AddWithValue("@referralFee", referralFee);
|
||||
sqlCommand.Parameters.AddWithValue("@variableClosingFee", variableClosingFee);
|
||||
sqlCommand.Parameters.AddWithValue("@perItemFee", perItemFee);
|
||||
sqlCommand.Parameters.AddWithValue("@fbaFee", fulfillmentFees);
|
||||
sqlCommand.Parameters.AddWithValue("@otherFee_Exception", otherFee_Exception);
|
||||
sqlCommand.Parameters.AddWithValue("@currencyCode", currencyCode);
|
||||
|
||||
sqlCommand.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database
|
||||
{
|
||||
public class ReadRandomData : Connection
|
||||
{
|
||||
public List<string> GetSkuNumber(int listCount)
|
||||
{
|
||||
var returnList = new List<string>();
|
||||
if (listCount < 1)
|
||||
return returnList;
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
using (SqlCommand cmd = new SqlCommand(
|
||||
"SELECT TOP "+ listCount + " [skuSkuNumber] FROM [e2A].[dbo].[tblSku] ORDER BY newid()", conn))
|
||||
{
|
||||
using (var reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
returnList.Add(reader.GetString(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnList;
|
||||
}
|
||||
|
||||
public List<string> GetAsinNumber(int listCount)
|
||||
{
|
||||
var returnList = new List<string>();
|
||||
if (listCount < 1)
|
||||
return returnList;
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(SqlConnectionString))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
using (SqlCommand cmd = new SqlCommand(
|
||||
"SELECT TOP " + listCount + " prdAmazonASIN FROM [e2A].[dbo].[tblProduct] WHERE prdAmazonASIN IS NOT NULL ORDER BY newid()", conn))
|
||||
{
|
||||
using (var reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
returnList.Add(reader.GetString(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnList;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
using bnhtrade.Core.Data.Database._BoilerPlate;
|
||||
using bnhtrade.Core.Data.Database.Repository.Interface;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Repository.Implementation
|
||||
{
|
||||
internal class AccountCodeRepository : _Base, IAccountCodeRepository
|
||||
{
|
||||
public AccountCodeRepository(IDbConnection connection, IDbTransaction transaction) : base(connection, transaction)
|
||||
{
|
||||
}
|
||||
|
||||
public Dictionary<int, Model.Account.Account> ReadAccountCode(List<int> accountIdList = null, List<int> accountCodeList = null)
|
||||
{
|
||||
var resultDict = new Dictionary<int, Model.Account.Account>();
|
||||
var sqlWhere = new SqlWhereBuilder();
|
||||
|
||||
//build sql query
|
||||
string sqlString = @"
|
||||
SELECT tblAccountChartOf.AccountChartOfID
|
||||
,tblAccountChartOf.AccountCode
|
||||
,tblAccountChartOf.AccountName
|
||||
,tblAccountChartOf.Description
|
||||
,tblAccountChartOfType.AccountChartOfType
|
||||
,tblAccountChartOfType.BasicType
|
||||
,tblAccountChartOfType.Multiplier
|
||||
FROM tblAccountChartOf
|
||||
INNER JOIN tblAccountChartOfType ON tblAccountChartOf.AccountChartOfTypeID = tblAccountChartOfType.AccountChartOfTypeID
|
||||
WHERE 1=1 ";
|
||||
|
||||
if (accountIdList != null && accountIdList.Any())
|
||||
{
|
||||
sqlWhere.In("tblAccountChartOf.AccountChartOfID", accountIdList, " AND ");
|
||||
}
|
||||
if (accountCodeList != null && accountCodeList.Any())
|
||||
{
|
||||
sqlWhere.In("tblAccountChartOf.AccountCode", accountCodeList, " AND ");
|
||||
}
|
||||
if (sqlWhere.IsSetSqlWhereString)
|
||||
{
|
||||
sqlString = sqlString + sqlWhere.SqlWhereString;
|
||||
}
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = sqlString;
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
|
||||
if (sqlWhere.ParameterListIsSet)
|
||||
{
|
||||
sqlWhere.AddParametersToSqlCommand(cmd);
|
||||
}
|
||||
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
|
||||
int tablePk = reader.GetInt32(0);
|
||||
int accountCode = reader.GetInt32(1);
|
||||
string title = reader.GetString(2);
|
||||
string description = null;
|
||||
if (!reader.IsDBNull(3)) { description = reader.GetString(3); }
|
||||
string type = reader.GetString(4);
|
||||
string basicType = reader.GetString(5);
|
||||
int multiplier = reader.GetInt32(6);
|
||||
|
||||
var result = new Model.Account.Account(tablePk, accountCode, title, description, type, basicType, multiplier);
|
||||
resultDict.Add(tablePk, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
return resultDict;
|
||||
}
|
||||
}
|
||||
}
|
||||
+488
@@ -0,0 +1,488 @@
|
||||
using bnhtrade.Core.Data.Database._BoilerPlate;
|
||||
using bnhtrade.Core.Data.Database.Repository.Interface;
|
||||
using bnhtrade.Core.Model.Account;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Transactions;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Repository.Implementation
|
||||
{
|
||||
internal class AccountJournalRepository : _Base, IAccountJournalRepository
|
||||
{
|
||||
public AccountJournalRepository(IDbConnection connection, IDbTransaction transaction) : base(connection, transaction)
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// create
|
||||
//
|
||||
|
||||
public int InsertJournalHeader(int accountJournalTypeId, DateTime entryDate, bool lockEntry = false)
|
||||
{
|
||||
// ensure date is UTC
|
||||
if (entryDate.Kind != DateTimeKind.Utc)
|
||||
{
|
||||
throw new Exception("DateTime kind must be utc");
|
||||
}
|
||||
|
||||
// debit and credit locks are checked in journal post method
|
||||
// insert the journal entry
|
||||
int journalId;
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText = @"
|
||||
INSERT INTO tblAccountJournal
|
||||
(AccountJournalTypeID, EntryDate, IsLocked)
|
||||
OUTPUT INSERTED.AccountJournalID
|
||||
VALUES
|
||||
(@journalTypeId, @entryDate, @lockEntry);";
|
||||
|
||||
// add parameters
|
||||
cmd.Parameters.AddWithValue("@journalTypeId", accountJournalTypeId);
|
||||
cmd.Parameters.AddWithValue("@entryDate", entryDate.ToUniversalTime());
|
||||
cmd.Parameters.AddWithValue("@lockEntry", lockEntry);
|
||||
|
||||
//execute
|
||||
journalId = (int)cmd.ExecuteScalar();
|
||||
}
|
||||
|
||||
return journalId;
|
||||
}
|
||||
|
||||
public int InsertJournalPost(int accountJournalId, int accountChartOfId, decimal amountGbp)
|
||||
{
|
||||
if (accountJournalId <= 0)
|
||||
{
|
||||
throw new ArgumentException("Invalid journal ID provided.", nameof(accountJournalId));
|
||||
}
|
||||
if (accountChartOfId <= 0)
|
||||
{
|
||||
throw new ArgumentException("Invalid account chart of ID provided.", nameof(accountChartOfId));
|
||||
}
|
||||
if (amountGbp == 0)
|
||||
{
|
||||
throw new ArgumentException("Amount cannot be zero.", nameof(amountGbp));
|
||||
}
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText = @"
|
||||
INSERT INTO tblAccountJournalPost
|
||||
(AccountJournalID, AccountChartOfID, AmountGbp)
|
||||
OUTPUT INSERTED.AccountJournalPostID
|
||||
VALUES
|
||||
(@accountJournalId, @accountChartOfId, @amountGbp);";
|
||||
|
||||
// add parameters
|
||||
cmd.Parameters.AddWithValue("@accountJournalId", accountJournalId);
|
||||
cmd.Parameters.AddWithValue("@accountChartOfId", accountChartOfId);
|
||||
cmd.Parameters.AddWithValue("@amountGbp", amountGbp);
|
||||
|
||||
// execute
|
||||
return (int)cmd.ExecuteScalar();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// read
|
||||
//
|
||||
|
||||
public Dictionary<int, Model.Account.JournalBuilder> ReadJournalBuilder(List<int> journalIdList)
|
||||
{
|
||||
var sqlBuilder = new SqlWhereBuilder();
|
||||
var returnDict = new Dictionary<int, Model.Account.JournalBuilder>();
|
||||
|
||||
//build sql query
|
||||
string sql = @"
|
||||
SELECT tblAccountJournal.AccountJournalID
|
||||
,tblAccountJournal.AccountJournalTypeID
|
||||
,tblAccountJournal.EntryDate
|
||||
,tblAccountJournal.PostDate
|
||||
,tblAccountJournal.LastModified
|
||||
,tblAccountJournal.IsLocked
|
||||
,tblAccountJournalPost.AccountJournalPostID
|
||||
,tblAccountJournalPost.AccountChartOfID
|
||||
,tblAccountJournalPost.AmountGbp
|
||||
FROM tblAccountJournal
|
||||
INNER JOIN tblAccountJournalPost ON tblAccountJournal.AccountJournalID = tblAccountJournalPost.AccountJournalID
|
||||
WHERE 1 = 1 ";
|
||||
|
||||
// build the where statments
|
||||
if (journalIdList.Any())
|
||||
{
|
||||
sqlBuilder.In("tblAccountJournal.AccountJournalID", journalIdList, "AND");
|
||||
}
|
||||
|
||||
// append where string to the sql
|
||||
if (sqlBuilder.IsSetSqlWhereString)
|
||||
{
|
||||
sql = sql + sqlBuilder.SqlWhereString;
|
||||
}
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = sql;
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
|
||||
if (sqlBuilder.ParameterListIsSet)
|
||||
{
|
||||
sqlBuilder.AddParametersToSqlCommand(cmd);
|
||||
}
|
||||
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
int journalId = reader.GetInt32(0);
|
||||
if (returnDict.ContainsKey(journalId) == false)
|
||||
{
|
||||
var journalBuilder = new Model.Account.JournalBuilder();
|
||||
journalBuilder.JournalId = journalId;
|
||||
journalBuilder.JournalTypeId = reader.GetInt32(1);
|
||||
journalBuilder.EntryDate = DateTime.SpecifyKind(reader.GetDateTime(2), DateTimeKind.Utc);
|
||||
journalBuilder.PostDate = DateTime.SpecifyKind(reader.GetDateTime(3), DateTimeKind.Utc);
|
||||
journalBuilder.LastModified = DateTime.SpecifyKind(reader.GetDateTime(4), DateTimeKind.Utc);
|
||||
journalBuilder.IsLocked = reader.GetBoolean(5);
|
||||
journalBuilder.JournalBuilderPosts = new List<Model.Account.JournalBuilder.JournalPostBuilder>();
|
||||
|
||||
returnDict.Add(journalId, journalBuilder);
|
||||
}
|
||||
|
||||
var journalBuilderLine = new Model.Account.JournalBuilder.JournalPostBuilder();
|
||||
journalBuilderLine.PostId = reader.GetInt32(6);
|
||||
journalBuilderLine.AccountId = reader.GetInt32(7);
|
||||
journalBuilderLine.AmountGbp = reader.GetDecimal(8);
|
||||
|
||||
returnDict[journalId].JournalBuilderPosts.Add(journalBuilderLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnDict;
|
||||
}
|
||||
|
||||
public DateTime ReadJournalEntryDate(int journalId)
|
||||
{
|
||||
if (journalId <= 0)
|
||||
{
|
||||
throw new ArgumentException("Invalid journal ID provided.", nameof(journalId));
|
||||
}
|
||||
|
||||
string sql = @"
|
||||
SELECT tblAccountJournal.EntryDate
|
||||
FROM tblAccountJournal
|
||||
WHERE (((tblAccountJournal.AccountJournalID)=@accountJournalId));";
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = sql;
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
|
||||
cmd.Parameters.AddWithValue("@accountJournalId", journalId);
|
||||
|
||||
object obj = cmd.ExecuteScalar();
|
||||
|
||||
if (obj == null)
|
||||
{
|
||||
throw new Exception("Journal entry not found for AccountJournalID=" + journalId);
|
||||
}
|
||||
|
||||
return DateTime.SpecifyKind((DateTime)obj, DateTimeKind.Utc);
|
||||
}
|
||||
}
|
||||
|
||||
public int CountJournalPosts(int accountJournalId)
|
||||
{
|
||||
if (accountJournalId <= 0)
|
||||
{
|
||||
throw new ArgumentException("Invalid journal ID provided.", nameof(accountJournalId));
|
||||
}
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText = @"
|
||||
SELECT
|
||||
Count(tblAccountJournalPost.AccountJournalPostID) AS CountOfAccountJournalPostID
|
||||
FROM
|
||||
tblAccountJournalPost
|
||||
WHERE
|
||||
(((tblAccountJournalPost.AccountJournalID)=@AccountJournalID));";
|
||||
cmd.Parameters.AddWithValue("@accountJournalId", accountJournalId);
|
||||
return (int)cmd.ExecuteScalar();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsJournalDebitAssetType(int accountJournalId)
|
||||
{
|
||||
if (accountJournalId <= 0)
|
||||
{
|
||||
throw new ArgumentException("Invalid journal ID provided.", nameof(accountJournalId));
|
||||
}
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText = @"
|
||||
SELECT
|
||||
Count(tblAccountJournalPost.AccountJournalPostID) AS CountOfAccountJournalPostID
|
||||
FROM
|
||||
(tblAccountJournalPost
|
||||
INNER JOIN tblAccountChartOf
|
||||
ON tblAccountJournalPost.AccountChartOfID = tblAccountChartOf.AccountChartOfID)
|
||||
INNER JOIN tblAccountChartOfType
|
||||
ON tblAccountChartOf.AccountChartOfTypeID = tblAccountChartOfType.AccountChartOfTypeID
|
||||
WHERE
|
||||
tblAccountJournalPost.AmountGbp>=0
|
||||
AND tblAccountChartOfType.BasicType='Asset'
|
||||
AND tblAccountJournalPost.AccountJournalID=@accountJournalId;";
|
||||
|
||||
cmd.Parameters.AddWithValue("@accountJournalId", accountJournalId);
|
||||
|
||||
if ((int)cmd.ExecuteScalar() < 1)
|
||||
{
|
||||
return false; // no debit posts of type Asset found
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test for locked journal entry
|
||||
/// </summary>
|
||||
/// <returns>True/False or null on no records found</returns>
|
||||
public bool? IsJournalLocked(int accountJournalId)
|
||||
{
|
||||
if (accountJournalId <= 0)
|
||||
{
|
||||
throw new ArgumentException("Invalid journal ID provided.", nameof(accountJournalId));
|
||||
}
|
||||
|
||||
string sql = @"
|
||||
SELECT
|
||||
tblAccountJournal.IsLocked
|
||||
FROM
|
||||
tblAccountJournal
|
||||
WHERE
|
||||
tblAccountJournal.AccountJournalID=@accountJournalId;";
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = sql;
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
|
||||
cmd.Parameters.AddWithValue("@accountJournalId", accountJournalId);
|
||||
|
||||
object obj = cmd.ExecuteScalar();
|
||||
if (obj == null || obj == DBNull.Value)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (bool)obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<(int, string, int?, int?)> ReadJournalType(List<int> accountJournalTypeIds = null, List<string> typeTitles = null)
|
||||
{
|
||||
var returnList = new List<(int, string, int?, int?)>();
|
||||
var sqlBuilder = new SqlWhereBuilder();
|
||||
|
||||
//build sql query
|
||||
string sql = @"
|
||||
SELECT [AccountJournalTypeID]
|
||||
,[TypeTitle]
|
||||
,[ChartOfAccountID_Debit]
|
||||
,[ChartOfAccountID_Credit]
|
||||
FROM [e2A].[dbo].[tblAccountJournalType]
|
||||
WHERE 1 = 1 ";
|
||||
|
||||
// build the where statments
|
||||
if (accountJournalTypeIds.Any())
|
||||
{
|
||||
sqlBuilder.In("AccountJournalTypeID", accountJournalTypeIds, "AND");
|
||||
}
|
||||
if (typeTitles.Any())
|
||||
{
|
||||
sqlBuilder.In("TypeTitle", typeTitles, "AND");
|
||||
}
|
||||
|
||||
// append where string to the sql
|
||||
if (sqlBuilder.IsSetSqlWhereString)
|
||||
{
|
||||
sql = sql + sqlBuilder.SqlWhereString;
|
||||
}
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = sql;
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
|
||||
if (sqlBuilder.ParameterListIsSet)
|
||||
{
|
||||
sqlBuilder.AddParametersToSqlCommand(cmd);
|
||||
}
|
||||
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
// read from db and create object
|
||||
int journalTypeId = reader.GetInt32(0);
|
||||
string title = reader.GetString(1);
|
||||
int? debitAccountId = null;
|
||||
if (!reader.IsDBNull(2))
|
||||
debitAccountId = reader.GetInt32(2);
|
||||
int? creditAccountId = null;
|
||||
if (!reader.IsDBNull(3))
|
||||
creditAccountId = reader.GetInt32(3);
|
||||
|
||||
returnList.Add((journalTypeId, title, debitAccountId, creditAccountId));
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the default debit and credit account IDs associated with a specific account journal.
|
||||
/// </summary>
|
||||
/// <remarks>This method queries the database to retrieve the default debit and credit account IDs
|
||||
/// for the specified account journal. If the account journal does not exist, an exception is thrown. Ensure
|
||||
/// that the provided <paramref name="accountJournalId"/> is valid.</remarks>
|
||||
/// <param name="accountJournalId">The unique identifier of the account journal for which to retrieve the default debit and credit account IDs.</param>
|
||||
/// <returns>A tuple containing two nullable integers: <list type="bullet"> <item><description>The first value represents
|
||||
/// the default debit account ID, or <see langword="null"/> if no debit account is set.</description></item>
|
||||
/// <item><description>The second value represents the default credit account ID, or <see langword="null"/> if
|
||||
/// no credit account is set.</description></item> </list></returns>
|
||||
/// <exception cref="Exception">Thrown if the specified <paramref name="accountJournalId"/> does not exist in the database.</exception>
|
||||
public (int?, int?) ReadJournalTypeDefaultDebitCredit(int accountJournalId)
|
||||
{
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText = @"
|
||||
SELECT
|
||||
tblAccountJournalType.ChartOfAccountID_Debit, tblAccountJournalType.ChartOfAccountID_Credit
|
||||
FROM
|
||||
tblAccountJournal
|
||||
INNER JOIN tblAccountJournalType
|
||||
ON tblAccountJournal.AccountJournalTypeID = tblAccountJournalType.AccountJournalTypeID
|
||||
WHERE
|
||||
(((tblAccountJournal.AccountJournalID)=@journalId));";
|
||||
|
||||
cmd.Parameters.AddWithValue("@journalId", accountJournalId);
|
||||
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
int? defaultDebit = null;
|
||||
int? defaultCredit = null;
|
||||
|
||||
// debit check
|
||||
if (reader.IsDBNull(0) == false)
|
||||
{
|
||||
defaultDebit = reader.GetInt32(0);
|
||||
}
|
||||
// credit check
|
||||
if (reader.IsDBNull(1) == false)
|
||||
{
|
||||
defaultCredit = reader.GetInt32(1);
|
||||
}
|
||||
return (defaultDebit, defaultCredit);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("AccountJournalID '" + accountJournalId + "' does not exist.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// update
|
||||
//
|
||||
|
||||
public bool UpdateJournalEntryModifiedDate(int accountJournalId)
|
||||
{
|
||||
if (accountJournalId <= 0)
|
||||
{
|
||||
throw new ArgumentException("Invalid journal ID provided.", nameof(accountJournalId));
|
||||
}
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText = @"
|
||||
UPDATE
|
||||
tblAccountJournal
|
||||
SET
|
||||
tblAccountJournal.LastModified=@utcNow
|
||||
WHERE
|
||||
(((tblAccountJournal.AccountJournalID)=@accountJournalId));";
|
||||
|
||||
cmd.Parameters.AddWithValue("@accountJournalId", accountJournalId);
|
||||
cmd.Parameters.AddWithValue("@utcNow", DateTime.UtcNow);
|
||||
|
||||
if (cmd.ExecuteNonQuery() == 1)
|
||||
{
|
||||
return true; // update successful
|
||||
}
|
||||
else
|
||||
{
|
||||
return false; // update failed, journal ID may not exist
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// delete
|
||||
//
|
||||
|
||||
public int DeleteJournalHeader(int accountJournalId)
|
||||
{
|
||||
if (accountJournalId <= 0)
|
||||
{
|
||||
throw new ArgumentException("Invalid journal ID provided.", nameof(accountJournalId));
|
||||
}
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText = @"
|
||||
DELETE FROM
|
||||
tblAccountJournal
|
||||
WHERE
|
||||
AccountJournalID=@accountJournalId;";
|
||||
|
||||
cmd.Parameters.AddWithValue("@accountJournalId", accountJournalId);
|
||||
return cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
|
||||
public int DeleteJournalPostAll(int accountJournalId)
|
||||
{
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText = @"
|
||||
DELETE FROM
|
||||
tblAccountJournalPost
|
||||
WHERE
|
||||
tblAccountJournalPost.AccountJournalID = @accountJournalId;";
|
||||
|
||||
cmd.Parameters.AddWithValue("@accountJournalId", accountJournalId);
|
||||
return cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
using bnhtrade.Core.Data.Database._BoilerPlate;
|
||||
using bnhtrade.Core.Data.Database.Repository.Interface;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Repository.Implementation
|
||||
{
|
||||
internal class AccountTaxRepository : _Base, IAccountTaxRepository
|
||||
{
|
||||
public AccountTaxRepository(IDbConnection connection, IDbTransaction transaction) : base(connection, transaction)
|
||||
{
|
||||
}
|
||||
|
||||
public Dictionary<int, Model.Account.TaxCodeInfo> ReadTaxCodeInfo(bool? IsActive = null, List<string> taxcodeList = null, List<int> taxcodeIdList = null)
|
||||
{
|
||||
var resultList = new Dictionary<int, Model.Account.TaxCodeInfo>();
|
||||
Data.Database.SqlWhereBuilder whereBuilder = new SqlWhereBuilder();
|
||||
|
||||
//build sql query
|
||||
string sqlString = @"
|
||||
SELECT
|
||||
AccountTaxCodeID
|
||||
,TaxCode
|
||||
,TaxCodeName
|
||||
,TaxCodeDescription
|
||||
,TaxRatePercent
|
||||
,IsMarginScheme
|
||||
,IsValidOnExpense
|
||||
,IsVailidOnIncome
|
||||
,IsActive
|
||||
,TaxType
|
||||
FROM tblAccountTaxCode
|
||||
WHERE 1=1 ";
|
||||
|
||||
// add where clauses
|
||||
if (IsActive.HasValue)
|
||||
{
|
||||
whereBuilder.IsEqualTo("IsActive", IsActive.Value, "AND");
|
||||
}
|
||||
if (taxcodeList != null && taxcodeList.Count > 0)
|
||||
{
|
||||
whereBuilder.In("TaxCode", taxcodeList, "AND");
|
||||
}
|
||||
if (taxcodeIdList != null && taxcodeIdList.Count > 0)
|
||||
{
|
||||
whereBuilder.In("AccountTaxCodeID", taxcodeIdList, "AND");
|
||||
}
|
||||
|
||||
if (whereBuilder.IsSetSqlWhereString)
|
||||
{
|
||||
sqlString = sqlString + whereBuilder.SqlWhereString;
|
||||
}
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = sqlString;
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
|
||||
if (whereBuilder.ParameterListIsSet)
|
||||
{
|
||||
whereBuilder.AddParametersToSqlCommand(cmd);
|
||||
}
|
||||
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
int taxCodeId = reader.GetByte(0);
|
||||
string taxCode = reader.GetString(1);
|
||||
string name = reader.GetString(2);
|
||||
string description = null;
|
||||
if (!reader.IsDBNull(3)) { description = reader.GetString(3); }
|
||||
decimal rate = reader.GetDecimal(4);
|
||||
bool isMargin = reader.GetBoolean(5);
|
||||
bool isValidOnExpense = reader.GetBoolean(6);
|
||||
bool isValidOnIncome = reader.GetBoolean(7);
|
||||
bool isActive = reader.GetBoolean(8);
|
||||
string taxType = reader.GetString(9);
|
||||
|
||||
var result = new Model.Account.TaxCodeInfo(
|
||||
taxCode,
|
||||
name,
|
||||
description,
|
||||
rate,
|
||||
isMargin,
|
||||
isValidOnExpense,
|
||||
isValidOnIncome,
|
||||
taxType,
|
||||
isActive);
|
||||
|
||||
resultList.Add(taxCodeId, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
return resultList;
|
||||
}
|
||||
|
||||
public Dictionary<string, string> GetTaxCodeBySkuNumber(List<string> skuNumberList)
|
||||
{
|
||||
var resultList = new Dictionary<string, string>();
|
||||
|
||||
if (skuNumberList == null || !skuNumberList.Any())
|
||||
{
|
||||
return resultList;
|
||||
}
|
||||
|
||||
skuNumberList = skuNumberList.Distinct().ToList();
|
||||
|
||||
string sql = @"
|
||||
SELECT tblSku.skuSkuNumber
|
||||
,tblAccountTaxCode.TaxCode
|
||||
FROM tblSku
|
||||
INNER JOIN tblAccountTaxCode ON tblSku.AccountTaxCodeID = tblAccountTaxCode.AccountTaxCodeID ";
|
||||
|
||||
var whereBuilder = new Data.Database.SqlWhereBuilder();
|
||||
whereBuilder.In("tblSku.skuSkuNumber", skuNumberList, "WHERE");
|
||||
|
||||
sql += whereBuilder.SqlWhereString;
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = sql;
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
|
||||
if (whereBuilder.ParameterListIsSet)
|
||||
{
|
||||
whereBuilder.AddParametersToSqlCommand(cmd);
|
||||
}
|
||||
|
||||
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> ReadTaxCodeByInvoiceLineItemCode(List<string> lineItemCode)
|
||||
{
|
||||
var resultList = new Dictionary<string, string>();
|
||||
|
||||
if (lineItemCode == null || !lineItemCode.Any())
|
||||
{
|
||||
return resultList;
|
||||
}
|
||||
|
||||
lineItemCode = lineItemCode.Distinct().ToList();
|
||||
|
||||
string sql = @"
|
||||
SELECT tblAccountInvoiceLineItem.ItemCode
|
||||
,tblAccountTaxCode.TaxCode
|
||||
FROM tblAccountInvoiceLineItem
|
||||
LEFT OUTER JOIN tblAccountTaxCode ON tblAccountInvoiceLineItem.AccountTaxCodeID_Default = tblAccountTaxCode.AccountTaxCodeID
|
||||
";
|
||||
|
||||
var whereBuilder = new Data.Database.SqlWhereBuilder();
|
||||
whereBuilder.In("tblAccountInvoiceLineItem.ItemCode", lineItemCode, "WHERE");
|
||||
|
||||
sql += whereBuilder.SqlWhereString;
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = sql;
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
|
||||
if (whereBuilder.ParameterListIsSet)
|
||||
{
|
||||
whereBuilder.AddParametersToSqlCommand(cmd);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
+740
@@ -0,0 +1,740 @@
|
||||
using bnhtrade.Core.Data.Database._BoilerPlate;
|
||||
using bnhtrade.Core.Data.Database.Repository.Interface;
|
||||
using bnhtrade.Core.Model.Amazon;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Transactions;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Repository.Implementation
|
||||
{
|
||||
internal class AmazonSettlementRepository : _Base, IAmazonSettlementRepository
|
||||
{
|
||||
Logic.Log.LogEvent _log = new Logic.Log.LogEvent();
|
||||
|
||||
public AmazonSettlementRepository(IDbConnection connection, IDbTransaction transaction) : base(connection, transaction)
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// Read Amazon Settlement Header Information
|
||||
//
|
||||
|
||||
public List<Model.Import.AmazonSettlementHeader> ReadAmazonSettlementHeaderInfoBySettlementId(List<string> settlementIdList)
|
||||
{
|
||||
if (settlementIdList == null || !settlementIdList.Any())
|
||||
{ return new List<Model.Import.AmazonSettlementHeader>(); }
|
||||
|
||||
return ReadAmazonSettlementHeaders(settlementIdList);
|
||||
}
|
||||
|
||||
public List<Model.Import.AmazonSettlementHeader> ReadAmazonSettlementHeaderInfoBySpapiReportId(List<string> spapiReportIdList)
|
||||
{
|
||||
if (spapiReportIdList == null || !spapiReportIdList.Any())
|
||||
{ return new List<Model.Import.AmazonSettlementHeader>(); }
|
||||
|
||||
return ReadAmazonSettlementHeaders(null, spapiReportIdList);
|
||||
}
|
||||
|
||||
private List<Model.Import.AmazonSettlementHeader> ReadAmazonSettlementHeaders(
|
||||
List<string> settlementIdList = null, List<string> spapiReportIdList = null, bool filterOutIsProcessed = false,
|
||||
bool DescendingOrder = false, int? returnTop = null)
|
||||
{
|
||||
var returnHeaderList = new List<Model.Import.AmazonSettlementHeader>();
|
||||
Dictionary<string, int> dicTablePkBySettlementId = new Dictionary<string, int>();
|
||||
|
||||
|
||||
// build the sql string
|
||||
string sqlString = "SELECT ";
|
||||
|
||||
if (returnTop != null)
|
||||
{
|
||||
sqlString = sqlString + "TOP " + returnTop.Value + " ";
|
||||
}
|
||||
|
||||
sqlString = sqlString + @"
|
||||
ImportAmazonSettlementReportID
|
||||
,[marketplace-name]
|
||||
,[settlement-id]
|
||||
,[settlement-start-date]
|
||||
,[settlement-end-date]
|
||||
,[deposit-date]
|
||||
,[total-amount]
|
||||
,currency
|
||||
,IsProcessed
|
||||
,SpapiReportId
|
||||
FROM tblImportAmazonSettlementReport
|
||||
WHERE 1 = 1";
|
||||
|
||||
if (filterOutIsProcessed)
|
||||
{
|
||||
sqlString = sqlString + @"
|
||||
AND IsProcessed = 0";
|
||||
}
|
||||
|
||||
// build dictionary of parameter and values for settlementid
|
||||
var dicSettlementIdByParameterString = new Dictionary<string, string>();
|
||||
if (settlementIdList != null)
|
||||
{
|
||||
int count = 0;
|
||||
foreach (string item in settlementIdList)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(item))
|
||||
{
|
||||
count = count + 1;
|
||||
string parameterString = "@settlementId" + count;
|
||||
dicSettlementIdByParameterString.Add(parameterString, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dicSettlementIdByParameterString.Any())
|
||||
{
|
||||
int count = 0;
|
||||
foreach (var item in dicSettlementIdByParameterString)
|
||||
{
|
||||
count = count + 1;
|
||||
if (count == 1)
|
||||
{
|
||||
sqlString = sqlString + @"
|
||||
AND ( [settlement-id] = " + item.Key;
|
||||
}
|
||||
else
|
||||
{
|
||||
sqlString = sqlString + @"
|
||||
OR [settlement-id] = " + item.Key;
|
||||
}
|
||||
}
|
||||
sqlString = sqlString + " )";
|
||||
}
|
||||
|
||||
// build dictionary of parameter and values for SP-API Report Id
|
||||
var dicSpapiReportIdByParameterString = new Dictionary<string, string>();
|
||||
if (spapiReportIdList != null && spapiReportIdList.Any())
|
||||
{
|
||||
int count = 0;
|
||||
foreach (string item in spapiReportIdList)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(item))
|
||||
{
|
||||
count = count + 1;
|
||||
string parameterString = "@SpapiReportId" + count;
|
||||
dicSpapiReportIdByParameterString.Add(parameterString, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dicSpapiReportIdByParameterString.Any())
|
||||
{
|
||||
int count = 0;
|
||||
foreach (var item in dicSpapiReportIdByParameterString)
|
||||
{
|
||||
count = count + 1;
|
||||
if (count == 1)
|
||||
{
|
||||
sqlString = sqlString + @"
|
||||
AND ( SpapiReportId = " + item.Key;
|
||||
}
|
||||
else
|
||||
{
|
||||
sqlString = sqlString + @"
|
||||
OR SpapiReportId = " + item.Key;
|
||||
}
|
||||
}
|
||||
sqlString = sqlString + " )";
|
||||
}
|
||||
|
||||
|
||||
sqlString = sqlString + @"
|
||||
ORDER BY [settlement-start-date] ";
|
||||
if (DescendingOrder) { sqlString = sqlString + " DESC"; }
|
||||
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = sqlString;
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
|
||||
if (dicSettlementIdByParameterString.Any())
|
||||
{
|
||||
foreach (var item in dicSettlementIdByParameterString)
|
||||
{
|
||||
cmd.Parameters.AddWithValue(item.Key, item.Value);
|
||||
}
|
||||
}
|
||||
|
||||
if (dicSpapiReportIdByParameterString.Any())
|
||||
{
|
||||
foreach (var item in dicSpapiReportIdByParameterString)
|
||||
{
|
||||
cmd.Parameters.AddWithValue(item.Key, item.Value);
|
||||
}
|
||||
}
|
||||
|
||||
using (var reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
var header = new Model.Import.AmazonSettlementHeader();
|
||||
|
||||
int tablePk = reader.GetInt32(0);
|
||||
if (!reader.IsDBNull(1)) { header.MarketPlace = MarketPlaceEnumExtensions.FromMarketplaceUrl(reader.GetString(1)); }
|
||||
header.SettlementId = reader.GetString(2);
|
||||
header.StartDate = DateTime.SpecifyKind(reader.GetDateTime(3), DateTimeKind.Utc);
|
||||
header.EndDate = DateTime.SpecifyKind(reader.GetDateTime(4), DateTimeKind.Utc);
|
||||
header.DepositDate = DateTime.SpecifyKind(reader.GetDateTime(5), DateTimeKind.Utc);
|
||||
header.TotalAmount = reader.GetDecimal(6);
|
||||
header.CurrencyCode = reader.GetString(7);
|
||||
header.IsProcessed = reader.GetBoolean(8);
|
||||
if (!reader.IsDBNull(9)) { header.SpapiReportId = reader.GetString(9); }
|
||||
|
||||
// update dictionary
|
||||
if (!dicTablePkBySettlementId.ContainsKey(header.SettlementId))
|
||||
{
|
||||
dicTablePkBySettlementId.Add(header.SettlementId, tablePk);
|
||||
}
|
||||
|
||||
// add header to list
|
||||
returnHeaderList.Add(header);
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnHeaderList;
|
||||
}
|
||||
|
||||
//
|
||||
// Read Amazon Settlement Report
|
||||
//
|
||||
|
||||
/// <summary>
|
||||
/// Gets Amazon settlement report information from the database.
|
||||
/// </summary>
|
||||
/// <returns>Dictionary where key=id and value=settlement</returns>
|
||||
public Dictionary<int, Model.Import.AmazonSettlement> ReadAmazonSettlements(
|
||||
List<string> settlementIdList = null, List<string> marketPlaceNameList = null, bool? isProcessed = null,
|
||||
bool descendingOrder = false, int? returnTop = null )
|
||||
{
|
||||
var returnList = new Dictionary<int, Model.Import.AmazonSettlement>();
|
||||
var whereBuilder = new Data.Database.SqlWhereBuilder();
|
||||
|
||||
// build the sql string
|
||||
string sqlString = "SELECT ";
|
||||
|
||||
if (returnTop != null)
|
||||
{
|
||||
sqlString = sqlString + "TOP " + returnTop.Value + " ";
|
||||
}
|
||||
|
||||
sqlString = sqlString + @"
|
||||
tblImportAmazonSettlementReport.ImportAmazonSettlementReportID,
|
||||
tblImportAmazonSettlementReport.[marketplace-name],
|
||||
tblImportAmazonSettlementReport.[settlement-id],
|
||||
tblImportAmazonSettlementReport.[settlement-start-date],
|
||||
tblImportAmazonSettlementReport.[settlement-end-date],
|
||||
tblImportAmazonSettlementReport.[deposit-date],
|
||||
tblImportAmazonSettlementReport.[total-amount],
|
||||
tblImportAmazonSettlementReport.currency,
|
||||
tblImportAmazonSettlementReport.IsProcessed,
|
||||
tblImportAmazonSettlementReport.SpapiReportId,
|
||||
tblImportAmazonSettlementReportLine.ImportAmazonSettlementReportLineID,
|
||||
tblImportAmazonSettlementReportLine.[transaction-type],
|
||||
tblImportAmazonSettlementReportLine.[order-id],
|
||||
tblImportAmazonSettlementReportLine.[merchant-order-id],
|
||||
tblImportAmazonSettlementReportLine.[adjustment-id],
|
||||
tblImportAmazonSettlementReportLine.[shipment-id],
|
||||
tblImportAmazonSettlementReportLine.[marketplace-name] AS Expr1,
|
||||
tblImportAmazonSettlementReportLine.[amount-type],
|
||||
tblImportAmazonSettlementReportLine.[amount-description],
|
||||
tblImportAmazonSettlementReportLine.amount,
|
||||
tblImportAmazonSettlementReportLine.currency,
|
||||
tblImportAmazonSettlementReportLine.[fulfillment-id],
|
||||
tblImportAmazonSettlementReportLine.[posted-date-time],
|
||||
tblImportAmazonSettlementReportLine.[order-item-code],
|
||||
tblImportAmazonSettlementReportLine.[merchant-order-item-id],
|
||||
tblImportAmazonSettlementReportLine.[merchant-adjustment-item-id],
|
||||
tblImportAmazonSettlementReportLine.sku,
|
||||
tblImportAmazonSettlementReportLine.[quantity-purchased],
|
||||
tblImportAmazonSettlementReportLine.[promotion-id],
|
||||
tblImportAmazonSettlementReportLine.IsProcessed,
|
||||
tblImportAmazonSettlementReportLine.ExportAccountInvoiceLineID
|
||||
FROM tblImportAmazonSettlementReport
|
||||
INNER JOIN
|
||||
tblImportAmazonSettlementReportLine
|
||||
ON tblImportAmazonSettlementReport.ImportAmazonSettlementReportID = tblImportAmazonSettlementReportLine.ImportAmazonSettlementReportID
|
||||
WHERE 1 = 1 ";
|
||||
|
||||
if (isProcessed != null)
|
||||
{
|
||||
if (isProcessed.Value == true)
|
||||
{
|
||||
sqlString = sqlString + @"
|
||||
AND tblImportAmazonSettlementReport.IsProcessed = 1";
|
||||
}
|
||||
else
|
||||
{
|
||||
sqlString = sqlString + @"
|
||||
AND tblImportAmazonSettlementReport.IsProcessed = 0";
|
||||
}
|
||||
}
|
||||
|
||||
if (settlementIdList != null && settlementIdList.Any() == true)
|
||||
{
|
||||
whereBuilder.In("tblImportAmazonSettlementReport.ImportAmazonSettlementReportID", settlementIdList, "AND");
|
||||
}
|
||||
|
||||
if (marketPlaceNameList != null && marketPlaceNameList.Any() == true)
|
||||
{
|
||||
whereBuilder.In("tblImportAmazonSettlementReport.[marketplace-name]", marketPlaceNameList, "AND");
|
||||
}
|
||||
|
||||
sqlString = sqlString + whereBuilder.SqlWhereString;
|
||||
|
||||
// add the order by clause(s)
|
||||
sqlString = sqlString + @"
|
||||
ORDER BY tblImportAmazonSettlementReport.[marketplace-name] ASC, tblImportAmazonSettlementReport.[settlement-start-date] ";
|
||||
if (descendingOrder) { sqlString = sqlString + " DESC"; }
|
||||
else { sqlString = sqlString + " ASC"; }
|
||||
sqlString = sqlString + ", tblImportAmazonSettlementReport.ImportAmazonSettlementReportID ASC, tblImportAmazonSettlementReportLine.[posted-date-time] ASC, "
|
||||
+ "tblImportAmazonSettlementReportLine.ImportAmazonSettlementReportLineID ASC;";
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = sqlString;
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
|
||||
whereBuilder.AddParametersToSqlCommand(cmd);
|
||||
|
||||
using (var reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
int tableId = reader.GetInt32(0);
|
||||
|
||||
if (returnList.ContainsKey(tableId) == false)
|
||||
{
|
||||
var settlement = new Model.Import.AmazonSettlement();
|
||||
|
||||
if (!reader.IsDBNull(1)) { settlement.MarketPlace = MarketPlaceEnumExtensions.FromMarketplaceUrl(reader.GetString(1)); }
|
||||
settlement.SettlementId = reader.GetString(2);
|
||||
settlement.StartDate = DateTime.SpecifyKind(reader.GetDateTime(3), DateTimeKind.Utc);
|
||||
settlement.EndDate = DateTime.SpecifyKind(reader.GetDateTime(4), DateTimeKind.Utc);
|
||||
settlement.DepositDate = DateTime.SpecifyKind(reader.GetDateTime(5), DateTimeKind.Utc);
|
||||
settlement.TotalAmount = reader.GetDecimal(6);
|
||||
settlement.CurrencyCode = reader.GetString(7);
|
||||
settlement.IsProcessed = reader.GetBoolean(8);
|
||||
if (!reader.IsDBNull(9)) { settlement.SpapiReportId = reader.GetString(9); }
|
||||
|
||||
returnList.Add(tableId, settlement);
|
||||
}
|
||||
|
||||
// add lines to settlement
|
||||
var line = new Model.Import.AmazonSettlement.SettlementLine();
|
||||
|
||||
line.TransactionType = reader.GetString(11);
|
||||
if (!reader.IsDBNull(12)) { line.OrderId = reader.GetString(12); }
|
||||
if (!reader.IsDBNull(13)) { line.MerchantOrderId = reader.GetString(13); }
|
||||
if (!reader.IsDBNull(14)) { line.AdjustmentId = reader.GetString(14); }
|
||||
if (!reader.IsDBNull(15)) { line.ShipmentId = reader.GetString(15); }
|
||||
if (!reader.IsDBNull(16)) { line.MarketPlaceName = reader.GetString(16); }
|
||||
line.AmountType = reader.GetString(17);
|
||||
line.AmountDescription = reader.GetString(18);
|
||||
line.Amount = reader.GetDecimal(19);
|
||||
line.CurrenyCode = reader.GetString(20);
|
||||
if (!reader.IsDBNull(21)) { line.FulfillmentId = reader.GetString(21); }
|
||||
line.PostDateTime = DateTime.SpecifyKind(reader.GetDateTime(22), DateTimeKind.Utc);
|
||||
if (!reader.IsDBNull(23)) { line.OrderItemCode = reader.GetString(23); }
|
||||
if (!reader.IsDBNull(24)) { line.MerchantOrderItemId = reader.GetString(24); }
|
||||
if (!reader.IsDBNull(25)) { line.MerchantAdjustmentItemId = reader.GetString(25); }
|
||||
if (!reader.IsDBNull(26)) { line.Sku = reader.GetString(26); }
|
||||
if (!reader.IsDBNull(27)) { line.QuantityPurchased = reader.GetInt32(27); }
|
||||
if (!reader.IsDBNull(28)) { line.PromotionId = reader.GetString(28); }
|
||||
line.IsProcessed = reader.GetBoolean(29);
|
||||
if (!reader.IsDBNull(30)) { line.ExportAccountInvoiceLineId = reader.GetInt32(30); }
|
||||
|
||||
returnList[tableId].SettlementLineList.Add(line);
|
||||
}
|
||||
return returnList;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Update Amazon Settlement Report
|
||||
//
|
||||
|
||||
/// <summary>
|
||||
/// Update the settlement report marketplace name by settlement Id (not row id)
|
||||
/// </summary>
|
||||
/// <param name="settlementId">Settlement id (not table/record id) of the settlement to update</param>
|
||||
/// <param name="marketPlaceName">marketplace name</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="Exception"></exception>
|
||||
public bool UpdateAmazonSettlementMarketPlaceName (string settlementId, Model.Amazon.MarketPlaceEnum marketPlace)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(settlementId) || marketPlace == null)
|
||||
{
|
||||
throw new Exception("Settlement id or market place is invalid.");
|
||||
}
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = @"
|
||||
UPDATE tblImportAmazonSettlementReport
|
||||
SET [marketplace-name] = @marketPlaceName
|
||||
WHERE [settlement-id] = @settlementId;";
|
||||
cmd.Parameters.AddWithValue("@marketPlaceName", marketPlace.GetMarketplaceUrl());
|
||||
cmd.Parameters.AddWithValue("@settlementId", settlementId);
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
return cmd.ExecuteNonQuery() > 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the IsProcessed flag to true or false for the specified settlement Ids.
|
||||
/// </summary>
|
||||
/// <param name="settlementIdList">List of settlement id (not table id)</param>
|
||||
/// <param name="isProcessed">value to set the isProcessed to</param>
|
||||
/// <returns>Number of rows effected</returns>
|
||||
public int UpdateAmazonSettlementIsProcessed(List<string> settlementIdList, bool isProcessed)
|
||||
{
|
||||
if (settlementIdList == null || !settlementIdList.Any())
|
||||
{
|
||||
throw new Exception("Settlement ID list is empty.");
|
||||
}
|
||||
|
||||
string sqlString = @"
|
||||
UPDATE tblImportAmazonSettlementReport ";
|
||||
|
||||
sqlString = sqlString + @"
|
||||
SET IsProcessed = " + (isProcessed ? "1" : "0");
|
||||
|
||||
var whereBuilder = new Data.Database.SqlWhereBuilder();
|
||||
whereBuilder.In("tblImportAmazonSettlementReport.[settlement-id]", settlementIdList, "WHERE");
|
||||
|
||||
sqlString = sqlString + whereBuilder.SqlWhereString;
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = sqlString;
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
|
||||
whereBuilder.AddParametersToSqlCommand(cmd);
|
||||
|
||||
return cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Takes a Settlement Report flat file from Amazon and imports it into the database.
|
||||
/// </summary>
|
||||
/// <param name="filePath">path to the Amazon report flat file</param>
|
||||
/// <param name="spapiReportId">The unique Amazon SP-API report id (not settlement id)</param>
|
||||
/// <returns></returns>
|
||||
public bool CreateAmazonSettlements(string filePath, string spapiReportId)
|
||||
{
|
||||
int settlementReportId = 0;
|
||||
string settlementRef = null;
|
||||
string marketplaceName = null;
|
||||
decimal settlementAmount = 0m;
|
||||
int lineNumber = 2;
|
||||
int lineSkip = 0;
|
||||
|
||||
using (var reader = new StreamReader(filePath))
|
||||
{
|
||||
//read file one line at a time and insert data into table if required
|
||||
|
||||
// read header and retrive information
|
||||
string headerRow = reader.ReadLine();
|
||||
string[] headers = headerRow.Split('\t');
|
||||
|
||||
int columnCount = headers.Length;
|
||||
|
||||
int indexSettlementId = Array.IndexOf(headers, "settlement-id");
|
||||
int indexSettlementStartDate = Array.IndexOf(headers, "settlement-start-date");
|
||||
int indexSettlementEndDate = Array.IndexOf(headers, "settlement-end-date");
|
||||
int indexDepositDate = Array.IndexOf(headers, "deposit-date");
|
||||
int indexTotalAmount = Array.IndexOf(headers, "total-amount");
|
||||
int indexCurrency = Array.IndexOf(headers, "currency");
|
||||
int indexTransactionType = Array.IndexOf(headers, "transaction-type");
|
||||
int indexOrderId = Array.IndexOf(headers, "order-id");
|
||||
int indexMerchantOrderId = Array.IndexOf(headers, "merchant-order-id");
|
||||
int indexAdjustmentId = Array.IndexOf(headers, "adjustment-id");
|
||||
int indexShipmentId = Array.IndexOf(headers, "shipment-id");
|
||||
int indexMarketplaceName = Array.IndexOf(headers, "marketplace-name");
|
||||
int indexAmountType = Array.IndexOf(headers, "amount-type");
|
||||
int indexAmountDescription = Array.IndexOf(headers, "amount-description");
|
||||
int indexAmount = Array.IndexOf(headers, "amount");
|
||||
int indexFulfillmentId = Array.IndexOf(headers, "fulfillment-id");
|
||||
// int indexPostedDate = Array.IndexOf(headers, "posted-date");
|
||||
int indexPostedDateTime = Array.IndexOf(headers, "posted-date-time");
|
||||
int indexOrderItemCode = Array.IndexOf(headers, "order-item-code");
|
||||
int indexMerchantOrderItemId = Array.IndexOf(headers, "merchant-order-item-id");
|
||||
int indexMerchantAdjustmentItemId = Array.IndexOf(headers, "merchant-adjustment-item-id");
|
||||
int indexSku = Array.IndexOf(headers, "sku");
|
||||
int indexQuantityPurchased = Array.IndexOf(headers, "quantity-purchased");
|
||||
int indexPromotionId = Array.IndexOf(headers, "promotion-id");
|
||||
|
||||
string currency = null;
|
||||
|
||||
string fileRow;
|
||||
while ((fileRow = reader.ReadLine()) != null)
|
||||
{
|
||||
Console.Write("\rParsing record: " + lineNumber);
|
||||
//split line into array
|
||||
string[] rowArray = fileRow.Split('\t');
|
||||
if (rowArray.Length != columnCount)
|
||||
{
|
||||
// skip line, check settlement total at the end
|
||||
lineSkip = lineSkip + 1;
|
||||
_log.LogWarning(
|
||||
"Line #" + lineNumber + " skipped due to no enough element in row.",
|
||||
filePath
|
||||
);
|
||||
}
|
||||
else if (lineNumber == 2)
|
||||
{
|
||||
settlementRef = rowArray[indexSettlementId];
|
||||
currency = rowArray[indexCurrency];
|
||||
settlementAmount = decimal.Parse(rowArray[indexTotalAmount].Replace(",", "."));
|
||||
|
||||
// check if settlement has already been imported
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = "SELECT COUNT(*) FROM tblImportAmazonSettlementReport WHERE [settlement-id]=@settlementId;";
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.Parameters.AddWithValue("@settlementId", rowArray[indexSettlementId]);
|
||||
|
||||
int recordCount = (int)cmd.ExecuteScalar();
|
||||
if (recordCount > 0)
|
||||
{
|
||||
SetSpapiReportId(rowArray[indexSettlementId], spapiReportId);
|
||||
_log.LogInformation("Settlement report already imported, skipping...");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// insert
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText = @"
|
||||
INSERT INTO tblImportAmazonSettlementReport (
|
||||
[settlement-id]
|
||||
,[settlement-start-date]
|
||||
,[settlement-end-date]
|
||||
,[deposit-date]
|
||||
,[total-amount]
|
||||
,[currency]
|
||||
,SpapiReportId
|
||||
)
|
||||
OUTPUT INSERTED.ImportAmazonSettlementReportID
|
||||
VALUES (
|
||||
@settlementId
|
||||
,@settlementStartDate
|
||||
,@settlementEndDate
|
||||
,@depositDate
|
||||
,@settlementotalAmounttId
|
||||
,@currency
|
||||
,@spapiReportId
|
||||
);";
|
||||
|
||||
var parseDateTime = new Core.Logic.Utilities.DateTime();
|
||||
|
||||
// add parameters
|
||||
cmd.Parameters.AddWithValue("@settlementId", rowArray[indexSettlementId]);
|
||||
cmd.Parameters.AddWithValue("@settlementStartDate", parseDateTime.ParseIsoDateTimeString(rowArray[indexSettlementStartDate]));
|
||||
cmd.Parameters.AddWithValue("@settlementEndDate", parseDateTime.ParseIsoDateTimeString(rowArray[indexSettlementEndDate]));
|
||||
cmd.Parameters.AddWithValue("@depositDate", parseDateTime.ParseIsoDateTimeString(rowArray[indexDepositDate]));
|
||||
cmd.Parameters.AddWithValue("@settlementotalAmounttId", settlementAmount);
|
||||
if (string.IsNullOrWhiteSpace(spapiReportId)) { cmd.Parameters.AddWithValue("@spapiReportId", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@spapiReportId", spapiReportId); }
|
||||
cmd.Parameters.AddWithValue("@currency", currency);
|
||||
|
||||
//execute and retrive id
|
||||
settlementReportId = (int)cmd.ExecuteScalar();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// attempt to retrieve marketplace name for header table
|
||||
if (rowArray[indexMarketplaceName].Length > 1 && settlementReportId > 0)
|
||||
{
|
||||
if (marketplaceName == null)
|
||||
{
|
||||
marketplaceName = rowArray[indexMarketplaceName];
|
||||
}
|
||||
else if (marketplaceName != rowArray[indexMarketplaceName])
|
||||
{
|
||||
_log.LogError("Marketplace name '" + rowArray[indexMarketplaceName] + "' on line " + lineNumber +
|
||||
" is different from marketplace name '" + marketplaceName + "' on previous line. This shouldn't be possible!");
|
||||
}
|
||||
}
|
||||
|
||||
//insert report items
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText =
|
||||
"INSERT INTO tblImportAmazonSettlementReportLine ( " +
|
||||
"ImportAmazonSettlementReportID, [transaction-type], [order-id], [merchant-order-id], [adjustment-id], [shipment-id], [marketplace-name], " +
|
||||
"[amount-type], [amount-description], [currency], [amount], [fulfillment-id], [posted-date-time], [order-item-code], " +
|
||||
"[merchant-order-item-id], [merchant-adjustment-item-id], [sku], [quantity-purchased], [promotion-id] ) " +
|
||||
"VALUES ( " +
|
||||
"@ImportAmazonSettlementReportID, @TransactionType, @orderRef, @merchantOrderRef, @AdjustmentRef, @ShipmentRef, @MarketplaceName, " +
|
||||
"@AmountType, @AmountDescription, @currency, @Amount, @FulfillmentRef, @PostedDateTimeUTC, @OrderItemCode, " +
|
||||
"@MerchantOrderItemRef, @MerchantAdjustmentItemRef, @SkuNumber, @QuantityPurchased, @PromotionRef );";
|
||||
|
||||
// add parameters
|
||||
cmd.Parameters.AddWithValue("@ImportAmazonSettlementReportID", settlementReportId);
|
||||
|
||||
cmd.Parameters.AddWithValue("@currency", currency);
|
||||
|
||||
if (indexTransactionType == -1 || rowArray[indexTransactionType].Length == 0) { cmd.Parameters.AddWithValue("@TransactionType", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@TransactionType", rowArray[indexTransactionType]); }
|
||||
|
||||
if (indexOrderId == -1 || rowArray[indexOrderId].Length == 0) { cmd.Parameters.AddWithValue("@orderRef", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@orderRef", rowArray[indexOrderId]); }
|
||||
|
||||
if (indexMerchantOrderId == -1 || rowArray[indexMerchantOrderId].Length == 0) { cmd.Parameters.AddWithValue("@merchantOrderRef", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@merchantOrderRef", rowArray[indexMerchantOrderId]); }
|
||||
|
||||
if (indexAdjustmentId == -1 || rowArray[indexAdjustmentId].Length == 0) { cmd.Parameters.AddWithValue("@AdjustmentRef", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@AdjustmentRef", rowArray[indexAdjustmentId]); }
|
||||
|
||||
if (indexShipmentId == -1 || rowArray[indexShipmentId].Length == 0) { cmd.Parameters.AddWithValue("@ShipmentRef", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@ShipmentRef", rowArray[indexShipmentId]); }
|
||||
|
||||
if (indexMarketplaceName == -1 || rowArray[indexMarketplaceName].Length == 0) { cmd.Parameters.AddWithValue("@MarketplaceName", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@MarketplaceName", rowArray[indexMarketplaceName]); }
|
||||
|
||||
if (indexAmountType == -1 || rowArray[indexAmountType].Length == 0) { cmd.Parameters.AddWithValue("@AmountType", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@AmountType", rowArray[indexAmountType]); }
|
||||
|
||||
if (indexAmountDescription == -1 || rowArray[indexAmountDescription].Length == 0) { cmd.Parameters.AddWithValue("@AmountDescription", DBNull.Value); }
|
||||
else
|
||||
{
|
||||
string amountDescription = rowArray[indexAmountDescription];
|
||||
if (amountDescription.Length > 100) { amountDescription = amountDescription.Substring(0, 100); }
|
||||
cmd.Parameters.AddWithValue("@AmountDescription", amountDescription);
|
||||
}
|
||||
|
||||
if (indexAmount == -1 || rowArray[indexAmount].Length == 0) { cmd.Parameters.AddWithValue("@Amount", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@Amount", decimal.Parse(rowArray[indexAmount].Replace(",", "."))); }
|
||||
|
||||
if (indexFulfillmentId == -1 || rowArray[indexFulfillmentId].Length == 0) { cmd.Parameters.AddWithValue("@FulfillmentRef", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@FulfillmentRef", rowArray[indexFulfillmentId]); }
|
||||
|
||||
if (indexPostedDateTime == -1 || rowArray[indexPostedDateTime].Length == 0) { cmd.Parameters.AddWithValue("@PostedDateTimeUTC", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@PostedDateTimeUTC", new Logic.Utilities.DateTime().ParseIsoDateTimeString(rowArray[indexPostedDateTime])); }
|
||||
|
||||
if (indexOrderItemCode == -1 || rowArray[indexOrderItemCode].Length == 0) { cmd.Parameters.AddWithValue("@OrderItemCode", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@OrderItemCode", long.Parse(rowArray[indexOrderItemCode])); }
|
||||
|
||||
if (indexMerchantOrderItemId == -1 || rowArray[indexMerchantOrderItemId].Length == 0) { cmd.Parameters.AddWithValue("@MerchantOrderItemRef", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@MerchantOrderItemRef", long.Parse(rowArray[indexMerchantOrderItemId])); }
|
||||
|
||||
if (indexMerchantAdjustmentItemId == -1 || rowArray[indexMerchantAdjustmentItemId].Length == 0) { cmd.Parameters.AddWithValue("@MerchantAdjustmentItemRef", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@MerchantAdjustmentItemRef", rowArray[indexMerchantAdjustmentItemId]); }
|
||||
|
||||
if (indexSku == -1 || rowArray[indexSku].Length == 0) { cmd.Parameters.AddWithValue("@SkuNumber", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@SkuNumber", rowArray[indexSku]); }
|
||||
|
||||
if (indexQuantityPurchased == -1 || rowArray[indexQuantityPurchased].Length == 0) { cmd.Parameters.AddWithValue("@QuantityPurchased", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@QuantityPurchased", int.Parse(rowArray[indexQuantityPurchased])); }
|
||||
|
||||
if (indexPromotionId == -1 || rowArray[indexPromotionId].Length == 0) { cmd.Parameters.AddWithValue("@PromotionRef", DBNull.Value); }
|
||||
else { cmd.Parameters.AddWithValue("@PromotionRef", rowArray[indexPromotionId]); }
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
lineNumber = lineNumber + 1;
|
||||
}
|
||||
// end of filestream reading
|
||||
|
||||
// if we haven't gotten the marketplace name from the line items, attempt to infer from currency
|
||||
if (marketplaceName == null && settlementReportId > 0)
|
||||
{
|
||||
if (currency == "GBP")
|
||||
{
|
||||
marketplaceName = MarketPlaceEnum.AmazonUK.GetMarketplaceUrl();
|
||||
marketplaceName = char.ToUpper(marketplaceName[0]) + marketplaceName.Substring(1);
|
||||
}
|
||||
}
|
||||
|
||||
// finally, if we have it, add marketplace name to main table
|
||||
if (marketplaceName != null && settlementReportId > 0)
|
||||
{
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText = @"
|
||||
UPDATE tblImportAmazonSettlementReport
|
||||
SET [marketplace-name]=@MarketplaceName
|
||||
WHERE ImportAmazonSettlementReportID=@ImportAmazonSettlementReportID;";
|
||||
cmd.Parameters.AddWithValue("@MarketplaceName", marketplaceName);
|
||||
cmd.Parameters.AddWithValue("@ImportAmazonSettlementReportID", settlementReportId);
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//final check - settlement amount matches sum of inserted settlement lines
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText = @"
|
||||
SELECT Sum(tblImportAmazonSettlementReportLine.amount) AS SumOfAmount
|
||||
FROM tblImportAmazonSettlementReportLine
|
||||
WHERE ImportAmazonSettlementReportID=@ImportAmazonSettlementReportID;";
|
||||
|
||||
decimal sumOfAmount = -1.12345m;
|
||||
|
||||
cmd.Parameters.AddWithValue("@ImportAmazonSettlementReportID", settlementReportId);
|
||||
sumOfAmount = (decimal)cmd.ExecuteScalar();
|
||||
|
||||
if (sumOfAmount != settlementAmount)
|
||||
{
|
||||
_log.LogError("Error importing settlement id'" + settlementRef + "'. Sum of inserted settlement lines (" + sumOfAmount +
|
||||
") does not match settlement amount (" + settlementAmount + ").");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Console.Write("\r");
|
||||
_log.LogInformation((lineNumber - (2 + lineSkip)) + " total settlement items inserted");
|
||||
if (lineSkip > 0)
|
||||
{
|
||||
_log.LogError(lineSkip + " total line(s) where skipped due to insufficent number of cells on row");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public int SetSpapiReportId(string settlementId, string spapiReportId)
|
||||
{
|
||||
string sqlString = @"
|
||||
UPDATE
|
||||
tblImportAmazonSettlementReport
|
||||
SET
|
||||
SpapiReportId = @spapiReportId
|
||||
WHERE
|
||||
[settlement-id] = @settlementId;";
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = sqlString;
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
|
||||
cmd.Parameters.AddWithValue("@spapiReportId", spapiReportId);
|
||||
cmd.Parameters.AddWithValue("@settlementId", settlementId);
|
||||
|
||||
return cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,267 @@
|
||||
using bnhtrade.Core.Data.Database.Repository.Interface;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Repository.Implementation
|
||||
{
|
||||
internal class CurrencyRepository : _Base, ICurrencyRepository
|
||||
{
|
||||
public CurrencyRepository(IDbConnection connection, IDbTransaction transaction) : base(connection, transaction)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns excahnge rate, in decimal format, for a given currency and datetime
|
||||
/// </summary>
|
||||
/// <param name="currencyCode">currency code</param>
|
||||
/// <param name="date">dat and time</param>
|
||||
/// <returns></returns>
|
||||
public decimal? ReadExchangeRate(Model.Account.CurrencyCode currencyCode, DateTime date)
|
||||
{
|
||||
string sql = @"
|
||||
SELECT CurrencyUnitsPerGBP
|
||||
FROM tblAccountExchangeRate
|
||||
WHERE CurrencyCode=@currencyCode AND StartDate<=@conversionDate AND EndDate>@conversionDate
|
||||
";
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = sql;
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
|
||||
cmd.Parameters.AddWithValue("@currencyCode", currencyCode.ToString());
|
||||
cmd.Parameters.AddWithValue("@conversionDate", date);
|
||||
|
||||
object result = cmd.ExecuteScalar();
|
||||
if (result != null)
|
||||
{
|
||||
return Convert.ToDecimal(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<Model.Account.CurrencyExchangeRate> ReadExchangeRate(List<Model.Account.CurrencyCode> currencyCodeList = null, DateTime date = default(DateTime))
|
||||
{
|
||||
//throw new NotImplementedException("Complete, but untested");
|
||||
|
||||
var returnList = new List<Model.Account.CurrencyExchangeRate>();
|
||||
|
||||
string sql = @"
|
||||
SELECT AccountExchangeRateID, ExchangeRateSource, CurrencyCode, CurrencyUnitsPerGBP, StartDate, EndDate
|
||||
FROM tblAccountExchangeRate
|
||||
WHERE 1=1 ";
|
||||
|
||||
if (date != default(DateTime))
|
||||
{
|
||||
sql = sql + " AND (@dateTime >= StartDate AND @dateTime < endDate) ";
|
||||
}
|
||||
|
||||
var sqlWhere = new Data.Database.SqlWhereBuilder();
|
||||
|
||||
// create string list
|
||||
List<string> stringList = new List<string>();
|
||||
if (currencyCodeList != null)
|
||||
{
|
||||
stringList = currencyCodeList.ConvertAll(f => f.ToString());
|
||||
if (stringList.Any())
|
||||
{
|
||||
sqlWhere.In("CurrencyCode", stringList, "AND");
|
||||
}
|
||||
}
|
||||
|
||||
sql = sql + sqlWhere.SqlWhereString;
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = sql;
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
|
||||
if (date != default(DateTime))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@dateTime", date);
|
||||
}
|
||||
if (stringList.Any())
|
||||
{
|
||||
sqlWhere.AddParametersToSqlCommand(cmd);
|
||||
}
|
||||
|
||||
using (var reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
int id = reader.GetInt32(0);
|
||||
int exchangeRateSource = reader.GetInt32(1);
|
||||
string currencyCodeString = reader.GetString(2);
|
||||
decimal currencyUnitsPerGBP = reader.GetDecimal(3);
|
||||
DateTime startDate = DateTime.SpecifyKind(reader.GetDateTime(4), DateTimeKind.Utc);
|
||||
DateTime endDate = DateTime.SpecifyKind(reader.GetDateTime(5), DateTimeKind.Utc);
|
||||
|
||||
|
||||
// convert string to enum
|
||||
if (Enum.TryParse(currencyCodeString, out Model.Account.CurrencyCode currencyCode) == false)
|
||||
{
|
||||
throw new Exception("Failed converting database string to enum");
|
||||
}
|
||||
|
||||
var item = new Model.Account.CurrencyExchangeRate(
|
||||
currencyCode
|
||||
, exchangeRateSource
|
||||
, currencyUnitsPerGBP
|
||||
, startDate
|
||||
, endDate
|
||||
);
|
||||
|
||||
returnList.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnList;
|
||||
}
|
||||
|
||||
public List<Model.Account.CurrencyExchangeRate> ReadExchangeRateLatest(List<Model.Account.CurrencyCode> currencyCodeList = null)
|
||||
{
|
||||
var returnList = new List<Model.Account.CurrencyExchangeRate>();
|
||||
|
||||
string sql = @"
|
||||
SELECT t1.AccountExchangeRateID, t1.ExchangeRateSource, t1.CurrencyCode, t1.CurrencyUnitsPerGBP, t1.StartDate, t1.EndDate,
|
||||
t2.maxdate
|
||||
FROM tblAccountExchangeRate AS t1
|
||||
INNER JOIN
|
||||
(SELECT max(StartDate) AS maxdate,
|
||||
CurrencyCode
|
||||
FROM tblAccountExchangeRate
|
||||
GROUP BY CurrencyCode
|
||||
";
|
||||
|
||||
// add any filters
|
||||
var sqlWhere = new Data.Database.SqlWhereBuilder();
|
||||
var codeStringList = new List<string>();
|
||||
if (currencyCodeList != null && currencyCodeList.Any() == true)
|
||||
{
|
||||
// convert to string list
|
||||
foreach (var currencyCode in currencyCodeList)
|
||||
{
|
||||
codeStringList.Add(currencyCode.ToString());
|
||||
}
|
||||
|
||||
// add to where statement
|
||||
sqlWhere.In("CurrencyCode", codeStringList, "HAVING");
|
||||
sql = sql + sqlWhere.SqlWhereString;
|
||||
}
|
||||
|
||||
sql = sql + @" ) AS t2
|
||||
ON t1.CurrencyCode = t2.CurrencyCode
|
||||
AND t1.StartDate = t2.maxdate
|
||||
ORDER BY t1.CurrencyCode;";
|
||||
|
||||
//query db
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = sql;
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
|
||||
if (codeStringList.Any())
|
||||
{
|
||||
sqlWhere.AddParametersToSqlCommand(cmd);
|
||||
}
|
||||
|
||||
using (var reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
int id = reader.GetInt32(0);
|
||||
int exchangeRateSource = reader.GetInt32(1);
|
||||
string currencyCodeString = reader.GetString(2);
|
||||
decimal currencyUnitsPerGBP = reader.GetDecimal(3);
|
||||
DateTime startDate = DateTime.SpecifyKind(reader.GetDateTime(4), DateTimeKind.Utc);
|
||||
DateTime endDate = DateTime.SpecifyKind(reader.GetDateTime(5), DateTimeKind.Utc);
|
||||
|
||||
|
||||
// convert string to enum
|
||||
if (Enum.TryParse(currencyCodeString, out Model.Account.CurrencyCode currencyCode) == false)
|
||||
{
|
||||
throw new Exception("Failed converting database string to enum");
|
||||
}
|
||||
|
||||
var item = new Model.Account.CurrencyExchangeRate(
|
||||
currencyCode
|
||||
, exchangeRateSource
|
||||
, currencyUnitsPerGBP
|
||||
, startDate
|
||||
, endDate
|
||||
);
|
||||
|
||||
returnList.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnList;
|
||||
}
|
||||
|
||||
public int InsertExchangeRate(int exchangeRateSource, Model.Account.CurrencyCode currencyCode,
|
||||
decimal currencyUnitsPerGbp, DateTime periodStartUtc, DateTime periodEnd, bool checkOverride = false)
|
||||
{
|
||||
// checks
|
||||
if (periodStartUtc.Kind != DateTimeKind.Utc || periodEnd.Kind != DateTimeKind.Utc)
|
||||
{
|
||||
throw new FormatException("Currency date time kind must be UTC");
|
||||
}
|
||||
|
||||
currencyUnitsPerGbp = decimal.Round(currencyUnitsPerGbp, 4);
|
||||
|
||||
// CHECKS
|
||||
if (periodEnd <= periodStartUtc)
|
||||
{
|
||||
throw new Exception("Invalid date period.");
|
||||
}
|
||||
|
||||
if (checkOverride == false && (periodEnd - periodStartUtc).Days > 31)
|
||||
{
|
||||
throw new Exception("Date period is greater than 31 days.");
|
||||
}
|
||||
|
||||
string sql = @"
|
||||
INSERT INTO tblAccountExchangeRate (ExchangeRateSource, CurrencyCode, CurrencyUnitsPerGBP, StartDate, EndDate)
|
||||
OUTPUT INSERTED.AccountExchangeRateID
|
||||
VALUES (@exchangeRateSource, @currencyCode, @currencyUnitsPerGbp, @periodStart, @periodEnd);
|
||||
";
|
||||
|
||||
// make the insert
|
||||
DateTime? periodEndLast = null;
|
||||
int recordId = 0;
|
||||
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = sql;
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
|
||||
cmd.Parameters.AddWithValue("@exchangeRateSource", exchangeRateSource);
|
||||
cmd.Parameters.AddWithValue("@currencyCode", currencyCode.ToString());
|
||||
cmd.Parameters.AddWithValue("@currencyUnitsPerGbp", currencyUnitsPerGbp);
|
||||
cmd.Parameters.AddWithValue("@periodStart", periodStartUtc);
|
||||
cmd.Parameters.AddWithValue("@periodEnd", periodEnd);
|
||||
|
||||
recordId = (int)cmd.ExecuteScalar();
|
||||
|
||||
if (recordId < 1)
|
||||
{
|
||||
throw new Exception("Error inserting record, did not retrive new record ID.");
|
||||
}
|
||||
}
|
||||
|
||||
return recordId;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,472 @@
|
||||
using bnhtrade.Core.Data.Database.Repository.Interface;
|
||||
using bnhtrade.Core.Logic.Account;
|
||||
using bnhtrade.Core.Logic.Validate;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Transactions;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Repository.Implementation
|
||||
{
|
||||
internal class ExportInvoiceRepository : _Base, IExportInvoiceRepository
|
||||
{
|
||||
public ExportInvoiceRepository(IDbConnection connection, IDbTransaction transaction) : base(connection, transaction)
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// invoice Insert methods
|
||||
//
|
||||
|
||||
/// <summary>
|
||||
/// Don't call this directly, use the logic layer instead (for validation and other checks).
|
||||
/// </summary>
|
||||
/// <param name="invoiceList">list of sales invoices to insert</param>
|
||||
/// <returns>dectionary, key= invoice id, value= new invoice </returns>
|
||||
public Dictionary<int, Model.Account.SalesInvoice> InsertSalesInvoices(IEnumerable<Model.Account.SalesInvoice> invoiceList)
|
||||
{
|
||||
var result = InsertBaseExecute(invoiceList);
|
||||
var returnList = new Dictionary<int, Model.Account.SalesInvoice>();
|
||||
foreach (var item in result)
|
||||
{
|
||||
returnList.Add(item.Key, (Model.Account.SalesInvoice)item.Value);
|
||||
}
|
||||
return returnList;
|
||||
}
|
||||
|
||||
private Dictionary<int, Model.Account.Invoice> InsertBaseExecute(IEnumerable<Model.Account.Invoice> invoiceList)
|
||||
{
|
||||
if (invoiceList == null)
|
||||
{
|
||||
throw new ArgumentException("Invoice list is null");
|
||||
}
|
||||
|
||||
var returnList = new Dictionary<int, Model.Account.Invoice>();
|
||||
int invoiceCount = invoiceList.Count();
|
||||
|
||||
// make the inserts
|
||||
foreach (var invoice in invoiceList)
|
||||
{
|
||||
int? invoiceId = null;
|
||||
string sql = @"
|
||||
INSERT INTO tblExportAccountInvoice (
|
||||
ExportAccountInvoiceTypeID
|
||||
,Contact
|
||||
,InvoiceDate
|
||||
,InvoiceDueDate
|
||||
,InvoiceNumber
|
||||
,Reference
|
||||
,CurrencyCode
|
||||
,LineUnitAmountIsTaxExclusive
|
||||
,InvoiceAmount
|
||||
,IsComplete
|
||||
)
|
||||
OUTPUT INSERTED.ExportAccountInvoiceID
|
||||
VALUES (
|
||||
@invoiceTypeId
|
||||
,@contact
|
||||
,@invoiceDate
|
||||
,@invoiceDueDate
|
||||
,@invoiceNumber
|
||||
,@reference
|
||||
,@currencyCode
|
||||
,@lineUnitAmountIsTaxExclusive
|
||||
,@invoiceAmount
|
||||
,@markComplete
|
||||
);";
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = sql;
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
|
||||
cmd.Parameters.AddWithValue("@invoiceTypeId", (int)invoice.InvoiceType);
|
||||
cmd.Parameters.AddWithValue("@contact", invoice.ContactName);
|
||||
cmd.Parameters.AddWithValue("@invoiceDate", invoice.InvoiceDate);
|
||||
cmd.Parameters.AddWithValue("@invoiceDueDate", invoice.InvoiceDueDate);
|
||||
cmd.Parameters.AddWithValue("@reference", invoice.InvoiceReference);
|
||||
cmd.Parameters.AddWithValue("@currencyCode", invoice.InvoiceCurrencyCode.ToString());
|
||||
cmd.Parameters.AddWithValue("@lineUnitAmountIsTaxExclusive", invoice.InvoiceLineUnitAmountIsTaxExclusive);
|
||||
cmd.Parameters.AddWithValue("@markComplete", false);
|
||||
cmd.Parameters.AddWithValue("@invoiceNumber", invoice.InvoiceNumber);
|
||||
cmd.Parameters.AddWithValue("@invoiceAmount", invoice.InvoiceTotalAmount);
|
||||
|
||||
invoiceId = (int)cmd.ExecuteScalar();
|
||||
}
|
||||
|
||||
foreach (var line in invoice.InvoiceLineList)
|
||||
{
|
||||
string lineSql = @"
|
||||
INSERT INTO tblExportAccountInvoiceLine (
|
||||
ExportAccountInvoiceID
|
||||
,AccountInvoiceLineItemID
|
||||
,NetAmount
|
||||
,AccountChartOfID
|
||||
,TaxAmount
|
||||
,AccountTaxCodeID
|
||||
)
|
||||
OUTPUT INSERTED.ExportAccountInvoiceLineID
|
||||
VALUES (
|
||||
@invoiceId
|
||||
,(
|
||||
SELECT AccountInvoiceLineItemID
|
||||
FROM tblAccountInvoiceLineItem
|
||||
WHERE ItemCode = @itemCode
|
||||
)
|
||||
,@netAmount
|
||||
,(
|
||||
SELECT AccountChartOfID
|
||||
FROM tblAccountChartOf
|
||||
WHERE AccountCode = @accountCode
|
||||
)
|
||||
,@taxAmount
|
||||
,(
|
||||
SELECT AccountTaxCodeID
|
||||
FROM tblAccountTaxCode
|
||||
WHERE TaxCode = @taxCode
|
||||
)
|
||||
);";
|
||||
|
||||
// insert record
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand) // Use _connection.CreateCommand()
|
||||
{
|
||||
cmd.CommandText = lineSql;
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
|
||||
cmd.Parameters.AddWithValue("@invoiceID", invoiceId);
|
||||
cmd.Parameters.AddWithValue("@itemCode", line.ItemCode);
|
||||
cmd.Parameters.AddWithValue("@netAmount", line.UnitAmount);
|
||||
cmd.Parameters.AddWithValue("@accountCode", (int)line.Account.AccountCode);
|
||||
cmd.Parameters.AddWithValue("@taxAmount", line.TaxAmountTotal);
|
||||
cmd.Parameters.AddWithValue("@taxCode", line.TaxCode.TaxCode);
|
||||
|
||||
int lineId = (int)cmd.ExecuteScalar();
|
||||
}
|
||||
}
|
||||
returnList.Add(invoiceId.Value, invoice);
|
||||
}
|
||||
|
||||
if (returnList.Count != invoiceCount)
|
||||
{
|
||||
throw new Exception("Not all invoices were inserted into the export table. Expected: " + invoiceCount + ", Actual: " + returnList.Count);
|
||||
}
|
||||
else
|
||||
{
|
||||
return returnList;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// invoice read methods
|
||||
//
|
||||
|
||||
/// <summary>
|
||||
/// Returns list of invoice numbers that have not yet been exported (i.e. IsComplete=True), in InvoiceNumber asending order.
|
||||
/// </summary>
|
||||
/// <param name="invoiceType">Sales or Purchase</param>
|
||||
/// <returns>Dictionary where key=ExportAccountInvoiceID, value=InvoiceNumber</returns>
|
||||
public Dictionary<int, string> GetNewInvoiceNumbers(Model.Account.InvoiceType invoiceType)
|
||||
{
|
||||
var returnList = new Dictionary<int, string>();
|
||||
|
||||
string sql = @"
|
||||
SELECT tblExportAccountInvoice.ExportAccountInvoiceID, [InvoiceNumber]
|
||||
FROM tblExportAccountInvoice
|
||||
WHERE (tblExportAccountInvoice.IsComplete = 0)
|
||||
AND (tblExportAccountInvoice.ExportAccountInvoiceTypeID = @invoiceType)
|
||||
ORDER BY [InvoiceNumber];";
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = sql;
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
|
||||
cmd.Parameters.AddWithValue("@invoiceType", (int)invoiceType);
|
||||
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
returnList.Add(reader.GetInt32(0), reader.GetString(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get list of invoices by invoice id
|
||||
/// </summary>
|
||||
/// <param name="idList">list of invoice ids</param>
|
||||
/// <returns>dictionary key=id, value=invoice-model</returns>
|
||||
public Dictionary<int, Model.Account.SalesInvoice> GetSalesInvoiceById(IEnumerable<int> idList)
|
||||
{
|
||||
var returnList = new Dictionary<int, Model.Account.SalesInvoice>();
|
||||
|
||||
if (idList.Any() == false)
|
||||
{
|
||||
return returnList;
|
||||
}
|
||||
|
||||
// get the account and tax code objects
|
||||
//var taxcode = new Data.Database.Account.ReadTaxCode().GetAllActive();
|
||||
//var account = new Data.Database.Account.ReadAccountCode().All();
|
||||
var taxcodeIds = new Dictionary<int, int>();
|
||||
var accountIds = new Dictionary<int, int>();
|
||||
var lineItemIds = new Dictionary<int, int>();
|
||||
|
||||
// build sql string
|
||||
string sql = @"
|
||||
SELECT tblExportAccountInvoice.ExportAccountInvoiceID,
|
||||
tblExportAccountInvoice.ExportAccountInvoiceTypeID,
|
||||
tblExportAccountInvoice.Contact,
|
||||
tblExportAccountInvoice.InvoiceNumber,
|
||||
tblExportAccountInvoice.InvoiceDate,
|
||||
tblExportAccountInvoice.InvoiceDueDate,
|
||||
tblExportAccountInvoice.Reference,
|
||||
tblExportAccountInvoice.CurrencyCode,
|
||||
tblExportAccountInvoice.InvoiceAmount,
|
||||
tblExportAccountInvoice.IsComplete,
|
||||
tblExportAccountInvoiceLine.ExportAccountInvoiceLineID,
|
||||
tblExportAccountInvoiceLine.AccountInvoiceLineItemID,
|
||||
tblExportAccountInvoiceLine.AccountChartOfID,
|
||||
tblExportAccountInvoiceLine.NetAmount,
|
||||
tblExportAccountInvoiceLine.AccountTaxCodeID,
|
||||
tblExportAccountInvoiceLine.TaxAmount,
|
||||
tblExportAccountInvoice.LineUnitAmountIsTaxExclusive
|
||||
FROM tblExportAccountInvoice
|
||||
INNER JOIN
|
||||
tblExportAccountInvoiceLine
|
||||
ON tblExportAccountInvoice.ExportAccountInvoiceID = tblExportAccountInvoiceLine.ExportAccountInvoiceID
|
||||
";
|
||||
|
||||
var sqlWhere = new Data.Database.SqlWhereBuilder();
|
||||
sqlWhere.In("tblExportAccountInvoice.ExportAccountInvoiceID", idList, "WHERE");
|
||||
|
||||
sql = sql + sqlWhere.SqlWhereString + " ORDER BY tblExportAccountInvoice.ExportAccountInvoiceID, tblExportAccountInvoiceLine.ExportAccountInvoiceLineID; ";
|
||||
|
||||
int i = 0;
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = sql;
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
|
||||
sqlWhere.AddParametersToSqlCommand(cmd);
|
||||
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (reader.HasRows == false)
|
||||
{
|
||||
return returnList;
|
||||
}
|
||||
|
||||
int? invoiceId = null;
|
||||
int? previousInvoiceId = null;
|
||||
Model.Account.SalesInvoice invoice = null;
|
||||
|
||||
i = -1;
|
||||
while (reader.Read())
|
||||
{
|
||||
i++;
|
||||
invoiceId = reader.GetInt32(0);
|
||||
|
||||
// test for first/next invoice
|
||||
if (invoice == null || previousInvoiceId.Value != invoiceId.Value)
|
||||
{
|
||||
// if next invoice, add previous to return list
|
||||
if (previousInvoiceId.HasValue)
|
||||
{
|
||||
// invoice complete, add to return list
|
||||
returnList.Add(previousInvoiceId.Value, invoice);
|
||||
}
|
||||
|
||||
// add header info to new invoice
|
||||
invoice = new Model.Account.SalesInvoice(reader.GetBoolean(16));
|
||||
int invoiceType = reader.GetInt32(1);
|
||||
invoice.ContactName = reader.GetString(2);
|
||||
invoice.InvoiceNumber = reader.GetString(3);
|
||||
invoice.InvoiceDate = reader.GetDateTime(4);
|
||||
invoice.InvoiceDueDate = reader.GetDateTime(5);
|
||||
if (!reader.IsDBNull(6)) { invoice.InvoiceReference = reader.GetString(6); }
|
||||
invoice.InvoiceCurrencyCode = Enum.Parse<Model.Account.CurrencyCode>(reader.GetString(7));
|
||||
if (!reader.IsDBNull(8)) { invoice.InvoiceTotalAmount = reader.GetDecimal(8); }
|
||||
bool isComplete = reader.GetBoolean(9);
|
||||
|
||||
// set credit note
|
||||
if (invoice.InvoiceTotalAmount < 0)
|
||||
{
|
||||
invoice.IsCreditNote = true;
|
||||
}
|
||||
}
|
||||
|
||||
// add line info
|
||||
var invoiceLine = new Model.Account.SalesInvoice.InvoiceLine(invoice);
|
||||
int lineId = reader.GetInt32(10);
|
||||
lineItemIds.Add(i, reader.GetInt32(11));
|
||||
accountIds.Add(i, reader.GetInt32(12));
|
||||
invoiceLine.UnitAmount = reader.GetDecimal(13);
|
||||
invoiceLine.Quantity = 1;
|
||||
taxcodeIds.Add(i, reader.GetByte(14));
|
||||
invoiceLine.SetTaxAdjustmentByTaxTotal(reader.GetDecimal(15));
|
||||
|
||||
invoice.InvoiceLineList.Add(invoiceLine);
|
||||
previousInvoiceId = invoiceId.Value;
|
||||
}
|
||||
|
||||
// complete final invoice and add to list
|
||||
returnList.Add(invoiceId.Value, invoice);
|
||||
}
|
||||
}
|
||||
|
||||
// get and add account/tax/item objects to invoice
|
||||
var dbTaxCodes = new AccountTaxRepository(_connection, _transaction).ReadTaxCodeInfo(null, null, taxcodeIds.Values.ToList());
|
||||
var dbAccountCodes = new AccountCodeRepository(_connection, _transaction).ReadAccountCode(accountIds.Values.ToList());
|
||||
var dbLineItems = new InvoiceRepository(_connection, _transaction).GetInvoiceLineItem(lineItemIds.Values.ToList());
|
||||
|
||||
i = -1;
|
||||
foreach (var invoice in returnList.Values)
|
||||
{
|
||||
foreach (var line in invoice.InvoiceLineList)
|
||||
{
|
||||
i++;
|
||||
line.TaxCode = dbTaxCodes[taxcodeIds[i]];
|
||||
line.Account = dbAccountCodes[accountIds[i]];
|
||||
|
||||
// fill in missing data for line item, if required
|
||||
var invoiceLineItem = dbLineItems[lineItemIds[i]];
|
||||
line.ItemCode = invoiceLineItem.ItemCode;
|
||||
if (string.IsNullOrEmpty(line.Description))
|
||||
{
|
||||
line.Description = invoiceLineItem.Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnList;
|
||||
}
|
||||
|
||||
//
|
||||
// invoice update methods
|
||||
//
|
||||
|
||||
public int UpdateInvoiceHeaderDetail(int invoiceId, string invoiceNumber = null, bool? isComplete = null)
|
||||
{
|
||||
if (invoiceNumber == null && isComplete == null)
|
||||
{
|
||||
throw new ArgumentException("At least one of the parameters must be set to update invoice header details.");
|
||||
}
|
||||
|
||||
// build the statement with my helper
|
||||
var sqlupdate = new Core.Data.Database.SqlUpdateBuilder();
|
||||
sqlupdate.SetTableName("tblExportAccountInvoice");
|
||||
if (invoiceNumber != null)
|
||||
sqlupdate.AddUpdateArugment("InvoiceNumber", invoiceNumber);
|
||||
if (isComplete.HasValue)
|
||||
sqlupdate.AddUpdateArugment("IsComplete", isComplete);
|
||||
sqlupdate.AddWhereArugment("ExportAccountInvoiceID", invoiceId);
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText = sqlupdate.GetSqlString();
|
||||
sqlupdate.AddParametersToSqlCommand(cmd);
|
||||
|
||||
return cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Invoice Delete Methods
|
||||
//
|
||||
|
||||
public int DeleteInvoice(IEnumerable<int> invoiceIdList)
|
||||
{
|
||||
if (invoiceIdList == null || invoiceIdList.Count() == 0)
|
||||
{
|
||||
throw new ArgumentException("InvoiceIdList is empty, nothing to delete.");
|
||||
}
|
||||
|
||||
int invoiceToDelete = invoiceIdList.Distinct().Count();
|
||||
int invoiceEffected = 0;
|
||||
|
||||
// delete lines first
|
||||
Core.Data.Database.SqlWhereBuilder sqlWhereBuilder = new Core.Data.Database.SqlWhereBuilder();
|
||||
sqlWhereBuilder.In("ExportAccountInvoiceID", invoiceIdList);
|
||||
int lineCount = DeleteInvoiceExecuteInvoiceLine(sqlWhereBuilder);
|
||||
|
||||
// then delete invoice
|
||||
sqlWhereBuilder = new Core.Data.Database.SqlWhereBuilder();
|
||||
sqlWhereBuilder.In("ExportAccountInvoiceID", invoiceIdList);
|
||||
invoiceEffected = DeleteInvoiceExecuteInvoice(sqlWhereBuilder);
|
||||
|
||||
if (invoiceEffected == invoiceToDelete)
|
||||
{
|
||||
return invoiceEffected;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Error: "
|
||||
+ invoiceToDelete + " number invoices requested for deletion, "
|
||||
+ invoiceEffected + " number invoices effected. Changes rolled back.");
|
||||
}
|
||||
}
|
||||
|
||||
public int DeleteInvoiceLine(int invoiceLineId)
|
||||
{
|
||||
// only being able to delete one line at a time is a design/safety decision
|
||||
// otherwise, delete whole invoice
|
||||
if (invoiceLineId <= 0)
|
||||
{
|
||||
throw new ArgumentException("InvoiceLineId must be greater than zero.");
|
||||
}
|
||||
Core.Data.Database.SqlWhereBuilder sqlWhereBuilder = new Core.Data.Database.SqlWhereBuilder();
|
||||
sqlWhereBuilder.In("ExportAccountInvoiceLineID", new List<int> { invoiceLineId });
|
||||
return DeleteInvoiceExecuteInvoiceLine(sqlWhereBuilder);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method Only intended for use with ExecuteInvoice() or ExecuteInvoiceLine()
|
||||
/// </summary>
|
||||
/// <param name="sql">the full sql statement</param>
|
||||
/// <param name="sqlWhereBuilder">instance of the sql where builder helper</param>
|
||||
/// <returns>Number of row effected (deleted)</returns>
|
||||
private int DeleteInvoiceExecuteHelper(string sql, Core.Data.Database.SqlWhereBuilder sqlWhereBuilder)
|
||||
{
|
||||
// Only intended for ExecuteInvoice() or ExecuteInvoiceLine()
|
||||
|
||||
// important checks
|
||||
if (sqlWhereBuilder.IsSetSqlWhereString == false)
|
||||
{
|
||||
throw new ArgumentException("SqlWhereBuilder is not set, set the SqlWhereBuilder before calling this method.");
|
||||
}
|
||||
if (sqlWhereBuilder.ParameterListCount == 0)
|
||||
{
|
||||
throw new Exception("Parameter list count is zero, this could delete all records in table, operation cancelled");
|
||||
}
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = sql;
|
||||
cmd.Transaction = _transaction as SqlTransaction; // Assign the shared transaction
|
||||
sqlWhereBuilder.AddParametersToSqlCommand(cmd);
|
||||
|
||||
return cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
|
||||
private int DeleteInvoiceExecuteInvoice(Core.Data.Database.SqlWhereBuilder sqlWhereBuilder)
|
||||
{
|
||||
string sql = "DELETE FROM tblExportAccountInvoice WHERE " + sqlWhereBuilder.SqlWhereString;
|
||||
return DeleteInvoiceExecuteHelper(sql, sqlWhereBuilder);
|
||||
}
|
||||
|
||||
private int DeleteInvoiceExecuteInvoiceLine(Core.Data.Database.SqlWhereBuilder sqlWhereBuilder)
|
||||
{
|
||||
string sql = "DELETE FROM tblExportAccountInvoiceLine WHERE " + sqlWhereBuilder.SqlWhereString;
|
||||
return DeleteInvoiceExecuteHelper(sql, sqlWhereBuilder);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,585 @@
|
||||
using bnhtrade.Core.Data.Database.Repository.Interface;
|
||||
using FikaAmazonAPI.AmazonSpApiSDK.Models.EasyShip20220323;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Repository.Implementation
|
||||
{
|
||||
internal class InvoiceRepository : _Base, IInvoiceRepository
|
||||
{
|
||||
public InvoiceRepository(IDbConnection connection, IDbTransaction transaction) : base(connection, transaction)
|
||||
{
|
||||
}
|
||||
|
||||
public int CreateDefaultInvoiceLineItem(string itemCode)
|
||||
{
|
||||
string sql = @"
|
||||
INSERT INTO tblAccountInvoiceLineItem ( ItemName, ItemCode )
|
||||
OUTPUT INSERTED.AccountInvoiceLineItemID
|
||||
VALUES ( @itemName, @itemCode )
|
||||
";
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = sql;
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a collection of invoice line items, optionally including account and tax information.
|
||||
/// </summary>
|
||||
/// <remarks>This method queries the database to retrieve invoice line items. If <paramref
|
||||
/// name="includeAccountInfo"/> or <paramref name="includeTaxInfo"/> is set to <see langword="true"/>,
|
||||
/// additional queries are performed to fetch the corresponding account and tax information, which may impact
|
||||
/// performance.</remarks>
|
||||
/// <param name="itemCodes">An optional collection of item codes to filter the results. If <see langword="null"/> or empty, all invoice
|
||||
/// line items are retrieved.</param>
|
||||
/// <param name="includeAccountInfo">A value indicating whether to include account information for each invoice line item. If <see
|
||||
/// langword="true"/>, the default account code is populated for each item. Defaults to <see langword="true"/>.</param>
|
||||
/// <param name="includeTaxInfo">A value indicating whether to include tax information for each invoice line item. If <see
|
||||
/// langword="true"/>, the default tax code is populated for each item. Defaults to <see langword="true"/>.</param>
|
||||
/// <returns>A dictionary where the key is the table record id of the invoice line item, and the value is the
|
||||
/// corresponding <see cref="Model.Account.InvoiceLineItem"/> object. The dictionary will be empty if no
|
||||
/// matching items are found.</returns>
|
||||
public Dictionary<int, Model.Account.InvoiceLineItem> GetInvoiceLineItem(
|
||||
IEnumerable<int> itemIds = null, IEnumerable<string> itemCodes = null, bool includeAccountInfo = true, bool includeTaxInfo = true
|
||||
)
|
||||
{
|
||||
var sqlwhere = new SqlWhereBuilder();
|
||||
var returnList = new Dictionary<int, Model.Account.InvoiceLineItem>();
|
||||
var accountCodeIdList = new Dictionary<int, int>(); // key=LineItemID, value=AccountChartOfID
|
||||
var taxCodeIdList = new Dictionary<int, int>(); // key=LineItemID, value=AccountTaxCodeID
|
||||
|
||||
string sql = @"
|
||||
SELECT [AccountInvoiceLineItemID]
|
||||
,[ItemName]
|
||||
,[ItemCode]
|
||||
,[ItemDescription]
|
||||
,[IsNewReviewRequired]
|
||||
,[InvoiceLineEntryEnable]
|
||||
,[AccountChartOfID_Default]
|
||||
,[AccountTaxCodeID_Default]
|
||||
FROM [e2A].[dbo].[tblAccountInvoiceLineItem]
|
||||
WHERE 1=1 ";
|
||||
|
||||
if (itemCodes != null && itemCodes.Any())
|
||||
{
|
||||
sqlwhere.In("ItemCode", itemCodes, "AND");
|
||||
sql += sqlwhere.SqlWhereString;
|
||||
}
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = sql;
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
|
||||
sqlwhere.AddParametersToSqlCommand(cmd);
|
||||
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
var lineItem = new Model.Account.InvoiceLineItem();
|
||||
|
||||
int recordId = reader.GetInt32(0);
|
||||
lineItem.Name = reader.GetString(1);
|
||||
lineItem.ItemCode = reader.GetString(2);
|
||||
if (!reader.IsDBNull(3)) { lineItem.Description = reader.GetString(3); }
|
||||
lineItem.IsNewReviewRequired = reader.GetBoolean(4);
|
||||
lineItem.InvoiceLineEntryEnabled = reader.GetBoolean(5);
|
||||
|
||||
if (!reader.IsDBNull(6))
|
||||
{
|
||||
accountCodeIdList.Add(recordId, reader.GetInt32(6));
|
||||
}
|
||||
if (!reader.IsDBNull(7))
|
||||
{
|
||||
taxCodeIdList.Add(recordId, reader.GetInt32(7));
|
||||
}
|
||||
|
||||
returnList.Add(recordId, lineItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get account codes and add to result list
|
||||
if (includeAccountInfo)
|
||||
{
|
||||
var accountCodeDictionary = new AccountCodeRepository(_connection, _transaction).ReadAccountCode(accountCodeIdList.Values.ToList());
|
||||
foreach (var accountCode in accountCodeIdList)
|
||||
{
|
||||
returnList[accountCode.Key].DefaultAccountCode = accountCodeDictionary[accountCode.Value];
|
||||
}
|
||||
}
|
||||
|
||||
// get tax codes
|
||||
if (includeTaxInfo)
|
||||
{
|
||||
var taxCodeDictionary = new AccountTaxRepository(_connection, _transaction).ReadTaxCodeInfo(null, null, taxCodeIdList.Values.ToList());
|
||||
foreach (var taxCode in taxCodeIdList)
|
||||
{
|
||||
returnList[taxCode.Key].DefaultTaxCode = taxCodeDictionary[taxCode.Value];
|
||||
}
|
||||
}
|
||||
|
||||
return returnList;
|
||||
}
|
||||
|
||||
|
||||
public Dictionary<int, Model.Account.PurchaseInvoice> ReadPurchaseInvoice(IEnumerable<int> purchaseInvoiceIdList)
|
||||
{
|
||||
var returnList = new Dictionary<int, Model.Account.PurchaseInvoice>();
|
||||
SqlWhereBuilder sqlBuilder = new SqlWhereBuilder();
|
||||
|
||||
//build sql query
|
||||
string sql = @"
|
||||
SELECT tblPurchase.PurchaseID
|
||||
,tblPurchase.PurchaseNumber
|
||||
,tblPurchase.RecordID
|
||||
,tblPurchase.PurchaseDate
|
||||
,tblPurchase.ContactID
|
||||
,tblPurchase.SupplierRef
|
||||
,tblPurchase.PurchaseTotalAmount
|
||||
,tblPurchase.VatInclusiveAmounts
|
||||
,tblPurchase.RecordCreated
|
||||
,tblPurchase.RecordModified
|
||||
,tblPurchase.IsActive
|
||||
,tblAccountCurrency.CurrencyCode
|
||||
,tblPurchaseChannel.PurchaseChannelName
|
||||
,tblPurchaseStatus.PurchaseStatus
|
||||
FROM tblPurchase
|
||||
LEFT OUTER JOIN tblAccountCurrency ON tblPurchase.AccountCurrencyID = tblAccountCurrency.AccountCurrencyID
|
||||
LEFT OUTER JOIN tblPurchaseStatus ON tblPurchase.PurchaseStatusID = tblPurchaseStatus.PurchaseStatusID
|
||||
LEFT OUTER JOIN tblPurchaseChannel ON tblPurchase.PurchaseChannelID = tblPurchaseChannel.PurchaseChannelID
|
||||
WHERE 1 = 1
|
||||
";
|
||||
|
||||
// build the where statments
|
||||
if (purchaseInvoiceIdList.Any())
|
||||
{
|
||||
sqlBuilder.In("[PurchaseID]", purchaseInvoiceIdList, "AND");
|
||||
}
|
||||
|
||||
// append where string to the sql
|
||||
if (sqlBuilder.IsSetSqlWhereString)
|
||||
{
|
||||
sql = sql + sqlBuilder.SqlWhereString;
|
||||
}
|
||||
|
||||
// dictionary so we can fill in details afterwards
|
||||
var invoiceContactDict = new Dictionary<int, int>();
|
||||
var purchaseIdList = new List<int>();
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = sql;
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
|
||||
sqlBuilder.AddParametersToSqlCommand(cmd);
|
||||
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (reader.HasRows)
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
|
||||
|
||||
int purchaseID = reader.GetInt32(0);
|
||||
int purchaseNumber = reader.GetInt32(1);
|
||||
int? recordID = null;
|
||||
if (!reader.IsDBNull(2)) { recordID = reader.GetInt32(2); }
|
||||
DateTime purchaseDate = DateTime.SpecifyKind(reader.GetDateTime(3), DateTimeKind.Utc);
|
||||
int? contactID = null;
|
||||
if (!reader.IsDBNull(4)) { contactID = reader.GetInt32(4); }
|
||||
string supplierRef = null;
|
||||
if (!reader.IsDBNull(5)) { supplierRef = reader.GetString(5); }
|
||||
decimal? purchaseTotalAmount = null;
|
||||
if (!reader.IsDBNull(6)) { purchaseTotalAmount = reader.GetDecimal(6); }
|
||||
bool vatInclusiveAmounts = reader.GetBoolean(7);
|
||||
DateTime recordCreated = DateTime.SpecifyKind(reader.GetDateTime(8), DateTimeKind.Utc);
|
||||
DateTime recordModified = DateTime.SpecifyKind(reader.GetDateTime(9), DateTimeKind.Utc);
|
||||
bool isActive = reader.GetBoolean(10);
|
||||
string currencyCode = reader.GetString(11);
|
||||
string purchaseChannelName = reader.GetString(12);
|
||||
string purchaseStatus = null;
|
||||
if (!reader.IsDBNull(13)) { purchaseStatus = reader.GetString(13); }
|
||||
|
||||
var invoice = new Model.Account.PurchaseInvoice();
|
||||
invoice.PurchaseID = purchaseID;
|
||||
invoice.PurchaseNumber = purchaseNumber;
|
||||
invoice.RecordID = recordID;
|
||||
invoice.PurchaseDate = purchaseDate;
|
||||
invoice.SupplierRef = supplierRef;
|
||||
//invoice.PurchaseTotalAmount = purchaseTotalAmount;
|
||||
invoice.VatInclusiveAmounts = vatInclusiveAmounts;
|
||||
invoice.RecordCreated = recordCreated;
|
||||
invoice.RecordModified = recordModified;
|
||||
invoice.IsActive = isActive;
|
||||
invoice.CurrencyCode = currencyCode;
|
||||
invoice.PurchaseChannel = purchaseChannelName;
|
||||
|
||||
// is there contact info that needs to be added?
|
||||
if (contactID != null)
|
||||
{
|
||||
invoiceContactDict.Add(purchaseID, (int)contactID);
|
||||
}
|
||||
|
||||
purchaseIdList.Add(purchaseID);
|
||||
|
||||
returnList.Add(purchaseID, invoice);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// add contact info
|
||||
if (invoiceContactDict.Any())
|
||||
{
|
||||
var readContact = new Data.Database.Account.ReadContact();
|
||||
readContact.ContactIdList = invoiceContactDict.Values.ToList();
|
||||
var contactDict = readContact.Read();
|
||||
|
||||
if (contactDict.Any())
|
||||
{
|
||||
foreach (var invoice in returnList)
|
||||
{
|
||||
if (invoiceContactDict.ContainsKey(invoice.Value.PurchaseID))
|
||||
{
|
||||
int contactId = invoiceContactDict[invoice.Value.PurchaseID];
|
||||
invoice.Value.Contact = contactDict[contactId];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add invoice lines
|
||||
var lines = ReadPurchaseInvoiceLine(purchaseIdList);
|
||||
foreach (var invoice in returnList.Values)
|
||||
{
|
||||
foreach (var line in lines.Values)
|
||||
{
|
||||
if (line.PurchaseId == invoice.PurchaseID)
|
||||
{
|
||||
if (invoice.InvoiceLines == null)
|
||||
{
|
||||
invoice.InvoiceLines = new List<Model.Account.PurchaseInvoice.Line>();
|
||||
}
|
||||
invoice.InvoiceLines.Add(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return returnList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves purchase invoice lines based on specified filters.
|
||||
/// </summary>
|
||||
/// <remarks>This method queries the database to retrieve purchase invoice line details that match
|
||||
/// the provided filters. The filters include invoice IDs, invoice line IDs, statuses, and item descriptions.
|
||||
/// The returned dictionary maps the purchase line ID to its corresponding <see
|
||||
/// cref="Model.Account.PurchaseInvoice.Line"/> object.</remarks>
|
||||
/// <param name="invoiceIdList">A list of purchase invoice IDs to filter the results. If empty, no filtering is applied.</param>
|
||||
/// <param name="invoiceLineIdList">A list of purchase invoice line IDs to filter the results. If empty, no filtering is applied.</param>
|
||||
/// <param name="statusList">A list of statuses to filter the results. If empty, no filtering is applied.</param>
|
||||
/// <param name="itemDescription">Searches for the specificed phases within the item description. Uses the LIKE AND sql function. Partial matches are supported. If empty, no filtering is
|
||||
/// applied.</param>
|
||||
/// <returns>A dictionary where the key is the purchase line ID and the value is the corresponding
|
||||
/// Model.Account.PurchaseInvoice.Line object containing detailed information about the purchase invoice line.</returns>
|
||||
/// <exception cref="Exception">Thrown if a fail-safe condition is triggered, indicating an unexpected issue with tax code assignment.</exception>
|
||||
public Dictionary<int, Model.Account.PurchaseInvoice.Line> ReadPurchaseInvoiceLine
|
||||
(List<int> invoiceIdList = null, List<int> invoiceLineIdList = null, List<string> statusList = null, List<string> itemDescriptionList = null)
|
||||
{
|
||||
var returnList = new Dictionary<int, Model.Account.PurchaseInvoice.Line>();
|
||||
var sqlBuilder = new SqlWhereBuilder();
|
||||
|
||||
//build sql query
|
||||
string sql = @"
|
||||
SELECT tblPurchaseLine.PurchaseLineID
|
||||
,tblPurchaseLine.PurchaseID
|
||||
,tblPurchaseLineStatus.PurchaseLineStatus
|
||||
,tblPurchaseLine.SupplierRef
|
||||
,tblPurchaseLine.CheckedIn
|
||||
,tblPurchaseLine.ItemDescription
|
||||
,tblPurchaseLine.ItemQuantity
|
||||
,tblPurchaseLine.ItemGross
|
||||
,tblPurchaseLine.ItemTax
|
||||
,tblPurchaseLine.ShippingGross
|
||||
,tblPurchaseLine.ShippingTax
|
||||
,tblPurchaseLine.OtherGross
|
||||
,tblPurchaseLine.OtherTax
|
||||
,tblPurchaseLine.AccountTaxCodeID
|
||||
,tblPurchaseLine.Tax_AccountTransactionID
|
||||
,tblPurchaseLine.Net_AccountChartOfID
|
||||
,tblPurchaseLine.Net_AccountTransactionID
|
||||
,tblPurchaseLine.RecordCreated
|
||||
,tblPurchaseLine.RecordModified
|
||||
,tblPurchaseLine.IsActive
|
||||
,tblAccountTaxCode.TaxCode
|
||||
FROM tblPurchaseLine
|
||||
INNER JOIN tblPurchaseLineStatus ON tblPurchaseLine.PurchaseLineStatusID = tblPurchaseLineStatus.PurchaseLineStatusID
|
||||
LEFT OUTER JOIN tblAccountTaxCode ON tblPurchaseLine.AccountTaxCodeID = tblAccountTaxCode.AccountTaxCodeID
|
||||
WHERE 1 = 1 ";
|
||||
|
||||
// build the where statments
|
||||
if (invoiceIdList != null && invoiceIdList.Any())
|
||||
{
|
||||
sqlBuilder.In("PurchaseID", invoiceLineIdList, "AND");
|
||||
}
|
||||
if (invoiceLineIdList != null && invoiceLineIdList.Any())
|
||||
{
|
||||
sqlBuilder.In("PurchaseLineID", invoiceLineIdList, "AND");
|
||||
}
|
||||
if (statusList != null && statusList.Any())
|
||||
{
|
||||
sqlBuilder.In("PurchaseLineStatus", invoiceLineIdList, "AND");
|
||||
}
|
||||
if (itemDescriptionList != null && itemDescriptionList.Any())
|
||||
{
|
||||
sqlBuilder.LikeAnd("ItemDescription", itemDescriptionList, "AND");
|
||||
}
|
||||
|
||||
|
||||
// append where string to the sql
|
||||
if (sqlBuilder.IsSetSqlWhereString)
|
||||
{
|
||||
sql = sql + sqlBuilder.SqlWhereString;
|
||||
}
|
||||
|
||||
// catch taxcode to add in after db read
|
||||
var lineTaxCodeDict = new Dictionary<int, string>();
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = sql;
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
|
||||
sqlBuilder.AddParametersToSqlCommand(cmd);
|
||||
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (reader.HasRows)
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
int purchaseLineID = reader.GetInt32(0);
|
||||
int purchaseID = reader.GetInt32(1);
|
||||
string purchaseLineStatus = reader.GetString(2);
|
||||
string supplierRef = null;
|
||||
if (!reader.IsDBNull(3)) { supplierRef = reader.GetString(3); }
|
||||
DateTime? checkedIn = null;
|
||||
if (!reader.IsDBNull(4)) { checkedIn = DateTime.SpecifyKind(reader.GetDateTime(4), DateTimeKind.Utc); }
|
||||
string itemDescription = null;
|
||||
if (!reader.IsDBNull(5)) { itemDescription = reader.GetString(5); }
|
||||
int itemQuantity = reader.GetInt32(6);
|
||||
decimal itemGross = 0;
|
||||
if (!reader.IsDBNull(7)) { itemGross = reader.GetDecimal(7); }
|
||||
decimal itemTax = 0;
|
||||
if (!reader.IsDBNull(8)) { itemTax = reader.GetDecimal(8); }
|
||||
decimal shippingGross = 0;
|
||||
if (!reader.IsDBNull(9)) { shippingGross = reader.GetDecimal(9); }
|
||||
decimal shippingTax = 0;
|
||||
if (!reader.IsDBNull(10)) { shippingTax = reader.GetDecimal(10); }
|
||||
decimal otherGross = 0;
|
||||
if (!reader.IsDBNull(11)) { otherGross = reader.GetDecimal(11); }
|
||||
decimal otherTax = 0;
|
||||
if (!reader.IsDBNull(12)) { otherTax = reader.GetDecimal(12); }
|
||||
int accountTaxCodeID = reader.GetInt32(13);
|
||||
int? tax_AccountTransactionID = null;
|
||||
if (!reader.IsDBNull(14)) { tax_AccountTransactionID = reader.GetInt32(14); }
|
||||
int net_AccountChartOfID = reader.GetInt32(15);
|
||||
int? net_AccountTransactionID = null;
|
||||
if (!reader.IsDBNull(16)) { net_AccountTransactionID = reader.GetInt32(16); }
|
||||
DateTime recordModified;
|
||||
DateTime recordCreated = DateTime.SpecifyKind(reader.GetDateTime(17), DateTimeKind.Utc);
|
||||
if (reader.IsDBNull(18)) { recordModified = recordCreated; }
|
||||
else { recordModified = DateTime.SpecifyKind(reader.GetDateTime(18), DateTimeKind.Utc); }
|
||||
bool isActive = reader.GetBoolean(19);
|
||||
string accountTaxCode = reader.GetString(20);
|
||||
|
||||
var line = new Model.Account.PurchaseInvoice.Line();
|
||||
line.PurchaseLineId = purchaseLineID;
|
||||
line.PurchaseId = purchaseID;
|
||||
line.Status = purchaseLineStatus;
|
||||
line.SupplierRef = supplierRef;
|
||||
line.CheckedIn = checkedIn;
|
||||
line.ItemDescription = itemDescription;
|
||||
line.ItemQuantity = itemQuantity;
|
||||
line.ItemGross = itemGross;
|
||||
line.ItemTax = itemTax;
|
||||
line.ShippingGross = shippingGross;
|
||||
line.ShippingTax = shippingTax;
|
||||
line.OtherGross = otherGross;
|
||||
line.OtherTax = otherTax;
|
||||
line.Tax_AccountTransactionId = tax_AccountTransactionID;
|
||||
line.Net_AccountChartOfId = net_AccountChartOfID;
|
||||
line.Net_AccountTransactionId = net_AccountTransactionID;
|
||||
line.RecordModified = recordModified;
|
||||
line.RecordCreated = recordCreated;
|
||||
line.IsActive = isActive;
|
||||
|
||||
returnList.Add(purchaseLineID, line);
|
||||
|
||||
lineTaxCodeDict.Add(purchaseLineID, accountTaxCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// read tax codes form db and add to return object
|
||||
var taxcodeList = new AccountTaxRepository(_connection, _transaction).ReadTaxCodeInfo(null, lineTaxCodeDict.Values.ToList()).Values.ToList();
|
||||
|
||||
foreach (var line in returnList.Values)
|
||||
{
|
||||
foreach (var taxcode in taxcodeList)
|
||||
{
|
||||
if (taxcode.TaxCode == lineTaxCodeDict[line.PurchaseLineId])
|
||||
{
|
||||
line.AccountTaxCode = taxcode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (line.AccountTaxCode == null)
|
||||
{
|
||||
throw new Exception("Fail safe, this really shouodn't happen");
|
||||
}
|
||||
}
|
||||
|
||||
// all done
|
||||
return returnList;
|
||||
}
|
||||
|
||||
public Dictionary<int, Model.Account.PurchaseInvoiceLineStatus> ReadPurchaseInvoiceLineStatus()
|
||||
{
|
||||
var returnList = new Dictionary<int, Model.Account.PurchaseInvoiceLineStatus>();
|
||||
|
||||
string sql = @"
|
||||
SELECT [PurchaseLineStatusID]
|
||||
,[PurchaseLineStatus]
|
||||
,[ListSort]
|
||||
,[TimeStamp]
|
||||
FROM [e2A].[dbo].[tblPurchaseLineStatus]
|
||||
ORDER BY [ListSort]";
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = sql;
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (!reader.HasRows)
|
||||
{
|
||||
// do something
|
||||
}
|
||||
else
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
int id = reader.GetInt32(0);
|
||||
string name = reader.GetString(1);
|
||||
int lineSort = reader.GetInt32(2);
|
||||
|
||||
var returnItem = new Model.Account.PurchaseInvoiceLineStatus(id, name, lineSort);
|
||||
returnList.Add(id, returnItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnList;
|
||||
}
|
||||
|
||||
public List<Model.Account.PurchaseInvoiceLineSummary> ReadPurchaseInvoiceLineSummary(DateTime periodTo, string lineStatus, List<string> descriptionSearch)
|
||||
{
|
||||
var returnList = new List<Model.Account.PurchaseInvoiceLineSummary>();
|
||||
var sqlBuilder = new bnhtrade.Core.Data.Database.SqlWhereBuilder();
|
||||
|
||||
//build sql query
|
||||
string sql = @"
|
||||
SELECT tblPurchase.PurchaseDate
|
||||
,tblPurchase.PurchaseID
|
||||
,tblPurchase.PurchaseNumber
|
||||
,tblPurchaseLine.PurchaseLineID
|
||||
,tblPurchaseLine.ItemDescription
|
||||
,tblPurchaseLineStatus.PurchaseLineStatus
|
||||
FROM tblPurchase
|
||||
INNER JOIN tblPurchaseLine ON tblPurchase.PurchaseID = tblPurchaseLine.PurchaseID
|
||||
INNER JOIN tblPurchaseLineStatus ON tblPurchaseLine.PurchaseLineStatusID = tblPurchaseLineStatus.PurchaseLineStatusID
|
||||
WHERE tblPurchase.PurchaseDate <= @purchaseDate
|
||||
";
|
||||
|
||||
if (lineStatus != null)
|
||||
{
|
||||
sql = sql + " AND PurchaseLineStatus = @purchaseLineStatus ";
|
||||
}
|
||||
|
||||
// build the where statments
|
||||
if (descriptionSearch.Any())
|
||||
{
|
||||
sqlBuilder.LikeAnd("ItemDescription", descriptionSearch, "AND");
|
||||
}
|
||||
|
||||
// append where string to the sql
|
||||
if (sqlBuilder.IsSetSqlWhereString)
|
||||
{
|
||||
sql = sql + sqlBuilder.SqlWhereString;
|
||||
}
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = sql;
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
|
||||
cmd.Parameters.AddWithValue("@purchaseDate", periodTo);
|
||||
if (lineStatus != null)
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@purchaseLineStatus", lineStatus);
|
||||
}
|
||||
|
||||
sqlBuilder.AddParametersToSqlCommand(cmd);
|
||||
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
DateTime purchaseDate = DateTime.SpecifyKind(reader.GetDateTime(0), DateTimeKind.Utc);
|
||||
int purchaseID = reader.GetInt32(1);
|
||||
int purchaseNumber = reader.GetInt32(2);
|
||||
int purchaseLineID = reader.GetInt32(3);
|
||||
string itemDescription = reader.GetString(4);
|
||||
string purchaseLineStatus = reader.GetString(5);
|
||||
|
||||
var item = new Model.Account.PurchaseInvoiceLineSummary();
|
||||
item.PurchaseDate = purchaseDate;
|
||||
item.PurchaseId = purchaseID;
|
||||
item.PurchaseNumber = purchaseNumber;
|
||||
item.PurchaseLineId = purchaseLineID;
|
||||
item.ItemDescription = itemDescription;
|
||||
item.LineStatus = purchaseLineStatus;
|
||||
|
||||
returnList.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return returnList;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
using bnhtrade.Core.Data.Database.Repository.Interface;
|
||||
using bnhtrade.Core.Model.Account;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Transactions;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Repository.Implementation
|
||||
{
|
||||
internal class PurchaseRepository : _Base, IPurchaseRepository
|
||||
{
|
||||
private static int accountJournalTypeIdNet = 1;
|
||||
private static int accountJournalTypeIdTax = 2;
|
||||
private static int stockJournalTypeId = 1;
|
||||
private static int creditAccountId = 59;
|
||||
private static int creditStatusId = 13;
|
||||
private static int defaultAccountId = 138;
|
||||
|
||||
public PurchaseRepository(IDbConnection connection, IDbTransaction transaction) : base(connection, transaction)
|
||||
{
|
||||
}
|
||||
|
||||
public int DeletePurchaseLineTransaction(int accountJournalId)
|
||||
{
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText = @"
|
||||
DELETE FROM tblPurchaseLineTransaction
|
||||
WHERE AccountJournalID=@accountJournalId;";
|
||||
|
||||
cmd.Parameters.AddWithValue("@accountJournalID", accountJournalId);
|
||||
|
||||
return cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
|
||||
public void InsertPurchaseLineTransaction(int accountJournalId, int purchaseLineId)
|
||||
{
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText = @"
|
||||
INSERT INTO
|
||||
tblPurchaseLineTransaction
|
||||
( PurchaseLineID, AccountJournalID )
|
||||
VALUES
|
||||
( @purchaseLineID, @accountJournalID );";
|
||||
|
||||
cmd.Parameters.AddWithValue("@purchaseLineID", purchaseLineId);
|
||||
cmd.Parameters.AddWithValue("@accountJournalID", accountJournalId);
|
||||
|
||||
int count = cmd.ExecuteNonQuery();
|
||||
|
||||
if (count != 1)
|
||||
{
|
||||
throw new Exception("Failed to insert record to tblPurchaseLineTransaction table");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void WIP_PurchaseLineTransactionNetUpdate(int accountJouranlId, string currencyCode, decimal amountNet, int debitAccountId)
|
||||
{
|
||||
// stock accountId check
|
||||
if (debitAccountId == 86)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText = @"
|
||||
SELECT Count(tblStock.StockID) AS CountOfStockID
|
||||
FROM tblStock
|
||||
WHERE (((tblStock.AccountJournalID)=@accountJournalId));
|
||||
";
|
||||
cmd.Parameters.AddWithValue("@accountJournalId", accountJouranlId);
|
||||
|
||||
count = (int)cmd.ExecuteScalar();
|
||||
}
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
throw new Exception("Add account journal entry to stock before attempting this operation.");
|
||||
}
|
||||
else if (count > 1)
|
||||
{
|
||||
throw new Exception("Houston we have a problem! An account journal entry is assigned to " + count + " stock lines.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// delete after testing....
|
||||
|
||||
//public void WIP_PurchaseLineTransactionStockDelete(string sqlConnectionString, int accountJournalId, int stockId)
|
||||
//{
|
||||
// using (TransactionScope scope = new TransactionScope())
|
||||
// using (SqlConnection conn = new SqlConnection(sqlConnectionString))
|
||||
// {
|
||||
// conn.Open();
|
||||
|
||||
// // get stock cost
|
||||
// (int quantity, decimal totalCost) result = Stock.StockJournal.StockGetTotalQuantityAndCost(sqlConnectionString, stockId);
|
||||
// decimal amount = result.totalCost;
|
||||
|
||||
// // delete accountJournalId from stock table
|
||||
// using (SqlCommand cmd = new SqlCommand(@"
|
||||
// UPDATE tblStock
|
||||
// SET AccountJournalID=Null
|
||||
// WHERE StockID=@stockId AND AccountJournalID=@accountJournalId;
|
||||
// ", conn))
|
||||
// {
|
||||
// cmd.Parameters.AddWithValue("@stockId", stockId);
|
||||
// cmd.Parameters.AddWithValue("@accountJournalId", accountJournalId);
|
||||
|
||||
// int count = cmd.ExecuteNonQuery();
|
||||
|
||||
// if (count != 1)
|
||||
// {
|
||||
// throw new Exception("Integrity check failure! StockID=" + stockId + ", AccountJournalID=" + accountJournalId +
|
||||
// " combination not found on stock table.");
|
||||
// }
|
||||
// }
|
||||
|
||||
// // reset the account journal to default
|
||||
// Account.AccountQuery.AccountJournalPostUpdate(sqlConnectionString, accountJournalId, "GBP", amount, defaultAccountId, creditAccountId);
|
||||
|
||||
// // delete the stock entry
|
||||
// Stock.StockCreate.WIP_StockDeleteSub(sqlConnectionString, stockId);
|
||||
|
||||
// scope.Complete();
|
||||
// }
|
||||
//}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using bnhtrade.Core.Data.Database.Repository.Interface;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Repository.Implementation
|
||||
{
|
||||
internal class SequenceGenerator : _Base, ISequenceGenerator
|
||||
{
|
||||
public SequenceGenerator (IDbConnection connection, IDbTransaction transaction) : base(connection, transaction)
|
||||
{
|
||||
}
|
||||
|
||||
public int GetNext(string sequenceName)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(sequenceName))
|
||||
{
|
||||
throw new Exception("Sequence name is null or whitespace.");
|
||||
}
|
||||
|
||||
string sql = $"SELECT NEXT VALUE FOR {sequenceName};";
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = sql;
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
|
||||
object obj = cmd.ExecuteScalar();
|
||||
|
||||
try
|
||||
{
|
||||
return Convert.ToInt32(obj);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Provide more context in the exception
|
||||
throw new InvalidOperationException($"Error retrieving next value for sequence '{sequenceName}'. " +
|
||||
$"Raw value: '{obj}'. Inner exception: {ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
using bnhtrade.Core.Data.Database._BoilerPlate;
|
||||
using bnhtrade.Core.Data.Database.Repository.Interface;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Transactions;
|
||||
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Repository.Implementation
|
||||
{
|
||||
internal class SkuRepository : _Base, ISkuRepository
|
||||
{
|
||||
public SkuRepository(IDbConnection connection, IDbTransaction transaction) : base(connection, transaction)
|
||||
{
|
||||
}
|
||||
|
||||
public int? ReadSkuId(int productId, int conditionId, int accountTaxCodeId)
|
||||
{
|
||||
int? returnId = null;
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = @"
|
||||
SELECT
|
||||
tblSku.skuSkuID
|
||||
FROM
|
||||
tblSku
|
||||
WHERE
|
||||
(((tblSku.skuProductID)=@productId) AND ((tblSku.skuSkuConditionID)=@conditionId) AND ((tblSku.AccountTaxCodeID)=@accountTaxCodeId));
|
||||
";
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
|
||||
cmd.Parameters.AddWithValue("@productId", productId);
|
||||
cmd.Parameters.AddWithValue("@conditionId", conditionId);
|
||||
cmd.Parameters.AddWithValue("@accountTaxCodeId", accountTaxCodeId);
|
||||
|
||||
object obj = cmd.ExecuteScalar();
|
||||
if (obj != null || obj == DBNull.Value)
|
||||
{
|
||||
returnId = (int)obj;
|
||||
}
|
||||
}
|
||||
return returnId;
|
||||
}
|
||||
|
||||
public int InsertNewSku(int productId, int conditionId, int accountTaxCodeId)
|
||||
{
|
||||
// check tax code id is a valid for SKU
|
||||
var taxCodeList = new AccountTaxRepository(_connection, _transaction).ReadTaxCodeInfo(null, null, new List<int> { accountTaxCodeId });
|
||||
|
||||
if (taxCodeList.ContainsKey(accountTaxCodeId) == false)
|
||||
{
|
||||
throw new Exception("AccountTaxCodeID=" + accountTaxCodeId + " doesn't exist!");
|
||||
}
|
||||
else if (taxCodeList[accountTaxCodeId].IsValidOnIncome == false)
|
||||
{
|
||||
throw new Exception("AccountTaxCodeID=" + accountTaxCodeId + " is not a valid type for an SKU.");
|
||||
}
|
||||
|
||||
// get info to create sku number
|
||||
int skuCount;
|
||||
int skuSuffix;
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = "SELECT NEXT VALUE FOR SkuCountSequence;";
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
skuCount = (int)cmd.ExecuteScalar();
|
||||
}
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = @"
|
||||
SELECT tblSkuCondition.scnSkuNumberSuffix
|
||||
FROM tblSkuCondition
|
||||
WHERE (((tblSkuCondition.scnSkuConditionID)=@conditionId));";
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.Parameters.AddWithValue("@conditionId", conditionId);
|
||||
|
||||
try
|
||||
{
|
||||
skuSuffix = (int)cmd.ExecuteScalar();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception("Error retriving SKU number suffix for SkuConditionID=" + conditionId + "." +
|
||||
System.Environment.NewLine + "Error Message: " + ex.Message);
|
||||
}
|
||||
}
|
||||
string skuNumber = skuCount.ToString("D6") + "-" + skuSuffix.ToString("D2");
|
||||
|
||||
// insert new sku
|
||||
int skuId;
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = @"
|
||||
INSERT INTO tblSku
|
||||
(skuSkuNumber, skuProductID, skuSkuConditionID, AccountTaxCodeID)
|
||||
OUTPUT INSERTED.skuSkuID
|
||||
VALUES
|
||||
(@skuNumber, @productId, @conditionId, @accountTaxCodeId)";
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
|
||||
cmd.Parameters.AddWithValue("@skuNumber", skuNumber);
|
||||
cmd.Parameters.AddWithValue("@productId", productId);
|
||||
cmd.Parameters.AddWithValue("@conditionId", conditionId);
|
||||
cmd.Parameters.AddWithValue("@accountTaxCodeId", accountTaxCodeId);
|
||||
|
||||
skuId = (int)cmd.ExecuteScalar();
|
||||
}
|
||||
return skuId;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,552 @@
|
||||
using bnhtrade.Core.Data.Database._BoilerPlate;
|
||||
using bnhtrade.Core.Data.Database.Repository.Interface;
|
||||
using bnhtrade.Core.Model.Account;
|
||||
using bnhtrade.Core.Model.Stock;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Transactions;
|
||||
using static bnhtrade.Core.Data.Database.Constants;
|
||||
using static bnhtrade.Core.Model.Account.Journal;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Repository.Implementation
|
||||
{
|
||||
internal class StockJournalRepository : _Base, IStockJournalRepository
|
||||
{
|
||||
public StockJournalRepository(IDbConnection connection, IDbTransaction transaction) : base(connection, transaction)
|
||||
{
|
||||
}
|
||||
|
||||
private List<string> ConvertStockNumbers(List<int> stockNumbers)
|
||||
{
|
||||
if (stockNumbers == null || stockNumbers.Count == 0)
|
||||
{
|
||||
return new List<string>();
|
||||
}
|
||||
return stockNumbers.Select(sn => "STK#" + sn.ToString("D6")).ToList();
|
||||
}
|
||||
|
||||
private List<int> ConvertStockNumbers(List<string> stockNumbers)
|
||||
{
|
||||
if (stockNumbers == null || stockNumbers.Count == 0)
|
||||
{
|
||||
return new List<int>();
|
||||
}
|
||||
return stockNumbers.Select(sn => int.Parse(sn.Substring(4))).ToList();
|
||||
}
|
||||
|
||||
//
|
||||
// Create
|
||||
//
|
||||
|
||||
public int InsertStockJournalHeader(int stockId, int journalTypeId, DateTime entryDate, bool isLocked)
|
||||
{
|
||||
if (entryDate.Kind != DateTimeKind.Utc)
|
||||
{
|
||||
throw new ArgumentException("Entry date must be in UTC format.", nameof(entryDate));
|
||||
}
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText = @"
|
||||
INSERT INTO tblStockJournal ( EntryDate, StockJournalTypeID, StockID, IsLocked )
|
||||
OUTPUT INSERTED.StockJournalID
|
||||
VALUES ( @EntryDate, @journalTypeId, @stockID, @isLocked );";
|
||||
|
||||
cmd.Parameters.AddWithValue("@stockID", stockId);
|
||||
cmd.Parameters.AddWithValue("@journalTypeId", journalTypeId);
|
||||
cmd.Parameters.AddWithValue("@EntryDate", entryDate.ToUniversalTime());
|
||||
cmd.Parameters.AddWithValue("@isLocked", isLocked);
|
||||
|
||||
//execute
|
||||
return (int)cmd.ExecuteScalar();
|
||||
}
|
||||
}
|
||||
|
||||
public int InsertStockJournalPost(int stockJournalId, int stockStatusId, int quantity)
|
||||
{
|
||||
if (quantity == 0)
|
||||
{
|
||||
throw new ArgumentException("Quantity must be non-zero.", nameof(quantity));
|
||||
}
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText = @"
|
||||
INSERT INTO tblStockJournalPost ( StockJournalID, StockStatusID, Quantity )
|
||||
OUTPUT INSERTED.StockJournalPostID
|
||||
VALUES ( @StockJournalId, @stockStatudId, @quantity );";
|
||||
|
||||
cmd.Parameters.AddWithValue("@StockJournalId", stockJournalId);
|
||||
cmd.Parameters.AddWithValue("@stockStatudId", stockStatusId);
|
||||
cmd.Parameters.AddWithValue("@quantity", quantity);
|
||||
|
||||
// execute
|
||||
return cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Read
|
||||
//
|
||||
|
||||
public Dictionary<int, Model.Stock.StockJournalBuilder> ReadStockJournal(bool lockRecords = false,
|
||||
List<int> stockJournalIds = null, List<int> stockIds = null, List<string> stockNumbers = null
|
||||
, DateTime? minEntryDate = null, DateTime? maxEntryDate = null, List<int> stockStatusIds = null)
|
||||
{
|
||||
var returnDict = new Dictionary<int, Model.Stock.StockJournalBuilder>();
|
||||
var sqlWhere = new SqlWhereBuilder();
|
||||
|
||||
string lockClause = "";
|
||||
if (lockRecords)
|
||||
{
|
||||
lockClause = "WITH (UPDLOCK, HOLDLOCK)";
|
||||
}
|
||||
|
||||
string sql = $@"
|
||||
SELECT tblStockJournal.StockJournalID,
|
||||
tblStockJournal.StockJournalTypeID,
|
||||
tblStockJournal.StockID,
|
||||
tblStock.StockNumber
|
||||
tblStockJournal.EntryDate,
|
||||
tblStockJournal.PostDate,
|
||||
tblStockJournal.LastModified,
|
||||
tblStockJournal.IsLocked,
|
||||
tblStockJournal.AccountIsProcessed,
|
||||
tblStockJournalPost.StockJournalPostID,
|
||||
tblStockJournalPost.StockStatusID,
|
||||
tblStockJournalPost.Quantity,
|
||||
FROM tblStockJournal {lockClause}
|
||||
LEFT OUTER JOIN tblStock {lockClause} ON tblStockJournal.StockID = tblStock.StockID
|
||||
LEFT OUTER JOIN tblStockJournalPost {lockClause} ON tblStockJournal.StockJournalID = tblStockJournalPost.StockJournalID
|
||||
WHERE 1=1 ";
|
||||
|
||||
// build where clause based on provided filters
|
||||
bool noFilter = true;
|
||||
if (stockJournalIds != null && stockJournalIds.Any())
|
||||
{
|
||||
sql += sqlWhere.InClause("tblStockJournal.StockJournalID", stockJournalIds, "AND");
|
||||
noFilter = false;
|
||||
}
|
||||
if (stockIds != null && stockIds.Any())
|
||||
{
|
||||
sql += sqlWhere.InClause("tblStockJournal.StockID", stockIds, "AND");
|
||||
noFilter = false;
|
||||
}
|
||||
if (stockNumbers != null && stockNumbers.Any())
|
||||
{
|
||||
List<int> stockNumbersInt = ConvertStockNumbers(stockNumbers);
|
||||
sql += sqlWhere.InClause("tblStock.StockNumber", stockNumbersInt, "AND");
|
||||
noFilter = false;
|
||||
}
|
||||
if (minEntryDate.HasValue)
|
||||
{
|
||||
sql += sqlWhere.IsEqualToOrGreaterThanClause("tblStockJournal.EntryDate", minEntryDate.Value.ToUniversalTime(), "AND");
|
||||
noFilter = false;
|
||||
}
|
||||
if (maxEntryDate.HasValue)
|
||||
{
|
||||
sql += sqlWhere.IsEqualToOrLessThanClause("tblStockJournal.EntryDate", maxEntryDate.Value.ToUniversalTime(), "AND");
|
||||
noFilter = false;
|
||||
}
|
||||
if (stockStatusIds != null && stockStatusIds.Any())
|
||||
{
|
||||
sql += sqlWhere.InClause(
|
||||
"StockStatusID"
|
||||
, stockStatusIds
|
||||
, " AND tblStockJournal.StockJournalID IN (SELECT StockJournalID FROM tblStockJournalPost WHERE "
|
||||
, " ) "
|
||||
);
|
||||
noFilter = false;
|
||||
}
|
||||
if (noFilter)
|
||||
{
|
||||
throw new ArgumentException("At least one filter must be provided for stock journal retrieval.");
|
||||
}
|
||||
|
||||
sql += " ORDER BY tblStockJournal.EntryDate, tblStockJournal.StockJournalID, tblStockJournalPost.StockJournalPostID;";
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText = sql;
|
||||
|
||||
if (sqlWhere.ParameterListIsSet)
|
||||
{
|
||||
sqlWhere.AddParametersToSqlCommand(cmd);
|
||||
}
|
||||
|
||||
using (var reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
int stockJournalId = reader.GetInt32(0);
|
||||
|
||||
// add header information, if not already in dictionary
|
||||
if (returnDict.ContainsKey(stockJournalId) == false)
|
||||
{
|
||||
// create new StockJournalBuilder
|
||||
var stockJournalBuilder = new Model.Stock.StockJournalBuilder
|
||||
{
|
||||
StockJournalId = stockJournalId,
|
||||
StockJournalTypeId = reader.GetInt32(1),
|
||||
StockId = reader.GetInt32(2),
|
||||
StockNumber = "STK#" + reader.GetInt32(3).ToString("D6"),
|
||||
EntryDate = DateTime.SpecifyKind(reader.GetDateTime(4), DateTimeKind.Utc),
|
||||
PostDate = DateTime.SpecifyKind(reader.GetDateTime(5), DateTimeKind.Utc),
|
||||
LastModified = DateTime.SpecifyKind(reader.GetDateTime(6), DateTimeKind.Utc),
|
||||
IsLocked = reader.GetBoolean(7),
|
||||
AccountIsProcessed = reader.GetBoolean(8),
|
||||
StockJournalBuilderPosts = new List<Model.Stock.StockJournalBuilder.StockJournalBuilderPost>()
|
||||
};
|
||||
returnDict.Add(stockJournalId, stockJournalBuilder);
|
||||
}
|
||||
|
||||
var stockJournalBuilderPost = new Model.Stock.StockJournalBuilder.StockJournalBuilderPost
|
||||
{
|
||||
StockJournalPostId = reader.GetInt32(9),
|
||||
StatusId = reader.GetInt32(10),
|
||||
Quantity = reader.GetInt32(11)
|
||||
};
|
||||
|
||||
returnDict[stockJournalId].StockJournalBuilderPosts.Add(stockJournalBuilderPost);
|
||||
}
|
||||
return returnDict;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Dictionary<int, (int id, string title, int? stockStatusIdDebit, int? stockStatusIdCredit)> ReadStockJournalType(List<int> stockJournalTypeIdList)
|
||||
{
|
||||
var returnDict = new Dictionary<int, (int id, string title, int? stockStatusIdDebit, int? stockStatusIdCredit)>();
|
||||
var sqlWhere = new SqlWhereBuilder();
|
||||
|
||||
string sql = @"
|
||||
SELECT StockJournalTypeID, TypeTitle, StockStatusID_Debit, StockStatusID_Credit
|
||||
FROM tblStockJournalType
|
||||
WHERE 1=1 ";
|
||||
|
||||
if (stockJournalTypeIdList != null && stockJournalTypeIdList.Any())
|
||||
{
|
||||
sql += sqlWhere.InClause("StockJournalTypeID", stockJournalTypeIdList, "AND");
|
||||
}
|
||||
|
||||
sql += ";";
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText = sql;
|
||||
|
||||
if (sqlWhere.ParameterListIsSet)
|
||||
{
|
||||
sqlWhere.AddParametersToSqlCommand(cmd);
|
||||
}
|
||||
|
||||
using (var reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
int stockJournalTypeId = reader.GetInt32(0);
|
||||
returnDict.Add(stockJournalTypeId, (
|
||||
id: stockJournalTypeId,
|
||||
title: reader.GetString(1),
|
||||
stockStatusIdDebit: reader.IsDBNull(2) ? (int?)null : reader.GetInt32(2),
|
||||
stockStatusIdCredit: reader.IsDBNull(3) ? (int?)null : reader.GetInt32(3)
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnDict;
|
||||
}
|
||||
|
||||
public (int, DateTime) ReadJournalStockIdAndEntryDate(int stockJournalId)
|
||||
{
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText = @"
|
||||
SELECT tblStockJournal.EntryDate, StockID
|
||||
FROM tblStockJournal
|
||||
WHERE (((tblStockJournal.StockJournalID)=@stockJournalId));";
|
||||
|
||||
cmd.Parameters.AddWithValue("@stockJournalId", stockJournalId);
|
||||
|
||||
using (var reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
return (reader.GetInt32(1), DateTime.SpecifyKind(reader.GetDateTime(0), DateTimeKind.Utc));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("StockJournalID=" + stockJournalId + " does not exist!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int ReadJournalTypeIdByStockId(int stockId)
|
||||
{
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText = @"
|
||||
SELECT tblStockJournal.StockJournalTypeID
|
||||
FROM tblStock INNER JOIN
|
||||
tblStockJournal ON tblStock.StockJournalID = tblStockJournal.StockJournalID
|
||||
WHERE (tblStock.StockID = @stockId);";
|
||||
|
||||
cmd.Parameters.AddWithValue("@stockId", stockId);
|
||||
|
||||
object obj = cmd.ExecuteScalar();
|
||||
|
||||
if (obj == null || obj == DBNull.Value)
|
||||
{
|
||||
throw new Exception("No stock journal type found for StockID=" + stockId);
|
||||
}
|
||||
|
||||
return (int)obj;
|
||||
}
|
||||
}
|
||||
|
||||
public int ReadStatusBalanceBySku(string sku, int statusId)
|
||||
{
|
||||
int statusBalance = new int();
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText = @"
|
||||
SELECT SUM(tblStockJournalPost.Quantity) AS Balance
|
||||
FROM tblStockJournal INNER JOIN
|
||||
tblStockJournalPost ON tblStockJournal.StockJournalID = tblStockJournalPost.StockJournalID INNER JOIN
|
||||
tblStock ON tblStockJournal.StockID = tblStock.StockID INNER JOIN
|
||||
tblSku ON tblStock.SkuID = tblSku.skuSkuID
|
||||
WHERE (tblStockJournalPost.StockStatusID = @statusId) AND (tblSku.skuSkuNumber = @sku);";
|
||||
|
||||
cmd.Parameters.AddWithValue("@sku", sku);
|
||||
cmd.Parameters.AddWithValue("@statusId", statusId);
|
||||
|
||||
// execute
|
||||
object obj = cmd.ExecuteScalar();
|
||||
if (obj == null || obj == DBNull.Value)
|
||||
{
|
||||
statusBalance = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
statusBalance = (int)obj;
|
||||
}
|
||||
}
|
||||
return statusBalance;
|
||||
}
|
||||
|
||||
public int ReadStatusBalanceByStockNumber(int stockNumber, int statusId)
|
||||
{
|
||||
int statusBalance = new int();
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText = @"
|
||||
SELECT SUM(tblStockJournalPost.Quantity) AS Balance
|
||||
FROM tblStockJournal INNER JOIN
|
||||
tblStockJournalPost ON tblStockJournal.StockJournalID = tblStockJournalPost.StockJournalID INNER JOIN
|
||||
tblStock ON tblStockJournal.StockID = tblStock.StockID
|
||||
WHERE (tblStockJournalPost.StockStatusID = @statusId) AND (tblStock.StockNumber = @stockNumber);";
|
||||
|
||||
cmd.Parameters.AddWithValue("@stockNumber", stockNumber);
|
||||
cmd.Parameters.AddWithValue("@statusId", statusId);
|
||||
|
||||
// execute
|
||||
object obj = cmd.ExecuteScalar();
|
||||
if (obj == null || obj == DBNull.Value)
|
||||
{
|
||||
statusBalance = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
statusBalance = (int)obj;
|
||||
}
|
||||
}
|
||||
return statusBalance;
|
||||
}
|
||||
|
||||
public int ReadStatusBalanceByStockId(int stockId, int statusId)
|
||||
{
|
||||
int statusBalance = new int();
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText = @"
|
||||
SELECT
|
||||
SUM(tblStockJournalPost.Quantity) AS Balance
|
||||
FROM
|
||||
tblStockJournal
|
||||
INNER JOIN tblStockJournalPost
|
||||
ON tblStockJournal.StockJournalID = tblStockJournalPost.StockJournalID
|
||||
WHERE
|
||||
(tblStockJournal.StockID = @stockId )
|
||||
AND (tblStockJournalPost.StockStatusID = @statusId );";
|
||||
|
||||
cmd.Parameters.AddWithValue("@stockId", stockId);
|
||||
cmd.Parameters.AddWithValue("@statusId", statusId);
|
||||
|
||||
// execute
|
||||
object obj = cmd.ExecuteScalar();
|
||||
if (obj == null || obj == DBNull.Value)
|
||||
{
|
||||
statusBalance = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
statusBalance = (int)obj;
|
||||
}
|
||||
}
|
||||
return statusBalance;
|
||||
}
|
||||
|
||||
public int ReadJournalEntryCountByStockId(int stockId)
|
||||
{
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText = @"
|
||||
SELECT Count(tblStockJournal.StockJournalID) AS CountOfStockJournalID
|
||||
FROM tblStockJournal
|
||||
WHERE (((tblStockJournal.StockID)=@stockId));";
|
||||
|
||||
cmd.Parameters.AddWithValue("@stockId", stockId);
|
||||
|
||||
return (int)cmd.ExecuteScalar();
|
||||
}
|
||||
}
|
||||
|
||||
public int? ReadTypeIdStatusCreditId(int stockJournalTypeId)
|
||||
{
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText = @"
|
||||
SELECT
|
||||
tblStockJournalType.StockStatusID_Credit
|
||||
FROM
|
||||
tblStockJournalType
|
||||
WHERE
|
||||
tblStockJournalType.StockJournalTypeID=@stockJournalTypeId
|
||||
AND tblStockJournalType.StockStatusID_Credit Is Not Null;";
|
||||
|
||||
cmd.Parameters.AddWithValue("@stockJournalTypeId", stockJournalTypeId);
|
||||
|
||||
object obj = cmd.ExecuteScalar();
|
||||
|
||||
if (obj == null || obj == DBNull.Value)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (int)obj;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public DateTime? ReadMostRecentEntryDateForStatusDebit(int stockId, List<int> stockStatusIdList)
|
||||
{
|
||||
if (stockId <= 0)
|
||||
{
|
||||
throw new ArgumentException("Stock ID must be greater than zero.", nameof(stockId));
|
||||
}
|
||||
if (stockStatusIdList == null || stockStatusIdList.Count == 0)
|
||||
{
|
||||
throw new ArgumentException("Stock status ID list cannot be null or empty.", nameof(stockStatusIdList));
|
||||
}
|
||||
|
||||
var sqlWhere = new SqlWhereBuilder();
|
||||
|
||||
// build sql string
|
||||
string stringSql = @"
|
||||
MAX (tblStockJournal.EntryDate) AS MostRecentEntryDate
|
||||
FROM
|
||||
tblStockJournal
|
||||
INNER JOIN tblStockJournalPost
|
||||
ON tblStockJournal.StockJournalID = tblStockJournalPost.StockJournalID
|
||||
WHERE
|
||||
tblStockJournal.StockID=@stockId
|
||||
AND tblStockJournalPost.Quantity>0 ";
|
||||
|
||||
stringSql += sqlWhere.InClause("tblStockJournalPost.StockStatusID", stockStatusIdList, "AND") + ";";
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = stringSql;
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
|
||||
cmd.Parameters.AddWithValue("@stockId", stockId);
|
||||
sqlWhere.AddParametersToSqlCommand(cmd);
|
||||
|
||||
object obj = cmd.ExecuteScalar();
|
||||
if (obj == null || obj == DBNull.Value)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return DateTime.SpecifyKind((DateTime)obj, DateTimeKind.Utc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// update
|
||||
//
|
||||
|
||||
|
||||
//
|
||||
// Delete
|
||||
//
|
||||
|
||||
public void StockJournalDelete(int stockJournalId)
|
||||
{
|
||||
// delete posts
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText = @"
|
||||
DELETE FROM tblStockJournalPost
|
||||
WHERE StockJournalID=@stockJournalId;";
|
||||
|
||||
cmd.Parameters.AddWithValue("@StockJournalId", stockJournalId);
|
||||
|
||||
// execute
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
// delete journal entry
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText = @"
|
||||
DELETE FROM tblStockJournal
|
||||
WHERE StockJournalID=@stockJournalId;";
|
||||
|
||||
// add parameters
|
||||
cmd.Parameters.AddWithValue("@stockJournalId", stockJournalId);
|
||||
|
||||
int count = cmd.ExecuteNonQuery();
|
||||
|
||||
if (count != 1)
|
||||
{
|
||||
throw new Exception("Failed to delete stock journal header.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,271 @@
|
||||
using bnhtrade.Core.Data.Database.Repository.Interface;
|
||||
using bnhtrade.Core.Data.Database.UnitOfWork;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Transactions;
|
||||
using static System.Formats.Asn1.AsnWriter;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Repository.Implementation
|
||||
{
|
||||
internal class StockRepository : _Base, IStockRepository
|
||||
{
|
||||
public StockRepository(IDbConnection connection, IDbTransaction transaction) : base(connection, transaction)
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// create
|
||||
//
|
||||
|
||||
public int InsertNewStock(int skuId, int accountJournalId)
|
||||
{
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText = @"
|
||||
INSERT INTO tblStock
|
||||
(SkuID, AccountJournalID)
|
||||
OUTPUT INSERTED.StockID
|
||||
VALUES
|
||||
(@skuId, @accountJournalId);";
|
||||
|
||||
cmd.Parameters.AddWithValue("@skuId", skuId);
|
||||
cmd.Parameters.AddWithValue("@accountJournalId", accountJournalId);
|
||||
|
||||
return (int)cmd.ExecuteScalar();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// read
|
||||
//
|
||||
|
||||
public int CountStockTableRecords(List<int> accountJournalId = null)
|
||||
{
|
||||
throw new NotImplementedException("This needs testing before use");
|
||||
|
||||
var sqlWhere = new SqlWhereBuilder();
|
||||
|
||||
string sql = @"
|
||||
SELECT Count(tblStock.StockID) AS CountOfID
|
||||
FROM tblStock
|
||||
WHERE 1=1 ";
|
||||
|
||||
if (accountJournalId != null)
|
||||
{
|
||||
sqlWhere.In("AccountJournalID", accountJournalId, "AND");
|
||||
}
|
||||
|
||||
if (sqlWhere.IsSetSqlWhereString)
|
||||
{
|
||||
sql += sqlWhere.SqlWhereString;
|
||||
}
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText = sql;
|
||||
|
||||
if (sqlWhere.ParameterListIsSet)
|
||||
{
|
||||
sqlWhere.AddParametersToSqlCommand(cmd);
|
||||
}
|
||||
|
||||
return (int)cmd.ExecuteScalar();
|
||||
}
|
||||
}
|
||||
|
||||
public int? ReadStockIdByAccountJournalId(int accountJournalId)
|
||||
{
|
||||
if (accountJournalId <= 0)
|
||||
{
|
||||
throw new ArgumentException("Account Journal ID must be greater than zero", nameof(accountJournalId));
|
||||
}
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText = @"
|
||||
SELECT StockID
|
||||
FROM tblStock
|
||||
WHERE AccountJournalID = @accountJournalId;
|
||||
";
|
||||
cmd.Parameters.AddWithValue("@accountJournalId", accountJournalId);
|
||||
|
||||
object obj = cmd.ExecuteScalar();
|
||||
|
||||
// unique index on tblStock.AccountJournalID ensures that this will return at most one row
|
||||
if (obj == null)
|
||||
{
|
||||
throw new Exception("AccountJournalID=" + accountJournalId + " does not exist.");
|
||||
}
|
||||
else if (obj == DBNull.Value)
|
||||
{
|
||||
return null; // no stock entry found
|
||||
}
|
||||
else
|
||||
{
|
||||
return (int)obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int? ReadStockJournalId(int stockId)
|
||||
{
|
||||
if (stockId <= 0)
|
||||
{
|
||||
throw new ArgumentException("Stock ID must be greater than zero", nameof(stockId));
|
||||
}
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText = @"
|
||||
SELECT StockJournalID
|
||||
FROM tblStock
|
||||
WHERE StockID=@stockId;;";
|
||||
|
||||
cmd.Parameters.AddWithValue("@stockId", stockId);
|
||||
object obj = cmd.ExecuteScalar();
|
||||
if (obj == null )
|
||||
{
|
||||
throw new Exception("StockID=" + stockId + " does not exist.");
|
||||
}
|
||||
else if (obj == DBNull.Value)
|
||||
{
|
||||
return null; // no stock journal entry
|
||||
}
|
||||
else
|
||||
{
|
||||
return (int)obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int? ReadAccountJournalId(int stockId)
|
||||
{
|
||||
if (stockId <= 0)
|
||||
{
|
||||
throw new ArgumentException("Stock ID must be greater than zero", nameof(stockId));
|
||||
}
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText = @"
|
||||
SELECT AccountJournalID
|
||||
FROM tblStock
|
||||
WHERE StockID=@stockId;";
|
||||
cmd.Parameters.AddWithValue("@stockId", stockId);
|
||||
object obj = cmd.ExecuteScalar();
|
||||
if (obj == null)
|
||||
{
|
||||
throw new Exception("StockID=" + stockId + " does not exist.");
|
||||
}
|
||||
else if (obj == DBNull.Value)
|
||||
{
|
||||
return null; // no account journal entry
|
||||
}
|
||||
else
|
||||
{
|
||||
return (int)obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// update
|
||||
//
|
||||
|
||||
public int UpdateAccountJournalId(int stockId, int? accountJournalID)
|
||||
{
|
||||
if (stockId <= 0)
|
||||
{
|
||||
throw new ArgumentException("Stock ID must be greater than zero", nameof(stockId));
|
||||
}
|
||||
|
||||
string sql = @"
|
||||
UPDATE
|
||||
tblStock
|
||||
SET
|
||||
AccountJournalID = @accountJournalID
|
||||
WHERE
|
||||
StockID = @stockId;";
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = sql;
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.Parameters.AddWithValue("@stockId", stockId);
|
||||
if (accountJournalID == null)
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@accountJournalID", DBNull.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@accountJournalID", accountJournalID);
|
||||
}
|
||||
|
||||
return cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
|
||||
public int UpdateStockJournalId(int stockId, int? stockJournalId)
|
||||
{
|
||||
if (stockId <= 0)
|
||||
{
|
||||
throw new ArgumentException("Stock ID must be greater than zero", nameof(stockId));
|
||||
}
|
||||
|
||||
string sql = @"
|
||||
UPDATE
|
||||
tblStock
|
||||
SET
|
||||
StockJournalID = @stockJournalId
|
||||
WHERE
|
||||
StockID = @stockId;";
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = sql;
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.Parameters.AddWithValue("@stockId", stockId);
|
||||
if (stockJournalId == null)
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@stockJournalId", DBNull.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@stockJournalId", stockJournalId);
|
||||
}
|
||||
|
||||
return cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// delete
|
||||
//
|
||||
|
||||
public int DeleteStock(int stockId)
|
||||
{
|
||||
if (stockId <= 0)
|
||||
{
|
||||
throw new ArgumentException("Stock ID must be greater than zero", nameof(stockId));
|
||||
}
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText = @"
|
||||
DELETE FROM tblStock
|
||||
WHERE StockID=@stockId;";
|
||||
cmd.Parameters.AddWithValue("@stockId", stockId);
|
||||
return cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
using Amazon.Runtime.Internal.Transform;
|
||||
using bnhtrade.Core.Data.Database._BoilerPlate;
|
||||
using bnhtrade.Core.Data.Database.Repository.Interface;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Repository.Implementation
|
||||
{
|
||||
internal class StockStatusRepository : _Base, IStockStatusRepository
|
||||
{
|
||||
public StockStatusRepository(IDbConnection connection, IDbTransaction transaction) : base(connection, transaction)
|
||||
{
|
||||
}
|
||||
|
||||
public Dictionary<int, Model.Stock.StatusBuilder> ReadStatus(List<int> statusIds = null, List<int> statusTypeIds = null)
|
||||
{
|
||||
var sqlBuilder = new SqlWhereBuilder();
|
||||
var returnList = new Dictionary<int, Model.Stock.StatusBuilder>();
|
||||
|
||||
//build sql query
|
||||
string sql = @"
|
||||
SELECT [StockStatusID]
|
||||
,[StatusCode]
|
||||
,[StockStatus]
|
||||
,[StockStatusTypeID]
|
||||
,[Reference]
|
||||
,[ForeignKeyID]
|
||||
,[IsCreditOnly]
|
||||
,[IsClosed]
|
||||
,[RecordCreated]
|
||||
FROM [e2A].[dbo].[tblStockStatus]
|
||||
WHERE 1=1 ";
|
||||
|
||||
// build the where statments
|
||||
if (statusIds.Any())
|
||||
{
|
||||
sqlBuilder.In("StockStatusID", statusIds, "AND");
|
||||
}
|
||||
if (statusTypeIds.Any())
|
||||
{
|
||||
sqlBuilder.In("StockStatusTypeID", statusTypeIds, "AND");
|
||||
}
|
||||
|
||||
// append where string to the sql
|
||||
if (sqlBuilder.IsSetSqlWhereString)
|
||||
{
|
||||
sql = sql + sqlBuilder.SqlWhereString;
|
||||
}
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = sql;
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
|
||||
if (sqlBuilder.ParameterListIsSet)
|
||||
{
|
||||
sqlBuilder.AddParametersToSqlCommand(cmd);
|
||||
}
|
||||
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
var statusBuilder = new Model.Stock.StatusBuilder
|
||||
{
|
||||
StatusId = reader.GetInt32(0),
|
||||
StatusCode = reader.IsDBNull(1) ? (int?)null : reader.GetInt32(1),
|
||||
StatusTitle = reader.GetString(2),
|
||||
StatusTypeId = reader.GetInt32(3),
|
||||
Reference = reader.IsDBNull(4) ? null : reader.GetString(4),
|
||||
ForeignKeyID = reader.IsDBNull(5) ? (int?)null : reader.GetInt32(5),
|
||||
IsCreditOnly = reader.GetBoolean(6),
|
||||
IsClosed = reader.GetBoolean(7),
|
||||
RecordCreated = DateTime.SpecifyKind(reader.GetDateTime(8), DateTimeKind.Utc)
|
||||
};
|
||||
|
||||
returnList.Add(statusBuilder.StatusId, statusBuilder);
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnList;
|
||||
}
|
||||
|
||||
public Dictionary<int, Model.Stock.StatusTypeBuilder> ReadStatusType(List<int> stockStatusTypeIds = null)
|
||||
{
|
||||
var returnDict = new Dictionary<int, Model.Stock.StatusTypeBuilder>();
|
||||
var sqlWhere = new SqlWhereBuilder();
|
||||
|
||||
string sql = @"
|
||||
SELECT [StockStatusTypeID]
|
||||
,[StatusTypeName]
|
||||
,[ForeignKeyType]
|
||||
,[ReferenceType]
|
||||
,[AccountChartOfID]
|
||||
FROM [e2A].[dbo].[tblStockStatusType]
|
||||
WHERE 1=1 ";
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = sql;
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
if (sqlWhere.ParameterListIsSet)
|
||||
{
|
||||
sqlWhere.AddParametersToSqlCommand(cmd);
|
||||
}
|
||||
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
var statusTypeBuilder = new Model.Stock.StatusTypeBuilder
|
||||
{
|
||||
StockStatusTypeID = reader.GetInt32(0),
|
||||
StatusTypeName = reader.GetString(1),
|
||||
ForeignKeyType = reader.IsDBNull(2) ? null : reader.GetString(2),
|
||||
ReferenceType = reader.IsDBNull(3) ? null : reader.GetString(3),
|
||||
AccountId = reader.GetInt32(4)
|
||||
};
|
||||
returnDict.Add(statusTypeBuilder.StockStatusTypeID, statusTypeBuilder);
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnDict;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Repository.Implementation
|
||||
{
|
||||
public abstract class _Base
|
||||
{
|
||||
protected readonly IDbConnection _connection;
|
||||
protected readonly IDbTransaction _transaction;
|
||||
|
||||
public _Base(IDbConnection connection, IDbTransaction transaction)
|
||||
{
|
||||
_connection = connection ?? throw new ArgumentNullException(nameof(connection));
|
||||
_transaction = transaction; // Transaction can be null if not needed for read-only ops
|
||||
// But for NEXT VALUE FOR, it implies a modification/dependency within a transaction
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
using bnhtrade.Core.Data.Database._BoilerPlate;
|
||||
using bnhtrade.Core.Data.Database.Repository.Interface;
|
||||
using FikaAmazonAPI.AmazonSpApiSDK.Models.FulfillmentOutbound;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Transactions;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Repository.Implementation
|
||||
{
|
||||
internal class _BoilerPlate : _Base, _IBoilerPlate
|
||||
{
|
||||
public _BoilerPlate(IDbConnection connection, IDbTransaction transaction) : base(connection, transaction)
|
||||
{
|
||||
}
|
||||
|
||||
public Dictionary<int, string> SelectByList(List<string> selectList)
|
||||
{
|
||||
var returnList = new Dictionary<int, string>();
|
||||
|
||||
// check input list for items
|
||||
if (selectList == null)
|
||||
{
|
||||
throw new ArgumentNullException("Method argument cannot be null");
|
||||
}
|
||||
|
||||
// build SQL string
|
||||
string sql = @"
|
||||
SELECT
|
||||
column01
|
||||
,column02
|
||||
FROM
|
||||
tblTable
|
||||
";
|
||||
|
||||
var sqlwhere = new Data.Database.SqlWhereBuilder();
|
||||
sqlwhere.In("column03", selectList, "WHERE");
|
||||
|
||||
sql = sql + sqlwhere.SqlWhereString;
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
cmd.CommandText = sql;
|
||||
|
||||
sqlwhere.AddParametersToSqlCommand(cmd);
|
||||
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
int id = reader.GetInt32(0);
|
||||
string data = reader.GetString(1);
|
||||
|
||||
returnList.Add(id, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnList;
|
||||
}
|
||||
|
||||
public int Insert()
|
||||
{
|
||||
string sql = @"
|
||||
INSERT INTO tblTable (
|
||||
column01
|
||||
,column02
|
||||
,column03
|
||||
,column04
|
||||
)
|
||||
OUTPUT INSERTED.TablePk
|
||||
VALUES (
|
||||
@value01
|
||||
,@value02
|
||||
,@value03
|
||||
,@value04
|
||||
)
|
||||
";
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = sql;
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
|
||||
cmd.Parameters.AddWithValue("@value01", "xxxxxxxx");
|
||||
cmd.Parameters.AddWithValue("@value02", "xxxxxxxx");
|
||||
cmd.Parameters.AddWithValue("@value03", "xxxxxxxx");
|
||||
cmd.Parameters.AddWithValue("@value04", "xxxxxxxx");
|
||||
|
||||
int newId = (int)cmd.ExecuteScalar();
|
||||
|
||||
return newId;
|
||||
}
|
||||
}
|
||||
|
||||
public int Update()
|
||||
{
|
||||
string sql = @"
|
||||
UPDATE
|
||||
tblTable
|
||||
SET
|
||||
column01 = @value01
|
||||
column02 = @value02
|
||||
column03 = @value03
|
||||
column04 = @value04
|
||||
WHERE
|
||||
column05 = @value05
|
||||
";
|
||||
|
||||
using (SqlCommand cmd = _connection.CreateCommand() as SqlCommand)
|
||||
{
|
||||
cmd.CommandText = sql;
|
||||
cmd.Transaction = _transaction as SqlTransaction;
|
||||
|
||||
cmd.Parameters.AddWithValue("@value01", "xxxxxxxx");
|
||||
cmd.Parameters.AddWithValue("@value02", "xxxxxxxx");
|
||||
cmd.Parameters.AddWithValue("@value03", "xxxxxxxx");
|
||||
cmd.Parameters.AddWithValue("@value04", "xxxxxxxx");
|
||||
cmd.Parameters.AddWithValue("@value04", "xxxxxxxx");
|
||||
|
||||
int recordsEffected = cmd.ExecuteNonQuery();
|
||||
|
||||
return recordsEffected;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Repository.Interface
|
||||
{
|
||||
internal interface IAccountCodeRepository
|
||||
{
|
||||
Dictionary<int, Model.Account.Account> ReadAccountCode(List<int> accountIdList = null, List<int> accountCodeList = null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Repository.Interface
|
||||
{
|
||||
internal interface IAccountJournalRepository
|
||||
{
|
||||
int InsertJournalHeader(int journalTypeId, DateTime entryDate, bool lockEntry = false);
|
||||
int InsertJournalPost(int accountJournalId, int accountChartOfId, decimal amountGbp);
|
||||
Dictionary<int, Model.Account.JournalBuilder> ReadJournalBuilder(List<int> journalIdList);
|
||||
DateTime ReadJournalEntryDate(int journalId);
|
||||
int CountJournalPosts(int accountJournalId);
|
||||
bool IsJournalDebitAssetType(int accountJournalId);
|
||||
bool? IsJournalLocked(int journalId);
|
||||
List<(int, string, int?, int?)> ReadJournalType(List<int> accountJournalTypeIds = null, List<string> typeTitles = null);
|
||||
(int?, int?) ReadJournalTypeDefaultDebitCredit(int accountJournalId);
|
||||
bool UpdateJournalEntryModifiedDate(int accountJournalId);
|
||||
int DeleteJournalHeader(int accountJournalId);
|
||||
int DeleteJournalPostAll(int accountJournalId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Repository.Interface
|
||||
{
|
||||
internal interface IAccountTaxRepository
|
||||
{
|
||||
Dictionary<int, Model.Account.TaxCodeInfo> ReadTaxCodeInfo(bool? IsActive = null, List<string> taxcodeList = null, List<int> taxcodeIdList = null);
|
||||
Dictionary<string, string> GetTaxCodeBySkuNumber(List<string> skuNumberList);
|
||||
Dictionary<string, string> ReadTaxCodeByInvoiceLineItemCode(List<string> lineItemCode);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Repository.Interface
|
||||
{
|
||||
internal interface IAmazonSettlementRepository
|
||||
{
|
||||
List<Model.Import.AmazonSettlementHeader> ReadAmazonSettlementHeaderInfoBySettlementId(List<string> settlementIdList);
|
||||
|
||||
List<Model.Import.AmazonSettlementHeader> ReadAmazonSettlementHeaderInfoBySpapiReportId(List<string> spapiReportIdList);
|
||||
|
||||
Dictionary<int, Model.Import.AmazonSettlement> ReadAmazonSettlements(
|
||||
List<string> settlementIdList = null, List<string> marketPlaceNameList = null, bool? isProcessed = null,
|
||||
bool descendingOrder = false, int? returnTop = null);
|
||||
|
||||
bool UpdateAmazonSettlementMarketPlaceName(string settlementId, Model.Amazon.MarketPlaceEnum marketPlace);
|
||||
|
||||
int UpdateAmazonSettlementIsProcessed(List<string> settlementIdList, bool isProcessed);
|
||||
|
||||
bool CreateAmazonSettlements(string filePath, string reportId);
|
||||
|
||||
int SetSpapiReportId(string settlementId, string spapiReportId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Repository.Interface
|
||||
{
|
||||
internal interface ICurrencyRepository
|
||||
{
|
||||
public decimal? ReadExchangeRate(Model.Account.CurrencyCode currencyCode, DateTime date);
|
||||
public List<Model.Account.CurrencyExchangeRate> ReadExchangeRate(List<Model.Account.CurrencyCode> currencyCodeList = null, DateTime date = default(DateTime));
|
||||
public List<Model.Account.CurrencyExchangeRate> ReadExchangeRateLatest(List<Model.Account.CurrencyCode> currencyCodeList = null);
|
||||
public int InsertExchangeRate(int exchangeRateSource, Model.Account.CurrencyCode currencyCode,
|
||||
decimal currencyUnitsPerGbp, DateTime periodStartUtc, DateTime periodEnd, bool checkOverride = false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace bnhtrade.Core.Data.Database.Repository.Interface
|
||||
{
|
||||
internal interface IExportInvoiceRepository
|
||||
{
|
||||
Dictionary<int, Model.Account.SalesInvoice> InsertSalesInvoices(IEnumerable<Model.Account.SalesInvoice> invoiceList);
|
||||
Dictionary<int, string> GetNewInvoiceNumbers(Model.Account.InvoiceType invoiceType);
|
||||
Dictionary<int, Model.Account.SalesInvoice> GetSalesInvoiceById(IEnumerable<int> idList);
|
||||
int UpdateInvoiceHeaderDetail(int invoiceId, string invoiceNumber = null, bool? isComplete = null);
|
||||
int DeleteInvoiceLine(int invoiceLineId);
|
||||
int DeleteInvoice(IEnumerable<int> invoiceIdList);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user