1441 lines
63 KiB
C#
1441 lines
63 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Text.Json;
|
|
using System.Threading.Tasks;
|
|
using gehGassi.Dto.Common;
|
|
using gehGassi.Dto;
|
|
using gehGassi.Dto.Walks;
|
|
using gehGassiApp.Core.Data;
|
|
using gehGassiApp.Core.Interfaces;
|
|
using gehGassiApp.Core.Interfaces.Synchronization;
|
|
using gehGassiApp.Core.Resources;
|
|
using gehGassiApp.Domain.Common;
|
|
using gehGassiApp.Domain.Users;
|
|
using gehGassiApp.Domain.Walks;
|
|
using gehGassi.Dto.Ratings;
|
|
using gehGassiApp.Core.Mapper;
|
|
|
|
namespace gehGassiApp.Core.Services
|
|
{
|
|
/// <summary>
|
|
/// Service der die Verwaltung von Walks ermöglicht
|
|
/// </summary>
|
|
public class WalkService : ServiceBase<Walk>, IWalkService
|
|
{
|
|
private readonly ICommunicationService _communicationService;
|
|
private readonly ISyncInfoPullService _pullService;
|
|
private readonly ISyncInfoPushService _pushService;
|
|
private readonly ILocationService _locationService;
|
|
|
|
private readonly IRepository<AppUser> _appUserRepository;
|
|
|
|
/// <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 WalkService(IUnitOfWork unitOfWork, ICommunicationService communicationService, ISyncInfoPullService syncInfoPullService, ISyncInfoPushService syncInfoPushService, ILocationService locationService) : base(unitOfWork)
|
|
{
|
|
_communicationService = communicationService;
|
|
_pullService = syncInfoPullService;
|
|
_pushService = syncInfoPushService;
|
|
_locationService = locationService;
|
|
|
|
_appUserRepository = unitOfWork.GetRepository<AppUser>();
|
|
}
|
|
|
|
/// <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 Walk 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<Walk> GetAsync(object id, bool noTracking = true)
|
|
{
|
|
await Task.Delay(1);
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gibt einen Walk mit Namen aufgelöst zurück. Kommt vom Server
|
|
/// </summary>
|
|
/// <param name="walkId">Id des Walks</param>
|
|
/// <param name="language">Gewünschte Sprache</param>
|
|
/// <param name="accessToken">Aktuelles Accesstoken</param>
|
|
/// <param name="token">CancellationToken</param>
|
|
/// <returns>WalkWithNames oder null, wenn nicht gefunden</returns>
|
|
public async Task<CommunicationResult<WalkWithNames>> GetWalkWithNamesAsync(string walkId, string language, string accessToken, CancellationToken token)
|
|
{
|
|
var result = new CommunicationResult<WalkWithNames>();
|
|
result.Success = false;
|
|
|
|
var isConnected = await _communicationService.IsConnected();
|
|
if (isConnected)
|
|
{
|
|
var queryResult = await _communicationService.GetWalkWithNamesAsync(walkId, language, accessToken, token);
|
|
if (queryResult.Success)
|
|
{
|
|
result.Success = true;
|
|
result.Value = queryResult.Value;
|
|
return result;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
result.Success = false;
|
|
result.ErrorCode = CommunicationErrors.ServerNoConnection;
|
|
result.ErrorMessage = Errors.Server_NoConnection;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gibt den nächsten Walk für einen Hundebesitzer zurück
|
|
/// </summary>
|
|
/// <param name="ownerId">Id des Hundebesitzers</param>
|
|
/// <param name="date">Datum ab wann gesucht werden soll. Normalerweise "Jetzt"</param>
|
|
/// <param name="language">Gewünschte Sprache</param>
|
|
/// <param name="appMode">Aktueller appMode</param>
|
|
/// <param name="location">Aktuelle Position</param>
|
|
/// <param name="accessToken">Aktuelles Accesstoken</param>
|
|
/// <param name="token">CancellationToken</param>
|
|
/// <returns>Nächster Walk oder null, wenn keiner vorhanden</returns>
|
|
public async Task<CommunicationResult<WalkWithNames>> GetNextWalkForOwnerAsync(string ownerId, DateTimeOffset date, string language, AppMode appMode, LocationDto location, string accessToken, CancellationToken token)
|
|
{
|
|
var result = new CommunicationResult<WalkWithNames>();
|
|
result.Success = false;
|
|
|
|
var isConnected = await _communicationService.IsConnected();
|
|
if (isConnected)
|
|
{
|
|
var query = new WalksQueryDto()
|
|
{
|
|
Location = location,
|
|
Language = language,
|
|
AppMode = (AppModeDto)appMode,
|
|
Take = 1,
|
|
Skip = 0,
|
|
LastUpdate = null,
|
|
DogOwnerId = ownerId,
|
|
DogWalkerId = string.Empty,
|
|
Date = date,
|
|
Status = null,
|
|
ServiceType = null,
|
|
PaymentStatus = null,
|
|
IgnoreCancelled = true,
|
|
ForNextWalk = true
|
|
};
|
|
|
|
var queryResult = await _communicationService.GetWalksWithNamesAsync(query, accessToken, token);
|
|
if (queryResult.Success && queryResult.Value.Count >= 1)
|
|
{
|
|
result.Success = true;
|
|
result.Value = queryResult.Value.First();
|
|
return result;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
result.Success = false;
|
|
result.ErrorCode = CommunicationErrors.ServerNoConnection;
|
|
result.ErrorMessage = Errors.Server_NoConnection;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gibt den nächsten Walk für einen Dogwalker zurück
|
|
/// </summary>
|
|
/// <param name="walkerId">Id des Hundebesitzers</param>
|
|
/// <param name="date">Datum ab wann gesucht werden soll. Normalerweise "Jetzt"</param>
|
|
/// <param name="language">Gewünschte Sprache</param>
|
|
/// <param name="appMode">Aktueller appMode</param>
|
|
/// <param name="location">Aktuelle Position</param>
|
|
/// <param name="accessToken">Aktuelles Accesstoken</param>
|
|
/// <param name="token">CancellationToken</param>
|
|
/// <returns>Nächster Walk oder null, wenn keiner vorhanden</returns>
|
|
public async Task<CommunicationResult<WalkWithNames>> GetNextWalkForWalkerAsync(string walkerId, DateTimeOffset date, string language, AppMode appMode, LocationDto location, string accessToken, CancellationToken token)
|
|
{
|
|
var result = new CommunicationResult<WalkWithNames>();
|
|
result.Success = false;
|
|
|
|
var isConnected = await _communicationService.IsConnected();
|
|
if (isConnected)
|
|
{
|
|
var query = new WalksQueryDto()
|
|
{
|
|
Location = location,
|
|
Language = language,
|
|
AppMode = (AppModeDto)appMode,
|
|
Take = 1,
|
|
Skip = 0,
|
|
LastUpdate = null,
|
|
DogOwnerId = string.Empty,
|
|
DogWalkerId = walkerId,
|
|
Date = date,
|
|
Status = null,
|
|
ServiceType = null,
|
|
PaymentStatus = null,
|
|
IgnoreCancelled = true,
|
|
ForNextWalk = true
|
|
};
|
|
|
|
var queryResult = await _communicationService.GetWalksWithNamesWalkerAsync(query, accessToken, token);
|
|
if (queryResult.Success && queryResult.Value.Count >= 1)
|
|
{
|
|
result.Success = true;
|
|
result.Value = queryResult.Value.First();
|
|
return result;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
result.Success = false;
|
|
result.ErrorCode = CommunicationErrors.ServerNoConnection;
|
|
result.ErrorMessage = Errors.Server_NoConnection;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gibt Walks vom Server zurück
|
|
/// </summary>
|
|
/// <param name="dogOwnerId">Id des Hundebesitzers - angeben wenn für Hundebesitzer</param>
|
|
/// <param name="dogWalkerId">Id des Dogwalkers - angeben wenn für DogWalker</param>
|
|
/// <param name="date">Datum ab wann gesucht werden soll. Normalerweise "Jetzt", leer für alle</param>
|
|
/// <param name="status">Status des Walks, NULL wenn alle</param>
|
|
/// <param name="serviceType">Service Type, NULL wenn alle</param>
|
|
/// <param name="paymentStatus">Zahlungsstatus, NULL wenn alle</param>
|
|
/// <param name="dogFilter">Optinal: Filter Hund</param>
|
|
/// <param name="walkerFilter">Optional: Filter Walker</param>
|
|
/// <param name="ownerFilter">Optional: Filter Owner</param>
|
|
/// <param name="ignoreCancelled">Stornierte ignorieren</param>
|
|
/// <param name="ignoreRequested">Sollen Walks die noch eine Anfrage sind, ohne Akzeptiert oder Agelehnt ignorniert werden?</param>
|
|
/// <param name="ignoreDeclined">Sollen abgelehnte Anfragen ignoriert werden?</param>
|
|
/// <param name="sortOrders">Liste von Sortierangaben</param>
|
|
/// <param name="language">Gewünschte Sprache</param>
|
|
/// <param name="appMode">Aktueller appMode</param>
|
|
/// <param name="location">Aktuelle Position</param>
|
|
/// <param name="take">Wie viele Walks sollen abgerufen werden? -1 Wenn nicht anwenden.</param>
|
|
/// <param name="skip">Wie viele Walks sollen ausgelassen werden? -1 Wenn nicht anwenden.</param>
|
|
/// <param name="accessToken">Aktuelles Accesstoken</param>
|
|
/// <param name="token">CancellationToken</param>
|
|
/// <returns>Nächster Walk oder null, wenn keiner vorhanden</returns>
|
|
public async Task<ListCommunicationResult<List<WalkWithNames>>> GetWalksAsync(string dogOwnerId, string dogWalkerId, DateTimeOffset? date, WalkStatus? status, WalkServiceType? serviceType, PaymentStatus? paymentStatus, string dogFilter, string walkerFilter, string ownerFilter, bool ignoreCancelled, bool ignoreRequested, bool ignoreDeclined, List<DynamicSortOrder> sortOrders, string language, AppMode appMode, LocationDto location, int take, int skip, string accessToken, CancellationToken token)
|
|
{
|
|
var result = new ListCommunicationResult<List<WalkWithNames>>() { Value = new List<WalkWithNames>() };
|
|
|
|
var isConnected = await _communicationService.IsConnected();
|
|
if (isConnected)
|
|
{
|
|
var query = new WalksQueryDto()
|
|
{
|
|
Location = location,
|
|
Language = language,
|
|
AppMode = (AppModeDto)appMode,
|
|
Take = take,
|
|
Skip = skip,
|
|
LastUpdate = null,
|
|
DogOwnerId = dogOwnerId,
|
|
DogWalkerId = dogWalkerId,
|
|
Date = date,
|
|
Status = (WalkStatusDto?)status,
|
|
ServiceType = (WalkServiceTypeDto?)serviceType,
|
|
PaymentStatus = (PaymentStatusDto?)paymentStatus,
|
|
DogFilter = dogFilter,
|
|
WalkerFilter = walkerFilter,
|
|
OwnerFilter = ownerFilter,
|
|
IgnoreCancelled = ignoreCancelled,
|
|
IgnoreRequested = ignoreRequested,
|
|
IgnoreDeclined = ignoreDeclined
|
|
};
|
|
query.DynamicSortOrder = sortOrders.ToDto();
|
|
|
|
var queryResult = await _communicationService.GetWalksWithNamesAsync(query, accessToken, token);
|
|
if (queryResult.Success && queryResult.Value.Count >= 1)
|
|
{
|
|
return queryResult;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
result.Success = false;
|
|
result.ErrorCode = CommunicationErrors.ServerNoConnection;
|
|
result.ErrorMessage = Errors.Server_NoConnection;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gibt Walks vom Server zurück.
|
|
/// Sondersituation: Für Walker werden nur Walks mit einem Paymentstatus größer gleich Authorized zurück
|
|
/// </summary>
|
|
/// <param name="dogOwnerId">Id des Hundebesitzers - angeben wenn für Hundebesitzer</param>
|
|
/// <param name="dogWalkerId">Id des Dogwalkers - angeben wenn für DogWalker</param>
|
|
/// <param name="date">Datum ab wann gesucht werden soll. Normalerweise "Jetzt", leer für alle</param>
|
|
/// <param name="status">Status des Walks, NULL wenn alle</param>
|
|
/// <param name="serviceType">Service Type, NULL wenn alle</param>
|
|
/// <param name="paymentStatus">Zahlungsstatus, NULL wenn alle</param>
|
|
/// <param name="dogFilter">Optinal: Filter Hund</param>
|
|
/// <param name="walkerFilter">Optional: Filter Walker</param>
|
|
/// <param name="ownerFilter">Optional: Filter Owner</param>
|
|
/// <param name="ignoreCancelled">Stornierte ignorieren</param>
|
|
/// <param name="ignoreRequested">Sollen Walks die noch eine Anfrage sind, ohne Akzeptiert oder Agelehnt ignorniert werden?</param>
|
|
/// <param name="ignoreDeclined">Sollen abgelehnte Anfragen ignoriert werden?</param>
|
|
/// <param name="sortOrders">Liste von Sortierangaben</param>
|
|
/// <param name="language">Gewünschte Sprache</param>
|
|
/// <param name="appMode">Aktueller appMode</param>
|
|
/// <param name="location">Aktuelle Position</param>
|
|
/// <param name="take">Wie viele Walks sollen abgerufen werden? -1 Wenn nicht anwenden.</param>
|
|
/// <param name="skip">Wie viele Walks sollen ausgelassen werden? -1 Wenn nicht anwenden.</param>
|
|
/// <param name="accessToken">Aktuelles Accesstoken</param>
|
|
/// <param name="token">CancellationToken</param>
|
|
/// <returns>Nächster Walk oder null, wenn keiner vorhanden</returns>
|
|
public async Task<ListCommunicationResult<List<WalkWithNames>>> GetWalksWalkerAsync(string dogOwnerId, string dogWalkerId, DateTimeOffset? date, WalkStatus? status, WalkServiceType? serviceType, PaymentStatus? paymentStatus, string dogFilter, string walkerFilter, string ownerFilter, bool ignoreCancelled, bool ignoreRequested, bool ignoreDeclined, List<DynamicSortOrder> sortOrders, string language, AppMode appMode, LocationDto location, int take, int skip, string accessToken, CancellationToken token)
|
|
{
|
|
var result = new ListCommunicationResult<List<WalkWithNames>>() { Value = new List<WalkWithNames>() };
|
|
|
|
var isConnected = await _communicationService.IsConnected();
|
|
if (isConnected)
|
|
{
|
|
var query = new WalksQueryDto()
|
|
{
|
|
Location = location,
|
|
Language = language,
|
|
AppMode = (AppModeDto)appMode,
|
|
Take = take,
|
|
Skip = skip,
|
|
LastUpdate = null,
|
|
DogOwnerId = dogOwnerId,
|
|
DogWalkerId = dogWalkerId,
|
|
Date = date,
|
|
Status = (WalkStatusDto?)status,
|
|
ServiceType = (WalkServiceTypeDto?)serviceType,
|
|
PaymentStatus = (PaymentStatusDto?)paymentStatus,
|
|
DogFilter = dogFilter,
|
|
WalkerFilter = walkerFilter,
|
|
OwnerFilter = ownerFilter,
|
|
IgnoreCancelled = ignoreCancelled,
|
|
IgnoreRequested = ignoreRequested,
|
|
IgnoreDeclined = ignoreDeclined
|
|
};
|
|
query.DynamicSortOrder = sortOrders.ToDto();
|
|
|
|
var queryResult = await _communicationService.GetWalksWithNamesWalkerAsync(query, accessToken, token);
|
|
if (queryResult.Success && queryResult.Value.Count >= 1)
|
|
{
|
|
return queryResult;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
result.Success = false;
|
|
result.ErrorCode = CommunicationErrors.ServerNoConnection;
|
|
result.ErrorMessage = Errors.Server_NoConnection;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gibt eine Liste der nächsten Walks, laufende, nicht abgeschlossene, nicht bezahlte usw. für einen Hundebesitzer zurück.
|
|
/// </summary>
|
|
/// <param name="appUserId">Id des App-Users</param>
|
|
/// <param name="date">Datum ab dem gesucht</param>
|
|
/// <param name="language">Gewünschte Sprache</param>
|
|
/// <param name="skip">Datensätze auslassen</param>
|
|
/// <param name="take">Datensätze nehmen</param>
|
|
/// <param name="accessToken">Aktuelles Accesstoken</param>
|
|
/// <param name="token">CancellationToken</param>
|
|
/// <returns>ListCommunicationResult</returns>
|
|
public async Task<ListCommunicationResult<List<WalkWithNames>>> GetNextWalksOwnerAsync(string appUserId, DateTimeOffset date, string language, int take, int skip, string accessToken, CancellationToken token)
|
|
{
|
|
var result = new ListCommunicationResult<List<WalkWithNames>>() { Value = new List<WalkWithNames>() };
|
|
|
|
var isConnected = await _communicationService.IsConnected();
|
|
if (isConnected)
|
|
{
|
|
var queryResult = await _communicationService.GetNextWalksOwnerAsync(appUserId, date, language, take, skip, accessToken, token);
|
|
if (queryResult.Success && queryResult.Value.Count >= 1)
|
|
{
|
|
return queryResult;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
result.Success = false;
|
|
result.ErrorCode = CommunicationErrors.ServerNoConnection;
|
|
result.ErrorMessage = Errors.Server_NoConnection;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gibt eine Liste der nächsten Walks, laufende, nicht abgeschlossene, nicht bezahlte usw. für einen Walker zurück.
|
|
/// </summary>
|
|
/// <param name="appUserId">Id des App-Users</param>
|
|
/// <param name="date">Datum ab dem gesucht</param>
|
|
/// <param name="language">Gewünschte Sprache</param>
|
|
/// <param name="skip">Datensätze auslassen</param>
|
|
/// <param name="take">Datensätze nehmen</param>
|
|
/// <param name="accessToken">Aktuelles Accesstoken</param>
|
|
/// <param name="token">CancellationToken</param>
|
|
/// <returns>ListCommunicationResult</returns>
|
|
public async Task<ListCommunicationResult<List<WalkWithNames>>> GetNextWalksWalkerAsync(string appUserId, DateTimeOffset date, string language, int take, int skip, string accessToken, CancellationToken token)
|
|
{
|
|
var result = new ListCommunicationResult<List<WalkWithNames>>() { Value = new List<WalkWithNames>() };
|
|
|
|
var isConnected = await _communicationService.IsConnected();
|
|
if (isConnected)
|
|
{
|
|
var queryResult = await _communicationService.GetNextWalksWalkerAsync(appUserId, date, language, take, skip, accessToken, token);
|
|
if (queryResult.Success && queryResult.Value.Count >= 1)
|
|
{
|
|
return queryResult;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
result.Success = false;
|
|
result.ErrorCode = CommunicationErrors.ServerNoConnection;
|
|
result.ErrorMessage = Errors.Server_NoConnection;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gibt einen Walk zurück, welcher einer öffentlichen Anfrage zugeordnet ist
|
|
/// </summary>
|
|
/// <param name="publicWalkRequestId">Id der öffentlichen Anfrage</param>
|
|
/// <returns>Walk oder null, wenn nicht gefunden</returns>
|
|
public async Task<Walk> GetWalkByPublicRequestAsync(string publicWalkRequestId)
|
|
{
|
|
var localWalk = await Repository.FirstOrDefaultAsync(c => c.PublicWalkRequestId == publicWalkRequestId);
|
|
return localWalk;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gibt einen Walk zurück, welcher einer öffentlichen Anfrage zugeordnet ist - nur online
|
|
/// </summary>
|
|
/// <param name="publicWalkRequestId">Id der öffentlichen Anfrage</param>
|
|
/// <returns>Walk oder null, wenn nicht gefunden</returns>
|
|
public async Task<CommunicationResult<Walk>> GetWalkByPublicRequestAsync(string publicWalkRequestId, string accessToken, CancellationToken token)
|
|
{
|
|
var result = new CommunicationResult<Walk>();
|
|
result.Success = false;
|
|
|
|
var isConnected = await _communicationService.IsConnected();
|
|
if (isConnected)
|
|
{
|
|
var queryResult = await _communicationService.GetWalkByPublicRequestAsync(publicWalkRequestId, accessToken, token);
|
|
if (queryResult.Success && queryResult.Value != null)
|
|
{
|
|
result.Success = true;
|
|
result.Value = queryResult.Value;
|
|
return result;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
result.Success = false;
|
|
result.ErrorCode = CommunicationErrors.ServerNoConnection;
|
|
result.ErrorMessage = Errors.Server_NoConnection;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Stornieren eines Walks
|
|
/// </summary>
|
|
/// <param name="walkId">ID des Walks</param>
|
|
/// <param name="cancellationSource">Quelle der Stornierung</param>
|
|
/// <param name="cancellationReason">Grund der Stornierung</param>
|
|
/// <param name="accessToken">Aktuelles Accesstoken</param>
|
|
/// <param name="token">CancellationToken</param>
|
|
/// <returns>true wenn erfolgreich, false sonst</returns>
|
|
public async Task<bool> CancelAsync(string walkId, CancellationSource cancellationSource, string cancellationReason, string accessToken, CancellationToken token)
|
|
{
|
|
var success = false;
|
|
|
|
var localWalk = await Repository.FirstOrDefaultAsync(c => c.Id == walkId, false);
|
|
var updatedAt = DateTimeOffset.UtcNow;
|
|
if (localWalk != null)
|
|
{
|
|
localWalk.Status = WalkStatus.Cancelled;
|
|
localWalk.UpdatedAt = updatedAt;
|
|
localWalk.CancelledBy = cancellationSource;
|
|
localWalk.CancelledReason = cancellationReason;
|
|
|
|
Repository.Update(localWalk);
|
|
await CommitAsync();
|
|
success = true;
|
|
}
|
|
|
|
//Jetzt am Server oder Delta erstellen
|
|
var createDelta = true;
|
|
var isConnected = await _communicationService.IsConnected();
|
|
if (isConnected)
|
|
{
|
|
var dto = new WalkCancelDto()
|
|
{
|
|
WalkId = walkId,
|
|
UpdatedAt = updatedAt,
|
|
CancellationSource = (CancellationSourceDto)cancellationSource,
|
|
CancelledReason = cancellationReason
|
|
};
|
|
|
|
var cancelResult = await _communicationService.CancelWalkAsync(dto, accessToken, token);
|
|
if (cancelResult.Success)
|
|
{
|
|
if (cancelResult.Value)
|
|
{
|
|
success = true;
|
|
createDelta = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (createDelta)
|
|
{
|
|
await _pushService.AddAsync(nameof(Walk), localWalk.Id, SyncOperation.Edit, localWalk).ConfigureAwait(false);
|
|
}
|
|
|
|
return success;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Starten eines Walks
|
|
/// </summary>
|
|
/// <param name="walkId">ID des Walks</param>
|
|
/// <param name="accessToken">Aktuelles Accesstoken</param>
|
|
/// <param name="token">CancellationToken</param>
|
|
/// <returns>true wenn erfolgreich, false sonst</returns>
|
|
public async Task<bool> StartAsync(string walkId, string accessToken, CancellationToken token)
|
|
{
|
|
var success = false;
|
|
|
|
var localWalk = await Repository.FirstOrDefaultAsync(c => c.Id == walkId, false);
|
|
var updatedAt = DateTimeOffset.UtcNow;
|
|
if (localWalk != null)
|
|
{
|
|
localWalk.Status = WalkStatus.Started;
|
|
localWalk.Started = updatedAt;
|
|
localWalk.UpdatedAt = updatedAt;
|
|
|
|
Repository.Update(localWalk);
|
|
await CommitAsync();
|
|
success = true;
|
|
}
|
|
|
|
//Jetzt am Server oder Delta erstellen
|
|
var createDelta = true;
|
|
var isConnected = await _communicationService.IsConnected();
|
|
if (isConnected)
|
|
{
|
|
var dto = new WalkStartDto()
|
|
{
|
|
WalkId = walkId,
|
|
UpdatedAt = updatedAt
|
|
};
|
|
|
|
var cancelResult = await _communicationService.StartWalkAsync(dto, accessToken, token);
|
|
if (cancelResult.Success)
|
|
{
|
|
if (cancelResult.Value)
|
|
{
|
|
success = true;
|
|
createDelta = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (createDelta)
|
|
{
|
|
await _pushService.AddAsync(nameof(Walk), localWalk.Id, SyncOperation.Edit, localWalk).ConfigureAwait(false);
|
|
}
|
|
|
|
return success;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Abschließen eines Walks
|
|
/// </summary>
|
|
/// <param name="walkId">ID des Walks</param>
|
|
/// <param name="defactation">Kotabsatz?</param>
|
|
/// <param name="completedInfo">Info des Walkers zum abschluss</param>
|
|
/// <param name="ratingPoints">Punkte für die Bewertung des Walks</param>
|
|
/// <param name="ratingComment">Anmerkungen zum Rating des Walks</param>
|
|
/// <param name="ratingDogsPoints">Punkte für die Bewertung des Hundes / der Hunde</param>
|
|
/// <param name="ratingDogsComment">Anmerkung zum Rating des Hundes / der Hunde</param>
|
|
/// <param name="accessToken">Aktuelles Accesstoken</param>
|
|
/// <param name="token">CancellationToken</param>
|
|
/// <returns>true wenn erfolgreich, false sonst</returns>
|
|
public async Task<bool> CompleteAsync(string walkId, bool defactation, string completedInfo, decimal ratingPoints, string ratingComment, decimal ratingDogsPoints, string ratingDogsComment, string accessToken, CancellationToken token)
|
|
{
|
|
var success = false;
|
|
|
|
var localWalk = await Repository.FirstOrDefaultAsync(c => c.Id == walkId, false);
|
|
var updatedAt = DateTimeOffset.UtcNow;
|
|
if (localWalk != null)
|
|
{
|
|
localWalk.Status = WalkStatus.Completed;
|
|
localWalk.Completed = updatedAt;
|
|
localWalk.Defactation = defactation;
|
|
localWalk.CompletedInfo = completedInfo;
|
|
localWalk.UpdatedAt = updatedAt;
|
|
|
|
Repository.Update(localWalk);
|
|
await CommitAsync();
|
|
success = true;
|
|
}
|
|
|
|
//Jetzt am Server oder Delta erstellen
|
|
var createDelta = true;
|
|
var isConnected = await _communicationService.IsConnected();
|
|
if (isConnected)
|
|
{
|
|
var dto = new WalkCompleteDto()
|
|
{
|
|
WalkId = walkId,
|
|
CompletedInfo = completedInfo,
|
|
Defactation = defactation,
|
|
RatingInfo = ratingComment,
|
|
RatingPoints = ratingPoints,
|
|
RatingDogsPoints = ratingDogsPoints,
|
|
RatingDogsInfo = ratingDogsComment,
|
|
UpdatedAt = updatedAt
|
|
};
|
|
|
|
var cancelResult = await _communicationService.CompleteWalkAsync(dto, accessToken, token);
|
|
if (cancelResult.Success)
|
|
{
|
|
if (cancelResult.Value)
|
|
{
|
|
success = true;
|
|
createDelta = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (createDelta)
|
|
{
|
|
//TODO: Delta für Rating? Wie genau machen?
|
|
await _pushService.AddAsync(nameof(Walk), localWalk.Id, SyncOperation.Edit, localWalk).ConfigureAwait(false);
|
|
}
|
|
|
|
return success;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Zahlungsstatus eines Walks setzen
|
|
/// </summary>
|
|
/// <param name="walkId">ID des Walks</param>
|
|
/// <param name="paymentStatus">Zahlungsstatus der gesetzt werden soll</param>
|
|
/// <param name="accessToken">Aktuelles Accesstoken</param>
|
|
/// <param name="token">CancellationToken</param>
|
|
/// <returns>true wenn erfolgreich, false sonst</returns>
|
|
public async Task<bool> SetPaymentStatusAsync(string walkId, PaymentStatus paymentStatus, string accessToken, CancellationToken token)
|
|
{
|
|
var success = false;
|
|
|
|
var localWalk = await Repository.FirstOrDefaultAsync(c => c.Id == walkId, false);
|
|
var updatedAt = DateTimeOffset.UtcNow;
|
|
if (localWalk != null)
|
|
{
|
|
localWalk.PaymentStatus = paymentStatus;
|
|
localWalk.UpdatedAt = updatedAt;
|
|
|
|
Repository.Update(localWalk);
|
|
await CommitAsync();
|
|
success = true;
|
|
}
|
|
|
|
//Jetzt am Server oder Delta erstellen
|
|
var createDelta = true;
|
|
var isConnected = await _communicationService.IsConnected();
|
|
if (isConnected)
|
|
{
|
|
var dto = new WalkPaymentStatusDto()
|
|
{
|
|
WalkId = walkId,
|
|
UpdatedAt = updatedAt,
|
|
PaymentStatus = (PaymentStatusDto)paymentStatus
|
|
};
|
|
|
|
var cancelResult = await _communicationService.SetWalkPaymentStatusAsync(dto, accessToken, token);
|
|
if (cancelResult.Success)
|
|
{
|
|
if (cancelResult.Value)
|
|
{
|
|
success = true;
|
|
createDelta = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (createDelta)
|
|
{
|
|
await _pushService.AddAsync(nameof(Walk), localWalk.Id, SyncOperation.Edit, localWalk).ConfigureAwait(false);
|
|
}
|
|
|
|
return success;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Prüfen ob ein Walk für einen DogWalker in einem Zeitraum gebucht werden kann
|
|
/// </summary>
|
|
/// <param name="dogWalkerId">Id des DogWalkers</param>
|
|
/// <param name="start">Start</param>
|
|
/// <param name="end">Ende</param>
|
|
/// <param name="accessToken">Aktuelles Accesstoken</param>
|
|
/// <param name="token">CancellationToken</param>
|
|
/// <returns>true wenn verfügbar, false sonst</returns>
|
|
public async Task<bool> IsWalkPossibleAsync(string dogWalkerId, DateTimeOffset start, DateTimeOffset end, string accessToken, CancellationToken token)
|
|
{
|
|
var isConnected = await _communicationService.IsConnected();
|
|
if (isConnected)
|
|
{
|
|
var query = new WalkPossibleDto()
|
|
{
|
|
DogWalkerId = dogWalkerId,
|
|
Start = start,
|
|
End = end
|
|
};
|
|
|
|
var queryResult = await _communicationService.IsWalkPossibleAsync(query, accessToken, token);
|
|
if (queryResult.Success)
|
|
return queryResult.Value;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Anlegen eines Walks wenn DIREKT! buchen möglich ist.
|
|
/// Wird online versucht und erst dann lokal gespeichert
|
|
/// </summary>
|
|
/// <param name="requestDto">WalkCreateDto</param>
|
|
/// <param name="accessToken">Aktuelles Accesstoken</param>
|
|
/// <param name="token">CancellationToken</param>
|
|
/// <returns>Angelegter Walk oder null, wenn nicht erfolgreich</returns>
|
|
public async Task<CommunicationResult<Walk>> CreateWalkDirectAsync(WalkCreateDto requestDto, string accessToken, CancellationToken token)
|
|
{
|
|
var result = new CommunicationResult<Walk>() { Value = null, Success = false};
|
|
|
|
var isConnected = await _communicationService.IsConnected();
|
|
if (isConnected)
|
|
{
|
|
var createResult = await _communicationService.CreateWalkDirectAsync(requestDto, accessToken, token);
|
|
if (createResult.Success && createResult.Value.Status == CreateStatus.Success)
|
|
{
|
|
var walk = createResult.Value.Value;
|
|
if (walk != null)
|
|
{
|
|
Repository.Add(walk);
|
|
await CommitAsync();
|
|
|
|
result.Success = true;
|
|
result.Value = walk;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
result.Success = false;
|
|
result.Value = null;
|
|
result.ErrorCode = createResult.ErrorCode;
|
|
result.ErrorMessage = createResult.ErrorMessage;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Anlegen eines Walks als Anfrage
|
|
/// Wird online versucht und erst dann lokal gespeichert
|
|
/// </summary>
|
|
/// <param name="requestDto">WalkCreateDto</param>
|
|
/// <param name="accessToken">Aktuelles Accesstoken</param>
|
|
/// <param name="token">CancellationToken</param>
|
|
/// <returns>Angelegter Walk oder null, wenn nicht erfolgreich</returns>
|
|
public async Task<CommunicationResult<Walk>> CreateWalkRequestAsync(WalkCreateDto requestDto, string accessToken, CancellationToken token)
|
|
{
|
|
var result = new CommunicationResult<Walk>() { Value = null, Success = false };
|
|
|
|
var isConnected = await _communicationService.IsConnected();
|
|
if (isConnected)
|
|
{
|
|
var createResult = await _communicationService.CreateWalkRequestAsync(requestDto, accessToken, token);
|
|
if (createResult.Success && createResult.Value.Status == CreateStatus.Success)
|
|
{
|
|
var walk = createResult.Value.Value;
|
|
if (walk != null)
|
|
{
|
|
Repository.Add(walk);
|
|
await CommitAsync();
|
|
|
|
result.Success = true;
|
|
result.Value = walk;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
result.Success = false;
|
|
result.Value = null;
|
|
result.ErrorCode = createResult.ErrorCode;
|
|
result.ErrorMessage = createResult.ErrorMessage;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Akzeptieren eines Walks
|
|
/// </summary>
|
|
/// <param name="walkId">ID des Walks</param>
|
|
/// <param name="accessToken">Aktuelles Accesstoken</param>
|
|
/// <param name="token">CancellationToken</param>
|
|
/// <returns>true wenn erfolgreich, false sonst</returns>
|
|
public async Task<bool> AcceptAsync(string walkId, string accessToken, CancellationToken token)
|
|
{
|
|
var success = false;
|
|
|
|
var localWalk = await Repository.FirstOrDefaultAsync(c => c.Id == walkId, false);
|
|
var updatedAt = DateTimeOffset.UtcNow;
|
|
if (localWalk != null)
|
|
{
|
|
localWalk.Status = WalkStatus.Accepted;
|
|
localWalk.PaymentStatus = PaymentStatus.Pending;
|
|
localWalk.UpdatedAt = updatedAt;
|
|
|
|
if(localWalk.Price == 0)
|
|
localWalk.PaymentStatus = PaymentStatus.Paid;
|
|
|
|
Repository.Update(localWalk);
|
|
await CommitAsync();
|
|
success = true;
|
|
}
|
|
|
|
//Jetzt am Server oder Delta erstellen
|
|
var createDelta = true;
|
|
var isConnected = await _communicationService.IsConnected();
|
|
if (isConnected)
|
|
{
|
|
var dto = new WalkAcceptDto()
|
|
{
|
|
WalkId = walkId,
|
|
UpdatedAt = updatedAt
|
|
};
|
|
|
|
var cancelResult = await _communicationService.AcceptWalkAsync(dto, accessToken, token);
|
|
if (cancelResult.Success)
|
|
{
|
|
if (cancelResult.Value)
|
|
{
|
|
success = true;
|
|
createDelta = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (createDelta)
|
|
{
|
|
await _pushService.AddAsync(nameof(Walk), localWalk.Id, SyncOperation.Edit, localWalk).ConfigureAwait(false);
|
|
}
|
|
|
|
return success;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ablehnen eines Walks
|
|
/// </summary>
|
|
/// <param name="walkId">ID des Walks</param>
|
|
/// <param name="declineReason">Grund der Ablehnung</param>
|
|
/// <param name="accessToken">Aktuelles Accesstoken</param>
|
|
/// <param name="token">CancellationToken</param>
|
|
/// <returns>true wenn erfolgreich, false sonst</returns>
|
|
public async Task<bool> DeclineAsync(string walkId, string declineReason, string accessToken, CancellationToken token)
|
|
{
|
|
var success = false;
|
|
|
|
var localWalk = await Repository.FirstOrDefaultAsync(c => c.Id == walkId, false);
|
|
var updatedAt = DateTimeOffset.UtcNow;
|
|
if (localWalk != null)
|
|
{
|
|
localWalk.Status = WalkStatus.Declined;
|
|
localWalk.UpdatedAt = updatedAt;
|
|
localWalk.DeclinedReason = declineReason;
|
|
|
|
Repository.Update(localWalk);
|
|
await CommitAsync();
|
|
success = true;
|
|
}
|
|
|
|
//Jetzt am Server oder Delta erstellen
|
|
var createDelta = true;
|
|
var isConnected = await _communicationService.IsConnected();
|
|
if (isConnected)
|
|
{
|
|
var dto = new WalkDeclineDto()
|
|
{
|
|
WalkId = walkId,
|
|
UpdatedAt = updatedAt,
|
|
DeclineReason = declineReason
|
|
};
|
|
|
|
var cancelResult = await _communicationService.DeclineWalkAsync(dto, accessToken, token);
|
|
if (cancelResult.Success)
|
|
{
|
|
if (cancelResult.Value)
|
|
{
|
|
success = true;
|
|
createDelta = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (createDelta)
|
|
{
|
|
await _pushService.AddAsync(nameof(Walk), localWalk.Id, SyncOperation.Edit, localWalk).ConfigureAwait(false);
|
|
}
|
|
|
|
return success;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gibt zurück ob ein Walker Anfragen hat
|
|
/// </summary>
|
|
/// <param name="dogWalkerId">Id des Walkers</param>
|
|
/// <returns>true wenn ja, false sonst</returns>
|
|
public async Task<bool> HasRequestedAsync(string dogWalkerId)
|
|
{
|
|
var requested = await Repository.CountAsync(c => c.DogWalkerId == dogWalkerId && c.Status == WalkStatus.Requested && c.Deleted == false).ConfigureAwait(false);
|
|
return requested > 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gibt eine Liste von Walks zurück, welche gleich gestartet werden sollen
|
|
/// </summary>
|
|
/// <param name="appUserId">ID des AppUsers</param>
|
|
/// <param name="date">Datum für den Vergleich</param>
|
|
/// <returns>Liste von Walks die gestartet werden sollen</returns>
|
|
public async Task<List<Walk>> GetWalksToStartAsync(string appUserId, DateTimeOffset date)
|
|
{
|
|
var upperDate = date.AddHours(1);
|
|
var walks = await Repository.FindAsync(c => c.DogWalkerId == appUserId && c.Status == WalkStatus.Accepted && c.Start >= date && c.Start <= upperDate && c.Deleted == false).ConfigureAwait(false);
|
|
return walks.ToList();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gibt eine Liste von Walks zurück, welche beendet werden sollen
|
|
/// </summary>
|
|
/// <param name="appUserId">ID des AppUsers</param>
|
|
/// <param name="date">Datum für den Vergleich</param>
|
|
/// <returns>Liste von Walks die gestartet werden sollen</returns>
|
|
public async Task<List<Walk>> GetWalksToCompleteAsync(string appUserId, DateTimeOffset date)
|
|
{
|
|
var walks = await Repository.FindAsync(c => c.DogWalkerId == appUserId && (c.Status == WalkStatus.Accepted || c.Status == WalkStatus.Started) && c.End <= date && c.Deleted == false).ConfigureAwait(false);
|
|
return walks.ToList();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Aktualisieren des Zahlungsstatus eines Walks in der lokalen DB
|
|
/// </summary>
|
|
/// <param name="walkId">Id des Wals</param>
|
|
/// <param name="paymentStatus">Zu setzender Zahlungsstatus</param>
|
|
/// <param name="updatedAt">Datum Aktualisierung</param>
|
|
/// <returns>Walk oder null, wenn nicht gefunden</returns>
|
|
public async Task<Walk> SetPaymentStatusLocalAsync(string walkId, PaymentStatus paymentStatus, DateTimeOffset updatedAt)
|
|
{
|
|
var localWalk = await Repository.FirstOrDefaultAsync(c => c.Id == walkId, false);
|
|
if (localWalk != null)
|
|
{
|
|
localWalk.PaymentStatus = paymentStatus;
|
|
localWalk.UpdatedAt = updatedAt;
|
|
|
|
Repository.Update(localWalk);
|
|
await CommitAsync();
|
|
|
|
await _pullService.AddOrUpddateAsync(nameof(Walk), updatedAt).ConfigureAwait(false);
|
|
|
|
return localWalk;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bestätigen eines Walks. Löst die Bezahlung für einen Walker aus. Geht nur Online!
|
|
/// </summary>
|
|
/// <param name="appUserId">Id des Hundebesitzers</param>
|
|
/// <param name="walkId">Id des Walks</param>
|
|
/// <param name="accessToken">Aktuelles Accesstoken</param>
|
|
/// <param name="token">CancellationToken</param>
|
|
/// <returns>CommunicationResult mit aktualisierten Walk</returns>
|
|
public async Task<CommunicationResult<Walk>> ConfirmAsync(string appUserId, string walkId, string accessToken, CancellationToken token)
|
|
{
|
|
var result = new CommunicationResult<Walk>();
|
|
|
|
var hasConnection = await _communicationService.IsConnected();
|
|
if (hasConnection)
|
|
{
|
|
var model = new WalkConfirmDto()
|
|
{
|
|
AppUserId = appUserId,
|
|
WalkId = walkId
|
|
};
|
|
|
|
var serverResult = await _communicationService.ConfirmWalkAsync(model, accessToken, token);
|
|
if (serverResult.Success && serverResult.Value != null)
|
|
{
|
|
//jetzt auch lokal die Änderung speichern
|
|
var localWalk = await Repository.FirstOrDefaultAsync(c => c.Id == walkId, false);
|
|
if (localWalk != null)
|
|
{
|
|
localWalk.Status = serverResult.Value.Status;
|
|
localWalk.Confirmed = serverResult.Value.Confirmed;
|
|
localWalk.PaymentStatus = serverResult.Value.PaymentStatus;
|
|
localWalk.UpdatedAt = serverResult.Value.UpdatedAt;
|
|
Repository.Update(localWalk);
|
|
await CommitAsync();
|
|
|
|
await _pullService.AddOrUpddateAsync(nameof(Walk), localWalk.UpdatedAt);
|
|
}
|
|
}
|
|
|
|
return serverResult;
|
|
}
|
|
else
|
|
{
|
|
result.Success = false;
|
|
result.ErrorCode = CommunicationErrors.ServerNoConnection;
|
|
result.ErrorMessage = Errors.Server_NoConnection;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bestätigen eines Walks mit Rating. Löst die Bezahlung für einen Walker aus. Geht nur Online!
|
|
/// </summary>
|
|
/// <param name="appUserId">Id des Hundebesitzers</param>
|
|
/// <param name="walkId">Id des Walks</param>
|
|
/// <param name="ratingPoints">Punkte für das Rating</param>
|
|
/// <param name="ratingInfo">Anmerkungen zum Rating</param>
|
|
/// <param name="accessToken">Aktuelles Accesstoken</param>
|
|
/// <param name="token">CancellationToken</param>
|
|
/// <returns>CommunicationResult mit aktualisierten Walk</returns>
|
|
public async Task<CommunicationResult<Walk>> ConfirmWithRatingAsync(string appUserId, string walkId, decimal ratingPoints, string ratingInfo, string accessToken, CancellationToken token)
|
|
{
|
|
var result = new CommunicationResult<Walk>();
|
|
|
|
var hasConnection = await _communicationService.IsConnected();
|
|
if (hasConnection)
|
|
{
|
|
var model = new WalkConfirmWithRatingDto()
|
|
{
|
|
AppUserId = appUserId,
|
|
WalkId = walkId,
|
|
RatingPoints = ratingPoints,
|
|
RatingInfo = ratingInfo
|
|
};
|
|
|
|
var serverResult = await _communicationService.ConfirmWalkWithRatingAsync(model, accessToken, token);
|
|
if (serverResult.Success && serverResult.Value != null)
|
|
{
|
|
//jetzt auch lokal die Änderung speichern
|
|
var localWalk = await Repository.FirstOrDefaultAsync(c => c.Id == walkId, false);
|
|
if (localWalk != null)
|
|
{
|
|
localWalk.Status = serverResult.Value.Status;
|
|
localWalk.Confirmed = serverResult.Value.Confirmed;
|
|
localWalk.PaymentStatus = serverResult.Value.PaymentStatus;
|
|
localWalk.UpdatedAt = serverResult.Value.UpdatedAt;
|
|
Repository.Update(localWalk);
|
|
await CommitAsync();
|
|
|
|
await _pullService.AddOrUpddateAsync(nameof(Walk), localWalk.UpdatedAt);
|
|
}
|
|
}
|
|
|
|
return serverResult;
|
|
}
|
|
else
|
|
{
|
|
result.Success = false;
|
|
result.ErrorCode = CommunicationErrors.ServerNoConnection;
|
|
result.ErrorMessage = Errors.Server_NoConnection;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reklamieren eines Walks
|
|
/// </summary>
|
|
/// <param name="walkId">ID des Walks</param>
|
|
/// <param name="type">Typ der Reklamation</param>
|
|
/// <param name="complainReason">Grund der Reklamation als Text</param>
|
|
/// <param name="accessToken">Aktuelles Accesstoken</param>
|
|
/// <param name="token">CancellationToken</param>
|
|
/// <returns>true wenn erfolgreich, false sonst</returns>
|
|
public async Task<CommunicationResult<bool>> ComplainAsync(string walkId, WalkComplaintType type, string complainReason, string accessToken, CancellationToken token)
|
|
{
|
|
var result = new CommunicationResult<bool>();
|
|
|
|
var hasConnection = await _communicationService.IsConnected();
|
|
if (hasConnection)
|
|
{
|
|
var model = new WalkComplaintCreateDto()
|
|
{
|
|
WalkId = walkId,
|
|
Type = type.ToDto(),
|
|
Message = complainReason
|
|
};
|
|
|
|
var serverResult = await _communicationService.ComplainWalkAsync(model, accessToken, token);
|
|
if (serverResult.Success && serverResult.Value != null)
|
|
{
|
|
//jetzt auch lokal die Änderung speichern
|
|
var localWalk = await Repository.FirstOrDefaultAsync(c => c.Id == walkId, false);
|
|
if (localWalk != null)
|
|
{
|
|
localWalk.Status = serverResult.Value.Status;
|
|
localWalk.Complained = serverResult.Value.Complained;
|
|
localWalk.ComplainReason = serverResult.Value.ComplainReason;
|
|
localWalk.UpdatedAt = serverResult.Value.UpdatedAt;
|
|
Repository.Update(localWalk);
|
|
await CommitAsync();
|
|
|
|
await _pullService.AddOrUpddateAsync(nameof(Walk), localWalk.UpdatedAt);
|
|
|
|
result.Success = true;
|
|
result.Value = true;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
result.Success = false;
|
|
result.ErrorCode = CommunicationErrors.ServerNoConnection;
|
|
result.ErrorMessage = Errors.Server_NoConnection;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Holen einer Reklamation zu einem Walk
|
|
/// </summary>
|
|
/// <param name="walkId">ID des Walks</param>
|
|
/// <param name="accessToken">Aktuelles Accesstoken</param>
|
|
/// <param name="token">CancellationToken</param>
|
|
/// <returns>CommunicationResult</returns>
|
|
public async Task<CommunicationResult<WalkComplaint>> GetWalkComplaintAsync(string walkId, string accessToken, CancellationToken token)
|
|
{
|
|
var result = new CommunicationResult<WalkComplaint>();
|
|
result.Success = false;
|
|
|
|
var isConnected = await _communicationService.IsConnected();
|
|
if (isConnected)
|
|
{
|
|
var queryResult = await _communicationService.GetWalkComplaintAsync(walkId, accessToken, token);
|
|
if (queryResult.Success)
|
|
{
|
|
result.Success = true;
|
|
result.Value = queryResult.Value;
|
|
return result;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
result.Success = false;
|
|
result.ErrorCode = CommunicationErrors.ServerNoConnection;
|
|
result.ErrorMessage = Errors.Server_NoConnection;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
#region Pull-Push Implementation
|
|
|
|
/// <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<Walk>> PullAsync(string language, string accessToken, CancellationToken token)
|
|
{
|
|
var result = new SyncResult<Walk>();
|
|
|
|
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(Walk));
|
|
if (lastSyncInfo != null)
|
|
lastUpdate = lastSyncInfo.LastUpdate;
|
|
|
|
var requestResult = await _communicationService.GetWalksForSyncAsync(user.Id, lastUpdate, accessToken, token);
|
|
if (requestResult.Success)
|
|
{
|
|
result = await HandleChangesAsync(requestResult.Value);
|
|
if (result.LastUpdate != null)
|
|
await _pullService.AddOrUpddateAsync(nameof(Walk), result.LastUpdate.Value).ConfigureAwait(false);
|
|
}
|
|
|
|
result.LastUpdate ??= lastUpdate;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
/// <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<Walk>> PushAsync(string accessToken, CancellationToken token)
|
|
{
|
|
var result = new SyncResult<Walk>();
|
|
|
|
if (await _pushService.HasOpenAsync(nameof(Walk)) > 0)
|
|
{
|
|
var deltas = await _pushService.GetAllAsync(nameof(Walk));
|
|
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<Walk>(syncInfoPush.Value, new JsonSerializerOptions(JsonSerializerDefaults.Web));
|
|
|
|
if (syncInfoPush.Operation == SyncOperation.Create)
|
|
{
|
|
var createDto = request.ToDto();
|
|
var createResult = await _communicationService.CreateWalkAsync(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.UpdateWalkAsync(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.DeleteWalkAsync(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;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Private
|
|
|
|
/// <summary>
|
|
/// Behandeln der Liste von öffentlichern Anfragen wenn welche vom Online-Store geholt werden.
|
|
/// </summary>
|
|
/// <param name="walks">Liste der anfragen</param>
|
|
/// <returns>Task</returns>
|
|
private async Task<SyncResult<Walk>> HandleChangesAsync(List<Walk> walks)
|
|
{
|
|
var result = new SyncResult<Walk>();
|
|
|
|
//Je Rasse durchgehen ob was gemacht werden soll
|
|
foreach (var walk in walks)
|
|
{
|
|
var localWalk = await Repository.FirstOrDefaultAsync(c => c.Id == walk.Id, false);
|
|
if (localWalk != null && localWalk.UpdatedAt < walk.UpdatedAt)
|
|
{
|
|
if (localWalk.UpdatedAt >= walk.UpdatedAt)
|
|
{
|
|
if (result.LastUpdate == null || result.LastUpdate < localWalk.UpdatedAt)
|
|
result.LastUpdate = localWalk.UpdatedAt;
|
|
continue;
|
|
}
|
|
|
|
var deleted = localWalk.Deleted == false && walk.Deleted;
|
|
|
|
localWalk.Version = walk.Version;
|
|
localWalk.UpdatedAt = walk.UpdatedAt;
|
|
localWalk.Deleted = walk.Deleted;
|
|
|
|
localWalk.Type = walk.Type;
|
|
localWalk.ServiceType = walk.ServiceType;
|
|
localWalk.DogWalkerId = walk.DogWalkerId;
|
|
localWalk.DogOwnerId = walk.DogOwnerId;
|
|
localWalk.PublicWalkRequestId = walk.PublicWalkRequestId;
|
|
localWalk.DogsJson = walk.DogsJson;
|
|
localWalk.DogCount = walk.DogCount;
|
|
localWalk.Start = walk.Start;
|
|
localWalk.End = walk.End;
|
|
localWalk.PickupAddress = walk.PickupAddress;
|
|
localWalk.PickupAddressLat = walk.PickupAddressLat;
|
|
localWalk.PickupAddressLng = walk.PickupAddressLng;
|
|
localWalk.ReturnAddress = walk.ReturnAddress;
|
|
localWalk.ReturnAddressLat = walk.ReturnAddressLat;
|
|
localWalk.ReturnAddressLng = walk.ReturnAddressLng;
|
|
localWalk.Price = walk.Price;
|
|
localWalk.Info = walk.Info;
|
|
localWalk.Status = walk.Status;
|
|
localWalk.Started = walk.Started;
|
|
localWalk.Completed = walk.Completed;
|
|
localWalk.Confirmed = walk.Confirmed;
|
|
localWalk.Complained = walk.Complained;
|
|
localWalk.ComplainReason = walk.ComplainReason;
|
|
localWalk.DeclinedReason = walk.DeclinedReason;
|
|
localWalk.CancelledReason = walk.CancelledReason;
|
|
localWalk.CancelledBy = walk.CancelledBy;
|
|
localWalk.CompletedInfo = walk.CompletedInfo;
|
|
localWalk.Defactation = walk.Defactation;
|
|
localWalk.PaymentStatus = walk.PaymentStatus;
|
|
|
|
localWalk.Created = walk.Created;
|
|
|
|
if (result.LastUpdate == null || result.LastUpdate < localWalk.UpdatedAt)
|
|
result.LastUpdate = localWalk.UpdatedAt;
|
|
if (!deleted)
|
|
result.Updated.Add(localWalk);
|
|
else
|
|
result.Deleted.Add(localWalk);
|
|
Repository.Update(localWalk);
|
|
}
|
|
|
|
if (localWalk == null)
|
|
{
|
|
localWalk = new Walk()
|
|
{
|
|
Id = walk.Id,
|
|
Version = walk.Version,
|
|
UpdatedAt = walk.UpdatedAt,
|
|
Deleted = walk.Deleted,
|
|
|
|
Type = walk.Type,
|
|
ServiceType = walk.ServiceType,
|
|
DogWalkerId = walk.DogWalkerId,
|
|
DogOwnerId = walk.DogOwnerId,
|
|
PublicWalkRequestId = walk.PublicWalkRequestId,
|
|
DogsJson = walk.DogsJson,
|
|
DogCount = walk.DogCount,
|
|
Start = walk.Start,
|
|
End = walk.End,
|
|
PickupAddress = walk.PickupAddress,
|
|
PickupAddressLat = walk.PickupAddressLat,
|
|
PickupAddressLng = walk.PickupAddressLng,
|
|
ReturnAddress = walk.ReturnAddress,
|
|
ReturnAddressLat = walk.ReturnAddressLat,
|
|
ReturnAddressLng = walk.ReturnAddressLng,
|
|
Price = walk.Price,
|
|
Info = walk.Info,
|
|
Status = walk.Status,
|
|
Started = walk.Started,
|
|
Completed = walk.Completed,
|
|
Confirmed = walk.Confirmed,
|
|
Complained = walk.Complained,
|
|
ComplainReason = walk.ComplainReason,
|
|
DeclinedReason = walk.DeclinedReason,
|
|
CancelledReason = walk.CancelledReason,
|
|
CancelledBy = walk.CancelledBy,
|
|
CompletedInfo = walk.CompletedInfo,
|
|
Defactation = walk.Defactation,
|
|
PaymentStatus = walk.PaymentStatus,
|
|
|
|
Created = walk.Created
|
|
};
|
|
|
|
Repository.Add(localWalk);
|
|
|
|
if (result.LastUpdate == null || result.LastUpdate < localWalk.UpdatedAt)
|
|
result.LastUpdate = localWalk.UpdatedAt;
|
|
result.Added.Add(localWalk);
|
|
}
|
|
}
|
|
|
|
if (result.HasChanges)
|
|
{
|
|
try
|
|
{
|
|
await CommitAsync().ConfigureAwait(false);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
var err = ex.Message;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|