openmeter / taxcode /taxcode.go
Leon4gr45's picture
Upload folder using huggingface_hub (part 7)
16cdcb7 verified
Raw
History Blame Contribute Delete
5.61 kB
package taxcode
import (
"errors"
"regexp"
"github.com/samber/lo"
"github.com/openmeterio/openmeter/openmeter/app"
"github.com/openmeterio/openmeter/pkg/models"
)
var TaxCodeStripeRegexp = regexp.MustCompile(`^txcd_\d{8}$`)
const ProviderDefaultTaxCodeKey = "default"
// TaxCodeAppMapping represents a mapping of an app type to a tax code.
type TaxCodeAppMapping struct {
AppType app.AppType `json:"app_type"`
TaxCode string `json:"tax_code"`
}
func (t TaxCodeAppMapping) Validate() error {
var errs []error
if err := t.AppType.Validate(); err != nil {
errs = append(errs, err)
}
if t.TaxCode == "" {
errs = append(errs, ErrTaxCodeEmpty)
} else {
switch t.AppType {
case app.AppTypeStripe:
if !TaxCodeStripeRegexp.MatchString(t.TaxCode) {
errs = append(errs, ErrTaxCodeStripeInvalid)
}
}
}
return models.NewNillableGenericValidationError(errors.Join(errs...))
}
// TaxCodeAppMappings is a list of TaxCodeAppMapping.
type TaxCodeAppMappings []TaxCodeAppMapping
func (t TaxCodeAppMappings) Validate() error {
var errs []error
appTypes := lo.UniqBy(t, func(t TaxCodeAppMapping) app.AppType {
return t.AppType
})
if len(appTypes) != len(t) {
errs = append(errs, ErrAppTypesMustBeUnique)
}
for _, t := range t {
if err := t.Validate(); err != nil {
errs = append(errs, err)
}
}
return models.NewNillableGenericValidationError(errors.Join(errs...))
}
// TaxCode represents a tax code with mappings to app types.
type TaxCode struct {
models.NamespacedID
models.ManagedModel
// Key is the unique key for TaxCode.
Key string `json:"key"`
// Name is the display name for TaxCode.
Name string `json:"name"`
// Description is the description for TaxCode.
Description *string `json:"description,omitempty"`
// AppMappings is the mapping of app types to tax codes.
AppMappings TaxCodeAppMappings `json:"app_mappings"`
// Metadata
Metadata models.Metadata `json:"metadata,omitempty"`
// Annotations are system-managed key/value pairs stored alongside the tax code.
Annotations models.Annotations `json:"annotations,omitempty"`
}
// Equal returns true when both TaxCode values carry identical semantic data.
// Compares ID, Namespace, Key, Name, Description, and AppMappings.
// ManagedModel timestamps, Metadata, and Annotations are excluded.
func (t *TaxCode) Equal(v *TaxCode) bool {
if t == nil && v == nil {
return true
}
if t == nil || v == nil {
return false
}
if t.ID != v.ID || t.Namespace != v.Namespace {
return false
}
if t.Key != v.Key || t.Name != v.Name {
return false
}
if (t.Description == nil) != (v.Description == nil) {
return false
}
if t.Description != nil && *t.Description != *v.Description {
return false
}
if len(t.AppMappings) != len(v.AppMappings) {
return false
}
left := lo.SliceToMap(t.AppMappings, func(m TaxCodeAppMapping) (app.AppType, string) {
return m.AppType, m.TaxCode
})
for _, m := range v.AppMappings {
code, ok := left[m.AppType]
if !ok || code != m.TaxCode {
return false
}
}
return true
}
// IsManagedBySystem returns true when this tax code was auto-created by the system.
func (t TaxCode) IsManagedBySystem() bool {
v, ok := t.Annotations[AnnotationKeyManagedBy]
if !ok {
return false
}
s, ok := v.(string)
return ok && s == AnnotationValueManagedBySystem
}
// GetAppMapping returns the app mapping for the given app type, if it exists.
func (t TaxCode) GetAppMapping(appType app.AppType) (TaxCodeAppMapping, bool) {
return lo.Find(t.AppMappings, func(m TaxCodeAppMapping) bool {
return m.AppType == appType
})
}
func (t TaxCode) Validate() error {
var errs []error
if err := t.NamespacedID.Validate(); err != nil {
errs = append(errs, err)
}
if err := t.ManagedModel.Validate(); err != nil {
errs = append(errs, err)
}
if err := t.AppMappings.Validate(); err != nil {
errs = append(errs, err)
}
return models.NewNillableGenericValidationError(errors.Join(errs...))
}
// OrganizationDefaultTaxCodesExpand controls which related objects are loaded.
type OrganizationDefaultTaxCodesExpand struct {
InvoicingTaxCode bool
CreditGrantTaxCode bool
}
// OrganizationDefaultTaxCodesExpandAll loads all related objects.
var OrganizationDefaultTaxCodesExpandAll = OrganizationDefaultTaxCodesExpand{
InvoicingTaxCode: true,
CreditGrantTaxCode: true,
}
// OrganizationDefaultTaxCodes stores the per-namespace default tax code references.
type OrganizationDefaultTaxCodes struct {
models.NamespacedID
models.ManagedModel
InvoicingTaxCodeID string `json:"invoicing_tax_code_id"`
InvoicingTaxCode *TaxCode `json:"invoicing_tax_code,omitempty"`
CreditGrantTaxCodeID string `json:"credit_grant_tax_code_id"`
CreditGrantTaxCode *TaxCode `json:"credit_grant_tax_code,omitempty"`
}
func (o OrganizationDefaultTaxCodes) Validate() error {
var errs []error
if err := o.NamespacedID.Validate(); err != nil {
errs = append(errs, err)
}
if err := o.ManagedModel.Validate(); err != nil {
errs = append(errs, err)
}
if o.InvoicingTaxCodeID == "" {
errs = append(errs, ErrResourceIDEmpty.WithPathString("invoicing_tax_code_id"))
}
if o.CreditGrantTaxCodeID == "" {
errs = append(errs, ErrResourceIDEmpty.WithPathString("credit_grant_tax_code_id"))
}
if o.InvoicingTaxCode != nil {
if err := o.InvoicingTaxCode.Validate(); err != nil {
errs = append(errs, err)
}
}
if o.CreditGrantTaxCode != nil {
if err := o.CreditGrantTaxCode.Validate(); err != nil {
errs = append(errs, err)
}
}
return models.NewNillableGenericValidationError(errors.Join(errs...))
}