diff --git a/src/bnhtrade.Core/Logic/Validate/Format.cs b/src/bnhtrade.Core/Logic/Validate/Format.cs
index 989b485..0fc5a90 100644
--- a/src/bnhtrade.Core/Logic/Validate/Format.cs
+++ b/src/bnhtrade.Core/Logic/Validate/Format.cs
@@ -45,6 +45,20 @@ namespace bnhtrade.Core.Logic.Validate
return true;
}
+ ///
+ /// Validates that a stock number string is in the format 'STK#000000' (six digits).
+ ///
+ ///
+ ///
+ public static bool StockNumber(string stockNumber)
+ {
+ if (string.IsNullOrEmpty(stockNumber))
+ return false;
+
+ // Check for exact match: STK# followed by 6 digits
+ return System.Text.RegularExpressions.Regex.IsMatch(stockNumber, @"^STK#\d{6}$");
+ }
+
///
/// Checks the datetime is not default and is utc
///
diff --git a/src/bnhtrade.Core/Model/Stock/StockJournal.cs b/src/bnhtrade.Core/Model/Stock/StockJournal.cs
index 8627a67..d64ce43 100644
--- a/src/bnhtrade.Core/Model/Stock/StockJournal.cs
+++ b/src/bnhtrade.Core/Model/Stock/StockJournal.cs
@@ -1,4 +1,7 @@
-using System;
+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;
@@ -9,7 +12,7 @@ namespace bnhtrade.Core.Model.Stock
{
public class StockJournal : IValidatableObject
{
- public StockJournal(int stockJournalId, StockJournalType stockJournalType, int stockId, int stockNumber, DateTime entryDate, DateTime postDate, DateTime lastModified, bool isLocked, List journalPosts)
+ public StockJournal(int stockJournalId, StockJournalType stockJournalType, int stockId, string stockNumber, DateTime entryDate, DateTime postDate, DateTime lastModified, bool isLocked, List journalPosts)
{
StockJournalId = stockJournalId;
StockJournalType = stockJournalType;
@@ -19,16 +22,21 @@ namespace bnhtrade.Core.Model.Stock
PostDate = postDate;
LastModified = lastModified;
IsLocked = isLocked;
- JournalPosts = journalPosts ?? throw new ArgumentNullException(nameof(journalPosts), "Journal posts cannot be null.");
+ 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; }
- public int StockNumber { get; }
+ [Required(ErrorMessage = "Stock number is required.")]
+ public string StockNumber { get; }
public DateTime EntryDate { get; }
@@ -38,18 +46,17 @@ namespace bnhtrade.Core.Model.Stock
public bool IsLocked { get; }
- public List JournalPosts { get; }
+ public List StockJournalPosts { get; }
- public class JournalPost
+ public class StockJournalPost : IValidatableObject
{
- public JournalPost(int journalPostId, Status status, int quantity)
+ public StockJournalPost(int journalPostId, Status status, int quantity)
{
- JournalPostId = journalPostId;
+ StockJournalPostId = journalPostId;
Status = status;
Quantity = quantity;
}
-
- public int JournalPostId { get; }
+ public int StockJournalPostId { get; }
[Required()]
public Status Status { get; }
@@ -94,12 +101,64 @@ namespace bnhtrade.Core.Model.Stock
}
}
}
+
+ 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)
{
- throw new NotImplementedException();
- }
+ 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;
+ }
}
}