mirror of
https://github.com/foomo/shop.git
synced 2026-07-01 07:10:08 +00:00
260 lines
7.2 KiB
Go
260 lines
7.2 KiB
Go
package pricerule
|
|
|
|
import (
|
|
"errors"
|
|
"reflect"
|
|
|
|
"github.com/foomo/shop/configuration"
|
|
"github.com/foomo/shop/persistence"
|
|
"github.com/foomo/shop/shop_error"
|
|
"github.com/mitchellh/mapstructure"
|
|
"gopkg.in/mgo.v2"
|
|
"gopkg.in/mgo.v2/bson"
|
|
)
|
|
|
|
//------------------------------------------------------------------
|
|
// ~ CONSTANTS / VARS
|
|
//------------------------------------------------------------------
|
|
|
|
const (
|
|
TypePriceRules string = "pricerules"
|
|
TypePriceRulesVouchers string = "vouchers"
|
|
TypePriceRulesGroups string = "groups"
|
|
)
|
|
|
|
var globalPriceRulePersistors = make(map[string]*persistence.Persistor)
|
|
|
|
var ensuredIndexes = map[string][]mgo.Index{
|
|
TypePriceRules: []mgo.Index{},
|
|
TypePriceRulesVouchers: []mgo.Index{
|
|
mgo.Index{
|
|
Name: "id",
|
|
Key: []string{"id"},
|
|
Unique: false,
|
|
Background: true,
|
|
},
|
|
mgo.Index{
|
|
Name: "vouchercode",
|
|
Key: []string{"vouchercode"},
|
|
Unique: false,
|
|
Background: true,
|
|
},
|
|
mgo.Index{
|
|
Name: "id-customerid",
|
|
Key: []string{"id", "customerid"},
|
|
Unique: false,
|
|
Background: true,
|
|
},
|
|
},
|
|
TypePriceRulesGroups: []mgo.Index{},
|
|
}
|
|
|
|
// PriceRuleCustomProvider - in case obj is extended
|
|
type PriceRuleCustomProvider interface {
|
|
NewPriceRuleCustom() interface{}
|
|
NewVoucherCustom() interface{}
|
|
NewGroupCustom() interface{}
|
|
Fields() *bson.M
|
|
}
|
|
|
|
//------------------------------------------------------------------
|
|
// ~ PUBLIC METHODS
|
|
//------------------------------------------------------------------
|
|
|
|
// GetGroupByID returns the group with id
|
|
func GetGroupByID(ID string, customProvider PriceRuleCustomProvider) (*Group, error) {
|
|
gr, err := findOneObj(new(Group), &bson.M{"id": ID}, nil, "", customProvider)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return gr.(*Group), err
|
|
}
|
|
|
|
// GetVoucherByID returns the voucher with id
|
|
func GetVoucherByID(ID string, customProvider PriceRuleCustomProvider) (*Voucher, error) {
|
|
voucher, err := findOneObj(new(Voucher), &bson.M{"id": ID}, nil, "", customProvider)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return voucher.(*Voucher), err
|
|
}
|
|
|
|
// GetVoucherByCode returns the voucher with code
|
|
func GetVoucherByCode(code string, customProvider PriceRuleCustomProvider) (*Voucher, error) {
|
|
voucher, err := findOneObj(new(Voucher), &bson.M{"vouchercode": code}, nil, "", customProvider)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return voucher.(*Voucher), err
|
|
}
|
|
|
|
// GetPriceRuleByID returns the group with id
|
|
func GetPriceRuleByID(ID string, customProvider PriceRuleCustomProvider) (*PriceRule, error) {
|
|
priceRule, err := findOneObj(new(PriceRule), &bson.M{"id": ID}, nil, "", customProvider)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return priceRule.(*PriceRule), err
|
|
}
|
|
|
|
// ObjectOfTypeAlreadyExistsInDB checks if a customer with given customerID already exists in the database
|
|
func ObjectOfTypeAlreadyExistsInDB(ID string, objOfType interface{}) (bool, error) {
|
|
p := GetPersistorForObject(objOfType)
|
|
session, collection := p.GetCollection()
|
|
defer session.Close()
|
|
|
|
q := collection.Find(&bson.M{"id": ID})
|
|
|
|
count, err := q.Count()
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
return count > 0, nil
|
|
}
|
|
|
|
// GetPersistorForObject - fun using reflection/
|
|
func GetPersistorForObject(obj interface{}) *persistence.Persistor {
|
|
//val := reflect.ValueOf(obj)
|
|
switch obj.(type) { //attrType.String() {
|
|
case *Group:
|
|
return getPriceRulePersistorForType(TypePriceRulesGroups)
|
|
case *Voucher:
|
|
return getPriceRulePersistorForType(TypePriceRulesVouchers)
|
|
case *PriceRule:
|
|
return getPriceRulePersistorForType(TypePriceRules)
|
|
default:
|
|
attrType := reflect.TypeOf(obj)
|
|
panic("unsupported persistor for type" + attrType.Name())
|
|
}
|
|
}
|
|
|
|
// Returns GLOBAL_PERSISTOR. If GLOBAL_PERSISTOR is nil, a new persistor is created, set as GLOBAL_PERSISTOR and returned
|
|
func getPriceRulePersistorForType(persistorType string) *persistence.Persistor {
|
|
|
|
// variables
|
|
indexes := []mgo.Index{}
|
|
url := configuration.GetMongoURL()
|
|
collection := configuration.MONGO_COLLECTION_PRICERULES
|
|
|
|
// switch collection and indices
|
|
switch persistorType {
|
|
case TypePriceRules:
|
|
collection = configuration.MONGO_COLLECTION_PRICERULES
|
|
indexes = ensuredIndexes[TypePriceRules]
|
|
case TypePriceRulesVouchers:
|
|
collection = configuration.MONGO_COLLECTION_PRICERULES_VOUCHERS
|
|
indexes = ensuredIndexes[TypePriceRulesVouchers]
|
|
case TypePriceRulesGroups:
|
|
collection = configuration.MONGO_COLLECTION_PRICERULES_GROUPS
|
|
indexes = ensuredIndexes[TypePriceRulesGroups]
|
|
default:
|
|
panic("type " + persistorType + " does not exist")
|
|
}
|
|
|
|
// check if persistor already exists and return it
|
|
if p, ok := globalPriceRulePersistors[persistorType]; ok {
|
|
return p
|
|
}
|
|
|
|
// create a new persistor
|
|
p, e := persistence.NewPersistorWithIndexes(url, collection, indexes)
|
|
if e != nil || p == nil {
|
|
panic(errors.New("failed to create mongoDB persistor: " + e.Error()))
|
|
}
|
|
globalPriceRulePersistors[persistorType] = p
|
|
return p
|
|
}
|
|
|
|
//------------------------------------------------------------------
|
|
// ~ PRIVATE METHODS
|
|
//------------------------------------------------------------------
|
|
|
|
// findOneGroup returns one Group from the database
|
|
func findOneObj(obj interface{}, find *bson.M, selection *bson.M, sort string, customProvider PriceRuleCustomProvider) (interface{}, error) {
|
|
var p *persistence.Persistor
|
|
p = GetPersistorForObject(obj)
|
|
|
|
if find == nil {
|
|
find = &bson.M{}
|
|
}
|
|
if selection == nil {
|
|
selection = &bson.M{}
|
|
}
|
|
|
|
session, collection := p.GetCollection()
|
|
defer session.Close()
|
|
|
|
if sort != "" {
|
|
err := collection.Find(find).Select(selection).Sort(sort).One(obj)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
} else {
|
|
err := collection.Find(find).Select(selection).One(obj)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
if customProvider != nil {
|
|
var err error
|
|
typedObject, err := mapDecodeObj(obj, customProvider)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
obj = typedObject
|
|
}
|
|
|
|
if obj == nil {
|
|
return nil, errors.New(string(shop_error.ErrorNotFound))
|
|
}
|
|
return obj, nil
|
|
}
|
|
|
|
// mapDecode maps interfaces to specific types provided by customProvider
|
|
func mapDecodeObj(obj interface{}, customProvider PriceRuleCustomProvider) (typedObject interface{}, err error) {
|
|
/* Map CustomerCustom */
|
|
|
|
switch obj.(type) { //attrType.String() {
|
|
case *Group:
|
|
typedObject := obj.(*Group)
|
|
objCustom := customProvider.NewGroupCustom()
|
|
if objCustom != nil && typedObject.Custom != nil {
|
|
err = mapstructure.Decode(typedObject.Custom, objCustom)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
typedObject.Custom = objCustom
|
|
return typedObject, nil
|
|
}
|
|
return typedObject, nil
|
|
case *Voucher:
|
|
typedObject := obj.(*Voucher)
|
|
objCustom := customProvider.NewVoucherCustom()
|
|
if objCustom != nil && typedObject.Custom != nil {
|
|
err = mapstructure.Decode(typedObject.Custom, objCustom)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
typedObject.Custom = objCustom
|
|
return typedObject, nil
|
|
}
|
|
return typedObject, nil
|
|
case *PriceRule:
|
|
typedObject := obj.(*PriceRule)
|
|
objCustom := customProvider.NewPriceRuleCustom()
|
|
if objCustom != nil && typedObject.Custom != nil {
|
|
err = mapstructure.Decode(typedObject.Custom, objCustom)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
typedObject.Custom = objCustom
|
|
return typedObject, nil
|
|
}
|
|
return typedObject, nil
|
|
default:
|
|
return nil, errors.New("unknown type " + reflect.TypeOf(obj).String())
|
|
}
|
|
|
|
}
|