arolariu.Backend.Domain.Invoices.DDD.AggregatorRoots.Invoices
arolariu.Backend.Domain.Invoices
arolariu.Backend.Domain.Invoices.DDD.AggregatorRoots.Invoices Namespace
Classes
Invoice Class
Represents the invoice aggregate root controlling line items, merchant linkage, payment details, scan data, AI enrichment artifacts (recipes, categorization) and arbitrary extensible metadata within the bounded invoices context.
public sealed class Invoice : arolariu.Backend.Common.DDD.Contracts.NamedEntity<System.Guid>
Inheritance System.Object 🡒 arolariu.Backend.Common.DDD.Contracts.BaseEntity<System.Guid> 🡒 arolariu.Backend.Common.DDD.Contracts.NamedEntity<System.Guid> 🡒 Invoice
Remarks
This aggregate encapsulates the canonical mutable state of an invoice. Identity (id) is immutable (Version 7 GUID) and is never reassigned.
Collections (Items, PossibleRecipes, SharedWith) preserve insertion order and allow duplicates. There is currently
no de-duplication or concurrency token; last writer wins on updates. Future optimization may introduce distinct filtering.
Soft Delete Lifecycle: When soft-deleted at the storage layer, the invoice and each contained product are marked; queries exclude soft-deleted entities unless explicitly overridden. See service layer deletion logic for cascade behavior.
Sentinel Defaults:Guid.Empty for UserIdentifier and MerchantReference, InvoiceCategory.NOT_DEFINED for Category,
and InvoiceScan.Default() for Scans indicate an unenriched or unlinked state. These SHOULD be replaced by upstream enrichment / user input
flows prior to final analytical usage.
Merge Semantics: See Merge(Invoice, Invoice) for partial update precedence rules.
Thread-safety: Not thread-safe. Do not share instances across threads without external synchronization.
Properties
Invoice.AdditionalMetadata Property
The invoice additional metadata. This metadata is used to store additional information about the invoice. Metadata is used to generate the invoice statistics.
public System.Collections.Generic.IDictionary<string,object> AdditionalMetadata { get; set; }
Property Value
System.Collections.Generic.IDictionary<System.String,System.Object>
Invoice.Category Property
The invoice category.
public arolariu.Backend.Domain.Invoices.DDD.AggregatorRoots.Invoices.InvoiceCategory Category { get; set; }
Property Value
Invoice.CountryRegion Property
Country or region where the receipt was issued (ISO code).
public string CountryRegion { get; set; }
Property Value
Remarks
Extracted from the CountryRegion field of the prebuilt-receipt model.
Invoice.id Property
Gets or initializes the unique identifier for this entity. This property serves as the primary key and must be unique within the entity's context.
public override System.Guid id { get; init; }
Property Value
System.Guid
The entity's unique identifier of type T.
Can be null for new entities that haven't been persisted yet.
Once set, the identifier is immutable to maintain entity identity integrity.
Remarks
The identifier property follows specific conventions:
- Uses lowercase 'id' for Cosmos DB compatibility requirements
- Marked as virtual to allow derived classes to override with specific initialization logic
- Ordered first in JSON serialization for consistent API responses
- Suppresses naming style warnings due to data store constraints
Common identifier types:
- System.Guid: Recommended for distributed systems and global uniqueness
- System.Int32: Suitable for sequential, auto-incrementing scenarios
- System.String: Used for natural keys or external system identifiers
Invoice.Items Property
The invoice 1:*? - item relationship.
public System.Collections.Generic.ICollection<arolariu.Backend.Domain.Invoices.DDD.ValueObjects.Products.Product> Items { get; set; }
Property Value
System.Collections.Generic.ICollection<Product>
Invoice.MerchantReference Property
The invoice's possible merchant relationship.
public System.Guid MerchantReference { get; set; }
Property Value
Invoice.PaymentInformation Property
Payment information (currency, total amount, total tax).
public arolariu.Backend.Domain.Invoices.DDD.ValueObjects.PaymentInformation PaymentInformation { get; set; }
Property Value
Invoice.Payments Property
Payment methods and amounts used to settle the transaction.
public System.Collections.Generic.ICollection<arolariu.Backend.Domain.Invoices.DDD.ValueObjects.PaymentDetail> Payments { get; set; }
Property Value
System.Collections.Generic.ICollection<PaymentDetail>
Remarks
Supports multiple payment methods per receipt (e.g., split payment with cash + card).
Supplements the PaymentInformation.PaymentType with granular per-method amounts.
Invoice.PossibleRecipes Property
Possible recipes for the invoice.
public System.Collections.Generic.ICollection<arolariu.Backend.Domain.Invoices.DDD.ValueObjects.Recipe> PossibleRecipes { get; set; }
Property Value
System.Collections.Generic.ICollection<Recipe>
Invoice.ReceiptType Property
Receipt type as classified by Document Intelligence (e.g., "Itemized", "Meal", "Gas", "Parking", "Hotel").
public string ReceiptType { get; set; }
Property Value
Remarks
Extracted from the ReceiptType field of the prebuilt-receipt model. Empty when not determined.
Invoice.Scans Property
The invoice scan value object.
public System.Collections.Generic.ICollection<arolariu.Backend.Domain.Invoices.DDD.AggregatorRoots.Invoices.InvoiceScan> Scans { get; init; }
Property Value
System.Collections.Generic.ICollection<InvoiceScan>
Invoice.SharedWith Property
The list of users that have access to this invoice.
public System.Collections.Generic.ICollection<System.Guid> SharedWith { get; init; }
Property Value
System.Collections.Generic.ICollection<System.Guid>
Invoice.TaxDetails Property
Structured tax breakdown extracted from the receipt.
public System.Collections.Generic.ICollection<arolariu.Backend.Domain.Invoices.DDD.ValueObjects.TaxDetail> TaxDetails { get; set; }
Property Value
System.Collections.Generic.ICollection<TaxDetail>
Remarks
Contains individual tax lines with amount, rate, net amount, and description.
Supplements the flat PaymentInformation.TotalTaxAmount with granular detail.
Invoice.UserIdentifier Property
The invoice 1:1 user relationship (owner).
public System.Guid UserIdentifier { get; set; }
Property Value
Methods
Invoice.Default() Method
Factory producing a new invoice aggregate initialized with sentinel defaults.
internal static arolariu.Backend.Domain.Invoices.DDD.AggregatorRoots.Invoices.Invoice Default();
Returns
Invoice
A new Invoice instance with immutable identity and sentinel defaults.
Remarks
Assigned identity is a Version 7 GUID for chronological ordering. All relationship references and enrichment fields are initialized to sentinel states (see aggregate remarks). This method does not persist the entity.
Use this factory when constructing a brand new invoice prior to population via OCR / AI enrichment or user-submitted metadata.
Invoice.Merge(Invoice, Invoice) Method
Produces a new invoice aggregate representing a non-destructive merge of an original invoice and a set of partial updates.
internal static arolariu.Backend.Domain.Invoices.DDD.AggregatorRoots.Invoices.Invoice Merge(arolariu.Backend.Domain.Invoices.DDD.AggregatorRoots.Invoices.Invoice original, arolariu.Backend.Domain.Invoices.DDD.AggregatorRoots.Invoices.Invoice partialUpdates);
Parameters
original Invoice
The persisted (authoritative) invoice snapshot.
partialUpdates Invoice
A partially populated invoice carrying candidate replacement values.
Returns
Invoice
A new Invoice representing the merged state.
Remarks
Identity: The original id is preserved.
Precedence Rules: A field in partialUpdates replaces the original when it is non-sentinel / non-empty;
otherwise the original value is retained. Collections are concatenated (original first unless otherwise stated) without de-duplication.
NumberOfUpdates is incremented. LastUpdatedAt is set to System.DateTime.UtcNow.
| Field | Partial Considered Non-Default When | Merge Behavior | Notes |
|---|---|---|---|
Side Effects: Original instances are left unmodified (pure functional merge). Returned instance has updated
audit counters (NumberOfUpdates, LastUpdatedAt).
Thread-safety: Not thread-safe; callers must ensure exclusive access to original references during merge decision workflow.
Invoice.NotDefault(Invoice) Method
Internal method to determine whether an invoice instance is non-default (i.e., has at least one field set to a non-sentinel value).
internal static bool NotDefault(arolariu.Backend.Domain.Invoices.DDD.AggregatorRoots.Invoices.Invoice invoice);
Parameters
invoice Invoice
Returns
Invoice.PerformUpdate(Guid) Method
Performs an update operation on the current object or its state.
public void PerformUpdate(System.Guid updatedById);
Parameters
updatedById System.Guid
Structs
InvoiceScan Struct
The InvoiceScan DTO class represents the invoice scan data transfer object. This object is used to transfer the invoice scan data from the client to the server.
public readonly record struct InvoiceScan : System.IEquatable<arolariu.Backend.Domain.Invoices.DDD.AggregatorRoots.Invoices.InvoiceScan>
Implements System.IEquatable<InvoiceScan>
Constructors
InvoiceScan(ScanType, Uri, IDictionary<string,object>) Constructor
The InvoiceScan DTO class represents the invoice scan data transfer object. This object is used to transfer the invoice scan data from the client to the server.
public InvoiceScan(arolariu.Backend.Domain.Invoices.DDD.AggregatorRoots.Invoices.ScanType Type, System.Uri Location, System.Collections.Generic.IDictionary<string,object>? Metadata);
Parameters
Type ScanType
Location System.Uri
Metadata System.Collections.Generic.IDictionary<System.String,System.Object>
Properties
InvoiceScan.Location Property
public System.Uri Location { get; init; }
Property Value
InvoiceScan.Metadata Property
public System.Collections.Generic.IDictionary<string,object>? Metadata { get; init; }
Property Value
System.Collections.Generic.IDictionary<System.String,System.Object>
InvoiceScan.Type Property
public arolariu.Backend.Domain.Invoices.DDD.AggregatorRoots.Invoices.ScanType Type { get; init; }
Property Value
Methods
InvoiceScan.Default() Method
Static method to create a new instance of the InvoiceScan with default values.
public static arolariu.Backend.Domain.Invoices.DDD.AggregatorRoots.Invoices.InvoiceScan Default();
Returns
InvoiceScan.NotDefault(InvoiceScan) Method
Static method to determine if the scan is not new (i.e. has been set to something else than the default values).
public static bool NotDefault(arolariu.Backend.Domain.Invoices.DDD.AggregatorRoots.Invoices.InvoiceScan scan);
Parameters
scan InvoiceScan
Returns
Enums
InvoiceCategory Enum
Classifies the high-level domain purpose / composition of an invoice for analytics, enrichment heuristics and UI grouping.
public enum InvoiceCategory
Fields
NOT_DEFINED 0
Sentinel; category not yet assigned (pre-enrichment / pre-classification state).
GROCERY 100
Predominantly household food / consumable products (general pantry and grocery analytics).
FAST_FOOD 200
Prepared or takeaway-oriented fast food items (low / no home preparation).
HOME_CLEANING 300
Household cleaning / maintenance and related chemical products and supplies.
CAR_AUTO 400
Automotive parts, consumables or service-related line items.
OTHER 9999
Fallback when an invoice does not map to any defined domain category; minimize long-term usage.
Remarks
Extensibility: Maintain numeric spacing (increments of 100) when adding new concrete categories to preserve stable ordering for downstream analytical exports.
Sentinel:NOT_DEFINED denotes an invoice whose category has not yet been user-assigned or AI-enriched and SHOULD be transient.
Usage: Category influences recipe suggestion relevance, allergen aggregation and future budgeting dashboards.
Thread-safety: Enum is immutable and inherently thread-safe.
ScanType Enum
The scan type enum represents the type of scan.
public enum ScanType
Fields
JPG 0
JPG format.
JPEG 1
JPEG format.
PNG 2
PNG format.
PDF 3
PDF format.
OTHER 4
Other format.
UNKNOWN 5
Unknown format.