Skip to main content

arolariu.Backend.Domain.Invoices.DTOs.Requests

arolariu.Backend.Domain.Invoices

arolariu.Backend.Domain.Invoices.DTOs.Requests Namespace

Structs

AddMerchantToInvoiceRequestDto Struct

Request DTO for creating and associating a new merchant with an invoice.

public readonly record struct AddMerchantToInvoiceRequestDto : System.IEquatable<arolariu.Backend.Domain.Invoices.DTOs.Requests.AddMerchantToInvoiceRequestDto>

Implements System.IEquatable<AddMerchantToInvoiceRequestDto>

Example

var request = new AddMerchantToInvoiceRequestDto(
Name: "Kaufland Iasi Pacurari",
Description: "Hypermarket in Iasi, open 07:00-22:00",
Category: MerchantCategory.GROCERY,
Address: new ContactInformation { City = "Iasi", Country = "Romania" },
ParentCompanyId: parentCompanyGuid);

var merchant = request.ToMerchant();
await invoiceService.AddMerchantToInvoiceAsync(invoiceId, merchant);

Remarks

Purpose: Creates a new merchant entity and immediately associates it with an invoice in a single atomic operation. Useful when processing invoices from previously unknown merchants.

Immutability: This is a readonly record struct ensuring thread-safety and value semantics for equality comparisons.

Precondition: The target invoice must not already have a merchant reference. Attempting to add a merchant to an invoice that already has one will result in a conflict error.

Hierarchical Structure: Merchants can optionally belong to a parent company (e.g., individual store locations under a franchise brand).

See Also

Constructors

AddMerchantToInvoiceRequestDto(string, string, MerchantCategory, ContactInformation, Nullable<Guid>) Constructor

Request DTO for creating and associating a new merchant with an invoice.

public AddMerchantToInvoiceRequestDto(string Name, string Description, arolariu.Backend.Domain.Invoices.DDD.Entities.Merchants.MerchantCategory Category, arolariu.Backend.Common.DDD.ValueObjects.ContactInformation? Address, System.Nullable<System.Guid> ParentCompanyId);

Parameters

Name System.String

The merchant's display name. Required. Typically the store or business name (e.g., "Kaufland Iasi Pacurari").

Description System.String

A detailed description of the merchant. Required. May include operating hours, specialties, or other relevant information.

Category MerchantCategory

The merchant category classification (e.g., Grocery, Restaurant, Pharmacy). Defaults to NOT_DEFINED if not specified.

Address arolariu.Backend.Common.DDD.ValueObjects.ContactInformation

Optional structured contact and address information including street, city, postal code, country, phone, and email.

ParentCompanyId System.Nullable<System.Guid>

Optional reference to a parent company merchant ID for franchise/chain stores. Null if the merchant is independent or the parent is unknown.

Example

var request = new AddMerchantToInvoiceRequestDto(
Name: "Kaufland Iasi Pacurari",
Description: "Hypermarket in Iasi, open 07:00-22:00",
Category: MerchantCategory.GROCERY,
Address: new ContactInformation { City = "Iasi", Country = "Romania" },
ParentCompanyId: parentCompanyGuid);

var merchant = request.ToMerchant();
await invoiceService.AddMerchantToInvoiceAsync(invoiceId, merchant);

Remarks

Purpose: Creates a new merchant entity and immediately associates it with an invoice in a single atomic operation. Useful when processing invoices from previously unknown merchants.

Immutability: This is a readonly record struct ensuring thread-safety and value semantics for equality comparisons.

Precondition: The target invoice must not already have a merchant reference. Attempting to add a merchant to an invoice that already has one will result in a conflict error.

Hierarchical Structure: Merchants can optionally belong to a parent company (e.g., individual store locations under a franchise brand).

See Also

Properties

AddMerchantToInvoiceRequestDto.Address Property

Optional structured contact and address information including street, city, postal code, country, phone, and email.

public arolariu.Backend.Common.DDD.ValueObjects.ContactInformation? Address { get; init; }

Property Value

arolariu.Backend.Common.DDD.ValueObjects.ContactInformation

AddMerchantToInvoiceRequestDto.Category Property

The merchant category classification (e.g., Grocery, Restaurant, Pharmacy). Defaults to NOT_DEFINED if not specified.

public arolariu.Backend.Domain.Invoices.DDD.Entities.Merchants.MerchantCategory Category { get; init; }

Property Value

MerchantCategory

AddMerchantToInvoiceRequestDto.Description Property

A detailed description of the merchant. Required. May include operating hours, specialties, or other relevant information.

public string Description { get; init; }

Property Value

System.String

AddMerchantToInvoiceRequestDto.Name Property

The merchant's display name. Required. Typically the store or business name (e.g., "Kaufland Iasi Pacurari").

public string Name { get; init; }

Property Value

System.String

AddMerchantToInvoiceRequestDto.ParentCompanyId Property

Optional reference to a parent company merchant ID for franchise/chain stores. Null if the merchant is independent or the parent is unknown.

public System.Nullable<System.Guid> ParentCompanyId { get; init; }

Property Value

System.Nullable<System.Guid>

Methods

AddMerchantToInvoiceRequestDto.ToMerchant() Method

Converts this DTO to a new Merchant domain entity.

public arolariu.Backend.Domain.Invoices.DDD.Entities.Merchants.Merchant ToMerchant();

Returns

Merchant
A new Merchant instance ready for persistence.

Remarks

ID Generation: A new System.Guid is generated for the merchant. Consider using Guid.CreateVersion7() for time-ordered IDs in production.

Defaults: Optional fields default to empty/sentinel values:

Timestamp:CreatedAt is set to the current UTC time.

AnalyzeInvoiceRequestDto Struct

Request DTO for triggering AI-powered invoice analysis and enrichment.

public readonly record struct AnalyzeInvoiceRequestDto : System.IEquatable<arolariu.Backend.Domain.Invoices.DTOs.Requests.AnalyzeInvoiceRequestDto>

Implements System.IEquatable<AnalyzeInvoiceRequestDto>

Example

// Request complete analysis
var request = new AnalyzeInvoiceRequestDto(AnalysisOptions.CompleteAnalysis);

// Request merchant extraction only
var merchantOnly = new AnalyzeInvoiceRequestDto(AnalysisOptions.InvoiceMerchantOnly);

Remarks

Purpose: Specifies which analysis operations should be performed on an invoice. The analysis pipeline uses Azure Document Intelligence and Azure OpenAI to extract and enrich invoice data.

Immutability: This is a readonly record struct ensuring thread-safety and value semantics for equality comparisons.

Analysis Types:

Processing Time:CompleteAnalysis may take 10-30 seconds depending on invoice complexity. Consider using background processing for large batches.

See Also

Constructors

AnalyzeInvoiceRequestDto(AnalysisOptions) Constructor

Request DTO for triggering AI-powered invoice analysis and enrichment.

public AnalyzeInvoiceRequestDto(arolariu.Backend.Domain.Invoices.DTOs.AnalysisOptions Options);

Parameters

Options AnalysisOptions

The type of analysis to perform on the invoice. Required. Determines which AI extraction pipelines are executed.

Example

// Request complete analysis
var request = new AnalyzeInvoiceRequestDto(AnalysisOptions.CompleteAnalysis);

// Request merchant extraction only
var merchantOnly = new AnalyzeInvoiceRequestDto(AnalysisOptions.InvoiceMerchantOnly);

Remarks

Purpose: Specifies which analysis operations should be performed on an invoice. The analysis pipeline uses Azure Document Intelligence and Azure OpenAI to extract and enrich invoice data.

Immutability: This is a readonly record struct ensuring thread-safety and value semantics for equality comparisons.

Analysis Types:

Processing Time:CompleteAnalysis may take 10-30 seconds depending on invoice complexity. Consider using background processing for large batches.

See Also

Properties

AnalyzeInvoiceRequestDto.Options Property

The type of analysis to perform on the invoice. Required. Determines which AI extraction pipelines are executed.

public arolariu.Backend.Domain.Invoices.DTOs.AnalysisOptions Options { get; init; }

Property Value

AnalysisOptions

Methods

AnalyzeInvoiceRequestDto.ToAnalysisOptions() Method

Converts this DTO to the domain AnalysisOptions value.

public arolariu.Backend.Domain.Invoices.DTOs.AnalysisOptions ToAnalysisOptions();

Returns

