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
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
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
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
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:
- Address: Empty arolariu.Backend.Common.DDD.ValueObjects.ContactInformation.
- ParentCompanyId: System.Guid.Empty.
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:
- NoAnalysis: Skip AI processing.
- CompleteAnalysis: Full extraction and enrichment.
- InvoiceOnly: Extract invoice-level data only.
- InvoiceItemsOnly: Extract line items only.
- InvoiceMerchantOnly: Extract merchant data only.
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:
- NoAnalysis: Skip AI processing.
- CompleteAnalysis: Full extraction and enrichment.
- InvoiceOnly: Extract invoice-level data only.
- InvoiceItemsOnly: Extract line items only.
- InvoiceMerchantOnly: Extract merchant data only.
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
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
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
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
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
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
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
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
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
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
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
CreateProductRequestDto.Price Property
The unit price per single quantity. Currency is inherited from the parent invoice.
public decimal Price { get; init; }
Property Value
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
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
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
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
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
ReferencedInvoicescollection. Duplicates are ignored. - DELETE: Removes the specified invoice identifiers from the
merchant's
ReferencedInvoicescollection. 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
ReferencedInvoicescollection. Duplicates are ignored. - DELETE: Removes the specified invoice identifiers from the
merchant's
ReferencedInvoicescollection. 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
MerchantReferencemeans "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
MerchantReferencemeans "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
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
PatchInvoiceRequestDto.Name Property
Optional new name for the invoice. Null or whitespace preserves the existing name.
public string? Name { get; init; }
Property Value
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
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:
- Name: Applied only if non-null and non-whitespace.
- Description: Applied only if non-null and non-whitespace.
- Category: Applied only if has value and not
NOT_DEFINED. - PaymentInformation: Applied only if non-null.
- MerchantReference: Applied only if has value and not
Empty. - IsImportant: Applied only if has value.
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
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
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
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
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
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
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
UpdateMerchantRequestDto.Description Property
The new detailed description. Required. Replaces the existing description.
public string Description { get; init; }
Property Value
UpdateMerchantRequestDto.Name Property
The merchant's new display name. Required. Replaces the existing name.
public string Name { get; init; }
Property Value
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
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:
- Address: Null becomes empty arolariu.Backend.Common.DDD.ValueObjects.ContactInformation.
- ParentCompanyId: Null becomes System.Guid.Empty.
- AdditionalMetadata: Null results in empty metadata.
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
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
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
UpdateProductRequestDto.Price Property
The new unit price. Total price is recomputed as Quantity × Price.
public decimal Price { get; init; }
Property Value
UpdateProductRequestDto.ProductCode Property
The new SKU or barcode identifier. Null becomes empty string.
public string? ProductCode { get; init; }
Property Value
UpdateProductRequestDto.Quantity Property
The new quantity of product units. Must be positive.
public decimal Quantity { get; init; }
Property Value
UpdateProductRequestDto.QuantityUnit Property
The new unit of measure. Null becomes empty string.
public string? QuantityUnit { get; init; }
Property Value
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.