Sparat innan resan

This commit is contained in:
2022-06-02 23:46:42 +02:00
parent bb5be33235
commit 3d883fdb99
9 changed files with 200 additions and 7 deletions

View File

@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
namespace OemanTrader.Domain.Exceptions
{
public class InsufficientFundsException : Exception
{
public double AccountBalance { get; set; }
public double RequiredBalance { get; set; }
public InsufficientFundsException(double accountBalance, double requiredBalance)
{
AccountBalance = accountBalance;
RequiredBalance = requiredBalance;
}
public InsufficientFundsException(double accountBalance, double requiredBalance, string? message) : base(message)
{
AccountBalance = accountBalance;
RequiredBalance = requiredBalance;
}
public InsufficientFundsException(double accountBalance, double requiredBalance, string? message, Exception? innerException) : base(message, innerException)
{
AccountBalance = accountBalance;
RequiredBalance = requiredBalance;
}
}
}

View File

@ -10,6 +10,6 @@ namespace OemanTrader.Domain.Models
{ {
public User AccountHolder { get; set; } public User AccountHolder { get; set; }
public double Balance { get; set; } public double Balance { get; set; }
public IEnumerable<AssetTransaction> AssetTransactions { get; set; } public ICollection<AssetTransaction> AssetTransactions { get; set; }
} }
} }

View File

@ -0,0 +1,52 @@
using OemanTrader.Domain.Exceptions;
using OemanTrader.Domain.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OemanTrader.Domain.Services.TransactionServices
{
public class BuyStockService : IBuyStockService
{
private readonly IStockPriceService _stockPriceService;
private readonly IDataService<Account> _accountService;
public BuyStockService(IStockPriceService stockPriceService, IDataService<Account> accountService)
{
_stockPriceService = stockPriceService;
_accountService = accountService;
}
public async Task<Account> BuyStock(Account buyer, string symbol, int shares)
{
double stockPrice = await _stockPriceService.GetPrice(symbol);
double transactionPrice = stockPrice * shares;
if (transactionPrice > buyer.Balance)
{
throw new InsufficientFundsException(buyer.Balance,transactionPrice);
}
AssetTransaction transaction = new AssetTransaction()
{
Account = buyer,
Asset = new Asset() {
PricePerShare = stockPrice,
Symbol = symbol
},
DateProcessed = DateTime.Now,
ShareAmount = shares,
IsPurchase = true
};
buyer.AssetTransactions.Add(transaction);
buyer.Balance -= transactionPrice;
await _accountService.Update(buyer.Id, buyer);
return buyer;
}
}
}

View File

@ -0,0 +1,14 @@
using OemanTrader.Domain.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OemanTrader.Domain.Services.TransactionServices
{
public interface IBuyStockService
{
Task<Account> BuyStock(Account buyer, string stock, int shares);
}
}

View File

@ -0,0 +1,73 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using Microsoft.EntityFrameworkCore.Internal;
using OemanTrader.Domain.Models;
using OemanTrader.Domain.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OemanTrader.EntityFramework.Services
{
public class AccountDataService : IDataService<Account>
{
private readonly OemanTraderDbContextFactory _contextFactory;
public AccountDataService(OemanTraderDbContextFactory contextFactory)
{
_contextFactory = contextFactory;
}
public async Task<Account> Create(Account entity)
{
using (var context = _contextFactory.CreateDbContext())
{
EntityEntry<Account> createdResult = await context.Set<Account>().AddAsync(entity);
await context.SaveChangesAsync();
return createdResult.Entity;
}
}
public async Task<bool> Delete(int id)
{
using (var context = _contextFactory.CreateDbContext())
{
Account entity = await context.Set<Account>().FirstOrDefaultAsync((e) => e.Id == id);
context.Set<Account>().Remove(entity);
await context.SaveChangesAsync();
return true;
}
}
public async Task<Account> Get(int id)
{
using (var context = _contextFactory.CreateDbContext())
{
Account entity = await context.Accounts.Include(a => a.AssetTransactions).FirstOrDefaultAsync((e) => e.Id == id);
return entity;
}
}
public async Task<IEnumerable<Account>> GetAll()
{
using (var context = _contextFactory.CreateDbContext())
{
IEnumerable<Account> entities = await context.Accounts.Include(a => a.AssetTransactions).ToListAsync();
return entities;
}
}
public async Task<Account> Update(int Id, Account entity)
{
using (var context = _contextFactory.CreateDbContext())
{
entity.Id = Id;
context.Set<Account>().Update(entity);
await context.SaveChangesAsync();
return entity;
}
}
}
}

View File

