Download ledger/validations.go from Leon4gr45/openmeter: direct link, hf CLI and curl.
- Browser
- Download file 3.28 kB
-
https://huggingface.co/spaces/Leon4gr45/openmeter/resolve/main/ledger/validations.go
- Command line
-
hf download hf://spaces/Leon4gr45/openmeter/ledger/validations.go
-
curl -L -o validations.go https://huggingface.co/spaces/Leon4gr45/openmeter/resolve/main/ledger/validations.go
3.28 kB
| package ledger | |
| import ( | |
| "context" | |
| "github.com/alpacahq/alpacadecimal" | |
| "github.com/samber/lo" | |
| "github.com/openmeterio/openmeter/pkg/currencyx" | |
| "github.com/openmeterio/openmeter/pkg/models" | |
| ) | |
| // ValidateInvariance validates that Debit - Credit = 0 for the given entries. | |
| func ValidateInvariance(ctx context.Context, entries []EntryInput) error { | |
| total := alpacadecimal.NewFromInt(0) | |
| for _, entry := range entries { | |
| total = total.Add(entry.Amount()) | |
| } | |
| if total.IsZero() { | |
| return nil | |
| } | |
| return ErrInvalidTransactionTotal.WithAttrs(models.Attributes{ | |
| "total": total, | |
| "entries": entries, | |
| }) | |
| } | |
| func ValidateRouting(ctx context.Context, entries []EntryInput) error { | |
| // Routing validation is implementation-specific and can be injected by the concrete ledger. | |
| return nil | |
| } | |
| func ValidateEntryInput(ctx context.Context, entry EntryInput) error { | |
| if entry == nil { | |
| return ErrEntryInvalid.WithAttrs(models.Attributes{ | |
| "reason": "entry_required", | |
| }) | |
| } | |
| // Let's validate the address | |
| if err := ValidateAddress(ctx, entry.PostingAddress()); err != nil { | |
| return ErrEntryInvalid.WithAttrs(models.Attributes{ | |
| "reason": "invalid_address", | |
| "error": err, | |
| }) | |
| } | |
| if err := validateEntryAmountPrecision(entry); err != nil { | |
| return err | |
| } | |
| if err := ValidateEntryIdentityKey(entry); err != nil { | |
| return ErrEntryInvalid.WithAttrs(models.Attributes{ | |
| "reason": "invalid_identity_key", | |
| "error": err, | |
| }) | |
| } | |
| return nil | |
| } | |
| func ValidateAddress(ctx context.Context, address PostingAddress) error { | |
| if address == nil { | |
| return ErrAddressInvalid.WithAttrs(models.Attributes{ | |
| "reason": "address_required", | |
| }) | |
| } | |
| return nil | |
| } | |
| func validateEntryAmountPrecision(entry EntryInput) error { | |
| currency, err := currencyx.NewCurrencyBuilder(currencyx.CurrencyTypeFiat). | |
| WithCode(entry.PostingAddress().Route().Route().Currency). | |
| Build() | |
| if err != nil { | |
| return ErrCurrencyInvalid.WithAttrs(models.Attributes{ | |
| "currency": entry.PostingAddress().Route().Route().Currency, | |
| "error": err, | |
| }) | |
| } | |
| amount := entry.Amount() | |
| if currency.IsRoundedToPrecision(amount) { | |
| return nil | |
| } | |
| return ErrTransactionAmountInvalid.WithAttrs(models.Attributes{ | |
| "reason": "amount_not_rounded_to_currency_precision", | |
| "currency": currency.Details().Code, | |
| "amount": amount.String(), | |
| "rounded_amount": currency.RoundToPrecision(amount).String(), | |
| }) | |
| } | |
| func ValidateTransactionInput(ctx context.Context, transaction TransactionInput) error { | |
| return ValidateTransactionInputWith(ctx, transaction, nil) | |
| } | |
| func ValidateTransactionInputWith(ctx context.Context, transaction TransactionInput, routingValidator RoutingValidator) error { | |
| if transaction == nil { | |
| return ErrTransactionInputRequired | |
| } | |
| // Let's validate that the entries add up | |
| if err := ValidateInvariance(ctx, lo.Map(transaction.EntryInputs(), func(e EntryInput, _ int) EntryInput { | |
| return e | |
| })); err != nil { | |
| return err | |
| } | |
| // Let's validate the entries themselves | |
| for _, entry := range transaction.EntryInputs() { | |
| if err := ValidateEntryInput(ctx, entry); err != nil { | |
| return err | |
| } | |
| } | |
| if routingValidator != nil { | |
| if err := routingValidator.ValidateEntries(transaction.EntryInputs()); err != nil { | |
| return err | |
| } | |
| } | |
| return nil | |
| } | |