Refactor: Invoice.ApplyPayment and Supporting Domain Logic #59
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
This PR delivers a full domain-level refactor of the
Invoice.ApplyPaymentmethod, refactoring what was previously a large, deeply nested, and imperative method into a clean, extensible, and domain-aligned implementation using established DDD principles and design patterns.The goal of this refactor was to improve readability, encapsulate business logic correctly, and set a strong architectural foundation for future enhancements (eg new invoice types, tax rules, or payment flows).
Key Changes
Business Logic Moved into Domain
All logic related to validation, tax application, and messaging lives entirely within the
Invoiceaggregate root.Introduced guard clauses and intention-revealing private methods to eliminate nested
ifblocks and make theApplyPayment()flow linear and intuitive.Strategy Pattern for Tax Calculation
Replaced hardcoded tax logic with pluggable tax strategies:
StandardInvoiceTaxStrategyCommercialInvoiceTaxStrategySelected via the
InvoiceTaxStrategyFactorybased onInvoiceType, aligning with Open/Closed Principle.Centralised Message Management
Moved all user-facing messages to
InvoiceMessages.cs, now sorted alphabetically and documented.This makes the code easier to maintain and localise if needed.
Improved Testability & Coverage
Existing tests were updated to use the refactored model correctly. Structure now supports testing each strategy or validation path in isolation.
Benefits after refactor
New domain structure
Notes for future developers
All new message constants in
InvoiceMessages.csmust be added in alphabetical order (see comment in file).New invoice types can be supported by:
Avoid placing domain logic in service classes. Services should delegate to the aggregate root (
Invoice).Test results
cc: @re-leased-hiring