Initial commit

This commit is contained in:
2026-04-23 21:38:24 -04:00
commit 63e12a9636
1762 changed files with 1672620 additions and 0 deletions
@@ -0,0 +1,164 @@
using System.ComponentModel.DataAnnotations;
namespace PowderCoating.Application.DTOs.Catalog
{
/// <summary>
/// DTO for displaying detailed catalog item information.
/// </summary>
public class CatalogItemDto
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public string? Description { get; set; }
public string? SKU { get; set; }
public int CategoryId { get; set; }
public string CategoryName { get; set; } = string.Empty;
public string FullCategoryPath { get; set; } = string.Empty;
public decimal DefaultPrice { get; set; }
public bool DefaultRequiresSandblasting { get; set; }
public bool DefaultRequiresMasking { get; set; }
public int? DefaultEstimatedMinutes { get; set; }
public decimal? ApproximateArea { get; set; }
public int DisplayOrder { get; set; }
public bool IsActive { get; set; }
[Display(Name = "Revenue Account")]
public int? RevenueAccountId { get; set; }
public string? RevenueAccountName { get; set; }
[Display(Name = "COGS Account")]
public int? CogsAccountId { get; set; }
public string? CogsAccountName { get; set; }
}
/// <summary>
/// DTO for displaying catalog items in list/grid views.
/// Contains only essential fields for performance.
/// </summary>
public class CatalogItemListDto
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public string? SKU { get; set; }
public string CategoryName { get; set; } = string.Empty;
public decimal DefaultPrice { get; set; }
public bool IsActive { get; set; }
}
/// <summary>
/// DTO for creating a new catalog item.
/// </summary>
public class CreateCatalogItemDto
{
[Required(ErrorMessage = "Item name is required")]
[StringLength(200, ErrorMessage = "Item name cannot exceed 200 characters")]
[Display(Name = "Item Name")]
public string Name { get; set; } = string.Empty;
[StringLength(1000, ErrorMessage = "Description cannot exceed 1000 characters")]
[Display(Name = "Description")]
public string? Description { get; set; }
[StringLength(50, ErrorMessage = "SKU cannot exceed 50 characters")]
[Display(Name = "SKU / Item Code")]
public string? SKU { get; set; }
[Required(ErrorMessage = "Category is required")]
[Display(Name = "Category")]
public int CategoryId { get; set; }
[Required(ErrorMessage = "Default price is required")]
[Range(0, 100000, ErrorMessage = "Price must be between $0 and $100,000")]
[Display(Name = "Default Price")]
[DataType(DataType.Currency)]
public decimal DefaultPrice { get; set; }
[Display(Name = "Requires Sandblasting")]
public bool DefaultRequiresSandblasting { get; set; }
[Display(Name = "Requires Masking/Taping")]
public bool DefaultRequiresMasking { get; set; }
[Range(1, 10000, ErrorMessage = "Estimated minutes must be between 1 and 10,000")]
[Display(Name = "Estimated Minutes")]
public int? DefaultEstimatedMinutes { get; set; }
[Range(0.01, 100000, ErrorMessage = "Area must be between 0.01 and 100,000")]
[Display(Name = "Approximate Area")]
public decimal? ApproximateArea { get; set; }
[Display(Name = "Display Order")]
[Range(0, 9999, ErrorMessage = "Display order must be between 0 and 9999")]
public int DisplayOrder { get; set; }
[Display(Name = "Revenue Account")]
public int? RevenueAccountId { get; set; }
[Display(Name = "COGS Account")]
public int? CogsAccountId { get; set; }
[Display(Name = "Available for direct sale (merchandise)")]
public bool IsMerchandise { get; set; }
}
/// <summary>
/// DTO for updating an existing catalog item.
/// </summary>
public class UpdateCatalogItemDto
{
public int Id { get; set; }
[Required(ErrorMessage = "Item name is required")]
[StringLength(200, ErrorMessage = "Item name cannot exceed 200 characters")]
[Display(Name = "Item Name")]
public string Name { get; set; } = string.Empty;
[StringLength(1000, ErrorMessage = "Description cannot exceed 1000 characters")]
[Display(Name = "Description")]
public string? Description { get; set; }
[StringLength(50, ErrorMessage = "SKU cannot exceed 50 characters")]
[Display(Name = "SKU / Item Code")]
public string? SKU { get; set; }
[Required(ErrorMessage = "Category is required")]
[Display(Name = "Category")]
public int CategoryId { get; set; }
[Required(ErrorMessage = "Default price is required")]
[Range(0, 100000, ErrorMessage = "Price must be between $0 and $100,000")]
[Display(Name = "Default Price")]
[DataType(DataType.Currency)]
public decimal DefaultPrice { get; set; }
[Display(Name = "Requires Sandblasting")]
public bool DefaultRequiresSandblasting { get; set; }
[Display(Name = "Requires Masking/Taping")]
public bool DefaultRequiresMasking { get; set; }
[Range(1, 10000, ErrorMessage = "Estimated minutes must be between 1 and 10,000")]
[Display(Name = "Estimated Minutes")]
public int? DefaultEstimatedMinutes { get; set; }
[Range(0.01, 100000, ErrorMessage = "Area must be between 0.01 and 100,000")]
[Display(Name = "Approximate Area")]
public decimal? ApproximateArea { get; set; }
[Display(Name = "Display Order")]
[Range(0, 9999, ErrorMessage = "Display order must be between 0 and 9999")]
public int DisplayOrder { get; set; }
[Display(Name = "Is Active")]
public bool IsActive { get; set; }
[Display(Name = "Revenue Account")]
public int? RevenueAccountId { get; set; }
[Display(Name = "COGS Account")]
public int? CogsAccountId { get; set; }
[Display(Name = "Available for direct sale (merchandise)")]
public bool IsMerchandise { get; set; }
}
}
@@ -0,0 +1,83 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace PowderCoating.Application.DTOs.Catalog
{
/// <summary>
/// DTO for displaying catalog category information.
/// </summary>
public class CategoryDto
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public string? Description { get; set; }
public int? ParentCategoryId { get; set; }
public string? ParentCategoryName { get; set; }
public int DisplayOrder { get; set; }
public bool IsActive { get; set; }
public int ItemCount { get; set; }
public int SubCategoryCount { get; set; }
}
/// <summary>
/// DTO for representing category hierarchy as a tree structure.
/// Used for tree views and navigation.
/// </summary>
public class CategoryTreeDto
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public int ItemCount { get; set; }
public List<CategoryTreeDto> Children { get; set; } = new();
public bool HasItems { get; set; }
}
/// <summary>
/// DTO for creating a new catalog category.
/// </summary>
public class CreateCategoryDto
{
[Required(ErrorMessage = "Category name is required")]
[StringLength(100, ErrorMessage = "Category name cannot exceed 100 characters")]
[Display(Name = "Category Name")]
public string Name { get; set; } = string.Empty;
[StringLength(500, ErrorMessage = "Description cannot exceed 500 characters")]
[Display(Name = "Description")]
public string? Description { get; set; }
[Display(Name = "Parent Category")]
public int? ParentCategoryId { get; set; }
[Display(Name = "Display Order")]
[Range(0, 9999, ErrorMessage = "Display order must be between 0 and 9999")]
public int DisplayOrder { get; set; }
}
/// <summary>
/// DTO for updating an existing catalog category.
/// </summary>
public class UpdateCategoryDto
{
public int Id { get; set; }
[Required(ErrorMessage = "Category name is required")]
[StringLength(100, ErrorMessage = "Category name cannot exceed 100 characters")]
[Display(Name = "Category Name")]
public string Name { get; set; } = string.Empty;
[StringLength(500, ErrorMessage = "Description cannot exceed 500 characters")]
[Display(Name = "Description")]
public string? Description { get; set; }
[Display(Name = "Parent Category")]
public int? ParentCategoryId { get; set; }
[Display(Name = "Display Order")]
[Range(0, 9999, ErrorMessage = "Display order must be between 0 and 9999")]
public int DisplayOrder { get; set; }
[Display(Name = "Is Active")]
public bool IsActive { get; set; }
}
}