Aktielista genereras och kan ses för valt datum i analysvy
This commit is contained in:
@ -25,5 +25,8 @@ public class AppDbContext : DbContext
|
||||
modelBuilder.Entity<StockEquity>()
|
||||
.HasIndex(s => new { s.Sold })
|
||||
.IsUnique(false);
|
||||
modelBuilder.Entity<StockEquity>()
|
||||
.HasIndex(s => new { s.Bought, s.StockCode, s.Quantity })
|
||||
.IsUnique(false);
|
||||
}
|
||||
}
|
||||
|
||||
102
StockHistory/Migrations/20260519083023_NewIndexInStockEquity.Designer.cs
generated
Normal file
102
StockHistory/Migrations/20260519083023_NewIndexInStockEquity.Designer.cs
generated
Normal file
@ -0,0 +1,102 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using StockHistory.Data;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace StockHistory.Migrations
|
||||
{
|
||||
[DbContext(typeof(AppDbContext))]
|
||||
[Migration("20260519083023_NewIndexInStockEquity")]
|
||||
partial class NewIndexInStockEquity
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "9.0.6");
|
||||
|
||||
modelBuilder.Entity("StockHistory.Models.StockEquity", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("Bought")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<decimal>("BoughtPrice")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Quantity")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("Sold")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<decimal>("SoldPrice")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("SoldQuant")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("StockCode")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("Bought");
|
||||
|
||||
b.HasIndex("Sold");
|
||||
|
||||
b.HasIndex("Bought", "StockCode", "Quantity");
|
||||
|
||||
b.ToTable("Stocks");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("StockHistory.Models.TransactionNote", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<decimal>("AmountToPay")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<decimal>("Commission")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("StockCode")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<decimal>("StockPrice")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("StockQuantity")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<decimal>("TotalAmount")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("TransactionDate")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("TransactionType")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("StockCode", "TransactionDate")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("TransactionNotes");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace StockHistory.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class NewIndexInStockEquity : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Stocks_Bought_StockCode_Quantity",
|
||||
table: "Stocks",
|
||||
columns: new[] { "Bought", "StockCode", "Quantity" });
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropIndex(
|
||||
name: "IX_Stocks_Bought_StockCode_Quantity",
|
||||
table: "Stocks");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -51,6 +51,8 @@ namespace StockHistory.Migrations
|
||||
|
||||
b.HasIndex("Sold");
|
||||
|
||||
b.HasIndex("Bought", "StockCode", "Quantity");
|
||||
|
||||
b.ToTable("Stocks");
|
||||
});
|
||||
|
||||
|
||||
@ -38,10 +38,11 @@ namespace StockHistory
|
||||
ServiceLifetime.Transient);
|
||||
|
||||
services.AddSingleton<frmStockHistoryInit>();
|
||||
services.AddScoped<frmStockHistoryAnalyse1>();
|
||||
services.AddScoped<frmStockHistoryAnalyse>();
|
||||
services.AddTransient<IPdfOpener, PdfOpener>();
|
||||
services.AddTransient<IPdfFormatter, PdfFormatter>();
|
||||
services.AddTransient<ITransactionNotesServices, TransactionNotesServices>();
|
||||
services.AddTransient<IStockEquityServices, StockEquityServices>();
|
||||
services.AddTransient<IHandleCsvNotes, HandleCsvNotes>();
|
||||
});
|
||||
|
||||
|
||||
11
StockHistory/Services/IStockEquityServices.cs
Normal file
11
StockHistory/Services/IStockEquityServices.cs
Normal file
@ -0,0 +1,11 @@
|
||||
using StockHistory.Models;
|
||||
|
||||
namespace StockHistory.Services
|
||||
{
|
||||
public interface IStockEquityServices
|
||||
{
|
||||
Task GenerateStockVision();
|
||||
Task<List<StockEquity>> GetAllAsync();
|
||||
Task<List<StockEquity>> GetAllAsync(DateTime equityDate);
|
||||
}
|
||||
}
|
||||
84
StockHistory/Services/StockEquityServices.cs
Normal file
84
StockHistory/Services/StockEquityServices.cs
Normal file
@ -0,0 +1,84 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using StockHistory.Data;
|
||||
using StockHistory.Models;
|
||||
|
||||
namespace StockHistory.Services;
|
||||
|
||||
public class StockEquityServices : IStockEquityServices
|
||||
{
|
||||
private readonly AppDbContext _dbContext;
|
||||
private readonly ITransactionNotesServices _notesServices;
|
||||
|
||||
public StockEquityServices(AppDbContext dbContext, ITransactionNotesServices notesServices)
|
||||
{
|
||||
_dbContext = dbContext;
|
||||
_notesServices = notesServices;
|
||||
}
|
||||
|
||||
public async Task<List<StockEquity>> GetAllAsync()
|
||||
{
|
||||
return await _dbContext.Stocks.ToListAsync();
|
||||
}
|
||||
public async Task<List<StockEquity>> GetAllAsync(DateTime equityDate)
|
||||
{
|
||||
return await _dbContext.Stocks
|
||||
.Where(s => s.Bought <= equityDate && s.Sold > equityDate)
|
||||
.ToListAsync();
|
||||
}
|
||||
public async Task GenerateStockVision()
|
||||
{
|
||||
var existingNotes = await _notesServices.GetAllAsync();
|
||||
// foreach (var note in await _notesServices.GetAllAsync())
|
||||
|
||||
foreach (var note in existingNotes)
|
||||
{
|
||||
if (note.TransactionType == null) { }
|
||||
else
|
||||
if (note.TransactionType.ToLower() == "köp")
|
||||
{
|
||||
var equity = new StockEquity
|
||||
{
|
||||
StockCode = note.StockCode,
|
||||
Bought = note.TransactionDate,
|
||||
BoughtPrice = note.StockPrice,
|
||||
Quantity = note.StockQuantity,
|
||||
Sold = DateTime.MinValue,
|
||||
SoldPrice = 0m,
|
||||
SoldQuant = 0
|
||||
};
|
||||
_dbContext.Stocks.Add(equity);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
else if (note.TransactionType.ToLower() == "sälj" || note.TransactionType.ToLower() == "försäljning")
|
||||
{
|
||||
var equity = await _dbContext.Stocks.FirstOrDefaultAsync(s => s.StockCode == note.StockCode && s.SoldQuant == 0);
|
||||
|
||||
if (equity != null)
|
||||
{
|
||||
if (note.StockQuantity < equity.Quantity)
|
||||
{
|
||||
var splitEquity = new StockEquity
|
||||
{
|
||||
StockCode = equity.StockCode,
|
||||
Bought = equity.Bought,
|
||||
BoughtPrice = equity.BoughtPrice,
|
||||
Quantity = equity.Quantity - Math.Abs(note.StockQuantity),
|
||||
Sold = DateTime.MinValue,
|
||||
SoldPrice = 0m,
|
||||
SoldQuant = 0
|
||||
};
|
||||
_dbContext.Stocks.Add(splitEquity);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
equity.Quantity = Math.Abs(note.StockQuantity);
|
||||
equity.Sold = note.TransactionDate;
|
||||
equity.SoldPrice = note.StockPrice;
|
||||
equity.SoldQuant = Math.Abs(note.StockQuantity);
|
||||
_dbContext.Stocks.Update(equity);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
146
StockHistory/frmStockHistoryAnalyse.Designer.cs
generated
Normal file
146
StockHistory/frmStockHistoryAnalyse.Designer.cs
generated
Normal file
@ -0,0 +1,146 @@
|
||||
namespace StockHistory
|
||||
{
|
||||
partial class frmStockHistoryAnalyse
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
lblHistAnalyseHeader = new Label();
|
||||
btnGenerateStockScheme = new Button();
|
||||
dtpChosenDate = new DateTimePicker();
|
||||
btnClose = new Button();
|
||||
lwStocks = new ListView();
|
||||
chStock = new ColumnHeader();
|
||||
chBought = new ColumnHeader();
|
||||
chPrize = new ColumnHeader();
|
||||
chNumber = new ColumnHeader();
|
||||
SuspendLayout();
|
||||
//
|
||||
// lblHistAnalyseHeader
|
||||
//
|
||||
lblHistAnalyseHeader.AutoSize = true;
|
||||
lblHistAnalyseHeader.Font = new Font("Segoe UI", 13F, FontStyle.Bold);
|
||||
lblHistAnalyseHeader.Location = new Point(22, 20);
|
||||
lblHistAnalyseHeader.Name = "lblHistAnalyseHeader";
|
||||
lblHistAnalyseHeader.Size = new Size(428, 25);
|
||||
lblHistAnalyseHeader.TabIndex = 0;
|
||||
lblHistAnalyseHeader.Text = "Analysera existerande Avräkningsnotor (Affärer)";
|
||||
//
|
||||
// btnGenerateStockScheme
|
||||
//
|
||||
btnGenerateStockScheme.BackColor = Color.Chartreuse;
|
||||
btnGenerateStockScheme.FlatStyle = FlatStyle.Flat;
|
||||
btnGenerateStockScheme.Font = new Font("Segoe UI", 11F, FontStyle.Bold);
|
||||
btnGenerateStockScheme.ImageAlign = ContentAlignment.MiddleLeft;
|
||||
btnGenerateStockScheme.Location = new Point(29, 65);
|
||||
btnGenerateStockScheme.Name = "btnGenerateStockScheme";
|
||||
btnGenerateStockScheme.Size = new Size(139, 29);
|
||||
btnGenerateStockScheme.TabIndex = 1;
|
||||
btnGenerateStockScheme.Text = "Generate Stocks";
|
||||
btnGenerateStockScheme.UseVisualStyleBackColor = false;
|
||||
btnGenerateStockScheme.Click += btnGenerateStockScheme_Click;
|
||||
//
|
||||
// dtpChosenDate
|
||||
//
|
||||
dtpChosenDate.Location = new Point(507, 67);
|
||||
dtpChosenDate.Name = "dtpChosenDate";
|
||||
dtpChosenDate.Size = new Size(200, 23);
|
||||
dtpChosenDate.TabIndex = 2;
|
||||
dtpChosenDate.ValueChanged += dtpChosenDate_ValueChanged;
|
||||
//
|
||||
// btnClose
|
||||
//
|
||||
btnClose.BackColor = Color.Chartreuse;
|
||||
btnClose.FlatStyle = FlatStyle.Popup;
|
||||
btnClose.Font = new Font("Segoe UI", 11F, FontStyle.Regular, GraphicsUnit.Point, 1, true);
|
||||
btnClose.Location = new Point(680, 411);
|
||||
btnClose.Margin = new Padding(3, 2, 3, 2);
|
||||
btnClose.Name = "btnClose";
|
||||
btnClose.Size = new Size(108, 28);
|
||||
btnClose.TabIndex = 8;
|
||||
btnClose.Text = "Stäng";
|
||||
btnClose.UseVisualStyleBackColor = false;
|
||||
btnClose.Click += btnClose_Click;
|
||||
//
|
||||
// lwStocks
|
||||
//
|
||||
lwStocks.Columns.AddRange(new ColumnHeader[] { chStock, chBought, chPrize, chNumber });
|
||||
lwStocks.Location = new Point(31, 110);
|
||||
lwStocks.Name = "lwStocks";
|
||||
lwStocks.Size = new Size(676, 172);
|
||||
lwStocks.TabIndex = 9;
|
||||
lwStocks.UseCompatibleStateImageBehavior = false;
|
||||
lwStocks.View = View.Details;
|
||||
//
|
||||
// chStock
|
||||
//
|
||||
chStock.Text = "Aktie";
|
||||
chStock.Width = 100;
|
||||
//
|
||||
// chBought
|
||||
//
|
||||
chBought.Text = "Köpt";
|
||||
chBought.Width = 100;
|
||||
//
|
||||
// chPrize
|
||||
//
|
||||
chPrize.Text = "Köpkurs";
|
||||
chPrize.Width = 100;
|
||||
//
|
||||
// chNumber
|
||||
//
|
||||
chNumber.Text = "Antal";
|
||||
chNumber.Width = 100;
|
||||
//
|
||||
// frmStockHistoryAnalyse
|
||||
//
|
||||
AutoScaleDimensions = new SizeF(7F, 15F);
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
ClientSize = new Size(800, 450);
|
||||
Controls.Add(lwStocks);
|
||||
Controls.Add(btnClose);
|
||||
Controls.Add(dtpChosenDate);
|
||||
Controls.Add(btnGenerateStockScheme);
|
||||
Controls.Add(lblHistAnalyseHeader);
|
||||
Name = "frmStockHistoryAnalyse";
|
||||
Text = "frnStockHistoryAnalyse";
|
||||
ResumeLayout(false);
|
||||
PerformLayout();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private Label lblHistAnalyseHeader;
|
||||
private Button btnGenerateStockScheme;
|
||||
private DateTimePicker dtpChosenDate;
|
||||
private Button btnClose;
|
||||
private ListView lwStocks;
|
||||
private ColumnHeader chStock;
|
||||
private ColumnHeader chBought;
|
||||
private ColumnHeader chPrize;
|
||||
private ColumnHeader chNumber;
|
||||
}
|
||||
}
|
||||
47
StockHistory/frmStockHistoryAnalyse.cs
Normal file
47
StockHistory/frmStockHistoryAnalyse.cs
Normal file
@ -0,0 +1,47 @@
|
||||
using StockHistory.Services;
|
||||
|
||||
namespace StockHistory;
|
||||
|
||||
public partial class frmStockHistoryAnalyse : Form
|
||||
{
|
||||
private readonly IStockEquityServices _equityServices;
|
||||
|
||||
public frmStockHistoryAnalyse(IStockEquityServices equityServices)
|
||||
{
|
||||
InitializeComponent();
|
||||
_equityServices = equityServices;
|
||||
}
|
||||
|
||||
private void btnGenerateStockScheme_Click(object sender, EventArgs e)
|
||||
{
|
||||
_equityServices.GenerateStockVision().Wait();
|
||||
}
|
||||
|
||||
private void btnClose_Click(object sender, EventArgs e)
|
||||
{
|
||||
this.Close();
|
||||
}
|
||||
|
||||
private void dtpChosenDate_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
LoadStockListAsync(dtpChosenDate.Value).Wait();
|
||||
}
|
||||
|
||||
private async Task LoadStockListAsync(DateTime equityDate)
|
||||
{
|
||||
|
||||
var stocks = await _equityServices.GetAllAsync(equityDate);
|
||||
// var stocks = await _equityServices.GetAllAsync();
|
||||
|
||||
lwStocks.Items.Clear();
|
||||
foreach (var t in stocks)
|
||||
{
|
||||
var item = new ListViewItem(t.StockCode);
|
||||
item.SubItems.Add(t.Bought.ToString());
|
||||
item.SubItems.Add(t.BoughtPrice.ToString());
|
||||
item.SubItems.Add(t.Quantity.ToString());
|
||||
lwStocks.Items.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
61
StockHistory/frmStockHistoryAnalyse1.Designer.cs
generated
61
StockHistory/frmStockHistoryAnalyse1.Designer.cs
generated
@ -1,61 +0,0 @@
|
||||
namespace StockHistory
|
||||
{
|
||||
partial class frmStockHistoryAnalyse1
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
label1 = new Label();
|
||||
SuspendLayout();
|
||||
//
|
||||
// label1
|
||||
//
|
||||
label1.AutoSize = true;
|
||||
label1.Font = new Font("Segoe UI", 13F, FontStyle.Bold);
|
||||
label1.Location = new Point(12, 9);
|
||||
label1.Name = "label1";
|
||||
label1.Size = new Size(428, 25);
|
||||
label1.TabIndex = 0;
|
||||
label1.Text = "Analysera existerande Avräkningsnotor (Affärer)";
|
||||
//
|
||||
// frmStockHistoryAnalyse1
|
||||
//
|
||||
AutoScaleDimensions = new SizeF(7F, 15F);
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
BackColor = Color.Gainsboro;
|
||||
ClientSize = new Size(922, 481);
|
||||
Controls.Add(label1);
|
||||
Name = "frmStockHistoryAnalyse1";
|
||||
Text = "Form1frmStockHistoryAnalyse1";
|
||||
ResumeLayout(false);
|
||||
PerformLayout();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private Label label1;
|
||||
}
|
||||
}
|
||||
@ -1,10 +0,0 @@
|
||||
namespace StockHistory
|
||||
{
|
||||
public partial class frmStockHistoryAnalyse1 : Form
|
||||
{
|
||||
public frmStockHistoryAnalyse1()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -12,7 +12,7 @@ public partial class frmStockHistoryInit : Form
|
||||
private readonly IPdfFormatter _pdfFormatter;
|
||||
private readonly ITransactionNotesServices _transactionNotes;
|
||||
private readonly IHandleCsvNotes _handleCsvNotes;
|
||||
private readonly frmStockHistoryAnalyse1 _analyseForm;
|
||||
private readonly frmStockHistoryAnalyse _analyseForm;
|
||||
private List<PdfSida> _pdfSidor = new();
|
||||
private List<PdfSida> localPdfSida = new();
|
||||
private bool lstWait = false;
|
||||
@ -26,7 +26,7 @@ public partial class frmStockHistoryInit : Form
|
||||
IPdfFormatter pdfFormatter,
|
||||
ITransactionNotesServices transactionNotes,
|
||||
IHandleCsvNotes handleCsvNotes,
|
||||
frmStockHistoryAnalyse1 analyseForm
|
||||
frmStockHistoryAnalyse analyseForm
|
||||
)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
Reference in New Issue
Block a user