Files
bnhtrade/src/bnhtrade.Core/Model/Stock/StockJournal.cs
T
2025-07-14 20:28:40 +01:00

154 lines
5.6 KiB
C#

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<StockJournalPost> 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<StockJournalPost> 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<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)
{
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;
}
}
}