diff --git a/StockTransToDB/DbConnections/SqliteDbConnectionFactory.cs b/StockTransToDB/DbConnections/SqliteDbConnectionFactory.cs new file mode 100644 index 0000000..73b6890 --- /dev/null +++ b/StockTransToDB/DbConnections/SqliteDbConnectionFactory.cs @@ -0,0 +1,25 @@ +using Microsoft.Data.Sqlite; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StockTransToDB.DbConnections +{ + public class SqliteDbConnectionFactory + { + private string? _connectionString; + + public SqliteDbConnectionFactory(string? connectionString) + { + _connectionString = connectionString; + } + + public IDbConnection Connect() + { + return new SqliteConnection(_connectionString); + } + } +} diff --git a/StockTransToDB/DbInitializers/ISqliteDbInitializer.cs b/StockTransToDB/DbInitializers/ISqliteDbInitializer.cs new file mode 100644 index 0000000..f08577c --- /dev/null +++ b/StockTransToDB/DbInitializers/ISqliteDbInitializer.cs @@ -0,0 +1,7 @@ +namespace StockTransToDB.DbInitializers +{ + public interface ISqliteDbInitializer + { + void Initialize(); + } +} \ No newline at end of file diff --git a/StockTransToDB/DbInitializers/SqliteDbInitializer.cs b/StockTransToDB/DbInitializers/SqliteDbInitializer.cs new file mode 100644 index 0000000..b17d8cb --- /dev/null +++ b/StockTransToDB/DbInitializers/SqliteDbInitializer.cs @@ -0,0 +1,43 @@ +using Dapper; +using Microsoft.Extensions.Logging; +using StockTransToDB.DbConnections; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StockTransToDB.DbInitializers +{ + public class SqliteDbInitializer : ISqliteDbInitializer + { + private const string INIT_TABLE = @" + CREATE TABLE [NewBackupRegings] ( + [Id] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL + , [BackedUp] text NOT NULL + , [DbName] + text NULL + , [BackupDbName] text NULL + , [BackupPath] text NULL + )"; + + private readonly SqliteDbConnectionFactory _sqliteDbConnectionFactory; + private readonly ILogger _log; + + public SqliteDbInitializer(SqliteDbConnectionFactory sqliteDbConnectionFactory, ILogger log) + { + _sqliteDbConnectionFactory = sqliteDbConnectionFactory; + _log = log; + } + + public void Initialize() + { + _log.LogInformation(INIT_TABLE); + using (IDbConnection database = _sqliteDbConnectionFactory.Connect()) + { + database.Execute(INIT_TABLE); + } + } + } +} diff --git a/StockTransToDB/Program.cs b/StockTransToDB/Program.cs new file mode 100644 index 0000000..89d44c7 --- /dev/null +++ b/StockTransToDB/Program.cs @@ -0,0 +1,74 @@ +// See https://aka.ms/new-console-template for more information +// +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Newtonsoft.Json; +using ReadSBAktieTrans; +using Serilog; +using StockTransToDB.DbConnections; +using StockTransToDB.DbInitializers; +using StockTransToDB.models; +using StockTransToDB.Runners; +using StockTransToDB.StocksProviders; + +var builder = new ConfigurationBuilder(); +BuildConfig(builder); + +Log.Logger = new LoggerConfiguration() + .ReadFrom.Configuration(builder.Build()) + .Enrich.FromLogContext() + .WriteTo.Console() + .CreateLogger(); + +var host = Host.CreateDefaultBuilder() + .ConfigureServices((hostContext, services) => + { + services.AddSingleton(); + string connectionString = hostContext.Configuration.GetConnectionString("Default"); + services.AddSingleton(new SqliteDbConnectionFactory(connectionString)); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + }) + .UseSerilog() + .Build(); + +ProcName.RunIdent = "new"; +var svc = ActivatorUtilities.CreateInstance(host.Services); +svc.FetchJsonData(); +//await svc.StockNameTable(); +//foreach (var x in svc.NameConverter) +//{ +// Console.WriteLine(x.ToString()); +//} + +//var sdi = host.Services.GetRequiredService(); +//sdi.Initialize(); + +//var dsp = host.Services.GetRequiredService(); +//var recs = await dsp.GetAllStocks(); + +//foreach (var stock in recs) +//{ +// Log.Logger.Information($"{stock.Id} " + +// $"{stock.StockId} " + +// $"{stock.StockExtId} " + +// $"{stock.ActValue} " + +// $"{stock.BuyValue} " + +// $"{stock.BuyDate} " + +// $"{stock.SoldDate} " + +// $"{stock.SoldValue} " + +// $"{stock.ActAmount} " + +// $"{stock.Comment} "); +//} + +static void BuildConfig(IConfigurationBuilder builder) +{ + builder.SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) + .AddJsonFile($"appsettings{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", optional: true) + .AddEnvironmentVariables(); +} + + diff --git a/StockTransToDB/Properties/launchSettings.json b/StockTransToDB/Properties/launchSettings.json new file mode 100644 index 0000000..6940015 --- /dev/null +++ b/StockTransToDB/Properties/launchSettings.json @@ -0,0 +1,8 @@ +{ + "profiles": { + "StockTransToDB": { + "commandName": "Project", + "nativeDebugging": true + } + } +} \ No newline at end of file diff --git a/StockTransToDB/Runners/FileDataCreator.cs b/StockTransToDB/Runners/FileDataCreator.cs new file mode 100644 index 0000000..2c61a58 --- /dev/null +++ b/StockTransToDB/Runners/FileDataCreator.cs @@ -0,0 +1,78 @@ +using Newtonsoft.Json; +using StockTransToDB.models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Runtime.Serialization.Formatters.Binary; +using System.Text; +using System.Threading.Tasks; + +namespace ReadSBAktieTrans +{ + public class FileDataCreator : IFileDataCreator + { + public string CreateAndSave(Dictionary dataStore) + { + var FileModelList = new List(); + for (var i = 0; i < dataStore.Count - 1; i++) + { + var item = dataStore[i]; + var fmRec = CreateRecord(item); + FileModelList.Add(fmRec); + } + + var fileSaved = SaveUpdateFile(FileModelList); + return fileSaved; + } + + public IEnumerable CreateDataList(Dictionary dataStore) + { + var FileModelList = new List(); + for (var i = 0; i < dataStore.Count - 1; i++) + { + var item = dataStore[i]; + var fmRec = CreateRecord(item); + FileModelList.Add(fmRec); + } + return FileModelList; + } + + private FileModel CreateRecord(string[] item) + { + var record = new FileModel(); + record.Bokföringsdag = DateTime.Parse(item[0]); + record.Affärsdag = DateTime.Parse(item[1]); + record.Likviddag = DateTime.Parse(item[2]); + record.Valuta = item[3]; + record.ISIN = item[4]; + record.Transaktionstyp = item[5]; + record.Beskrivning = item[6]; + record.Specifikation = item[7]; + record.Antal = int.Parse(item[8] == "" ? "0" : item[8]); + record.Kurs = decimal.Parse(item[9] == "" ? "0" : item[9]); + record.Belopp = decimal.Parse(item[10] == "" ? "0" : item[10]); + record.Saldo = decimal.Parse(item[11] == "" ? "0" : item[11]); + return record; + } + + private string SaveUpdateFile(List DumpObjects) + { + var output = JsonConvert.SerializeObject(DumpObjects, Formatting.Indented); + // Assembly assem = typeof(ReadSBAktieTrans).Assembly; + Assembly assem = Assembly.GetExecutingAssembly(); + var programPath = assem.Location.Substring(0, assem.Location.LastIndexOf("\\")); + var DataPath = new DirectoryInfo(programPath + "\\DataFiles"); + if (!DataPath.Exists) + { + DataPath.Create(); + } + var outFileName = $"StockData{DateTime.Now.ToShortDateString()}.txt"; + File.WriteAllText($"{programPath}\\DataFiles\\{outFileName}", output); + Console.WriteLine($"Skapad fil: {outFileName}"); + return outFileName; + } + + + } +} diff --git a/StockTransToDB/Runners/FileToJson.cs b/StockTransToDB/Runners/FileToJson.cs new file mode 100644 index 0000000..4c4d923 --- /dev/null +++ b/StockTransToDB/Runners/FileToJson.cs @@ -0,0 +1,346 @@ +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; +using ReadSBAktieTrans; +using StockTransToDB.models; +using StockTransToDB.StocksProviders; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Diagnostics.Metrics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StockTransToDB.Runners +{ + public class FileToJson : IFileToJson + { + //private const string BYTE_INLAGG_VP = "BYTE INLÄGG VP"; + //private const string BYTE_UTTAG_VP = "BYTE UTTAG VP"; + //private const string DECIMALER_LIKVID = "DECIMALER LIKVID"; + //private const string DECIMALER_UTTAG_VP = "DECIMALER UTTAG VP"; + //private const string INLAGG_FISSION = "INLÄGG FISSION"; + //private const string INLOSEN_LIKVID = "INLÖSEN LIKVID"; + //private const string INLOSEN_UTTAG_VP = "INLÖSEN UTTAG VP"; + //private const string INSATTNING = "INSÄTTNING"; + //private const string KOPT = "KÖPT"; + //private const string SPLIT_INLÄGG_VP = "SPLIT INLÄGG VP"; + //private const string SPLIT_UTTAG_VP = "SPLIT UTTAG VP"; + //private const string SALT = "SÅLT"; + //private const string UTDELNING = "UTDELNING"; + //private const string UTL_KUPSKATT = "UTL KUPSKATT"; + //private const string UTTAG = "UTTAG"; + + private readonly ILogger _log; + private readonly IConfiguration _config; + private readonly IDapperStocksProvider _dapperStocksProvider; + private readonly IFileDataCreator _fileDataCreator; + + public Dictionary NameConverter { get; set; } = new Dictionary(); + public FileToJson(ILogger log, + IConfiguration config, + IDapperStocksProvider dapperStocksProvider, + IFileDataCreator fileDataCreator) + { + _log = log; + _config = config; + _dapperStocksProvider = dapperStocksProvider; + _fileDataCreator = fileDataCreator; + } + public async Task> FetchJsonData() + { + + _log.LogInformation("Starting ReadSBAktieTrans reading from xls!"); + string fileName = @$"C:\Users\tommy\Downloads\" + _config.GetValue("TransFile").Trim(); + _log.LogInformation($"Inläst fil : {fileName}"); + + string contents = File.ReadAllText(fileName, System.Text.Encoding.Latin1); + string[] records = contents.Split("\r\n"); + _log.LogInformation($"{records.Count()} records read"); + + + Dictionary dataStore = new Dictionary(); + var rNr = 0; + foreach (var record in records.Skip(1).ToArray()) + { + var fieldArr = record.Split("\t"); + dataStore.Add(rNr++, fieldArr); + } + + var fileModelList = _fileDataCreator.CreateDataList(dataStore).ToList(); + + + _log.LogInformation("InLäsning klar!"); + + Console.WriteLine("Create Name Converter ?"); + var answ = Console.ReadLine(); + + if (answ == "Y" || answ == "J") + { + await PrepareNameConverter(fileModelList); + } + + await UpDateNameConverter(); + + + Console.WriteLine("Show data ?"); + answ = Console.ReadLine(); + + if (answ == "ok") + { + foreach (var rec in fileModelList) + { + Console.WriteLine($"Bokföringsdag {rec.Bokföringsdag} Affärsdag {rec.Affärsdag} Likviddag {rec.Likviddag}"); + } + } + + var skrivna = 0; + foreach (var rec in fileModelList) + { + if (rec.Transaktionstyp == ProcName.KOPT) + { + try + { + var stockmember = new StockMember(); + stockmember.StockId = NameConverter[rec.Beskrivning.Trim()]; + stockmember.StockExtId = NameConverter[rec.Beskrivning.Trim()]; + stockmember.BuyValue = rec.Kurs; + stockmember.BuyDate = rec.Affärsdag; + stockmember.ActValue = rec.Kurs; + stockmember.ActDate = rec.Affärsdag; + stockmember.ActAmount = rec.Antal; + stockmember.SoldValue = 0; + stockmember.SoldDate = null; + stockmember.Comment = $"{ProcName.RunIdent}from trans"; + stockmember.PostAmount = rec.Antal; + stockmember.SoldStockPrice = 0; + + _dapperStocksProvider.AddStock(stockmember); + skrivna++; + + } + catch (Exception e) + { + _log.LogError(e.Message, e.StackTrace); + } + } + } + + _log.LogInformation($"Köpta klart {skrivna} st skrivna"); + skrivna = 0; + foreach (var rec in fileModelList) + { + if (rec.Transaktionstyp == ProcName.SPLIT_INLÄGG_VP) + { + UpDateWithSplitPlus(rec); + + skrivna++; + } + + if (rec.Transaktionstyp == ProcName.SPLIT_UTTAG_VP) + { + UpDateWithSplitMinus(rec); + + skrivna++; + } + + } + + _log.LogInformation($"Split update {skrivna} st skrivna"); + + skrivna = 0; + foreach (var rec in fileModelList) + { + if (rec.Transaktionstyp == ProcName.SALT) + { + UpDateWithSold(rec); + + skrivna++; + } + } + _log.LogInformation($"Sålda klart {skrivna} st skrivna"); + + + await _dapperStocksProvider.ResetCommentsFromNew(); + _log.LogInformation($"Comments restored"); + + return fileModelList; + + + } + + + + private async Task PrepareNameConverter(List recList) + { + var tempListNew = new HashSet(); + await _dapperStocksProvider.CleanStockNames(); + + foreach (var rec in recList) + { + if (rec.Transaktionstyp == ProcName.KOPT) + { + try + { + tempListNew.Add(rec.Beskrivning); + } + catch (Exception) + { + _log.LogInformation($"Dublett : {rec.Beskrivning}"); + } + } + } + + var templist = await _dapperStocksProvider.GetStockNames(); + foreach (var webName in templist) + { + _log.LogInformation($"Upplägg : {webName}, --"); + await _dapperStocksProvider.AddWebStockNames(webName); + } + + foreach (var newName in tempListNew) + { + //var founds = templist.Where(t => t.StartsWith(newName.Substring(0, 3))).ToList(); + var founds = await _dapperStocksProvider.GetStockNamesByPart(newName.Substring(0, 3)); + if (founds.Any()) + { + if (founds.Count() > 1) + { + var choseNr = 0; + Console.WriteLine($"{newName} skall passas ihop med en av nedan nr:"); + Console.WriteLine(); + foreach (var found in founds) + { + Console.WriteLine($"välj {choseNr++} for {found}"); + } + Console.WriteLine(); + Console.Write("Chose a number: "); + var valNumber = Console.ReadLine(); + if (int.Parse(valNumber) < 0) + { + Console.WriteLine($"{newName} skall passas ihop med ?"); + Console.WriteLine(); + Console.Write("Write the correct name: "); + var stockName = Console.ReadLine(); + await _dapperStocksProvider.UpdateStockName(newName, stockName); + } + else + { + await _dapperStocksProvider.UpdateStockName(newName, founds[int.Parse(valNumber)]); + } + } + else + { + await _dapperStocksProvider.UpdateStockName(newName, founds[0]); + } + } + else + { + Console.WriteLine($"{newName} skall passas ihop med ?"); + Console.WriteLine(); + Console.Write("Write the correct name: "); + var valNumber = Console.ReadLine(); + await _dapperStocksProvider.UpdateStockName(newName, valNumber); + } + } + + } + private async void UpDateWithSplitMinus(FileModel rec) + { + var members = await _dapperStocksProvider.GetStocksByStockIdPart(rec.Beskrivning, rec.Affärsdag); + var remainingInit = rec.Antal; + var remaining = rec.Antal; + foreach (var member in members) + { + if (remaining >= member.ActAmount) + { + remaining -= (int)member.ActAmount; + await _dapperStocksProvider.RemoveStockById(member.Id); + } + else + { + member.ActAmount -= remaining; + member.Comment += ",-Split"; + await _dapperStocksProvider.UpdateStock(member); + } + + _log.LogInformation($"Split {member.StockId} ({member.Id}) ändrad (minskad)"); + + if (remaining <= 0) + { + break; + } + } + } + + private async void UpDateWithSplitPlus(FileModel rec) + { + var members = await _dapperStocksProvider.GetStocksByStockIdPart( + rec.Beskrivning, rec.Affärsdag); + foreach (var member in members) + { + member.ActAmount += rec.Antal; + member.Comment += ", +split"; + + await _dapperStocksProvider.UpdateStock(member); + _log.LogInformation($"Split {member.StockId} ({member.Id}) ändrad (ökad)"); + + break; + } + } + + private async Task UpDateNameConverter() + { + var stockNameList = await _dapperStocksProvider.GetStockNameTable(); + NameConverter.Clear(); + foreach (var stockname in stockNameList) + { + try + { + NameConverter.Add(stockname.StockNameBank, stockname.StockNameWeb); + } + catch (Exception ex) + { + _log.LogError($"Namnkonvert {stockname} error {ex.Message}"); + } + } + } + + public async void UpDateWithSold(FileModel rec) + { + var members = await _dapperStocksProvider.GetStocksByStockId(NameConverter[rec.Beskrivning], rec.Affärsdag); + var remainingInit = rec.Antal; + var remaining = rec.Antal; + foreach (var member in members) + { + if (remaining >= member.ActAmount) + { + remaining -= (int)member.ActAmount; + member.SoldValue = ((int)member.ActAmount * rec.Belopp) / remainingInit; + member.ActAmount = 0; + } + else + { + member.ActAmount -= remaining; + member.SoldValue = (remaining * rec.Belopp) / remainingInit; + remaining = 0; + } + member.SoldDate = rec.Affärsdag; + member.Comment += ",Sold"; + member.SoldStockPrice = rec.Kurs; + + await _dapperStocksProvider.UpdateStock(member); + _log.LogInformation($"Såld {member.StockId} ({member.Id}) ändrad"); + + if (remaining <= 0) + { + break; + } + } + } + + + } +} \ No newline at end of file diff --git a/StockTransToDB/Runners/IFileDataCreator.cs b/StockTransToDB/Runners/IFileDataCreator.cs new file mode 100644 index 0000000..b9ba352 --- /dev/null +++ b/StockTransToDB/Runners/IFileDataCreator.cs @@ -0,0 +1,10 @@ +using StockTransToDB.models; + +namespace ReadSBAktieTrans +{ + public interface IFileDataCreator + { + string CreateAndSave(Dictionary dataStore); + IEnumerable CreateDataList(Dictionary dataStore); + } +} \ No newline at end of file diff --git a/StockTransToDB/Runners/IFileToJson.cs b/StockTransToDB/Runners/IFileToJson.cs new file mode 100644 index 0000000..6e53926 --- /dev/null +++ b/StockTransToDB/Runners/IFileToJson.cs @@ -0,0 +1,12 @@ +using StockTransToDB.models; + +namespace StockTransToDB.Runners +{ + public interface IFileToJson + { + Dictionary NameConverter { get; set; } + + Task> FetchJsonData(); + void UpDateWithSold(FileModel rec); + } +} \ No newline at end of file diff --git a/StockTransToDB/StockTransToDB.csproj b/StockTransToDB/StockTransToDB.csproj new file mode 100644 index 0000000..c8d1d21 --- /dev/null +++ b/StockTransToDB/StockTransToDB.csproj @@ -0,0 +1,30 @@ + + + + Exe + net6.0 + enable + enable + + + + + + + + + + + + + + + + + + + Always + + + + diff --git a/StockTransToDB/StocksProviders/DapperStocksProvider.cs b/StockTransToDB/StocksProviders/DapperStocksProvider.cs new file mode 100644 index 0000000..b978672 --- /dev/null +++ b/StockTransToDB/StocksProviders/DapperStocksProvider.cs @@ -0,0 +1,334 @@ +using Dapper; +using Microsoft.Extensions.Logging; +using StockTransToDB.DbConnections; +using StockTransToDB.models; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StockTransToDB.StocksProviders +{ + public class DapperStocksProvider : IDapperStocksProvider + { + private const string GET_ALL_STOCKS_SQL = @" + SELECT * + FROM Stocks + WHERE Substring(Comment,1,Length(@RunId))='@RunId'"; + + private const string ADD_NEW_STOCKMEMBER = @" + INSERT INTO STOCKS ( + StockId, + StockExtId, + BuyValue, + BuyDate, + ActValue, + ActDate, + ActAmount, + SoldValue, + SoldDate, + Comment, + PostAmount, + SoldStockPrice + ) + VALUES ( + @StockId, + @StockExtId, + @BuyValue, + @BuyDate, + @ActValue, + @ActDate, + @ActAmount, + @SoldValue, + @SoldDate, + @Comment, + @PostAmount, + @SoldStockPrice + )"; + + private const string UPDATE_STOCKMEMBER = @" + UPDATE Stocks + SET StockId = @StockId, + StockExtId = @StockExtId, + BuyValue = @BuyValue, + BuyDate = @BuyDate, + ActValue = @ActValue, + ActDate = @ActDate, + ActAmount = @ActAmount, + SoldValue = @SoldValue, + SoldDate = @SoldDate, + Comment = @Comment, + PostAmount = @PostAmount, + SoldStockPrice = @SoldStockPrice + WHERE Id = @Id"; + + private const string GET_STOCKS_BY_STOCKID = @" + SELECT * + FROM Stocks + WHERE StockId = @StockId + AND Substring(Comment,1,Length(@RunId))=@RunId + AND BuyDate <= @BuyDate + ORDER BY BuyDate DESC"; + + private const string GET_STOCKS_BY_STOCKIDPART = @" + SELECT * + FROM Stocks + WHERE Substring(StockId,1,@Length) = @StockIdPart + AND Substring(Comment,1,Length(@RunId))= @RunId + AND BuyDate <= @BuyDate + ORDER BY BuyDate DESC"; + + private const string ADD_TO_STOCKNAME = @" + Insert into StockNames (StockNameWeb, StockNameBank) + values ( @StockId, @StockId)"; + + private const string REMOVE_STOCKNAMES = @" + Delete + from StockNames"; + + private const string GET_WEB_STOCKNAMES = @" + select distinct StockId + from StocksOld"; + + private const string UPDATE_STOCKNAME_BANK = @" + UPDATE StockNames + SET StockNameBank = @StockNameBank + WHERE StockNameWeb = @StockNameWeb"; + + private const string GET_WEB_STOCKNAM_FULL = @" + SELECT * + FROM StockNames"; + + private const string WEB_STOCKNAMES_EXISTS = @" + SELECT CAST( + CASE WHEN EXISTS ( + SELECT 1 FROM StockNames WHERE StockNameWeb = @StockNameWeb) + THEN 1 ELSE 0 END as BIT)"; + + private const string DELETE_STOCK_BY_ID = @" + SELECT * + FROM Stocks + WHERE Id = @Id"; + + private const string STOCKNAMES_BY_PART = @" + select StockName from StockGroups + where StockName like @NamePart"; + + private const string RESET_STOCK_COMMENTS = @" + Update Stocks + set Comment = substring(Comment,4) + where Substring(Comment,1,Length(@RunId))=@RunId"; + + + + private readonly SqliteDbConnectionFactory _sqliteDbConnectionFactory; + private readonly ILogger _log; + + public DapperStocksProvider(SqliteDbConnectionFactory sqliteDbConnectionFactory, ILogger log) + { + _sqliteDbConnectionFactory = sqliteDbConnectionFactory; + _log = log; + } + public async Task AddStock(StockMember stockMember) + { + using (IDbConnection database = _sqliteDbConnectionFactory.Connect()) + { + _log.LogInformation("ADD_NEW_STOCKMEMBER"); + + object parameters = new + { + StockId = stockMember.StockId, + StockExtId = stockMember.StockExtId, + BuyValue = stockMember.BuyValue, + BuyDate = stockMember.BuyDate, + ActValue = stockMember.ActValue, + ActDate = stockMember.ActDate, + ActAmount = stockMember.ActAmount, + SoldValue = stockMember.SoldValue, + SoldDate = stockMember.SoldDate, + Comment = stockMember.Comment, + PostAmount = stockMember.PostAmount, + SoldStockPrice = stockMember.SoldStockPrice + }; + + await database.ExecuteAsync(ADD_NEW_STOCKMEMBER, parameters); + } + } + public async Task AddWebStockNames(string stockName) + { + using (IDbConnection database = _sqliteDbConnectionFactory.Connect()) + { + _log.LogInformation("ADD_TO_STOCKNAME"); + object parameters = new + { + StockId = stockName + }; + await database.ExecuteAsync(ADD_TO_STOCKNAME, parameters); + } + } + public async Task CleanStockNames() + { + using (IDbConnection database = _sqliteDbConnectionFactory.Connect()) + { + _log.LogInformation("REMOVE_STOCKNAMES"); + await database.ExecuteAsync(REMOVE_STOCKNAMES); + } + } + public async Task> GetAllStocks() + { + using (IDbConnection database = _sqliteDbConnectionFactory.Connect()) + { + _log.LogInformation(GET_ALL_STOCKS_SQL); + IEnumerable stockMembers = await database.QueryAsync(GET_ALL_STOCKS_SQL, new { RunId = ProcName.RunIdent }); + return stockMembers.ToList(); + } + } + public async Task> GetStockNames() + { + using (IDbConnection database = _sqliteDbConnectionFactory.Connect()) + { + _log.LogInformation("GET_WEB_STOCKNAMES"); + + IEnumerable stockNames = await database.QueryAsync(GET_WEB_STOCKNAMES); + return stockNames.ToList(); + } + } + public async Task> GetStocksByStockId(string stockId, DateTime Affärsdag) + { + using (IDbConnection database = _sqliteDbConnectionFactory.Connect()) + { + // Obs ta hänsyn till köpdatum + _log.LogInformation("GET_STOCKS_BY_STOCKID"); + + object parameters = new + { + StockId = stockId, + BuyDate = Affärsdag, + RunId = ProcName.RunIdent + }; + + IEnumerable stockMembers = await database.QueryAsync(GET_STOCKS_BY_STOCKID, parameters); + return stockMembers.ToList(); + } + } + + public async Task> GetStocksByStockIdPart(string stockIdPart, DateTime Affärsdag) + { + using (IDbConnection database = _sqliteDbConnectionFactory.Connect()) + { + // Obs ta hänsyn till köpdatum + _log.LogInformation("GET_STOCKS_BY_STOCKIDPART"); + var tmpstr = stockIdPart.Substring(0, stockIdPart.IndexOf(" ")); + object parameters = new + { + Length = tmpstr.Length, + StockIdPart = tmpstr, + BuyDate = Affärsdag, + RunId = ProcName.RunIdent + }; + + IEnumerable stockMembers = await database.QueryAsync(GET_STOCKS_BY_STOCKIDPART, parameters); + return stockMembers.ToList(); + } + } + public async Task UpdateStock(StockMember stockMember) + { + using (IDbConnection database = _sqliteDbConnectionFactory.Connect()) + { + + object parameters = new + { + Id = stockMember.Id, + StockId = stockMember.StockId, + StockExtId = stockMember.StockExtId, + BuyValue = stockMember.BuyValue, + BuyDate = stockMember.BuyDate, + ActValue = stockMember.ActValue, + ActDate = stockMember.ActDate, + ActAmount = stockMember.ActAmount, + SoldValue = stockMember.SoldValue, + SoldDate = stockMember.SoldDate, + Comment = stockMember.Comment, + PostAmount = stockMember.PostAmount, + SoldStockPrice = stockMember.SoldStockPrice + }; + + _log.LogInformation($"UPDATE_STOCKMEMBER {stockMember.Id} = {stockMember.StockId}"); + + await database.ExecuteAsync(UPDATE_STOCKMEMBER, parameters); + } + } + public async Task UpdateStockName(string stockNameBank, string stockNameWeb) + { + using (IDbConnection database = _sqliteDbConnectionFactory.Connect()) + { + + var exists = await database.ExecuteScalarAsync(WEB_STOCKNAMES_EXISTS, new { StockNameWeb = stockNameWeb }); + + if (!exists) + { + await AddWebStockNames(stockNameWeb); + } + + object parameters = new + { + StockNameBank = stockNameBank, + StockNameWeb = stockNameWeb, + }; + + _log.LogInformation($"UPDATE_STOCKNAME_BANK {stockNameBank} , {stockNameWeb}"); + + await database.ExecuteAsync(UPDATE_STOCKNAME_BANK, parameters); + } + } + + public async Task> GetStockNameTable() + { + using (IDbConnection database = _sqliteDbConnectionFactory.Connect()) + { + _log.LogInformation("GET_WEB_STOCKNAMES"); + + IEnumerable stockNames = await database.QueryAsync(GET_WEB_STOCKNAM_FULL); + return stockNames.ToList(); + } + } + + public async Task RemoveStockById(int id) + { + using (IDbConnection database = _sqliteDbConnectionFactory.Connect()) + { + // Obs ta hänsyn till köpdatum + _log.LogInformation("DELETE_STOCK_BY_ID"); + + await database.ExecuteAsync(DELETE_STOCK_BY_ID, new { Id = id }); + } + } + + + public async Task> GetStockNamesByPart(string idPart) + { + using (IDbConnection database = _sqliteDbConnectionFactory.Connect()) + { + _log.LogInformation("STOCKNAMES_BY_PART"); + + + var stockNames = await database.QueryAsync(STOCKNAMES_BY_PART, new { NamePart = "%" + idPart + "%" }); + return stockNames.ToList(); + } + } + + //RESET_STOCK_COMMENTS + public async Task ResetCommentsFromNew() + { + using (IDbConnection database = _sqliteDbConnectionFactory.Connect()) + { + // Obs ta hänsyn till köpdatum + _log.LogInformation("RESET_STOCK_COMMENTS"); + + await database.ExecuteAsync(RESET_STOCK_COMMENTS,new {RunId = ProcName.RunIdent }); + } + } + } +} diff --git a/StockTransToDB/StocksProviders/IDapperStocksProvider.cs b/StockTransToDB/StocksProviders/IDapperStocksProvider.cs new file mode 100644 index 0000000..2ad0a42 --- /dev/null +++ b/StockTransToDB/StocksProviders/IDapperStocksProvider.cs @@ -0,0 +1,21 @@ +using StockTransToDB.models; + +namespace StockTransToDB.StocksProviders +{ + public interface IDapperStocksProvider + { + Task AddStock(StockMember stockMember); + Task AddWebStockNames(string stockName); + Task CleanStockNames(); + Task> GetAllStocks(); + Task> GetStockNames(); + Task> GetStockNamesByPart(string idPart); + Task> GetStockNameTable(); + Task> GetStocksByStockId(string stockId, DateTime Affärsdag); + Task> GetStocksByStockIdPart(string stockIdPart, DateTime Affärsdag); + Task RemoveStockById(int id); + Task ResetCommentsFromNew(); + Task UpdateStock(StockMember stockMember); + Task UpdateStockName(string stockNameBank, string stockNameWeb); + } +} \ No newline at end of file diff --git a/StockTransToDB/appsettings.json b/StockTransToDB/appsettings.json new file mode 100644 index 0000000..c305d0d --- /dev/null +++ b/StockTransToDB/appsettings.json @@ -0,0 +1,16 @@ +{ + "TransFile": "Skandiabanken_transaktioner_insatsen.xls", + "StdFileName": "StockData2022-09-14.txt", + "Serilog": { + "MinimumLevel": { + "Default": "Information", + "Override": { + "Microsoft": "Information", + "System": "Warning" + } + } + }, + "ConnectionStrings": { + "Default": "Data source=C:\\Aktier\\net6.0-windows\\NewData\\Stocks.db" + } +} \ No newline at end of file diff --git a/StockTransToDB/models/Address.cs b/StockTransToDB/models/Address.cs new file mode 100644 index 0000000..327cb91 --- /dev/null +++ b/StockTransToDB/models/Address.cs @@ -0,0 +1,12 @@ +namespace StockTransToDB.models +{ + public class Address + { + public int Id { get; set; } + public string Street { get; set; } + public string Street2 { get; set; } + public int Zipcode { get; set; } + public string Destination { get; set; } + public string Nation { get; set; } + } +} \ No newline at end of file diff --git a/StockTransToDB/models/BackupRegister.cs b/StockTransToDB/models/BackupRegister.cs new file mode 100644 index 0000000..a6db411 --- /dev/null +++ b/StockTransToDB/models/BackupRegister.cs @@ -0,0 +1,11 @@ +namespace StockTransToDB.models +{ + public class BackupRegister + { + public int Id { get; set; } + public DateTime BackedUp { get; set; } + public string DbName { get; set; } + public string BackupDbName { get; set; } + public string BackupPath { get; set; } + } +} \ No newline at end of file diff --git a/StockTransToDB/models/DiTraderStockRow.cs b/StockTransToDB/models/DiTraderStockRow.cs new file mode 100644 index 0000000..4d3cc31 --- /dev/null +++ b/StockTransToDB/models/DiTraderStockRow.cs @@ -0,0 +1,16 @@ +namespace StockTransToDB.models +{ + public class DiTraderStockRow + { + public string StockName { get; set; } + public decimal ProcChange { get; set; } + public decimal RealChange { get; set; } + public decimal BuyPrice { get; set; } + public decimal SellPrice { get; set; } + public decimal LatestPrice { get; set; } + public decimal HighestPrice { get; set; } + public decimal LowestPrice { get; set; } + public long Volume { get; set; } + public TimeSpan TimeOfDay { get; set; } + } +} \ No newline at end of file diff --git a/StockTransToDB/models/FileModel.cs b/StockTransToDB/models/FileModel.cs new file mode 100644 index 0000000..3d5946f --- /dev/null +++ b/StockTransToDB/models/FileModel.cs @@ -0,0 +1,19 @@ +namespace StockTransToDB.models +{ + public class FileModel + { + public DateTime Bokföringsdag { get; set; } + public DateTime Affärsdag { get; set; } + public DateTime Likviddag { get; set; } + public string Valuta { get; set; } + public string ISIN { get; set; } + public string Transaktionstyp { get; set; } + public string Beskrivning { get; set; } + public string Specifikation { get; set; } + public int Antal { get; set; } + public decimal Kurs { get; set; } + public decimal Belopp { get; set; } + public decimal Saldo { get; set; } + + } +} \ No newline at end of file diff --git a/StockTransToDB/models/LatestSoldStock.cs b/StockTransToDB/models/LatestSoldStock.cs new file mode 100644 index 0000000..354f00d --- /dev/null +++ b/StockTransToDB/models/LatestSoldStock.cs @@ -0,0 +1,8 @@ +namespace StockTransToDB.models +{ + public class LatestSoldStock + { + public decimal SoldStockPrice { get; set; } + public DateTime? LatestSoldDate { get; set; } + } +} \ No newline at end of file diff --git a/StockTransToDB/models/Person.cs b/StockTransToDB/models/Person.cs new file mode 100644 index 0000000..f7ac27e --- /dev/null +++ b/StockTransToDB/models/Person.cs @@ -0,0 +1,16 @@ +namespace StockTransToDB.models +{ + public class Person + { + public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public string NickName { get; set; } + public string Born { get; set; } + public string Comments { get; set; } + public int HomeAddress { get; set; } + public int InvoiceAddress { get; set; } + public int ClearingNo { get; set; } + public long AccountNo { get; set; } + } +} \ No newline at end of file diff --git a/StockTransToDB/models/PersonStock.cs b/StockTransToDB/models/PersonStock.cs new file mode 100644 index 0000000..00ebb11 --- /dev/null +++ b/StockTransToDB/models/PersonStock.cs @@ -0,0 +1,11 @@ +namespace StockTransToDB.models +{ + public class PersonStock + { + public int Id { get; set; } + public int PersonId { get; set; } + public int StockId { get; set; } + public string Comment { get; set; } + + } +} \ No newline at end of file diff --git a/StockTransToDB/models/ProcName.cs b/StockTransToDB/models/ProcName.cs new file mode 100644 index 0000000..80f676a --- /dev/null +++ b/StockTransToDB/models/ProcName.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StockTransToDB.models +{ + public static class ProcName + { + public const string BYTE_INLAGG_VP = "BYTE INLÄGG VP"; + public const string BYTE_UTTAG_VP = "BYTE UTTAG VP"; + public const string DECIMALER_LIKVID = "DECIMALER LIKVID"; + public const string DECIMALER_UTTAG_VP = "DECIMALER UTTAG VP"; + public const string INLAGG_FISSION = "INLÄGG FISSION"; + public const string INLOSEN_LIKVID = "INLÖSEN LIKVID"; + public const string INLOSEN_UTTAG_VP = "INLÖSEN UTTAG VP"; + public const string INSATTNING = "INSÄTTNING"; + public const string KOPT = "KÖPT"; + public const string SPLIT_INLÄGG_VP = "SPLIT INLÄGG VP"; + public const string SPLIT_UTTAG_VP = "SPLIT UTTAG VP"; + public const string SALT = "SÅLT"; + public const string UTDELNING = "UTDELNING"; + public const string UTL_KUPSKATT = "UTL KUPSKATT"; + public const string UTTAG = "UTTAG"; + public static string RunIdent { get; set; } = "xx"; + } +} diff --git a/StockTransToDB/models/ShareModel.cs b/StockTransToDB/models/ShareModel.cs new file mode 100644 index 0000000..ead5312 --- /dev/null +++ b/StockTransToDB/models/ShareModel.cs @@ -0,0 +1,10 @@ +namespace StockTransToDB.models +{ + public class ShareModel + { + public int Id { get; set; } + public string GroupName { get; set; } + public string StockName { get; set; } + + } +} \ No newline at end of file diff --git a/StockTransToDB/models/StockGroupModel.cs b/StockTransToDB/models/StockGroupModel.cs new file mode 100644 index 0000000..56daebe --- /dev/null +++ b/StockTransToDB/models/StockGroupModel.cs @@ -0,0 +1,9 @@ +namespace StockTransToDB.models +{ + public class StockGroupModel + { + public int Id { get; set; } + public string StockGroup { get; set; } + public string StockName { get; set; } + } +} \ No newline at end of file diff --git a/StockTransToDB/models/StockGrpPers.cs b/StockTransToDB/models/StockGrpPers.cs new file mode 100644 index 0000000..65b3a91 --- /dev/null +++ b/StockTransToDB/models/StockGrpPers.cs @@ -0,0 +1,9 @@ +namespace StockTransToDB.models +{ + public class StockGrpPers + { + public string StockId { get; set; } + public string StockGroup { get; set; } + public int PersId { get; set; } + } +} \ No newline at end of file diff --git a/StockTransToDB/models/StockMember.cs b/StockTransToDB/models/StockMember.cs new file mode 100644 index 0000000..f5f97db --- /dev/null +++ b/StockTransToDB/models/StockMember.cs @@ -0,0 +1,27 @@ +namespace StockTransToDB.models +{ + public class StockMember + { + public int Id { get; set; } + public string StockId { get; set; } + public string StockExtId { get; set; } + public decimal BuyValue { get; set; } + public DateTime BuyDate { get; set; } + public decimal ActValue { get; set; } + public DateTime? ActDate { get; set; } + public long ActAmount { get; set; } + public decimal? SoldValue { get; set; } + public DateTime? SoldDate { get; set; } + // public string PostId { get; set; } + public string Comment { get; set; } + public long PostAmount { get; set; } + public decimal SoldStockPrice { get; set; } + + //public decimal PostValue + //{ + // get { return ActAmount * ActValue; } + //} + + + } +} \ No newline at end of file diff --git a/StockTransToDB/models/StockNames.cs b/StockTransToDB/models/StockNames.cs new file mode 100644 index 0000000..d95a61f --- /dev/null +++ b/StockTransToDB/models/StockNames.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StockTransToDB.models +{ + public class StockNames + { + public string StockNameWeb { get; set; } + public string StockNameBank { get; set; } + } +} diff --git a/StockTransToDBApp.sln b/StockTransToDBApp.sln new file mode 100644 index 0000000..752666b --- /dev/null +++ b/StockTransToDBApp.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.3.32825.248 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StockTransToDB", "StockTransToDB\StockTransToDB.csproj", "{5362240B-812B-4980-96AF-E1AADDE72C0B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5362240B-812B-4980-96AF-E1AADDE72C0B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5362240B-812B-4980-96AF-E1AADDE72C0B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5362240B-812B-4980-96AF-E1AADDE72C0B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5362240B-812B-4980-96AF-E1AADDE72C0B}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {0442A087-824F-4B88-AD24-C5D055CCD670} + EndGlobalSection +EndGlobal