186 lines
5.2 KiB
Go
186 lines
5.2 KiB
Go
package service
|
|
|
|
import (
|
|
"errors"
|
|
"narasi-ahli-be/app/database/entity"
|
|
"narasi-ahli-be/app/module/ebooks/mapper"
|
|
"narasi-ahli-be/app/module/ebooks/repository"
|
|
"narasi-ahli-be/app/module/ebooks/response"
|
|
usersRepository "narasi-ahli-be/app/module/users/repository"
|
|
"narasi-ahli-be/utils/paginator"
|
|
utilSvc "narasi-ahli-be/utils/service"
|
|
"time"
|
|
|
|
"github.com/rs/zerolog"
|
|
)
|
|
|
|
// EbookPurchasesService
|
|
type ebookPurchasesService struct {
|
|
Repo repository.EbookPurchasesRepository
|
|
EbooksRepo repository.EbooksRepository
|
|
Log zerolog.Logger
|
|
UsersRepo usersRepository.UsersRepository
|
|
}
|
|
|
|
// EbookPurchasesService define interface of IEbookPurchasesService
|
|
type EbookPurchasesService interface {
|
|
GetByBuyerId(authToken string, pagination *paginator.Pagination) (purchases []*response.EbookPurchaseResponse, paging paginator.Pagination, err error)
|
|
PurchaseEbook(authToken string, ebookId uint, paymentMethod string) (purchase *response.EbookPurchaseResponse, err error)
|
|
UpdatePaymentStatus(purchaseId uint, paymentStatus string, transactionId string, paymentProof string) (err error)
|
|
GetPurchaseById(purchaseId uint) (purchase *response.EbookPurchaseResponse, err error)
|
|
ConfirmPayment(purchaseId uint) (err error)
|
|
}
|
|
|
|
// NewEbookPurchasesService init EbookPurchasesService
|
|
func NewEbookPurchasesService(
|
|
repo repository.EbookPurchasesRepository,
|
|
ebooksRepo repository.EbooksRepository,
|
|
log zerolog.Logger,
|
|
usersRepo usersRepository.UsersRepository) EbookPurchasesService {
|
|
|
|
return &ebookPurchasesService{
|
|
Repo: repo,
|
|
EbooksRepo: ebooksRepo,
|
|
Log: log,
|
|
UsersRepo: usersRepo,
|
|
}
|
|
}
|
|
|
|
// GetByBuyerId implement interface of EbookPurchasesService
|
|
func (_i *ebookPurchasesService) GetByBuyerId(authToken string, pagination *paginator.Pagination) (purchases []*response.EbookPurchaseResponse, paging paginator.Pagination, err error) {
|
|
user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
|
|
if user == nil {
|
|
return nil, paginator.Pagination{}, errors.New("user not found")
|
|
}
|
|
|
|
purchasesData, paging, err := _i.Repo.GetByBuyerId(user.ID, pagination)
|
|
if err != nil {
|
|
return nil, paging, err
|
|
}
|
|
|
|
purchases = mapper.ToEbookPurchaseResponseList(purchasesData)
|
|
|
|
return purchases, paging, nil
|
|
}
|
|
|
|
// PurchaseEbook implement interface of EbookPurchasesService
|
|
func (_i *ebookPurchasesService) PurchaseEbook(authToken string, ebookId uint, paymentMethod string) (purchase *response.EbookPurchaseResponse, err error) {
|
|
user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
|
|
if user == nil {
|
|
return nil, errors.New("user not found")
|
|
}
|
|
|
|
// Check if ebook exists
|
|
ebook, err := _i.EbooksRepo.FindOne(ebookId)
|
|
if err != nil {
|
|
return nil, errors.New("ebook not found")
|
|
}
|
|
|
|
// Check if already purchased
|
|
existingPurchase, err := _i.Repo.FindByBuyerAndEbook(user.ID, ebookId)
|
|
if err == nil && existingPurchase != nil {
|
|
return nil, errors.New("ebook already purchased")
|
|
}
|
|
|
|
// Create purchase record
|
|
purchaseEntity := &entity.EbookPurchases{
|
|
BuyerId: user.ID,
|
|
EbookId: ebookId,
|
|
PurchasePrice: ebook.Price,
|
|
PaymentMethod: &paymentMethod,
|
|
PaymentStatus: stringPtr("pending"),
|
|
StatusId: intPtr(1),
|
|
IsActive: boolPtr(true),
|
|
}
|
|
|
|
purchaseData, err := _i.Repo.Create(purchaseEntity)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Update purchase count
|
|
err = _i.EbooksRepo.UpdatePurchaseCount(ebookId)
|
|
if err != nil {
|
|
_i.Log.Error().Err(err).Msg("Failed to update purchase count")
|
|
}
|
|
|
|
purchase = mapper.ToEbookPurchaseResponse(purchaseData)
|
|
|
|
return purchase, nil
|
|
}
|
|
|
|
// UpdatePaymentStatus implement interface of EbookPurchasesService
|
|
func (_i *ebookPurchasesService) UpdatePaymentStatus(purchaseId uint, paymentStatus string, transactionId string, paymentProof string) (err error) {
|
|
_, err = _i.Repo.FindOne(purchaseId)
|
|
if err != nil {
|
|
return errors.New("purchase not found")
|
|
}
|
|
|
|
updateData := &entity.EbookPurchases{
|
|
PaymentStatus: &paymentStatus,
|
|
TransactionId: &transactionId,
|
|
PaymentProof: &paymentProof,
|
|
}
|
|
|
|
if paymentStatus == "paid" {
|
|
now := time.Now()
|
|
updateData.PaymentDate = &now
|
|
}
|
|
|
|
err = _i.Repo.Update(purchaseId, updateData)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetPurchaseById implement interface of EbookPurchasesService
|
|
func (_i *ebookPurchasesService) GetPurchaseById(purchaseId uint) (purchase *response.EbookPurchaseResponse, err error) {
|
|
purchaseData, err := _i.Repo.FindOne(purchaseId)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
purchase = mapper.ToEbookPurchaseResponse(purchaseData)
|
|
|
|
return purchase, nil
|
|
}
|
|
|
|
// ConfirmPayment implement interface of EbookPurchasesService
|
|
func (_i *ebookPurchasesService) ConfirmPayment(purchaseId uint) (err error) {
|
|
purchase, err := _i.Repo.FindOne(purchaseId)
|
|
if err != nil {
|
|
return errors.New("purchase not found")
|
|
}
|
|
|
|
if purchase.PaymentStatus == nil || *purchase.PaymentStatus != "paid" {
|
|
return errors.New("payment not completed")
|
|
}
|
|
|
|
// Update status to confirmed
|
|
updateData := &entity.EbookPurchases{
|
|
StatusId: intPtr(2), // Assuming 2 is confirmed status
|
|
}
|
|
|
|
err = _i.Repo.Update(purchaseId, updateData)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Helper functions
|
|
func stringPtr(s string) *string {
|
|
return &s
|
|
}
|
|
|
|
func intPtr(i int) *int {
|
|
return &i
|
|
}
|
|
|
|
func boolPtr(b bool) *bool {
|
|
return &b
|
|
}
|