namespace LibraryApp.Domain.Entities; public class LendRecord { public LendRecordId Id { get; private set; } public BookInstanceId BookInstanceId { get; private set; } public MemberId MemberId { get; private set; } public LendCode Code { get; private set; } public DateTime LendDate { get; private set; } public DateTime? ReturnDate { get; private set; } public LendRecord(BookInstanceId bookInstanceId, MemberId memberId, LendCode code) : this(new LendRecordId(string.Empty), bookInstanceId, memberId, code, DateTime.UtcNow, null) { } public LendRecord(LendRecordId id, BookInstanceId bookInstanceId, MemberId memberId, LendCode code, DateTime lendDate, DateTime? returnDate) { Id = id; BookInstanceId = bookInstanceId; MemberId = memberId; Code = code; LendDate = lendDate; ReturnDate = returnDate; } public LendRecord MarkAsReturned() { if(ReturnDate != null) throw new InvalidOperationException("This lend record is already marked as returned."); ReturnDate = DateTime.UtcNow; return this; } public LendRecord UpdateLendDate(DateTime newLendDate) { if(ReturnDate != null) throw new InvalidOperationException("Cannot update lend date for a record that is already marked as returned."); LendDate = newLendDate; return this; } public LendRecord UnmarkAsReturned() { if(ReturnDate == null) throw new InvalidOperationException("This lend record is not marked as returned."); ReturnDate = null; return this; } } public record LendRecordId : DbId { public LendRecordId(string id) : base(id) {} } /// /// A short, human-friendly code written on the physical lend slip alongside the member's name. /// Must be unique per lend record and no longer than 8 characters. /// public record LendCode { public string Code { get; init; } public LendCode(string code) { if (string.IsNullOrWhiteSpace(code)) throw new ArgumentException("Lend code cannot be empty."); if (code.Length > 8) throw new ArgumentException("Lend code cannot exceed 8 characters."); Code = code.ToUpperInvariant(); } }