Skip to content

Commit

Permalink
insert operation
Browse files Browse the repository at this point in the history
  • Loading branch information
rodrigojap committed Feb 3, 2021
1 parent 8ef14d3 commit 0a69d04
Show file tree
Hide file tree
Showing 9 changed files with 98 additions and 20 deletions.
3 changes: 2 additions & 1 deletion VirtuaMind.Infrastructure/DI/DependencyInjection.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using VirtualMind.Application.Interfaces;
using VirtuaMind.Infrastructure.Persistence;
Expand All @@ -21,7 +22,7 @@ private static void AddDatabase(IServiceCollection services)
services.AddDbContext<VirtualMindDbContext>(options =>
options.UseInMemoryDatabase("VirtualMindDB"));

services.AddScoped<IVirtualMindDbContext>(provider => provider.GetService<VirtualMindDbContext>());
services.AddScoped<IVirtualMindDbContext>(provider => provider.GetService<VirtualMindDbContext>());
}

private static void AddRestServicesDependency(IServiceCollection services)
Expand Down
7 changes: 7 additions & 0 deletions VirtuaMind.Infrastructure/Persistence/VirtualMindDbContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ public VirtualMindDbContext(DbContextOptions options): base(options)

public DbSet<Operation> Operations { get; set; }

public DbSet<OperationCurrency> OperationCurrencies { get; set; }

public override int SaveChanges()
{
return base.SaveChanges();
}

public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken())
{
foreach (Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry<AuditableEntity> entry in ChangeTracker.Entries<AuditableEntity>())
Expand Down
1 change: 1 addition & 0 deletions VirtuaMind.Infrastructure/VirtuaMind.Infrastructure.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="5.0.2" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="5.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="RestSharp" Version="106.11.7" />
</ItemGroup>
Expand Down
47 changes: 34 additions & 13 deletions VirtualMind.Application/Commands/CreateOperationCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@
using MediatR;
using VirtualMind.Application.Queries;
using VirtualMind.Application.DTOs;
using System.Collections.Generic;
using VirtualMind.Domain.Entities;
using VirtualMind.Domain.Enums;
using System;
using VirtualMind.Application.Extensions;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using VirtualMind.Application.Exceptions;
using System.Globalization;

namespace VirtualMind.Application.Commands
{
Expand All @@ -26,37 +29,34 @@ public class CreateOperationCommandHandler : IRequestHandler<CreateOperationComm
private readonly IVirtualMindDbContext VirtualMindDbContext;
private readonly ICurrencyExchangeFactory CurrencyExchangeFactory;

public CreateOperationCommandHandler(IVirtualMindDbContext virtualMindDbContext, ICurrencyExchangeFactory currencyExchangeFactory)
public CreateOperationCommandHandler(IVirtualMindDbContext virtualMindDbContext,
ICurrencyExchangeFactory currencyExchangeFactory)
{
VirtualMindDbContext = virtualMindDbContext;
CurrencyExchangeFactory = currencyExchangeFactory;
}

public async Task<int> Handle(CreateOperationCommand request, CancellationToken cancellationToken)
{
var currentQuote = await GetCurrentQuote(request.CurrencyType);
var currentQuote = await GetCurrentQuote(request.CurrencyType);
var purchasedAmount = CalcPurchasedAmount(request, currentQuote);
var currency = (Currency)Enum.Parse(typeof(Currency), request.CurrencyType);




await CheckLimitOperation(request.UserId, purchasedAmount, currency);

var operation = new Operation
{
Currency = (Currency)Enum.Parse(typeof(Currency), request.CurrencyType),
Currency = currency,
UserId = request.UserId,
RequestedAmount = request.RequestedAmount,
CurrentQuote = currentQuote.Purchase.ConvertStringToDecimal(),
PurchasedAmount = purchasedAmount
};

await VirtualMindDbContext.Operations.AddAsync(operation);
await VirtualMindDbContext.SaveChangesAsync();

return await Task.FromResult(0);
return await VirtualMindDbContext.SaveChangesAsync();
}


private async Task<ExchangeRateDTO> GetCurrentQuote(string currencyType)
{
var result = await CurrencyExchangeFactory.GetExchangeRate(currencyType);
Expand All @@ -70,9 +70,30 @@ private async Task<ExchangeRateDTO> GetCurrentQuote(string currencyType)
return currnetQuote;
}

private static decimal CalcPurchasedAmount(CreateOperationCommand request, ExchangeRateDTO currentQuote)
private decimal CalcPurchasedAmount(CreateOperationCommand request, ExchangeRateDTO currentQuote)
{
return decimal.Round(request.RequestedAmount / currentQuote.Purchase.ConvertStringToDecimal(), 2);
}
}

private async Task CheckLimitOperation(int userId, decimal purchasedAmount, Currency currency)
{
var userSubmittedOperations = await VirtualMindDbContext.Operations
.Where(o => o.UserId == userId && o.Currency == currency && o.Created.Month == DateTime.Now.Month)
.ToListAsync();

var currencyParameters = await VirtualMindDbContext.OperationCurrencies.Where(c => c.Currency == currency)
.FirstOrDefaultAsync();

var total = userSubmittedOperations.Sum(o => o.PurchasedAmount) + purchasedAmount;

if (total > currencyParameters.Limit)
{
throw new ValidationException("InvalidOperation", new[]
{
$"This operation is not allowed because it exceeds the limits for the currency [{currency}] and user.",
$"Limit: [{currencyParameters.Limit}], Operation Total: [{total.ToString(new CultureInfo("en-US"))}]"
});
}
}
}
}
6 changes: 6 additions & 0 deletions VirtualMind.Application/Exceptions/ValidationException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ public ValidationException(IEnumerable<ValidationFailure> failures)
.ToDictionary(failureGroup => failureGroup.Key, failureGroup => failureGroup.ToArray());
}