@ -1,4 +1,8 @@
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using OemanTrader.Domain.Models;
using OemanTrader.Domain.Services;
using OemanTrader.Domain.Services.TransactionServices;
using OemanTrader.EntityFramework.Services;
using OemanTrader.FinantialModelingPrepAPI.Services; using OemanTrader.FinantialModelingPrepAPI.Services;
using OemanTrader.WPF.ViewModels; using OemanTrader.WPF.ViewModels;
using System; using System;
@ -16,17 +20,29 @@ namespace OemanTrader.WPF
/// </summary> /// </summary>
public partial class App : Application public partial class App : Application
{ {
protected override void OnStartup(StartupEventArgs e) protected override async void OnStartup(StartupEventArgs e)
{ {
//new MajorIndexService().GetMajorIndex(Domain.Models.MajorIndexType.DowJones).ContinueWith((t) => //new MajorIndexService().GetMajorIndex(Domain.Models.MajorIndexType.DowJones).ContinueWith((t) =>
//{ //{
// var index = t.Result; // var index = t.Result;
//}); //});
IDataService<Account> accountService = new AccountDataService(new EntityFramework.OemanTraderDbContextFactory());
IStockPriceService stockPriceService = new StockPriceService(new FinantialModelingPrepAPI.FinancialModelingPrepHttpClientFactory("2035d4934632e1d7c38f15982e39d3aa"));
IBuyStockService buyStockService = new BuyStockService(stockPriceService, accountService);
Account buyer = await accountService.Get(1);
await buyStockService.BuyStock(buyer, "T", 5);
//new StockPriceService(new FinantialModelingPrepAPI.FinancialModelingPrepHttpClientFactory("2035d4934632e1d7c38f15982e39d3aa")).GetPrice("AAPL");
Window window = new MainWindow(); Window window = new MainWindow();
window.DataContext = new MainViewModel(); window.DataContext = new MainViewModel();
window.Show(); window.Show();
base.OnStartup(e); base.OnStartup(e);
} }

View File

@ -34,7 +34,7 @@ namespace OemanTrader.WPF.Commands
{ {
case ViewType.Home: case ViewType.Home:
// OBS OBS // OBS OBS
//_navigator.CurrentViewModel = new HomeViewModel(MajorIndexViewModel.LoadMajorIndexViewModel(new MajorIndexService())); _navigator.CurrentViewModel = new HomeViewModel(MajorIndexListingViewModel.LoadMajorIndexViewModel(new MajorIndexService( new FinantialModelingPrepAPI.FinancialModelingPrepHttpClientFactory("2035d4934632e1d7c38f15982e39d3aa"))));
break; break;
case ViewType.Portfolio: case ViewType.Portfolio:
_navigator.CurrentViewModel = new PortfolioViewModel(); _navigator.CurrentViewModel = new PortfolioViewModel();

View File

@ -12,7 +12,7 @@
<RowDefinition Height="auto"/> <RowDefinition Height="auto"/>
<RowDefinition Height="auto"/> <RowDefinition Height="auto"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="{Binding Type, FallbackValue=Name}" FontSize="18" HorizontalAlignment="Center" /> <TextBlock Grid.Row="0" Text="{Binding IndexName, FallbackValue=Name}" FontSize="18" HorizontalAlignment="Center" />
<Grid Grid.Row="1" Margin="0 10"> <Grid Grid.Row="1" Margin="0 10">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="auto"/> <RowDefinition Height="auto"/>

View File

@ -7,6 +7,7 @@
xmlns:nav="clr-namespace:OemanTrader.WPF.State.Navigators" d:DataContext="{d:DesignInstance Type=nav:Navigator}" xmlns:nav="clr-namespace:OemanTrader.WPF.State.Navigators" d:DataContext="{d:DesignInstance Type=nav:Navigator}"
xmlns:vm="clr-namespace:OemanTrader.WPF.ViewModels" xmlns:vm="clr-namespace:OemanTrader.WPF.ViewModels"
xmlns:converters="clr-namespace:OemanTrader.WPF.Converters" xmlns:converters="clr-namespace:OemanTrader.WPF.Converters"
mc:Ignorable="d" mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"> d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources> <UserControl.Resources>
@ -29,7 +30,9 @@
<ColumnDefinition Width="auto" /> <ColumnDefinition Width="auto" />
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<RadioButton Grid.Column="0" Content="Home" IsChecked="{Binding CurrentViewModel, Converter={StaticResource EqualValueToParameterConverter}, ConverterParameter={x:Type vm:HomeViewModel}}" <RadioButton Grid.Column="0" Content="Home" IsChecked="{Binding CurrentViewModel,
Converter={StaticResource EqualValueToParameterConverter},
ConverterParameter={x:Type vm:HomeViewModel}}"
Command="{Binding UpdateCurrentViewModelCommand}" Command="{Binding UpdateCurrentViewModelCommand}"
CommandParameter="{x:Static nav:ViewType.Home}" /> CommandParameter="{x:Static nav:ViewType.Home}" />
<RadioButton Grid.Column="1" Content="Portfolio" Command="{Binding UpdateCurrentViewModelCommand}" CommandParameter="{x:Static nav:ViewType.Portfolio}" /> <RadioButton Grid.Column="1" Content="Portfolio" Command="{Binding UpdateCurrentViewModelCommand}" CommandParameter="{x:Static nav:ViewType.Portfolio}" />