190 lines
5.8 KiB
C#
190 lines
5.8 KiB
C#
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);
|
||
}
|