Files
ReifenSpaeth/Lagerbestand/Models/SiteSettings.cs
T

190 lines
5.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
namespace Lagerbestand.Models;
/// <summary>
/// Site-wide settings stored in the database
/// </summary>
public class SiteSettings
{
public Guid Id { get; set; } = Guid.NewGuid();
/// <summary>
/// Unique key for the setting (e.g., "PromoBanner")
/// </summary>
public string Key { get; set; } = string.Empty;
/// <summary>
/// JSON-serialized value of the setting
/// </summary>
public string Value { get; set; } = string.Empty;
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public DateTime? UpdatedAt { get; set; }
}
/// <summary>
/// Promotion banner settings
/// </summary>
public class PromoBannerSettings
{
public bool IsEnabled { get; set; }
public string Title { get; set; } = string.Empty;
public string Message { get; set; } = string.Empty;
public DateTime? StartDate { get; set; }
public DateTime? EndDate { get; set; }
public bool ShowContactButton { get; set; } = true;
/// <summary>
/// Check if banner should be shown based on current date and content
/// </summary>
public bool ShouldShow()
{
// Must be enabled
if (!IsEnabled) return false;
// Must have content
if (string.IsNullOrWhiteSpace(Title) && string.IsNullOrWhiteSpace(Message))
return false;
var now = DateTime.UtcNow.Date;
// Check date range if specified
if (StartDate.HasValue && now < StartDate.Value.Date)
return false;
if (EndDate.HasValue && now > EndDate.Value.Date)
return false;
return true;
}
}
/// <summary>
/// Lexware API connection settings for customer data synchronization
/// </summary>
public class LexwareApiSettings
{
public bool IsEnabled { get; set; }
/// <summary>
/// Lexware API base URL (e.g., https://api.lexoffice.io/v1)
/// </summary>
public string BaseUrl { get; set; } = string.Empty;
/// <summary>
/// API key for authentication
/// </summary>
public string ApiKey { get; set; } = string.Empty;
/// <summary>
/// Whether automatic daily sync is enabled
/// </summary>
public bool AutoSyncEnabled { get; set; } = true;
/// <summary>
/// Time of day for automatic sync (HH:mm format)
/// </summary>
public string AutoSyncTime { get; set; } = "02:00";
/// <summary>
/// Timestamp of the last successful sync
/// </summary>
public DateTime? LastSyncAt { get; set; }
/// <summary>
/// Result message from the last sync
/// </summary>
public string? LastSyncResult { get; set; }
/// <summary>
/// Number of customers synced in last run
/// </summary>
public int LastSyncCount { get; set; }
/// <summary>
/// Whether the API connection is configured
/// </summary>
public bool IsConfigured => !string.IsNullOrWhiteSpace(BaseUrl) && !string.IsNullOrWhiteSpace(ApiKey);
}
/// <summary>
/// Two-Factor Authentication settings stored in SiteSettings
/// </summary>
public class TwoFactorSettings
{
/// <summary>
/// Global toggle: when false, no 2FA is used at all
/// </summary>
public bool IsEnabled { get; set; }
/// <summary>
/// Issuer name shown in authenticator apps (e.g. "Reifen Späth")
/// </summary>
public string Issuer { get; set; } = "Reifen Späth Lagerverwaltung";
/// <summary>
/// Whether email fallback codes are enabled
/// </summary>
public bool EmailFallbackEnabled { get; set; }
}
/// <summary>
/// Session / long-duration usage settings (idle lock, circuit retention).
/// Editable by admins in the Status page.
/// </summary>
public class SessionSettings
{
public const int DefaultIdleTimeoutMinutes = 60;
public const int MaxIdleTimeoutMinutes = 60;
public const int MinIdleTimeoutMinutes = 1;
public const double DefaultCircuitRetentionHours = 2.0;
public const double MaxCircuitRetentionHours = 4.0;
public const double MinCircuitRetentionHours = 0.5;
/// <summary>
/// Minutes of inactivity before the browser tab shows a "Confirm to continue" lock overlay.
/// Range: 1 – 60. Default: 60.
/// </summary>
public int IdleTimeoutMinutes { get; set; } = DefaultIdleTimeoutMinutes;
/// <summary>
/// Hours a disconnected Blazor Server circuit is retained on the server
/// before being discarded (allows reconnect without state loss).
/// Range: 0.5 – 4. Default: 2. Applied at next app restart.
/// </summary>
public double CircuitRetentionHours { get; set; } = DefaultCircuitRetentionHours;
public int GetSafeIdleTimeoutMinutes()
{
if (IdleTimeoutMinutes < MinIdleTimeoutMinutes) return MinIdleTimeoutMinutes;
if (IdleTimeoutMinutes > MaxIdleTimeoutMinutes) return MaxIdleTimeoutMinutes;
return IdleTimeoutMinutes;
}
public double GetSafeCircuitRetentionHours()
{
if (CircuitRetentionHours < MinCircuitRetentionHours) return MinCircuitRetentionHours;
if (CircuitRetentionHours > MaxCircuitRetentionHours) return MaxCircuitRetentionHours;
return CircuitRetentionHours;
}
}
/// <summary>
/// SMTP settings for sending email-based 2FA codes and notifications
/// </summary>
public class SmtpSettings
{
public bool IsEnabled { get; set; }
public string Host { get; set; } = string.Empty;
public int Port { get; set; } = 587;
public string Username { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
public string FromEmail { get; set; } = string.Empty;
public string FromName { get; set; } = "Reifen Späth Lagerverwaltung";
public bool UseSsl { get; set; } = true;
public bool IsConfigured => !string.IsNullOrWhiteSpace(Host)
&& !string.IsNullOrWhiteSpace(Username)
&& !string.IsNullOrWhiteSpace(FromEmail);
}