Skip to content

Commit

Permalink
New - Ajout d'une page de gestion des comptes bancaire des producteurs
Browse files Browse the repository at this point in the history
  • Loading branch information
noelmugnier committed Nov 9, 2020
1 parent 78ca3d2 commit dc7d954
Show file tree
Hide file tree
Showing 15 changed files with 427 additions and 15 deletions.
22 changes: 22 additions & 0 deletions Sheaft.Application.Commands/Bank/UpdateBankAccountCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System;
using Newtonsoft.Json;
using Sheaft.Core;
using Sheaft.Application.Models;

namespace Sheaft.Application.Commands
{
public class UpdateBankAccountCommand : Command<bool>
{
[JsonConstructor]
public UpdateBankAccountCommand(RequestUser requestUser) : base(requestUser)
{
}

public Guid Id { get; set; }
public string Name { get; set; }
public string Owner { get; set; }
public string BIC { get; set; }
public string IBAN { get; set; }
public AddressInput Address { get; set; }
}
}
41 changes: 41 additions & 0 deletions Sheaft.Application.Handlers/Commands/PaymentCommandsHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ namespace Sheaft.Application.Handlers
{
public class PaymentCommandsHandler : ResultsHandler,
IRequestHandler<CreateBankAccountCommand, Result<Guid>>,
IRequestHandler<UpdateBankAccountCommand, Result<bool>>,
IRequestHandler<EnsureBankAccountValidatedCommand, Result<bool>>
{
private readonly IPspService _pspService;
Expand Down Expand Up @@ -51,13 +52,53 @@ public async Task<Result<Guid>> Handle(CreateBankAccountCommand request, Cancell
}
bankAccount.SetIdentifier(result.Data);
await _context.SaveChangesAsync(token);
await transaction.CommitAsync(token);
return Ok(bankAccount.Id);
}
});
}

public async Task<Result<bool>> Handle(UpdateBankAccountCommand request, CancellationToken token)
{
return await ExecuteAsync(request, async () =>
{
var bankAccount = await _context.GetByIdAsync<BankAccount>(request.Id, token);
var address = request.Address != null ?
new BankAddress(request.Address.Line1, request.Address.Line2, request.Address.Zipcode, request.Address.City,
request.Address.Country)
: null;
bankAccount.SetAddress(address);
bankAccount.SetName(request.Name);
bankAccount.SetOwner(request.Owner);
bankAccount.SetIban(request.IBAN);
bankAccount.SetBic(request.BIC);
await _context.SaveChangesAsync(token);
if (!string.IsNullOrWhiteSpace(bankAccount.Identifier))
{
var resetResult = await _pspService.UpdateBankIbanAsync(bankAccount, false, token);
if (!resetResult.Success)
return Failed<bool>(resetResult.Exception);
bankAccount.SetIdentifier(string.Empty);
}
var result = await _pspService.CreateBankIbanAsync(bankAccount, token);
if (!result.Success)
return Failed<bool>(result.Exception);
bankAccount.SetIdentifier(result.Data);
await _context.SaveChangesAsync(token);
return Ok(true);
});
}