AnalysisOptions
The AnalysisOptions value encapsulated by this DTO.

Remarks

Simple passthrough method provided for consistency with other DTO conversion patterns.

CreateInvoiceRequestDto Struct

Request DTO for creating a new invoice in the system.

public readonly record struct CreateInvoiceRequestDto : System.IEquatable<arolariu.Backend.Domain.Invoices.DTOs.Requests.CreateInvoiceRequestDto>

Implements System.IEquatable<CreateInvoiceRequestDto>

Example

var request = new CreateInvoiceRequestDto(
UserIdentifier: userId,
InitialScan: new InvoiceScan(ScanType.JPG, blobUri, null),
Metadata: new Dictionary<string, object> { ["source"] = "mobile-app" });

var invoice = request.ToInvoice();
await invoiceService.CreateAsync(invoice);

Remarks

Purpose: Captures the minimal required data to create a new invoice. The invoice starts in a minimal state and is enriched through AI analysis.

Immutability: This is a readonly record struct ensuring thread-safety and value semantics for equality comparisons.

Initial Scan Requirement: At least one scan (receipt image) is required. The scan triggers the document analysis pipeline which extracts merchant, line items, and payment information automatically.

Metadata: Optional key-value pairs for client-specific data such as source application, import batch ID, or custom tags.

See Also

Constructors

CreateInvoiceRequestDto(Guid, InvoiceScan, IDictionary<string,object>) Constructor

Request DTO for creating a new invoice in the system.

public CreateInvoiceRequestDto(System.Guid UserIdentifier, arolariu.Backend.Domain.Invoices.DDD.AggregatorRoots.Invoices.InvoiceScan InitialScan, System.Collections.Generic.IDictionary<string,object>? Metadata);

Parameters

UserIdentifier System.Guid

The unique identifier of the user who owns this invoice. Required. Must be a valid, authenticated user ID from the identity provider.

InitialScan InvoiceScan

The initial receipt scan to process. Required. Supported formats: JPG, PNG, PDF (single page), TIFF. Maximum file size determined by storage configuration.

Metadata System.Collections.Generic.IDictionary<System.String,System.Object>

Optional key-value metadata to attach to the invoice. Values are converted to strings during persistence. Null if no custom metadata is needed.

Example

var request = new CreateInvoiceRequestDto(
UserIdentifier: userId,
InitialScan: new InvoiceScan(ScanType.JPG, blobUri, null),
Metadata: new Dictionary<string, object> { ["source"] = "mobile-app" });

var invoice = request.ToInvoice();
await invoiceService.CreateAsync(invoice);

Remarks

Purpose: Captures the minimal required data to create a new invoice. The invoice starts in a minimal state and is enriched through AI analysis.

Immutability: This is a readonly record struct ensuring thread-safety and value semantics for equality comparisons.

Initial Scan Requirement: At least one scan (receipt image) is required. The scan triggers the document analysis pipeline which extracts merchant, line items, and payment information automatically.

Metadata: Optional key-value pairs for client-specific data such as source application, import batch ID, or custom tags.

See Also

Properties

CreateInvoiceRequestDto.InitialScan Property

The initial receipt scan to process. Required. Supported formats: JPG, PNG, PDF (single page), TIFF. Maximum file size determined by storage configuration.

public arolariu.Backend.Domain.Invoices.DDD.AggregatorRoots.Invoices.InvoiceScan InitialScan { get; init; }

Property Value

InvoiceScan

CreateInvoiceRequestDto.Metadata Property

Optional key-value metadata to attach to the invoice. Values are converted to strings during persistence. Null if no custom metadata is needed.

public System.Collections.Generic.IDictionary<string,object>? Metadata { get; init; }

Property Value

System.Collections.Generic.IDictionary<System.String,System.Object>

CreateInvoiceRequestDto.UserIdentifier Property

The unique identifier of the user who owns this invoice. Required. Must be a valid, authenticated user ID from the identity provider.

public System.Guid UserIdentifier { get; init; }

Property Value

System.Guid

Methods

CreateInvoiceRequestDto.ToInvoice() Method

Converts this DTO to a new Invoice domain aggregate.

public arolariu.Backend.Domain.Invoices.DDD.AggregatorRoots.Invoices.Invoice ToInvoice();

Returns

Invoice
A new Invoice instance initialized with the provided values and ready for persistence or further processing.

Remarks

Factory Method: Creates a minimal invoice with default sentinel values. The invoice ID is auto-generated as a Version 7 GUID.

Metadata Conversion: All metadata values are converted to strings via System.Object.ToString. Null values become empty strings.

CreateInvoiceScanRequestDto Struct

Request DTO for adding a new scan (receipt image/document) to an invoice.

public readonly record struct CreateInvoiceScanRequestDto : System.IEquatable<arolariu.Backend.Domain.Invoices.DTOs.Requests.CreateInvoiceScanRequestDto>

Implements System.IEquatable<CreateInvoiceScanRequestDto>

Example

// Upload scan to blob storage first
var blobUri = await blobService.UploadAsync(scanBytes, "receipt.jpg");

// Create the scan request
var request = new CreateInvoiceScanRequestDto(
Type: ScanType.JPG,
Location: blobUri,
Metadata: new Dictionary<string, object> { ["pageNumber"] = 2 });

var scan = request.ToInvoiceScan();
invoice.Scans.Add(scan);

Remarks

Purpose: Enables adding additional scans to an existing invoice. Useful for multi-page receipts, supplementary documentation, or re-scans with better quality.

Immutability: This is a readonly record struct ensuring thread-safety and value semantics for equality comparisons.

Supported Formats: See ScanType for supported formats: JPG, PNG, PDF (single page recommended), TIFF.

Storage: The Location URI should point to Azure Blob Storage. The scan must be uploaded to storage before creating this DTO.

AI Processing: After adding a scan, trigger analysis via the AnalyzeInvoiceRequestDto to extract data from the new scan.

See Also

Constructors

CreateInvoiceScanRequestDto(ScanType, Uri, IDictionary<string,object>) Constructor

Request DTO for adding a new scan (receipt image/document) to an invoice.

public CreateInvoiceScanRequestDto(arolariu.Backend.Domain.Invoices.DDD.AggregatorRoots.Invoices.ScanType Type, System.Uri Location, System.Collections.Generic.IDictionary<string,object>? Metadata);

Parameters

Type ScanType

The scan format type. Required. Must match the actual file format to ensure proper processing by Document Intelligence.

Location System.Uri

The URI where the scan image/document is stored. Required. Must be a valid, accessible URI (typically Azure Blob Storage with SAS token).

Metadata System.Collections.Generic.IDictionary<System.String,System.Object>

Optional metadata associated with this scan. May include:

  • pageNumber: For multi-page documents.
  • scanQuality: DPI or quality indicator.
  • source: Scanning device or application.

Example

// Upload scan to blob storage first
var blobUri = await blobService.UploadAsync(scanBytes, "receipt.jpg");

// Create the scan request
var request = new CreateInvoiceScanRequestDto(
Type: ScanType.JPG,
Location: blobUri,
Metadata: new Dictionary<string, object> { ["pageNumber"] = 2 });

var scan = request.ToInvoiceScan();
invoice.Scans.Add(scan);

Remarks

Purpose: Enables adding additional scans to an existing invoice. Useful for multi-page receipts, supplementary documentation, or re-scans with better quality.

Immutability: This is a readonly record struct ensuring thread-safety and value semantics for equality comparisons.

Supported Formats: See ScanType for supported formats: JPG, PNG, PDF (single page recommended), TIFF.

Storage: The Location URI should point to Azure Blob Storage. The scan must be uploaded to storage before creating this DTO.

AI Processing: After adding a scan, trigger analysis via the AnalyzeInvoiceRequestDto to extract data from the new scan.

See Also

Properties

CreateInvoiceScanRequestDto.Location Property

The URI where the scan image/document is stored. Required. Must be a valid, accessible URI (typically Azure Blob Storage with SAS token).

public System.Uri Location { get; init; }

Property Value

System.Uri

CreateInvoiceScanRequestDto.Metadata Property

Optional metadata associated with this scan. May include:

  • pageNumber: For multi-page documents.
  • scanQuality: DPI or quality indicator.
  • source: Scanning device or application.
public System.Collections.Generic.IDictionary<string,object>? Metadata { get; init; }

Property Value

