112 lines
3.1 KiB
Go
112 lines
3.1 KiB
Go
package transaction
|
|
|
|
import (
|
|
errors2 "enaklo-pos-be/internal/common/errors"
|
|
"enaklo-pos-be/internal/common/logger"
|
|
"enaklo-pos-be/internal/common/mycontext"
|
|
"enaklo-pos-be/internal/entity"
|
|
"enaklo-pos-be/internal/repository"
|
|
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
type TransactionService struct {
|
|
repo repository.TransactionRepository
|
|
wallet repository.WalletRepository
|
|
trx repository.Trx
|
|
}
|
|
|
|
func New(repo repository.TransactionRepository,
|
|
wallet repository.WalletRepository,
|
|
trx repository.Trx,
|
|
) *TransactionService {
|
|
return &TransactionService{
|
|
repo: repo,
|
|
wallet: wallet,
|
|
trx: trx,
|
|
}
|
|
}
|
|
|
|
func (s *TransactionService) GetTransactionList(ctx mycontext.Context,
|
|
req entity.TransactionSearch) ([]*entity.TransactionList, int, error) {
|
|
transactions, total, err := s.repo.GetTransactionList(ctx, req)
|
|
if err != nil {
|
|
logger.ContextLogger(ctx).Error("error when get all products", zap.Error(err))
|
|
return nil, 0, err
|
|
}
|
|
|
|
return transactions, total, nil
|
|
}
|
|
|
|
func (s *TransactionService) Approval(ctx mycontext.Context, req *entity.TransactionApproval) error {
|
|
// Start a transaction
|
|
trx, _ := s.trx.Begin(ctx)
|
|
|
|
// Retrieve the transaction by ID
|
|
transaction, err := s.repo.FindByID(ctx, req.TransactionID)
|
|
if err != nil {
|
|
logger.ContextLogger(ctx).Error("error when retrieving transaction by ID", zap.Error(err))
|
|
trx.Rollback()
|
|
return errors2.ErrorInternalServer
|
|
}
|
|
|
|
if transaction.Status != "WAITING_APPROVAL" {
|
|
return errors2.NewError(errors2.ErrorBadRequest.ErrorType(),
|
|
"invalid state, transaction already approved or rejected")
|
|
}
|
|
|
|
// Retrieve the wallet associated with the transaction's partner ID
|
|
wallet, err := s.wallet.GetForUpdate(ctx, trx, transaction.PartnerID)
|
|
if err != nil {
|
|
logger.ContextLogger(ctx).Error("error retrieving wallet by partner ID", zap.Error(err))
|
|
trx.Rollback()
|
|
return errors2.ErrorInternalServer
|
|
}
|
|
|
|
// Approve or Reject the transaction
|
|
switch req.Status {
|
|
case "APPROVE":
|
|
if wallet.AuthBalance < transaction.Amount {
|
|
trx.Rollback()
|
|
return errors2.ErrorInsufficientBalance
|
|
}
|
|
wallet.AuthBalance -= transaction.Amount
|
|
transaction.Status = "APPROVED"
|
|
case "REJECT":
|
|
if wallet.AuthBalance < transaction.Amount {
|
|
trx.Rollback()
|
|
return errors2.ErrorInsufficientBalance
|
|
}
|
|
transaction.Status = "REJECTED"
|
|
wallet.AuthBalance -= transaction.Amount
|
|
wallet.Balance += transaction.Amount
|
|
|
|
default:
|
|
trx.Rollback()
|
|
return errors2.ErrorBadRequest
|
|
}
|
|
|
|
// Update the wallet with the new balances
|
|
if _, err := s.wallet.Update(ctx, trx, wallet); err != nil {
|
|
logger.ContextLogger(ctx).Error("error updating wallet balance", zap.Error(err))
|
|
trx.Rollback()
|
|
return errors2.ErrorInternalServer
|
|
}
|
|
|
|
// Update the transaction status and persist changes
|
|
transaction.UpdatedBy = ctx.RequestedBy()
|
|
|
|
if _, err := s.repo.Update(ctx, trx, transaction); err != nil {
|
|
logger.ContextLogger(ctx).Error("error updating transaction status", zap.Error(err))
|
|
trx.Rollback()
|
|
return errors2.ErrorInternalServer
|
|
}
|
|
|
|
if err := trx.Commit().Error; err != nil {
|
|
logger.ContextLogger(ctx).Error("error committing transaction", zap.Error(err))
|
|
return errors2.ErrorInternalServer
|
|
}
|
|
|
|
return nil
|
|
}
|