gehgassi_backend/gehGassi.Core/Services/PublicWalkResponseService.cs

179 lines
8.7 KiB
C#

using gehGassi.Core.Interfaces;
using gehGassi.Domain.Dogs;
using gehGassi.Domain.Walks;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using gehGassi.Domain.Common;
namespace gehGassi.Core.Services
{
/// <summary>
/// Service der die Verwaltung von Antworten auf öffentlichen Anfragen ermöglicht
/// </summary>
public class PublicWalkResponseService : ServiceBase<PublicWalkResponse>, IPublicWalkResponseService
{
private readonly IRepository<PublicWalkResponseWithNames> _namesRepository;
/// <summary>
/// Erstellt eine Instanz
/// </summary>
/// <param name="unitOfWork">Instanz eines IUnitOfWork</param>
public PublicWalkResponseService(IUnitOfWork unitOfWork) : base(unitOfWork)
{
_namesRepository = unitOfWork.GetRepository<PublicWalkResponseWithNames>();
}
/// <summary>
/// Erstellen einer Antwort auf eine öffentlichen Anfrage
/// </summary>
/// <returns></returns>
public PublicWalkResponse Create(string publicWalkRequestId)
{
var item = new PublicWalkResponse()
{
Id = Guid.NewGuid().ToString("N"),
Created = DateTimeOffset.UtcNow,
PublicWalkRequestId = publicWalkRequestId
};
return item;
}
/// <summary>
/// Gibt eine Liste der Antworten auf öffentlichen Anfragen eines Benutzers zurück
/// </summary>
/// <param name="appUserId">Id des AppUsers</param>
/// <param name="lastUpdate">Letztes Update</param>
/// <returns>Liste der Antworten auf öffentlichen Anfragen</returns>
public async Task<List<PublicWalkResponse>> GetForSyncAppAsync(string appUserId, DateTimeOffset? lastUpdate)
{
var query = Repository.Query(c => c.DogWalkerId == appUserId);
if (lastUpdate.HasValue)
query = query.Where(c => c.UpdatedAt > lastUpdate);
return await query.ToListAsync().ConfigureAwait(false);
}
/// <summary>
/// Gibt eine Antwort eines Walkers auf eine öffentliche Anfrage zurück
/// </summary>
/// <param name="appUserId">Id des AppUsers dem die öffentliche Anfrage gehört</param>
/// <param name="publicWalkResponseId">Id der Antwort zur öffentlichen Anfrage</param>
/// <returns>PublicWalkResponse oder null, wenn keine gefunden</returns>
public async Task<PublicWalkResponseWithNames> GetWithNamesAsync(string appUserId, string publicWalkResponseId)
{
var baseQuery = _namesRepository.QueryStoredProcedure("SELECT * FROM tv_PublicWalkResponseWithNames({0})", c => c.Id == publicWalkResponseId && c.Deleted == false, appUserId);
return await baseQuery.FirstOrDefaultAsync().ConfigureAwait(false);
}
/// <summary>
/// Gibt eine Antwort eines Walkers auf eine öffentliche Anfrage zurück
/// </summary>
/// <param name="dogWalkerId">Id des Walkers</param>
/// <param name="publicWalkRequestId">Id der öffntlichen Anfrage</param>
/// <returns>PublicWalkResponse oder null, wenn keine gefunden</returns>
public async Task<PublicWalkResponse> GetForWalkerAsync(string dogWalkerId, string publicWalkRequestId)
{
return await Repository.FirstOrDefaultAsync(c => c.DogWalkerId == dogWalkerId && c.PublicWalkRequestId == publicWalkRequestId).ConfigureAwait(false);
}
/// <summary>
/// Gibt die Anzahl der Antworten auf eine öffentliche Anfrage zurück
/// </summary>
/// <param name="publicWalkRequestId">Id der öffentlichen Anfrage</param>
/// <returns>Anzahl Antworten</returns>
public async Task<int> CountForPublicWalkRequestAsync(string publicWalkRequestId)
{
return await Repository.CountAsync(c => c.PublicWalkRequestId == publicWalkRequestId && c.Deleted == false).ConfigureAwait(false);
}
/// <summary>
/// Gibt eine Liste von Antworten zu einer öffentlichen Anfragen für die App zurück.
/// </summary>
/// <param name="appUserId">Id des AppUsers dem die öffentliche Anfrage gehört</param>
/// <param name="publicRequestId">Id der öffentlichen Anfrage</param>
/// <param name="skip">Datensätze auslassen</param>
/// <param name="take">Datensätze nehmen</param>
/// <returns>Liste passender antworten</returns>
public async Task<(int total, List<PublicWalkResponseWithNames> list)> GetResponsesAsync(string appUserId, string publicRequestId, int skip, int take)
{
var baseQuery = _namesRepository.QueryStoredProcedure("SELECT * FROM tv_PublicWalkResponseWithNames({0})", c => c.PublicWalkRequestId == publicRequestId && c.Deleted == false, appUserId);
var total = await baseQuery.CountAsync().ConfigureAwait(false);
var list = await baseQuery.OrderByDescending(c => c.UpdatedAt).Skip(skip).Take(take).ToListAsync().ConfigureAwait(false);
return (total, list);
}
/// <summary>
/// Gibt eine Liste aller Antworten zu einer öffentlichen Anfragen zurück.
/// </summary>
/// <param name="appUserId">Id des AppUsers dem die öffentliche Anfrage gehört</param>
/// <param name="publicRequestId">Id der öffentlichen Anfrage</param>
/// <returns>Liste passender antworten</returns>
public async Task<List<PublicWalkResponseWithNames>> GetResponsesAsync(string appUserId, string publicRequestId)
{
var baseQuery = _namesRepository.QueryStoredProcedure("SELECT * FROM tv_PublicWalkResponseWithNames({0})", c => c.PublicWalkRequestId == publicRequestId && c.Deleted == false, appUserId);
return await baseQuery.ToListAsync();
}
/// <summary>
/// Setzen des Closed Status für Angebote die im Warten-Status sind.
/// Wird verwendet wenn ein Angebot angenommen wurde und man nun den anderen Bewerbern mitteilen muss, dass wer anderes genommen wurde
/// </summary>
/// <param name="publicWalkRequestId">Id der öffentlichen Anfrage</param>
/// <returns>Anzahl geännderte Angebote</returns>
public async Task<int> SetCompletedForWaitingAsync(string publicWalkRequestId)
{
var responses = await Repository.FindAsync(c => c.PublicWalkRequestId == publicWalkRequestId && c.Deleted == false && c.Status == PublicWalkResponseStatus.Awaiting).ConfigureAwait(false);
foreach (var response in responses)
{
response.Status = PublicWalkResponseStatus.Closed;
response.UpdatedAt = DateTimeOffset.UtcNow;
}
return responses.Count();
}
/// <summary>
/// Setzen des Open Status für Angebote die im Closed-Status sind.
/// Wird verwendet wenn ein angenommenes Angebot nicht bezahlt wurde und ein Reset der öffentlichen Anfrage durchgeführt wird
/// </summary>
/// <param name="publicWalkRequestId">Id der öffentlichen Anfrage</param>
/// <returns>Anzahl geännderte Angebote</returns>
public async Task<int> SetOpenForClosedOrAcceptedAsync(string publicWalkRequestId)
{
var responses = await Repository.FindAsync(c => c.PublicWalkRequestId == publicWalkRequestId && c.Deleted == false && (c.Status == PublicWalkResponseStatus.Closed || c.Status == PublicWalkResponseStatus.Accepted)).ConfigureAwait(false);
foreach (var response in responses)
{
response.Status = PublicWalkResponseStatus.Awaiting;
response.UpdatedAt = DateTimeOffset.UtcNow;
}
return responses.Count();
}
/// <summary>
/// Stornieren von Angeobten für offene öffentliche Anfragen wenn ein Benutzer gesperrt wurde
/// </summary>
/// <param name="appUserId">Id des App-Users</param>
/// <returns>Anzahl stornierte Angebote</returns>
public async Task<int> CancelForLockedAsync(string appUserId)
{
var responses = await Repository.FindAsync(c => c.DogWalkerId == appUserId && c.Deleted == false && c.Status == PublicWalkResponseStatus.Awaiting).ConfigureAwait(false);
foreach (var response in responses)
{
response.Status = PublicWalkResponseStatus.Cancelled;
response.UpdatedAt = DateTimeOffset.UtcNow;
response.CancellationReason = "User locked";
}
await CommitAsync("System");
return responses.Count();
}
}
}