Files
sendico/api/ledger/internal/model/ownership.go
Stephan D 62a6631b9a
All checks were successful
ci/woodpecker/push/db Pipeline was successful
ci/woodpecker/push/nats Pipeline was successful
service backend
2025-11-07 18:35:26 +01:00

58 lines
1.7 KiB
Go

package ledger
import (
"time"
"go.mongodb.org/mongo-driver/bson/primitive"
)
// OwnershipRole captures legal roles (not permissions).
type OwnershipRole string
const (
RoleLegalOwner OwnershipRole = "legal_owner"
RoleBeneficialOwner OwnershipRole = "beneficial_owner"
RoleCustodian OwnershipRole = "custodian"
RoleSignatory OwnershipRole = "signatory"
)
type Ownership struct {
OwnerPartyRef primitive.ObjectID `bson:"ownerPartyRef" json:"ownerPartyRef"`
Role OwnershipRole `bson:"role" json:"role"`
SharePct *float64 `bson:"sharePct,omitempty" json:"sharePct,omitempty"` // 0..100; nil = unspecified
From time.Time `bson:"effectiveFrom" json:"effectiveFrom"`
To *time.Time `bson:"effectiveTo,omitempty" json:"effectiveTo,omitempty"` // active if t < To; nil = open
}
func (o *Ownership) Validate() error {
var verr *ValidationError
if o.OwnerPartyRef.IsZero() {
veAdd(&verr, "ownerPartyRef", "required", "owner party reference required")
}
switch o.Role {
case RoleLegalOwner, RoleBeneficialOwner, RoleCustodian, RoleSignatory:
default:
veAdd(&verr, "role", "invalid", "unknown ownership role")
}
if o.SharePct != nil {
if *o.SharePct < 0 || *o.SharePct > 100 {
veAdd(&verr, "sharePct", "out_of_range", "must be between 0 and 100")
}
}
if o.To != nil && o.To.Before(o.From) {
veAdd(&verr, "effectiveTo", "before_from", "must be >= effectiveFrom")
}
return verr
}
func (o *Ownership) ActiveAt(t time.Time) bool {
if t.Before(o.From) {
return false
}
if o.To != nil && !t.Before(*o.To) { // active iff t < To
return false
}
return true
}