484 lines
17 KiB
Plaintext
484 lines
17 KiB
Plaintext
|
package repository
|
|||
|
|
|||
|
import (
|
|||
|
"context"
|
|||
|
"time"
|
|||
|
"fmt"
|
|||
|
|
|||
|
"github.com/sirupsen/logrus"
|
|||
|
"go.mongodb.org/mongo-driver/bson"
|
|||
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
|||
|
"go.mongodb.org/mongo-driver/mongo"
|
|||
|
"go.mongodb.org/mongo-driver/mongo/options"
|
|||
|
"go.mongodb.org/mongo-driver/mongo/readconcern"
|
|||
|
"go.mongodb.org/mongo-driver/mongo/writeconcern"
|
|||
|
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/core"
|
|||
|
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/fields"
|
|||
|
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/models"
|
|||
|
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/utils/expression"
|
|||
|
"penahub.gitlab.yandexcloud.net/pena-services/accruals-service/internal/utils/expression/discount"
|
|||
|
mongoWrapper "penahub.gitlab.yandexcloud.net/pena-services/accruals-service/pkg/mongo"
|
|||
|
)
|
|||
|
|
|||
|
type DiscountRepository struct {
|
|||
|
mongoDB *mongo.Collection
|
|||
|
logger *logrus.Logger
|
|||
|
}
|
|||
|
|
|||
|
func NewDiscountRepository(mongoDB *mongo.Collection, logger *logrus.Logger) *DiscountRepository {
|
|||
|
return &DiscountRepository{
|
|||
|
mongoDB: mongoDB,
|
|||
|
logger: logger,
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
func (receiver *DiscountRepository) getLayer(ctx context.Context, keyGroup, keyParam string, layer uint64, groupPrices, privilegeAmounts map[string]uint64, conditions *core.DiscountConditions) ([]models.Discount, error) {
|
|||
|
conditionFilter := discount.ConditionFilter(conditions, groupPrices, privilegeAmounts, layer)
|
|||
|
|
|||
|
if conditionFilter == nil {
|
|||
|
return []models.Discount{}, ErrEmptyArgs
|
|||
|
}
|
|||
|
|
|||
|
filter := bson.M{
|
|||
|
"$and": []bson.M{
|
|||
|
*conditionFilter,
|
|||
|
{"$or": []bson.M{{fields.Discount.Deprecated: false}, {fields.Discount.Deprecated: nil}}},
|
|||
|
{"$or": []bson.M{{fields.Audit.Deleted: false}, {fields.Audit.Deleted: nil}}},
|
|||
|
},
|
|||
|
}
|
|||
|
|
|||
|
receiver.logger.Info("DR cf", conditionFilter)
|
|||
|
|
|||
|
cursor, err := receiver.mongoDB.Aggregate(ctx, mongo.Pipeline{
|
|||
|
bson.D{
|
|||
|
{Key: "$match", Value: filter},
|
|||
|
},
|
|||
|
bson.D{
|
|||
|
{Key: "$sort", Value: bson.M{
|
|||
|
keyGroup: 1,
|
|||
|
keyParam: -1,
|
|||
|
}},
|
|||
|
},
|
|||
|
bson.D{
|
|||
|
{Key: "$group", Value: bson.M{
|
|||
|
"_id": "$" + keyGroup,
|
|||
|
"doc": bson.M{"$first": "$$ROOT"},
|
|||
|
}},
|
|||
|
},
|
|||
|
bson.D{
|
|||
|
{Key: "$replaceRoot", Value: bson.M{
|
|||
|
"newRoot": "$doc",
|
|||
|
}},
|
|||
|
},
|
|||
|
})
|
|||
|
|
|||
|
if err != nil {
|
|||
|
return []models.Discount{}, err
|
|||
|
}
|
|||
|
|
|||
|
discounts := []models.Discount{}
|
|||
|
|
|||
|
err = cursor.All(ctx, &discounts)
|
|||
|
|
|||
|
fmt.Println("DISCOOOO", discounts)
|
|||
|
return discounts, err
|
|||
|
}
|
|||
|
|
|||
|
func (receiver *DiscountRepository) Determine(ctx context.Context, conditions *core.DiscountConditions) ([]models.Discount, uint64, error) {
|
|||
|
if conditions == nil {
|
|||
|
receiver.logger.Errorln("empty condition on <Determine> of <DiscountRepository>")
|
|||
|
return []models.Discount{}, uint64(0), ErrEmptyArgs
|
|||
|
}
|
|||
|
|
|||
|
var (
|
|||
|
applyed = []models.Discount{}
|
|||
|
keyGroup = "condition.product"
|
|||
|
keyParam = "condition.term"
|
|||
|
//rawPrice = uint64(0)
|
|||
|
groupPrices = map[string]uint64{}
|
|||
|
privilegeAmounts = map[string]uint64{}
|
|||
|
privilegePrices = map[string]uint64{}
|
|||
|
privilegeGroups = map[string]string{}
|
|||
|
priority = make(map[string]struct{})
|
|||
|
noAccept = make(map[string]struct{})
|
|||
|
)
|
|||
|
|
|||
|
for layer := uint64(1); layer < 5; layer++ {
|
|||
|
switch layer {
|
|||
|
case 1:
|
|||
|
for _, condition := range conditions.Optionals {
|
|||
|
if condition.Product == nil || condition.Term == nil {
|
|||
|
continue
|
|||
|
}
|
|||
|
// вычисляем количество привилегий во всей корзине
|
|||
|
fmt.Println("GRP", *condition.Group)
|
|||
|
privilegeAmounts[*condition.Product] += *condition.Term
|
|||
|
privilegePrices[*condition.Product] += *condition.PriceFrom
|
|||
|
if _, ok := privilegeAmounts[*condition.Product]; !ok {
|
|||
|
privilegeGroups[*condition.Product] = *condition.Group
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
discounts, err := receiver.getLayer(ctx, keyGroup, keyParam, layer, privilegeAmounts, groupPrices, conditions)
|
|||
|
if err != nil {
|
|||
|
return []models.Discount{}, uint64(0), err
|
|||
|
}
|
|||
|
// проверяем юзера, если его тип nko, то нужно просто применить скидку на nko к сумму сумм привилегий
|
|||
|
// в getLayer возвращаются все подходящие скидыки для юзера но нужно только nko
|
|||
|
if conditions.Common.UserType == "nko" {
|
|||
|
for _, discount := range discounts {
|
|||
|
if discount.Condition.UserType != nil && *discount.Condition.UserType == "nko" {
|
|||
|
var nkoPrice uint64
|
|||
|
for _, privilegePrice := range privilegePrices {
|
|||
|
nkoPrice += privilegePrice
|
|||
|
}
|
|||
|
return []models.Discount{discount}, uint64(float64(nkoPrice) * discount.Target.Factor), nil
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
// если юзер не nko, то выбираем все скидки за первый слой
|
|||
|
|
|||
|
// сначала делаем все нужные проверки записываем запреты
|
|||
|
for privilege, privilegePrice := range privilegePrices {
|
|||
|
fmt.Println("PREPPRIV", privilege, privilegePrice)
|
|||
|
|
|||
|
// проверки существования скидки за 2 слой noAccept не применям скидки к этой группе если есть такие
|
|||
|
for _, discount := range discounts {
|
|||
|
if discount.Condition.User != nil && *discount.Condition.User == conditions.Common.User && privilegeGroups[privilege] == *discount.Condition.Group && discount.Layer == 2 {
|
|||
|
noAccept[privilegeGroups[privilege]] = struct{}{}
|
|||
|
}
|
|||
|
}
|
|||
|
// если к этой привилегии не было запрета в виде слоя 2, и это скидка для этого юзера и слой 1
|
|||
|
// то применям к этой привилегии скидку только раз, но никак не ограничиваем скидку на группу,
|
|||
|
// только конкретно на привилегию
|
|||
|
for _, discount := range discounts {
|
|||
|
fmt.Println("PREPPRIV1", groupPrices, *discount.Condition.User, conditions.Common.User, privilege, *discount.Condition.Product, discount.Layer )
|
|||
|
if _, ok := noAccept[privilegeGroups[privilege]]; !ok {
|
|||
|
fmt.Println("PREPPRIV3", priority, privilegeGroups)
|
|||
|
if discount.Condition.User != nil && discount.Condition.Product != nil && privilege == *discount.Condition.Product && discount.Layer == 1 {
|
|||
|
fmt.Println("PREPPRIV4", priority, float64(privilegePrice), discount.Target.Products[0].Factor)
|
|||
|
groupPrices[privilegeGroups[privilege]] += uint64(float64(privilegePrice) * discount.Target.Products[0].Factor)
|
|||
|
applyed = append(applyed, discount)
|
|||
|
priority[privilege] = struct{}{}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
for privilege, privilegePrice := range privilegePrices {
|
|||
|
found := false
|
|||
|
// приминеям оставшиеся просто где слой 1 и дозаполняем полностью groupPrices
|
|||
|
for _, discount := range discounts {
|
|||
|
if _, ok := noAccept[privilegeGroups[privilege]]; !ok {
|
|||
|
if _, ok := priority[privilege]; !ok {
|
|||
|
if discount.Condition.Product != nil && privilege == *discount.Condition.Product && discount.Layer == 1 && discount.Condition.User == nil {
|
|||
|
fmt.Println("PREPPRIV5", groupPrices)
|
|||
|
groupPrices[privilegeGroups[privilege]] += uint64(float64(privilegePrice) * discount.Target.Factor)
|
|||
|
applyed = append(applyed, discount)
|
|||
|
found = true
|
|||
|
// сли у нас в ревесте есть такая привилегия но ее нет в пришедших скидках, просто добавляем ее в groupPrices с ключем группы
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
fmt.Println("PREPPRIV2", groupPrices)
|
|||
|
if !found {
|
|||
|
groupPrices[privilegeGroups[privilege]] += privilegePrice
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
keyGroup = "condition.group"
|
|||
|
keyParam = "condition.priceFrom"
|
|||
|
|
|||
|
case 2:
|
|||
|
discounts, err := receiver.getLayer(ctx, keyGroup, keyParam, layer, privilegeAmounts, groupPrices, conditions)
|
|||
|
if err != nil {
|
|||
|
return []models.Discount{}, uint64(0), err
|
|||
|
}
|
|||
|
var price uint64
|
|||
|
// проходимся по мапе где ключ группа и значение прайс за группу с учетом скидки за привилегии
|
|||
|
// ищем в скидках скидку за эту группу, для этого юзера, за 2 слой, если найдена то применяем
|
|||
|
// и добавляем группу в мапу для предотвращения повторного применения скидки за группу
|
|||
|
noAccept := make(map[string]struct{})
|
|||
|
for group, nowPrice := range groupPrices {
|
|||
|
for _, discount := range discounts {
|
|||
|
if discount.Condition.Group != nil && *discount.Condition.Group == group && discount.Layer == 2 && discount.Condition.User != nil && *discount.Condition.User == conditions.Common.User {
|
|||
|
groupPrices[group] += uint64(float64(nowPrice) * discount.Target.Factor)
|
|||
|
noAccept[group] = struct{}{}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
// вычисляем оставшиеся скидки за сервис с ограничениями noAccept
|
|||
|
for group, nowPrice := range groupPrices {
|
|||
|
for _, discount := range discounts {
|
|||
|
if discount.Condition.Group != nil && *discount.Condition.Group == group && discount.Layer == 2 {
|
|||
|
if _, ok := noAccept[*discount.Condition.Group]; !ok {
|
|||
|
groupPrices[group] += uint64(float64(nowPrice) * discount.Target.Factor)
|
|||
|
applyed = append(applyed, discount)
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// вычислям сумму корзины за 1 и 2 слой для 3 слоя
|
|||
|
for _, val := range groupPrices {
|
|||
|
price += val
|
|||
|
}
|
|||
|
|
|||
|
fmt.Println("GPP", conditions.Common.CartPurchasesAmount)
|
|||
|
conditions.Common.CartPurchasesAmount += price
|
|||
|
// если сумма корзины на этом этапе равна 0, то лен(groupPrices) =0 следовательно 3,4 слои тоже будут без скидок
|
|||
|
// заполним groupPrices и почитаем conditions.Common.CartPurchasesAmount
|
|||
|
if conditions.Common.CartPurchasesAmount == 0 {
|
|||
|
for pr, p := range privilegePrices {
|
|||
|
conditions.Common.CartPurchasesAmount += p
|
|||
|
groupPrices[privilegeGroups[pr]] += p
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//restrictions = noAccept
|
|||
|
|
|||
|
keyGroup = "condition.user"
|
|||
|
keyParam = "condition.cartPurchasesAmount"
|
|||
|
|
|||
|
case 3:
|
|||
|
discounts, err := receiver.getLayer(ctx, keyGroup, keyParam, layer, privilegeAmounts, groupPrices, conditions)
|
|||
|
if err != nil {
|
|||
|
return []models.Discount{}, uint64(0), err
|
|||
|
}
|
|||
|
|
|||
|
for _, discount := range discounts {
|
|||
|
if discount.Condition.User != nil && *discount.Condition.User == "" && discount.Layer == 3 {
|
|||
|
for gr, pr := range groupPrices {
|
|||
|
if _, ok := noAccept[gr]; !ok {
|
|||
|
groupPrices[gr] = uint64(float64(pr) * discount.Target.Factor)
|
|||
|
}
|
|||
|
}
|
|||
|
applyed = append(applyed, discount)
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
keyGroup = "condition.userType"
|
|||
|
keyParam = "condition.purchasesAmount"
|
|||
|
|
|||
|
case 4:
|
|||
|
discounts, err := receiver.getLayer(ctx, keyGroup, keyParam, layer, privilegeAmounts, groupPrices, conditions)
|
|||
|
if err != nil {
|
|||
|
return []models.Discount{}, uint64(0), err
|
|||
|
}
|
|||
|
|
|||
|
for _, discount := range discounts {
|
|||
|
if discount.Condition.User != nil && *discount.Condition.User == "" && discount.Layer == 4 {
|
|||
|
for gr, pr := range groupPrices {
|
|||
|
if _, ok := noAccept[gr]; !ok {
|
|||
|
groupPrices[gr] = uint64(float64(pr) * discount.Target.Factor)
|
|||
|
}
|
|||
|
}
|
|||
|
applyed = append(applyed, discount)
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
var finishPrice uint64
|
|||
|
for _, p := range groupPrices {
|
|||
|
finishPrice += p
|
|||
|
}
|
|||
|
|
|||
|
return applyed, finishPrice, nil
|
|||
|
}
|
|||
|
|
|||
|
func (receiver *DiscountRepository) FindByID(ctx context.Context, id string) (*models.Discount, error) {
|
|||
|
objectID, err := primitive.ObjectIDFromHex(id)
|
|||
|
if err != nil {
|
|||
|
receiver.logger.Errorf("failed to parse ObjectID <%s> on <FindByID> of <DiscountRepository>: %v", id, err)
|
|||
|
return nil, ErrInvalidID
|
|||
|
}
|
|||
|
|
|||
|
filter := bson.M{
|
|||
|
fields.Discount.ID: objectID,
|
|||
|
fields.Discount.Deprecated: false,
|
|||
|
fields.Audit.Deleted: false,
|
|||
|
}
|
|||
|
|
|||
|
discount, err := mongoWrapper.FindOne[models.Discount](ctx, &mongoWrapper.RequestSettings{
|
|||
|
Driver: receiver.mongoDB,
|
|||
|
Filter: filter,
|
|||
|
})
|
|||
|
if err != nil {
|
|||
|
receiver.logger.Errorf("failed to find discount <%s> on <FindByID> of <DiscountRepository>: %v", id, err)
|
|||
|
|
|||
|
if err == mongo.ErrNoDocuments {
|
|||
|
return nil, ErrNoRecord
|
|||
|
}
|
|||
|
|
|||
|
return nil, ErrFindRecord
|
|||
|
}
|
|||
|
|
|||
|
return discount, nil
|
|||
|
}
|
|||
|
|
|||
|
func (receiver *DiscountRepository) FindByUserID(ctx context.Context, userID string) ([]models.Discount, error) {
|
|||
|
filter := bson.M{
|
|||
|
"$or": expression.GetValueConditionBSON(fields.DiscountCondition.User, userID),
|
|||
|
fields.Discount.Deprecated: false,
|
|||
|
fields.Audit.Deleted: false,
|
|||
|
}
|
|||
|
|
|||
|
discounts, err := mongoWrapper.Find[models.Discount](ctx, &mongoWrapper.RequestSettings{
|
|||
|
Driver: receiver.mongoDB,
|
|||
|
Filter: filter,
|
|||
|
})
|
|||
|
if err != nil {
|
|||
|
receiver.logger.Errorf("failed to find user <%s> discount on <FindByUserID> of <DiscountRepository>: %v", userID, err)
|
|||
|
return nil, ErrFindRecord
|
|||
|
}
|
|||
|
|
|||
|
return discounts, nil
|
|||
|
}
|
|||
|
|
|||
|
func (receiver *DiscountRepository) FindAll(ctx context.Context) ([]models.Discount, error) {
|
|||
|
filter := bson.M{
|
|||
|
fields.Audit.Deleted: false,
|
|||
|
fields.Discount.Deprecated: false,
|
|||
|
}
|
|||
|
|
|||
|
discounts, err := mongoWrapper.Find[models.Discount](ctx, &mongoWrapper.RequestSettings{
|
|||
|
Driver: receiver.mongoDB,
|
|||
|
Filter: filter,
|
|||
|
})
|
|||
|
if err != nil {
|
|||
|
receiver.logger.Errorf("failed to find all discount on <FindAll> of <DiscountRepository>: %v", err)
|
|||
|
return nil, ErrFindRecord
|
|||
|
}
|
|||
|
|
|||
|
return discounts, nil
|
|||
|
}
|
|||
|
|
|||
|
func (receiver *DiscountRepository) UpdateOne(ctx context.Context, request *core.UpdateDiscountSettings) (*models.Discount, error) {
|
|||
|
if request == nil {
|
|||
|
receiver.logger.Errorln("empy update on <UpdateOne> of <DiscountRepository>")
|
|||
|
return nil, ErrEmptyArgs
|
|||
|
}
|
|||
|
|
|||
|
update := discount.GetUpdateDiscountExpression(request)
|
|||
|
|
|||
|
objectID, err := primitive.ObjectIDFromHex(update.ID)
|
|||
|
if err != nil {
|
|||
|
receiver.logger.Errorf("failed to parse ObjectID <%s> on <UpdateOne> of <DiscountRepository>: %v", update.ID, err)
|
|||
|
return nil, ErrInvalidID
|
|||
|
}
|
|||
|
|
|||
|
updatedDiscount := models.Discount{}
|
|||
|
options := options.FindOneAndUpdate().SetUpsert(false).SetReturnDocument(options.After)
|
|||
|
|
|||
|
filter := bson.M{
|
|||
|
fields.Discount.ID: objectID,
|
|||
|
}
|
|||
|
|
|||
|
if err := receiver.mongoDB.FindOneAndUpdate(ctx, filter, update.Expression, options).Decode(&updatedDiscount); err != nil {
|
|||
|
receiver.logger.Errorf("failed to update discount with id <%s> on <UpdateOne> of <DiscountRepository>: %v", update.ID, err)
|
|||
|
|
|||
|
if err == mongo.ErrNoDocuments {
|
|||
|
return nil, ErrNoRecord
|
|||
|
}
|
|||
|
|
|||
|
return nil, ErrUpdateRecord
|
|||
|
}
|
|||
|
|
|||
|
return &updatedDiscount, nil
|
|||
|
}
|
|||
|
|
|||
|
func (receiver *DiscountRepository) UpdateMany(ctx context.Context, updates []core.UpdateDiscountSettings) error {
|
|||
|
if len(updates) < 1 {
|
|||
|
receiver.logger.Errorln("empy updates on <UpdateMany>")
|
|||
|
return ErrEmptyArgs
|
|||
|
}
|
|||
|
|
|||
|
transactionOptions := options.Transaction().
|
|||
|
SetReadConcern(readconcern.Snapshot()).
|
|||
|
SetWriteConcern(writeconcern.New(writeconcern.WMajority()))
|
|||
|
|
|||
|
session, err := receiver.mongoDB.Database().Client().StartSession()
|
|||
|
if err != nil {
|
|||
|
receiver.logger.Errorln("failed to start session on <UpdateMany> of <DiscountRepository>")
|
|||
|
return ErrTransactionSessionStart
|
|||
|
}
|
|||
|
|
|||
|
defer session.EndSession(ctx)
|
|||
|
|
|||
|
if _, transactionError := session.WithTransaction(ctx, func(sessionContext mongo.SessionContext) (interface{}, error) {
|
|||
|
for _, update := range updates {
|
|||
|
updateCopy := update
|
|||
|
|
|||
|
if _, err := receiver.UpdateOne(sessionContext, &updateCopy); err != nil {
|
|||
|
receiver.logger.Errorf("failed to update <%s> in transaction on <UpdateMany> of <DiscountRepository>: %v", update.ID, err)
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return nil, nil
|
|||
|
}, transactionOptions); transactionError != nil {
|
|||
|
receiver.logger.Errorf("failed to transaction on <UpdateMany> of <DiscountRepository>: %v", transactionError)
|
|||
|
return ErrTransaction
|
|||
|
}
|
|||
|
|
|||
|
return nil
|
|||
|
}
|
|||
|
|
|||
|
func (receiver *DiscountRepository) Insert(ctx context.Context, discount *models.Discount) (string, error) {
|
|||
|
if discount.Condition.User != nil && *discount.Condition.User != "" {
|
|||
|
filter := bson.M{"condition.user": *discount.Condition.User, "audit.deleted": false}
|
|||
|
update := bson.M{
|
|||
|
"$set": bson.M{"audit.deleted": true},
|
|||
|
}
|
|||
|
_, err := receiver.mongoDB.UpdateMany(ctx, filter, update)
|
|||
|
if err != nil && err != mongo.ErrNoDocuments {
|
|||
|
return "", ErrAlreadyExistDiscount
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
res, err := receiver.mongoDB.InsertOne(ctx, discount.Sanitize())
|
|||
|
if err != nil {
|
|||
|
receiver.logger.Errorf("failed to insert record on <Insert> of <DiscountRepository>: %v", err)
|
|||
|
return "", ErrInsertRecord
|
|||
|
}
|
|||
|
|
|||
|
return res.InsertedID.(primitive.ObjectID).Hex(), nil
|
|||
|
}
|
|||
|
|
|||
|
func (receiver *DiscountRepository) DeleteByID(ctx context.Context, id string) (*models.Discount, error) {
|
|||
|
objectID, err := primitive.ObjectIDFromHex(id)
|
|||
|
if err != nil {
|
|||
|
receiver.logger.Errorf("failed to parse ObjectID <%s> on <DeleteByID> of <DiscountRepository>: %v", id, err)
|
|||
|
return nil, ErrInvalidID
|
|||
|
}
|
|||
|
|
|||
|
discount := models.Discount{}
|
|||
|
now := time.Now()
|
|||
|
options := options.FindOneAndUpdate().SetReturnDocument(options.After)
|
|||
|
|
|||
|
update := bson.M{"$set": bson.M{
|
|||
|
fields.Audit.Deleted: true,
|
|||
|
fields.Audit.DeletedAt: now,
|
|||
|
fields.Audit.UpdatedAt: now,
|
|||
|
}}
|
|||
|
|
|||
|
filter := bson.M{
|
|||
|
fields.Discount.ID: objectID,
|
|||
|
}
|
|||
|
|
|||
|
if err := receiver.mongoDB.FindOneAndUpdate(ctx, filter, update, options).Decode(&discount); err != nil {
|
|||
|
receiver.logger.Errorf("failed to set 'deleted=true' with id <%s> on <DeleteByID> of <DiscountRepository>: %v", id, err)
|
|||
|
|
|||
|
if err == mongo.ErrNoDocuments {
|
|||
|
return nil, ErrNoRecord
|
|||
|
}
|
|||
|
|
|||
|
return nil, ErrUpdateRecord
|
|||
|
}
|
|||
|
|
|||
|
return &discount, nil
|
|||
|
}
|