Skip to content
This repository has been archived by the owner on Jun 25, 2022. It is now read-only.

Commit

Permalink
feat(back-end): move payment logic to a payment controller
Browse files Browse the repository at this point in the history
  • Loading branch information
CarlosPavajeau committed May 28, 2021
1 parent 5d0c743 commit 193bcb3
Show file tree
Hide file tree
Showing 5 changed files with 223 additions and 174 deletions.
41 changes: 20 additions & 21 deletions Kaizen.Test/Controllers/ProductInvoicesControllerTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
using Kaizen.Domain.Repositories;
using Kaizen.Models.ProductInvoice;
using Kaizen.Test.Helpers;
using MercadoPago.Client.Payment;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Moq;
Expand All @@ -22,17 +21,15 @@ public class ProductInvoicesControllerTest : BaseControllerTest
private ProductInvoicesController _productInvoicesController;
private Mock<IProductInvoicesRepository> _productInvoicesRepository;
private Mock<IUnitWork> _unitWork;
private Mock<PaymentClient> _paymentClient;

[SetUp]
public void SetUp()
{
_productInvoicesRepository = new Mock<IProductInvoicesRepository>();
_unitWork = new Mock<IUnitWork>();
_paymentClient = new Mock<PaymentClient>();

_productInvoicesController = new ProductInvoicesController(_productInvoicesRepository.Object,
_unitWork.Object, ServiceProvider.GetService<IMapper>(), _paymentClient.Object);
_unitWork.Object, ServiceProvider.GetService<IMapper>());