public async Task<Result<bool>> Handle(EnsureBankAccountValidatedCommand request, CancellationToken token)
{
return await ExecuteAsync(request, async () =>
Expand Down
1 change: 1 addition & 0 deletions Sheaft.Application.Interop/Persistence/IAppDbContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ namespace Sheaft.Application.Interop
public interface IAppDbContext : IDisposable, IAsyncDisposable, IInfrastructure<IServiceProvider>, IDbContextDependencies, IDbSetCache, IDbContextPoolable, IResettableService
{
DbSet<Agreement> Agreements { get; set; }
DbSet<BankAccount> BankAccounts { get; set; }
DbSet<Country> Countries { get; set; }
DbSet<DeliveryMode> DeliveryModes { get; set; }
DbSet<Department> Departments { get; set; }
Expand Down
1 change: 1 addition & 0 deletions Sheaft.Application.Interop/Services/IPspService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public interface IPspService
{
Task<Result<bool>> AddPageToDocumentAsync(Page page, Document document, string userIdentifier, byte[] bytes, CancellationToken token);
Task<Result<string>> CreateBankIbanAsync(BankAccount payment, CancellationToken token);
Task<Result<bool>> UpdateBankIbanAsync(BankAccount payment, bool isActive, CancellationToken token);
Task<Result<KeyValuePair<string, string>>> CreateCardAsync(Card payment, CancellationToken token);
Task<Result<PspDocumentResultDto>> CreateDocumentAsync(Document document, string userIdentifier, CancellationToken token);
Task<Result<PspPaymentResultDto>> CreatePayoutAsync(Payout transaction, CancellationToken token);
Expand Down
8 changes: 8 additions & 0 deletions Sheaft.Application.Mappers/BankAccountProfile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ public class BankAccountProfile : Profile
public BankAccountProfile()
{
CreateMap<BankAccount, BankAccountShortViewModel>();
CreateMap<BankAccount, BankAccountViewModel>()
.ForMember(c => c.Address, opt => opt.MapFrom(r => new AddressViewModel {
Line1 = r.Line1,
Line2 = r.Line2,
Zipcode = r.Zipcode,
City = r.City,
Country = r.Country,
}));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ public class BankAccountShortViewModel
{
public Guid Id { get; set; }
public string Identifier { get; set; }
public bool IsActive { get; private set; }
public string IBAN { get; private set; }
public string BIC { get; private set; }
public string Owner { get; private set; }
public bool IsActive { get; set; }
public string IBAN { get; set; }
public string BIC { get; set; }
public string Owner { get; set; }
}
}
19 changes: 19 additions & 0 deletions Sheaft.Application.Models/ViewModels/BankAccountViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using Sheaft.Domain.Enums;
using System;
using System.Collections.Generic;

namespace Sheaft.Application.Models
{
public class BankAccountViewModel
{
public Guid Id { get; set; }
public string Identifier { get; set; }
public bool IsActive { get; set; }
public string IBAN { get; set; }
public string BIC { get; set; }
public string Owner { get; set; }
public string Name { get; set; }
public AddressViewModel Address { get; set; }
public Guid OwnerId { get; set; }
}
}
36 changes: 36 additions & 0 deletions Sheaft.Domain/BankAccount.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,41 @@ public BankAccount(Guid id, string name, string owner, string iban, string bic,
public string Zipcode { get; private set; }
public string City { get; private set; }
public CountryIsoCode Country { get; private set; }

public void SetAddress(BankAddress address)
{
if (address == null)
return;

Line1 = address.Line1;
Line2 = address.Line2;
Zipcode = address.Zipcode;
City = address.City;
Country = address.Country;
}

public void SetOwner(string owner)
{
if (owner == null)
return;

Owner = owner;
}

public void SetIban(string iban)
{
if (iban == null)
return;

IBAN = iban;
}

public void SetBic(string bic)
{
if (bic == null)
return;

BIC = bic;
}
}
}
8 changes: 8 additions & 0 deletions Sheaft.Domain/Base/PaymentMethod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,13 @@ public void SetIsActive(bool isActive)
{
IsActive = isActive;
}

public void SetName(string name)
{
if (name == null)
return;

Name = name;
}
}
}
1 change: 1 addition & 0 deletions Sheaft.Infrastructure.Persistence/AppDbContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public AppDbContext(DbContextOptions<AppDbContext> options, IStringLocalizer<Mes
}

public DbSet<Agreement> Agreements { get; set; }
public DbSet<BankAccount> BankAccounts { get; set; }
public DbSet<Country> Countries { get; set; }
public DbSet<DeliveryMode> DeliveryModes { get; set; }
public DbSet<Department> Departments { get; set; }
Expand Down
25 changes: 23 additions & 2 deletions Sheaft.Infrastructure.Services/PspService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ public async Task<Result<string>> CreateBankIbanAsync(BankAccount payment, Cance
await EnsureAccessTokenIsValidAsync(token);
var result = await _api.Users.CreateBankAccountIbanAsync(GetIdempotencyKey(payment.Id),
var result = await _api.Users.CreateBankAccountIbanAsync(payment.User.Identifier,
new BankAccountIbanPostDTO(
payment.Owner,
new MangoPay.SDK.Entities.Address
Expand All @@ -203,14 +203,35 @@ public async Task<Result<string>> CreateBankIbanAsync(BankAccount payment, Cance
{
BIC = payment.BIC,
Type = BankAccountType.IBAN,
UserId = payment.User.Identifier,
Tag = $"Id='{payment.Id}'"
});
return Ok(result.Id);
});
}

public async Task<Result<bool>> UpdateBankIbanAsync(BankAccount payment, bool isActive, CancellationToken token)
{
return await ExecuteAsync(async () =>
{
if (string.IsNullOrWhiteSpace(payment.User.Identifier))
return BadRequest<bool>(MessageKind.PsP_CannotCreate_Transfer_User_Not_Exists);
if (!string.IsNullOrWhiteSpace(payment.Identifier))
return BadRequest<bool>(MessageKind.PsP_CannotCreate_Transfer_BankIBAN_Exists);
await EnsureAccessTokenIsValidAsync(token);
var result = await _api.Users.UpdateBankAccountAsync(payment.User.Identifier,
new DisactivateBankAccountPutDTO
{
Active = isActive
}, payment.Identifier);
return Ok(result.Active);
});
}

public async Task<Result<KeyValuePair<string, string>>> CreateCardAsync(Card payment, CancellationToken token)
{
return await ExecuteAsync(async () =>
Expand Down
97 changes: 91 additions & 6 deletions Sheaft.Web.Manage/Controllers/ProducersController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ public async Task<IActionResult> Edit(Guid id, CancellationToken token)
if (entity == null)
throw new NotFoundException();

ViewBag.LegalsId = (await _context.FindSingleAsync<Legal>(c => c.User.Id == id, token))?.Id;
ViewBag.BankAccountId = (await _context.FindSingleAsync<BankAccount>(c => c.User.Id == id, token))?.Id;

ViewBag.Tags = await GetTags(token);
return View(entity);
}
Expand All @@ -92,7 +95,6 @@ public async Task<IActionResult> Edit(Guid id, CancellationToken token)
public async Task<IActionResult> Edit(ProducerViewModel model, IFormFile picture, CancellationToken token)
{
var requestUser = await GetRequestUser(token);

if (picture != null)
{
using (var ms = new MemoryStream())
Expand Down Expand Up @@ -122,6 +124,8 @@ public async Task<IActionResult> Edit(ProducerViewModel model, IFormFile picture

if (!result.Success)
{
ViewBag.LegalsId = (await _context.FindSingleAsync<Legal>(c => c.User.Id == model.Id, token))?.Id;
ViewBag.BankAccountId = (await _context.FindSingleAsync<BankAccount>(c => c.User.Id == model.Id, token))?.Id;
ViewBag.Tags = await GetTags(token);

ModelState.AddModelError("", result.Exception.Message);
Expand Down Expand Up @@ -185,15 +189,59 @@ public async Task<IActionResult> CreateLegal(BusinessLegalViewModel model, Cance
}

[HttpGet]
public async Task<IActionResult> UpdateLegal(Guid userId, CancellationToken token)
public async Task<IActionResult> CreateBankAccount(Guid userId, CancellationToken token)
{
var entity = await _context.Legals.OfType<BusinessLegal>()
.Where(c => c.User.Id == userId)
.ProjectTo<BusinessLegalViewModel>(_configurationProvider)
var entity = await _context.Users.OfType<Business>()
.AsNoTracking()
.Where(c => c.Id == userId)
.SingleOrDefaultAsync(token);

if (entity == null)
return RedirectToAction("CreateLegal", new { userId = userId });
throw new NotFoundException();

ViewBag.Countries = await GetCountries(token);
return View(new BankAccountViewModel
{
OwnerId = entity.Id,
IsActive = true
});
}

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> CreateBankAccount(BankAccountViewModel model, CancellationToken token)
{
var requestUser = await GetRequestUser(token);
var user = await _context.FindByIdAsync<Producer>(model.OwnerId, token);

var result = await _mediatr.Process(new CreateBankAccountCommand(requestUser)
{
UserId = user.Id,
Address = _mapper.Map<AddressInput>(model.Address),
BIC = model.BIC,
IBAN = model.IBAN,
Name = model.Name,
Owner = model.Owner
}, token);

if (!result.Success)
{
ViewBag.Countries = await GetCountries(token);
ModelState.AddModelError("", result.Exception.Message);
return View(model);
}

TempData["Created"] = JsonConvert.SerializeObject(new EntityViewModel { Id = model.OwnerId, Name = $"{model.Name}" });
return RedirectToAction("Edit", new { id = model.OwnerId });
}

[HttpGet]
public async Task<IActionResult> UpdateLegal(Guid legalId, CancellationToken token)
{
var entity = await _context.Legals.OfType<BusinessLegal>()
.Where(c => c.Id == legalId)
.ProjectTo<BusinessLegalViewModel>(_configurationProvider)
.SingleOrDefaultAsync(token);

ViewBag.Countries = await GetCountries(token);
ViewBag.Nationalities = await GetNationalities(token);
Expand Down Expand Up @@ -229,6 +277,43 @@ public async Task<IActionResult> UpdateLegal(BusinessLegalViewModel model, Cance
return RedirectToAction("Edit", new { id = model.Owner.Id });
}

[HttpGet]
public async Task<IActionResult> UpdateBankAccount(Guid bankAccountId, CancellationToken token)
{
var entity = await _context.BankAccounts.Get(c => c.Id == bankAccountId)
.ProjectTo<BankAccountViewModel>(_configurationProvider)
.SingleOrDefaultAsync(token);

ViewBag.Countries = await GetCountries(token);
return View(entity);
}

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> UpdateBankAccount(BankAccountViewModel model, CancellationToken token)
{
var requestUser = await GetRequestUser(token);
var result = await _mediatr.Process(new UpdateBankAccountCommand(requestUser)
{
Id = model.Id,
Address = _mapper.Map<AddressInput>(model.Address),
BIC = model.BIC,
IBAN = model.IBAN,
Name = model.Name,
Owner = model.Owner
}, token);

if (!result.Success)
{
ViewBag.Countries = await GetCountries(token);
ModelState.AddModelError("", result.Exception.Message);
return View(model);
}

TempData["Edited"] = JsonConvert.SerializeObject(new EntityViewModel { Id = model.OwnerId, Name = $"{model.Name}" });
return RedirectToAction("Edit", new { id = model.OwnerId });
}

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Delete(Guid id, CancellationToken token)
Expand Down
Loading

0 comments on commit dc7d954

Please sign in to comment.