159 lines
6.8 KiB
C#
159 lines
6.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text.Json.Serialization;
|
|
using System.Threading.Tasks;
|
|
using FinlyticAssets.Models;
|
|
using FinlyticBackend.Util;
|
|
using FinlyticCore.Dtos;
|
|
using FinlyticCore.Dtos.Fundamentals;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace FinlyticBackend.Controllers;
|
|
|
|
|
|
[ApiController]
|
|
[Authorize]
|
|
[Route("api/v1/calendar")]
|
|
public class CalendarController : ControllerBase
|
|
{
|
|
private readonly WebMqttClient _mqttClient;
|
|
private readonly ILogger<CalendarController> _logger;
|
|
|
|
public CalendarController(WebMqttClient mqttClient, ILogger<CalendarController> logger)
|
|
{
|
|
_mqttClient = mqttClient;
|
|
_logger = logger;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieves corporate calendar events with optional filters.
|
|
/// </summary>
|
|
[HttpGet("events/{year:int?}/{month:int?}")]
|
|
public async Task<IActionResult> GetCorporateCalendar(
|
|
int? year = null,
|
|
int? month = null,
|
|
[FromQuery] string? category = null,
|
|
[FromQuery] DateTime? date = null,
|
|
[FromQuery] string? symbol = null,
|
|
[FromQuery] string? isin = null)
|
|
{
|
|
string? activeSymbol = !string.IsNullOrWhiteSpace(symbol) ? symbol.Trim() : isin?.Trim();
|
|
int targetYear = year ?? DateTime.UtcNow.Year;
|
|
int targetMonth = month ?? DateTime.UtcNow.Month;
|
|
|
|
try
|
|
{
|
|
if (_mqttClient.IsConnected)
|
|
{
|
|
var rawEvents = await _mqttClient.SendRpcRequestAsync<List<CorporateEventDto>, GetEventsByMonthRequest>(
|
|
"events_GetByMonth",
|
|
new GetEventsByMonthRequest(targetYear, targetMonth),
|
|
TimeSpan.FromSeconds(4)
|
|
);
|
|
|
|
if (rawEvents != null && rawEvents.Count > 0)
|
|
{
|
|
var allAssets = AssetsController.LoadAssetsFromIndexJson() ?? new List<AssetIndex>();
|
|
var isinLookup = allAssets
|
|
.Where(a => !string.IsNullOrEmpty(a.Isin))
|
|
.GroupBy(a => a.Isin, StringComparer.OrdinalIgnoreCase)
|
|
.ToDictionary(g => g.Key, g => g.First(), StringComparer.OrdinalIgnoreCase);
|
|
|
|
var parsedEvents = rawEvents.Select(e =>
|
|
{
|
|
string eventIsin = e.Isin ?? string.Empty;
|
|
string ticker = e.Ticker?.Ticker ?? string.Empty;
|
|
string companyName = e.CompanyName ?? string.Empty;
|
|
string eventType = e.EventType ?? string.Empty;
|
|
DateTime eventDate = e.Date;
|
|
|
|
string image = $"/api/v1/logo/{eventIsin}";
|
|
if (!string.IsNullOrEmpty(eventIsin) && isinLookup.TryGetValue(eventIsin, out var matchedAsset))
|
|
{
|
|
if (!string.IsNullOrWhiteSpace(matchedAsset.Name))
|
|
{
|
|
companyName = matchedAsset.Name;
|
|
}
|
|
|
|
if (!string.IsNullOrWhiteSpace(matchedAsset.Image))
|
|
{
|
|
image = matchedAsset.Image;
|
|
}
|
|
}
|
|
|
|
return new CalendarEventResponseDto(
|
|
Id: e.Id.ToString(),
|
|
CompanyName: companyName,
|
|
EventType: eventType,
|
|
EventDate: eventDate,
|
|
Date: eventDate.ToString("o"),
|
|
Isin: e.Isin,
|
|
Ticker: ticker,
|
|
Description: $"{eventType} - {companyName}",
|
|
Details: $"Termin für {companyName} am {eventDate:dd.MM.yyyy}",
|
|
Image: image
|
|
);
|
|
});
|
|
|
|
// Optionales Filtern
|
|
var filtered = parsedEvents;
|
|
|
|
if (!string.IsNullOrWhiteSpace(category) &&
|
|
!string.Equals(category, "Alle", StringComparison.OrdinalIgnoreCase) &&
|
|
!string.Equals(category, "all", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
string catKey = category.ToLowerInvariant();
|
|
filtered = filtered.Where(e =>
|
|
{
|
|
string t = (e.EventType ?? string.Empty).ToLowerInvariant();
|
|
if (catKey.Contains("earn") || catKey.Contains("quartal") || catKey.Contains("ergebnis"))
|
|
{
|
|
return t.Contains("earn") || t.Contains("quart") || t.Contains("ergebnis") || t.Contains("finan") || t.Contains("report") || t.Contains("bilanz") || string.Equals(t, "event", StringComparison.OrdinalIgnoreCase);
|
|
}
|
|
if (catKey.Contains("ex") || catKey.Contains("div"))
|
|
{
|
|
return (t.Contains("ex") || t.Contains("div") || t.Contains("ausschütt")) && !t.Contains("pay") && !t.Contains("zahl");
|
|
}
|
|
if (catKey.Contains("pay") || catKey.Contains("zahl"))
|
|
{
|
|
return t.Contains("pay") || t.Contains("zahl") || t.Contains("auszahl");
|
|
}
|
|
if (catKey.Contains("split"))
|
|
{
|
|
return t.Contains("split");
|
|
}
|
|
return t.Contains(catKey) || string.Equals(e.EventType, category, StringComparison.OrdinalIgnoreCase);
|
|
});
|
|
}
|
|
|
|
if (date.HasValue)
|
|
{
|
|
filtered = filtered.Where(e => e.EventDate.Date == date.Value.Date);
|
|
}
|
|
|
|
if (!string.IsNullOrWhiteSpace(activeSymbol))
|
|
{
|
|
filtered = filtered.Where(e =>
|
|
string.Equals(e.Isin, activeSymbol, StringComparison.OrdinalIgnoreCase) ||
|
|
string.Equals(e.Ticker, activeSymbol, StringComparison.OrdinalIgnoreCase));
|
|
}
|
|
|
|
return Ok(filtered.OrderBy(e => e.EventDate).ToList());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
_logger.LogWarning("[CalendarController] MQTT client is NOT connected to broker.");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogWarning(ex, "[CalendarController] Failed to retrieve corporate events via MQTT RPC.");
|
|
}
|
|
|
|
return Ok(new List<CalendarEventResponseDto>());
|
|
}
|
|
} |