249 lines
13 KiB
C#
249 lines
13 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using gehGassi.Common.Data;
|
|
using gehGassi.Core.Interfaces;
|
|
using gehGassi.Domain.Advertisements;
|
|
using gehGassi.Domain.Common;
|
|
using gehGassi.Domain.News;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using NetTopologySuite;
|
|
using NetTopologySuite.Geometries;
|
|
|
|
namespace gehGassi.Core.Services
|
|
{
|
|
/// <summary>
|
|
/// Service der die Verwaltung von News realisiert
|
|
/// </summary>
|
|
public class NewsService : ServiceBase<News>, INewsService
|
|
{
|
|
private readonly IRepository<NewsWithNames> _namesRepository;
|
|
|
|
/// <summary>
|
|
/// Erstellt eine Instanz
|
|
/// </summary>
|
|
/// <param name="unitOfWork">Instanz eines IUnitOfWork</param>
|
|
public NewsService(IUnitOfWork unitOfWork) : base(unitOfWork)
|
|
{
|
|
_namesRepository = unitOfWork.GetRepository<NewsWithNames>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gibt eine gefilterte Liste von News zurück
|
|
/// </summary>
|
|
/// <param name="filter">Filterbegriff der in bestimmten Feldern gesucht wird</param>
|
|
/// <returns>List betroffener News</returns>
|
|
public IQueryable<News> Filter(string filter)
|
|
{
|
|
return Repository.Query(c => c.Headline.Contains(filter));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Erstellen einer News
|
|
/// </summary>
|
|
/// <returns>News</returns>
|
|
public News Create()
|
|
{
|
|
var item = new News()
|
|
{
|
|
Status = NewsStatus.Draft,
|
|
Visibility = NewsVisibility.None,
|
|
GeoMode = GeoMode.None,
|
|
Created = DateTimeOffset.UtcNow,
|
|
Location = new Point(0,0){SRID = 4326}
|
|
};
|
|
return item;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gibt eine gefilterte Liste von News zurück. Sucht nur im Titel
|
|
/// </summary>
|
|
/// <param name="filter">Filterbegriff der in bestimmten Feldern gesucht wird</param>
|
|
/// <returns>List betroffener News</returns>
|
|
public async Task<List<News>> SearchAsync(string filter)
|
|
{
|
|
return (await Repository.FindAsync(c => c.Headline.Contains(filter))).ToList();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gibt eine gefilterte Liste von News mit Namen zurück in einer gewählten Sprache
|
|
/// </summary>
|
|
/// <param name="filter">Filterbegriff der in bestimmten Feldern gesucht wird</param>
|
|
/// <param name="language">Gewünschte Sprache</param>
|
|
/// <param name="fallback">Fallback Sprache</param>
|
|
/// <param name="includeDeleted">Sollen gelöschte inkludiert werden?</param>
|
|
/// <returns>Liste betroffener News</returns>
|
|
public IQueryable<NewsWithNames> FilterWithNames(string filter, string language, string fallback, bool includeDeleted)
|
|
{
|
|
language = language.ToUpperInvariant();
|
|
fallback = fallback.ToUpperInvariant();
|
|
|
|
var baseQuery = _namesRepository.QueryStoredProcedure("SELECT * FROM tv_NewsWithNames({0},{1})", c => c.Headline.Contains(filter), language, fallback);
|
|
|
|
if (!includeDeleted)
|
|
baseQuery = baseQuery.Where(c => c.Deleted == false);
|
|
|
|
return baseQuery;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gibt eine gefilterte Liste von News mit Namen zurück in einer gewählten Sprache
|
|
/// </summary>
|
|
/// <param name="filter">Filterbegriff der in bestimmten Feldern gesucht wird</param>
|
|
/// <param name="states">Liste nach Bundesländern nach Filter</param>
|
|
/// <param name="language">Gewünschte Sprache</param>
|
|
/// <param name="fallback">Fallback Sprache</param>
|
|
/// <param name="includeDeleted">Sollen gelöschte inkludiert werden?</param>
|
|
/// <param name="countries">Liste von Ländern nach Filter</param>
|
|
/// <returns>Liste betroffener News</returns>
|
|
public IQueryable<NewsWithNames> FilterWithNames(string filter, List<string> countries, List<string> states, string language, string fallback, bool includeDeleted)
|
|
{
|
|
language = language.ToUpperInvariant();
|
|
fallback = fallback.ToUpperInvariant();
|
|
|
|
var baseQuery = _namesRepository.QueryStoredProcedure("SELECT * FROM tv_NewsWithNames({0},{1})", c => c.Headline.Contains(filter), language, fallback);
|
|
|
|
if (countries.Any())
|
|
baseQuery = baseQuery.Where(c => c.CountryCode != null && c.CountryCode != "" && countries.Contains(c.CountryCode));
|
|
|
|
if (states.Any())
|
|
baseQuery = baseQuery.Where(c => c.State != null && c.State != "" && states.Contains(c.State));
|
|
|
|
if (!includeDeleted)
|
|
baseQuery = baseQuery.Where(c => c.Deleted == false);
|
|
|
|
return baseQuery;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gibt eine Liste von News-Meldungen für die App zurück. Es werden nur laufende News berücksichtigt
|
|
/// </summary>
|
|
/// <param name="visibility">Sichtbar für wen? Wird adaptiert!</param>
|
|
/// <param name="categoryId">Gewünschte Kategorie oder leer wenn alle</param>
|
|
/// <param name="country">Land</param>
|
|
/// <param name="state">Bundesland</param>
|
|
/// <param name="lat">Optional: Breitengrad</param>
|
|
/// <param name="lng">Optional: Längengrad</param>
|
|
/// <param name="language">Gewünschte Sprache</param>
|
|
/// <param name="fallback">Fallback Sprache</param>
|
|
/// <param name="skip">Datensätze auslassen</param>
|
|
/// <param name="take">Datensätze nehmen</param>
|
|
/// <returns>Liste passender News</returns>
|
|
public async Task<(int total, List<NewsWithNames> list)> GetForAppAsync(NewsVisibility visibility, string categoryId, string country, string state, double? lat, double? lng, string language, string fallback, int skip, int take)
|
|
{
|
|
language = language.ToUpperInvariant();
|
|
fallback = fallback.ToUpperInvariant();
|
|
if(!string.IsNullOrWhiteSpace(country))
|
|
country = country.ToUpperInvariant();
|
|
if (!string.IsNullOrWhiteSpace(state))
|
|
state = state.ToUpperInvariant();
|
|
|
|
|
|
var geometryFactory = NtsGeometryServices.Instance.CreateGeometryFactory(srid: 4326);
|
|
var location = geometryFactory.CreatePoint(new Coordinate(lng.Value, lat.Value));
|
|
|
|
var baseQuery = _namesRepository.QueryStoredProcedure("SELECT * FROM tv_NewsWithNames({0},{1})", c => c.CategoryId == categoryId && c.Deleted == false && c.Status == NewsStatus.Running && c.Language == language && (c.Visibility == visibility || c.Visibility == NewsVisibility.DogWalkerAndOwners) &&
|
|
(c.GeoMode == GeoMode.None ||
|
|
(c.GeoMode == GeoMode.Country && c.CountryCode == country) ||
|
|
(c.GeoMode == GeoMode.CountryAndState && c.CountryCode == country && c.State == state) ||
|
|
(c.GeoMode == GeoMode.Location && c.Location.IsWithinDistance(location, c.Radius * 1000))), language, fallback);
|
|
|
|
//if (geoMode == GeoMode.None)
|
|
//{
|
|
// var baseQuery = _namesRepository.QueryStoredProcedure("SELECT * FROM tv_NewsWithNames({0},{1})", c => c.Deleted == false && c.Status == NewsStatus.Running && c.Language == language && c.GeoMode == GeoMode.None && (c.Visibility == visibility || c.Visibility == NewsVisibility.DogWalkerAndOwners), language, fallback);
|
|
// if(!string.IsNullOrEmpty(categoryId))
|
|
// baseQuery = baseQuery.Where(c => c.CategoryId == categoryId);
|
|
|
|
// return await baseQuery.ToListAsync().ConfigureAwait(false);
|
|
//}
|
|
//else if (geoMode == GeoMode.Country && !string.IsNullOrWhiteSpace(country))
|
|
//{
|
|
// var baseQuery = _namesRepository.QueryStoredProcedure("SELECT * FROM tv_NewsWithNames({0},{1})", c => c.Deleted == false && c.Status == NewsStatus.Running && c.Language == language && c.GeoMode == GeoMode.Country && c.CountryCode == country && (c.Visibility == visibility || c.Visibility == NewsVisibility.DogWalkerAndOwners), language, fallback);
|
|
// if (!string.IsNullOrEmpty(categoryId))
|
|
// baseQuery = baseQuery.Where(c => c.CategoryId == categoryId);
|
|
|
|
// return await baseQuery.ToListAsync().ConfigureAwait(false);
|
|
//}
|
|
//else if (geoMode == GeoMode.CountryAndState && !string.IsNullOrWhiteSpace(country) && !string.IsNullOrWhiteSpace(state))
|
|
//{
|
|
// var baseQuery = _namesRepository.QueryStoredProcedure("SELECT * FROM tv_NewsWithNames({0},{1})", c => c.Deleted == false && c.Status == NewsStatus.Running && c.Language == language && c.GeoMode == GeoMode.CountryAndState && c.CountryCode == country && c.State == state && (c.Visibility == visibility || c.Visibility == NewsVisibility.DogWalkerAndOwners), language, fallback);
|
|
// if (!string.IsNullOrEmpty(categoryId))
|
|
// baseQuery = baseQuery.Where(c => c.CategoryId == categoryId);
|
|
|
|
// return await baseQuery.ToListAsync().ConfigureAwait(false);
|
|
//}
|
|
//else if(geoMode == GeoMode.Location && lat.HasValue && lng.HasValue)
|
|
//{
|
|
// //Lokalisierungsmodus --> Andere Abfrage weil wir die Distanz zu den Geokoordinaten brauchen
|
|
// var geometryFactory = NtsGeometryServices.Instance.CreateGeometryFactory(srid: 4326);
|
|
// var location = geometryFactory.CreatePoint(new Coordinate(lng.Value, lat.Value));
|
|
|
|
// var baseQuery = _namesRepository.QueryStoredProcedure("SELECT * FROM tv_NewsWithNames({0},{1})", c => c.Deleted == false && c.Status == NewsStatus.Running && c.Language == language && c.GeoMode == GeoMode.Location && (c.Visibility == visibility || c.Visibility == NewsVisibility.DogWalkerAndOwners), language, fallback);
|
|
// baseQuery = baseQuery.Where(c => c.Location.IsWithinDistance(location, c.Radius * 1000));
|
|
// if (!string.IsNullOrEmpty(categoryId))
|
|
// baseQuery = baseQuery.Where(c => c.CategoryId == categoryId);
|
|
|
|
// return await baseQuery.ToListAsync().ConfigureAwait(false);
|
|
// //var baseQuery = _namesRepository.QueryStoredProcedure("SELECT * FROM tv_NewsWithNamesDistance({0},{1},{2},{3})", c => c.Deleted == false && c.Status == NewsStatus.Running && c.Language == language && c.GeoMode == GeoMode.Location && (c.Visibility == visibility || c.Visibility == NewsVisibility.DogWalkerAndOwners), language, fallback, lat.Value, lng.Value);
|
|
// //if (!string.IsNullOrEmpty(categoryId))
|
|
// // baseQuery = baseQuery.Where(c => c.CategoryId == categoryId);
|
|
|
|
// //return await baseQuery.ToListAsync().ConfigureAwait(false);
|
|
//}
|
|
|
|
|
|
var total = await baseQuery.CountAsync().ConfigureAwait(false);
|
|
var list = await baseQuery.OrderByDescending(c => c.Start).ThenBy(c => c.Location.Distance(location)).Skip(skip).Take(take).ToListAsync().ConfigureAwait(false);
|
|
return (total, list);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gibt eine News mit Sprachen aufgelöst zurück
|
|
/// </summary>
|
|
/// <param name="newsId">Id der News</param>
|
|
/// <param name="language">Gewünschte Sprache</param>
|
|
/// <param name="fallback">Fallback Sprache</param>
|
|
/// <returns>News mit Namen aufgelöst</returns>
|
|
public async Task<NewsWithNames> GetWithNamesAsync(long newsId, string language, string fallback)
|
|
{
|
|
language = language.ToUpperInvariant();
|
|
fallback = fallback.ToUpperInvariant();
|
|
|
|
var baseQuery = _namesRepository.QueryStoredProcedure("SELECT * FROM tv_NewsWithNames({0},{1})", c => c.Deleted == false && c.Id == newsId, language, fallback);
|
|
return await baseQuery.FirstOrDefaultAsync().ConfigureAwait(false);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Starten von freigegebenen News wenn diese das Start-Datum erreicht haben
|
|
/// </summary>
|
|
/// <returns>Anzahl gestartete News</returns>
|
|
public async Task<int> StartApprovedAsnyc()
|
|
{
|
|
var items = await Repository.FindAsync(c => c.Status == NewsStatus.Approved && c.Deleted == false && c.Start <= DateTimeOffset.UtcNow && c.End.Value >= DateTimeOffset.UtcNow);
|
|
foreach (var item in items)
|
|
{
|
|
item.Status = NewsStatus.Running;
|
|
}
|
|
|
|
return items.Count();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Stoppen von abgelaufenen News wenn diese das Enddatum erreicht haben
|
|
/// </summary>
|
|
/// <returns>Anzahl gestoppte News</returns>
|
|
public async Task<int> StopRunningAsync()
|
|
{
|
|
var items = await Repository.FindAsync(c => c.Status == NewsStatus.Running && c.Deleted == false && c.End.Value <= DateTimeOffset.UtcNow);
|
|
foreach (var item in items)
|
|
{
|
|
item.Status = NewsStatus.Ended;
|
|
}
|
|
|
|
return items.Count();
|
|
}
|
|
}
|
|
}
|