books/backend/Books.Api/Commands/Invoices/CreditNoteCommands.cs
Nicolaj Hartmann 1f75c5d791 Add all backend domain, commands, repositories, and tests
This commit includes all previously untracked backend files:

Domain:
- Accounts, Attachments, BankConnections, Customers
- FiscalYears, Invoices, JournalEntryDrafts
- Orders, Products, UserAccess

Commands & Handlers:
- Full CQRS command structure for all domains

Repositories:
- PostgreSQL repositories for all read models
- Bank transaction and ledger repositories

GraphQL:
- Input types, scalars, and types for all entities
- Mutations and queries

Infrastructure:
- Banking integration (Enable Banking client)
- File storage, Invoicing, Reporting, SAF-T export
- Database migrations (003-029)

Tests:
- Integration tests for GraphQL endpoints
- Domain tests
- Invoicing and reporting tests

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 22:19:42 +01:00

77 lines
2.8 KiB
C#

using Books.Api.Domain.Invoices;
using EventFlow.Commands;
namespace Books.Api.Commands.Invoices;
/// <summary>
/// Creates a new credit note draft for a customer.
/// Credit note number is assigned at creation (Momsloven §52).
/// </summary>
public class CreateCreditNoteCommand(
InvoiceId invoiceId,
string companyId,
string fiscalYearId,
string customerId,
string customerName,
string customerNumber,
string creditNoteNumber,
DateOnly creditNoteDate,
string currency,
string? vatCode,
string? notes,
string? reference,
string createdBy,
string? originalInvoiceId = null,
string? originalInvoiceNumber = null,
string? creditReason = null) : Command<InvoiceAggregate, InvoiceId>(invoiceId)
{
public string CompanyId { get; } = companyId;
public string FiscalYearId { get; } = fiscalYearId;
public string CustomerId { get; } = customerId;
public string CustomerName { get; } = customerName;
public string CustomerNumber { get; } = customerNumber;
public string CreditNoteNumber { get; } = creditNoteNumber;
public DateOnly CreditNoteDate { get; } = creditNoteDate;
public string Currency { get; } = currency;
public string? VatCode { get; } = vatCode;
public string? Notes { get; } = notes;
public string? Reference { get; } = reference;
public string CreatedBy { get; } = createdBy;
public string? OriginalInvoiceId { get; } = originalInvoiceId;
public string? OriginalInvoiceNumber { get; } = originalInvoiceNumber;
public string? CreditReason { get; } = creditReason;
}
/// <summary>
/// Issues a credit note (posts to ledger).
/// This is the credit note equivalent of MarkInvoiceSentCommand.
/// Should be called after successfully posting to the ledger.
/// </summary>
public class IssueCreditNoteCommand(
InvoiceId invoiceId,
string ledgerTransactionId,
string issuedBy) : Command<InvoiceAggregate, InvoiceId>(invoiceId)
{
public string LedgerTransactionId { get; } = ledgerTransactionId;
public string IssuedBy { get; } = issuedBy;
}
/// <summary>
/// Applies a credit note to an invoice, reducing the invoice's outstanding balance.
/// </summary>
public class ApplyCreditNoteCommand(
InvoiceId creditNoteId,
string targetInvoiceId,
string targetInvoiceNumber,
decimal amount,
DateOnly appliedDate,
string appliedBy,
string? ledgerTransactionId = null) : Command<InvoiceAggregate, InvoiceId>(creditNoteId)
{
public string TargetInvoiceId { get; } = targetInvoiceId;
public string TargetInvoiceNumber { get; } = targetInvoiceNumber;
public decimal Amount { get; } = amount;
public DateOnly AppliedDate { get; } = appliedDate;
public string AppliedBy { get; } = appliedBy;
public string? LedgerTransactionId { get; } = ledgerTransactionId;
}