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); } } }