System.Collections.Generic.IDictionary<System.String,System.Object>

CreateInvoiceScanRequestDto.Type Property

The scan format type. Required. Must match the actual file format to ensure proper processing by Document Intelligence.

public arolariu.Backend.Domain.Invoices.DDD.AggregatorRoots.Invoices.ScanType Type { get; init; }

Property Value

ScanType

Methods

CreateInvoiceScanRequestDto.ToInvoiceScan() Method

Converts this DTO to an InvoiceScan domain value object.

public arolariu.Backend.Domain.Invoices.DDD.AggregatorRoots.Invoices.InvoiceScan ToInvoiceScan();

Returns

InvoiceScan
A new InvoiceScan instance ready to be added to an invoice.

Remarks

Direct Mapping: All fields are passed directly to the InvoiceScan constructor without transformation.

Metadata Handling: The metadata dictionary is passed by reference. If immutability is required, the caller should provide a copy.

CreateMerchantRequestDto Struct

Request DTO for creating a new standalone merchant entity.

public readonly record struct CreateMerchantRequestDto : System.IEquatable<arolariu.Backend.Domain.Invoices.DTOs.Requests.CreateMerchantRequestDto>

Implements System.IEquatable<CreateMerchantRequestDto>

Example

var request = new CreateMerchantRequestDto(
Name: "Kaufland Romania",
Description: "German hypermarket chain operating in Romania",
Address: "Str. Pacurari 123, Iasi 700000, Romania",
ParentCompanyIdentifier: Guid.Empty); // No parent

var merchant = request.ToMerchant();
await merchantService.CreateAsync(merchant);

Remarks

Purpose: Creates a new merchant in the system without immediately associating it with an invoice. Useful for pre-populating the merchant database or managing merchants independently.

Immutability: This is a readonly record struct ensuring thread-safety and value semantics for equality comparisons.

Hierarchical Structure: Use ParentCompanyIdentifier to establish franchise/chain relationships. Set to System.Guid.Empty for independent merchants.

Address Handling: The Address string is currently stored as-is. Structured parsing into arolariu.Backend.Common.DDD.ValueObjects.ContactInformation may be performed by the service layer or AI enrichment.

See Also

Constructors

CreateMerchantRequestDto(string, string, string, Guid) Constructor

Request DTO for creating a new standalone merchant entity.

public CreateMerchantRequestDto(string Name, string Description, string Address, System.Guid ParentCompanyIdentifier);

Parameters

Name System.String

The merchant's display name. Required. Should be unique within a reasonable scope (e.g., within a city or region).

Description System.String

A detailed description of the merchant. Required. May include business type, operating hours, or other relevant details.

Address System.String

The merchant's address as a free-form string. Required. Will be wrapped in arolariu.Backend.Common.DDD.ValueObjects.ContactInformation during conversion.

ParentCompanyIdentifier System.Guid

Identifier of the parent company for hierarchical grouping. Use System.Guid.Empty for independent merchants.

Example

var request = new CreateMerchantRequestDto(
Name: "Kaufland Romania",
Description: "German hypermarket chain operating in Romania",
Address: "Str. Pacurari 123, Iasi 700000, Romania",
ParentCompanyIdentifier: Guid.Empty); // No parent

var merchant = request.ToMerchant();
await merchantService.CreateAsync(merchant);

Remarks

Purpose: Creates a new merchant in the system without immediately associating it with an invoice. Useful for pre-populating the merchant database or managing merchants independently.

Immutability: This is a readonly record struct ensuring thread-safety and value semantics for equality comparisons.

Hierarchical Structure: Use ParentCompanyIdentifier to establish franchise/chain relationships. Set to System.Guid.Empty for independent merchants.

Address Handling: The Address string is currently stored as-is. Structured parsing into arolariu.Backend.Common.DDD.ValueObjects.ContactInformation may be performed by the service layer or AI enrichment.

See Also

Properties

CreateMerchantRequestDto.Address Property

The merchant's address as a free-form string. Required. Will be wrapped in arolariu.Backend.Common.DDD.ValueObjects.ContactInformation during conversion.

public string Address { get; init; }

Property Value

System.String

CreateMerchantRequestDto.Description Property

A detailed description of the merchant. Required. May include business type, operating hours, or other relevant details.

public string Description { get; init; }

Property Value

System.String

CreateMerchantRequestDto.Name Property

The merchant's display name. Required. Should be unique within a reasonable scope (e.g., within a city or region).

public string Name { get; init; }

Property Value

System.String

CreateMerchantRequestDto.ParentCompanyIdentifier Property

Identifier of the parent company for hierarchical grouping. Use System.Guid.Empty for independent merchants.

public System.Guid ParentCompanyIdentifier { get; init; }

Property Value

System.Guid

Methods

CreateMerchantRequestDto.ToMerchant() Method

Converts this DTO to a new Merchant domain entity.

public arolariu.Backend.Domain.Invoices.DDD.Entities.Merchants.Merchant ToMerchant();

Returns

Merchant
A new Merchant instance with generated ID and current timestamp.

Remarks

ID Generation: A new System.Guid is generated for the merchant.

Category Default: The category is set to OTHER and should be refined through subsequent updates or AI classification.

Address Note: The Address string parameter is not currently parsed into the arolariu.Backend.Common.DDD.ValueObjects.ContactInformation structure. The resulting entity receives an empty arolariu.Backend.Common.DDD.ValueObjects.ContactInformation instance.

CreateProductRequestDto Struct

Request DTO for adding a new product line item to an existing invoice.

public readonly record struct CreateProductRequestDto : System.IEquatable<arolariu.Backend.Domain.Invoices.DTOs.Requests.CreateProductRequestDto>

Implements System.IEquatable<CreateProductRequestDto>

Example

var request = new CreateProductRequestDto(
Name: "Milk 1L (LAPTE ZUZU)",
Category: ProductCategory.DAIRY,
Quantity: 2,
QuantityUnit: "buc",
ProductCode: "5941234567890",
Price: 8.99m,
DetectedAllergens: [Allergen.Lactose]);

var product = request.ToProduct();
invoice.Items.Add(product);

Remarks

Purpose: Enables manual addition of products to an invoice, useful for correcting OCR errors or adding items that weren't automatically detected.

Immutability: This is a readonly record struct ensuring thread-safety and value semantics for equality comparisons.

AI Enrichment: After creation, the product may be enriched by AI analysis to populate Category and DetectedAllergens if not provided.

Total Price: The total price is computed automatically as Quantity × Price during conversion to the domain object.

See Also

Constructors

CreateProductRequestDto(string, ProductCategory, decimal, string, string, decimal, IEnumerable<Allergen>) Constructor

Request DTO for adding a new product line item to an existing invoice.

public CreateProductRequestDto(string Name, arolariu.Backend.Domain.Invoices.DDD.ValueObjects.Products.ProductCategory Category, decimal Quantity, string? QuantityUnit, string? ProductCode, decimal Price, System.Collections.Generic.IEnumerable<arolariu.Backend.Domain.Invoices.DDD.ValueObjects.Allergen>? DetectedAllergens);

Parameters

Name System.String

The product name as it appears on the receipt. Required. This will be used as the product's display name.

Category ProductCategory

The product category classification. Defaults to NOT_DEFINED if not specified. May be auto-classified by AI analysis.

Quantity System.Decimal

The quantity of product units. Must be positive. Supports decimal for fractional quantities (e.g., 1.5 kg).

QuantityUnit System.String

The unit of measure (e.g., "kg", "L", "buc", "pcs"). Null if not specified; defaults to empty string in domain object.

ProductCode System.String

Optional SKU, barcode (EAN/UPC), or internal product identifier. Null if not available on the receipt.

Price System.Decimal

The unit price per single quantity. Currency is inherited from the parent invoice.

DetectedAllergens System.Collections.Generic.IEnumerable<Allergen>

Optional collection of known allergens in this product. May be populated by AI analysis if not provided.

Example

var request = new CreateProductRequestDto(
Name: "Milk 1L (LAPTE ZUZU)",
Category: ProductCategory.DAIRY,
Quantity: 2,
QuantityUnit: "buc",
ProductCode: "5941234567890",
Price: 8.99m,
DetectedAllergens: [Allergen.Lactose]);

var product = request.ToProduct();
invoice.Items.Add(product);

Remarks

Purpose: Enables manual addition of products to an invoice, useful for correcting OCR errors or adding items that weren't automatically detected.

