843 lines
39 KiB
C#

using gehGassiApp.Core.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using gehGassi.Dto;
using gehGassi.Dto.Common;
using gehGassiApp.Core.Data;
using gehGassiApp.Core.Helper;
using gehGassiApp.Domain.Users;
using gehGassiApp.Core.Interfaces.Synchronization;
using gehGassiApp.Core.Mapper;
using gehGassiApp.Domain.Common;
using gehGassiApp.Core.Services.Synchronization;
using gehGassiApp.Core.Resources;
using gehGassi.Dto.Reporting;
namespace gehGassiApp.Core.Services
{
/// <summary>
/// Service der die Verwaltung des Benutzers ermöglicht
/// </summary>
public class UserService : ServiceBase<User>, IUserService
{
private readonly ICommunicationService _communicationService;
private readonly ISyncInfoPushService _pushService;
private readonly ISyncInfoPullService _pullService;
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="pushService">Instanz eines ISyncInfoPushService</param>
/// <param name="pullService">Instanz eines ISyncInfoPullService</param>
public UserService(IUnitOfWork unitOfWork, ICommunicationService communicationService, ISyncInfoPushService pushService, ISyncInfoPullService pullService) : base(unitOfWork)
{
_communicationService = communicationService;
_pushService = pushService;
_pullService = pullService;
_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 User Get(object id, bool noTracking = true)
{
//Bewusst nicht implementiert
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<User> GetAsync(object id, bool noTracking = true)
{
//Bewusst nicht implementiert
await Task.Delay(1);
throw new NotImplementedException();
}
/// <summary>
/// Gibt den aktuellen Benutzer zurück
/// </summary>
/// <returns>Aktueller Benutzer oder null, wenn noch keiner vorhanden</returns>
public async Task<User> GetAsync()
{
var user = await Repository.FirstOrDefaultAsync(c => c.Id != "", false).ConfigureAwait(false);
return user;
}
/// <summary>
/// Hinzufügen oder aktualisieren des Benutzers
/// </summary>
/// <param name="user">Benutzer der hinzugefügt oder aktualisiert werden soll</param>
/// <returns></returns>
public async Task<User> CreateOrUpdateAsync(User user)
{
var foundUser = await GetAsync().ConfigureAwait(false);
if (foundUser == null)
{
Repository.Add(user);
await CommitAsync();
return user;
}
foundUser.FirstName = user.FirstName;
foundUser.LastName = user.LastName;
foundUser.Roles = user.Roles;
foundUser.Photo = user.Photo;
foundUser.RegistrationDate = user.RegistrationDate;
foundUser.LastLoginDate = user.LastLoginDate;
foundUser.AppUserId = user.AppUserId;
Repository.Update(foundUser);
await CommitAsync().ConfigureAwait(false);
return foundUser;
}
/// <summary>
/// Prüft für einen übergebenen Benutzernamen ob es sich um den gespeicherten Benutzer handelt
/// </summary>
/// <param name="userName">Benutzername (E-Mail Adresse)</param>
/// <returns>UserCheckResult</returns>
public async Task<UserCheckResult> CheckAsync(string userName)
{
var user = await Repository.FirstOrDefaultAsync(c => c.Id != "", true).ConfigureAwait(false);
if (user != null)
{
return string.Equals(user.UserName, userName, StringComparison.CurrentCultureIgnoreCase) ? UserCheckResult.IsCurrentUser : UserCheckResult.IsOtherUser;
}
return UserCheckResult.Empty;
}
/// <summary>
/// Gibt den aktuellen App-User zurück.
/// </summary>
/// <returns>AppUser oder null wenn nicht gefunden</returns>
public async Task<AppUser> GetAppUserAsync()
{
var appUser = await _appUserRepository.FirstOrDefaultAsync(c => c.Id != "").ConfigureAwait(false);
return appUser;
}
/// <summary>
/// Gibt den aktuellen App-User zurück.
/// </summary>
/// <param name="noTracking">Tracking</param>
/// <returns>AppUser oder null wenn nicht gefunden</returns>
public async Task<AppUser> GetAppUserAsync(bool noTracking)
{
var appUser = await _appUserRepository.FirstOrDefaultAsync(c => c.Id != "", noTracking).ConfigureAwait(false);
return appUser;
}
/// <summary>
/// Gibt den aktuellen App-User zurück
/// Versucht auch online - wenn lokal nicht vorhanden
/// </summary>
/// <param name="accessToken">Aktuelles Accesstoken</param>
/// <param name="token">CancellationToken</param>
/// <param name="forceOnline">Wenn true, wird in jedem Fall die Online-Abfrage verwendet</param>
/// <returns>AppUser oder null wenn nicht gefunden</returns>
public async Task<AppUser> GetAppUserAsync(string accessToken, CancellationToken token, bool forceOnline)
{
//Zuerst DB
if (forceOnline)
{
var isConnected = await _communicationService.IsConnected();
if (isConnected)
{
var appUserResult = await _communicationService.GetAppUserAsync(accessToken, token);
if (appUserResult.Success)
{
var appUserUpdated = await CreateOrUpdateAppUserAsync(appUserResult.Value);
await _pullService.AddOrUpddateAsync(nameof(AppUser), DateTimeOffset.UtcNow);
return appUserUpdated;
}
}
}
var appUser = await _appUserRepository.FirstOrDefaultAsync(c => c.Id != "").ConfigureAwait(false);
if (appUser != null)
return appUser;
return null;
}
/// <summary>
/// Hinzufügen oder aktualisieren eines App-Users
/// </summary>
/// <param name="appUser">App-User</param>
/// <returns>AppUser</returns>
public async Task<AppUser> CreateOrUpdateAppUserAsync(AppUser appUser)
{
var foundUser = await _appUserRepository.FirstOrDefaultAsync(c => c.Id != "", false).ConfigureAwait(false);
if (foundUser == null)
{
_appUserRepository.Add(appUser);
await CommitAsync();
return appUser;
}
if (appUser.UpdatedAt > foundUser.UpdatedAt)
{
foundUser.Type = appUser.Type;
foundUser.Title = appUser.Title;
foundUser.FirstName = appUser.FirstName;
foundUser.LastName = appUser.LastName;
foundUser.Sex = appUser.Sex;
foundUser.BirthDate = appUser.BirthDate;
foundUser.Photo = appUser.Photo;
foundUser.Contact = appUser.Contact;
foundUser.Address = appUser.Address;
foundUser.Lat = appUser.Lat;
foundUser.Lng = appUser.Lng;
foundUser.SocialMedia = appUser.SocialMedia;
foundUser.Locked = appUser.Locked;
foundUser.LockedUntil = appUser.LockedUntil;
foundUser.UpdatedAt = appUser.UpdatedAt;
foundUser.Deleted = appUser.Deleted;
foundUser.TermsAccepted = appUser.TermsAccepted;
foundUser.TermsAcceptedDate = appUser.TermsAcceptedDate;
foundUser.PrivacyAccepted = appUser.PrivacyAccepted;
foundUser.PrivacyAcceptedDate = appUser.PrivacyAcceptedDate;
foundUser.PaymentTermsAccepted = appUser.PaymentTermsAccepted;
foundUser.PaymentTermsAcceptedDate = appUser.PaymentTermsAcceptedDate;
foundUser.NationalityCode = appUser.NationalityCode ?? string.Empty;
foundUser.MainResidenceCode = appUser.MainResidenceCode ?? string.Empty;
foundUser.PaymentId = appUser.PaymentId;
foundUser.KycPassed = appUser.KycPassed;
foundUser.KycPassedDate = appUser.KycPassedDate;
foundUser.Verified = appUser.Verified;
foundUser.VerifiedDate = appUser.VerifiedDate;
foundUser.AutoPayout = appUser.AutoPayout;
_appUserRepository.Update(foundUser);
var changes = await CommitAsync().ConfigureAwait(false);
}
return await GetAppUserAsync();
}
/// <summary>
/// Aktualisieren eines App-Users.
/// Online wird versucht. Wenn nicht möglich wird ein Delta erstellt.
/// </summary>
/// <param name="appUser">App-User</param>
/// <param name="accessToken">Aktuelles Accesstoken</param>
/// <param name="token">CancellationToken</param>
/// <returns>App-User</returns>
public async Task<AppUser> UpdateAppUserAsync(AppUser appUser, string accessToken, CancellationToken token)
{
//Zuerst in der DB aktualisieren
var foundUser = await _appUserRepository.FirstOrDefaultAsync(c => c.Id == appUser.Id, false);
foundUser.FirstName = appUser.FirstName;
foundUser.LastName = appUser.LastName;
foundUser.Sex = appUser.Sex;
foundUser.BirthDate = appUser.BirthDate;
foundUser.Photo = appUser.Photo;
foundUser.Contact.Mobile = appUser.Contact.Mobile;
foundUser.Contact.Phone = appUser.Contact.Phone;
foundUser.Address.AddressLine1 = appUser.Address.AddressLine1;
foundUser.Address.AddressLine2 = appUser.Address.AddressLine2;
foundUser.Address.Zip = appUser.Address.Zip;
foundUser.Address.City = appUser.Address.City;
foundUser.Address.State = appUser.Address.State;
foundUser.Address.CountryCode = appUser.Address.CountryCode;
foundUser.NationalityCode = appUser.NationalityCode ?? string.Empty;
foundUser.MainResidenceCode = appUser.MainResidenceCode ?? string.Empty;
foundUser.AutoPayout = appUser.AutoPayout;
foundUser.UpdatedAt = DateTimeOffset.UtcNow;
if (appUser.Lat != 0 && appUser.Lng != 0)
{
foundUser.Lat = appUser.Lat;
foundUser.Lng = appUser.Lng;
}
_appUserRepository.Update(foundUser);
await CommitAsync().ConfigureAwait(false);
var appUserDto = foundUser.ToDto();
var photoFileName = string.Empty;
byte[] photo = null;
if (!string.IsNullOrWhiteSpace(foundUser.Photo))
{
if (!foundUser.Photo.StartsWithHttp())
{
//Datei laden und in byte array umwandeln
if (File.Exists(foundUser.Photo))
{
await using var stream = File.OpenRead(foundUser.Photo);
using var memoryStream = new MemoryStream();
await stream.CopyToAsync(memoryStream, token);
photo = memoryStream.ToArray();
photoFileName = Path.GetFileName(appUserDto.Photo);
}
}
}
var isConnected = await _communicationService.IsConnected();
if (isConnected)
{
var updateResult = await _communicationService.UpdateAppUserAsync(appUserDto,photoFileName,photo,accessToken, token);
if (updateResult.Success)
{
//Alles gut nichts weglegen
//Für den Pull-Service das Update-Datum setzen
await _pullService.AddOrUpddateAsync(nameof(AppUser), foundUser.UpdatedAt).ConfigureAwait(false);
}
else
{
//Weglegen und später versuchen
await _pushService.AddAsync(nameof(AppUser), foundUser.Id, SyncOperation.Edit, foundUser).ConfigureAwait(false);
}
}
else
{
//Weglegen und später versuchen
await _pushService.AddAsync(nameof(AppUser), foundUser.Id, SyncOperation.Edit, foundUser).ConfigureAwait(false);
}
return foundUser;
}
/// <summary>
/// Setzen des App-User Types für einen AppUser.
/// Immer online und nur wenn erfolgreich auch ein Update lokal!
/// </summary>
/// <param name="appUserId">Id des AppUsers</param>
/// <param name="appUserType">Typ der gesetzt werden soll</param>
/// <param name="accessToken">Aktuelles Accesstoken</param>
/// <param name="token">CancellationToken</param>
/// <returns>CommunicationResult</returns>
public async Task<CommunicationResult<bool>> SetAppUserTypeAsync(string appUserId, AppUserType appUserType, string accessToken, CancellationToken token)
{
var result = new CommunicationResult<bool>();
var hasConnection = await _communicationService.IsConnected();
if (hasConnection)
{
var model = new SetAppUserTypeDto()
{
Id = appUserId,
Type = (AppUserTypeDto)appUserType,
UpdatedAt = DateTimeOffset.UtcNow
};
var serverResult = await _communicationService.SetAppUserTypeAsync(model, accessToken, token);
if (serverResult.Success && serverResult.Value)
{
//jetzt auch lokal die Änderung speichern
var appUser = await GetAppUserAsync(false);
appUser.Type = appUserType;
appUser.UpdatedAt = model.UpdatedAt;
_appUserRepository.Update(appUser);
await CommitAsync().ConfigureAwait(false);
await _pullService.AddOrUpddateAsync(nameof(AppUser), model.UpdatedAt);
}
return serverResult;
}
else
{
result.Success = false;
result.ErrorCode = CommunicationErrors.ServerNoConnection;
result.ErrorMessage = Errors.Server_NoConnection;
}
return result;
}
/// <summary>
/// Setzen des App-User Types für einen AppUser.
/// Immer online und nur wenn erfolgreich auch ein Update lokal!
/// </summary>
/// <param name="appUserId">Id des AppUsers</param>
/// <param name="appUserType">Typ der gesetzt werden soll</param>
/// <param name="nationality">Nationalität</param>
/// <param name="mainResidence">Land des Hauptwohnsitzes</param>
/// <param name="paymentTermsAccepted">AGB Paymentprovider akzeptiert</param>
/// <param name="accessToken">Aktuelles Accesstoken</param>
/// <param name="token">CancellationToken</param>
/// <returns>CommunicationResult</returns>
public async Task<CommunicationResult<bool>> SetAppUserTypeAsync(string appUserId, AppUserType appUserType, string nationality, string mainResidence, bool paymentTermsAccepted, string accessToken, CancellationToken token)
{
var result = new CommunicationResult<bool>();
var hasConnection = await _communicationService.IsConnected();
if (hasConnection)
{
var model = new SetAppUserTypeExDto()
{
Id = appUserId,
Type = (AppUserTypeDto)appUserType,
NationalityCode = nationality,
MainResidenceCode = mainResidence,
PaymentTermsAccepted = paymentTermsAccepted,
PaymentTermsAcceptedDate = DateTimeOffset.UtcNow,
UpdatedAt = DateTimeOffset.UtcNow
};
var serverResult = await _communicationService.SetAppUserTypeAsync(model, accessToken, token);
if (serverResult.Success && serverResult.Value != null)
{
//jetzt auch lokal die Änderung speichern
var appUser = await GetAppUserAsync(false);
appUser.Type = appUserType;
appUser.NationalityCode = serverResult.Value.NationalityCode;
appUser.MainResidenceCode = serverResult.Value.MainResidenceCode;
appUser.PaymentTermsAccepted = serverResult.Value.PaymentTermsAccepted;
appUser.PaymentTermsAcceptedDate = serverResult.Value.PaymentTermsAcceptedDate;
appUser.PaymentId = serverResult.Value.PaymentId;
appUser.UpdatedAt = model.UpdatedAt;
_appUserRepository.Update(appUser);
await CommitAsync().ConfigureAwait(false);
await _pullService.AddOrUpddateAsync(nameof(AppUser), model.UpdatedAt);
result.Success = true;
result.Value = true;
}
}
else
{
result.Success = false;
result.ErrorCode = CommunicationErrors.ServerNoConnection;
result.ErrorMessage = Errors.Server_NoConnection;
}
return result;
}
/// <summary>
/// Hinzufügen eines Payment-Users. Für Hundebesitzer wenn sie noch keine PaymentId haben
/// </summary>
/// <param name="appUserId">Id des AppUsers</param>
/// <param name="nationality">Nationalität</param>
/// <param name="mainResidence">Land des Hauptwohnsitzes</param>
/// <param name="paymentTermsAccepted">AGB Paymentprovider akzeptiert</param>
/// <param name="accessToken">Aktuelles Accesstoken</param>
/// <param name="token">CancellationToken</param>
/// <returns>CommunicationResult</returns>
public async Task<CommunicationResult<bool>> AddPaymentUserAsync(string appUserId, string nationality, string mainResidence, bool paymentTermsAccepted, string accessToken, CancellationToken token)
{
var result = new CommunicationResult<bool>();
var hasConnection = await _communicationService.IsConnected();
if (hasConnection)
{
var model = new AddPaymentUserDto()
{
Id = appUserId,
NationalityCode = nationality,
MainResidenceCode = mainResidence,
PaymentTermsAccepted = paymentTermsAccepted,
PaymentTermsAcceptedDate = DateTimeOffset.UtcNow
};
var serverResult = await _communicationService.AddPaymentUserAsync(model, accessToken, token);
if (serverResult.Success && serverResult.Value != null)
{
//jetzt auch lokal die Änderung speichern
var appUser = await GetAppUserAsync(false);
appUser.NationalityCode = serverResult.Value.NationalityCode;
appUser.MainResidenceCode = serverResult.Value.MainResidenceCode;
appUser.PaymentTermsAccepted = serverResult.Value.PaymentTermsAccepted;
appUser.PaymentTermsAcceptedDate = serverResult.Value.PaymentTermsAcceptedDate;
appUser.PaymentId = serverResult.Value.PaymentId;
appUser.UpdatedAt = serverResult.Value.UpdatedAt;
_appUserRepository.Update(appUser);
await CommitAsync().ConfigureAwait(false);
await _pullService.AddOrUpddateAsync(nameof(AppUser), appUser.UpdatedAt);
result.Success = true;
result.Value = true;
}
}
else
{
result.Success = false;
result.ErrorCode = CommunicationErrors.ServerNoConnection;
result.ErrorMessage = Errors.Server_NoConnection;
}
return result;
}
/// <summary>
/// Setzen der Bankverbindungs-ID für einen AppUser.
/// </summary>
/// <param name="appUserId">Id des App-Users</param>
/// <param name="bankId">ID der Bankverbindung</param>
/// <param name="updatedAt">Datum letzte Aktualisierung</param>
/// <returns>App-User</returns>
public async Task<AppUser> SetBankAccountAsync(string appUserId, string bankId, DateTimeOffset updatedAt)
{
var appUser = await GetAppUserAsync(false);
appUser.BankId = bankId;
appUser.UpdatedAt = updatedAt;
_appUserRepository.Update(appUser);
await CommitAsync().ConfigureAwait(false);
await _pullService.AddOrUpddateAsync(nameof(AppUser), appUser.UpdatedAt);
return appUser;
}
/// <summary>
/// Blockieren eines App-Users am Server
/// </summary>
/// <param name="appUserId">Id des App-Users der die Blockierung vornimmt</param>
/// <param name="blockedAppUserId">Id des App-Users der blockiert wird</param>
/// <param name="accessToken">Aktuelles Accesstoken</param>
/// <param name="token">CancellationToken</param>
/// <returns>CommunicationResult</returns>
public async Task<CommunicationResult<bool>> BlockAppUserAsync(string appUserId, string blockedAppUserId, string accessToken, CancellationToken token)
{
var result = new CommunicationResult<bool>();
var hasConnection = await _communicationService.IsConnected();
if (hasConnection)
{
var model = new BlockCreateDto()
{
BlockingAppUserId = appUserId,
BlockedAppUserId = blockedAppUserId
};
var serverResult = await _communicationService.BlockAppUserAsync(model, accessToken, token);
return serverResult;
}
else
{
result.Success = false;
result.ErrorCode = CommunicationErrors.ServerNoConnection;
result.ErrorMessage = Errors.Server_NoConnection;
}
return result;
}
/// <summary>
/// Aufheben der Blockierung eines App-Users am Server
/// </summary>
/// <param name="appUserId">Id des App-Users der die Blockierung vorgenommen hat</param>
/// <param name="blockedAppUserId">Id des App-Users dessen Blockierung aufgehoben wird</param>
/// <param name="accessToken">Aktuelles Accesstoken</param>
/// <param name="token">CancellationToken</param>
/// <returns>CommunicationResult</returns>
public async Task<CommunicationResult<bool>> UnblockAppUserAsync(string appUserId, string blockedAppUserId, string accessToken, CancellationToken token)
{
var result = new CommunicationResult<bool>();
var hasConnection = await _communicationService.IsConnected();
if (hasConnection)
{
var model = new BlockRemoveDto()
{
BlockingAppUserId = appUserId,
BlockedAppUserId = blockedAppUserId
};
var serverResult = await _communicationService.UnblockAppUserAsync(model, accessToken, token);
return serverResult;
}
else
{
result.Success = false;
result.ErrorCode = CommunicationErrors.ServerNoConnection;
result.ErrorMessage = Errors.Server_NoConnection;
}
return result;
}
/// <summary>
/// Holen von blockierten App-Usern
/// </summary>
/// <param name="query">Abfrageobjekt</param>
/// <param name="location">Aktuelle Position</param>
/// <param name="accessToken">Aktuelles Accesstoken</param>
/// <param name="token">CancellationToken</param>
/// <returns>ListCommunicationResult</returns>
public async Task<ListCommunicationResult<List<AppUserBlockWithNames>>> GetBlockedAppUsersAsync(BlockedQueryDto query, LocationDto location, string accessToken, CancellationToken token)
{
var result = new ListCommunicationResult<List<AppUserBlockWithNames>>() { Value = new List<AppUserBlockWithNames>() };
var isConnected = await _communicationService.IsConnected();
if (isConnected)
{
query.Location = location;
var queryResult = await _communicationService.GetBlockedAppUsersAsync(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>
/// Melden eines App-Users durch einen anderen bei Verfehlungen oder anstößigen Inhalten
/// </summary>
/// <param name="appUserId">Id des App-Users der die Meldung vornimmt</param>
/// <param name="reportedAppUserId">Id des App-Users der gemeldet wird</param>
/// <param name="section">Betroffener Bereich</param>
/// <param name="sectionId">Id des Bereichs</param>
/// <param name="sectionId2">Optional: zweite Id falls nötig</param>
/// <param name="reportedImage">Bild beanstanded</param>
/// <param name="reportedName">Name beanstanded</param>
/// <param name="reportedText">Text beanstanded</param>
/// <param name="reportedMessage">Nachricht beanstanded</param>
/// <param name="reportedAddress">Adresse beanstanded</param>
/// <param name="type">Typ der Meldung</param>
/// <param name="email">Email-Adresse des meldenen Benutzers für Kontaktaufnahme</param>
/// <param name="comment">Anmerkungen des meldenden Benutzers</param>
/// <param name="message">Chat-Nachricht wenn es eine betrifft</param>
/// <param name="blockType">Art der bBlockierung</param>
/// <param name="contactAllowed">Darf für Rückfragen kontaktiert werden</param>
/// <param name="accessToken">Aktuelles Accesstoken</param>
/// <param name="token">CancellationToken</param>
/// <returns>ListCommunicationResult</returns>
public async Task<CommunicationResult<bool>> ReportAppUserAsync(string appUserId, string reportedAppUserId, AppUserReportSection section, string sectionId, string sectionId2,
bool reportedImage, bool reportedName, bool reportedText, bool reportedMessage, bool reportedAddress, AppUserReportType type, string email, string comment, string message, AppUserReportBlockType blockType, bool contactAllowed,
string accessToken, CancellationToken token)
{
var result = new CommunicationResult<bool>();
var hasConnection = await _communicationService.IsConnected();
if (hasConnection)
{
var model = new AppUserReportDto()
{
ReportingAppUserId = appUserId,
ReportedAppUserId = reportedAppUserId,
Section = section.ToDto(),
SectionId = sectionId,
SectionId2 = sectionId2,
ReportedImage = reportedImage,
ReportedName = reportedName,
ReportedText = reportedText,
ReportedMessage = reportedMessage,
ReportedAddress = reportedAddress,
Type = type.ToDto(),
Email = email,
Comment = comment,
Message = message,
BlockType = blockType.ToDto(),
ContactAllowed = contactAllowed
};
var serverResult = await _communicationService.ReportAppUserAsync(model, accessToken, token);
return serverResult;
}
else
{
result.Success = false;
result.ErrorCode = CommunicationErrors.ServerNoConnection;
result.ErrorMessage = Errors.Server_NoConnection;
}
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<AppUser>> PushAsync(string accessToken, CancellationToken token)
{
var result = new SyncResult<AppUser>();
if (await _pushService.HasOpenAsync(nameof(AppUser)) > 0)
{
var deltas = await _pushService.GetAllAsync(nameof(AppUser)).ConfigureAwait(false);
if (deltas.Any())
{
var isConnected = await _communicationService.IsConnected();
if (!isConnected) return result;
deltas = deltas.OrderBy(c => c.DateTime).ToList();
foreach (var syncInfoPush in deltas)
{
//Es gibt hier ur Update... daher alles andere ignorieren
if (syncInfoPush.Operation != SyncOperation.Edit)
{
await _pushService.RemoveAsync(syncInfoPush.Id).ConfigureAwait(false);
continue;
}
try
{
if (!string.IsNullOrWhiteSpace(syncInfoPush.Value))
{
var appUser = JsonSerializer.Deserialize<AppUser>(syncInfoPush.Value, new JsonSerializerOptions(JsonSerializerDefaults.Web));
//Jetzt Update senden...
var appUserDto = appUser.ToDto();
var photoFileName = string.Empty;
byte[] photo = null;
if (!string.IsNullOrWhiteSpace(appUser.Photo))
{
if (!appUser.Photo.StartsWithHttp())
{
//Datei laden und in byte array umwandeln
if (File.Exists(appUser.Photo))
{
await using var stream = File.OpenRead(appUser.Photo);
using var memoryStream = new MemoryStream();
await stream.CopyToAsync(memoryStream, token);
photo = memoryStream.ToArray();
photoFileName = Path.GetFileName(appUserDto.Photo);
}
}
}
var updateResult = await _communicationService.UpdateAppUserAsync(appUserDto, photoFileName, photo, accessToken, token);
if (updateResult.Success)
{
//Aktualisierung durchgeführt.
await _pullService.AddOrUpddateAsync(nameof(AppUser), appUser.UpdatedAt).ConfigureAwait(false);
await _pushService.RemoveAsync(syncInfoPush.Id).ConfigureAwait(false);
}
else
{
//TODO: Prüfen!!!!
//Derzeiut egal welcher Fehler vorliegt, weg damit
//Aktualisierung durchgeführt.
await _pullService.AddOrUpddateAsync(nameof(AppUser), appUser.UpdatedAt).ConfigureAwait(false);
await _pushService.RemoveAsync(syncInfoPush.Id).ConfigureAwait(false);
}
//Else ist nichts tun, konnte nicht übertragen werden.
}
else
{
await _pushService.RemoveAsync(syncInfoPush.Id).ConfigureAwait(false);
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
await _pushService.RemoveAsync(syncInfoPush.Id).ConfigureAwait(false);
}
}
}
}
//Es gibt hier kein Push!
await Task.Delay(1);
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<AppUser>> PullAsync(string language, string accessToken, CancellationToken token)
{
var result = new SyncResult<AppUser>();
//Zuerst immer online...
var isConnected = await _communicationService.IsConnected();
if (isConnected)
{
//Zuerst lezte Aktivität holen...
DateTimeOffset? lastUpdate = null;
var lastSyncInfo = await _pullService.GetAsync(nameof(AppUser)).ConfigureAwait(false);
if (lastSyncInfo != null)
lastUpdate = lastSyncInfo.LastUpdate;
var ctsQuery = new CancellationTokenSource(Common.Constants.PushPullTimeout);
var appUserResult = await _communicationService.GetAppUserSyncAsync(lastUpdate, accessToken, token);
if (appUserResult.Success)
{
if (appUserResult.Value != null)
{
var appUser = await _appUserRepository.GetAsync(appUserResult.Value.Id).ConfigureAwait(false);
if (appUser != null)
{
appUser.FirstName = appUserResult.Value.FirstName;
appUser.LastName = appUserResult.Value.LastName;
appUser.Sex = appUserResult.Value.Sex;
appUser.BirthDate = appUserResult.Value.BirthDate;
appUser.Photo = appUserResult.Value.Photo;
appUser.Contact.Mobile = appUserResult.Value.Contact.Mobile;
appUser.Contact.Phone = appUserResult.Value.Contact.Phone;
appUser.Address.AddressLine1 = appUserResult.Value.Address.AddressLine1;
appUser.Address.AddressLine2 = appUserResult.Value.Address.AddressLine2;
appUser.Address.Zip = appUserResult.Value.Address.Zip;
appUser.Address.City = appUserResult.Value.Address.City;
appUser.Address.State = appUserResult.Value.Address.State;
appUser.Address.CountryCode = appUserResult.Value.Address.CountryCode;
appUser.Lat = appUserResult.Value.Lat;
appUser.Lng = appUserResult.Value.Lng;
appUser.Type = appUserResult.Value.Type;
appUser.TermsAccepted = appUserResult.Value.TermsAccepted;
appUser.TermsAcceptedDate = appUserResult.Value.TermsAcceptedDate;
appUser.PrivacyAccepted = appUserResult.Value.PrivacyAccepted;
appUser.PrivacyAcceptedDate = appUserResult.Value.PrivacyAcceptedDate;
appUser.PaymentTermsAccepted = appUserResult.Value.PaymentTermsAccepted;
appUser.PaymentTermsAcceptedDate = appUserResult.Value.PaymentTermsAcceptedDate;
appUser.NationalityCode = appUserResult.Value.NationalityCode;
appUser.MainResidenceCode = appUserResult.Value.MainResidenceCode;
appUser.PaymentId = appUserResult.Value.PaymentId;
appUser.KycPassed = appUserResult.Value.KycPassed;
appUser.KycPassedDate = appUserResult.Value.KycPassedDate;
appUser.BankId = appUserResult.Value.BankId;
appUser.Verified = appUserResult.Value.Verified;
appUser.VerifiedDate = appUserResult.Value.VerifiedDate;
appUser.AutoPayout = appUserResult.Value.AutoPayout;
appUser.UpdatedAt = DateTimeOffset.UtcNow;
_appUserRepository.Update(appUser);
await CommitAsync().ConfigureAwait(false);
result.Updated.Add(appUser);
result.LastUpdate = appUserResult.Value.UpdatedAt;
await _pullService.AddOrUpddateAsync(nameof(AppUser), appUserResult.Value.UpdatedAt).ConfigureAwait(false);
}
}
}
result.LastUpdate ??= lastUpdate;
}
return result;
}
}
}