Add refund order
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
package cashier_session
|
||||
|
||||
import (
|
||||
"enaklo-pos-be/internal/common/logger"
|
||||
"enaklo-pos-be/internal/common/mycontext"
|
||||
"enaklo-pos-be/internal/entity"
|
||||
"github.com/pkg/errors"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type Service interface {
|
||||
OpenSession(ctx mycontext.Context, session *entity.CashierSession) (*entity.CashierSession, error)
|
||||
CloseSession(ctx mycontext.Context, sessionID int64, closingAmount float64) (*entity.CashierSessionReport, error)
|
||||
GetOpenSession(ctx mycontext.Context, cashierID int64) (*entity.CashierSession, error)
|
||||
GetSessionReport(ctx mycontext.Context, sessionID int64) (*entity.CashierSessionReport, error)
|
||||
}
|
||||
|
||||
type Repository interface {
|
||||
CreateSession(ctx mycontext.Context, session *entity.CashierSession) (*entity.CashierSession, error)
|
||||
CloseSession(ctx mycontext.Context, sessionID int64, closingAmount, expectedAmount float64) error
|
||||
GetOpenSessionByCashierID(ctx mycontext.Context, cashierID int64) (*entity.CashierSession, error)
|
||||
GetSessionByID(ctx mycontext.Context, sessionID int64) (*entity.CashierSession, error)
|
||||
GetPaymentSummaryBySessionID(ctx mycontext.Context, sessionID int64) ([]entity.PaymentSummary, error)
|
||||
}
|
||||
|
||||
type cashierSessionSvc struct {
|
||||
repo Repository
|
||||
}
|
||||
|
||||
func New(repo Repository) Service {
|
||||
return &cashierSessionSvc{repo: repo}
|
||||
}
|
||||
|
||||
func (s *cashierSessionSvc) OpenSession(ctx mycontext.Context, session *entity.CashierSession) (*entity.CashierSession, error) {
|
||||
openSession, err := s.repo.GetOpenSessionByCashierID(ctx, session.CashierID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to check existing open session")
|
||||
}
|
||||
if openSession != nil {
|
||||
return nil, errors.New("cashier already has an open session")
|
||||
}
|
||||
|
||||
newSession, err := s.repo.CreateSession(ctx, session)
|
||||
if err != nil {
|
||||
logger.ContextLogger(ctx).Error("failed to create cashier session", zap.Error(err))
|
||||
return nil, errors.Wrap(err, "failed to create cashier session")
|
||||
}
|
||||
|
||||
return newSession, nil
|
||||
}
|
||||
|
||||
func (s *cashierSessionSvc) CloseSession(ctx mycontext.Context, sessionID int64, closingAmount float64) (*entity.CashierSessionReport, error) {
|
||||
report, err := s.repo.GetPaymentSummaryBySessionID(ctx, sessionID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get payment summary")
|
||||
}
|
||||
|
||||
var expectedAmount float64
|
||||
for _, r := range report {
|
||||
expectedAmount += r.TotalAmount
|
||||
}
|
||||
|
||||
if err := s.repo.CloseSession(ctx, sessionID, closingAmount, expectedAmount); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to close session")
|
||||
}
|
||||
|
||||
return &entity.CashierSessionReport{
|
||||
SessionID: sessionID,
|
||||
ClosingAmount: closingAmount,
|
||||
ExpectedAmount: expectedAmount,
|
||||
Payments: report,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *cashierSessionSvc) GetOpenSession(ctx mycontext.Context, cashierID int64) (*entity.CashierSession, error) {
|
||||
session, err := s.repo.GetOpenSessionByCashierID(ctx, cashierID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get open session")
|
||||
}
|
||||
return session, nil
|
||||
}
|
||||
|
||||
func (s *cashierSessionSvc) GetSessionReport(ctx mycontext.Context, sessionID int64) (*entity.CashierSessionReport, error) {
|
||||
report, err := s.repo.GetPaymentSummaryBySessionID(ctx, sessionID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get payment summary")
|
||||
}
|
||||
|
||||
var expectedAmount float64
|
||||
for _, r := range report {
|
||||
expectedAmount += r.TotalAmount
|
||||
}
|
||||
|
||||
return &entity.CashierSessionReport{
|
||||
SessionID: sessionID,
|
||||
ExpectedAmount: expectedAmount,
|
||||
Payments: report,
|
||||
}, nil
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package category
|
||||
|
||||
import (
|
||||
"enaklo-pos-be/internal/common/logger"
|
||||
"enaklo-pos-be/internal/common/mycontext"
|
||||
"enaklo-pos-be/internal/entity"
|
||||
"github.com/pkg/errors"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type Service interface {
|
||||
Create(ctx mycontext.Context, category *entity.Category) (*entity.Category, error)
|
||||
GetByPartnerID(ctx mycontext.Context, partnerID int64) ([]*entity.Category, error)
|
||||
Update(ctx mycontext.Context, category *entity.Category) error
|
||||
Delete(ctx mycontext.Context, id int64) error
|
||||
GetByID(ctx mycontext.Context, id int64) (*entity.Category, error)
|
||||
}
|
||||
|
||||
type Repository interface {
|
||||
Create(ctx mycontext.Context, category *entity.Category) (*entity.Category, error)
|
||||
GetByPartnerID(ctx mycontext.Context, partnerID int64) ([]*entity.Category, error)
|
||||
Update(ctx mycontext.Context, category *entity.Category) error
|
||||
Delete(ctx mycontext.Context, id int64) error
|
||||
GetByID(ctx mycontext.Context, id int64) (*entity.Category, error)
|
||||
}
|
||||
|
||||
type categorySvc struct {
|
||||
repo Repository
|
||||
}
|
||||
|
||||
func New(repo Repository) Service {
|
||||
return &categorySvc{repo: repo}
|
||||
}
|
||||
|
||||
func (s *categorySvc) Create(ctx mycontext.Context, category *entity.Category) (*entity.Category, error) {
|
||||
existing, err := s.repo.GetByPartnerID(ctx, category.PartnerID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to fetch categories")
|
||||
}
|
||||
|
||||
for _, cat := range existing {
|
||||
if cat.Name == category.Name {
|
||||
return nil, errors.New("category name already exists for this partner")
|
||||
}
|
||||
}
|
||||
|
||||
newCategory, err := s.repo.Create(ctx, category)
|
||||
if err != nil {
|
||||
logger.ContextLogger(ctx).Error("failed to create category", zap.Error(err))
|
||||
return nil, errors.Wrap(err, "failed to create category")
|
||||
}
|
||||
|
||||
return newCategory, nil
|
||||
}
|
||||
|
||||
func (s *categorySvc) GetByPartnerID(ctx mycontext.Context, partnerID int64) ([]*entity.Category, error) {
|
||||
categories, err := s.repo.GetByPartnerID(ctx, partnerID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get categories by partner")
|
||||
}
|
||||
return categories, nil
|
||||
}
|
||||
|
||||
func (s *categorySvc) Update(ctx mycontext.Context, category *entity.Category) error {
|
||||
err := s.repo.Update(ctx, category)
|
||||
if err != nil {
|
||||
logger.ContextLogger(ctx).Error("failed to update category", zap.Error(err))
|
||||
return errors.Wrap(err, "failed to update category")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *categorySvc) Delete(ctx mycontext.Context, id int64) error {
|
||||
err := s.repo.Delete(ctx, id)
|
||||
if err != nil {
|
||||
logger.ContextLogger(ctx).Error("failed to delete category", zap.Error(err))
|
||||
return errors.Wrap(err, "failed to delete category")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *categorySvc) GetByID(ctx mycontext.Context, id int64) (*entity.Category, error) {
|
||||
category, err := s.repo.GetByID(ctx, id)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get category by ID")
|
||||
}
|
||||
return category, nil
|
||||
}
|
||||
@@ -12,6 +12,13 @@ import (
|
||||
|
||||
func (s *orderSvc) CreateOrderInquiry(ctx mycontext.Context,
|
||||
req *entity.OrderRequest) (*entity.OrderInquiryResponse, error) {
|
||||
|
||||
cashierSession, err := s.cashierSvc.GetOpenSession(ctx, ctx.RequestedBy())
|
||||
if err != nil {
|
||||
logger.ContextLogger(ctx).Error("no open session found for cashier", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
productIDs, filteredItems, err := s.ValidateOrderItems(ctx, req.OrderItems)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -60,6 +67,7 @@ func (s *orderSvc) CreateOrderInquiry(ctx mycontext.Context,
|
||||
req.PaymentProvider,
|
||||
req.TableNumber,
|
||||
req.OrderType,
|
||||
cashierSession.ID,
|
||||
)
|
||||
|
||||
for _, item := range req.OrderItems {
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"enaklo-pos-be/internal/constants"
|
||||
"enaklo-pos-be/internal/entity"
|
||||
"fmt"
|
||||
"github.com/pkg/errors"
|
||||
"go.uber.org/zap"
|
||||
"time"
|
||||
)
|
||||
@@ -36,6 +37,20 @@ func (s *orderSvc) ExecuteOrderInquiry(ctx mycontext.Context,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *orderSvc) RefundRequest(ctx mycontext.Context, partnerID, orderID int64, reason string) error {
|
||||
order, err := s.repo.FindByIDAndPartnerID(ctx, partnerID, orderID)
|
||||
if err != nil {
|
||||
logger.ContextLogger(ctx).Error("failed to create order", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
|
||||
if order.Status != "PAID" {
|
||||
return errors.New("only paid order can be refund")
|
||||
}
|
||||
|
||||
return s.repo.UpdateOrder(ctx, order.ID, "REFUNDED", reason)
|
||||
}
|
||||
|
||||
func (s *orderSvc) processPostOrderActions(
|
||||
ctx mycontext.Context,
|
||||
order *entity.Order,
|
||||
|
||||
@@ -12,6 +12,7 @@ type Repository interface {
|
||||
CreateInquiry(ctx mycontext.Context, inquiry *entity.OrderInquiry) (*entity.OrderInquiry, error)
|
||||
FindInquiryByID(ctx mycontext.Context, id string) (*entity.OrderInquiry, error)
|
||||
UpdateInquiryStatus(ctx mycontext.Context, id string, status string) error
|
||||
UpdateOrder(ctx mycontext.Context, id int64, status string, description string) error
|
||||
GetOrderHistoryByPartnerID(ctx mycontext.Context, partnerID int64, req entity.SearchRequest) ([]*entity.Order, int64, error)
|
||||
GetOrderPaymentMethodBreakdown(
|
||||
ctx mycontext.Context,
|
||||
@@ -65,6 +66,7 @@ type Service interface {
|
||||
req *entity.OrderRequest) (*entity.OrderInquiryResponse, error)
|
||||
ExecuteOrderInquiry(ctx mycontext.Context,
|
||||
token string, paymentMethod, paymentProvider string, inProgressOrderID int64) (*entity.OrderResponse, error)
|
||||
RefundRequest(ctx mycontext.Context, partnerID, orderID int64, reason string) error
|
||||
GetOrderHistory(ctx mycontext.Context, partnerID int64, request entity.SearchRequest) ([]*entity.Order, int64, error)
|
||||
CalculateOrderTotals(
|
||||
ctx mycontext.Context,
|
||||
@@ -122,6 +124,10 @@ type VoucherUndianRepo interface {
|
||||
CreateUndianVouchers(ctx mycontext.Context, vouchers []*entity.UndianVoucherDB) error
|
||||
}
|
||||
|
||||
type CashierSvc interface {
|
||||
GetOpenSession(ctx mycontext.Context, cashierID int64) (*entity.CashierSession, error)
|
||||
}
|
||||
|
||||
type orderSvc struct {
|
||||
repo Repository
|
||||
product ProductService
|
||||
@@ -133,6 +139,7 @@ type orderSvc struct {
|
||||
partnerSetting PartnerSettings
|
||||
inprogressOrder InProgressOrderRepository
|
||||
voucherUndianRepo VoucherUndianRepo
|
||||
cashierSvc CashierSvc
|
||||
}
|
||||
|
||||
func New(
|
||||
@@ -145,6 +152,7 @@ func New(
|
||||
notification NotificationService,
|
||||
partnerSetting PartnerSettings,
|
||||
voucherUndianRepo VoucherUndianRepo,
|
||||
cashierSvc CashierSvc,
|
||||
) Service {
|
||||
return &orderSvc{
|
||||
repo: repo,
|
||||
@@ -156,5 +164,6 @@ func New(
|
||||
notification: notification,
|
||||
partnerSetting: partnerSetting,
|
||||
voucherUndianRepo: voucherUndianRepo,
|
||||
cashierSvc: cashierSvc,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user