Immutability: This is a readonly record struct ensuring thread-safety and value semantics for equality comparisons.

AI Enrichment: After creation, the product may be enriched by AI analysis to populate Category and DetectedAllergens if not provided.

Total Price: The total price is computed automatically as Quantity × Price during conversion to the domain object.

See Also

Properties

CreateProductRequestDto.Category Property

The product category classification. Defaults to NOT_DEFINED if not specified. May be auto-classified by AI analysis.

public arolariu.Backend.Domain.Invoices.DDD.ValueObjects.Products.ProductCategory Category { get; init; }

Property Value

ProductCategory

CreateProductRequestDto.DetectedAllergens Property

Optional collection of known allergens in this product. May be populated by AI analysis if not provided.

public System.Collections.Generic.IEnumerable<arolariu.Backend.Domain.Invoices.DDD.ValueObjects.Allergen>? DetectedAllergens { get; init; }

Property Value

System.Collections.Generic.IEnumerable<Allergen>

CreateProductRequestDto.Name Property

The product name as it appears on the receipt. Required. This will be used as the product's display name.

public string Name { get; init; }

Property Value

System.String

CreateProductRequestDto.Price Property

The unit price per single quantity. Currency is inherited from the parent invoice.

public decimal Price { get; init; }

Property Value

System.Decimal

CreateProductRequestDto.ProductCode Property

Optional SKU, barcode (EAN/UPC), or internal product identifier. Null if not available on the receipt.

public string? ProductCode { get; init; }

Property Value

System.String

CreateProductRequestDto.Quantity Property

The quantity of product units. Must be positive. Supports decimal for fractional quantities (e.g., 1.5 kg).

public decimal Quantity { get; init; }

Property Value

System.Decimal

CreateProductRequestDto.QuantityUnit Property

The unit of measure (e.g., "kg", "L", "buc", "pcs"). Null if not specified; defaults to empty string in domain object.

public string? QuantityUnit { get; init; }

Property Value

System.String

Methods

CreateProductRequestDto.ToProduct() Method

Converts this DTO to a Product domain value object.

public arolariu.Backend.Domain.Invoices.DDD.ValueObjects.Products.Product ToProduct();

Returns

Product
A new Product instance initialized with the provided values.

Remarks

Null Handling: Optional string fields are converted to empty strings. Optional collections default to empty enumerables.

Total Price: The TotalPrice is computed automatically by the domain object as Quantity × Price.

DeleteMetadataRequestDto Struct

Request DTO for removing metadata entries from an invoice.

public readonly record struct DeleteMetadataRequestDto : System.IEquatable<arolariu.Backend.Domain.Invoices.DTOs.Requests.DeleteMetadataRequestDto>

Implements System.IEquatable<DeleteMetadataRequestDto>

Example

// Remove specific metadata keys
var request = new DeleteMetadataRequestDto(
Keys: new[] { "ai.rawExtraction", "temp.processingFlag" });

// Service layer handles the removal
foreach (var key in request.Keys)
{
invoice.AdditionalMetadata.Remove(key);
}

Remarks

Purpose: Enables batch removal of metadata keys from an invoice's AdditionalMetadata collection.

Immutability: This is a readonly record struct ensuring thread-safety and value semantics for equality comparisons.

Idempotent Operation: Non-existent keys are silently ignored. The operation succeeds even if some or all specified keys don't exist.

Use Cases:

  • Cleaning up AI-generated metadata that is no longer relevant.
  • Removing user annotations or temporary processing flags.
  • Clearing sensitive data from metadata before sharing.

See Also

Constructors

DeleteMetadataRequestDto(IEnumerable<string>) Constructor

Request DTO for removing metadata entries from an invoice.

public DeleteMetadataRequestDto(System.Collections.Generic.IEnumerable<string> Keys);

Parameters

Keys System.Collections.Generic.IEnumerable<System.String>

Collection of metadata keys to remove. Required. Must contain at least one key. Keys should match the exact key strings stored in the invoice's metadata (case-sensitive).

Example

// Remove specific metadata keys
var request = new DeleteMetadataRequestDto(
Keys: new[] { "ai.rawExtraction", "temp.processingFlag" });

// Service layer handles the removal
foreach (var key in request.Keys)
{
invoice.AdditionalMetadata.Remove(key);
}

Remarks

Purpose: Enables batch removal of metadata keys from an invoice's AdditionalMetadata collection.

Immutability: This is a readonly record struct ensuring thread-safety and value semantics for equality comparisons.

Idempotent Operation: Non-existent keys are silently ignored. The operation succeeds even if some or all specified keys don't exist.

Use Cases:

  • Cleaning up AI-generated metadata that is no longer relevant.
  • Removing user annotations or temporary processing flags.
  • Clearing sensitive data from metadata before sharing.

See Also

Properties

DeleteMetadataRequestDto.Keys Property

Collection of metadata keys to remove. Required. Must contain at least one key. Keys should match the exact key strings stored in the invoice's metadata (case-sensitive).

public System.Collections.Generic.IEnumerable<string> Keys { get; init; }

Property Value

System.Collections.Generic.IEnumerable<System.String>

DeleteProductRequestDto Struct

Request DTO for removing a product line item from an invoice.

public readonly record struct DeleteProductRequestDto : System.IEquatable<arolariu.Backend.Domain.Invoices.DTOs.Requests.DeleteProductRequestDto>

Implements System.IEquatable<DeleteProductRequestDto>

Example

// Remove a product by its name
var request = new DeleteProductRequestDto(ProductName: "LAPTE ZUZU 1L");

// Service layer handles the actual deletion
await invoiceService.DeleteProductAsync(invoiceId, request);

Remarks

Purpose: Identifies a product for removal from an invoice's item collection. Typically used to remove incorrectly added items or duplicate entries.

Immutability: This is a readonly record struct ensuring thread-safety and value semantics for equality comparisons.

Soft Delete: By default, deletion marks the product's Metadata.IsSoftDeleted flag as true rather than physically removing it. This preserves audit history and allows for potential recovery.

Recalculation: After deletion, the invoice's PaymentInformation.TotalAmount should be recalculated to exclude the deleted product.

See Also

Constructors

DeleteProductRequestDto(string) Constructor

Request DTO for removing a product line item from an invoice.

public DeleteProductRequestDto(string ProductName);

Parameters

ProductName System.String

The name of the product to delete. Required. Matched against existing product Name values using a case-insensitive substring comparison in the current service implementation.

Example

// Remove a product by its name
var request = new DeleteProductRequestDto(ProductName: "LAPTE ZUZU 1L");

// Service layer handles the actual deletion
await invoiceService.DeleteProductAsync(invoiceId, request);

Remarks

Purpose: Identifies a product for removal from an invoice's item collection. Typically used to remove incorrectly added items or duplicate entries.

Immutability: This is a readonly record struct ensuring thread-safety and value semantics for equality comparisons.

Soft Delete: By default, deletion marks the product's Metadata.IsSoftDeleted flag as true rather than physically removing it. This preserves audit history and allows for potential recovery.

Recalculation: After deletion, the invoice's PaymentInformation.TotalAmount should be recalculated to exclude the deleted product.

See Also

Properties

DeleteProductRequestDto.ProductName Property

The name of the product to delete. Required. Matched against existing product Name values using a case-insensitive substring comparison in the current service implementation.

public string ProductName { get; init; }

Property Value

System.String

MerchantInvoicesRequestDto Struct

Request DTO for managing invoice associations with a merchant.

public readonly record struct MerchantInvoicesRequestDto : System.IEquatable<arolariu.Backend.Domain.Invoices.DTOs.Requests.MerchantInvoicesRequestDto>

Implements System.IEquatable<MerchantInvoicesRequestDto>

Example

// Add invoices to a merchant
var addRequest = new MerchantInvoicesRequestDto(
InvoiceIdentifiers: new[] { invoice1Id, invoice2Id, invoice3Id });
await merchantService.AddInvoicesAsync(merchantId, addRequest);

// Remove invoices from a merchant
var removeRequest = new MerchantInvoicesRequestDto(
InvoiceIdentifiers: new[] { oldInvoiceId });
await merchantService.RemoveInvoicesAsync(merchantId, removeRequest);

Remarks

Purpose: Provides a batch operation interface for adding or removing invoice references from a merchant's tracked collection.

