Receipt Threshold Validator
Component Detail
Description
Evaluates whether a receipt attachment is required or optional based on the org-configurable monetary threshold (default 100 kr for HLF). Reads the threshold value from organization configuration and exposes a reactive stream so the form UI updates instantly when the claim amount changes.
receipt-threshold-validator
Summaries
The Receipt Threshold Validator enforces the organization's expense policy automatically, reducing reliance on employees knowing the rules. For HLF, the default 100 kr threshold ensures that receipts are only required when they materially impact the audit trail, reducing unnecessary friction for small purchases while maintaining compliance controls where they matter. Because the threshold is organization-configurable, the same system can serve multiple organizations with different policies without code changes — a key capability for scaling the product to new customers. This component is shared across mobile and backend contexts, ensuring policy is enforced consistently regardless of submission channel.
This shared component runs in both mobile and backend execution contexts, which adds coordination overhead — logic must be consistent across platforms or centralized. Its role as a dependency for the Receipt Attachment Indicator means it sits on the critical path for that widget's integration. The reactive stream interface (`getThresholdStatusStream`) requires testing under amount-change scenarios, including boundary values at exactly the threshold amount. Organization configuration loading must be tested with multiple org IDs to confirm isolation.
Since this component has no external dependencies, it can be developed and unit-tested independently early in the sprint, de-risking downstream components. Low complexity but high integration breadth.
The Receipt Threshold Validator is a shared service with no external dependencies, making it a clean, easily testable unit. Its core logic evaluates `claimAmount >= threshold` against a per-org config value loaded via `getThresholdForOrg(orgId)`. The reactive interface `getThresholdStatusStream(Stream
Cache org configuration to avoid repeated reads on each amount change. Boundary condition: treat `claimAmount == threshold` as required.
Responsibilities
- Load org-specific receipt threshold from configuration
- Determine if receipt is required given a claim amount
- Expose reactive threshold status stream for UI binding
- Support multiple organizations with different threshold values
Interfaces
isReceiptRequired(double claimAmount, String orgId)
getThresholdForOrg(String orgId)
getThresholdStatusStream(Stream<double> amountStream, String orgId)
validateSubmission(double claimAmount, bool hasAttachment, String orgId)
Relationships
Related Data Entities (3)
Data entities managed by this component