Neil67's picture
Deploy Bakery ERP Space
13240d3
Raw
History Blame Contribute Delete
23.1 kB
namespace BakeryErp.Infrastructure.Database;
public sealed class LocalDataStore
{
public List<LocalSupplier> Suppliers { get; set; } = [];
public List<LocalItem> Items { get; set; } = [];
public List<LocalStore> Stores { get; set; } = [];
public List<LocalWarehouse> Warehouses { get; set; } = [];
public List<LocalOcrDocument> OcrDocuments { get; set; } = [];
public List<LocalStockBalance> StockBalances { get; set; } = [];
public List<LocalInventoryTransaction> InventoryTransactions { get; set; } = [];
public List<LocalPurchaseOrder> PurchaseOrders { get; set; } = [];
public List<LocalPettyCashTransaction> PettyCashTransactions { get; set; } = [];
public List<LocalTransferOrder> TransferOrders { get; set; } = [];
public List<LocalStoreReturn> StoreReturns { get; set; } = [];
public List<LocalReportDefinition> ReportDefinitions { get; set; } = [];
public int SupplierCount => Suppliers.Count(static supplier => supplier.IsActive);
public int ItemCount => Items.Count(static item => item.IsActive);
public int StoreCount => Stores.Count(static store => store.IsActive);
public int WarehouseCount => Warehouses.Count(static warehouse => warehouse.IsActive);
public int OcrDocumentCount => OcrDocuments.Count;
public static LocalDataStore CreateSeed()
{
return new LocalDataStore
{
Suppliers =
[
new LocalSupplier
{
Id = Guid.Parse("55555555-5555-5555-5555-555555555555"),
Code = "SUP-FLOUR",
Name = "範例麵粉供應商",
PaymentTermDays = 30,
CreatedAt = DateTime.UtcNow,
IsActive = true
}
],
Items =
[
new LocalItem
{
Id = Guid.Parse("13131313-1313-1313-1313-131313131313"),
Sku = "RM-FLOUR-001",
Name = "高筋麵粉",
ItemType = LocalItemType.RawMaterial,
CategoryName = "麵粉",
BaseUnit = "kg",
SafetyStockQuantity = 50,
ShelfLifeDays = 180,
CreatedAt = DateTime.UtcNow,
IsActive = true
},
new LocalItem
{
Id = Guid.Parse("14141414-1414-1414-1414-141414141414"),
Sku = "PKG-BAG-001",
Name = "吐司袋",
ItemType = LocalItemType.Packaging,
CategoryName = "包材",
BaseUnit = "個",
SafetyStockQuantity = 500,
CreatedAt = DateTime.UtcNow,
IsActive = true
}
],
Stores =
[
new LocalStore
{
Id = Guid.Parse("15151515-1515-1515-1515-151515151515"),
Code = "HQ",
Name = "中央廚房",
StoreType = LocalStoreType.CentralKitchen,
CreatedAt = DateTime.UtcNow,
IsActive = true
},
new LocalStore
{
Id = Guid.Parse("16161616-1616-1616-1616-161616161616"),
Code = "S001",
Name = "直營一店",
StoreType = LocalStoreType.Direct,
CreatedAt = DateTime.UtcNow,
IsActive = true
}
],
Warehouses =
[
new LocalWarehouse
{
Id = Guid.Parse("17171717-1717-1717-1717-171717171717"),
Code = "WH-HQ",
Name = "中央廚房主倉",
StoreName = "中央廚房",
WarehouseType = LocalWarehouseType.CentralKitchen,
CreatedAt = DateTime.UtcNow,
IsActive = true
},
new LocalWarehouse
{
Id = Guid.Parse("18181818-1818-1818-1818-181818181818"),
Code = "WH-S001",
Name = "直營一店倉",
StoreName = "直營一店",
WarehouseType = LocalWarehouseType.Store,
CreatedAt = DateTime.UtcNow,
IsActive = true
}
],
OcrDocuments =
[
new LocalOcrDocument
{
Id = Guid.Parse("88888888-8888-8888-8888-888888888888"),
DocumentNumber = "OCR-20260525-001",
FileName = "sample-receipt.jpg",
SupplierName = "範例麵粉供應商",
DocumentDate = DateOnly.FromDateTime(DateTime.Today),
Status = LocalOcrStatus.Recognized,
TotalAmount = 1280,
RawText = "高筋麵粉 20kg x 2",
ReviewNote = "範例辨識資料",
CreatedAt = DateTime.UtcNow
}
],
StockBalances =
[
new LocalStockBalance
{
Id = Guid.Parse("99999999-9999-9999-9999-999999999999"),
WarehouseName = "中央廚房主倉",
ItemSku = "RM-FLOUR-001",
ItemName = "高筋麵粉",
Unit = "kg",
QuantityOnHand = 40,
SafetyStockQuantity = 50,
LastTransactionAt = DateTime.UtcNow
},
new LocalStockBalance
{
Id = Guid.Parse("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"),
WarehouseName = "直營一店倉",
ItemSku = "PKG-BAG-001",
ItemName = "吐司袋",
Unit = "個",
QuantityOnHand = 800,
SafetyStockQuantity = 500,
LastTransactionAt = DateTime.UtcNow
}
],
InventoryTransactions =
[
new LocalInventoryTransaction
{
Id = Guid.Parse("bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"),
TransactionNumber = "INV-20260525-001",
WarehouseName = "中央廚房主倉",
ItemSku = "RM-FLOUR-001",
ItemName = "高筋麵粉",
TransactionType = LocalInventoryTransactionType.GoodsReceipt,
Quantity = 40,
Unit = "kg",
Status = LocalInventoryTransactionStatus.Approved,
SourceDocumentNumber = "OCR-20260525-001",
Note = "範例進貨入庫",
OccurredAt = DateTime.UtcNow,
CreatedAt = DateTime.UtcNow,
ApprovedAt = DateTime.UtcNow
}
],
PurchaseOrders =
[
new LocalPurchaseOrder
{
Id = Guid.Parse("cccccccc-cccc-cccc-cccc-cccccccccccc"),
OrderNumber = "PO-20260525-001",
SupplierName = "範例麵粉供應商",
OrderDate = DateOnly.FromDateTime(DateTime.Today),
ItemSku = "RM-FLOUR-001",
ItemName = "高筋麵粉",
Quantity = 40,
Unit = "kg",
UnitPrice = 32,
Status = LocalPurchaseOrderStatus.Approved,
Note = "範例採購單",
CreatedAt = DateTime.UtcNow,
ApprovedAt = DateTime.UtcNow
}
],
PettyCashTransactions =
[
new LocalPettyCashTransaction
{
Id = Guid.Parse("dddddddd-dddd-dddd-dddd-dddddddddddd"),
TransactionNumber = "PC-20260525-001",
StoreName = "直營一店",
TransactionDate = DateOnly.FromDateTime(DateTime.Today),
TransactionType = LocalPettyCashTransactionType.Expense,
ExpenseCategory = "清潔用品",
Amount = 360,
Description = "門市臨時採買清潔用品",
Status = LocalPettyCashStatus.Approved,
CreatedAt = DateTime.UtcNow,
ApprovedAt = DateTime.UtcNow
}
],
TransferOrders =
[
new LocalTransferOrder
{
Id = Guid.Parse("eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee"),
TransferNumber = "TRF-20260525-001",
StoreName = "直營一店",
FromWarehouseName = "中央廚房主倉",
ToWarehouseName = "直營一店倉",
ItemSku = "PKG-BAG-001",
ItemName = "吐司袋",
RequestedQuantity = 200,
PreparedQuantity = 200,
ShippedQuantity = 200,
ReceivedQuantity = 0,
DifferenceQuantity = 0,
Unit = "個",
Status = LocalTransferStatus.InTransit,
RequestDate = DateOnly.FromDateTime(DateTime.Today),
CreatedAt = DateTime.UtcNow,
ShippedAt = DateTime.UtcNow
}
],
StoreReturns =
[
new LocalStoreReturn
{
Id = Guid.Parse("ffffffff-ffff-ffff-ffff-ffffffffffff"),
ReturnNumber = "RTN-20260525-001",
StoreName = "直營一店",
ItemSku = "PKG-BAG-001",
ItemName = "吐司袋",
Quantity = 20,
Unit = "個",
Reason = "破損",
ReturnDate = DateOnly.FromDateTime(DateTime.Today),
Status = LocalStoreReturnStatus.PendingCentralKitchenReview,
CreatedAt = DateTime.UtcNow
}
],
ReportDefinitions =
[
new LocalReportDefinition
{
Id = Guid.Parse("12121212-1212-1212-1212-121212121212"),
ReportCode = "RPT-INVENTORY",
ReportName = "即時庫存報表",
ReportCategory = "庫存",
Description = "輸出目前即時庫存、安全庫存與低庫存狀態。",
Status = LocalReportStatus.Approved,
CreatedAt = DateTime.UtcNow,
ApprovedAt = DateTime.UtcNow
}
],
};
}
public void EnsureSeedData()
{
if (Suppliers.Count == 0)
{
Suppliers = CreateSeed().Suppliers;
}
if (Items.Count == 0)
{
Items = CreateSeed().Items;
}
if (Stores.Count == 0)
{
Stores = CreateSeed().Stores;
}
if (Warehouses.Count == 0)
{
Warehouses = CreateSeed().Warehouses;
}
if (OcrDocuments.Count == 0)
{
OcrDocuments = CreateSeed().OcrDocuments;
}
if (StockBalances.Count == 0)
{
StockBalances = CreateSeed().StockBalances;
}
if (InventoryTransactions.Count == 0)
{
InventoryTransactions = CreateSeed().InventoryTransactions;
}
if (PurchaseOrders.Count == 0)
{
PurchaseOrders = CreateSeed().PurchaseOrders;
}
if (PettyCashTransactions.Count == 0)
{
PettyCashTransactions = CreateSeed().PettyCashTransactions;
}
if (TransferOrders.Count == 0)
{
TransferOrders = CreateSeed().TransferOrders;
}
if (StoreReturns.Count == 0)
{
StoreReturns = CreateSeed().StoreReturns;
}
if (ReportDefinitions.Count == 0)
{
ReportDefinitions = CreateSeed().ReportDefinitions;
}
}
}
public sealed class LocalSupplier
{
public Guid Id { get; set; }
public string Code { get; set; } = string.Empty;
public string Name { get; set; } = string.Empty;
public string? TaxId { get; set; }
public string? ContactName { get; set; }
public string? Phone { get; set; }
public string? Email { get; set; }
public string? Address { get; set; }
public int PaymentTermDays { get; set; } = 30;
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public DateTime? UpdatedAt { get; set; }
public bool IsActive { get; set; } = true;
}
public sealed class LocalItem
{
public Guid Id { get; set; }
public string Sku { get; set; } = string.Empty;
public string Name { get; set; } = string.Empty;
public LocalItemType ItemType { get; set; } = LocalItemType.RawMaterial;
public string CategoryName { get; set; } = string.Empty;
public string BaseUnit { get; set; } = string.Empty;
public decimal SafetyStockQuantity { get; set; }
public int? ShelfLifeDays { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public DateTime? UpdatedAt { get; set; }
public bool IsActive { get; set; } = true;
}
public enum LocalItemType
{
RawMaterial = 1,
SemiFinished = 2,
FinishedProduct = 3,
Packaging = 4,
ExpenseSupply = 5
}
public sealed class LocalStore
{
public Guid Id { get; set; }
public string Code { get; set; } = string.Empty;
public string Name { get; set; } = string.Empty;
public LocalStoreType StoreType { get; set; } = LocalStoreType.Direct;
public string? Phone { get; set; }
public string? Address { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public DateTime? UpdatedAt { get; set; }
public bool IsActive { get; set; } = true;
}
public enum LocalStoreType
{
Direct = 1,
Franchise = 2,
CentralKitchen = 3
}
public sealed class LocalWarehouse
{
public Guid Id { get; set; }
public string Code { get; set; } = string.Empty;
public string Name { get; set; } = string.Empty;
public string? StoreName { get; set; }
public LocalWarehouseType WarehouseType { get; set; } = LocalWarehouseType.Store;
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public DateTime? UpdatedAt { get; set; }
public bool IsActive { get; set; } = true;
}
public enum LocalWarehouseType
{
MainWarehouse = 1,
CentralKitchen = 2,
Store = 3
}
public sealed class LocalOcrDocument
{
public Guid Id { get; set; }
public string DocumentNumber { get; set; } = string.Empty;
public string FileName { get; set; } = string.Empty;
public string? SupplierName { get; set; }
public DateOnly? DocumentDate { get; set; }
public LocalOcrStatus Status { get; set; } = LocalOcrStatus.Uploaded;
public decimal? TotalAmount { get; set; }
public string? RawText { get; set; }
public string? RecognizedItems { get; set; }
public string? ReviewNote { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public DateTime? UpdatedAt { get; set; }
public DateTime? ReviewedAt { get; set; }
}
public enum LocalOcrStatus
{
Uploaded = 1,
Recognized = 2,
MappingRequired = 3,
Confirmed = 4,
ConvertedToReceipt = 5,
Failed = 9
}
public sealed class LocalStockBalance
{
public Guid Id { get; set; }
public string WarehouseName { get; set; } = string.Empty;
public string ItemSku { get; set; } = string.Empty;
public string ItemName { get; set; } = string.Empty;
public decimal QuantityOnHand { get; set; }
public string Unit { get; set; } = string.Empty;
public decimal SafetyStockQuantity { get; set; }
public DateTime LastTransactionAt { get; set; } = DateTime.UtcNow;
}
public sealed class LocalInventoryTransaction
{
public Guid Id { get; set; }
public string TransactionNumber { get; set; } = string.Empty;
public string WarehouseName { get; set; } = string.Empty;
public string ItemSku { get; set; } = string.Empty;
public string ItemName { get; set; } = string.Empty;
public LocalInventoryTransactionType TransactionType { get; set; } = LocalInventoryTransactionType.GoodsReceipt;
public decimal Quantity { get; set; }
public string Unit { get; set; } = string.Empty;
public LocalInventoryTransactionStatus Status { get; set; } = LocalInventoryTransactionStatus.Draft;
public string? SourceDocumentNumber { get; set; }
public string? Note { get; set; }
public DateTime OccurredAt { get; set; } = DateTime.UtcNow;
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public DateTime? UpdatedAt { get; set; }
public DateTime? ApprovedAt { get; set; }
}
public enum LocalInventoryTransactionType
{
GoodsReceipt = 1,
StockOut = 2,
StockAdjustment = 3,
Scrap = 4,
StoreReturn = 5
}
public enum LocalInventoryTransactionStatus
{
Draft = 1,
PendingApproval = 2,
Approved = 3,
Cancelled = 9
}
public sealed class LocalPurchaseOrder
{
public Guid Id { get; set; }
public string OrderNumber { get; set; } = string.Empty;
public string SupplierName { get; set; } = string.Empty;
public DateOnly OrderDate { get; set; } = DateOnly.FromDateTime(DateTime.Today);
public string ItemSku { get; set; } = string.Empty;
public string ItemName { get; set; } = string.Empty;
public decimal Quantity { get; set; }
public string Unit { get; set; } = string.Empty;
public decimal UnitPrice { get; set; }
public decimal LineAmount => Quantity * UnitPrice;
public LocalPurchaseOrderStatus Status { get; set; } = LocalPurchaseOrderStatus.Draft;
public string? Note { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public DateTime? UpdatedAt { get; set; }
public DateTime? ApprovedAt { get; set; }
public DateTime? ClosedAt { get; set; }
}
public enum LocalPurchaseOrderStatus
{
Draft = 1,
PendingApproval = 2,
Approved = 3,
MonthlyClosed = 4,
Cancelled = 9
}
public sealed class LocalPettyCashTransaction
{
public Guid Id { get; set; }
public string TransactionNumber { get; set; } = string.Empty;
public string StoreName { get; set; } = string.Empty;
public DateOnly TransactionDate { get; set; } = DateOnly.FromDateTime(DateTime.Today);
public LocalPettyCashTransactionType TransactionType { get; set; } = LocalPettyCashTransactionType.Expense;
public string ExpenseCategory { get; set; } = string.Empty;
public decimal Amount { get; set; }
public string? Description { get; set; }
public string? ReceiptImagePath { get; set; }
public LocalPettyCashStatus Status { get; set; } = LocalPettyCashStatus.Draft;
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public DateTime? UpdatedAt { get; set; }
public DateTime? ApprovedAt { get; set; }
public DateTime? ClosedAt { get; set; }
}
public enum LocalPettyCashTransactionType
{
Expense = 1,
Replenishment = 2,
Adjustment = 3
}
public enum LocalPettyCashStatus
{
Draft = 1,
PendingFinanceApproval = 2,
Approved = 3,
MonthlyClosed = 4,
Replenished = 5,
Rejected = 8,
Cancelled = 9
}
public sealed class LocalTransferOrder
{
public Guid Id { get; set; }
public string TransferNumber { get; set; } = string.Empty;
public string StoreName { get; set; } = string.Empty;
public string FromWarehouseName { get; set; } = string.Empty;
public string ToWarehouseName { get; set; } = string.Empty;
public string ItemSku { get; set; } = string.Empty;
public string ItemName { get; set; } = string.Empty;
public decimal RequestedQuantity { get; set; }
public decimal PreparedQuantity { get; set; }
public decimal ShippedQuantity { get; set; }
public decimal ReceivedQuantity { get; set; }
public decimal DifferenceQuantity { get; set; }
public string Unit { get; set; } = string.Empty;
public LocalTransferStatus Status { get; set; } = LocalTransferStatus.Draft;
public DateOnly RequestDate { get; set; } = DateOnly.FromDateTime(DateTime.Today);
public string? Note { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public DateTime? UpdatedAt { get; set; }
public DateTime? PreparedAt { get; set; }
public DateTime? ShippedAt { get; set; }
public DateTime? ReceivedAt { get; set; }
}
public enum LocalTransferStatus
{
Draft = 1,
StoreRequested = 2,
Prepared = 3,
InTransit = 4,
Completed = 5,
Discrepancy = 6,
Cancelled = 9
}
public sealed class LocalStoreReturn
{
public Guid Id { get; set; }
public string ReturnNumber { get; set; } = string.Empty;
public string StoreName { get; set; } = string.Empty;
public string ItemSku { get; set; } = string.Empty;
public string ItemName { get; set; } = string.Empty;
public decimal Quantity { get; set; }
public string Unit { get; set; } = string.Empty;
public string Reason { get; set; } = string.Empty;
public string? PhotoPath { get; set; }
public DateOnly ReturnDate { get; set; } = DateOnly.FromDateTime(DateTime.Today);
public LocalStoreReturnStatus Status { get; set; } = LocalStoreReturnStatus.Draft;
public LocalStoreReturnDisposition? Disposition { get; set; }
public string? ReviewNote { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public DateTime? UpdatedAt { get; set; }
public DateTime? ReviewedAt { get; set; }
public DateTime? DisposedAt { get; set; }
}
public enum LocalStoreReturnStatus
{
Draft = 1,
PendingCentralKitchenReview = 2,
Approved = 3,
Rejected = 4,
Disposed = 5,
Cancelled = 9
}
public enum LocalStoreReturnDisposition
{
Restock = 1,
Scrap = 2,
ReturnToSupplier = 3
}
public sealed class LocalReportDefinition
{
public Guid Id { get; set; }
public string ReportCode { get; set; } = string.Empty;
public string ReportName { get; set; } = string.Empty;
public string ReportCategory { get; set; } = string.Empty;
public string? Description { get; set; }
public LocalReportStatus Status { get; set; } = LocalReportStatus.Draft;
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public DateTime? UpdatedAt { get; set; }
public DateTime? ApprovedAt { get; set; }
}
public enum LocalReportStatus
{
Draft = 1,
PendingApproval = 2,
Approved = 3,
Cancelled = 9
}