Immutability: This is a readonly record struct ensuring thread-safety and value semantics for equality comparisons.

HTTP Method Semantics:

  • PATCH: Adds the specified invoice identifiers to the merchant's ReferencedInvoices collection. Duplicates are ignored.
  • DELETE: Removes the specified invoice identifiers from the merchant's ReferencedInvoices collection. Missing IDs are ignored.

Validation: Invoice identifiers are validated for existence in the handler layer. Non-existent invoices result in partial success with warnings.

Use Cases:

  • Bulk-associating historical invoices with a newly created merchant.
  • Correcting merchant associations when invoices were misclassified.
  • Cleaning up references when invoices are deleted or reassigned.

See Also

Constructors

MerchantInvoicesRequestDto(IEnumerable<Guid>) Constructor

Request DTO for managing invoice associations with a merchant.

public MerchantInvoicesRequestDto(System.Collections.Generic.IEnumerable<System.Guid> InvoiceIdentifiers);

Parameters

InvoiceIdentifiers System.Collections.Generic.IEnumerable<System.Guid>

Collection of invoice GUIDs to add or remove. Required. Must contain at least one identifier. Empty collections result in validation errors.

Example

// Add invoices to a merchant
var addRequest = new MerchantInvoicesRequestDto(
InvoiceIdentifiers: new[] { invoice1Id, invoice2Id, invoice3Id });
await merchantService.AddInvoicesAsync(merchantId, addRequest);

// Remove invoices from a merchant
var removeRequest = new MerchantInvoicesRequestDto(
InvoiceIdentifiers: new[] { oldInvoiceId });
await merchantService.RemoveInvoicesAsync(merchantId, removeRequest);

Remarks

Purpose: Provides a batch operation interface for adding or removing invoice references from a merchant's tracked collection.

Immutability: This is a readonly record struct ensuring thread-safety and value semantics for equality comparisons.

HTTP Method Semantics:

  • PATCH: Adds the specified invoice identifiers to the merchant's ReferencedInvoices collection. Duplicates are ignored.
  • DELETE: Removes the specified invoice identifiers from the merchant's ReferencedInvoices collection. Missing IDs are ignored.

Validation: Invoice identifiers are validated for existence in the handler layer. Non-existent invoices result in partial success with warnings.

Use Cases:

  • Bulk-associating historical invoices with a newly created merchant.
  • Correcting merchant associations when invoices were misclassified.
  • Cleaning up references when invoices are deleted or reassigned.

See Also

Properties

MerchantInvoicesRequestDto.InvoiceIdentifiers Property

Collection of invoice GUIDs to add or remove. Required. Must contain at least one identifier. Empty collections result in validation errors.

public System.Collections.Generic.IEnumerable<System.Guid> InvoiceIdentifiers { get; init; }

Property Value

System.Collections.Generic.IEnumerable<System.Guid>

PatchInvoiceRequestDto Struct

Request DTO for partial invoice update operations (HTTP PATCH semantics).

public readonly record struct PatchInvoiceRequestDto : System.IEquatable<arolariu.Backend.Domain.Invoices.DTOs.Requests.PatchInvoiceRequestDto>

Implements System.IEquatable<PatchInvoiceRequestDto>

Example

// Update only the name and importance flag
var request = new PatchInvoiceRequestDto(
Name: "Updated Name",
Description: null, // Keep existing
Category: null, // Keep existing
PaymentInformation: null,
MerchantReference: null,
IsImportant: true,
AdditionalMetadata: null);

var patched = request.ApplyTo(existingInvoice);
await invoiceService.UpdateAsync(patched);

Remarks

Purpose: Allows selective updates to specific invoice fields without replacing the entire resource. Follows HTTP PATCH semantics where null values indicate "no change".

Immutability: This is a readonly record struct ensuring thread-safety and value semantics for equality comparisons.

Merge Strategy: Uses ApplyTo(Invoice, Guid) which performs a non-destructive merge with the following rules:

  • Null values preserve the original field value.
  • System.Guid.Empty for MerchantReference means "no change".
  • NOT_DEFINED means "no change".
  • Empty or whitespace strings for Name/Description mean "no change".

Collections: Scans, Items, Recipes, and SharedWith are copied from the existing invoice (not modifiable via PATCH). Metadata entries are merged with key-wise overwrite semantics.

Full Replacement: For complete invoice replacement, use UpdateInvoiceRequestDto which follows HTTP PUT semantics.

See Also

Constructors

PatchInvoiceRequestDto(string, string, Nullable<InvoiceCategory>, PaymentInformation, Nullable<Guid>, Nullable<bool>, ICollection<Guid>, IDictionary<string,object>) Constructor

Request DTO for partial invoice update operations (HTTP PATCH semantics).

public PatchInvoiceRequestDto(string? Name, string? Description, System.Nullable<arolariu.Backend.Domain.Invoices.DDD.AggregatorRoots.Invoices.InvoiceCategory> Category, arolariu.Backend.Domain.Invoices.DDD.ValueObjects.PaymentInformation? PaymentInformation, System.Nullable<System.Guid> MerchantReference, System.Nullable<bool> IsImportant, System.Collections.Generic.ICollection<System.Guid>? SharedWith, System.Collections.Generic.IDictionary<string,object>? AdditionalMetadata);

Parameters

Name System.String

Optional new name for the invoice. Null or whitespace preserves the existing name.

Description System.String

Optional new description. Null or whitespace preserves the existing description.

Category System.Nullable<InvoiceCategory>

Optional new category classification. Null or NOT_DEFINED preserves the existing category.

PaymentInformation PaymentInformation

Optional new payment information. Null preserves the existing payment details.

MerchantReference System.Nullable<System.Guid>

Optional new merchant reference. Null or System.Guid.Empty preserves the existing merchant association.

IsImportant System.Nullable<System.Boolean>

Optional importance flag update. Null preserves the existing flag value.

SharedWith System.Collections.Generic.ICollection<System.Guid>

Optional list of user identifiers to share the invoice with. When provided, this completely replaces the existing SharedWith list. Use an empty list to remove all shares. Null preserves the existing sharing settings.

AdditionalMetadata System.Collections.Generic.IDictionary<System.String,System.Object>

Optional metadata entries to merge with existing metadata. Existing keys are overwritten; new keys are added. Null or empty dictionary means no metadata changes.

Example

// Update only the name and importance flag
var request = new PatchInvoiceRequestDto(
Name: "Updated Name",
Description: null, // Keep existing
Category: null, // Keep existing
PaymentInformation: null,
MerchantReference: null,
IsImportant: true,
AdditionalMetadata: null);

var patched = request.ApplyTo(existingInvoice);
await invoiceService.UpdateAsync(patched);

Remarks

Purpose: Allows selective updates to specific invoice fields without replacing the entire resource. Follows HTTP PATCH semantics where null values indicate "no change".

Immutability: This is a readonly record struct ensuring thread-safety and value semantics for equality comparisons.

Merge Strategy: Uses ApplyTo(Invoice, Guid) which performs a non-destructive merge with the following rules:

  • Null values preserve the original field value.
  • System.Guid.Empty for MerchantReference means "no change".
  • NOT_DEFINED means "no change".
  • Empty or whitespace strings for Name/Description mean "no change".

Collections: Scans, Items, Recipes, and SharedWith are copied from the existing invoice (not modifiable via PATCH). Metadata entries are merged with key-wise overwrite semantics.

Full Replacement: For complete invoice replacement, use UpdateInvoiceRequestDto which follows HTTP PUT semantics.

See Also

Properties

PatchInvoiceRequestDto.AdditionalMetadata Property

Optional metadata entries to merge with existing metadata. Existing keys are overwritten; new keys are added. Null or empty dictionary means no metadata changes.

public System.Collections.Generic.IDictionary<string,object>? AdditionalMetadata { get; init; }

Property Value

System.Collections.Generic.IDictionary<System.String,System.Object>

PatchInvoiceRequestDto.Category Property

Optional new category classification. Null or NOT_DEFINED preserves the existing category.

public System.Nullable<arolariu.Backend.Domain.Invoices.DDD.AggregatorRoots.Invoices.InvoiceCategory> Category { get; init; }

Property Value

System.Nullable<InvoiceCategory>

PatchInvoiceRequestDto.Description Property

Optional new description. Null or whitespace preserves the existing description.

public string? Description { get; init; }

Property Value

System.String

PatchInvoiceRequestDto.IsImportant Property

