Florian Mihalits ada8b7a200 Add payment types for walks and update related models
This commit introduces new payment types, including "MangoPay" and "Cash", to the localization resource files for both German and English. A new enum `WalkPaymentType` is created to represent these payment types, and the `Walk` class is updated to include a required `PaymentType` property of this enum type.

The database context is modified to add a `PaymentType` column to the `Walks` table, accompanied by a migration to implement this change and set a default value. The `WalkController` is updated to support filtering by the new `PaymentType` field, and the mapping profile is enhanced to include mappings for `WalkPaymentType` and its view model counterpart.

View models are also updated to incorporate the new `PaymentType` and its display name. Front-end TypeScript files are adjusted to utilize the new `WalkPaymentType` enum and related properties, while the UI is enhanced to display the payment type in the details view of walks. Version numbers in various configuration files are incremented to reflect these changes.
2025-06-30 11:06:30 +02:00

311 lines
13 KiB
C#

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 gehGassi.Web.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Localization;
using System.Collections.Generic;
using System.Linq;
using gehGassi.Web.Helper;
using System.Threading.Tasks;
using gehGassi.Domain.Dogs;
using gehGassi.Domain.Walks;
using System.Text.Json;
namespace gehGassi.Web.Controllers
{
/// <summary>
/// Controller für die Verwaltung von Walks und öffentliche Anfragen
/// </summary>
[Authorize]
public class WalkController : BaseController
{
private readonly IMapper _mapper;
private readonly IStringLocalizer<WalkController> _localizer;
private readonly IWalkService _walkService;
private readonly IPublicWalkRequestService _publicWalkRequestService;
private readonly IPublicWalkResponseService _publicWalkResponseService;
private readonly IDogService _dogService;
/// <summary>
/// Erstellt eine Instanz
/// </summary>
/// <param name="mapper">Instanz eines IMapper</param>
/// <param name="localizer">Instanz eines IStringLocalizer</param>
/// <param name="walkService">Instanz eines IWalkService</param>
/// <param name="publicWalkRequestService">Instanz eines IPublicWalkRequestService</param>
/// <param name="publicWalkResponseService">Instanz eines IPublicWalkResponseService</param>
/// <param name="dogService">Instanz eines IDogService</param>
public WalkController(IMapper mapper, IStringLocalizer<WalkController> localizer, IWalkService walkService, IPublicWalkRequestService publicWalkRequestService, IPublicWalkResponseService publicWalkResponseService,
IDogService dogService)
{
_mapper = mapper;
_localizer = localizer;
_walkService = walkService;
_publicWalkRequestService = publicWalkRequestService;
_publicWalkResponseService = publicWalkResponseService;
_dogService = dogService;
}
#region Walks
/// <summary>
/// Gibt einen View für die Verwaltung von Walks 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 GetWalks([FromBody] DataManager dm)
{
if (dm != null)
{
var propList = new List<ComplexProperty>();
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 = (WalkType)((int)((long)whereFilterPredicate.value));
if (whereFilterPredicate.Field == "serviceType")
whereFilterPredicate.value = (WalkServiceType)((int)((long)whereFilterPredicate.value));
if (whereFilterPredicate.Field == "status")
whereFilterPredicate.value = (WalkStatus)((int)((long)whereFilterPredicate.value));
if (whereFilterPredicate.Field == "paymentStatus")
whereFilterPredicate.value = (PaymentStatus)((int)((long)whereFilterPredicate.value));
if (whereFilterPredicate.Field == "paymentType")
whereFilterPredicate.value = (WalkPaymentType)((int)((long)whereFilterPredicate.value));
}
}
}
}
var resultList = _walkService.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<WalkWithNamesListVm>(item)).ToList();
foreach (var itemVm in resultListVm)
{
itemVm.TypeText = itemVm.Type.GetDisplayName(AnnotationsLocalizer);
itemVm.ServiceTypeText = itemVm.ServiceType.GetDisplayName(AnnotationsLocalizer);
itemVm.StatusText = itemVm.Status.GetDisplayName(AnnotationsLocalizer);
itemVm.PaymentStatusText = itemVm.PaymentStatus.GetDisplayName(AnnotationsLocalizer);
itemVm.PaymentTypeText = itemVm.PaymentType.GetDisplayName(AnnotationsLocalizer);
}
//FilterPreview?
if (!dm.RequiresCounts)
return Json(resultListVm);
return Json(new { result = resultListVm, count = countFiltered });
}
/// <summary>
/// Details eines Walks
/// </summary>
/// <param name="id">Id der Anfrage</param>
/// <returns>PartialView</returns>
[Authorize(Policy = Policies.PowerUserOnly)]
[HasPermission(Permission.AppUsersManage, Permission.AppUsersRead)]
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public async Task<IActionResult> Details(string id)
{
var item = await _walkService.GetWalkWithNamesAsync(id);
if (item != null)
{
var model = _mapper.Map<WalkWithNamesVm>(item);
model.Dogs = new List<DogMinInfo>();
if (!string.IsNullOrWhiteSpace(model.DogsJson))
{
var dogsList = JsonSerializer.Deserialize<List<DogWalkJson>>(model.DogsJson, new JsonSerializerOptions(JsonSerializerDefaults.Web));
foreach (var dogItem in dogsList)
{
var dog = await _dogService.GetWithNamesAsync(dogItem.Id, SelectedLanguage, LocalizationOptions.Value.DefaultCulture, true);
if (dog != null)
{
model.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,
Photo = dog.Photo,
});
}
}
}
return PartialView("_Details", model);
}
return PartialView("_Error");
}
#endregion
#region PublicWalkRequests
/// <summary>
/// Gibt einen View für die Verwaltung von Öffentlichen Anfragen zurück
/// </summary>
/// <returns>View</returns>
[Authorize(Policy = Policies.PowerUserOnly)]
[HasPermission(Permission.AppUsersManage, Permission.AppUsersRead)]
public IActionResult IndexRequests()
{
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 GetPublicWalkRequests([FromBody] DataManager dm)
{
if (dm != null)
{
var propList = new List<ComplexProperty>();
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 == "requestType")
whereFilterPredicate.value = (PublicWalkRequestType)((int)((long)whereFilterPredicate.value));
if (whereFilterPredicate.Field == "status")
whereFilterPredicate.value = (PublicWalkRequestStatus)((int)((long)whereFilterPredicate.value));
}
}
}
}
var resultList = _publicWalkRequestService.FilterPublicWalkRequestsWithNames(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<PublicWalkRequestListVm>(item)).ToList();
foreach (var itemVm in resultListVm)
{
itemVm.RequestTypeText = itemVm.RequestType.GetDisplayName(AnnotationsLocalizer);
itemVm.StatusText = itemVm.Status.GetDisplayName(AnnotationsLocalizer);
}
//FilterPreview?
if (!dm.RequiresCounts)
return Json(resultListVm);
return Json(new { result = resultListVm, count = countFiltered });
}
/// <summary>
/// Details einer Öffentlichen Anfrage
/// </summary>
/// <param name="id">Id der Anfrage</param>
/// <returns>PartialView</returns>
[Authorize(Policy = Policies.PowerUserOnly)]
[HasPermission(Permission.AppUsersManage, Permission.AppUsersRead)]
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public async Task<IActionResult> DetailsPublicWalkRequest(string id)
{
var item = await _publicWalkRequestService.GetWithNamesAsync(id);
if (item != null)
{
var model = _mapper.Map<PublicWalkRequestWithNamesVm>(item);
model.Dogs = new List<DogMinInfo>();
if (!string.IsNullOrWhiteSpace(model.DogsJson))
{
var dogsList = JsonSerializer.Deserialize<List<DogWalkJson>>(model.DogsJson, new JsonSerializerOptions(JsonSerializerDefaults.Web));
foreach (var dogItem in dogsList)
{
var dog = await _dogService.GetWithNamesAsync(dogItem.Id, SelectedLanguage, LocalizationOptions.Value.DefaultCulture, true);
if (dog != null)
{
model.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,
Photo = dog.Photo,
});
}
}
}
//Nun noch alle Antworten suchen, wenn es welche gibt.
var responses = await _publicWalkResponseService.GetResponsesAsync(item.DogOwnerId, id);
var responseListVm = _mapper.Map<List<PublicWalkResponseWithNamesVm>>(responses);
ViewBag.Responses = responseListVm;
return PartialView("_DetailsPublicWalkRequest", model);
}
return PartialView("_Error");
}
#endregion
}
}