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 { /// /// Service der die Verwaltung von Antworten auf öffentlichen Anfragen ermöglicht /// public class PublicWalkResponseService : ServiceBase, IPublicWalkResponseService { private readonly IRepository _namesRepository; /// /// Erstellt eine Instanz /// /// Instanz eines IUnitOfWork public PublicWalkResponseService(IUnitOfWork unitOfWork) : base(unitOfWork) { _namesRepository = unitOfWork.GetRepository(); } /// /// Erstellen einer Antwort auf eine öffentlichen Anfrage /// /// public PublicWalkResponse Create(string publicWalkRequestId) { var item = new PublicWalkResponse() { Id = Guid.NewGuid().ToString("N"), Created = DateTimeOffset.UtcNow, PublicWalkRequestId = publicWalkRequestId }; return item; } /// /// Gibt eine Liste der Antworten auf öffentlichen Anfragen eines Benutzers zurück /// /// Id des AppUsers /// Letztes Update /// Liste der Antworten auf öffentlichen Anfragen public async Task> 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); } /// /// Gibt eine Antwort eines Walkers auf eine öffentliche Anfrage zurück /// /// Id des AppUsers dem die öffentliche Anfrage gehört /// Id der Antwort zur öffentlichen Anfrage /// PublicWalkResponse oder null, wenn keine gefunden public async Task 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); } /// /// Gibt eine Antwort eines Walkers auf eine öffentliche Anfrage zurück /// /// Id des Walkers /// Id der öffntlichen Anfrage /// PublicWalkResponse oder null, wenn keine gefunden public async Task GetForWalkerAsync(string dogWalkerId, string publicWalkRequestId) { return await Repository.FirstOrDefaultAsync(c => c.DogWalkerId == dogWalkerId && c.PublicWalkRequestId == publicWalkRequestId).ConfigureAwait(false); } /// /// Gibt die Anzahl der Antworten auf eine öffentliche Anfrage zurück /// /// Id der öffentlichen Anfrage /// Anzahl Antworten public async Task CountForPublicWalkRequestAsync(string publicWalkRequestId) { return await Repository.CountAsync(c => c.PublicWalkRequestId == publicWalkRequestId && c.Deleted == false).ConfigureAwait(false); } /// /// Gibt eine Liste von Antworten zu einer öffentlichen Anfragen für die App zurück. /// /// Id des AppUsers dem die öffentliche Anfrage gehört /// Id der öffentlichen Anfrage /// Datensätze auslassen /// Datensätze nehmen /// Liste passender antworten public async Task<(int total, List 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); } /// /// Gibt eine Liste aller Antworten zu einer öffentlichen Anfragen zurück. /// /// Id des AppUsers dem die öffentliche Anfrage gehört /// Id der öffentlichen Anfrage /// Liste passender antworten public async Task> 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(); } /// /// 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 /// /// Id der öffentlichen Anfrage /// Anzahl geännderte Angebote public async Task 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(); } /// /// 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 /// /// Id der öffentlichen Anfrage /// Anzahl geännderte Angebote public async Task 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(); } /// /// Stornieren von Angeobten für offene öffentliche Anfragen wenn ein Benutzer gesperrt wurde /// /// Id des App-Users /// Anzahl stornierte Angebote public async Task 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(); } } }