Optional importance flag update. Null preserves the existing flag value.

public System.Nullable<bool> IsImportant { get; init; }

Property Value

System.Nullable<System.Boolean>

PatchInvoiceRequestDto.MerchantReference Property

Optional new merchant reference. Null or System.Guid.Empty preserves the existing merchant association.

public System.Nullable<System.Guid> MerchantReference { get; init; }

Property Value

System.Nullable<System.Guid>

PatchInvoiceRequestDto.Name Property

Optional new name for the invoice. Null or whitespace preserves the existing name.

public string? Name { get; init; }

Property Value

System.String

PatchInvoiceRequestDto.PaymentInformation Property

Optional new payment information. Null preserves the existing payment details.

public arolariu.Backend.Domain.Invoices.DDD.ValueObjects.PaymentInformation? PaymentInformation { get; init; }

Property Value

PaymentInformation

PatchInvoiceRequestDto.SharedWith Property

Optional list of user identifiers to share the invoice with. When provided, this completely replaces the existing SharedWith list. Use an empty list to remove all shares. Null preserves the existing sharing settings.

public System.Collections.Generic.ICollection<System.Guid>? SharedWith { get; init; }

Property Value

System.Collections.Generic.ICollection<System.Guid>

Methods

PatchInvoiceRequestDto.ApplyTo(Invoice, Guid) Method

Applies this partial update to an existing Invoice instance.

public arolariu.Backend.Domain.Invoices.DDD.AggregatorRoots.Invoices.Invoice ApplyTo(arolariu.Backend.Domain.Invoices.DDD.AggregatorRoots.Invoices.Invoice existing, System.Guid updatedBy);

Parameters

existing Invoice

The existing invoice to apply patches to. Must not be null.

updatedBy System.Guid

Returns

Invoice
A new Invoice instance with merged values from this DTO and the existing invoice.

Exceptions

System.ArgumentNullException
Thrown when existing is null.

Remarks

Immutable Operation: Creates a new invoice instance with merged values. The original existing invoice is not mutated.

Field Update Rules:

Collection Handling: All collections (Scans, Items, PossibleRecipes, SharedWith) are copied from the existing invoice to preserve referential integrity.

Metadata Merge: Existing metadata is copied first, then DTO metadata is overlaid, allowing selective key updates without losing other entries.

PatchMetadataRequestDto Struct

Request DTO for adding or updating metadata entries on an invoice.

public readonly record struct PatchMetadataRequestDto : System.IEquatable<arolariu.Backend.Domain.Invoices.DTOs.Requests.PatchMetadataRequestDto>

Implements System.IEquatable<PatchMetadataRequestDto>

Example

var request = new PatchMetadataRequestDto(
Entries: new Dictionary<string, object>
{
["user.note"] = "Important receipt for tax purposes",
["ai.confidence"] = 0.95,
["custom.projectId"] = "PROJ-2025-001"
});

request.ApplyTo(invoice.AdditionalMetadata);

Remarks

Purpose: Enables partial updates to an invoice's metadata collection using HTTP PATCH semantics. Existing keys are overwritten; new keys are added.

Immutability: This is a readonly record struct ensuring thread-safety and value semantics for equality comparisons.

Merge Strategy: Uses "last writer wins" semantics. When a key already exists, its value is replaced with the new value from this DTO.

Key Naming Convention: Keys should follow a dotted namespace pattern for organization and to avoid collisions:

  • ai.confidence: AI-generated confidence scores.
  • ai.extractionDate: When AI analysis was performed.
  • user.note: User-provided annotations.
  • import.source: Data source for imported invoices.

Value Types: Supports strings, numbers (int/double), booleans, and null. Complex objects should be serialized to JSON strings.

See Also

Constructors

PatchMetadataRequestDto(IDictionary<string,object>) Constructor

Request DTO for adding or updating metadata entries on an invoice.

public PatchMetadataRequestDto(System.Collections.Generic.IDictionary<string,object> Entries);

Parameters

Entries System.Collections.Generic.IDictionary<System.String,System.Object>

Dictionary of metadata entries to add or update. Required. Keys must be non-empty strings. Values are converted from System.Text.Json.JsonElement to native types during processing.

Example

var request = new PatchMetadataRequestDto(
Entries: new Dictionary<string, object>
{
["user.note"] = "Important receipt for tax purposes",
["ai.confidence"] = 0.95,
["custom.projectId"] = "PROJ-2025-001"
});

request.ApplyTo(invoice.AdditionalMetadata);

Remarks

Purpose: Enables partial updates to an invoice's metadata collection using HTTP PATCH semantics. Existing keys are overwritten; new keys are added.

Immutability: This is a readonly record struct ensuring thread-safety and value semantics for equality comparisons.

Merge Strategy: Uses "last writer wins" semantics. When a key already exists, its value is replaced with the new value from this DTO.

Key Naming Convention: Keys should follow a dotted namespace pattern for organization and to avoid collisions:

  • ai.confidence: AI-generated confidence scores.
  • ai.extractionDate: When AI analysis was performed.
  • user.note: User-provided annotations.
  • import.source: Data source for imported invoices.

Value Types: Supports strings, numbers (int/double), booleans, and null. Complex objects should be serialized to JSON strings.

See Also

Properties

PatchMetadataRequestDto.Entries Property

Dictionary of metadata entries to add or update. Required. Keys must be non-empty strings. Values are converted from System.Text.Json.JsonElement to native types during processing.

public System.Collections.Generic.IDictionary<string,object> Entries { get; init; }

Property Value

System.Collections.Generic.IDictionary<System.String,System.Object>

Methods

PatchMetadataRequestDto.ApplyTo(IDictionary<string,object>) Method

Applies the metadata entries to an existing metadata dictionary.

public void ApplyTo(System.Collections.Generic.IDictionary<string,object> existingMetadata);

Parameters

existingMetadata System.Collections.Generic.IDictionary<System.String,System.Object>

The existing metadata dictionary to update. Must not be null. Will be modified in place with merged values.

Exceptions

System.ArgumentNullException
Thrown when existingMetadata is null.

Remarks

In-Place Modification: This method modifies the provided dictionary directly. The original Entries from this DTO are not modified.

JsonElement Conversion: When receiving data from HTTP requests, values may arrive as System.Text.Json.JsonElement. This method automatically converts them to native .NET types (string, long, double, bool) for proper storage.

PatchMetadataRequestDto.ConvertJsonElement(object) Method

Converts a System.Text.Json.JsonElement to its native .NET type.

private static object ConvertJsonElement(object value);

Parameters

value System.Object

The value to convert. If not a System.Text.Json.JsonElement, returned as-is.

Returns

System.Object
The converted native type (string, long, double, bool, or raw JSON text).

Remarks

Handles conversion of JSON deserialized values to their appropriate .NET representations for storage and subsequent serialization.

Number Handling: Attempts integer conversion first (as System.Int64), falling back to System.Double for decimal values.

UpdateInvoiceRequestDto Struct

Request DTO for full invoice replacement operations (HTTP PUT semantics).

public readonly record struct UpdateInvoiceRequestDto : System.IEquatable<arolariu.Backend.Domain.Invoices.DTOs.Requests.UpdateInvoiceRequestDto>

Implements System.IEquatable<UpdateInvoiceRequestDto>

Example

var request = new UpdateInvoiceRequestDto(
Name: "Updated Invoice Name",
Description: "Monthly groceries",
Category: InvoiceCategory.GROCERIES,
PaymentInformation: new PaymentInformation(Currency.RON, 150.50m, 28.60m, PaymentMethod.Card),
MerchantReference: merchantId,
IsImportant: true,
AdditionalMetadata: null);

var invoice = request.ToInvoice(invoiceId, userId);
await invoiceService.UpdateAsync(invoice);

Remarks

Purpose: Replaces the entire invoice resource with the provided values. This follows HTTP PUT semantics where the entire resource is replaced.

Immutability: This is a readonly record struct ensuring thread-safety and value semantics for equality comparisons.

Required Fields: All fields except MerchantReference and AdditionalMetadata are required. Validation is enforced via System.ComponentModel.DataAnnotations.RequiredAttribute and business rules in the service layer.

Partial Updates: For partial updates, use PatchInvoiceRequestDto which supports HTTP PATCH semantics with null-as-unchanged behavior.

See Also

Constructors

