2023-06-13 13:22:51 +00:00
|
|
|
package repository
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
"time"
|
|
|
|
|
2024-12-16 13:47:40 +00:00
|
|
|
"gitea.pena/PenaSide/treasurer/internal/errors"
|
|
|
|
"gitea.pena/PenaSide/treasurer/internal/models"
|
2023-06-13 13:22:51 +00:00
|
|
|
"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.uber.org/zap"
|
|
|
|
)
|
|
|
|
|
|
|
|
var PaymentFields = struct {
|
|
|
|
ID string
|
|
|
|
UserID string
|
|
|
|
PaymentID string
|
|
|
|
IdempotencePaymentID string
|
|
|
|
ClientIP string
|
|
|
|
Currency string
|
|
|
|
Amount string
|
|
|
|
Type string
|
|
|
|
Status string
|
|
|
|
Completed string
|
|
|
|
IsDeleted string
|
|
|
|
CreatedAt string
|
|
|
|
UpdatedAt string
|
|
|
|
DeletedAt string
|
|
|
|
RawPaymentBody string
|
|
|
|
CallbackHostGRPC string
|
|
|
|
}{
|
|
|
|
ID: "_id",
|
|
|
|
UserID: "userId",
|
|
|
|
PaymentID: "paymentId",
|
|
|
|
IdempotencePaymentID: "idempotencePaymentId",
|
|
|
|
ClientIP: "clientIp",
|
|
|
|
Currency: "currency",
|
|
|
|
Amount: "amount",
|
|
|
|
Type: "type",
|
|
|
|
Status: "status",
|
|
|
|
Completed: "completed",
|
|
|
|
IsDeleted: "isDeleted",
|
|
|
|
CreatedAt: "createdAt",
|
|
|
|
UpdatedAt: "updatedAt",
|
|
|
|
DeletedAt: "deletedAt",
|
|
|
|
RawPaymentBody: "rawPaymentBody",
|
|
|
|
CallbackHostGRPC: "callbackHostGrpc",
|
|
|
|
}
|
|
|
|
|
|
|
|
type PaymentRepositoryDeps struct {
|
|
|
|
Logger *zap.Logger
|
|
|
|
Collection *mongo.Collection
|
|
|
|
}
|
|
|
|
|
|
|
|
type PaymentRepository struct {
|
|
|
|
logger *zap.Logger
|
|
|
|
collection *mongo.Collection
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewPaymentRepository(deps PaymentRepositoryDeps) (*PaymentRepository, errors.Error) {
|
|
|
|
if deps.Logger == nil {
|
|
|
|
return nil, errors.NewWithMessage("Logger in nil on <NewPaymentRepository>", errors.ErrInvalidArgs)
|
|
|
|
}
|
|
|
|
|
|
|
|
if deps.Collection == nil {
|
|
|
|
return nil, errors.NewWithMessage("Collection in nil on <NewPaymentRepository>", errors.ErrInvalidArgs)
|
|
|
|
}
|
|
|
|
|
|
|
|
return &PaymentRepository{
|
|
|
|
logger: deps.Logger,
|
|
|
|
collection: deps.Collection,
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (receiver *PaymentRepository) SetPaymentComplete(ctx context.Context, paymentID string) (*models.Payment, errors.Error) {
|
|
|
|
payment := models.Payment{}
|
|
|
|
options := options.FindOneAndUpdate().SetReturnDocument(options.After)
|
|
|
|
filter := bson.M{PaymentFields.PaymentID: paymentID}
|
|
|
|
update := bson.M{"$set": bson.M{
|
|
|
|
PaymentFields.Completed: true,
|
|
|
|
PaymentFields.UpdatedAt: time.Now(),
|
|
|
|
}}
|
|
|
|
|
|
|
|
if err := receiver.collection.FindOneAndUpdate(ctx, filter, update, options).Decode(&payment); err != nil {
|
|
|
|
receiver.logger.Error("failed to set payment complete on <SetPaymentComplete> of <PaymentRepository>",
|
|
|
|
zap.Error(err),
|
|
|
|
zap.String("paymentID", paymentID),
|
|
|
|
)
|
|
|
|
|
|
|
|
removeErr := errors.NewWithError(
|
|
|
|
fmt.Errorf("failed to set payment complete with <%s> on <SetPaymentComplete> of <PaymentRepository>: %w", paymentID, err),
|
|
|
|
errors.ErrInternalError,
|
|
|
|
)
|
|
|
|
|
|
|
|
if err == mongo.ErrNoDocuments {
|
|
|
|
return nil, removeErr.SetType(errors.ErrNotFound)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil, removeErr
|
|
|
|
}
|
|
|
|
|
|
|
|
return &payment, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (receiver *PaymentRepository) Insert(ctx context.Context, payment *models.Payment) (*models.Payment, errors.Error) {
|
|
|
|
sanitizedPayment := payment.Sanitize()
|
|
|
|
|
|
|
|
result, err := receiver.collection.InsertOne(ctx, sanitizedPayment)
|
|
|
|
if err != nil {
|
|
|
|
receiver.logger.Error("failed to insert payment on <Insert> of <PaymentRepository>",
|
|
|
|
zap.Any("payment", sanitizedPayment),
|
|
|
|
zap.Error(err),
|
|
|
|
)
|
|
|
|
|
|
|
|
return nil, errors.NewWithError(
|
|
|
|
fmt.Errorf("failed to insert payment on <Insert> of <AccountRepository>: %w", err),
|
|
|
|
errors.ErrInternalError,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
insertedID := result.InsertedID.(primitive.ObjectID).Hex()
|
|
|
|
sanitizedPayment.ID = insertedID
|
|
|
|
|
|
|
|
return sanitizedPayment, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (receiver *PaymentRepository) SetPaymentStatus(ctx context.Context, paymentID string, status models.PaymentStatus) (*models.Payment, errors.Error) {
|
|
|
|
payment := models.Payment{}
|
|
|
|
options := options.FindOneAndUpdate().SetReturnDocument(options.After)
|
|
|
|
filter := bson.M{PaymentFields.PaymentID: paymentID}
|
|
|
|
update := bson.M{"$set": bson.M{
|
|
|
|
PaymentFields.Status: status,
|
|
|
|
PaymentFields.UpdatedAt: time.Now(),
|
|
|
|
}}
|
|
|
|
|
|
|
|
if err := receiver.collection.FindOneAndUpdate(ctx, filter, update, options).Decode(&payment); err != nil {
|
|
|
|
receiver.logger.Error("failed to set payment status on <SetPaymentStatus> of <PaymentRepository>",
|
|
|
|
zap.Error(err),
|
|
|
|
zap.String("paymentID", paymentID),
|
|
|
|
)
|
|
|
|
|
|
|
|
removeErr := errors.NewWithError(
|
|
|
|
fmt.Errorf("failed to set payment status with <%s> on <SetPaymentStatus> of <PaymentRepository>: %w", paymentID, err),
|
|
|
|
errors.ErrInternalError,
|
|
|
|
)
|
|
|
|
|
|
|
|
if err == mongo.ErrNoDocuments {
|
|
|
|
return nil, removeErr.SetType(errors.ErrNotFound)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil, removeErr
|
|
|
|
}
|
|
|
|
|
|
|
|
return &payment, nil
|
|
|
|
}
|