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