持久层重构为独立 MiGu.DB 工程并优化集成
- 新增 MiGu.DB 项目,迁移所有领域实体与枚举,统一模型约定 - 实现 Entity/Repository/UoW/Provider/Exception 等接口与实现 - 支持数据修补机制,完善 Sqlite 初始迁移与数据库管理 - Server 侧移除 EF Core 相关,依赖 MiGu.DB,PlatformPersistence 适配 - 业务服务注入 UoW/Repository,状态字段统一用 enum 及辅助类 - 统一异常处理,Controller 映射 HTTP 状态码 - 配置项与文档补充数据库启动、SchemaMode、迁移说明 - 新增 GlobalUsings.Db.cs、WmsStatusAliases.cs 简化类型引用 - 新增 HttpActorContextMiddleware 支持操作者上下文一致性 - 新增 MiGuDbContextModelSnapshot 追踪数据库结构 - 优化代码结构,解耦领域与持久层,提升扩展性与安全性
This commit is contained in:
@@ -0,0 +1,170 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using MiGu.DB.Domains.Dashboard;
|
||||
using MiGu.DB.Domains.SimpleFields;
|
||||
using MiGu.DB.Domains.Transport;
|
||||
using MiGu.DB.Domains.Wms;
|
||||
using MiGu.DB.Kernel.Entities;
|
||||
|
||||
namespace MiGu.DB.Domains.Wms;
|
||||
|
||||
public sealed class WarehouseConfiguration : IEntityTypeConfiguration<Warehouse>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<Warehouse> b)
|
||||
{
|
||||
b.ToTable("wms_warehouses");
|
||||
b.HasKey(x => x.Id);
|
||||
b.HasIndex(x => x.Code).IsUnique();
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class WarehouseAreaConfiguration : IEntityTypeConfiguration<WarehouseArea>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<WarehouseArea> b)
|
||||
{
|
||||
b.ToTable("wms_areas");
|
||||
b.HasKey(x => x.Id);
|
||||
b.HasIndex(x => x.Code).IsUnique();
|
||||
b.HasIndex(x => x.WarehouseId);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class StorageConfiguration : IEntityTypeConfiguration<Storage>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<Storage> b)
|
||||
{
|
||||
b.ToTable("wms_storages");
|
||||
b.HasKey(x => x.Id);
|
||||
b.HasIndex(x => x.Code).IsUnique();
|
||||
b.HasIndex(x => x.AreaId);
|
||||
b.HasIndex(x => x.Barcode);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class ContainerConfiguration : IEntityTypeConfiguration<Container>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<Container> b)
|
||||
{
|
||||
b.ToTable("wms_containers");
|
||||
b.HasKey(x => x.Id);
|
||||
b.HasIndex(x => x.Code).IsUnique();
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class MaterialTypeConfiguration : IEntityTypeConfiguration<MaterialType>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<MaterialType> b)
|
||||
{
|
||||
b.ToTable("wms_material_types");
|
||||
b.HasKey(x => x.Id);
|
||||
b.HasIndex(x => x.Code).IsUnique();
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class MaterialConfiguration : IEntityTypeConfiguration<Material>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<Material> b)
|
||||
{
|
||||
b.ToTable("wms_materials");
|
||||
b.HasKey(x => x.Id);
|
||||
b.HasIndex(x => x.Code).IsUnique();
|
||||
b.HasIndex(x => x.Barcode);
|
||||
b.HasIndex(x => new { x.LifecycleStatus, x.UpdatedAt });
|
||||
b.HasIndex(x => x.TypeCode);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class ContainerLocationConfiguration : IEntityTypeConfiguration<ContainerLocation>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<ContainerLocation> b)
|
||||
{
|
||||
b.ToTable("wms_container_locations");
|
||||
b.HasKey(x => x.Id);
|
||||
b.HasIndex(x => x.ContainerId).IsUnique();
|
||||
b.HasIndex(x => new { x.LocationType, x.LocationId });
|
||||
b.HasIndex(x => x.StorageId);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class ContainerMaterialConfiguration : IEntityTypeConfiguration<ContainerMaterial>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<ContainerMaterial> b)
|
||||
{
|
||||
b.ToTable("wms_container_materials");
|
||||
b.HasKey(x => x.Id);
|
||||
b.HasIndex(x => x.MaterialId).IsUnique();
|
||||
b.HasIndex(x => x.ContainerId);
|
||||
b.Property(x => x.Quantity).HasPrecision(18, 4);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class StockEventConfiguration : IEntityTypeConfiguration<StockEvent>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<StockEvent> b)
|
||||
{
|
||||
b.ToTable("wms_stock_events");
|
||||
b.HasKey(x => x.Id);
|
||||
b.Property(x => x.EventType).HasMaxLength(32);
|
||||
b.Property(x => x.MaterialCode).HasMaxLength(64);
|
||||
b.Property(x => x.MaterialName).HasMaxLength(128);
|
||||
b.Property(x => x.MaterialBarcode).HasMaxLength(128);
|
||||
b.Property(x => x.MaterialTypeCode).HasMaxLength(64);
|
||||
b.Property(x => x.ContainerCode).HasMaxLength(64);
|
||||
b.Property(x => x.ContainerName).HasMaxLength(128);
|
||||
b.Property(x => x.StorageCode).HasMaxLength(64);
|
||||
b.Property(x => x.StorageName).HasMaxLength(128);
|
||||
b.Property(x => x.AreaCode).HasMaxLength(64);
|
||||
b.Property(x => x.FromStorageCode).HasMaxLength(64);
|
||||
b.Property(x => x.FromStorageName).HasMaxLength(128);
|
||||
b.Property(x => x.ToStorageCode).HasMaxLength(64);
|
||||
b.Property(x => x.ToStorageName).HasMaxLength(128);
|
||||
b.Property(x => x.RefType).HasMaxLength(64);
|
||||
b.Property(x => x.RefCode).HasMaxLength(64);
|
||||
b.Property(x => x.Operator).HasMaxLength(128);
|
||||
b.Property(x => x.Reason).HasMaxLength(500);
|
||||
b.HasIndex(x => x.OperatedAt);
|
||||
b.HasIndex(x => x.EventType);
|
||||
b.HasIndex(x => x.MaterialId);
|
||||
b.HasIndex(x => x.ContainerId);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class HistoryConfigurationBase<T> : IEntityTypeConfiguration<T> where T : HistoryEntity
|
||||
{
|
||||
private readonly string _table;
|
||||
protected HistoryConfigurationBase(string table) => _table = table;
|
||||
|
||||
public virtual void Configure(EntityTypeBuilder<T> b)
|
||||
{
|
||||
b.ToTable(_table);
|
||||
b.HasKey(x => x.Id);
|
||||
b.Property(x => x.EventType).HasMaxLength(64);
|
||||
b.Property(x => x.BeforeJson).HasColumnType("text");
|
||||
b.Property(x => x.AfterJson).HasColumnType("text");
|
||||
b.Property(x => x.Operator).HasMaxLength(128);
|
||||
b.Property(x => x.Source).HasMaxLength(32);
|
||||
b.Property(x => x.Reason).HasMaxLength(500);
|
||||
b.Property(x => x.Remark).HasMaxLength(1000);
|
||||
b.Property(x => x.Extend).HasColumnType("text");
|
||||
b.HasIndex(x => x.ContainerId);
|
||||
b.HasIndex(x => x.OperatedAt);
|
||||
b.HasIndex(x => x.EventType);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class ContainerLocationHistoryConfiguration : HistoryConfigurationBase<ContainerLocationHistory>
|
||||
{
|
||||
public ContainerLocationHistoryConfiguration() : base("wms_container_location_history") { }
|
||||
}
|
||||
|
||||
public sealed class ContainerMaterialHistoryConfiguration : HistoryConfigurationBase<ContainerMaterialHistory>
|
||||
{
|
||||
public ContainerMaterialHistoryConfiguration() : base("wms_container_material_history") { }
|
||||
|
||||
public override void Configure(EntityTypeBuilder<ContainerMaterialHistory> b)
|
||||
{
|
||||
base.Configure(b);
|
||||
b.Property(x => x.QuantityDelta).HasPrecision(18, 4);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using MiGu.DB.Kernel.Entities;
|
||||
|
||||
namespace MiGu.DB.Domains.Wms;
|
||||
|
||||
// WMS 聚合实体。状态/类型字段为枚举(库内 TEXT,见全局 HasConversion);DTO 仍用字符串,由 *Statuses 辅助类解析。
|
||||
|
||||
public sealed class Warehouse : AggregateRoot
|
||||
{
|
||||
[MaxLength(64)] public string Code { get; set; } = "";
|
||||
[MaxLength(128)] public string Name { get; set; } = "";
|
||||
[MaxLength(64)] public string Type { get; set; } = "Default";
|
||||
public bool Enabled { get; set; } = true;
|
||||
public int SortOrder { get; set; }
|
||||
}
|
||||
|
||||
public sealed class WarehouseArea : AggregateRoot
|
||||
{
|
||||
public Guid WarehouseId { get; set; }
|
||||
[MaxLength(64)] public string Code { get; set; } = "";
|
||||
[MaxLength(128)] public string Name { get; set; } = "";
|
||||
[MaxLength(64)] public string Type { get; set; } = "Storage";
|
||||
public AreaLayoutMode LayoutMode { get; set; } = AreaLayoutMode.Flat;
|
||||
[MaxLength(32)] public string State { get; set; } = "Default";
|
||||
public bool Enabled { get; set; } = true;
|
||||
public int SortOrder { get; set; }
|
||||
}
|
||||
|
||||
public sealed class Storage : AggregateRoot
|
||||
{
|
||||
public Guid AreaId { get; set; }
|
||||
[MaxLength(64)] public string Code { get; set; } = "";
|
||||
[MaxLength(128)] public string Name { get; set; } = "";
|
||||
[MaxLength(64)] public string StorageType { get; set; } = StorageTypeCodes.Storage;
|
||||
// 属性名与枚举类型同名合法;默认值引用枚举成员 LocationKind.Station(勿再引入同名静态类)
|
||||
public LocationKind LocationKind { get; set; } = LocationKind.Station;
|
||||
public int ColumnNo { get; set; }
|
||||
public int LevelNo { get; set; } = 1;
|
||||
public int DepthNo { get; set; } = 1;
|
||||
[MaxLength(64)] public string SiteId { get; set; } = "";
|
||||
[MaxLength(64)] public string SiteCode { get; set; } = "";
|
||||
[MaxLength(128)] public string Barcode { get; set; } = "";
|
||||
public int Capacity { get; set; }
|
||||
public StorageStatus Status { get; set; } = StorageStatus.Empty;
|
||||
[MaxLength(64)] public string Usage { get; set; } = "";
|
||||
public int Priority { get; set; }
|
||||
[MaxLength(64)] public string ZoneCode { get; set; } = "";
|
||||
public bool AllowInbound { get; set; } = true;
|
||||
public bool AllowOutbound { get; set; } = true;
|
||||
public bool Enabled { get; set; } = true;
|
||||
}
|
||||
|
||||
public sealed class Container : AggregateRoot
|
||||
{
|
||||
public Guid? AreaId { get; set; }
|
||||
[MaxLength(64)] public string Code { get; set; } = "";
|
||||
[MaxLength(128)] public string Name { get; set; } = "";
|
||||
[MaxLength(64)] public string ContainerType { get; set; } = "Box";
|
||||
public ContainerStatus Status { get; set; } = ContainerStatus.EmptyMaterial;
|
||||
[MaxLength(128)] public string Barcode { get; set; } = "";
|
||||
public double Length { get; set; }
|
||||
public double Width { get; set; }
|
||||
public double Height { get; set; }
|
||||
public bool Enabled { get; set; } = true;
|
||||
}
|
||||
|
||||
public sealed class MaterialType : AggregateRoot
|
||||
{
|
||||
[MaxLength(64)] public string Code { get; set; } = "";
|
||||
[MaxLength(128)] public string Name { get; set; } = "";
|
||||
[MaxLength(128)] public string Spec { get; set; } = "";
|
||||
[MaxLength(32)] public string Unit { get; set; } = "pcs";
|
||||
[MaxLength(64)] public string Category { get; set; } = "";
|
||||
[MaxLength(64)] public string BarcodePrefix { get; set; } = "";
|
||||
public bool Enabled { get; set; } = true;
|
||||
}
|
||||
|
||||
public sealed class Material : AggregateRoot
|
||||
{
|
||||
[MaxLength(64)] public string Code { get; set; } = "";
|
||||
[MaxLength(128)] public string Name { get; set; } = "";
|
||||
[MaxLength(64)] public string TypeCode { get; set; } = "";
|
||||
[MaxLength(128)] public string Barcode { get; set; } = "";
|
||||
[MaxLength(128)] public string Spec { get; set; } = "";
|
||||
[MaxLength(32)] public string Unit { get; set; } = "pcs";
|
||||
[MaxLength(64)] public string Category { get; set; } = "";
|
||||
public MaterialLifecycle LifecycleStatus { get; set; } = MaterialLifecycle.Active;
|
||||
public DateTimeOffset? UnboundAt { get; set; }
|
||||
public bool Enabled { get; set; } = true;
|
||||
}
|
||||
|
||||
public sealed class ContainerLocation : AggregateRoot
|
||||
{
|
||||
public Guid ContainerId { get; set; }
|
||||
public ContainerLocationType LocationType { get; set; } = ContainerLocationType.Storage;
|
||||
[MaxLength(64)] public string LocationId { get; set; } = "";
|
||||
/// <summary>LocationType=Storage 时的库位 Id;由 LocationId 回填,供库存 join 下推。</summary>
|
||||
public Guid? StorageId { get; set; }
|
||||
[MaxLength(64)] public string LocationCode { get; set; } = "";
|
||||
[MaxLength(128)] public string LocationName { get; set; } = "";
|
||||
public ContainerLocationStatus Status { get; set; } = ContainerLocationStatus.Active;
|
||||
public DateTimeOffset EnteredAt { get; set; }
|
||||
}
|
||||
|
||||
public sealed class ContainerMaterial : AggregateRoot
|
||||
{
|
||||
public Guid ContainerId { get; set; }
|
||||
public Guid MaterialId { get; set; }
|
||||
public decimal Quantity { get; set; } = 1;
|
||||
[MaxLength(64)] public string BatchNo { get; set; } = "";
|
||||
[MaxLength(64)] public string SerialNo { get; set; } = "";
|
||||
public ContainerMaterialStatus Status { get; set; } = ContainerMaterialStatus.Bound;
|
||||
public DateTimeOffset BoundAt { get; set; }
|
||||
public DateTimeOffset LoadedAt { get; set; }
|
||||
public DateTimeOffset? UnloadedAt { get; set; }
|
||||
}
|
||||
|
||||
public sealed class StockEvent : Kernel.Entities.Entity<Guid>
|
||||
{
|
||||
public StockEventType EventType { get; set; }
|
||||
public Guid? MaterialId { get; set; }
|
||||
[MaxLength(64)] public string MaterialCode { get; set; } = "";
|
||||
[MaxLength(128)] public string MaterialName { get; set; } = "";
|
||||
[MaxLength(128)] public string MaterialBarcode { get; set; } = "";
|
||||
[MaxLength(64)] public string MaterialTypeCode { get; set; } = "";
|
||||
public Guid? ContainerId { get; set; }
|
||||
[MaxLength(64)] public string ContainerCode { get; set; } = "";
|
||||
[MaxLength(128)] public string ContainerName { get; set; } = "";
|
||||
public Guid? StorageId { get; set; }
|
||||
[MaxLength(64)] public string StorageCode { get; set; } = "";
|
||||
[MaxLength(128)] public string StorageName { get; set; } = "";
|
||||
[MaxLength(64)] public string AreaCode { get; set; } = "";
|
||||
public Guid? FromStorageId { get; set; }
|
||||
[MaxLength(64)] public string FromStorageCode { get; set; } = "";
|
||||
[MaxLength(128)] public string FromStorageName { get; set; } = "";
|
||||
public Guid? ToStorageId { get; set; }
|
||||
[MaxLength(64)] public string ToStorageCode { get; set; } = "";
|
||||
[MaxLength(128)] public string ToStorageName { get; set; } = "";
|
||||
[MaxLength(64)] public string RefType { get; set; } = "Manual";
|
||||
public Guid? RefId { get; set; }
|
||||
[MaxLength(64)] public string RefCode { get; set; } = "";
|
||||
[MaxLength(128)] public string Operator { get; set; } = "";
|
||||
public DateTimeOffset OperatedAt { get; set; }
|
||||
[MaxLength(500)] public string Reason { get; set; } = "";
|
||||
}
|
||||
|
||||
public sealed class ContainerLocationHistory : HistoryEntity
|
||||
{
|
||||
[MaxLength(32)] public string FromLocationType { get; set; } = "";
|
||||
[MaxLength(64)] public string FromLocationId { get; set; } = "";
|
||||
[MaxLength(32)] public string ToLocationType { get; set; } = "";
|
||||
[MaxLength(64)] public string ToLocationId { get; set; } = "";
|
||||
}
|
||||
|
||||
public sealed class ContainerMaterialHistory : HistoryEntity
|
||||
{
|
||||
public Guid? MaterialId { get; set; }
|
||||
public decimal QuantityDelta { get; set; }
|
||||
}
|
||||
|
||||
public static class StorageTypeCodes
|
||||
{
|
||||
public const string Storage = "Storage";
|
||||
public const string LineSide = "LineSide";
|
||||
public const string OfflinePoint = "OfflinePoint";
|
||||
public const string Buffer = "Buffer";
|
||||
public const string FinishedGoods = "FinishedGoods";
|
||||
}
|
||||
|
||||
public static class WmsDefaults
|
||||
{
|
||||
public const string DefaultWarehouseCode = "DEFAULT";
|
||||
public const string DefaultWarehouseName = "默认仓库";
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
namespace MiGu.DB.Domains.Wms;
|
||||
|
||||
/// <summary>
|
||||
/// WMS 状态/类型枚举。列以字符串存储(见约定 HasConversion<string>),成员名即库内合法值。
|
||||
/// 旧别名(Available/Idle/Occupied 等)不进入枚举,由 LegacyStatusNormalizationMigrator 刷库。
|
||||
/// </summary>
|
||||
public enum AreaLayoutMode
|
||||
{
|
||||
Flat,
|
||||
Grid
|
||||
}
|
||||
|
||||
public enum LocationKind
|
||||
{
|
||||
Grid,
|
||||
Station
|
||||
}
|
||||
|
||||
public enum StorageStatus
|
||||
{
|
||||
Empty,
|
||||
EmptyContainer,
|
||||
FullContainer,
|
||||
Disabled
|
||||
}
|
||||
|
||||
public enum ContainerStatus
|
||||
{
|
||||
EmptyMaterial,
|
||||
FullMaterial
|
||||
}
|
||||
|
||||
public enum ContainerLocationType
|
||||
{
|
||||
Storage,
|
||||
Car
|
||||
}
|
||||
|
||||
public enum ContainerLocationStatus
|
||||
{
|
||||
Active,
|
||||
Locked,
|
||||
Exception
|
||||
}
|
||||
|
||||
public enum ContainerMaterialStatus
|
||||
{
|
||||
Bound,
|
||||
Loaded,
|
||||
Unloaded,
|
||||
Adjusted,
|
||||
Frozen
|
||||
}
|
||||
|
||||
public enum MaterialLifecycle
|
||||
{
|
||||
Active,
|
||||
Archived
|
||||
}
|
||||
|
||||
public enum StockEventType
|
||||
{
|
||||
Bind,
|
||||
Unbind,
|
||||
ContainerMove
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
namespace MiGu.DB.Domains.Wms;
|
||||
|
||||
/// <summary>
|
||||
/// 枚举辅助类(复数命名):承接 API/DTO 的字符串入参,解析为实体上的枚举。
|
||||
/// 与同名枚举分离,避免「属性 LocationKind 初始值引用实例属性」一类编译冲突。
|
||||
/// Server 侧通过 global using 别名(如 StorageStatuses)引用本文件类型。
|
||||
/// </summary>
|
||||
public static class AreaLayoutModes
|
||||
{
|
||||
public static readonly HashSet<AreaLayoutMode> All = new() { AreaLayoutMode.Flat, AreaLayoutMode.Grid };
|
||||
|
||||
public static AreaLayoutMode ParseOr(string? value, AreaLayoutMode fallback = AreaLayoutMode.Flat) =>
|
||||
Enum.TryParse<AreaLayoutMode>(value, true, out var e) && All.Contains(e) ? e : fallback;
|
||||
}
|
||||
|
||||
public static class LocationKinds
|
||||
{
|
||||
public const LocationKind Grid = LocationKind.Grid;
|
||||
public const LocationKind Station = LocationKind.Station;
|
||||
public static readonly HashSet<LocationKind> All = new() { Grid, Station };
|
||||
|
||||
public static LocationKind ParseOr(string? value, LocationKind fallback = LocationKind.Station) =>
|
||||
Enum.TryParse<LocationKind>(value, true, out var e) && All.Contains(e) ? e : fallback;
|
||||
}
|
||||
|
||||
public static class StorageStatuses
|
||||
{
|
||||
public const StorageStatus Empty = StorageStatus.Empty;
|
||||
public const StorageStatus EmptyContainer = StorageStatus.EmptyContainer;
|
||||
public const StorageStatus FullContainer = StorageStatus.FullContainer;
|
||||
public const StorageStatus Disabled = StorageStatus.Disabled;
|
||||
|
||||
public static readonly HashSet<StorageStatus> All = new()
|
||||
{ Empty, EmptyContainer, FullContainer, Disabled };
|
||||
|
||||
/// <summary>
|
||||
/// 写路径归一:兼容历史字符串 Available/Idle/Occupied。
|
||||
/// 库内残留旧值须靠 DataMigrator 刷掉,不能依赖 converter 读侧归一(WHERE 会漏行)。
|
||||
/// </summary>
|
||||
public static StorageStatus Normalize(string? status) => status switch
|
||||
{
|
||||
"Available" or "Idle" => Empty,
|
||||
"Occupied" => FullContainer,
|
||||
_ when Enum.TryParse<StorageStatus>(status, true, out var e) && All.Contains(e) => e,
|
||||
_ => Empty
|
||||
};
|
||||
}
|
||||
|
||||
public static class ContainerStatuses
|
||||
{
|
||||
public const ContainerStatus EmptyMaterial = ContainerStatus.EmptyMaterial;
|
||||
public const ContainerStatus FullMaterial = ContainerStatus.FullMaterial;
|
||||
public static readonly HashSet<ContainerStatus> All = new() { EmptyMaterial, FullMaterial };
|
||||
|
||||
public static ContainerStatus ParseOr(string? value, ContainerStatus fallback = ContainerStatus.EmptyMaterial) =>
|
||||
Enum.TryParse<ContainerStatus>(value, true, out var e) && All.Contains(e) ? e : fallback;
|
||||
}
|
||||
|
||||
public static class ContainerLocationTypes
|
||||
{
|
||||
public const ContainerLocationType Storage = ContainerLocationType.Storage;
|
||||
public const ContainerLocationType Car = ContainerLocationType.Car;
|
||||
public static readonly HashSet<ContainerLocationType> All = new() { Storage, Car };
|
||||
|
||||
public static bool IsDefined(string? value) =>
|
||||
Enum.TryParse<ContainerLocationType>(value, true, out var e) && All.Contains(e);
|
||||
|
||||
public static ContainerLocationType ParseOr(string? value, ContainerLocationType fallback = ContainerLocationType.Storage) =>
|
||||
Enum.TryParse<ContainerLocationType>(value, true, out var e) && All.Contains(e) ? e : fallback;
|
||||
|
||||
public static bool EqualsString(ContainerLocationType value, string? other) =>
|
||||
Enum.TryParse<ContainerLocationType>(other, true, out var e) && e == value;
|
||||
}
|
||||
|
||||
public static class ContainerLocationStatuses
|
||||
{
|
||||
public const ContainerLocationStatus Active = ContainerLocationStatus.Active;
|
||||
public const ContainerLocationStatus Locked = ContainerLocationStatus.Locked;
|
||||
public const ContainerLocationStatus Exception = ContainerLocationStatus.Exception;
|
||||
public static readonly HashSet<ContainerLocationStatus> All = new() { Active, Locked, Exception };
|
||||
|
||||
public static bool IsDefined(string? value) =>
|
||||
Enum.TryParse<ContainerLocationStatus>(value, true, out var e) && All.Contains(e);
|
||||
|
||||
public static ContainerLocationStatus ParseOr(string? value, ContainerLocationStatus fallback = ContainerLocationStatus.Active) =>
|
||||
Enum.TryParse<ContainerLocationStatus>(value, true, out var e) && All.Contains(e) ? e : fallback;
|
||||
}
|
||||
|
||||
public static class ContainerMaterialStatuses
|
||||
{
|
||||
public const ContainerMaterialStatus Bound = ContainerMaterialStatus.Bound;
|
||||
public const ContainerMaterialStatus Loaded = ContainerMaterialStatus.Loaded;
|
||||
public const ContainerMaterialStatus Unloaded = ContainerMaterialStatus.Unloaded;
|
||||
public const ContainerMaterialStatus Adjusted = ContainerMaterialStatus.Adjusted;
|
||||
public const ContainerMaterialStatus Frozen = ContainerMaterialStatus.Frozen;
|
||||
|
||||
public static readonly HashSet<ContainerMaterialStatus> ActiveBind = new()
|
||||
{ Bound, Loaded, Adjusted, Frozen };
|
||||
}
|
||||
|
||||
public static class MaterialLifecycles
|
||||
{
|
||||
public const MaterialLifecycle Active = MaterialLifecycle.Active;
|
||||
public const MaterialLifecycle Archived = MaterialLifecycle.Archived;
|
||||
public static readonly HashSet<MaterialLifecycle> All = new() { Active, Archived };
|
||||
|
||||
public static MaterialLifecycle ParseOr(string? value, MaterialLifecycle fallback = MaterialLifecycle.Active) =>
|
||||
Enum.TryParse<MaterialLifecycle>(value, true, out var e) && All.Contains(e) ? e : fallback;
|
||||
}
|
||||
|
||||
public static class StockEventTypes
|
||||
{
|
||||
public const StockEventType Bind = StockEventType.Bind;
|
||||
public const StockEventType Unbind = StockEventType.Unbind;
|
||||
public const StockEventType ContainerMove = StockEventType.ContainerMove;
|
||||
}
|
||||
Reference in New Issue
Block a user