using AutoMapper;
using gehGassi.Common.Data;
using gehGassi.Core.Interfaces;
using gehGassi.Core.Services;
using gehGassi.Domain.Common;
using gehGassi.Permissions;
using gehGassi.Web.Auth;
using gehGassi.Web.Auth.Attributes;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Localization;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using gehGassi.Web.Helper;
using gehGassi.Web.Models;
using System.Threading.Tasks;
using gehGassi.Domain.Dogs;
using gehGassi.Dto.Messages;
using System;
using gehGassi.Web.Hubs;
using gehGassi.External.Services;
namespace gehGassi.Web.Controllers
{
///
/// Controller für die Verwaltung von Reklamationen
///
[Authorize]
public class WalkComplaintController : BaseController
{
private readonly IMapper _mapper;
private readonly IStringLocalizer _localizer;
private readonly IWalkComplaintService _walkComplaintService;
private readonly IWalkService _walkService;
private readonly IAppUserService _appUserService;
private readonly IDogService _dogService;
private readonly ISystemMessageService _systemMessageService;
private readonly IAppHubSender _appHubSender;
private readonly ITransactionFeeService _transactionFeeService;
private readonly IWalletService _walletService;
private readonly IMangoPayService _mangoPayService;
private readonly IPushNotificationService _pushNotificationService;
///
/// Erstellt eine Instanz
///
/// Instanz eines IMapper
/// Instanz eines IStringLocalizer
/// Instanz eines IWalkComplaintService
/// Instanz eines IWalkService
/// Instanz eines IAppUserService
/// Instanz eines IDogService
/// Instanz eines ISystemMessageService
/// Instanz eines IAppHubSender
/// Instanz eines ITransactionFeeService
/// Instanz eines IWalletService
/// Instanz eines IMangoPayService
/// Instanz eines IPushNotificationService
public WalkComplaintController(IMapper mapper, IStringLocalizer localizer, IWalkComplaintService walkComplaintService, IWalkService walkService, IAppUserService appUserService, IDogService dogService,
ISystemMessageService systemMessageService, IAppHubSender appHubSender, ITransactionFeeService transactionFeeService, IWalletService walletService, IMangoPayService mangoPayService, IPushNotificationService pushNotificationService)
{
_mapper = mapper;
_localizer = localizer;
_walkComplaintService = walkComplaintService;
_walkService = walkService;
_appUserService = appUserService;
_dogService = dogService;
_systemMessageService = systemMessageService;
_appHubSender = appHubSender;
_transactionFeeService = transactionFeeService;
_walletService = walletService;
_mangoPayService = mangoPayService;
_pushNotificationService = pushNotificationService;
}
///
/// Gibt einen View für die Verwaltung von Reklamationen zurück
///
/// View
[Authorize(Policy = Policies.PowerUserOnly)]
[HasPermission(Permission.SettingsManage, Permission.SettingsComplaints)]
public IActionResult Index()
{
return View();
}
///
/// Gibt eine Liste von Entitäten basierend auf Abfragekriterien zurück
///
/// Abfragekriterien
/// Liste von gefundenen Entitäten
[Authorize(Policy = Policies.PowerUserOnly)]
[HasPermission(Permission.SettingsManage, Permission.SettingsComplaints)]
[HttpPost]
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult GetComplaints([FromBody] DataManager dm)
{
if (dm != null)
{
var propList = new List();
dm.SetComplexProperties(propList);
if (dm.Where != null)
{
foreach (var whereFilter in dm.Where)
{
if (whereFilter.predicates == null)
continue;
foreach (var whereFilterPredicate in whereFilter.predicates)
{
if (whereFilterPredicate.Field == "walkType")
whereFilterPredicate.value = (WalkType)((int)((long)whereFilterPredicate.value));
if (whereFilterPredicate.Field == "walkServiceType")
whereFilterPredicate.value = (WalkServiceType)((int)((long)whereFilterPredicate.value));
if (whereFilterPredicate.Field == "source")
whereFilterPredicate.value = (WalkComplaintSource)((int)((long)whereFilterPredicate.value));
if (whereFilterPredicate.Field == "type")
whereFilterPredicate.value = (WalkComplaintType)((int)((long)whereFilterPredicate.value));
if (whereFilterPredicate.Field == "status")
whereFilterPredicate.value = (WalkComplaintStatus)((int)((long)whereFilterPredicate.value));
}
}
}
}
var resultList = _walkComplaintService.FilterWithNames(dm?.SearchValue ?? "", false);
//Sortierung
resultList = dm.ApplySorting(resultList);
//Filter
resultList = dm.ApplyFiltering(resultList, out var countFiltered);
//Paging
resultList = dm.ApplyPaging(resultList);
var resultListVm = resultList.ToList().Select(item => _mapper.Map(item)).ToList();
foreach (var itemVm in resultListVm)
{
itemVm.WalkTypeText = itemVm.WalkType.GetDisplayName(AnnotationsLocalizer);
itemVm.WalkServiceTypeText = itemVm.WalkServiceType.GetDisplayName(AnnotationsLocalizer);
itemVm.SourceText = itemVm.Source.GetDisplayName(AnnotationsLocalizer);
itemVm.TypeText = itemVm.Type.GetDisplayName(AnnotationsLocalizer);
itemVm.StatusText = itemVm.Status.GetDisplayName(AnnotationsLocalizer);
}
//FilterPreview?
if (!dm.RequiresCounts)
return Json(resultListVm);
return Json(new { result = resultListVm, count = countFiltered });
}
///
/// Details einer Reklamation
///
/// Id der reklamation
/// PartialView
[Authorize(Policy = Policies.PowerUserOnly)]
[HasPermission(Permission.SettingsManage, Permission.SettingsComplaints)]
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public async Task Details(string id)
{
var item = await _walkComplaintService.GetAsync(id);
if (item != null)
{
var model = _mapper.Map(item);
//Nun noch weitere Details holen....
var walk = await _walkService.GetWalkWithNamesAsync(item.WalkId);
walk.Dogs = new List();
if (!string.IsNullOrWhiteSpace(walk.DogsJson))
{
var dogsList = JsonSerializer.Deserialize>(walk.DogsJson, new JsonSerializerOptions(JsonSerializerDefaults.Web));
foreach (var dogItem in dogsList)
{
var dog = await _dogService.GetWithNamesAsync(dogItem.Id, "DE", LocalizationOptions.Value.DefaultCulture, true);
if (dog != null)
{
walk.Dogs.Add(new DogMinInfo()
{
Id = dog.Id,
Index = dog.Index,
Version = dog.Version,
UpdatedAt = dog.UpdatedAt,
Deleted = dog.Deleted,
DogRaceId = dog.DogRaceId,
DogRaceName = dog.DogRaceName,
Name = dog.Name,
Sex = dog.Sex,
Size = dog.Size,
BirthDate = dog.BirthDate
});
}
}
}
ViewBag.Walk = walk;
var dogOwner = await _appUserService.GetAsync(walk.DogOwnerId);
ViewBag.DogOwner = dogOwner;
var dogWalker = await _appUserService.GetAsync(walk.DogWalkerId);
ViewBag.DogWalker = dogWalker;
return PartialView("_Details", model);
}
return PartialView("_Error");
}
///
/// Details einer Reklamation
///
/// Model
/// Json
[Authorize(Policy = Policies.PowerUserOnly)]
[HasPermission(Permission.SettingsManage, Permission.SettingsComplaints)]
[ValidateAntiForgeryToken]
[HttpPost]
public async Task Details(WalkComplaintVm model)
{
var result = new ResponseVm { Success = false };
if (ModelState.IsValid)
{
var item = await _walkComplaintService.GetAsync(model.Id);
if (item.Status < model.Status)
{
if (item.Status <= WalkComplaintStatus.InProgress)
{
item.Status = (WalkComplaintStatus)model.Status;
item.Comment = model.Comment;
item.UserName = User.Identity.Name;
await _walkComplaintService.CommitAsync(User.Identity.Name);
var walkUsed = await _walkService.GetAsync(model.WalkId);
//Nun den Status behandeln
if (item.Status > WalkComplaintStatus.InProgress)
{
item.Resolved = DateTimeOffset.UtcNow;
await _walkComplaintService.CommitAsync(User.Identity.Name);
walkUsed.Status = WalkStatus.ComplainResolved;
}
if (item.Status == WalkComplaintStatus.Resolved_Pay)
{
walkUsed.PaymentStatus = PaymentStatus.Paid;
await _walkService.CommitAsync(User.Identity.Name);
//Zahlung veranlassen....
decimal feeDecimal = 0;
long fee = 0;
var gehGassiFee = await _transactionFeeService.GetMinGehGassiFeeAsync(walkUsed.Price);
if (gehGassiFee != null)
{
if (gehGassiFee.Percent > 0)
{
var percent = walkUsed.Price * gehGassiFee.Percent / 100;
feeDecimal = percent;
}
if (gehGassiFee.Fixed > 0)
{
feeDecimal += gehGassiFee.Fixed;
}
}
if (feeDecimal > 0)
{
fee = (long)(feeDecimal * 100);
}
var sourceWallet = await _walletService.GetAsync(walkUsed.DogOwnerId, WalletType.Fees);
var targetWallet = await _walletService.GetAsync(walkUsed.DogWalkerId, WalletType.Credits);
if (sourceWallet != null && targetWallet != null)
{
var sourceUser = await _appUserService.GetAsync(walkUsed.DogOwnerId);
var targetUser = await _appUserService.GetAsync(walkUsed.DogWalkerId);
if (sourceUser != null && targetUser != null)
{
var ammount = (long)(walkUsed.Price * 100);
var transcationSuccess = await _mangoPayService.TransferMoneyAsync(walkUsed.DogOwnerId, walkUsed.DogWalkerId, walkUsed.Id, ammount, fee, $"WalkId_Payment_{walkUsed.Id}");
//Wallets aktualisieren
await _mangoPayService.GetWalletBalanceAsync(sourceUser.Id, WalletType.Credits);
await _mangoPayService.GetWalletBalanceAsync(sourceUser.Id, WalletType.Fees);
await _mangoPayService.GetWalletBalanceAsync(targetUser.Id, WalletType.Credits);
await _mangoPayService.GetWalletBalanceAsync(targetUser.Id, WalletType.Fees);
}
}
}
if (item.Status == WalkComplaintStatus.Resolved_Refund)
{
// Zurücküberweisen der Summe vom Transaktionskonto auf das Guthabenkonto
if (walkUsed.Price > 0)
{
var ammount = (long)(walkUsed.Price * 100);
var tag = $"Walk_Complaint_Refund_{walkUsed.Id}";
var refundResult = await _mangoPayService.TransferMoneyFromFeeToCreditAccountAsync(walkUsed.DogOwnerId, ammount, tag);
if (refundResult.Success)
walkUsed.PaymentStatus = PaymentStatus.Refunded;
else
walkUsed.PaymentStatus = PaymentStatus.Voided;
}
else
walkUsed.PaymentStatus = PaymentStatus.Voided;
await _walkService.CommitAsync(User.Identity.Name);
}
if (item.Status == WalkComplaintStatus.Resolved_Gehgassi)
{
// Zurücküberweisen der Summe vom Transaktionskonto auf das Guthabenkonto
if (walkUsed.Price > 0)
{
var ammount = (long)(walkUsed.Price * 100);
var tag = $"Walk_Complaint_RefundPay_{walkUsed.Id}";
var refundResult = await _mangoPayService.TransferMoneyFromFeeToCreditAccountAsync(walkUsed.DogOwnerId, ammount, tag);
if (refundResult.Success)
walkUsed.PaymentStatus = PaymentStatus.RefundendAndPayed;
else
walkUsed.PaymentStatus = PaymentStatus.Voided;
}
else
walkUsed.PaymentStatus = PaymentStatus.Voided;
await _walkService.CommitAsync(User.Identity.Name);
}
_systemMessageService.Add(walkUsed.DogWalkerId, AppUserType.DogWalker, walkUsed.Id, SystemMessageTables.Walk, SystemMessageType.WalkComplainedUpdate, DateTimeOffset.UtcNow.AddDays(14));
await _systemMessageService.CommitAsync(User.Identity.Name);
await _appHubSender.SystemMessageAddedAsync(walkUsed.DogWalkerId);
await _pushNotificationService.SendWalkComplainedUpdateAsync(walkUsed.DogWalkerId, walkUsed.Id, AppMode.DogWalker);
_systemMessageService.Add(walkUsed.DogOwnerId, AppUserType.DogOwner, walkUsed.Id, SystemMessageTables.Walk, SystemMessageType.WalkComplainedUpdate, DateTimeOffset.UtcNow.AddDays(14));
await _systemMessageService.CommitAsync(User.Identity.Name);
await _appHubSender.SystemMessageAddedAsync(walkUsed.DogOwnerId);
await _pushNotificationService.SendWalkComplainedUpdateAsync(walkUsed.DogOwnerId, walkUsed.Id, AppMode.DogOwner);
}
}
else
{
item.Comment = model.Comment;
item.UserName = User.Identity.Name;
await _walkComplaintService.CommitAsync(User.Identity.Name);
}
result.Data = item.ToCamelCaseJson();
result.Success = true;
result.Html = string.Empty;
return Json(new { result.Success, result.Html, result.Data });
}
//Nun noch weitere Details holen....
var walk = await _walkService.GetWalkWithNamesAsync(model.WalkId);
walk.Dogs = new List();
if (!string.IsNullOrWhiteSpace(walk.DogsJson))
{
var dogsList = JsonSerializer.Deserialize>(walk.DogsJson, new JsonSerializerOptions(JsonSerializerDefaults.Web));
foreach (var dogItem in dogsList)
{
var dog = await _dogService.GetWithNamesAsync(dogItem.Id, "DE", LocalizationOptions.Value.DefaultCulture, true);
if (dog != null)
{
walk.Dogs.Add(new DogMinInfo()
{
Id = dog.Id,
Index = dog.Index,
Version = dog.Version,
UpdatedAt = dog.UpdatedAt,
Deleted = dog.Deleted,
DogRaceId = dog.DogRaceId,
DogRaceName = dog.DogRaceName,
Name = dog.Name,
Sex = dog.Sex,
Size = dog.Size,
BirthDate = dog.BirthDate
});
}
}
}
ViewBag.Walk = walk;
var dogOwner = await _appUserService.GetAsync(walk.DogOwnerId);
ViewBag.DogOwner = dogOwner;
var dogWalker = await _appUserService.GetAsync(walk.DogWalkerId);
ViewBag.DogWalker = dogWalker;
result.Html = await PartialView("_Details", model).ToStringAsync(ControllerContext);
return Json(result);
}
}
}