This commit is contained in:
2025-07-11 11:52:31 +01:00
parent be9944f066
commit afd4bae10e
2 changed files with 85 additions and 12 deletions

View File

@@ -45,6 +45,20 @@ namespace bnhtrade.Core.Logic.Validate
return true; return true;
} }
/// <summary>
/// Validates that a stock number string is in the format 'STK#000000' (six digits).
/// </summary>
/// <param name="stockNumber"></param>
/// <returns></returns>
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}$");
}
/// <summary> /// <summary>
/// Checks the datetime is not default and is utc /// Checks the datetime is not default and is utc
/// </summary> /// </summary>

View File

@@ -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.Collections.Generic;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Linq; using System.Linq;
@@ -9,7 +12,7 @@ namespace bnhtrade.Core.Model.Stock
{ {
public class StockJournal : IValidatableObject public class StockJournal : IValidatableObject
{ {
public StockJournal(int stockJournalId, StockJournalType stockJournalType, int stockId, int stockNumber, DateTime entryDate, DateTime postDate, DateTime lastModified, bool isLocked, List<JournalPost> journalPosts) public StockJournal(int stockJournalId, StockJournalType stockJournalType, int stockId, string stockNumber, DateTime entryDate, DateTime postDate, DateTime lastModified, bool isLocked, List<StockJournalPost> journalPosts)
{ {
StockJournalId = stockJournalId; StockJournalId = stockJournalId;
StockJournalType = stockJournalType; StockJournalType = stockJournalType;
@@ -19,16 +22,21 @@ namespace bnhtrade.Core.Model.Stock
PostDate = postDate; PostDate = postDate;
LastModified = lastModified; LastModified = lastModified;
IsLocked = isLocked; 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 int StockJournalId { get; }
public StockJournalType StockJournalType { get; } public StockJournalType StockJournalType { get; }
[Required()]
[Range(1, int.MaxValue, ErrorMessage = "StockId must be greater than 0.")]
public int StockId { get; } public int StockId { get; }
public int StockNumber { get; } [Required(ErrorMessage = "Stock number is required.")]
public string StockNumber { get; }
public DateTime EntryDate { get; } public DateTime EntryDate { get; }
@@ -38,18 +46,17 @@ namespace bnhtrade.Core.Model.Stock
public bool IsLocked { get; } public bool IsLocked { get; }
public List<JournalPost> JournalPosts { get; } public List<StockJournalPost> 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; Status = status;
Quantity = quantity; Quantity = quantity;
} }
public int StockJournalPostId { get; }
public int JournalPostId { get; }
[Required()] [Required()]
public Status Status { get; } public Status Status { get; }
@@ -94,12 +101,64 @@ namespace bnhtrade.Core.Model.Stock
} }
} }
} }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var validationResults = new List<ValidationResult>();
if (Quantity == 0)
{
validationResults.Add(new ValidationResult("Quantity cannot be zero for a journal post.", new[] { nameof(Quantity) }));
}
return validationResults;
}
} }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{ {
throw new NotImplementedException(); var validationResults = new List<ValidationResult>();
// 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;
}
} }
} }