766 lines
38 KiB
C#
766 lines
38 KiB
C#
using CommunityToolkit.Mvvm.Messaging;
|
|
using gehGassi.Dto;
|
|
using gehGassiApp.Core.Data;
|
|
using gehGassiApp.Core.Interfaces;
|
|
using gehGassiApp.Core.Interfaces.Synchronization;
|
|
using gehGassiApp.Domain.Common;
|
|
using gehGassiApp.Domain.Messages;
|
|
using gehGassiApp.Domain.Users;
|
|
using gehGassiApp.Domain.Walks;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using gehGassi.Dto.Walks;
|
|
using System.Text.Json;
|
|
using gehGassi.Dto.Common;
|
|
using gehGassiApp.Core.Mapper;
|
|
using gehGassiApp.Core.Resources;
|
|
|
|
namespace gehGassiApp.Core.Services
|
|
{
|
|
/// <summary>
|
|
/// Service der die Verwaltung von öffentlichen Anfragen ermöglicht
|
|
/// </summary>
|
|
public class PublicWalkRequestService : ServiceBase<PublicWalkRequest>, IPublicWalkRequestService
|
|
{
|
|
private readonly ICommunicationService _communicationService;
|
|
private readonly ISyncInfoPullService _pullService;
|
|
private readonly ISyncInfoPushService _pushService;
|
|
private readonly ILocationService _locationService;
|
|
private readonly IRepository<AppUser> _appUserRepository;
|
|
private readonly IRepository<PublicWalkRequestWithNames> _namesRepository;
|
|
private readonly IRepository<Walk> _walksRepository;
|
|
|
|
/// <summary>
|
|
/// Erstellt eine Instanz
|
|
/// </summary>
|
|
/// <param name="unitOfWork">Instanz eines IUnitOfWork</param>
|
|
/// <param name="communicationService">Instanz eines ICommunicationService</param>
|
|
/// <param name="syncInfoPullService">Instanz eines ISyncInfoPullService</param>
|
|
/// <param name="syncInfoPushService">Instanz eines ISyncInfoPushService</param>
|
|
/// <param name="locationService">Instanz eines ILocationService</param>
|
|
public PublicWalkRequestService(IUnitOfWork unitOfWork, ICommunicationService communicationService, ISyncInfoPullService syncInfoPullService, ISyncInfoPushService syncInfoPushService,
|
|
ILocationService locationService) : base(unitOfWork)
|
|
{
|
|
_communicationService = communicationService;
|
|
_pullService = syncInfoPullService;
|
|
_pushService = syncInfoPushService;
|
|
_locationService = locationService;
|
|
_appUserRepository = unitOfWork.GetRepository<AppUser>();
|
|
_namesRepository = unitOfWork.GetRepository<PublicWalkRequestWithNames>();
|
|
_walksRepository = unitOfWork.GetRepository<Walk>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gibt eine Entität anhand der eindeutigen Id zurück
|
|
/// </summary>
|
|
/// <param name="id">Id der Entität</param>
|
|
/// <param name="noTracking">Gibt an ob NoTRacking verwendet werden soll. Es werden keine Entitäten im EF-Speicher gehalten</param>
|
|
/// <returns>Entität oder null, wenn nicht gefunden</returns>
|
|
public override PublicWalkRequest Get(object id, bool noTracking = true)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gibt eine Entität anhand der eindeutigen Id zurück
|
|
/// </summary>
|
|
/// <param name="id">Id der Entität</param>
|
|
/// <param name="noTracking">Gibt an ob NoTRacking verwendet werden soll. Es werden keine Entitäten im EF-Speicher gehalten</param>
|
|
/// <returns>Entität oder null, wenn nicht gefunden</returns>
|
|
public override async Task<PublicWalkRequest> GetAsync(object id, bool noTracking = true)
|
|
{
|
|
await Task.Delay(1);
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Zählt die Anzahl der öffentlichen Anfragen für den aktuellen Benutzer
|
|
/// </summary>
|
|
/// <param name="accessToken">Aktuelles Accesstoken</param>
|
|
/// <param name="token">CancellationToken</param>
|
|
/// <returns>Anzahl öffentliche Anfragen</returns>
|
|
public async Task<CommunicationResult<int>> CountPublicWalkRequestsAsync(string accessToken, CancellationToken token)
|
|
{
|
|
var result = new CommunicationResult<int>() { Value = 0 };
|
|
|
|
var isConnected = await _communicationService.IsConnected();
|
|
if (isConnected)
|
|
{
|
|
var queryResult = await _communicationService.CountPublicWalkRequestsAsync(accessToken, token);
|
|
if (queryResult.Success)
|
|
return queryResult;
|
|
}
|
|
else
|
|
{
|
|
result.Success = false;
|
|
result.ErrorCode = CommunicationErrors.ServerNoConnection;
|
|
result.ErrorMessage = Errors.Server_NoConnection;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gibt eine Liste von öffentlichen Anfragen zurück
|
|
/// </summary>
|
|
/// <param name="ignoreId">Id die ignoriert werden soll (DogOwnerId)</param>
|
|
/// <param name="dogOwnerId">Optional: Id des Hundebesitzers</param>
|
|
/// <param name="dogWalkerId">Optional: Id des Hundeausführers</param>
|
|
/// <param name="status">Status der Ausschreibung oder NULL für alle</param>
|
|
/// <param name="sortOrders">Liste von Sortierangaben</param>
|
|
/// <param name="location">Aktuelle Position</param>
|
|
/// <param name="take">Wie viele Listungen sollen abgerufen werden? -1 Wenn nicht anwenden.</param>
|
|
/// <param name="skip">Wie viele Listungen sollen ausgelassen werden? -1 Wenn nicht anwenden.</param>
|
|
/// <param name="appMode">Akteuller Modus der App</param>
|
|
/// <param name="language">Gewählte Sprache</param>
|
|
/// <param name="accessToken">Aktuelles Accesstoken</param>
|
|
/// <param name="token">CancellationToken</param>
|
|
/// <returns>ListCommunicationResult</returns>
|
|
public async Task<ListCommunicationResult<List<PublicWalkRequestWithNames>>> GetAsync(string ignoreId, string dogOwnerId, string dogWalkerId, PublicWalkRequestStatus? status, List<DynamicSortOrder> sortOrders, LocationDto location, int take, int skip, AppMode appMode, string language, string accessToken, CancellationToken token)
|
|
{
|
|
var result = new ListCommunicationResult<List<PublicWalkRequestWithNames>>() { Value = new List<PublicWalkRequestWithNames>() };
|
|
|
|
var isConnected = await _communicationService.IsConnected();
|
|
if (isConnected)
|
|
{
|
|
var query = new PublicWalkRequestQueryDto
|
|
{
|
|
Location = location,
|
|
Language = language,
|
|
AppMode = (AppModeDto)appMode,
|
|
Take = take,
|
|
Skip = skip,
|
|
IgnoreId = ignoreId,
|
|
DogOwnerId = dogOwnerId,
|
|
DogWalkerId = dogWalkerId,
|
|
Status = (PublicWalkRequestStatusDto?)status,
|
|
};
|
|
query.DynamicSortOrder = sortOrders.ToDto();
|
|
|
|
var queryResult = await _communicationService.GetPublicWalkRequestsAsync(query, accessToken, token);
|
|
if (queryResult.Success)
|
|
return queryResult;
|
|
}
|
|
else
|
|
{
|
|
result.Success = false;
|
|
result.ErrorCode = CommunicationErrors.ServerNoConnection;
|
|
result.ErrorMessage = Errors.Server_NoConnection;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gibt eine Liste von öffentlichen Anfragen zurück erweitert
|
|
/// </summary>
|
|
/// <param name="ignoreId">Id die ignoriert werden soll (DogOwnerId)</param>
|
|
/// <param name="dogOwnerId">Optional: Id des Hundebesitzers</param>
|
|
/// <param name="dogWalkerId">Optional: Id des Hundeausführers</param>
|
|
/// <param name="status">Status der Ausschreibung oder NULL für alle</param>
|
|
/// <param name="maxRadius">Maximaler Radius</param>
|
|
/// <param name="type">Gesuchter Typ oder NULL für alle</param>
|
|
/// <param name="minPrice">Mindestpreis</param>
|
|
/// <param name="sortOrders">Liste von Sortierangaben</param>
|
|
/// <param name="location">Aktuelle Position</param>
|
|
/// <param name="take">Wie viele Listungen sollen abgerufen werden? -1 Wenn nicht anwenden.</param>
|
|
/// <param name="skip">Wie viele Listungen sollen ausgelassen werden? -1 Wenn nicht anwenden.</param>
|
|
/// <param name="appMode">Akteuller Modus der App</param>
|
|
/// <param name="language">Gewählte Sprache</param>
|
|
/// <param name="accessToken">Aktuelles Accesstoken</param>
|
|
/// <param name="token">CancellationToken</param>
|
|
/// <returns>ListCommunicationResult</returns>
|
|
public async Task<ListCommunicationResult<List<PublicWalkRequestWithNames>>> GetExAsync(string ignoreId, string dogOwnerId, string dogWalkerId, PublicWalkRequestStatus? status, double maxRadius, PublicWalkRequestType? type, decimal minPrice, List<DynamicSortOrder> sortOrders, LocationDto location, int take, int skip, AppMode appMode, string language, string accessToken, CancellationToken token)
|
|
{
|
|
var result = new ListCommunicationResult<List<PublicWalkRequestWithNames>>() { Value = new List<PublicWalkRequestWithNames>() };
|
|
|
|
var isConnected = await _communicationService.IsConnected();
|
|
if (isConnected)
|
|
{
|
|
var query = new PublicWalkRequestQueryExDto()
|
|
{
|
|
Location = location,
|
|
Language = language,
|
|
AppMode = (AppModeDto)appMode,
|
|
Take = take,
|
|
Skip = skip,
|
|
IgnoreId = ignoreId,
|
|
DogOwnerId = dogOwnerId,
|
|
DogWalkerId = dogWalkerId,
|
|
Status = (PublicWalkRequestStatusDto?)status,
|
|
MaxRadius = maxRadius,
|
|
Type = (PublicWalkRequestTypeDto?)type,
|
|
MinPrice = minPrice
|
|
};
|
|
query.DynamicSortOrder = sortOrders.ToDto();
|
|
|
|
var queryResult = await _communicationService.GetPublicWalkRequestsExAsync(query, accessToken, token);
|
|
if (queryResult.Success)
|
|
return queryResult;
|
|
}
|
|
else
|
|
{
|
|
result.Success = false;
|
|
result.ErrorCode = CommunicationErrors.ServerNoConnection;
|
|
result.ErrorMessage = Errors.Server_NoConnection;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gibt eine Liste von öffentlichen Anfragen zurück mit einem Antwort-Status für einen DogWalker
|
|
/// </summary>
|
|
/// <param name="ignoreId">Id die ignoriert werden soll (DogOwnerId)</param>
|
|
/// <param name="dogOwnerId">Optional: Id des Hundebesitzers</param>
|
|
/// <param name="dogWalkerId">Optional: Id des Hundeausführers</param>
|
|
/// <param name="status">Status der Ausschreibung oder null für alle</param>
|
|
/// <param name="mustHaveResponse">es muss ein Angebot vom Dogwalker vorhanden sein</param>
|
|
/// <param name="sortOrders">Liste von Sortierangaben</param>
|
|
/// <param name="location">Aktuelle Position</param>
|
|
/// <param name="includeBlockedAndLocked">Sollten blockierte unnd/oder gesperrte Benutzer in die Liste eingefügt werden?</param>
|
|
/// <param name="take">Wie viele Listungen sollen abgerufen werden? -1 Wenn nicht anwenden.</param>
|
|
/// <param name="skip">Wie viele Listungen sollen ausgelassen werden? -1 Wenn nicht anwenden.</param>
|
|
/// <param name="appMode">Akteuller Modus der App</param>
|
|
/// <param name="language">Gewählte Sprache</param>
|
|
/// <param name="accessToken">Aktuelles Accesstoken</param>
|
|
/// <param name="token">CancellationToken</param>
|
|
/// <param name="targetDogWalkerId">Id des Dogwalkers der die Anfrage absetzt</param>
|
|
/// <param name="responseStatus">Ziel Response-Status oder Null für alle</param>
|
|
/// <returns>ListCommunicationResult</returns>
|
|
public async Task<ListCommunicationResult<List<PublicWalkRequestWithNamesAndResponseStatus>>> GetWithResponseStatusAsync(string ignoreId, string dogOwnerId, string dogWalkerId, PublicWalkRequestStatus? status, string targetDogWalkerId, PublicWalkResponseStatus? responseStatus, bool mustHaveResponse, List<DynamicSortOrder> sortOrders, LocationDto location, bool includeBlockedAndLocked, int take, int skip, AppMode appMode, string language, string accessToken, CancellationToken token)
|
|
{
|
|
var result = new ListCommunicationResult<List<PublicWalkRequestWithNamesAndResponseStatus>>() { Value = new List<PublicWalkRequestWithNamesAndResponseStatus>() };
|
|
|
|
var isConnected = await _communicationService.IsConnected();
|
|
if (isConnected)
|
|
{
|
|
var query = new PublicWalkRequestAndResponseStatusQueryDto
|
|
{
|
|
Location = location,
|
|
Language = language,
|
|
AppMode = (AppModeDto)appMode,
|
|
IncludeBlockedAndLocked = includeBlockedAndLocked,
|
|
Take = take,
|
|
Skip = skip,
|
|
IgnoreId = ignoreId,
|
|
DogOwnerId = dogOwnerId,
|
|
DogWalkerId = dogWalkerId,
|
|
Status = (PublicWalkRequestStatusDto?)status,
|
|
TargetDogWalkerId = targetDogWalkerId,
|
|
ResponseStatus = (PublicWalkResponseStatusDto?)responseStatus,
|
|
MustHaveResponse = mustHaveResponse
|
|
};
|
|
query.DynamicSortOrder = sortOrders.ToDto();
|
|
|
|
var queryResult = await _communicationService.GetPublicWalkRequestsWithResponseStatusAsync(query, accessToken, token);
|
|
if (queryResult.Success)
|
|
return queryResult;
|
|
}
|
|
else
|
|
{
|
|
result.Success = false;
|
|
result.ErrorCode = CommunicationErrors.ServerNoConnection;
|
|
result.ErrorMessage = Errors.Server_NoConnection;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gibt eine Liste von öffentlichen Anfragen zurück mit einem Antwort-Status für einen DogWalker mit erweiterten Suchparametern
|
|
/// </summary>
|
|
/// <param name="ignoreId">Id die ignoriert werden soll (DogOwnerId)</param>
|
|
/// <param name="dogOwnerId">Optional: Id des Hundebesitzers</param>
|
|
/// <param name="dogWalkerId">Optional: Id des Hundeausführers</param>
|
|
/// <param name="status">Status der Ausschreibung oder null für alle</param>
|
|
/// <param name="mustHaveResponse">Es muss ein Angebot vom DogWalker vorhanden sein</param>
|
|
/// <param name="searchText">Suchtext in Hundename, Besitzername oder Stadt</param>
|
|
/// <param name="sortOrders">Liste von Sortierangaben</param>
|
|
/// <param name="location">Aktuelle Position</param>
|
|
/// <param name="includeBlockedAndLocked">Sollten blockierte unnd/oder gesperrte Benutzer in die Liste eingefügt werden?</param>
|
|
/// <param name="take">Wie viele Listungen sollen abgerufen werden? -1 Wenn nicht anwenden.</param>
|
|
/// <param name="skip">Wie viele Listungen sollen ausgelassen werden? -1 Wenn nicht anwenden.</param>
|
|
/// <param name="appMode">Akteuller Modus der App</param>
|
|
/// <param name="language">Gewählte Sprache</param>
|
|
/// <param name="accessToken">Aktuelles Accesstoken</param>
|
|
/// <param name="token">CancellationToken</param>
|
|
/// <param name="targetDogWalkerId">Id des Dogwalkers der die Anfrage absetzt</param>
|
|
/// <param name="responseStatus">Ziel Response-Status oder Null für alle</param>
|
|
/// <param name="maxRadius">Maximaler Radius</param>
|
|
/// <param name="type">Gesuchter Typ oder null für alle</param>
|
|
/// <param name="minPrice">Mindestpreis</param>
|
|
/// <returns>ListCommunicationResult</returns>
|
|
public async Task<ListCommunicationResult<List<PublicWalkRequestWithNamesAndResponseStatus>>> GetWithResponseStatusExAsync(string ignoreId, string dogOwnerId, string dogWalkerId, PublicWalkRequestStatus? status, string targetDogWalkerId, PublicWalkResponseStatus? responseStatus, double maxRadius, PublicWalkRequestType? type, decimal minPrice, bool mustHaveResponse, string searchText, List<DynamicSortOrder> sortOrders, LocationDto location, bool includeBlockedAndLocked, int take, int skip, AppMode appMode, string language, string accessToken, CancellationToken token)
|
|
{
|
|
var result = new ListCommunicationResult<List<PublicWalkRequestWithNamesAndResponseStatus>>() { Value = new List<PublicWalkRequestWithNamesAndResponseStatus>() };
|
|
|
|
var isConnected = await _communicationService.IsConnected();
|
|
if (isConnected)
|
|
{
|
|
var query = new PublicWalkRequestAndResponseStatusQueryExDto()
|
|
{
|
|
Location = location,
|
|
Language = language,
|
|
AppMode = (AppModeDto)appMode,
|
|
IncludeBlockedAndLocked = includeBlockedAndLocked,
|
|
Take = take,
|
|
Skip = skip,
|
|
IgnoreId = ignoreId,
|
|
DogOwnerId = dogOwnerId,
|
|
DogWalkerId = dogWalkerId,
|
|
Status = (PublicWalkRequestStatusDto?)status,
|
|
TargetDogWalkerId = targetDogWalkerId,
|
|
ResponseStatus = (PublicWalkResponseStatusDto?)responseStatus,
|
|
MaxRadius = maxRadius,
|
|
Type = (PublicWalkRequestTypeDto?)type,
|
|
MinPrice = minPrice,
|
|
MustHaveResponse = mustHaveResponse,
|
|
SearchText = searchText
|
|
};
|
|
query.DynamicSortOrder = sortOrders.ToDto();
|
|
|
|
var queryResult = await _communicationService.GetPublicWalkRequestsWithResponseStatusExAsync(query, accessToken, token);
|
|
if (queryResult.Success)
|
|
return queryResult;
|
|
}
|
|
else
|
|
{
|
|
result.Success = false;
|
|
result.ErrorCode = CommunicationErrors.ServerNoConnection;
|
|
result.ErrorMessage = Errors.Server_NoConnection;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gibt eine Anzahl von öffentlichen Anfragen zurück, absteigend nach Datum sortiert
|
|
/// </summary>
|
|
/// <param name="take">Wie viele sollen genommen werden?</param>
|
|
/// <returns>Liste von öffntlichen Anfragen</returns>
|
|
public async Task<List<PublicWalkRequest>> GetLatestAsync(int take)
|
|
{
|
|
//var requests = await Repository.Query(c => c.Deleted == false).OrderByDescending(c => c.UpdatedAt).Take(take).ToListAsync();
|
|
var requests = (await Repository.FindAsync(c => c.Deleted == false, c => c.StartDate, 0, take, false)).ToList();
|
|
return requests;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gibt eine Anzahl von öffentlichen Anfragen zurück, absteigend nach Datum sortiert
|
|
/// </summary>
|
|
/// <param name="appUserId">Id des App-Users</param>
|
|
/// <param name="language">Gewünschte Sprache</param>
|
|
/// <param name="take">Wie viele sollen genommen werden?</param>
|
|
/// <param name="accessToken">Aktuelles Accesstoken</param>
|
|
/// <param name="token">CancellationToken</param>
|
|
/// <returns>Liste von öffntlichen Anfragen</returns>
|
|
public async Task<List<PublicWalkRequestWithNames>> GetLatestWithNamesAsync(string appUserId, string language, int take, string accessToken, CancellationToken token)
|
|
{
|
|
var isConnected = await _communicationService.IsConnected();
|
|
if (isConnected)
|
|
{
|
|
var requestResult = await _communicationService.GetPublicWalkRequestsLatestAsync(appUserId, language, take, accessToken, token);
|
|
if (requestResult.Success)
|
|
return requestResult.Value;
|
|
}
|
|
|
|
//var requests = await _namesRepository.Query(c => c.Deleted == false).OrderBy(c => c.StartDate).Take(take).ToListAsync();
|
|
var requests = (await _namesRepository.FindAsync(c => c.Deleted == false, c => c.StartDate, 0, take, true)).ToList();
|
|
return requests;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gibt eine öffentliche Anfrage zurück
|
|
/// </summary>
|
|
/// <param name="id">Id der Anfrage</param>
|
|
/// <param name="language">Gewünschte Sprache</param>
|
|
/// <param name="accessToken">Aktuelles Accesstoken</param>
|
|
/// <param name="token">CancellationToken</param>
|
|
/// <returns>Öffentliche Anfrage oder null, wenn nicht gefunden</returns>
|
|
public async Task<PublicWalkRequestWithNames> GetWithNamesAsync(string id, string language, string accessToken, CancellationToken token)
|
|
{
|
|
var isConnected = await _communicationService.IsConnected();
|
|
if (isConnected)
|
|
{
|
|
var requestResult = await _communicationService.GetPublicWalkRequestWithNamesAsync(id, language, accessToken, token);
|
|
if (requestResult.Success)
|
|
return requestResult.Value;
|
|
}
|
|
|
|
var request = await _namesRepository.FirstOrDefaultAsync(c => c.Id == id).ConfigureAwait(false);
|
|
return request;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Hinzufügen einer öffentlichen Anfrage
|
|
/// </summary>
|
|
/// <param name="request">Öffentliche Anfrage</param>
|
|
/// <param name="accessToken">Aktuelles Accesstoken</param>
|
|
/// <param name="token">CancellationToken</param>
|
|
/// <returns>PublicWalkRequest</returns>
|
|
public async Task<PublicWalkRequest> AddAsync(PublicWalkRequest request, string accessToken, CancellationToken token)
|
|
{
|
|
//Zuerst in der Datenbank
|
|
Repository.Add(request);
|
|
await CommitAsync();
|
|
|
|
//Jetzt am Server oder Delta erstellen
|
|
var createDelta = true;
|
|
var isConnected = await _communicationService.IsConnected();
|
|
if (isConnected)
|
|
{
|
|
var dto = request.ToCreateDto();
|
|
|
|
var createResult = await _communicationService.CreatePublicWalkRequestAsync(dto, accessToken, token);
|
|
if (createResult.Success)
|
|
{
|
|
if (createResult.Value.Status == CreateStatus.Success)
|
|
{
|
|
createDelta = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (createDelta)
|
|
{
|
|
await _pushService.AddAsync(nameof(PublicWalkRequest), request.Id, SyncOperation.Create, request).ConfigureAwait(false);
|
|
}
|
|
|
|
return request;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Stornieren einer öffentlichen Anfrage
|
|
/// </summary>
|
|
/// <param name="publicWalkRequestId">Id der Öffentliche Anfrage</param>
|
|
/// <param name="accessToken">Aktuelles Accesstoken</param>
|
|
/// <param name="token">CancellationToken</param>
|
|
/// <returns>PublicWalkRequest</returns>
|
|
public async Task<bool> CancelAsync(string publicWalkRequestId, string accessToken, CancellationToken token)
|
|
{
|
|
var localRequest = await Repository.FirstOrDefaultAsync(c => c.Id == publicWalkRequestId, false);
|
|
|
|
if (localRequest != null)
|
|
{
|
|
localRequest.Status = PublicWalkRequestStatus.Cancelled;
|
|
localRequest.UpdatedAt = DateTimeOffset.UtcNow;
|
|
Repository.Update(localRequest);
|
|
await CommitAsync();
|
|
|
|
//Jetzt am Server oder Delta erstellen
|
|
var createDelta = true;
|
|
var isConnected = await _communicationService.IsConnected();
|
|
if (isConnected)
|
|
{
|
|
var dto = new PublicWalkRequestCancelDto()
|
|
{
|
|
PublicWalkRequestId = publicWalkRequestId,
|
|
UpdatedAt = localRequest.UpdatedAt
|
|
};
|
|
|
|
var cancelResult = await _communicationService.CancelPublicWalkRequestAsync(dto, accessToken, token);
|
|
if (cancelResult.Success)
|
|
{
|
|
if (cancelResult.Value)
|
|
{
|
|
createDelta = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (createDelta)
|
|
{
|
|
await _pushService.AddAsync(nameof(PublicWalkRequest), localRequest.Id, SyncOperation.Edit, localRequest).ConfigureAwait(false);
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Akzeptieren eines Angebotes zu einer öffnentlichen Anfrage
|
|
/// </summary>
|
|
/// <param name="publicWalkRequestId">Id der öffentlichen Anfrage</param>
|
|
/// <param name="publicWalkResponseId">Id des akzeptierten Angebotes</param>
|
|
/// <param name="appUserId">Id des Hundebesitzers</param>
|
|
/// <param name="accessToken">Aktuelles Accesstoken</param>
|
|
/// <param name="token">CancellationToken</param>
|
|
/// <returns>Erstellter Walk wenn erfolgreich, false sonst</returns>
|
|
public async Task<Walk> AcceptResponseAsync(string publicWalkRequestId, string publicWalkResponseId, string appUserId, string accessToken, CancellationToken token)
|
|
{
|
|
var dto = new PublicWalkRequestAcceptDto()
|
|
{
|
|
PublicWalkRequestId = publicWalkRequestId,
|
|
PublicWalkResponseId = publicWalkResponseId,
|
|
DogOwnerId = appUserId,
|
|
UpdatedAt = DateTimeOffset.UtcNow
|
|
};
|
|
|
|
//Das hier muss online funktionieren, damit es lokal gespeichert wird
|
|
var isConnected = await _communicationService.IsConnected();
|
|
if (isConnected)
|
|
{
|
|
var acceptResult = await _communicationService.AcceptPublicWalkRequestAsync(dto, accessToken, token);
|
|
if (acceptResult.Success)
|
|
{
|
|
//Nun lokal aktualisieren?
|
|
var localRequest = await Repository.FirstOrDefaultAsync(c => c.Id == publicWalkRequestId, false);
|
|
if (localRequest != null)
|
|
{
|
|
localRequest.PublicWalkResponseId = publicWalkResponseId;
|
|
localRequest.Status = PublicWalkRequestStatus.Placed;
|
|
localRequest.UpdatedAt = dto.UpdatedAt;
|
|
localRequest.PlacedDate = dto.UpdatedAt;
|
|
|
|
Repository.Update(localRequest);
|
|
await CommitAsync();
|
|
|
|
//Walk lokal anlegen wenn nicht vorhanden
|
|
var existingWalk = _walksRepository.FirstOrDefaultAsync(c => c.Id == acceptResult.Value.Id);
|
|
if (existingWalk == null)
|
|
{
|
|
_walksRepository.Add(acceptResult.Value);
|
|
await CommitAsync();
|
|
}
|
|
|
|
return acceptResult.Value;
|
|
}
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
#region Pull-Push Implementation
|
|
|
|
/// <summary>
|
|
/// Holen der Daten vom lokalen Speicher die noch nicht synchronisiert wurden und senden an den Server
|
|
/// </summary>
|
|
/// <param name="accessToken">Aktuelles Accesstoken</param>
|
|
/// <param name="token">CancellationToken</param>
|
|
/// <returns>Task</returns>
|
|
public async Task<SyncResult<PublicWalkRequest>> PushAsync(string accessToken, CancellationToken token)
|
|
{
|
|
var result = new SyncResult<PublicWalkRequest>();
|
|
|
|
if (await _pushService.HasOpenAsync(nameof(PublicWalkRequest)) > 0)
|
|
{
|
|
var deltas = await _pushService.GetAllAsync(nameof(PublicWalkRequest));
|
|
if (deltas.Any())
|
|
{
|
|
var user = await _appUserRepository.FirstOrDefaultAsync(c => c.Id != "", false).ConfigureAwait(false);
|
|
deltas = deltas.OrderBy(c => c.DateTime).ToList();
|
|
|
|
var isConnected = await _communicationService.IsConnected();
|
|
|
|
if (!isConnected) return result;
|
|
|
|
foreach (var syncInfoPush in deltas)
|
|
{
|
|
try
|
|
{
|
|
if (!string.IsNullOrWhiteSpace(syncInfoPush.Value))
|
|
{
|
|
var request = JsonSerializer.Deserialize<PublicWalkRequest>(syncInfoPush.Value, new JsonSerializerOptions(JsonSerializerDefaults.Web));
|
|
|
|
if (syncInfoPush.Operation == SyncOperation.Create)
|
|
{
|
|
var createDto = request.ToCreateDto();
|
|
var createResult = await _communicationService.CreatePublicWalkRequestAsync(createDto, accessToken, token);
|
|
if (createResult.Success && createResult.Value.Status != CreateStatus.Error)
|
|
{
|
|
await _pushService.RemoveAsync(syncInfoPush.Id).ConfigureAwait(false);
|
|
}
|
|
//TODO: Was tun wenn Fehler?
|
|
}
|
|
else if (syncInfoPush.Operation == SyncOperation.Edit)
|
|
{
|
|
var updateDto = request.ToDto();
|
|
var updateResult = await _communicationService.UpdatePublicWalkRequestAsync(updateDto, accessToken, token);
|
|
if (updateResult.Success && updateResult.Value)
|
|
await _pushService.RemoveAsync(syncInfoPush.Id).ConfigureAwait(false);
|
|
//TODO: Was tun wenn Fehler?
|
|
}
|
|
else
|
|
{
|
|
var deleteDto = request.ToDto();
|
|
var deleteResult = await _communicationService.DeletePublicWalkRequestAsync(deleteDto, user.Id, accessToken, token);
|
|
if (deleteResult.Success && deleteResult.Value)
|
|
await _pushService.RemoveAsync(syncInfoPush.Id).ConfigureAwait(false);
|
|
//TODO: Was tun wenn Fehler?
|
|
}
|
|
}
|
|
else
|
|
{
|
|
await _pushService.RemoveAsync(syncInfoPush.Id).ConfigureAwait(false);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
System.Diagnostics.Debug.WriteLine(ex.Message);
|
|
await _pushService.RemoveAsync(syncInfoPush.Id).ConfigureAwait(false);
|
|
}
|
|
}
|
|
//Else ist nichts tun, konnte nicht übertragen werden.
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Holen der letzten Daten vom Server und Synchronisieren mit den lokalen Daten
|
|
/// </summary>
|
|
/// <param name="language">Sprache</param>
|
|
/// <param name="accessToken">Aktuelles Accesstoken</param>
|
|
/// <param name="token">CancellationToken</param>
|
|
/// <returns>Task</returns>
|
|
public async Task<SyncResult<PublicWalkRequest>> PullAsync(string language, string accessToken, CancellationToken token)
|
|
{
|
|
var result = new SyncResult<PublicWalkRequest>();
|
|
|
|
var isConnected = await _communicationService.IsConnected();
|
|
|
|
if (isConnected)
|
|
{
|
|
var user = await _appUserRepository.FirstOrDefaultAsync(c => c.Id != "", false).ConfigureAwait(false);
|
|
|
|
//Zuerst lezte Aktivität holen...
|
|
DateTimeOffset? lastUpdate = null;
|
|
var lastSyncInfo = await _pullService.GetAsync(nameof(PublicWalkRequest));
|
|
if (lastSyncInfo != null)
|
|
lastUpdate = lastSyncInfo.LastUpdate;
|
|
|
|
var requestResult = await _communicationService.GetPublicWalkRequestsForSyncAsync(user.Id, lastUpdate, accessToken, token);
|
|
if (requestResult.Success)
|
|
{
|
|
result = await HandleChangesAsync(requestResult.Value);
|
|
if (result.LastUpdate != null)
|
|
await _pullService.AddOrUpddateAsync(nameof(PublicWalkRequest), result.LastUpdate.Value).ConfigureAwait(false);
|
|
}
|
|
|
|
result.LastUpdate ??= lastUpdate;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Private
|
|
|
|
/// <summary>
|
|
/// Behandeln der Liste von öffentlichern Anfragen wenn welche vom Online-Store geholt werden.
|
|
/// </summary>
|
|
/// <param name="requests">Liste der anfragen</param>
|
|
/// <returns>Task</returns>
|
|
private async Task<SyncResult<PublicWalkRequest>> HandleChangesAsync(List<PublicWalkRequest> requests)
|
|
{
|
|
var result = new SyncResult<PublicWalkRequest>();
|
|
|
|
//Je Rasse durchgehen ob was gemacht werden soll
|
|
foreach (var request in requests)
|
|
{
|
|
var localRequest = await Repository.FirstOrDefaultAsync(c => c.Id == request.Id, false);
|
|
if (localRequest != null && localRequest.UpdatedAt < request.UpdatedAt)
|
|
{
|
|
if (localRequest.UpdatedAt >= request.UpdatedAt)
|
|
{
|
|
if (result.LastUpdate == null || result.LastUpdate < localRequest.UpdatedAt)
|
|
result.LastUpdate = localRequest.UpdatedAt;
|
|
continue;
|
|
}
|
|
|
|
var deleted = localRequest.Deleted == false && request.Deleted;
|
|
|
|
localRequest.Version = request.Version;
|
|
localRequest.UpdatedAt = request.UpdatedAt;
|
|
localRequest.Deleted = request.Deleted;
|
|
|
|
localRequest.PickupAddress = request.PickupAddress;
|
|
localRequest.Lat = request.Lat;
|
|
localRequest.Lng = request.Lng;
|
|
localRequest.RequestType = request.RequestType;
|
|
localRequest.StartDate = request.StartDate;
|
|
localRequest.EndDate = request.EndDate;
|
|
localRequest.DogId = request.DogId;
|
|
localRequest.Exclusive = request.Exclusive;
|
|
localRequest.Price = request.Price;
|
|
localRequest.Info = request.Info;
|
|
localRequest.ExpirationDate = request.ExpirationDate;
|
|
localRequest.DogWalkerId = request.DogWalkerId;
|
|
localRequest.PublicWalkResponseId = request.PublicWalkResponseId;
|
|
localRequest.ResponseCount = request.ResponseCount;
|
|
localRequest.Status = request.Status;
|
|
localRequest.PlacedDate = request.PlacedDate;
|
|
|
|
localRequest.Created = request.Created;
|
|
|
|
if (result.LastUpdate == null || result.LastUpdate < localRequest.UpdatedAt)
|
|
result.LastUpdate = localRequest.UpdatedAt;
|
|
if (!deleted)
|
|
result.Updated.Add(localRequest);
|
|
else
|
|
result.Deleted.Add(localRequest);
|
|
Repository.Update(localRequest);
|
|
}
|
|
|
|
if (localRequest == null)
|
|
{
|
|
localRequest = new PublicWalkRequest()
|
|
{
|
|
Id = request.Id,
|
|
Version = request.Version,
|
|
UpdatedAt = request.UpdatedAt,
|
|
Deleted = request.Deleted,
|
|
|
|
PickupAddress = request.PickupAddress,
|
|
Lat = request.Lat,
|
|
Lng = request.Lng,
|
|
RequestType = request.RequestType,
|
|
StartDate = request.StartDate,
|
|
EndDate = request.EndDate,
|
|
DogId = request.DogId,
|
|
Exclusive = request.Exclusive,
|
|
Price = request.Price,
|
|
Info = request.Info,
|
|
ExpirationDate = request.ExpirationDate,
|
|
DogWalkerId = request.DogWalkerId,
|
|
PublicWalkResponseId = request.PublicWalkResponseId,
|
|
ResponseCount = request.ResponseCount,
|
|
Status = request.Status,
|
|
PlacedDate = request.PlacedDate,
|
|
Created = request.Created,
|
|
};
|
|
|
|
Repository.Add(localRequest);
|
|
|
|
if (result.LastUpdate == null || result.LastUpdate < localRequest.UpdatedAt)
|
|
result.LastUpdate = localRequest.UpdatedAt;
|
|
result.Added.Add(localRequest);
|
|
}
|
|
}
|
|
|
|
if (result.HasChanges)
|
|
{
|
|
try
|
|
{
|
|
await CommitAsync().ConfigureAwait(false);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
var err = ex.Message;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|