UpdateInvoiceRequestDto(string, string, InvoiceCategory, PaymentInformation, Nullable<Guid>, bool, IDictionary<string,object>) Constructor

Request DTO for full invoice replacement operations (HTTP PUT semantics).

public UpdateInvoiceRequestDto(string Name, string Description, arolariu.Backend.Domain.Invoices.DDD.AggregatorRoots.Invoices.InvoiceCategory Category, arolariu.Backend.Domain.Invoices.DDD.ValueObjects.PaymentInformation PaymentInformation, System.Nullable<System.Guid> MerchantReference, bool IsImportant, System.Collections.Generic.IDictionary<string,object>? AdditionalMetadata);

Parameters

Name System.String

The invoice name or title. Required. Must be non-empty. Typically a user-friendly identifier like "Groceries - May 2025".

Description System.String

A detailed description of the invoice. Required, but may be empty. Useful for notes, context, or search purposes.

Category InvoiceCategory

The invoice category classification (e.g., Groceries, Entertainment, Utilities). Defaults to NOT_DEFINED if not specified.

PaymentInformation PaymentInformation

Payment details including currency, total amount, tax, and payment method. Required for proper financial tracking and reporting.

MerchantReference System.Nullable<System.Guid>

Optional reference to an associated merchant entity by ID. Null if no merchant is linked or if merchant should be cleared.

IsImportant System.Boolean

Flag indicating if the invoice is marked as important/favorite. Important invoices may appear prominently in UI or be excluded from cleanup.

AdditionalMetadata System.Collections.Generic.IDictionary<System.String,System.Object>

Extensible key-value metadata for client-specific data. Null or empty dictionary replaces any existing metadata.

Example

var request = new UpdateInvoiceRequestDto(
Name: "Updated Invoice Name",
Description: "Monthly groceries",
Category: InvoiceCategory.GROCERIES,
PaymentInformation: new PaymentInformation(Currency.RON, 150.50m, 28.60m, PaymentMethod.Card),
MerchantReference: merchantId,
IsImportant: true,
AdditionalMetadata: null);

var invoice = request.ToInvoice(invoiceId, userId);
await invoiceService.UpdateAsync(invoice);

Remarks

Purpose: Replaces the entire invoice resource with the provided values. This follows HTTP PUT semantics where the entire resource is replaced.

Immutability: This is a readonly record struct ensuring thread-safety and value semantics for equality comparisons.

Required Fields: All fields except MerchantReference and AdditionalMetadata are required. Validation is enforced via System.ComponentModel.DataAnnotations.RequiredAttribute and business rules in the service layer.

Partial Updates: For partial updates, use PatchInvoiceRequestDto which supports HTTP PATCH semantics with null-as-unchanged behavior.

See Also

Properties

UpdateInvoiceRequestDto.AdditionalMetadata Property

Extensible key-value metadata for client-specific data. Null or empty dictionary replaces any existing metadata.

public System.Collections.Generic.IDictionary<string,object>? AdditionalMetadata { get; init; }

Property Value

System.Collections.Generic.IDictionary<System.String,System.Object>

UpdateInvoiceRequestDto.Category Property

The invoice category classification (e.g., Groceries, Entertainment, Utilities). Defaults to NOT_DEFINED if not specified.

public arolariu.Backend.Domain.Invoices.DDD.AggregatorRoots.Invoices.InvoiceCategory Category { get; init; }

Property Value

InvoiceCategory

UpdateInvoiceRequestDto.Description Property

A detailed description of the invoice. Required, but may be empty. Useful for notes, context, or search purposes.

public string Description { get; init; }

Property Value

System.String

UpdateInvoiceRequestDto.IsImportant Property

Flag indicating if the invoice is marked as important/favorite. Important invoices may appear prominently in UI or be excluded from cleanup.

public bool IsImportant { get; init; }

Property Value

System.Boolean

UpdateInvoiceRequestDto.MerchantReference Property

Optional reference to an associated merchant entity by ID. Null if no merchant is linked or if merchant should be cleared.

public System.Nullable<System.Guid> MerchantReference { get; init; }

Property Value

System.Nullable<System.Guid>

UpdateInvoiceRequestDto.Name Property

The invoice name or title. Required. Must be non-empty. Typically a user-friendly identifier like "Groceries - May 2025".

public string Name { get; init; }

Property Value

System.String

UpdateInvoiceRequestDto.PaymentInformation Property

Payment details including currency, total amount, tax, and payment method. Required for proper financial tracking and reporting.

public arolariu.Backend.Domain.Invoices.DDD.ValueObjects.PaymentInformation PaymentInformation { get; init; }

Property Value

PaymentInformation

Methods

UpdateInvoiceRequestDto.ToInvoice(Guid, Guid) Method

Converts this DTO to an Invoice domain aggregate.

public arolariu.Backend.Domain.Invoices.DDD.AggregatorRoots.Invoices.Invoice ToInvoice(System.Guid invoiceId, System.Guid userIdentifier);

Parameters

invoiceId System.Guid

The existing invoice identifier to preserve. Must match an existing invoice.

userIdentifier System.Guid

The owner's user identifier. Used for authorization and partitioning.

Returns

Invoice
A fully populated Invoice instance ready for persistence.

Remarks

Identity Preservation: The invoiceId and userIdentifier are required to preserve the invoice's identity during the update operation.

Metadata Handling: Metadata values are stored as objects, allowing flexible serialization. Null metadata results in an empty metadata collection.

Merchant Reference: A null MerchantReference is converted to System.Guid.Empty to indicate no merchant association.

UpdateMerchantRequestDto Struct

Request DTO for full merchant replacement operations (HTTP PUT semantics).

public readonly record struct UpdateMerchantRequestDto : System.IEquatable<arolariu.Backend.Domain.Invoices.DTOs.Requests.UpdateMerchantRequestDto>

Implements System.IEquatable<UpdateMerchantRequestDto>

Example

var request = new UpdateMerchantRequestDto(
Name: "Kaufland Iasi Pacurari",
Description: "Updated description with new hours",
Category: MerchantCategory.GROCERY,
Address: new ContactInformation { City = "Iasi", Country = "Romania" },
ParentCompanyId: parentId,
AdditionalMetadata: new Dictionary<string, string> { ["storeCode"] = "IS001" });

var merchant = request.ToMerchant(existingMerchantId);
await merchantService.UpdateAsync(merchant);

Remarks

Purpose: Replaces the entire merchant resource with the provided values. This follows HTTP PUT semantics where all mutable fields are replaced.

Immutability: This is a readonly record struct ensuring thread-safety and value semantics for equality comparisons.

Identity Preservation: The merchant's ID and creation metadata are preserved. Only mutable business fields are replaced.

Relationships: The ParentCompanyId establishes hierarchical grouping for franchise/chain organizations.

See Also

Constructors

UpdateMerchantRequestDto(string, string, MerchantCategory, ContactInformation, Nullable<Guid>, IDictionary<string,string>) Constructor

Request DTO for full merchant replacement operations (HTTP PUT semantics).

public UpdateMerchantRequestDto(string Name, string Description, arolariu.Backend.Domain.Invoices.DDD.Entities.Merchants.MerchantCategory Category, arolariu.Backend.Common.DDD.ValueObjects.ContactInformation? Address, System.Nullable<System.Guid> ParentCompanyId, System.Collections.Generic.IDictionary<string,string>? AdditionalMetadata);

Parameters

Name System.String

The merchant's new display name. Required. Replaces the existing name.

Description System.String

The new detailed description. Required. Replaces the existing description.

Category MerchantCategory

The new category classification. Replaces the existing category.

Address arolariu.Backend.Common.DDD.ValueObjects.ContactInformation

The new structured contact and address information. Null creates an empty arolariu.Backend.Common.DDD.ValueObjects.ContactInformation instance.

ParentCompanyId System.Nullable<System.Guid>

The new parent company reference for hierarchical organization. Null or System.Guid.Empty indicates no parent company.

AdditionalMetadata System.Collections.Generic.IDictionary<System.String,System.String>

The new extensible key-value metadata. Replaces all existing metadata. Null or empty dictionary clears existing metadata.

Example

var request = new UpdateMerchantRequestDto(
Name: "Kaufland Iasi Pacurari",
Description: "Updated description with new hours",
Category: MerchantCategory.GROCERY,
Address: new ContactInformation { City = "Iasi", Country = "Romania" },
ParentCompanyId: parentId,
AdditionalMetadata: new Dictionary<string, string> { ["storeCode"] = "IS001" });

