100 lines
3.4 KiB
Go
100 lines
3.4 KiB
Go
|
|
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
|
||
|
|
}
|