Tillägg för inläsning från csv-filer anpassning för att få in händelser med samma aktie samma dag då transaktions datum bara sparas som datum
This commit is contained in:
@ -28,7 +28,9 @@ public class HandleCsvNotes : IHandleCsvNotes
|
||||
TransactionType = values[NamePos(Header_table, "Typ av transaktion")] == "Köp" ? "KÖP" : "SÄLJ",
|
||||
StockCode = values[NamePos(Header_table, @"Värdepapper/beskrivning")],
|
||||
StockPrice = decimal.Parse((values[NamePos(Header_table, "Kurs")] == "") ? "0" : values[NamePos(Header_table, "Kurs")]),
|
||||
Currency = values[NamePos(Header_table, @"Instrumentvaluta")],
|
||||
StockQuantity = Math.Abs(ParseCsvNumber(values[NamePos(Header_table, "Antal")])),
|
||||
ExchangeRate = decimal.Parse((values[NamePos(Header_table, "Valutakurs")] == "") ? "0" : "0" + values[NamePos(Header_table, "Valutakurs")]),
|
||||
Commission = decimal.Parse((values[NamePos(Header_table, "Courtage")] == "") ? "0" : "0" + values[NamePos(Header_table, "Courtage")]),
|
||||
TotalAmount = Math.Abs(decimal.Parse((values[NamePos(Header_table, "Belopp")] == "") ? "0" : values[NamePos(Header_table, "Belopp")])) - decimal.Parse((values[NamePos(Header_table, "Courtage")] == "") ? "0" : values[NamePos(Header_table, "Courtage")]),
|
||||
AmountToPay = Math.Abs(decimal.Parse((values[NamePos(Header_table, "Belopp")] == "") ? "0" : values[NamePos(Header_table, "Belopp")]))
|
||||
@ -36,6 +38,43 @@ public class HandleCsvNotes : IHandleCsvNotes
|
||||
transactionNotes.Add(transactionNote);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"Warning: '{ex.Message}'");
|
||||
}
|
||||
}
|
||||
}
|
||||
return transactionNotes;
|
||||
}
|
||||
|
||||
public List<TransactionNote> GetSHBTransactionNotes(string filePath)
|
||||
{
|
||||
lines = File.ReadAllLines(filePath).ToList();
|
||||
Header_table = lines[0].Split(';');
|
||||
var transactionNotes = new List<TransactionNote>();
|
||||
foreach (var line in lines.Skip(1))
|
||||
{
|
||||
var values = line.Split(';');
|
||||
var test = values[NamePos(Header_table, "Transaktion")];
|
||||
if (test == "Köp" || test == "Sälj")
|
||||
{
|
||||
try
|
||||
{
|
||||
var transactionNote = new TransactionNote
|
||||
{
|
||||
TransactionDate = DateTime.Parse(values[NamePos(Header_table, "Affärsdag")]),
|
||||
TransactionType = values[NamePos(Header_table, "Transaktion")] == "Köp" ? "KÖP" : "SÄLJ",
|
||||
StockCode = values[NamePos(Header_table, @"Värdepapper")],
|
||||
StockPrice = decimal.Parse((values[NamePos(Header_table, "Kurs")] == "") ? "0" : values[NamePos(Header_table, "Kurs")]),
|
||||
Currency = values[NamePos(Header_table, @"Noteringsvaluta")],
|
||||
StockQuantity = Math.Abs(ParseCsvNumber(values[NamePos(Header_table, "Innehavsförändring")])),
|
||||
ExchangeRate = decimal.Parse((values[NamePos(Header_table, "Växlingskurs")] == "") ? "0" : "0" + values[NamePos(Header_table, "Växlingskurs")]),
|
||||
Commission = decimal.Parse((values[NamePos(Header_table, "Courtage")] == "") ? "0" : "0" + values[NamePos(Header_table, "Courtage")]),
|
||||
TotalAmount = Math.Abs(decimal.Parse((values[NamePos(Header_table, "Likvidbelopp (Betalvaluta)")] == "") ? "0" : values[NamePos(Header_table, "Likvidbelopp (Betalvaluta)")])) - decimal.Parse((values[NamePos(Header_table, "Courtage")] == "") ? "0" : values[NamePos(Header_table, "Courtage")]),
|
||||
AmountToPay = Math.Abs(decimal.Parse((values[NamePos(Header_table, "Likvidbelopp (Betalvaluta)")] == "") ? "0" : values[NamePos(Header_table, "Likvidbelopp (Betalvaluta)")]))
|
||||
};
|
||||
transactionNotes.Add(transactionNote);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"Warning: '{ex.Message}'");
|
||||
// throw;
|
||||
@ -45,6 +84,7 @@ public class HandleCsvNotes : IHandleCsvNotes
|
||||
return transactionNotes;
|
||||
}
|
||||
|
||||
|
||||
private int NamePos(string[] h_table, string value)
|
||||
{
|
||||
var pos = Array.IndexOf(h_table, value);
|
||||
|
||||
@ -5,5 +5,6 @@ namespace StockHistory
|
||||
public interface IHandleCsvNotes
|
||||
{
|
||||
List<TransactionNote> GetTransactionNotes(string filePath);
|
||||
List<TransactionNote> GetSHBTransactionNotes(string filePath);
|
||||
}
|
||||
}
|
||||
148
StockHistory/Migrations/20260830144416_CurrencyAndExchangeRate.Designer.cs
generated
Normal file
148
StockHistory/Migrations/20260830144416_CurrencyAndExchangeRate.Designer.cs
generated
Normal file
@ -0,0 +1,148 @@
|
||||
// <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("20260830144416_CurrencyAndExchangeRate")]
|
||||
partial class CurrencyAndExchangeRate
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "9.0.6");
|
||||
|
||||
modelBuilder.Entity("StockHistory.Models.SglStockEquity", 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("SglStocks");
|
||||
});
|
||||
|
||||
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>("Currency")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<decimal>("ExchangeRate")
|
||||
.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,40 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace StockHistory.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class CurrencyAndExchangeRate : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "Currency",
|
||||
table: "TransactionNotes",
|
||||
type: "TEXT",
|
||||
nullable: false,
|
||||
defaultValue: "");
|
||||
|
||||
migrationBuilder.AddColumn<decimal>(
|
||||
name: "ExchangeRate",
|
||||
table: "TransactionNotes",
|
||||
type: "TEXT",
|
||||
nullable: false,
|
||||
defaultValue: 0m);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Currency",
|
||||
table: "TransactionNotes");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "ExchangeRate",
|
||||
table: "TransactionNotes");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -107,6 +107,13 @@ namespace StockHistory.Migrations
|
||||
b.Property<decimal>("Commission")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Currency")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<decimal>("ExchangeRate")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("StockCode")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
|
||||
@ -7,8 +7,8 @@ public class TransactionNote
|
||||
public string? TransactionType { get; set; }
|
||||
public string? StockCode { get; set; }
|
||||
public decimal StockPrice { get; set; }
|
||||
public decimal ExchangeCours { get; set; }
|
||||
public string Valuta { get; set; }
|
||||
public decimal ExchangeRate { get; set; }
|
||||
public string Currency { get; set; }
|
||||
public int StockQuantity { get; set; }
|
||||
public decimal TotalAmount { get; set; }
|
||||
public decimal Commission { get; set; }
|
||||
@ -17,7 +17,7 @@ public class TransactionNote
|
||||
public override string ToString()
|
||||
{
|
||||
//return $"TransactionDate: {TransactionDate},\r\nTransactionType: {TransactionType},\r\nStockCode: {StockCode},\r\nStockPrice: {StockPrice},\r\nStockQuantity: {StockQuantity},\r\nTotalAmount: {TotalAmount},\r\nCommission: {Commission},\r\nAmountToPay: {AmountToPay}\r\n";
|
||||
return $" {TransactionDate} | {TransactionType} | {StockCode} | {StockPrice} | {StockQuantity} | {TotalAmount} | {Commission} | {AmountToPay}";
|
||||
return $" {TransactionDate} | {TransactionType} | {StockCode} | {StockPrice} | {ExchangeRate} | {Currency} | {StockQuantity} | {TotalAmount} | {Commission} | {AmountToPay}";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
83
StockHistory/NoWrapMessageBoxForm.cs
Normal file
83
StockHistory/NoWrapMessageBoxForm.cs
Normal file
@ -0,0 +1,83 @@
|
||||
namespace StockHistory.Forms;
|
||||
|
||||
public class NoWrapMessageBox : Form
|
||||
{
|
||||
private Label line1;
|
||||
private Label line2;
|
||||
private Label line3;
|
||||
private Button yesButton;
|
||||
private Button noButton;
|
||||
|
||||
public NoWrapMessageBox(string row1, string row2)
|
||||
{
|
||||
Text = "Bekräfta";
|
||||
StartPosition = FormStartPosition.CenterScreen;
|
||||
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||
MaximizeBox = false;
|
||||
MinimizeBox = false;
|
||||
ShowInTaskbar = false;
|
||||
Size = new Size(1000, 180);
|
||||
|
||||
TopMost = true; // ← gör att dialogen hamnar överst
|
||||
|
||||
line1 = new Label()
|
||||
{
|
||||
Text = row1,
|
||||
AutoSize = true,
|
||||
Location = new Point(20, 20),
|
||||
Font = new Font("Consolas", 9),
|
||||
MaximumSize = Size.Empty // ingen wrapping
|
||||
};
|
||||
|
||||
line2 = new Label()
|
||||
{
|
||||
Text = row2,
|
||||
AutoSize = true,
|
||||
Location = new Point(20, 50),
|
||||
Font = new Font("Consolas", 9),
|
||||
MaximumSize = Size.Empty
|
||||
};
|
||||
|
||||
line3 = new Label()
|
||||
{
|
||||
Text = "Kan posten läggas till ?",
|
||||
AutoSize = true,
|
||||
Location = new Point(20, 80),
|
||||
Font = new Font("Consolas", 10),
|
||||
MaximumSize = Size.Empty
|
||||
};
|
||||
|
||||
yesButton = new Button()
|
||||
{
|
||||
Text = "Yes",
|
||||
DialogResult = DialogResult.Yes,
|
||||
Location = new Point(350, 100),
|
||||
Size = new Size(100, 30)
|
||||
};
|
||||
|
||||
noButton = new Button()
|
||||
{
|
||||
Text = "No",
|
||||
DialogResult = DialogResult.No,
|
||||
Location = new Point(460, 100),
|
||||
Size = new Size(100, 30)
|
||||
};
|
||||
|
||||
Controls.Add(line1);
|
||||
Controls.Add(line2);
|
||||
Controls.Add(line3);
|
||||
Controls.Add(yesButton);
|
||||
Controls.Add(noButton);
|
||||
|
||||
AcceptButton = yesButton;
|
||||
CancelButton = noButton;
|
||||
}
|
||||
|
||||
public static DialogResult Show(string row1, string row2)
|
||||
{
|
||||
using (var dlg = new NoWrapMessageBox(row1, row2))
|
||||
{
|
||||
return dlg.ShowDialog();
|
||||
}
|
||||
}
|
||||
}
|
||||
120
StockHistory/NoWrapMessageBoxForm.resx
Normal file
120
StockHistory/NoWrapMessageBoxForm.resx
Normal file
@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
@ -8,6 +8,7 @@ namespace StockHistory.Services
|
||||
Task DeleteAsync(int id);
|
||||
Task<List<TransactionNote>> GetAllAsync();
|
||||
Task<TransactionNote?> GetByIdAsync(int id);
|
||||
Task<TransactionNote?> GetByIndexAsync(string stockCode, DateTime transDate);
|
||||
Task<List<TransactionNote>> GetByStockCodeAsync(string stockCode);
|
||||
Task UpdateAsync(TransactionNote transactionNote);
|
||||
}
|
||||
|
||||
@ -31,6 +31,13 @@ public class TransactionNotesServices : ITransactionNotesServices
|
||||
return await _dbContext.TransactionNotes.FindAsync(id);
|
||||
}
|
||||
|
||||
public async Task<TransactionNote?> GetByIndexAsync(string stockCode, DateTime transDate)
|
||||
{
|
||||
return await _dbContext.TransactionNotes
|
||||
.FirstOrDefaultAsync(s => s.StockCode == stockCode && s.TransactionDate == transDate);
|
||||
}
|
||||
|
||||
|
||||
public async Task<List<TransactionNote>> GetByStockCodeAsync(string stockCode)
|
||||
{
|
||||
if (string.IsNullOrEmpty(stockCode))
|
||||
|
||||
BIN
StockHistory/Stockbrokerage.db
Normal file
BIN
StockHistory/Stockbrokerage.db
Normal file
Binary file not shown.
30
StockHistory/frmStockHistoryInit.Designer.cs
generated
30
StockHistory/frmStockHistoryInit.Designer.cs
generated
@ -47,6 +47,7 @@
|
||||
btnNext = new Button();
|
||||
btnDtaAnalyse1 = new Button();
|
||||
btnListNoteDates = new Button();
|
||||
btnSaveAllToDB = new Button();
|
||||
SuspendLayout();
|
||||
//
|
||||
// btnChooseFile
|
||||
@ -81,7 +82,7 @@
|
||||
btnAnalysera.Location = new Point(23, 94);
|
||||
btnAnalysera.Margin = new Padding(3, 2, 3, 2);
|
||||
btnAnalysera.Name = "btnAnalysera";
|
||||
btnAnalysera.Size = new Size(125, 28);
|
||||
btnAnalysera.Size = new Size(97, 28);
|
||||
btnAnalysera.TabIndex = 2;
|
||||
btnAnalysera.Text = "Analysera";
|
||||
btnAnalysera.UseVisualStyleBackColor = false;
|
||||
@ -103,10 +104,10 @@
|
||||
btnSaveToDb.BackColor = Color.FromArgb(128, 255, 128);
|
||||
btnSaveToDb.FlatStyle = FlatStyle.Flat;
|
||||
btnSaveToDb.Font = new Font("Segoe UI", 11F);
|
||||
btnSaveToDb.Location = new Point(307, 94);
|
||||
btnSaveToDb.Location = new Point(202, 94);
|
||||
btnSaveToDb.Margin = new Padding(3, 2, 3, 2);
|
||||
btnSaveToDb.Name = "btnSaveToDb";
|
||||
btnSaveToDb.Size = new Size(125, 28);
|
||||
btnSaveToDb.Size = new Size(110, 28);
|
||||
btnSaveToDb.TabIndex = 4;
|
||||
btnSaveToDb.Text = "Spara till DB";
|
||||
btnSaveToDb.UseVisualStyleBackColor = false;
|
||||
@ -186,10 +187,10 @@
|
||||
btnNext.Enabled = false;
|
||||
btnNext.FlatStyle = FlatStyle.Flat;
|
||||
btnNext.Font = new Font("Segoe UI", 11F);
|
||||
btnNext.Location = new Point(164, 94);
|
||||
btnNext.Location = new Point(126, 94);
|
||||
btnNext.Margin = new Padding(3, 2, 3, 2);
|
||||
btnNext.Name = "btnNext";
|
||||
btnNext.Size = new Size(125, 28);
|
||||
btnNext.Size = new Size(70, 28);
|
||||
btnNext.TabIndex = 8;
|
||||
btnNext.Text = "Nästa";
|
||||
btnNext.UseVisualStyleBackColor = false;
|
||||
@ -224,12 +225,30 @@
|
||||
btnListNoteDates.UseVisualStyleBackColor = false;
|
||||
btnListNoteDates.Click += btnListNoteDates_Click;
|
||||
//
|
||||
// btnSaveAllToDB
|
||||
//
|
||||
btnSaveAllToDB.BackColor = Color.FromArgb(255, 192, 128);
|
||||
btnSaveAllToDB.Cursor = Cursors.IBeam;
|
||||
btnSaveAllToDB.Enabled = false;
|
||||
btnSaveAllToDB.FlatStyle = FlatStyle.Flat;
|
||||
btnSaveAllToDB.Font = new Font("Segoe UI", 11F);
|
||||
btnSaveAllToDB.Location = new Point(318, 94);
|
||||
btnSaveAllToDB.Margin = new Padding(3, 2, 3, 2);
|
||||
btnSaveAllToDB.Name = "btnSaveAllToDB";
|
||||
btnSaveAllToDB.Size = new Size(114, 28);
|
||||
btnSaveAllToDB.TabIndex = 11;
|
||||
btnSaveAllToDB.Text = "Spara Alla";
|
||||
btnSaveAllToDB.UseVisualStyleBackColor = false;
|
||||
btnSaveAllToDB.Visible = false;
|
||||
btnSaveAllToDB.Click += btnSaveAllToDB_Click;
|
||||
//
|
||||
// frmStockHistoryInit
|
||||
//
|
||||
AutoScaleDimensions = new SizeF(7F, 15F);
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
BackColor = Color.LightGray;
|
||||
ClientSize = new Size(1236, 423);
|
||||
Controls.Add(btnSaveAllToDB);
|
||||
Controls.Add(btnListNoteDates);
|
||||
Controls.Add(btnDtaAnalyse1);
|
||||
Controls.Add(btnNext);
|
||||
@ -268,5 +287,6 @@
|
||||
private Button btnNext;
|
||||
private Button btnDtaAnalyse1;
|
||||
private Button btnListNoteDates;
|
||||
private Button btnSaveAllToDB;
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
using Microsoft.Data.Sqlite;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using StockHistory.Forms;
|
||||
using StockHistory.Models;
|
||||
using StockHistory.Services;
|
||||
using System.ComponentModel;
|
||||
@ -20,6 +21,8 @@ public partial class frmStockHistoryInit : Form
|
||||
private TaskCompletionSource<bool> _waiter;
|
||||
private TransactionNote trans = new();
|
||||
private bool SHB = false;
|
||||
private bool PDF = false;
|
||||
private bool MULTIRUN = false;
|
||||
private string pdfFilePath = string.Empty;
|
||||
// Sortering
|
||||
private int _sortColumn = -1;
|
||||
@ -70,12 +73,14 @@ public partial class frmStockHistoryInit : Form
|
||||
|
||||
btnAnalysera.Enabled = true;
|
||||
SHB = true;
|
||||
PDF = true;
|
||||
|
||||
}
|
||||
else if (lblFileName.Text.Length > 5 && lblFileName.Text.ToLower().EndsWith("csv"))
|
||||
{
|
||||
btnAnalysera.Enabled = true;
|
||||
SHB = false;
|
||||
SHB = lblFileName.Text.ToLower().Contains("shbnotor");
|
||||
PDF = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -84,34 +89,104 @@ public partial class frmStockHistoryInit : Form
|
||||
}
|
||||
|
||||
|
||||
private void btnAnalysera_Click(object sender, EventArgs e)
|
||||
private async void btnAnalysera_Click(object sender, EventArgs e)
|
||||
{
|
||||
string PdfResult = string.Empty;
|
||||
// if (lblFileName.Text.ToLower().EndsWith("csv"))
|
||||
if (!SHB)
|
||||
{
|
||||
var Result = string.Empty; //DocoticPdfReading.ExtractText(lblFileName.Text);
|
||||
SelectAvanzaPdfData(lblFileName.Text);
|
||||
var Result = string.Empty;
|
||||
await SelectCsvData(lblFileName.Text);
|
||||
}
|
||||
else
|
||||
{
|
||||
PdfResult = _pdfFormatter.ExtractFormattedTextUsingWords(_pdfSidor);
|
||||
SelectPdfData(PdfResult);
|
||||
if (lblFileName.Text.ToLower().EndsWith("pdf"))
|
||||
{
|
||||
PdfResult = _pdfFormatter.ExtractFormattedTextUsingWords(_pdfSidor);
|
||||
SelectPdfData(PdfResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lblFileName.Text.ToLower().EndsWith("csv"))
|
||||
{
|
||||
await SelectCsvData(lblFileName.Text);
|
||||
}
|
||||
}
|
||||
}
|
||||
btnAnalysera.Enabled = false;
|
||||
pdfFilePath = lblFileName.Text;
|
||||
lblFileName.Text = string.Empty;
|
||||
}
|
||||
|
||||
private async Task SelectAvanzaPdfData(string infile)
|
||||
//private async Task SelectSHBCsvData(string infile)
|
||||
//{
|
||||
// txtFound.Text = string.Empty;
|
||||
|
||||
// List<TransactionNote> result = _handleCsvNotes.GetSHBTransactionNotes(infile);
|
||||
// txtFound.Refresh();
|
||||
// btnNext.Enabled = true;
|
||||
// btnNext.Visible = true;
|
||||
// btnNext.Refresh();
|
||||
|
||||
// await Task.Delay(100); // Liten fördröjning för att säkerställa att UI uppdateras innan vi börjar visa resultaten
|
||||
|
||||
// await ShowListAsync(result);
|
||||
|
||||
// btnNext.Enabled = false;
|
||||
// btnNext.Visible = false;
|
||||
// btnNext.Refresh();
|
||||
|
||||
|
||||
//}
|
||||
|
||||
|
||||
|
||||
//private async Task SelectAvanzaCsvData(string infile)
|
||||
//{
|
||||
// txtFound.Text = string.Empty;
|
||||
|
||||
// List<TransactionNote> result = _handleCsvNotes.GetTransactionNotes(infile);
|
||||
// txtFound.Refresh();
|
||||
// btnNext.Enabled = true;
|
||||
// btnNext.Visible = true;
|
||||
// btnNext.Refresh();
|
||||
// btnSaveAllToDB.Enabled = true;
|
||||
// btnSaveAllToDB.Visible = true;
|
||||
// btnSaveAllToDB.Refresh();
|
||||
|
||||
// await Task.Delay(100); // Liten fördröjning för att säkerställa att UI uppdateras innan vi börjar visa resultaten
|
||||
|
||||
// await ShowListAsync(result);
|
||||
|
||||
// btnNext.Enabled = false;
|
||||
// btnNext.Visible = false;
|
||||
// btnNext.Refresh();
|
||||
// btnSaveAllToDB.Enabled = false;
|
||||
// btnSaveAllToDB.Visible = true;
|
||||
// btnSaveAllToDB.Refresh();
|
||||
|
||||
|
||||
//}
|
||||
|
||||
private async Task SelectCsvData(string infile)
|
||||
{
|
||||
txtFound.Text = string.Empty;
|
||||
List<TransactionNote> result = new List<TransactionNote>();
|
||||
if (SHB)
|
||||
{
|
||||
result = _handleCsvNotes.GetSHBTransactionNotes(infile);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = _handleCsvNotes.GetTransactionNotes(infile);
|
||||
}
|
||||
|
||||
List<TransactionNote> result = _handleCsvNotes.GetTransactionNotes(infile);
|
||||
txtFound.Refresh();
|
||||
btnNext.Enabled = true;
|
||||
btnNext.Visible = true;
|
||||
btnNext.Refresh();
|
||||
btnSaveAllToDB.Enabled = true;
|
||||
btnSaveAllToDB.Visible = true;
|
||||
btnSaveAllToDB.Refresh();
|
||||
|
||||
await Task.Delay(100); // Liten fördröjning för att säkerställa att UI uppdateras innan vi börjar visa resultaten
|
||||
|
||||
@ -120,6 +195,9 @@ public partial class frmStockHistoryInit : Form
|
||||
btnNext.Enabled = false;
|
||||
btnNext.Visible = false;
|
||||
btnNext.Refresh();
|
||||
btnSaveAllToDB.Enabled = false;
|
||||
btnSaveAllToDB.Visible = false;
|
||||
btnSaveAllToDB.Refresh();
|
||||
|
||||
|
||||
}
|
||||
@ -132,13 +210,27 @@ public partial class frmStockHistoryInit : Form
|
||||
|
||||
trans = note;
|
||||
|
||||
_waiter = new TaskCompletionSource<bool>();
|
||||
if (!MULTIRUN)
|
||||
{
|
||||
_waiter = new TaskCompletionSource<bool>();
|
||||
|
||||
await _waiter.Task; // Väntar utan att blockera UI
|
||||
await _waiter.Task; // Väntar utan att blockera UI
|
||||
}
|
||||
else
|
||||
{
|
||||
HandleMultiSave();
|
||||
}
|
||||
}
|
||||
if (MULTIRUN)
|
||||
{
|
||||
await LoadBusinessAsync();
|
||||
btnSaveAllToDB.BackColor = Color.FromArgb(128, 255, 128);
|
||||
MULTIRUN = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void btnNext_Click(object sender, EventArgs e)
|
||||
{
|
||||
_waiter?.TrySetResult(true);
|
||||
@ -173,7 +265,7 @@ public partial class frmStockHistoryInit : Form
|
||||
|
||||
private async void btnSaveToDb_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (SHB)
|
||||
if (SHB && PDF)
|
||||
{
|
||||
trans = new();
|
||||
|
||||
@ -259,24 +351,53 @@ public partial class frmStockHistoryInit : Form
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
HandleMultiSave();
|
||||
await LoadBusinessAsync();
|
||||
}
|
||||
|
||||
private async void HandleMultiSave()
|
||||
{
|
||||
bool retry = true;
|
||||
|
||||
while (retry)
|
||||
{
|
||||
await _transactionNotes.AddAsync(trans);
|
||||
txtFound.Text = string.Empty;
|
||||
if (SHB) RenameHandledFile(pdfFilePath);
|
||||
}
|
||||
catch (DbUpdateException ex) when (ex.InnerException is SqliteException sqlite && sqlite.SqliteErrorCode == 19)
|
||||
{
|
||||
MessageBox.Show("Den här transaktionen finns redan.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show("Fel vid sparande till databas: " + ex.Message);
|
||||
try
|
||||
{
|
||||
await _transactionNotes.AddAsync(trans);
|
||||
txtFound.Text = string.Empty;
|
||||
if (SHB && PDF) RenameHandledFile(pdfFilePath);
|
||||
retry = false;
|
||||
}
|
||||
catch (DbUpdateException ex) when (ex.InnerException is SqliteException sqlite && sqlite.SqliteErrorCode == 19)
|
||||
{
|
||||
MessageBox.Show("Den här transaktionen finns redan.");
|
||||
if (!await showChooseIns(trans))
|
||||
retry = false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show("Fel vid sparande till databas: " + ex.Message);
|
||||
retry = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Selected.Clear();
|
||||
}
|
||||
private async Task<bool> showChooseIns(TransactionNote localTrans)
|
||||
{
|
||||
var result = false;
|
||||
var jmfPost = await _transactionNotes.GetByIndexAsync(localTrans.StockCode, localTrans.TransactionDate);
|
||||
|
||||
await LoadBusinessAsync();
|
||||
if (NoWrapMessageBox.Show($"I DB: {jmfPost.ToString()}", $"Nytt: {localTrans.ToString()}") == DialogResult.Yes)
|
||||
{
|
||||
DateTime transDatTemp = localTrans.TransactionDate.AddSeconds(5);
|
||||
localTrans.TransactionDate = transDatTemp;
|
||||
trans = localTrans;
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
@ -352,5 +473,20 @@ public partial class frmStockHistoryInit : Form
|
||||
);
|
||||
}
|
||||
|
||||
private void btnSaveAllToDB_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (MessageBox.Show("Multikörning ?", "Transladdning", MessageBoxButtons.OKCancel) != DialogResult.OK)
|
||||
{
|
||||
MessageBox.Show("OK, inget händer!!", "Transladdning", MessageBoxButtons.OK);
|
||||
MULTIRUN = false;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
btnSaveAllToDB.BackColor = Color.Red;
|
||||
MULTIRUN = true;
|
||||
_waiter?.TrySetResult(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user