File size: 2,476 Bytes
429334c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | package charges
import (
"errors"
"fmt"
"github.com/samber/lo"
"github.com/openmeterio/openmeter/openmeter/billing/charges/meta"
"github.com/openmeterio/openmeter/openmeter/customer"
"github.com/openmeterio/openmeter/pkg/models"
)
type Patch = meta.Patch
var _ models.Validator = (*ApplyPatchesInput)(nil)
type ApplyPatchesInput struct {
CustomerID customer.CustomerID
Creates ChargeIntents
// PatchesByChargeID is a map of charge ID to the patches to apply to the charge. This format is used to make sure
// there's only a single patch affecting a single charge.
PatchesByChargeID map[string]Patch
}
func (i ApplyPatchesInput) Validate() error {
var errs []error
if err := i.CustomerID.Validate(); err != nil {
errs = append(errs, fmt.Errorf("customer ID: %w", err))
}
if err := i.Creates.Validate(); err != nil {
errs = append(errs, fmt.Errorf("creates: %w", err))
}
for chargeID, patch := range i.PatchesByChargeID {
if chargeID == "" {
errs = append(errs, fmt.Errorf("charge ID is required"))
continue
}
if patch == nil {
errs = append(errs, fmt.Errorf("patch for charge ID %s is nil", chargeID))
continue
}
if err := patch.Validate(); err != nil {
errs = append(errs, fmt.Errorf("patch for charge ID %s: %w", chargeID, err))
}
}
return models.NewNillableGenericValidationError(errors.Join(errs...))
}
// ConcatenateApplyPatchesInputs concatenates the given inputs into a single input, while enforcing uniqueness constraints.
func ConcatenateApplyPatchesInputs(inputs ...ApplyPatchesInput) (ApplyPatchesInput, error) {
if len(inputs) == 0 {
return ApplyPatchesInput{}, nil
}
result := ApplyPatchesInput{
CustomerID: inputs[0].CustomerID,
Creates: make(ChargeIntents, 0, lo.SumBy(inputs, func(input ApplyPatchesInput) int { return len(input.Creates) })),
PatchesByChargeID: make(map[string]Patch, lo.SumBy(inputs, func(input ApplyPatchesInput) int { return len(input.PatchesByChargeID) })),
}
for _, input := range inputs {
result.Creates = append(result.Creates, input.Creates...)
for chargeID, patch := range input.PatchesByChargeID {
if _, exists := result.PatchesByChargeID[chargeID]; exists {
return ApplyPatchesInput{}, fmt.Errorf("duplicate charge ID: %s", chargeID)
}
result.PatchesByChargeID[chargeID] = patch
}
}
return result, nil
}
func (i ApplyPatchesInput) IsEmpty() bool {
return len(i.PatchesByChargeID) == 0 && len(i.Creates) == 0
}
|