112 lines
3.1 KiB
Go
Raw Normal View History

2024-07-30 23:39:55 +07:00
package transaction
import (
2025-03-04 20:36:17 +07:00
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"
2024-07-30 23:39:55 +07:00
"go.uber.org/zap"
)
type TransactionService struct {
2024-07-31 23:54:17 +07:00
repo repository.TransactionRepository
wallet repository.WalletRepository
trx repository.TransactionManager
2024-07-30 23:39:55 +07:00
}
2024-07-31 23:54:17 +07:00
func New(repo repository.TransactionRepository,
wallet repository.WalletRepository,
trx repository.TransactionManager,
) *TransactionService {
2024-07-30 23:39:55 +07:00
return &TransactionService{
2024-07-31 23:54:17 +07:00
repo: repo,
wallet: wallet,
trx: trx,
2024-07-30 23:39:55 +07:00
}
}
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
}
2024-07-31 23:54:17 +07:00
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
2024-08-02 15:08:42 +07:00
transaction.Status = "APPROVED"
2024-07-31 23:54:17 +07:00
case "REJECT":
if wallet.AuthBalance < transaction.Amount {
trx.Rollback()
return errors2.ErrorInsufficientBalance
}
2024-08-02 15:08:42 +07:00
transaction.Status = "REJECTED"
2024-07-31 23:54:17 +07:00
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
}