public ValidationException(string type, string[] errorMessages)
: this()
{
Errors.Add(type, errorMessages);
}

public IDictionary<string, string[]> Errors { get; }
}
}
6 changes: 5 additions & 1 deletion VirtualMind.Application/Interfaces/IVirtualMindDbContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ public interface IVirtualMindDbContext
{
DbSet<Operation> Operations { get; set; }

Task<int> SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken());
DbSet<OperationCurrency> OperationCurrencies { get; set; }

Task<int> SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken());

int SaveChanges();
}
}
4 changes: 0 additions & 4 deletions VirtualMind.Application/VirtualMind.Application.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,4 @@
<ProjectReference Include="..\VirtualMind.Domain\VirtualMind.Domain.csproj" />
</ItemGroup>

<ItemGroup>
<Folder Include="Commom\Extensions\" />
</ItemGroup>

</Project>
13 changes: 13 additions & 0 deletions VirtualMind.Domain/Entities/OperationCurrency.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using VirtualMind.Domain.Enums;

namespace VirtualMind.Domain.Entities
{
public class OperationCurrency
{
public int Id { get; set; }

public Currency Currency { get; set; }

public decimal Limit { get; set; }
}
}
31 changes: 30 additions & 1 deletion VirtualMind.WebApp/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System.Collections.Generic;
using VirtualMind.Application.Configurations;
using VirtualMind.Application.Interfaces;
using VirtualMind.WebApp.Filters;
using VirtuaMind.Infrastructure.DI;

Expand All @@ -21,7 +23,7 @@ public Startup(IConfiguration configuration)

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
{
services.AddApplicationDI();
services.RegisterGlobalFilters();
services.AddInfrastructure();
Expand Down Expand Up @@ -53,6 +55,8 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)

app.UseRouting();

AddInitialValues(app);

app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
Expand All @@ -73,5 +77,30 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
}
});
}

private void AddInitialValues(IApplicationBuilder app)
{
using (var serviceScope = app.ApplicationServices.CreateScope())
{
var context = serviceScope.ServiceProvider.GetService<IVirtualMindDbContext>();

var listCurrency = new List<Domain.Entities.OperationCurrency>
{
new Domain.Entities.OperationCurrency
{
Currency = Domain.Enums.Currency.BRL,
Limit = 300
},
new Domain.Entities.OperationCurrency
{
Currency = Domain.Enums.Currency.USD,
Limit = 200
},
};

context.OperationCurrencies.AddRange(listCurrency);
context.SaveChanges();
}
}
}
}

0 comments on commit 0a69d04

Please sign in to comment.