SetUpProductInvoicesRepository();
SetUpUnitWork();
Expand All @@ -43,14 +40,14 @@ private void SetUpProductInvoicesRepository()
_productInvoicesRepository.Setup(r => r.GetAll()).Returns(new TestAsyncEnumerable<ProductInvoice>(
new List<ProductInvoice>
{
new ()
new()
{
Id = 1,
ClientId = "1007870922",
GenerationDate = DateTime.Now,
ProductInvoiceDetails = new List<ProductInvoiceDetail>()
},
new ()
new()
{
Id = 2,
ClientId = "1007870922",
Expand All @@ -66,11 +63,10 @@ private void SetUpProductInvoicesRepository()
GenerationDate = DateTime.Now,
ProductInvoiceDetails = new List<ProductInvoiceDetail>()
});
_productInvoicesRepository.Setup(r => r.FindByIdAsync(3)).ReturnsAsync((ProductInvoice)null);
_productInvoicesRepository.Setup(r => r.FindByIdAsync(3)).ReturnsAsync((ProductInvoice) null);

_productInvoicesRepository.Setup(r => r.Update(It.IsAny<ProductInvoice>()));
_productInvoicesRepository.Setup(r => r.Insert(It.IsAny<ProductInvoice>())).Verifiable();

}

private void SetUpUnitWork()
Expand Down Expand Up @@ -110,10 +106,11 @@ public async Task Get_Non_Existent_ProductInvoice()
[Test]
public async Task Update_Existing_ProductInvoice()
{
ActionResult<ProductInvoiceViewModel> result = await _productInvoicesController.PutProductInvoice(1, new ProductInvoiceEditModel
{
State = InvoiceState.Regenerated
});
ActionResult<ProductInvoiceViewModel> result = await _productInvoicesController.PutProductInvoice(1,
new ProductInvoiceEditModel
{
State = InvoiceState.Regenerated
});

Assert.NotNull(result);
Assert.NotNull(result.Value);
Expand All @@ -122,10 +119,11 @@ public async Task Update_Existing_ProductInvoice()
[Test]
public async Task Update_Non_Existent_ProductInvoice()
{
ActionResult<ProductInvoiceViewModel> result = await _productInvoicesController.PutProductInvoice(3, new ProductInvoiceEditModel
{
State = InvoiceState.Regenerated
});
ActionResult<ProductInvoiceViewModel> result = await _productInvoicesController.PutProductInvoice(3,
new ProductInvoiceEditModel
{
State = InvoiceState.Regenerated
});

Assert.IsNotNull(result);
Assert.IsNull(result.Value);
Expand All @@ -135,11 +133,12 @@ public async Task Update_Non_Existent_ProductInvoice()
[Test]
public async Task Save_New_ProductInvoice()
{
ActionResult<ProductInvoiceViewModel> result = await _productInvoicesController.PostProductInvoice(new ProductInvoiceInputModel
{
ClientId = "1007870922",
State = InvoiceState.Generated
});
ActionResult<ProductInvoiceViewModel> result = await _productInvoicesController.PostProductInvoice(
new ProductInvoiceInputModel
{
ClientId = "1007870922",
State = InvoiceState.Generated
});

Assert.NotNull(result);
Assert.NotNull(result.Value);
Expand Down
32 changes: 16 additions & 16 deletions Kaizen.Test/Controllers/ServiceInvoicesControllerTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
using Kaizen.Domain.Repositories;
using Kaizen.Models.ServiceInvoice;
using Kaizen.Test.Helpers;
using MercadoPago.Client.Payment;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Moq;
Expand All @@ -20,17 +19,15 @@ public class ServiceInvoicesControllerTest : BaseControllerTest
private ServiceInvoicesController _serviceInvoicesController;
private Mock<IServiceInvoicesRepository> _serviceInvoicesRepository;
private Mock<IUnitWork> _unitWork;
private Mock<PaymentClient> _paymentClient;

[SetUp]
public void SetUp()
{
_serviceInvoicesRepository = new Mock<IServiceInvoicesRepository>();
_unitWork = new Mock<IUnitWork>();
_paymentClient = new Mock<PaymentClient>();

_serviceInvoicesController = new ServiceInvoicesController(_serviceInvoicesRepository.Object,
_unitWork.Object, ServiceProvider.GetService<IMapper>(), _paymentClient.Object);
_unitWork.Object, ServiceProvider.GetService<IMapper>());

SetUpServiceInvoicesRepository();
SetUpUnitWork();
Expand Down Expand Up @@ -71,7 +68,7 @@ private void SetUpServiceInvoicesRepository()
}
});

_serviceInvoicesRepository.Setup(r => r.FindByIdAsync(3)).ReturnsAsync((ServiceInvoice)null);
_serviceInvoicesRepository.Setup(r => r.FindByIdAsync(3)).ReturnsAsync((ServiceInvoice) null);

_serviceInvoicesRepository.Setup(r => r.GetClientInvoices("1007870922"))
.ReturnsAsync(new List<ServiceInvoice>
Expand Down Expand Up @@ -128,7 +125,8 @@ public async Task Get_Non_Existent_ServiceInvoice()
[Test]
public async Task Get_ClientInvoices()
{
OkObjectResult result = (await _serviceInvoicesController.ClientInvoices("1007870922")).Result as OkObjectResult;
OkObjectResult result =
(await _serviceInvoicesController.ClientInvoices("1007870922")).Result as OkObjectResult;

Assert.IsNotNull(result);
Assert.IsNotNull(result.Value);
Expand All @@ -138,11 +136,12 @@ public async Task Get_ClientInvoices()
[Test]
public async Task Update_Existing_ServiceInvoice()
{
ActionResult<ServiceInvoiceViewModel> result = await _serviceInvoicesController.PutServiceInvoice(1, new ServiceInvoiceEditModel
{
PaymentMethod = PaymentMethod.Cash,
State = InvoiceState.Paid
});
ActionResult<ServiceInvoiceViewModel> result = await _serviceInvoicesController.PutServiceInvoice(1,
new ServiceInvoiceEditModel
{
PaymentMethod = PaymentMethod.Cash,
State = InvoiceState.Paid
});

Assert.IsNotNull(result);
Assert.IsNotNull(result.Value);
Expand All @@ -152,11 +151,12 @@ public async Task Update_Existing_ServiceInvoice()
[Test]
public async Task Update_Non_Existent_ServiceInvoice()
{
ActionResult<ServiceInvoiceViewModel> result = await _serviceInvoicesController.PutServiceInvoice(3, new ServiceInvoiceEditModel
{
PaymentMethod = PaymentMethod.Cash,
State = InvoiceState.Paid
});
ActionResult<ServiceInvoiceViewModel> result = await _serviceInvoicesController.PutServiceInvoice(3,
new ServiceInvoiceEditModel
{
PaymentMethod = PaymentMethod.Cash,
State = InvoiceState.Paid
});

Assert.IsNotNull(result);
Assert.IsNull(result.Value);
Expand Down
168 changes: 168 additions & 0 deletions Kaizen/Controllers/PaymentsController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using AutoMapper;
using Kaizen.Domain.Entities;
using Kaizen.Domain.Events;
using Kaizen.Domain.Repositories;
using Kaizen.Models.Base;
using Kaizen.Models.ProductInvoice;
using Kaizen.Models.ServiceInvoice;
using MercadoPago.Client.Payment;
using MercadoPago.Resource.Payment;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;

namespace Kaizen.Controllers
{
[Route("api/[controller]")]
[ApiController]
[Authorize]
public class PaymentsController : ControllerBase
{
private readonly PaymentClient _paymentClient;
private readonly IProductInvoicesRepository _productInvoicesRepository;
private readonly IServiceInvoicesRepository _serviceInvoicesRepository;
private readonly IUnitWork _unitWork;
private readonly IMapper _mapper;

public PaymentsController(PaymentClient paymentClient, IProductInvoicesRepository productInvoicesRepository,
IServiceInvoicesRepository serviceInvoicesRepository, IUnitWork unitWork, IMapper mapper)
{
_paymentClient = paymentClient;
_productInvoicesRepository = productInvoicesRepository;
_serviceInvoicesRepository = serviceInvoicesRepository;
_unitWork = unitWork;
_mapper = mapper;
}

[HttpPost("[action]/{id:int}")]
public async Task<ActionResult<ProductInvoiceViewModel>> PayProductInvoice(int id,
[FromBody] PaymentModel paymentModel)
{
ProductInvoice productInvoice = await _productInvoicesRepository.FindByIdAsync(id);
if (productInvoice is null)
{
return NotFound($"No existe ninguna factura de producto con el código {id}");
}

productInvoice.CalculateTotal();

PaymentCreateRequest paymentCreateRequest = new PaymentCreateRequest
{
Token = paymentModel.Token,
PaymentMethodId = paymentModel.PaymentMethodId,
TransactionAmount = productInvoice.Total,
Description = $"Pay for product invoice {id}",
Installments = 1,
Payer = new PaymentPayerRequest
{
FirstName = productInvoice.Client.FirstName,
LastName = productInvoice.Client.LastName,
Email = paymentModel.Email
}
};

Payment payment = await _paymentClient.CreateAsync(paymentCreateRequest);

if (payment.Status == PaymentStatus.Rejected)
{
return BadRequest("El pago no pudo ser procesado.");
}

productInvoice.PublishEvent(new PaidInvoice(productInvoice));
productInvoice.State = InvoiceState.Paid;
productInvoice.PaymentDate = DateTime.Now;
productInvoice.PaymentMethod = PaymentMethod.CreditCard;

_productInvoicesRepository.Update(productInvoice);

try
{
await _unitWork.SaveAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!ProductInvoiceExists(id))
{
return NotFound(
$"Error de actualizacón. No existe ninguna factura de producto con el código {id}.");
}

throw;
}

return _mapper.Map<ProductInvoiceViewModel>(productInvoice);
}

private bool ProductInvoiceExists(int id)
{
return _productInvoicesRepository.GetAll().Any(p => p.Id == id);
}

[HttpPost("[action]/{id:int}")]
public async Task<ActionResult<ServiceInvoiceViewModel>> PayServiceInvoice(int id,
[FromBody] PaymentModel paymentModel)
{
ServiceInvoice serviceInvoice = await _serviceInvoicesRepository.FindByIdAsync(id);
if (serviceInvoice is null)
{
return NotFound($"No existe ninguna factura de servicio con el código {id}.");
}

serviceInvoice.CalculateTotal();

PaymentCreateRequest paymentCreateRequest = new PaymentCreateRequest
{
Token = paymentModel.Token,
PaymentMethodId = paymentModel.PaymentMethodId,
TransactionAmount = serviceInvoice.Total,
Description = $"Pay of service invoice {serviceInvoice.Id}",
Installments = 1,
Payer = new PaymentPayerRequest
{
FirstName = serviceInvoice.Client.FirstName,
LastName = serviceInvoice.Client.LastName,
Email = paymentModel.Email
}
};

Payment payment = await _paymentClient.CreateAsync(paymentCreateRequest);

if (payment.Status == PaymentStatus.Rejected)
{
return BadRequest("El pago no pudo ser procesado.");
}

serviceInvoice.State = InvoiceState.Paid;
serviceInvoice.PaymentDate = DateTime.Now;
serviceInvoice.PaymentMethod = PaymentMethod.CreditCard;

serviceInvoice.PublishEvent(new PaidInvoice(serviceInvoice));
_serviceInvoicesRepository.Update(serviceInvoice);

try
{
await _unitWork.SaveAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!ServiceInvoiceExists(id))
{
return NotFound(
$"Error de actualizacón. No existe ninguna factura de servicio con el código {id}.");
}

throw;
}

return _mapper.Map<ServiceInvoiceViewModel>(serviceInvoice);
}

private bool ServiceInvoiceExists(int id)
{
return _serviceInvoicesRepository.GetAll().Any(s => s.Id == id);
}
}
}
Loading

0 comments on commit 193bcb3

Please sign in to comment.