855 lines
39 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using AutoMapper;
using gehGassi.Common.Data;
using gehGassi.Core.Interfaces;
using gehGassi.Core.Services;
using gehGassi.Domain.Common;
using gehGassi.Domain.Dogs;
using gehGassi.External.Services;
using gehGassi.Permissions;
using gehGassi.Web.Auth;
using gehGassi.Web.Auth.Attributes;
using gehGassi.Web.Helper;
using gehGassi.Web.Hubs;
using gehGassi.Web.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Localization;
using NetTopologySuite;
using NetTopologySuite.Geometries;
namespace gehGassi.Web.Controllers
{
/// <summary>
/// Controller für die Verwaltung von App-Usern
/// </summary>
[Authorize]
public class AppUserController : BaseController
{
private readonly IMapper _mapper;
private readonly IStringLocalizer<AppUserController> _localizer;
private readonly IAppUserService _appUserService;
private readonly ICountryService _countryService;
private readonly IUserService _userService;
private readonly IGeoLocationService _geoLocationService;
private readonly IAppHubSender _appHubSender;
private readonly IPushNotificationService _pushNotificationService;
private readonly IWalkService _walkService;
private readonly IPublicWalkResponseService _publicWalkResponseService;
private readonly IFavouriteService _favouriteService;
private readonly ISystemMessageService _systemMessageService;
private readonly IDeviceService _deviceService;
private readonly IRefreshTokenService _refreshTokenService;
private readonly IRatingService _ratingService;
private readonly IMessageService _messageService;
private readonly IAppUserReportService _appUserReportService;
private readonly IVoucherCampaignService _voucherCampaignService;
/// <summary>
/// Erstellt eine Instanz
/// </summary>
/// <param name="mapper">Instanz eines IMapper</param>
/// <param name="localizer">Instanz eines IStringLocalizer</param>
/// <param name="appUserService">Instanz eines IDogOwnerService</param>
/// <param name="countryService">Instanz eines ICountryService</param>
/// <param name="userService">Instanz eines IUserService</param>
/// <param name="geoLocationService">Instanz eines IGeoLocationService</param>
/// <param name="appHubSender">Instanz eines IAppHubSender</param>
/// <param name="pushNotificationService">Instanz eines IPushNotificationService</param>
/// <param name="walkService">Instanz eines IWalkService</param>
/// <param name="publicWalkResponseService">Instanz eines IPublicWalkResponseService</param>
/// <param name="favouriteService">Instanz eines IFavouriteService</param>
/// <param name="systemMessageService">Instanz eines ISystemMessageService</param>
/// <param name="deviceService">Instanz eines IDeviceService</param>
/// <param name="refreshTokenService">Instanz eines IRefreshTokenService</param>
/// <param name="ratingService">Instanz eines IRatingService</param>
/// <param name="messageService">Instanz eines IMessageService</param>
/// <param name="appUserReportService">Instanz eines IAppUserReportService</param>
/// <param name="voucherCampaignService">Instanz eines IVoucherCampaignService</param>
public AppUserController(IMapper mapper, IStringLocalizer<AppUserController> localizer, IAppUserService appUserService, ICountryService countryService, IUserService userService,
IGeoLocationService geoLocationService, IAppHubSender appHubSender, IPushNotificationService pushNotificationService, IWalkService walkService, IPublicWalkResponseService publicWalkResponseService,
IFavouriteService favouriteService, ISystemMessageService systemMessageService, IDeviceService deviceService, IRefreshTokenService refreshTokenService, IRatingService ratingService,
IMessageService messageService, IAppUserReportService appUserReportService, IVoucherCampaignService voucherCampaignService)
{
_mapper = mapper;
_localizer = localizer;
_appUserService = appUserService;
_countryService = countryService;
_userService = userService;
_geoLocationService = geoLocationService;
_appHubSender = appHubSender;
_pushNotificationService = pushNotificationService;
_walkService = walkService;
_publicWalkResponseService = publicWalkResponseService;
_favouriteService = favouriteService;
_systemMessageService = systemMessageService;
_deviceService = deviceService;
_refreshTokenService = refreshTokenService;
_ratingService = ratingService;
_messageService = messageService;
_appUserReportService = appUserReportService;
_voucherCampaignService = voucherCampaignService;
}
/// <summary>
/// Gibt einen View für die App-User-Verwaltung zurück
/// </summary>
/// <returns>View</returns>
[Authorize(Policy = Policies.PowerUserOnly)]
[HasPermission(Permission.AppUsersManage, Permission.AppUsersRead)]
public IActionResult Index()
{
return View();
}
/// <summary>
/// Gibt eine Liste von Entitäten basierend auf Abfragekriterien zurück
/// </summary>
/// <param name="dm">Abfragekriterien</param>
/// <returns>Liste von gefundenen Entitäten</returns>
[Authorize(Policy = Policies.PowerUserOnly)]
[HasPermission(Permission.AppUsersManage, Permission.AppUsersRead)]
[HttpPost]
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult GetAppUsers([FromBody] DataManager dm)
{
if (dm != null)
{
var propList = new List<ComplexProperty>
{
new() { Original = "email", Complex = "Contact.Email" },
new() { Original = "city", Complex = "Address.City" },
new() { Original = "zip", Complex = "Address.Zip" },
new() { Original = "countryCode", Complex = "Address.CountryCode" },
new() { Original = "state", Complex = "Address.State" }
};
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 == "type")
whereFilterPredicate.value = (AppUserType)((int)((long)whereFilterPredicate.value));
if (whereFilterPredicate.Field == "sex")
whereFilterPredicate.value = (Sex)((int)((long)whereFilterPredicate.value));
}
}
}
}
var resultList = _appUserService.Filter(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<AppUserListVm>(item)).ToList();
foreach (var itemVm in resultListVm)
{
itemVm.TypeText = itemVm.Type.GetDisplayName(AnnotationsLocalizer);
itemVm.SexText = itemVm.Sex.GetDisplayName(AnnotationsLocalizer);
itemVm.Photo = Tools.GetPhotoThumb(itemVm.Photo, 100);
}
//FilterPreview?
if (!dm.RequiresCounts)
return Json(resultListVm);
return Json(new { result = resultListVm, count = countFiltered });
}
/// <summary>
/// Anlegen eines App-Users
/// </summary>
/// <returns>PartialView</returns>
[Authorize(Policy = Policies.PowerUserOnly)]
[HasPermission(Permission.AppUsersManage, Permission.AppUsersCreate)]
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Create()
{
var model = new AppUserCrudVm()
{
Id = Guid.NewGuid().ToString("N"),
Number = _appUserService.GetNextNumber()
};
return PartialView("_Create", model);
}
/// <summary>
/// Anlegen eines App-Users
/// </summary>
/// <param name="model">Model</param>
/// <returns>Json</returns>
[Authorize(Policy = Policies.PowerUserOnly)]
[HasPermission(Permission.AppUsersManage, Permission.AppUsersCreate)]
[ValidateAntiForgeryToken]
[HttpPost]
public async Task<IActionResult> Create(AppUserCrudVm model)
{
var result = new ResponseVm { Success = false };
if (ModelState.IsValid)
{
var item = _appUserService.Create();
_mapper.Map(model, item);
if(model.TermsAccepted)
item.TermsAcceptedDate = DateTimeOffset.UtcNow;
else
item.TermsAcceptedDate = null;
if (model.PrivacyAccepted)
item.PrivacyAcceptedDate = DateTimeOffset.UtcNow;
else
item.PrivacyAcceptedDate = null;
if (model.PaymentTermsAccepted)
item.PaymentTermsAcceptedDate = DateTimeOffset.UtcNow;
else
item.PaymentTermsAcceptedDate = null;
if (model.Verified)
item.VerifiedDate = DateTimeOffset.UtcNow;
else
item.VerifiedDate = null;
if (model.KycPassed)
item.KycPassedDate = DateTimeOffset.UtcNow;
else
item.KycPassedDate = null;
if (model.BirthDate.HasValue)
item.BirthDate = new DateTimeOffset(model.BirthDate.Value.DateTime, TimeSpan.Zero);
item.Created = DateTimeOffset.UtcNow;
item.UpdatedAt = DateTimeOffset.UtcNow;
var location = await _geoLocationService.GetLocationAsync(item.Address, SelectedLanguage);
if (location.Success)
{
var geometryFactory = NtsGeometryServices.Instance.CreateGeometryFactory(srid: 4326);
var geoLocation = geometryFactory.CreatePoint(new Coordinate(location.Longitude, location.Latitude));
item.Location = geoLocation;
}
_appUserService.Add(item);
await _appUserService.CommitAsync(User.Identity.Name);
if (item.Type != AppUserType.DogOwner)
{
await _appUserService.CreateWalkerProfileIfNotExistsAsync(item.Id);
await _appUserService.CommitAsync(User.Identity.Name);
}
if (!string.IsNullOrWhiteSpace(model.Photo))
{
//Nun das Bild umbenennen und dann kopieren. Ebenso Thumbnails erstellen
var extension = Path.GetExtension(model.Photo);
var fileName = Path.GetFileName(model.Photo);
var filenameToUse = FileServiceHelper.GetAppUserPath(item.Id) + $"photo-{Guid.NewGuid():N}{extension}";
item.Photo = filenameToUse;
await _appUserService.CommitAsync(User.Identity.Name);
//Kopieren
var tempFile = await FileService.GetAsync(FileServiceHelper.TempContainer, model.Photo);
await FileService.StoreAsync(FileServiceHelper.DocumentContainer, filenameToUse, tempFile);
//Thumbnails
await GenerateThumbnail(FileServiceHelper.DocumentContainer, filenameToUse, 400);
await GenerateThumbnail(FileServiceHelper.DocumentContainer, filenameToUse, 200);
await GenerateThumbnail(FileServiceHelper.DocumentContainer, filenameToUse, 100);
//Altes Löschen
await FileService.DeleteAsync(FileServiceHelper.TempContainer, model.Photo);
}
result.Data = item.ToCamelCaseJson();
result.Success = true;
result.Html = string.Empty;
return Json(result);
}
ModelState.Remove("CountryName");
var country = _countryService.GetCountry(model.Address.CountryCode);
model.CountryName = country != null ? country.Name : "";
ModelState.Remove("StateName");
var state = _countryService.GetState(model.Address.CountryCode, model.Address.State);
model.StateName = state != null ? state.Name : "";
ModelState.Remove("NationalityName");
var nationality = _countryService.GetCountry(model.NationalityCode);
model.NationalityName = nationality != null ? nationality.Name : "";
ModelState.Remove("MainResidenceName");
var mainResidence = _countryService.GetCountry(model.MainResidenceCode);
model.MainResidenceName = mainResidence != null ? mainResidence.Name : "";
result.Html = await PartialView("_Create", model).ToStringAsync(ControllerContext);
return Json(result);
}
/// <summary>
/// Bearbeiten eines App-Users
/// </summary>
/// <param name="id">Id des AppUsers</param>
/// <returns>PartialView</returns>
[Authorize(Policy = Policies.PowerUserOnly)]
[HasPermission(Permission.AppUsersManage, Permission.AppUsersEdit)]
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public async Task<IActionResult> Edit(string id)
{
var item = await _appUserService.GetAsync(id);
if (item != null)
{
var model = _mapper.Map<AppUserCrudVm>(item);
var country = _countryService.GetCountry(item.Address.CountryCode);
model.CountryName = country != null ? country.Name : "";
var state = _countryService.GetState(item.Address.CountryCode, item.Address.State);
model.StateName = state != null ? state.Name : "";
var nationality = _countryService.GetCountry(item.NationalityCode);
model.NationalityName = nationality != null ? nationality.Name : "";
var mainResidence = _countryService.GetCountry(item.MainResidenceCode);
model.MainResidenceName = mainResidence != null ? mainResidence.Name : "";
return PartialView("_Edit", model);
}
return PartialView("_Error");
}
/// <summary>
/// Bearbeiten eines App-Users
/// </summary>
/// <param name="model">Model</param>
/// <returns>Json</returns>
[Authorize(Policy = Policies.PowerUserOnly)]
[HasPermission(Permission.AppUsersManage, Permission.AppUsersEdit)]
[ValidateAntiForgeryToken]
[HttpPost]
public async Task<IActionResult> Edit(AppUserCrudVm model)
{
var result = new ResponseVm { Success = false };
if (ModelState.IsValid)
{
var item = await _appUserService.GetAsync(model.Id);
if (item is { Deleted: false })
{
if (item.Version.SequenceEqual(model.Version))
{
var oldPhoto = item.Photo;
var addressHasChanges = item.Address.HasChanges(model.Address);
var oldTermsAccepted = item.TermsAccepted;
var oldPrivacyAccepted = item.PrivacyAccepted;
var oldPaymentTermsAccepted = item.PaymentTermsAccepted;
var oldVerified = item.Verified;
var oldKycPassed = item.KycPassed;
_mapper.Map(model, item);
if (model.TermsAccepted != oldTermsAccepted && model.TermsAccepted)
item.TermsAcceptedDate = DateTimeOffset.UtcNow;
else
if(!model.TermsAccepted)
item.TermsAcceptedDate = null;
if (model.PrivacyAccepted != oldPrivacyAccepted && model.PrivacyAccepted)
item.PrivacyAcceptedDate = DateTimeOffset.UtcNow;
else
if(!model.PrivacyAccepted)
item.PrivacyAcceptedDate = null;
if (model.PaymentTermsAccepted != oldPaymentTermsAccepted && model.PaymentTermsAccepted)
item.PaymentTermsAcceptedDate = DateTimeOffset.UtcNow;
else
if(!model.PaymentTermsAccepted)
item.PaymentTermsAcceptedDate = null;
if (model.Verified != oldVerified && model.Verified)
item.VerifiedDate = DateTimeOffset.UtcNow;
else
if(!model.Verified)
item.VerifiedDate = null;
if (model.KycPassed != oldKycPassed && model.KycPassed)
item.KycPassedDate = DateTimeOffset.UtcNow;
else
if(!model.KycPassed)
item.KycPassedDate = null;
if (model.BirthDate.HasValue)
item.BirthDate = new DateTimeOffset(model.BirthDate.Value.DateTime, TimeSpan.Zero);
item.UpdatedAt = DateTimeOffset.UtcNow;
if (oldPhoto != item.Photo)
{
//Alte Daten löschen, neue Daten anlegen
if (!string.IsNullOrWhiteSpace(oldPhoto))
{
await FileService.DeleteAsync(FileServiceHelper.DocumentContainer, oldPhoto);
await RemoveThumbnail(FileServiceHelper.DocumentContainer, oldPhoto, 400);
await RemoveThumbnail(FileServiceHelper.DocumentContainer, oldPhoto, 200);
await RemoveThumbnail(FileServiceHelper.DocumentContainer, oldPhoto, 100);
}
if (!string.IsNullOrWhiteSpace(item.Photo))
{
//Neue Bilddaten verwenden....
var extension = Path.GetExtension(item.Photo);
var fileName = Path.GetFileName(item.Photo);
var filenameToUse = FileServiceHelper.GetAppUserPath(item.Id) + $"photo-{Guid.NewGuid():N}{extension}";
item.Photo = filenameToUse;
//Kopieren
var tempFile = await FileService.GetAsync(FileServiceHelper.TempContainer, model.Photo);
await FileService.StoreAsync(FileServiceHelper.DocumentContainer, filenameToUse, tempFile);
//Thumbnails
await GenerateThumbnailByWidth(FileServiceHelper.DocumentContainer, filenameToUse, 400);
await GenerateThumbnailByWidth(FileServiceHelper.DocumentContainer, filenameToUse, 200);
await GenerateThumbnailByWidth(FileServiceHelper.DocumentContainer, filenameToUse, 100);
//Altes Löschen
await FileService.DeleteAsync(FileServiceHelper.TempContainer, model.Photo);
}
}
if (addressHasChanges)
{
var location = await _geoLocationService.GetLocationAsync(item.Address, SelectedLanguage);
if (location.Success)
{
var geometryFactory = NtsGeometryServices.Instance.CreateGeometryFactory(srid: 4326);
var geoLocation = geometryFactory.CreatePoint(new Coordinate(location.Longitude, location.Latitude));
item.Location = geoLocation;
}
}
await _appUserService.CommitAsync(User.Identity.Name);
await _appHubSender.AppUserChangedAsync(item.Id);
result.Data = item.ToCamelCaseJson();
result.Success = true;
result.Html = string.Empty;
return Json(new { result.Success, result.Html, result.Data });
}
else
{
ModelState.AddModelError("", _localizer["Err_Entity_Changed"].Value);
}
}
else
{
ModelState.AddModelError("", _localizer["Err_Entity_Deleted"].Value);
}
}
ModelState.Remove("CountryName");
var country = _countryService.GetCountry(model.Address.CountryCode);
model.CountryName = country != null ? country.Name : "";
ModelState.Remove("StateName");
var state = _countryService.GetState(model.Address.CountryCode, model.Address.State);
model.StateName = state != null ? state.Name : "";
ModelState.Remove("NationalityName");
var nationality = _countryService.GetCountry(model.NationalityCode);
model.NationalityName = nationality != null ? nationality.Name : "";
ModelState.Remove("MainResidenceName");
var mainResidence = _countryService.GetCountry(model.MainResidenceCode);
model.MainResidenceName = mainResidence != null ? mainResidence.Name : "";
result.Html = await PartialView("_Edit", model).ToStringAsync(ControllerContext);
return Json(result);
}
/// <summary>
/// Löschen eines App-Users
/// </summary>
/// <param name="ids">Liste Id der Entität</param>
/// <param name="forceDelete">Sollen die Daten physisch gelöscht werden?</param>
/// <returns>Json</returns>
[Authorize(Policy = Policies.PowerUserOnly)]
[HasPermission(Permission.AppUsersManage, Permission.AppUsersDelete)]
[HttpPost]
public async Task<IActionResult> Delete(List<string> ids, bool forceDelete = false)
{
var batchErrorHeader = $"<p><strong>{_localizer["Common_BatchDelete_Failed"].Value}</strong></p>";
var batchResult = new BatchResponseVm(batchErrorHeader) { Success = true };
var ratingTargetsToUpdate = new List<Tuple<string, RatingTarget>>();
foreach (var id in ids)
{
var item = await _appUserService.GetAsync(id);
if (item != null)
{
//await _customerService.ResetTypeAsync(item.Id); //Spezial zurücksetzen wenn nötig
var specialCount = 0;
if (specialCount == 0)
{
batchResult.BatchResponseList.Add(new BatchResponseItemVm() { Id = item.Id.ToString(), Name = item.Title, Success = true, NotFound = false, ErrorMessage = "" });
if (forceDelete)
{
var postingPath = FileServiceHelper.GetAppUserPath(item.Id);
await FileService.ClearDirectoryAsync(FileServiceHelper.DocumentContainer, postingPath);
await RemoveThumbnail(FileServiceHelper.DocumentContainer, item.Photo, 400);
await RemoveThumbnail(FileServiceHelper.DocumentContainer, item.Photo, 200);
await RemoveThumbnail(FileServiceHelper.DocumentContainer, item.Photo, 100);
var applicationUser = await _userService.GetByAppUserAsync(item.Id);
if (applicationUser != null)
{
//Refreshtokens löschen
await _refreshTokenService.RemoveAllAsync(applicationUser.Id, applicationUser.UserName);
//Benutzer löschen
_userService.Remove(applicationUser);
}
//Walker-Profil löschen
await _appUserService.RemoveWalkerProfileAsync(item.Id);
//Blockierungen löschen
await _appUserService.RemoveBlocksByBlockedUserAsync(item.Id);
//Ratings löschen
var ratingTargets = await _ratingService.DeleteAllForAppUserAsync(item.Id);
foreach (var ratingTarget in ratingTargets)
{
if(ratingTargetsToUpdate.FirstOrDefault(c => c.Item1 == ratingTarget.Item1 && c.Item2 == ratingTarget.Item2) == null)
ratingTargetsToUpdate.Add(ratingTarget);
}
System.Diagnostics.Debug.WriteLine($"Ratings: {ratingTargetsToUpdate.Count}");
//Favourites löschen
var favouritesCount = await _favouriteService.DeleteAllForAppUserAsync(item.Id);
System.Diagnostics.Debug.WriteLine($"Favourites: {favouritesCount}");
//SystemMessages löschen
var systemMessageCount = await _systemMessageService.DeleteAllForAppUserAsync(item.Id);
System.Diagnostics.Debug.WriteLine($"SystemMessages: {systemMessageCount}");
//Konversationen löschen
var conversations = await _messageService.RemoveConversationByAppUserAsync(item.Id);
//Devices vor löschen abmelden
var devices = await _deviceService.GetAllAsync(item.Id);
foreach (var device in devices)
{
#if RELEASE
await _pushNotificationService.DeleteInstallationByIdAsync(device.InstallationId);
#endif
await _deviceService.DeleteAsync(item.Id, device.InstallationId, true);
}
System.Diagnostics.Debug.WriteLine($"Devices: {devices.Count}");
//AppReports löschen
var appUserReportCount = await _appUserReportService.DeleteAllForAppUserAsync(item.Id);
System.Diagnostics.Debug.WriteLine($"AppUserReports: {appUserReportCount}");
_appUserService.Remove(item);
await _voucherCampaignService.RemoveVoucherUsageForAppUserAsync(item.Id);
}
else
{
item.Deleted = true;
item.UpdatedAt = DateTimeOffset.UtcNow;
var applicationUser = await _userService.GetByAppUserAsync(item.Id);
if (applicationUser != null)
{
//Refreshtokens löschen
await _refreshTokenService.RemoveAllAsync(applicationUser.Id, applicationUser.UserName);
}
//Zuordnung zum Benutzer zurücksetzen
await _userService.ResetAppUserAsync(item.Id);
//Ratings löschen
var ratingTargets = await _ratingService.DeleteAllForAppUserAsync(item.Id);
foreach (var ratingTarget in ratingTargets)
{
if (ratingTargetsToUpdate.FirstOrDefault(c => c.Item1 == ratingTarget.Item1 && c.Item2 == ratingTarget.Item2) == null)
ratingTargetsToUpdate.Add(ratingTarget);
}
//Favourites löschen
await _favouriteService.DeleteAllForAppUserAsync(item.Id);
//SystemMessages löschen
await _systemMessageService.DeleteAllForAppUserAsync(item.Id);
//Konversationen löschen
var conversations = await _messageService.RemoveConversationByAppUserAsync(item.Id);
//Devices vor löschen abmelden
var devices = await _deviceService.GetAllAsync(item.Id);
foreach (var device in devices)
{
#if RELEASE
await _pushNotificationService.DeleteInstallationByIdAsync(device.InstallationId);
#endif
await _deviceService.DeleteAsync(item.Id, device.InstallationId, true);
}
//AppReports löschen
var appUserReportCount = await _appUserReportService.DeleteAllForAppUserAsync(item.Id);
System.Diagnostics.Debug.WriteLine($"AppUserReports: {appUserReportCount}");
}
}
else
{
if (specialCount != 0)
{
batchResult.Success = false;
batchResult.BatchResponseList.Add(new BatchResponseItemVm() { Id = id.ToString(), Name = item.Title, Success = false, NotFound = false, ErrorMessage = string.Format(_localizer["Common_BatchDelete_InUse"], $"<strong>{item.Title}</strong>", $"<strong>{specialCount}</strong>") + "<br/>" });
}
}
}
else
{
batchResult.Success = false;
batchResult.BatchResponseList.Add(new BatchResponseItemVm() { Id = id.ToString(), Name = "", Success = false, NotFound = true, ErrorMessage = string.Format(_localizer["Common_BatchDelete_NotFound"], $"<strong>{id}</strong>") + "<br/>" });
}
}
if (batchResult.BatchResponseList.Any(c => c.Success))
{
await _appUserService.CommitAsync(User.Identity.Name);
if (ratingTargetsToUpdate.Any())
{
foreach (var ratingTargetToUpdate in ratingTargetsToUpdate)
{
await _ratingService.UpdateRatingStatisticsAsync(ratingTargetToUpdate.Item1, ratingTargetToUpdate.Item2);
}
await _ratingService.CommitAsync(User.Identity.Name);
}
}
return Json(batchResult);
}
/// <summary>
/// Sperren eines App-Users
/// </summary>
/// <param name="id">Id des AppUsers</param>
/// <returns>PartialView</returns>
[Authorize(Policy = Policies.PowerUserOnly)]
[HasPermission(Permission.AppUsersManage, Permission.AppUsersEdit)]
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public async Task<IActionResult> Lock(string id)
{
var item = await _appUserService.GetAsync(id);
if (item != null)
{
var model = new AppUserLockVm()
{
Id = item.Id,
LockedUntil = null,
LockedReason = string.Empty
};
return PartialView("_Lock", model);
}
return PartialView("_Error");
}
/// <summary>
/// Sperren eines App-Users
/// </summary>
/// <param name="model">Model</param>
/// <returns>Json</returns>
[Authorize(Policy = Policies.PowerUserOnly)]
[HasPermission(Permission.AppUsersManage, Permission.AppUsersEdit)]
[ValidateAntiForgeryToken]
[HttpPost]
public async Task<IActionResult> Lock(AppUserLockVm model)
{
var result = new ResponseVm { Success = false };
if (ModelState.IsValid)
{
var item = await _appUserService.GetAsync(model.Id);
if (item is { Deleted: false })
{
item.Locked = true;
item.LockedReason = model.LockedReason;
item.LockedUntil = model.LockedUntil;
item.LockedCount += 1;
await _appUserService.CommitAsync(User.Identity.Name);
//Senden einer Nachricht an die App dass ein Logout durchgeführt werden soll?
if (!string.IsNullOrWhiteSpace(item.Id))
{
//Logout-Aufforderung via SignalR
await _appHubSender.LogoutAsync(item.Id);
//Logout-Aufforderung via Push-Notification
await _pushNotificationService.SendLogoutAsync(item.Id);
}
//Offene Walks stornieren
var canceled = await _walkService.CancelWalksForLockedAsync(item.Id);
//Offene Angebote auf öffentliche Anfragen stornieren
var canceledResponses = await _publicWalkResponseService.CancelForLockedAsync(item.Id);
result.Data = item.ToCamelCaseJson();
result.Success = true;
result.Html = string.Empty;
return Json(new { result.Success, result.Html, result.Data });
}
else
{
ModelState.AddModelError("", _localizer["Err_Entity_Deleted"].Value);
}
}
result.Html = await PartialView("_Lock", model).ToStringAsync(ControllerContext);
return Json(result);
}
/// <summary>
/// Entsperren eines App-Users
/// </summary>
/// <param name="id">Id des App-Users</param>
/// <returns>Json</returns>
[Authorize(Policy = Policies.PowerUserOnly)]
[HasPermission(Permission.AppUsersManage, Permission.AppUsersEdit)]
[HttpPost]
public async Task<IActionResult> Unlock(string id)
{
var result = new ResponseVm { Success = false };
var item = await _appUserService.GetAsync(id);
if (item is { Locked: true })
{
item.Locked = false;
item.LockedUntil = null;
item.LockedReason = string.Empty;
await _appUserService.CommitAsync(User.Identity.Name);
result.Success = true;
return Json(result);
}
return Json(result);
}
#region Profil DogWalker
/// <summary>
/// Bearbeiten des DogWalker Profils eines App-Users
/// </summary>
/// <param name="id">Id des AppUsers</param>
/// <returns>PartialView</returns>
[Authorize(Policy = Policies.PowerUserOnly)]
[HasPermission(Permission.AppUsersManage, Permission.AppUsersEdit)]
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public async Task<IActionResult> EditProfile(string id)
{
var item = await _appUserService.GetAsync(id);
if (item != null && item.Type != AppUserType.DogOwner)
{
var profile = await _appUserService.CreateWalkerProfileIfNotExistsAsync(id);
await _appUserService.CommitAsync(User.Identity.Name);
var model = _mapper.Map<DogWalkerProfileVm>(profile);
return PartialView("_EditProfile", model);
}
return PartialView("_Error");
}
/// <summary>
/// Bearbeiten des DogWalker Profils eines App-Users
/// </summary>
/// <param name="model">Model</param>
/// <returns>Json</returns>
[Authorize(Policy = Policies.PowerUserOnly)]
[HasPermission(Permission.AppUsersManage, Permission.AppUsersEdit)]
[ValidateAntiForgeryToken]
[HttpPost]
public async Task<IActionResult> EditProfile(DogWalkerProfileVm model)
{
var result = new ResponseVm { Success = false };
if (ModelState.IsValid)
{
var item = await _appUserService.GetWalkerProfileAsync(model.Id);
if (item is { Deleted: false })
{
if (item.Version.SequenceEqual(model.Version))
{
_mapper.Map(model, item);
item.UpdatedAt = DateTimeOffset.UtcNow;
await _appUserService.CommitAsync(User.Identity.Name);
await _appHubSender.AppUserChangedAsync(item.Id);
result.Data = item.ToCamelCaseJson();
result.Success = true;
result.Html = string.Empty;
return Json(new { result.Success, result.Html, result.Data });
}
else
{
ModelState.AddModelError("", _localizer["Err_Entity_Changed"].Value);
}
}
else
{
ModelState.AddModelError("", _localizer["Err_Entity_Deleted"].Value);
}
}
result.Html = await PartialView("_EditProfile", model).ToStringAsync(ControllerContext);
return Json(result);
}
#endregion
#region Helper
/// <summary>
/// Gibt eine Liste von App-Usern für LookUp zurück
/// </summary>
/// <param name="dm">DataManager</param>
/// <param name="includeNone">Soll "Keine(r)" integriert werden</param>
/// <returns>Liste</returns>
[Authorize(Policy = Policies.PowerUserOnly)]
public async Task<IActionResult> Lookup([FromBody] DataManager dm, bool includeNone = false)
{
var filter = string.Empty;
if (dm.Where?.FirstOrDefault() != null)
{
filter = dm.Where.First().value.ToString();
if (filter.IndexOf('(') > 0)
{
filter = filter.Substring(0, (filter.IndexOf('(') - 1));
filter = filter.TrimEnd();
}
}
var items = await _appUserService.SearchAsync(filter, false);
var result = items.Select(item => new LookupItemVm() { Id = item.Id.ToString(), Name = $"{item.FirstName} {item.LastName} ({AnnotationsLocalizer["AppUserType_" + item.Type.ToString()]})" }).OrderBy(c => c.Name).ToList();
if (includeNone)
result.Insert(0, new LookupItemVm() { Id = "", Name = _localizer["Common_None"].ToString() });
return Json(result);
}
#endregion
}
}