diff --git a/StockHistory/Services/ISglStockEquityServices.cs b/StockHistory/Services/ISglStockEquityServices.cs index c8d83ec..9576b02 100644 --- a/StockHistory/Services/ISglStockEquityServices.cs +++ b/StockHistory/Services/ISglStockEquityServices.cs @@ -6,6 +6,7 @@ namespace StockHistory.Services { Task GenerateStockVision(); Task> GetAllAsync(); + List GetLatestSoldInfoAsync(); Task> GetAllAsync(DateTime equityDate); Task> GetByCodeAsync(string stockCode); } diff --git a/StockHistory/Services/IStockEquityServices.cs b/StockHistory/Services/IStockEquityServices.cs index 030f86e..0d92da8 100644 --- a/StockHistory/Services/IStockEquityServices.cs +++ b/StockHistory/Services/IStockEquityServices.cs @@ -6,6 +6,7 @@ namespace StockHistory.Services { Task> GenerateStockVision(); Task> GetAllAsync(); + Task> GetLatestSoldInfoAsync(); Task> GetAllAsync(DateTime equityDate); Task> GetByCodeAsync(string stockCode); } diff --git a/StockHistory/Services/ITransactionNotesServices.cs b/StockHistory/Services/ITransactionNotesServices.cs index 0ac07ec..8cbd514 100644 --- a/StockHistory/Services/ITransactionNotesServices.cs +++ b/StockHistory/Services/ITransactionNotesServices.cs @@ -6,6 +6,7 @@ namespace StockHistory.Services { Task AddAsync(TransactionNote transactionNote); Task DeleteAsync(int id); + Task> GetAllExistingStockCodes(); Task> GetAllAsync(); Task GetByIdAsync(int id); Task GetByIndexAsync(string stockCode, DateTime transDate); diff --git a/StockHistory/Services/SglStockEquityServices.cs b/StockHistory/Services/SglStockEquityServices.cs index 45bc147..46b71a7 100644 --- a/StockHistory/Services/SglStockEquityServices.cs +++ b/StockHistory/Services/SglStockEquityServices.cs @@ -36,6 +36,27 @@ namespace StockHistory.Services .OrderBy(s => s.Bought) .ToListAsync(); } + + public List GetLatestSoldInfoAsync() + { + var today = DateTime.Today; + + var query = + from s in _dbContext.SglStocks + where s.Sold < today + group s by s.StockCode into g + let maxSold = g.Max(x => x.Sold) + let minBought = g.Where(x => x.Sold == maxSold).Min(x => x.BoughtPrice) + from row in g + where row.Sold == maxSold && row.BoughtPrice == minBought + select row; + + var result = query.ToList(); + + return result; + + } + /// /// Skapar en ny lista med aktieinnehav baserat på transaktionsnoteringar. /// Den rensar först den befintliga listan och bygger sedan upp den igen genom att diff --git a/StockHistory/Services/StockEquityServices.cs b/StockHistory/Services/StockEquityServices.cs index 56336eb..07fde43 100644 --- a/StockHistory/Services/StockEquityServices.cs +++ b/StockHistory/Services/StockEquityServices.cs @@ -36,6 +36,48 @@ public class StockEquityServices : IStockEquityServices .OrderBy(s => s.Bought) .ToListAsync(); } + + public async Task> GetLatestSoldInfoAsync() + { + var today = DateTime.Today; + + var maxPerCode = _dbContext.Stocks + .Where(s => s.Sold < today) + .GroupBy(s => s.StockCode) + .Select(g => new { StockCode = g.Key, MaxSold = g.Max(x => x.Sold) }); + + var minBoughtPerCodeAndSold = _dbContext.Stocks + .Where(s => s.Sold < today) + .Join(maxPerCode, + s => new { s.StockCode, s.Sold }, + m => new { m.StockCode, Sold = m.MaxSold }, + (s, m) => new { s.StockCode, s.Sold, s.BoughtPrice }) + .GroupBy(x => new { x.StockCode, x.Sold }) + .Select(g => new { g.Key.StockCode, g.Key.Sold, MinBought = g.Min(x => (double)x.BoughtPrice) }); + + var result = from s in _dbContext.Stocks + where s.Sold < today + join mm in minBoughtPerCodeAndSold + on new { s.StockCode, s.Sold, BoughtPrice = (double)s.BoughtPrice } + equals new { mm.StockCode, Sold = mm.Sold, BoughtPrice = mm.MinBought } + select s; + + return await result.ToListAsync(); + + //var query = + // from s in _dbContext.Stocks + // where s.Sold < today + // group s by s.StockCode into g + // let maxSold = g.Max(x => x.Sold) + // let minBought = g.Where(x => x.Sold == maxSold).Min(x => x.BoughtPrice) + // from row in g + // where row.Sold == maxSold && row.BoughtPrice == minBought + // select row; + + //return await query.ToListAsync(); + + } + /// /// Skapar en ny lista med aktieinnehav baserat på transaktionsnoteringar. /// Den rensar först den befintliga listan och bygger sedan upp den igen genom att diff --git a/StockHistory/Services/TransactionNotesServices.cs b/StockHistory/Services/TransactionNotesServices.cs index b22da15..2f76e85 100644 --- a/StockHistory/Services/TransactionNotesServices.cs +++ b/StockHistory/Services/TransactionNotesServices.cs @@ -48,6 +48,18 @@ public class TransactionNotesServices : ITransactionNotesServices return await _dbContext.TransactionNotes.Where(t => t.StockCode == stockCode).ToListAsync(); } + public async Task> GetAllExistingStockCodes() + { + List stockCodes = new List(); + stockCodes = await _dbContext.TransactionNotes + .Select(t => t.StockCode) + .Distinct() + .ToListAsync(); + + return stockCodes; + } + + public async Task AddAsync(TransactionNote transactionNote) { using var scope = _provider.CreateScope(); diff --git a/StockHistory/frmStockHistoryAnalyse.cs b/StockHistory/frmStockHistoryAnalyse.cs index 8d4bb85..0a9afda 100644 --- a/StockHistory/frmStockHistoryAnalyse.cs +++ b/StockHistory/frmStockHistoryAnalyse.cs @@ -7,12 +7,16 @@ namespace StockHistory; public partial class frmStockHistoryAnalyse : Form { private readonly IStockEquityServices _equityServices; + private readonly ITransactionNotesServices _transactionNotesServices; + List stockList = new(); - public frmStockHistoryAnalyse(IStockEquityServices equityServices) + public frmStockHistoryAnalyse(IStockEquityServices equityServices, ITransactionNotesServices transactionNotesServices) { InitializeComponent(); _equityServices = equityServices; + _transactionNotesServices = transactionNotesServices; lwStocks.EnableSmartSorting(); + lwStockHistory.EnableSmartSorting(); } @@ -38,6 +42,8 @@ public partial class frmStockHistoryAnalyse : Form private async Task LoadStockListAsync(DateTime equityDate) { + stockList = await _transactionNotesServices.GetAllExistingStockCodes(); + var stocks = await _equityServices.GetAllAsync(equityDate); // var stocks = await _equityServices.GetAllAsync(); @@ -57,8 +63,11 @@ public partial class frmStockHistoryAnalyse : Form { if (t.StockCode != equityTemp.StockCode) { + stockList.Remove(t.StockCode); + if (equityTemp.StockCode != "Total") { + var item = new ListViewItem(equityTemp.StockCode); item.SubItems.Add(equityTemp.Bought.ToString()); item.SubItems.Add(equityTemp.Quantity.ToString()); @@ -87,6 +96,7 @@ public partial class frmStockHistoryAnalyse : Form l_item.SubItems.Add(equityTemp.Quantity.ToString()); l_item.SubItems.Add(equityTemp.BoughtPrice.ToString()); l_item.SubItems.Add((equityTemp.TotalValue).ToString("C")); + stockList.Remove(l_item.Text); lwStocks.Items.Add(l_item); } @@ -100,10 +110,7 @@ public partial class frmStockHistoryAnalyse : Form } } - private void btnStockHistory_Click(object sender, EventArgs e) - { - } private void lwStocks_MouseClick(object sender, MouseEventArgs e) { @@ -159,4 +166,35 @@ public partial class frmStockHistoryAnalyse : Form } lwStockHistory.Refresh(); } + + private async void btnStockHistory_Click(object sender, EventArgs e) + { + + // var stockList = _transactionNotesServices.GetAllExistingStockCodes(); + + var histRecs = await _equityServices.GetLatestSoldInfoAsync(); + if (histRecs != null) + { + lblVarning.Visible = false; + + lwStockHistory.Items.Clear(); + foreach (var histRec in histRecs) + { + if (stockList.Contains(histRec.StockCode)) + { + var l_item = new ListViewItem(histRec.StockCode); + l_item.SubItems.Add(histRec.Bought.ToString()); + l_item.SubItems.Add(histRec.Quantity.ToString()); + l_item.SubItems.Add(histRec.BoughtPrice.ToString()); + Debug.WriteLine(histRec.ToString()); + var totval = (histRec.SoldQuant > 0) ? histRec.SoldQuant * histRec.SoldPrice - histRec.BoughtPrice * histRec.Quantity : histRec.BoughtPrice * histRec.Quantity; + l_item.SubItems.Add((totval).ToString("C")); + l_item.SubItems.Add((histRec.SoldQuant > 0) ? "B" : "K"); + lwStockHistory.Items.Add(l_item); + stockList.Remove(histRec.StockCode); + } + } + } + lwStockHistory.Refresh(); + } } diff --git a/StockHistory/frmStockHistoryInit.cs b/StockHistory/frmStockHistoryInit.cs index 98aea46..7b0277b 100644 --- a/StockHistory/frmStockHistoryInit.cs +++ b/StockHistory/frmStockHistoryInit.cs @@ -285,6 +285,7 @@ public partial class frmStockHistoryInit : Form } if (line.StartsWith("Kurs")) { + trans.Currency = line.Split(" ", StringSplitOptions.RemoveEmptyEntries)[1]; trans.StockPrice = decimal.Parse(line.Split(" ", StringSplitOptions.RemoveEmptyEntries)[2]); } if (line.StartsWith("Antal"))