331 lines
16 KiB
C#
331 lines
16 KiB
C#
using System.Threading.Tasks;
|
|
using Asp.Versioning;
|
|
using AutoMapper;
|
|
using gehGassi.Core.Interfaces;
|
|
using gehGassi.Domain.Common;
|
|
using gehGassi.Domain.Vouchers;
|
|
using gehGassi.Dto;
|
|
using gehGassi.Dto.Common;
|
|
using gehGassi.Dto.Vouchers;
|
|
using gehGassi.Web.Helper;
|
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Hosting;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.Extensions.Hosting;
|
|
using Microsoft.Extensions.Logging;
|
|
using Microsoft.Extensions.Options;
|
|
|
|
namespace gehGassi.Web.Controllers.Api
|
|
{
|
|
/// <summary>
|
|
/// Controller für die Verwaltung von Gutscheinen
|
|
/// </summary>
|
|
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
|
|
[ApiController]
|
|
[ApiVersion(1)]
|
|
[Route("api/vouchers")]
|
|
[Route("api/v{v:apiVersion}/vouchers")]
|
|
public class ApiVoucherController : ApiBaseController
|
|
{
|
|
private readonly ILogger<ApiVoucherController> _logger;
|
|
private readonly IVoucherCampaignService _voucherCampaignService;
|
|
private readonly IMangoPayService _mangoPayService;
|
|
private readonly IWebHostEnvironment _hostEnvironment;
|
|
private readonly IWalletService _walletService;
|
|
private readonly IWalkService _walkService;
|
|
private readonly ICustomerService _customerService;
|
|
|
|
/// <summary>
|
|
/// Erstellt eine Instanz
|
|
/// </summary>
|
|
/// <param name="mapper">Instanz eines IMapper</param>
|
|
/// <param name="logger">Instanz eines ILogger</param>
|
|
/// <param name="localizationOptions">Instanz von LocalizationOptions</param>
|
|
/// <param name="appUserService">Instanz eines IAppUserService</param>
|
|
/// <param name="voucherCampaignService">Instanz eines IVoucherCampaignService</param>
|
|
/// <param name="mangoPayService">Instanz eines IMangoPayService</param>
|
|
/// <param name="hostEnvironment">Instanz eines IWebHostEnvironment</param>
|
|
/// <param name="walletService">Instanz eines IWalletService</param>
|
|
/// <param name="walkService">Instanz eines IWalkService</param>
|
|
/// <param name="customerService">Instanz eines ICustomerService</param>
|
|
public ApiVoucherController(IMapper mapper, ILogger<ApiVoucherController> logger, IOptions<LocalizationOptions> localizationOptions, IAppUserService appUserService,
|
|
IVoucherCampaignService voucherCampaignService, IMangoPayService mangoPayService, IWebHostEnvironment hostEnvironment, IWalletService walletService,
|
|
IWalkService walkService, ICustomerService customerService) : base(mapper, localizationOptions, appUserService)
|
|
{
|
|
_logger = logger;
|
|
_voucherCampaignService = voucherCampaignService;
|
|
_mangoPayService = mangoPayService;
|
|
_hostEnvironment = hostEnvironment;
|
|
_walletService = walletService;
|
|
_walkService = walkService;
|
|
_customerService = customerService;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Prüfen eines Gutscheincodes für einen AppUser
|
|
/// </summary>
|
|
/// <param name="dto">Model mit Code und AppUserId</param>
|
|
/// <returns>HTTP 200 OK wenn erfolgreich</returns>
|
|
[HttpPost]
|
|
[Route("CheckVoucherCode")]
|
|
public async Task<IActionResult> CheckVoucherCode(CheckVoucherCodeDto dto)
|
|
{
|
|
var validationResult = await _voucherCampaignService.ValidateVoucherCodeAsync(dto.Code, dto.AppUserId);
|
|
|
|
if (User?.Identity != null && User.Identity.IsAuthenticated)
|
|
{
|
|
if (ModelState.IsValid)
|
|
{
|
|
var result = new CheckVoucherCodeResultDto()
|
|
{
|
|
VoucherId = string.Empty,
|
|
VoucherCampaignId = string.Empty,
|
|
VoucherAmmount = 0,
|
|
CampaignType = VoucherCampaignTypeDto.SingleVoucher,
|
|
ValidationResult = (VoucherValidationResultDto)validationResult
|
|
};
|
|
|
|
if (validationResult == VoucherValidationResult.Valid)
|
|
{
|
|
var voucher = await _voucherCampaignService.GetVoucherByCodeAsync(dto.Code);
|
|
result.VoucherId = voucher.Id;
|
|
result.VoucherCampaignId = voucher.VoucherCampaignId;
|
|
result.VoucherAmmount = voucher.VoucherAmmount;
|
|
|
|
var campaign = await _voucherCampaignService.GetAsync(voucher.VoucherCampaignId);
|
|
if (campaign != null)
|
|
{
|
|
result.CampaignType = (VoucherCampaignTypeDto)campaign.CampaignType;
|
|
//Nun noch das Budget gegen das Wallet prüfen
|
|
if (!_hostEnvironment.IsDevelopment())
|
|
result.ValidationResult = (VoucherValidationResultDto)await CheckBalance(campaign.WalletCreditId, voucher.VoucherAmmount);
|
|
}
|
|
}
|
|
|
|
return Ok(result);
|
|
}
|
|
}
|
|
return BadRequest(CommunicationErrors.Common_Model_Invalid);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Holt einen Gutscheincode anhand des QR-Codes
|
|
/// </summary>
|
|
/// <param name="dto">Model mit QR-Code</param>
|
|
/// <returns>HTTP 200 OK wenn erfolgreich</returns>
|
|
[HttpPost]
|
|
[Route("GetVoucherCodeByQrCode")]
|
|
public async Task<IActionResult> GetVoucherCodeByQrCode(GetVoucherByQrCodeDto dto)
|
|
{
|
|
if (User?.Identity != null && User.Identity.IsAuthenticated)
|
|
{
|
|
var result = new VoucherByQrCodeResultDto()
|
|
{
|
|
Exists = false,
|
|
Code = string.Empty
|
|
};
|
|
|
|
var voucher = await _voucherCampaignService.GetVoucherByQrCodeAsync(dto.QrCode);
|
|
if (voucher != null)
|
|
{
|
|
result.Exists = true;
|
|
result.Code = voucher.Code;
|
|
}
|
|
|
|
return Ok(result);
|
|
}
|
|
return BadRequest(CommunicationErrors.Common_Model_Invalid);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reserviert einen Gutschein für einen Walk
|
|
/// </summary>
|
|
/// <param name="dto">Model mit nötigen Daten</param>
|
|
/// <returns>HTTP 200 OK wenn erfolgreich</returns>
|
|
[HttpPost]
|
|
[Route("ReserveVoucher")]
|
|
public async Task<IActionResult> ReserveVoucher(ReserveVoucherDto dto)
|
|
{
|
|
var result = new ReserveVoucherResultDto()
|
|
{
|
|
Success = false,
|
|
VoucherUsageId = -1
|
|
};
|
|
|
|
if (User?.Identity != null && User.Identity.IsAuthenticated)
|
|
{
|
|
if (ModelState.IsValid)
|
|
{
|
|
//1. Prüfen ob der Gutschein existiert und gültig ist
|
|
var validationResult = await _voucherCampaignService.ValidateVoucherCodeAsync(dto.Code, dto.AppUserId);
|
|
|
|
if (validationResult == VoucherValidationResult.Valid)
|
|
{
|
|
var voucher = await _voucherCampaignService.GetVoucherByCodeAsync(dto.Code);
|
|
if (voucher != null && voucher.Id == dto.VoucherId)
|
|
{
|
|
var campaign = await _voucherCampaignService.GetAsync(voucher.VoucherCampaignId);
|
|
if (campaign != null)
|
|
{
|
|
var customer = await _customerService.GetAsync(campaign.CustomerId);
|
|
if (customer != null)
|
|
{
|
|
//2. Prüfen ob noch genug Budget in der Kampagne vorhanden ist
|
|
validationResult = await CheckBalance(campaign.WalletCreditId, voucher.VoucherAmmount);
|
|
|
|
if (validationResult == VoucherValidationResult.Valid)
|
|
{
|
|
//3. Geld vom Guthabenkonto der Kamapgne auf das Transferskonto überweisen mit Verweis auf den Walk und Transaktion erfassen
|
|
var ammount = (int)(dto.Ammount * 100);
|
|
var transferResult = await _mangoPayService.TransferMoneyAsync(customer.MangopayPaymentId, campaign.WalletCreditId,
|
|
customer.MangopayPaymentId, campaign.WalletFeeId, dto.WalkId, ammount, 0, $"VoucherId_{voucher.Id}_WalkId_{dto.WalkId}", "", "");
|
|
|
|
if (transferResult.Success)
|
|
{
|
|
//4. Reservieren durch die Anlage einer VoucherUsage
|
|
var voucherUsage = await _voucherCampaignService.ReserveVoucherAsync(voucher.Id, dto.AppUserId, dto.WalkId, voucher.VoucherAmmount, dto.Ammount);
|
|
|
|
//5. Den Gutschein beim Walk eintragen
|
|
await _walkService.AddVoucherToWalk(dto.WalkId, voucher.Id, dto.Ammount);
|
|
|
|
//6. Usage in der Kampagne eintragen (VouchersUsed, BudgetUsed)
|
|
campaign.VouchersUsed += 1;
|
|
campaign.BudgetUsed += dto.Ammount;
|
|
|
|
//7. Usage beim voucher eintragen (UsedCount, IsValid wenn Einzelgutschein)
|
|
voucher.UsedCount += 1;
|
|
voucher.IsValid = campaign.CampaignType != VoucherCampaignType.MultiVoucher;
|
|
|
|
await _voucherCampaignService.CommitAsync(User.Identity.Name);
|
|
result.Success = true;
|
|
result.VoucherUsageId = voucherUsage.Id;
|
|
}
|
|
else
|
|
{
|
|
result.TransferFailed = true;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
result.CustomerNotFound = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
result.CampaignNotFound = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
result.VoucherNotFound = true;
|
|
}
|
|
}
|
|
|
|
result.ValidationResult = (VoucherValidationResultDto)validationResult;
|
|
|
|
return Ok(result);
|
|
}
|
|
}
|
|
return BadRequest(CommunicationErrors.Common_Model_Invalid);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Stornieren eines Gutscheins
|
|
/// </summary>
|
|
/// <param name="dto">Model mit nötigen Daten</param>
|
|
/// <returns>HTTP 200 OK wenn erfolgreich</returns>
|
|
[HttpPost]
|
|
[Route("CancelVoucher")]
|
|
public async Task<IActionResult> CancelVoucher(CancelVoucherDto dto)
|
|
{
|
|
if (User?.Identity != null && User.Identity.IsAuthenticated)
|
|
{
|
|
if (ModelState.IsValid)
|
|
{
|
|
var usage = await _voucherCampaignService.GetUsageAsync(dto.VoucherId, dto.AppUserId, dto.WalkId);
|
|
if (usage != null)
|
|
{
|
|
var voucher = await _voucherCampaignService.GetVoucherAsync(usage.VoucherId);
|
|
if (voucher != null && voucher.Id == dto.VoucherId)
|
|
{
|
|
var campaign = await _voucherCampaignService.GetAsync(voucher.VoucherCampaignId);
|
|
if (campaign != null)
|
|
{
|
|
var customer = await _customerService.GetAsync(campaign.CustomerId);
|
|
if (customer != null)
|
|
{
|
|
//Geld vom Transferkonto der Kamapgne auf das Guthabenkonto überweisen mit Verweis auf den Walk und Transaktion erfassen
|
|
var ammount = (int)(usage.VoucherAmmountUsed * 100);
|
|
var transferResult = await _mangoPayService.TransferMoneyAsync(customer.MangopayPaymentId, campaign.WalletFeeId,
|
|
customer.MangopayPaymentId, campaign.WalletCreditId, dto.WalkId, ammount, 0, $"VoucherId_{voucher.Id}_WalkId_{dto.WalkId}", "", "");
|
|
|
|
if (transferResult.Success)
|
|
{
|
|
//Usage beim voucher zurücksetzen (UsedCount, IsValid wenn Einzelgutschein)
|
|
voucher.UsedCount -= 1;
|
|
if (voucher.UsedCount < 0)
|
|
voucher.UsedCount = 0;
|
|
voucher.IsValid = true;
|
|
|
|
//Usage in der Kampagne zurücksetzen (VouchersUsed, BudgetUsed)
|
|
campaign.VouchersUsed -= 1;
|
|
if (campaign.VouchersUsed < 0)
|
|
campaign.VouchersUsed = 0;
|
|
campaign.BudgetUsed -= usage.VoucherAmmountUsed;
|
|
if(campaign.BudgetUsed < 0)
|
|
campaign.BudgetUsed = 0;
|
|
|
|
//Den Gutschein vom Walk entfernen
|
|
await _walkService.RemoveVoucherFromWalk(dto.WalkId, voucher.Id);
|
|
|
|
//Reservieren durch die Anlage einer VoucherUsage
|
|
_voucherCampaignService.RemoveUsage(usage);
|
|
|
|
await _voucherCampaignService.CommitAsync(User.Identity.Name);
|
|
return Ok();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return NotFound(CommunicationErrors.Common_NotFound);
|
|
}
|
|
}
|
|
return BadRequest(CommunicationErrors.Common_Model_Invalid);
|
|
}
|
|
|
|
|
|
#region Private
|
|
|
|
/// <summary>
|
|
/// Prüft ob ein Wallet genug Guthaben hat
|
|
/// </summary>
|
|
/// <param name="walletId">Id des Wallets</param>
|
|
/// <param name="minAmmount">Minimum Guthaben</param>
|
|
/// <returns>VoucherValidationResultDto</returns>
|
|
private async Task<VoucherValidationResult> CheckBalance(string walletId, decimal minAmmount)
|
|
{
|
|
var wallet = await _walletService.GetAsync(walletId);
|
|
if (wallet != null)
|
|
{
|
|
var mangoPayResult = await _mangoPayService.GetWalletBalanceAsync(wallet.WalletId);
|
|
if (mangoPayResult.Success)
|
|
{
|
|
if ((decimal)(mangoPayResult.Value / 100) < minAmmount)
|
|
{
|
|
return VoucherValidationResult.CampaignBudgetUsedUp;
|
|
}
|
|
return VoucherValidationResult.Valid;
|
|
}
|
|
return VoucherValidationResult.Invalid;
|
|
}
|
|
|
|
return VoucherValidationResult.Invalid;
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|