203 lines
8.6 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using gehGassiApp.Core.Data;
using gehGassiApp.Core.Interfaces;
using gehGassiApp.Core.Interfaces.Synchronization;
using gehGassiApp.Domain.Common;
using gehGassiApp.Domain.Payment;
namespace gehGassiApp.Core.Services
{
/// <summary>
/// Service der die Verwaltung von Transaktionsgebühren realisiert
/// </summary>
public class TransactionFeeService : ServiceBase<TransactionFee>, ITransactionFeeService
{
private readonly ICommunicationService _communicationService;
private readonly ISyncInfoPullService _syncInfoPullService;
/// <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>
public TransactionFeeService(IUnitOfWork unitOfWork, ICommunicationService communicationService, ISyncInfoPullService syncInfoPullService) : base(unitOfWork)
{
_communicationService = communicationService;
_syncInfoPullService = syncInfoPullService;
}
/// <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 TransactionFee Get(object id, bool noTracking = true)
{
return Repository.SingleOrDefault(c => c.Id == id.ToString(), noTracking);
}
/// <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<TransactionFee> GetAsync(object id, bool noTracking = true)
{
return await Repository.SingleOrDefaultAsync(c => c.Id == id.ToString(), noTracking).ConfigureAwait(false);
}
/// <summary>
/// Gibt eine Transaktionsgebühr für einen bestimmten Zahlungstyp zurück
/// </summary>
/// <param name="payinType">Zahlungstyp</param>
/// <returns>Transaktionsgebühr oder null, wenn nicht gefunden</returns>
public async Task<TransactionFee> GetAsync(PayInType payinType)
{
return await Repository.FirstOrDefaultAsync(c => c.PayInType == payinType && c.Deleted == false).ConfigureAwait(false);
}
#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<TransactionFee>> PushAsync(string accessToken, CancellationToken token)
{
var result = new SyncResult<TransactionFee>();
//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<TransactionFee>> PullAsync(string language, string accessToken, CancellationToken token)
{
var result = new SyncResult<TransactionFee>();
var isConnected = await _communicationService.IsConnected();
if (isConnected)
{
//Zuerst lezte Aktivität holen...
DateTimeOffset? lastUpdate = null;
var lastSyncInfo = await _syncInfoPullService.GetAsync(nameof(TransactionFee));
if (lastSyncInfo != null)
lastUpdate = lastSyncInfo.LastUpdate;
var ctsQuery = new CancellationTokenSource(Common.Constants.PushPullTimeout);
var transactionFeesResult = await _communicationService.GetTransactionFeesAsync(lastUpdate, accessToken, token);
if (transactionFeesResult.Success)
{
result = await HandleChangesAsync(transactionFeesResult.Value);
if (result.LastUpdate != null)
await _syncInfoPullService.AddOrUpddateAsync(nameof(TransactionFee), result.LastUpdate.Value).ConfigureAwait(false);
}
result.LastUpdate ??= lastUpdate;
}
return result;
}
#endregion
#region Private
/// <summary>
/// Behandeln der Liste von Transaktionsgebühren wenn welche vom Online-Store geholt werden.
/// </summary>
/// <param name="transactionFees">Liste der Transaktionsgebühren</param>
/// <returns>Task</returns>
private async Task<SyncResult<TransactionFee>> HandleChangesAsync(List<TransactionFee> transactionFees)
{
var result = new SyncResult<TransactionFee>();
//Je Rasse durchgehen ob was gemacht werden soll
foreach (var transactionFee in transactionFees)
{
var localTransactionFee = await Repository.FirstOrDefaultAsync(c => c.Id == transactionFee.Id, false);
if (localTransactionFee != null && localTransactionFee.UpdatedAt < transactionFee.UpdatedAt)
{
if (localTransactionFee.UpdatedAt >= transactionFee.UpdatedAt)
{
if (result.LastUpdate == null || result.LastUpdate < localTransactionFee.UpdatedAt)
result.LastUpdate = localTransactionFee.UpdatedAt;
continue;
}
var deleted = localTransactionFee.Deleted == false && transactionFee.Deleted;
localTransactionFee.Version = transactionFee.Version;
localTransactionFee.UpdatedAt = transactionFee.UpdatedAt;
localTransactionFee.Deleted = transactionFee.Deleted;
localTransactionFee.PayInType = transactionFee.PayInType;
localTransactionFee.Percent = transactionFee.Percent;
localTransactionFee.Fixed = transactionFee.Fixed;
if (result.LastUpdate == null || result.LastUpdate < localTransactionFee.UpdatedAt)
result.LastUpdate = localTransactionFee.UpdatedAt;
if (!deleted)
result.Updated.Add(localTransactionFee);
else
result.Deleted.Add(localTransactionFee);
Repository.Update(localTransactionFee);
}
if (localTransactionFee == null)
{
localTransactionFee = new TransactionFee()
{
Id = transactionFee.Id,
Version = transactionFee.Version,
UpdatedAt = transactionFee.UpdatedAt,
Deleted = transactionFee.Deleted,
PayInType = transactionFee.PayInType,
Percent = transactionFee.Percent,
Fixed = transactionFee.Fixed
};
Repository.Add(localTransactionFee);
if (result.LastUpdate == null || result.LastUpdate < localTransactionFee.UpdatedAt)
result.LastUpdate = localTransactionFee.UpdatedAt;
result.Added.Add(localTransactionFee);
}
}
if (result.HasChanges)
{
try
{
await CommitAsync().ConfigureAwait(false);
}
catch (Exception ex)
{
var err = ex.Message;
}
}
return result;
}
#endregion
}
}