89 lines
3.7 KiB
Go
89 lines
3.7 KiB
Go
package payments
|
|
|
|
import (
|
|
"context"
|
|
|
|
db "git.sendico.io/tech/sxchnge/shared/database"
|
|
deps "git.sendico.io/tech/sxchnge/shared/database/dependencies"
|
|
"git.sendico.io/tech/sxchnge/shared/database/repository"
|
|
"git.sendico.io/tech/sxchnge/shared/database/repository/builder"
|
|
ri "git.sendico.io/tech/sxchnge/shared/database/repository/index"
|
|
"git.sendico.io/tech/sxchnge/shared/database/source"
|
|
"go.mongodb.org/mongo-driver/v2/bson"
|
|
)
|
|
|
|
type Store interface {
|
|
Create(context.Context, *Record) error
|
|
Get(context.Context, bson.ObjectID, bson.ObjectID, string) (*Record, error)
|
|
ByKey(context.Context, bson.ObjectID, string, string) (*Record, error)
|
|
List(context.Context, bson.ObjectID, string) ([]Record, error)
|
|
Authorize(context.Context, *Record, string) error
|
|
Attach(context.Context, *Record, string) error
|
|
}
|
|
type mongoStore struct{ records repository.Repository }
|
|
|
|
func OpenStore(factory db.Factory) (Store, error) {
|
|
d, err := deps.ResolveDependencies(factory)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
r := repository.CreateRepository(source.Majority(d.Database), "payment_quotes")
|
|
err = r.CreateIndex(&ri.Definition{Name: "customer_execution_key", Unique: true, Keys: []ri.Key{{Field: "customer", Sort: ri.Asc}, {Field: "namespace", Sort: ri.Asc}, {Field: "key", Sort: ri.Asc}}, PartialFilter: repository.Query().Comparison(repository.Field("key"), builder.Gt, "")})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if err = r.CreateIndex(&ri.Definition{Name: "provider_quote_unique", Unique: true, Keys: []ri.Key{{Field: "namespace", Sort: ri.Asc}, {Field: "providerQuote", Sort: ri.Asc}}, PartialFilter: repository.Query().Comparison(repository.Field("providerQuote"), builder.Gt, "")}); err != nil {
|
|
return nil, err
|
|
}
|
|
return &mongoStore{r}, nil
|
|
}
|
|
func scope(customer bson.ObjectID, namespace string) repository.FilterQuery {
|
|
return repository.Query().Filter(repository.Field("customer"), customer).Filter(repository.Field("namespace"), namespace)
|
|
}
|
|
func (s *mongoStore) Create(ctx context.Context, r *Record) error {
|
|
return s.records.Insert(ctx, r, nil)
|
|
}
|
|
func (s *mongoStore) Get(ctx context.Context, id, customer bson.ObjectID, namespace string) (*Record, error) {
|
|
r := &Record{}
|
|
err := s.records.FindOneByFilter(ctx, scope(customer, namespace).Filter(repository.IDField(), id), r)
|
|
return r, err
|
|
}
|
|
func (s *mongoStore) ByKey(ctx context.Context, customer bson.ObjectID, namespace, key string) (*Record, error) {
|
|
r := &Record{}
|
|
err := s.records.FindOneByFilter(ctx, scope(customer, namespace).Filter(repository.Field("key"), key), r)
|
|
return r, err
|
|
}
|
|
func (s *mongoStore) List(ctx context.Context, customer bson.ObjectID, namespace string) ([]Record, error) {
|
|
var rows []Record
|
|
err := s.records.FindAllByFilter(ctx, scope(customer, namespace).Comparison(repository.Field("key"), builder.Gt, "").Sort(repository.Field("createdAt"), true), &rows)
|
|
return rows, err
|
|
}
|
|
func (s *mongoStore) Authorize(ctx context.Context, r *Record, key string) error {
|
|
matched, err := s.records.PatchOneByFilter(ctx, scope(r.Customer, r.Namespace).Filter(repository.IDField(), r.ID).Filter(repository.Field("key"), ""), repository.Patch().Set(repository.Field("key"), key), &Record{})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if !matched {
|
|
return Uncertain
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (s *mongoStore) Attach(ctx context.Context, r *Record, id string) error {
|
|
matched, err := s.records.PatchOneByFilter(ctx, scope(r.Customer, r.Namespace).Filter(repository.IDField(), r.ID).Filter(repository.Field("payment"), ""), repository.Patch().Set(repository.Field("payment"), id), &Record{})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if matched {
|
|
return nil
|
|
}
|
|
current, err := s.Get(ctx, r.ID, r.Customer, r.Namespace)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if current.Payment != id {
|
|
return Uncertain
|
|
}
|
|
return nil
|
|
}
|