using System.Text.Json.Serialization;
namespace Books.Api.AiBookkeeper;
///
/// Client for the AI Bookkeeper service that analyzes documents
/// and suggests bookkeeping entries.
///
public interface IAiBookkeeperClient
{
///
/// Process a document (invoice, receipt, etc.) and get AI-suggested bookkeeping.
///
/// The document file stream
/// Original filename
/// MIME type of the document
/// Chart of accounts data
/// Cancellation token
/// AI extraction and suggested bookkeeping
Task ProcessDocumentAsync(
Stream document,
string fileName,
string contentType,
ChartOfAccountsDto chartOfAccounts,
CancellationToken cancellationToken = default);
}
///
/// Response from AI Bookkeeper document processing.
///
public class AiBookkeeperResponse
{
///
/// Whether the document was successfully analyzed.
///
public bool Success { get; set; }
///
/// Error message if processing failed.
///
public string? ErrorMessage { get; set; }
///
/// Extracted document information.
///
public DocumentExtraction? Extraction { get; set; }
///
/// Suggested bookkeeping entry.
///
public BookkeepingSuggestion? Suggestion { get; set; }
}
///
/// Extracted information from the document.
///
public class DocumentExtraction
{
///
/// Detected document type (invoice, receipt, credit_note, etc.)
///
[JsonPropertyName("documentType")]
public string? DocumentType { get; set; }
///
/// Vendor/supplier name.
///
[JsonPropertyName("vendor")]
public string? Vendor { get; set; }
///
/// Vendor CVR number (Danish company registration).
///
[JsonPropertyName("vendorCvr")]
public string? VendorCvr { get; set; }
///
/// Invoice/receipt number.
///
[JsonPropertyName("invoiceNumber")]
public string? InvoiceNumber { get; set; }
///
/// Document date.
///
[JsonPropertyName("date")]
public DateOnly? Date { get; set; }
///
/// Due date (for invoices).
///
[JsonPropertyName("dueDate")]
public DateOnly? DueDate { get; set; }
///
/// Total amount including VAT.
///
[JsonPropertyName("totalAmount")]
public decimal? TotalAmount { get; set; }
///
/// Amount excluding VAT.
///
[JsonPropertyName("amountExVat")]
public decimal? AmountExVat { get; set; }
///
/// VAT amount.
///
[JsonPropertyName("vatAmount")]
public decimal? VatAmount { get; set; }
///
/// Currency code (default DKK).
///
[JsonPropertyName("currency")]
public string Currency { get; set; } = "DKK";
///
/// Extracted line items.
///
[JsonPropertyName("lineItems")]
public List LineItems { get; set; } = [];
///
/// Payment reference (FIK, girocard number, etc.)
///
[JsonPropertyName("paymentReference")]
public string? PaymentReference { get; set; }
///
/// Raw text extracted from the document.
///
[JsonPropertyName("rawText")]
public string? RawText { get; set; }
}
///
/// Extracted line item from invoice/receipt.
///
public class ExtractedLineItem
{
[JsonPropertyName("description")]
public string? Description { get; set; }
[JsonPropertyName("quantity")]
public decimal? Quantity { get; set; }
[JsonPropertyName("unitPrice")]
public decimal? UnitPrice { get; set; }
[JsonPropertyName("amount")]
public decimal? Amount { get; set; }
[JsonPropertyName("vatRate")]
public decimal? VatRate { get; set; }
}
///
/// AI-suggested bookkeeping entry.
///
public class BookkeepingSuggestion
{
///
/// Suggested description for the journal entry.
///
public string? Description { get; set; }
///
/// Suggested account lines.
///
public List Lines { get; set; } = [];
///
/// Overall confidence in the suggestion (0.0 - 1.0).
///
public decimal Confidence { get; set; }
}
///
/// A suggested bookkeeping line with standard account number.
///
public class SuggestedLine
{
///
/// Standard account number from Erhvervsstyrelsen.
///
public string? StandardAccountNumber { get; set; }
///
/// Suggested account name/description.
///
public string? AccountName { get; set; }
///
/// Debit amount.
///
public decimal DebitAmount { get; set; }
///
/// Credit amount.
///
public decimal CreditAmount { get; set; }
///
/// VAT code (I25, U25, etc.)
///
public string? VatCode { get; set; }
///
/// Confidence in this specific line (0.0 - 1.0).
///
public decimal Confidence { get; set; }
}
///
/// AI service's single account suggestion.
/// The AI analyzes the document and suggests the most appropriate expense account.
///
public class AiAccountSuggestion
{
///
/// Company account number suggested by AI (e.g., "6080" for parking).
///
public required string AccountNumber { get; init; }
///
/// Account name (e.g., "Parkering (gulplade)").
///
public required string AccountName { get; init; }
///
/// VAT code for this account (e.g., "I25" for 25% input VAT).
///
public string? VatCode { get; init; }
///
/// Confidence in the suggestion (0.0 - 1.0).
///
public decimal Confidence { get; init; }
///
/// AI's reasoning for why this account was chosen.
///
public string? Reasoning { get; init; }
}