var merchant = request.ToMerchant(existingMerchantId);
await merchantService.UpdateAsync(merchant);

Remarks

Purpose: Replaces the entire merchant resource with the provided values. This follows HTTP PUT semantics where all mutable fields are replaced.

Immutability: This is a readonly record struct ensuring thread-safety and value semantics for equality comparisons.

Identity Preservation: The merchant's ID and creation metadata are preserved. Only mutable business fields are replaced.

Relationships: The ParentCompanyId establishes hierarchical grouping for franchise/chain organizations.

See Also

Properties

UpdateMerchantRequestDto.AdditionalMetadata Property

The new extensible key-value metadata. Replaces all existing metadata. Null or empty dictionary clears existing metadata.

public System.Collections.Generic.IDictionary<string,string>? AdditionalMetadata { get; init; }

Property Value

System.Collections.Generic.IDictionary<System.String,System.String>

UpdateMerchantRequestDto.Address Property

The new structured contact and address information. Null creates an empty arolariu.Backend.Common.DDD.ValueObjects.ContactInformation instance.

public arolariu.Backend.Common.DDD.ValueObjects.ContactInformation? Address { get; init; }

Property Value

arolariu.Backend.Common.DDD.ValueObjects.ContactInformation

UpdateMerchantRequestDto.Category Property

The new category classification. Replaces the existing category.

public arolariu.Backend.Domain.Invoices.DDD.Entities.Merchants.MerchantCategory Category { get; init; }

Property Value

MerchantCategory

UpdateMerchantRequestDto.Description Property

The new detailed description. Required. Replaces the existing description.

public string Description { get; init; }

Property Value

System.String

UpdateMerchantRequestDto.Name Property

The merchant's new display name. Required. Replaces the existing name.

public string Name { get; init; }

Property Value

System.String

UpdateMerchantRequestDto.ParentCompanyId Property

The new parent company reference for hierarchical organization. Null or System.Guid.Empty indicates no parent company.

public System.Nullable<System.Guid> ParentCompanyId { get; init; }

Property Value

System.Nullable<System.Guid>

Methods

UpdateMerchantRequestDto.ToMerchant(Guid) Method

Converts this DTO to a Merchant domain entity.

public arolariu.Backend.Domain.Invoices.DDD.Entities.Merchants.Merchant ToMerchant(System.Guid merchantId);

Parameters

merchantId System.Guid

The existing merchant identifier to preserve. Must match an existing merchant.

Returns

Merchant
A fully populated Merchant instance ready for persistence.

Remarks

Identity Preservation: The merchantId is used to maintain the merchant's identity across the update operation.

Null Handling:

Metadata Handling: The metadata dictionary is copied entry-by-entry to the domain entity's metadata collection.

UpdateProductRequestDto Struct

Request DTO for replacing an existing product within an invoice (PUT semantics).

public readonly record struct UpdateProductRequestDto : System.IEquatable<arolariu.Backend.Domain.Invoices.DTOs.Requests.UpdateProductRequestDto>

Implements System.IEquatable<UpdateProductRequestDto>

Example

// Fix OCR error in product name and price
var request = new UpdateProductRequestDto(
OriginalProductName: "LAPTE ZU2U 1L", // OCR misread
Name: "LAPTE ZUZU 1L", // Corrected
Category: ProductCategory.DAIRY,
Quantity: 2,
QuantityUnit: "buc",
ProductCode: "5941234567890",
Price: 8.99m,
DetectedAllergens: [Allergen.Lactose]);

var updatedProduct = request.ToProduct();

Remarks

Purpose: Enables full replacement of a product's data, typically used to correct OCR errors or update product information after manual review.

Immutability: This is a readonly record struct ensuring thread-safety and value semantics for equality comparisons.

Product Identification: Products within an invoice are identified by their OriginalProductName. The update replaces the entire product data while maintaining its position in the invoice's item collection.

Metadata Flag: When a product is updated via this DTO, its Metadata.IsEdited flag is set to true to track manual modifications.

See Also

Constructors

UpdateProductRequestDto(string, string, ProductCategory, decimal, string, string, decimal, IEnumerable<Allergen>) Constructor

Request DTO for replacing an existing product within an invoice (PUT semantics).

public UpdateProductRequestDto(string OriginalProductName, string Name, arolariu.Backend.Domain.Invoices.DDD.ValueObjects.Products.ProductCategory Category, decimal Quantity, string? QuantityUnit, string? ProductCode, decimal Price, System.Collections.Generic.IEnumerable<arolariu.Backend.Domain.Invoices.DDD.ValueObjects.Allergen>? DetectedAllergens);

Parameters

OriginalProductName System.String

The current name of the product to update. Required. Used to locate the product within the invoice's item collection.

Name System.String

The new name for the product. Required. May be the same as OriginalProductName if only other fields change.

Category ProductCategory

The product category classification. Replaces the existing category.

Quantity System.Decimal

The new quantity of product units. Must be positive.

QuantityUnit System.String

The new unit of measure. Null becomes empty string.

ProductCode System.String

The new SKU or barcode identifier. Null becomes empty string.

Price System.Decimal

The new unit price. Total price is recomputed as Quantity × Price.

DetectedAllergens System.Collections.Generic.IEnumerable<Allergen>

The new collection of detected allergens. Null becomes empty collection.

Example

// Fix OCR error in product name and price
var request = new UpdateProductRequestDto(
OriginalProductName: "LAPTE ZU2U 1L", // OCR misread
Name: "LAPTE ZUZU 1L", // Corrected
Category: ProductCategory.DAIRY,
Quantity: 2,
QuantityUnit: "buc",
ProductCode: "5941234567890",
Price: 8.99m,
DetectedAllergens: [Allergen.Lactose]);

var updatedProduct = request.ToProduct();

Remarks

Purpose: Enables full replacement of a product's data, typically used to correct OCR errors or update product information after manual review.

Immutability: This is a readonly record struct ensuring thread-safety and value semantics for equality comparisons.

Product Identification: Products within an invoice are identified by their OriginalProductName. The update replaces the entire product data while maintaining its position in the invoice's item collection.

Metadata Flag: When a product is updated via this DTO, its Metadata.IsEdited flag is set to true to track manual modifications.

See Also

Properties

UpdateProductRequestDto.Category Property

The product category classification. Replaces the existing category.

public arolariu.Backend.Domain.Invoices.DDD.ValueObjects.Products.ProductCategory Category { get; init; }

Property Value

ProductCategory

UpdateProductRequestDto.DetectedAllergens Property

The new collection of detected allergens. Null becomes empty collection.

public System.Collections.Generic.IEnumerable<arolariu.Backend.Domain.Invoices.DDD.ValueObjects.Allergen>? DetectedAllergens { get; init; }

Property Value

System.Collections.Generic.IEnumerable<Allergen>

UpdateProductRequestDto.Name Property

The new name for the product. Required. May be the same as OriginalProductName if only other fields change.

public string Name { get; init; }

Property Value

System.String

UpdateProductRequestDto.OriginalProductName Property

The current name of the product to update. Required. Used to locate the product within the invoice's item collection.

public string OriginalProductName { get; init; }

Property Value

System.String

UpdateProductRequestDto.Price Property

The new unit price. Total price is recomputed as Quantity × Price.

public decimal Price { get; init; }

Property Value

System.Decimal

UpdateProductRequestDto.ProductCode Property

The new SKU or barcode identifier. Null becomes empty string.

public string? ProductCode { get; init; }

Property Value

System.String

UpdateProductRequestDto.Quantity Property

The new quantity of product units. Must be positive.

public decimal Quantity { get; init; }

Property Value

System.Decimal

UpdateProductRequestDto.QuantityUnit Property

The new unit of measure. Null becomes empty string.

public string? QuantityUnit { get; init; }

Property Value

System.String

Methods

UpdateProductRequestDto.ToProduct() Method

Converts this DTO to a Product domain value object.

public arolariu.Backend.Domain.Invoices.DDD.ValueObjects.Products.Product ToProduct();

Returns

Product
A new Product instance with the updated values.

Remarks

Note: The OriginalProductName is not included in the returned product—it is only used for identification during the update operation.

Null Handling: Optional string fields are converted to empty strings. Optional collections default to empty enumerables.

// was this page useful?