using bnhtrade.Core.Logic.Validate; using bnhtrade.Core.Model.Account; using FikaAmazonAPI.AmazonSpApiSDK.Models.FulfillmentInboundv20240320; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using System.Threading.Tasks; namespace bnhtrade.Core.Model.Stock { public class StockJournal : IValidatableObject { public StockJournal(int stockJournalId, StockJournalType stockJournalType, int stockId, string stockNumber, DateTime entryDate, DateTime postDate, DateTime lastModified, bool isLocked, List journalPosts) { StockJournalId = stockJournalId; StockJournalType = stockJournalType; StockId = stockId; StockNumber = stockNumber; EntryDate = entryDate; PostDate = postDate; LastModified = lastModified; IsLocked = isLocked; StockJournalPosts = journalPosts ?? throw new ArgumentNullException(nameof(journalPosts), "Journal posts cannot be null."); } [Required()] [Range(1, int.MaxValue, ErrorMessage = "StockJournalId must be greater than 0.")] public int StockJournalId { get; } public StockJournalType StockJournalType { get; } [Required()] [Range(1, int.MaxValue, ErrorMessage = "StockId must be greater than 0.")] public int StockId { get; } [Required(ErrorMessage = "Stock number is required.")] public string StockNumber { get; } public DateTime EntryDate { get; } public DateTime PostDate { get; } public DateTime LastModified { get; } public bool IsLocked { get; } public List StockJournalPosts { get; } public class StockJournalPost : IValidatableObject { public StockJournalPost(int journalPostId, Status status, int quantity) { StockJournalPostId = journalPostId; Status = status; Quantity = quantity; } public int StockJournalPostId { get; } [Required()] public Status Status { get; } [Required()] public int Quantity { get; } public bool IsCredit { get { if (Quantity < 0) { return true; } else if (Quantity > 0) { return false; } else { throw new InvalidOperationException("Quantity cannot be zero for a journal post."); } } } public bool IsDebit { get { return !IsCredit; } } public IEnumerable Validate(ValidationContext validationContext) { var validationResults = new List(); if (Quantity == 0) { validationResults.Add(new ValidationResult("Quantity cannot be zero for a journal post.", new[] { nameof(Quantity) })); } return validationResults; } } public IEnumerable Validate(ValidationContext validationContext) { var validationResults = new List(); // dates are in UTC format if (EntryDate.Kind != DateTimeKind.Utc || EntryDate == default(DateTime)) { validationResults.Add(new ValidationResult("Entry Date must be in UTC format and not a default value.", new[] { nameof(EntryDate) })); } if (PostDate.Kind != DateTimeKind.Utc || PostDate == default(DateTime)) { validationResults.Add(new ValidationResult("PostDate must be in UTC format and not a default value.", new[] { nameof(PostDate) })); } if (LastModified.Kind != DateTimeKind.Utc || LastModified == default(DateTime)) { validationResults.Add(new ValidationResult("LastModified must be in UTC format and not a default value.", new[] { nameof(LastModified) })); } if (Format.StockNumber(StockNumber) == false) { validationResults.Add(new ValidationResult("StockNumber must be in the format 'STK#000000'.", new[] { nameof(StockNumber) })); } // Validate each StockJournalPost using its own context and Validate method int sum = 0; for (int i = 0; i < StockJournalPosts.Count; i++) { sum += StockJournalPosts[i].Quantity; var post = StockJournalPosts[i]; var postContext = new ValidationContext(post, validationContext, validationContext.Items); foreach (var result in post.Validate(postContext)) { // Prefix property name with the index for clarity var memberNames = result.MemberNames.Select(name => $"StockJournalPosts[{i}].{name}"); validationResults.Add(new ValidationResult(result.ErrorMessage, memberNames)); } } if (sum != 0) { validationResults.Add(new ValidationResult("The sum of all journal posts must equal zero.", new[] { nameof(StockJournalPosts) })); } return validationResults; } } }