Add ingredieints

This commit is contained in:
Aditya Siregar
2025-08-08 00:22:28 +07:00
parent 93a3b29ae9
commit fe4f17b34d
22 changed files with 535 additions and 229 deletions
+100 -2
View File
@@ -3,9 +3,11 @@ package service
import (
"context"
"fmt"
"time"
"apskel-pos-be/internal/models"
"apskel-pos-be/internal/processor"
"apskel-pos-be/internal/repository"
"github.com/google/uuid"
)
@@ -26,11 +28,13 @@ type OrderService interface {
type OrderServiceImpl struct {
orderProcessor processor.OrderProcessor
tableRepo repository.TableRepositoryInterface
}
func NewOrderServiceImpl(orderProcessor processor.OrderProcessor) *OrderServiceImpl {
func NewOrderServiceImpl(orderProcessor processor.OrderProcessor, tableRepo repository.TableRepositoryInterface) *OrderServiceImpl {
return &OrderServiceImpl{
orderProcessor: orderProcessor,
tableRepo: tableRepo,
}
}
@@ -39,11 +43,23 @@ func (s *OrderServiceImpl) CreateOrder(ctx context.Context, req *models.CreateOr
return nil, fmt.Errorf("validation error: %w", err)
}
if req.TableID != nil {
if err := s.validateTable(ctx, req); err != nil {
return nil, fmt.Errorf("table validation failed: %w", err)
}
}
response, err := s.orderProcessor.CreateOrder(ctx, req, organizationID)
if err != nil {
return nil, fmt.Errorf("failed to create order: %w", err)
}
if req.TableID != nil {
if err := s.occupyTableWithOrder(ctx, *req.TableID, response.ID); err != nil {
fmt.Printf("Warning: failed to occupy table %s with order %s: %v\n", *req.TableID, response.ID, err)
}
}
return response, nil
}
@@ -121,6 +137,12 @@ func (s *OrderServiceImpl) VoidOrder(ctx context.Context, req *models.VoidOrderR
return fmt.Errorf("failed to void order: %w", err)
}
// Release table if order is voided
if err := s.handleTableReleaseOnVoid(ctx, req.OrderID); err != nil {
// Log the error but don't fail the void operation
fmt.Printf("Warning: failed to handle table release for voided order %s: %v\n", req.OrderID, err)
}
return nil
}
@@ -151,12 +173,15 @@ func (s *OrderServiceImpl) CreatePayment(ctx context.Context, req *models.Create
return nil, fmt.Errorf("validation error: %w", err)
}
// Process payment creation
response, err := s.orderProcessor.CreatePayment(ctx, req)
if err != nil {
return nil, fmt.Errorf("failed to create payment: %w", err)
}
if err := s.handleTableReleaseOnPayment(ctx, req.OrderID); err != nil {
fmt.Printf("Warning: failed to handle table release for order %s: %v\n", req.OrderID, err)
}
return response, nil
}
@@ -247,6 +272,11 @@ func (s *OrderServiceImpl) validateCreateOrderRequest(req *models.CreateOrderReq
return fmt.Errorf("user ID is required")
}
// Validate table ID if provided
if req.TableID != nil && *req.TableID == uuid.Nil {
return fmt.Errorf("table ID cannot be nil if provided")
}
if len(req.OrderItems) == 0 {
return fmt.Errorf("order must have at least one item")
}
@@ -445,3 +475,71 @@ func (s *OrderServiceImpl) validateSplitBillRequest(req *models.SplitBillRequest
return nil
}
// validateTable validates that the table exists and is available for occupation
func (s *OrderServiceImpl) validateTable(ctx context.Context, req *models.CreateOrderRequest) error {
// Validate table exists and is available
table, err := s.tableRepo.GetByID(ctx, *req.TableID)
if err != nil {
return fmt.Errorf("table not found: %w", err)
}
// Check if table belongs to the same outlet
if table.OutletID != req.OutletID {
return fmt.Errorf("table does not belong to the specified outlet")
}
// Check if table is available for occupation
if !table.CanBeOccupied() {
return fmt.Errorf("table is not available for occupation (current status: %s)", table.Status)
}
return nil
}
func (s *OrderServiceImpl) occupyTableWithOrder(ctx context.Context, tableID, orderID uuid.UUID) error {
startTime := time.Now()
if err := s.tableRepo.OccupyTable(ctx, tableID, orderID, &startTime); err != nil {
return fmt.Errorf("failed to occupy table: %w", err)
}
return nil
}
func (s *OrderServiceImpl) handleTableReleaseOnPayment(ctx context.Context, orderID uuid.UUID) error {
order, err := s.orderProcessor.GetOrderByID(ctx, orderID)
if err != nil {
return fmt.Errorf("failed to get order: %w", err)
}
if order.PaymentStatus == "completed" {
table, err := s.tableRepo.GetByOrderID(ctx, orderID)
if err != nil {
return nil
}
if table != nil {
if err := s.tableRepo.ReleaseTable(ctx, table.ID, order.TotalAmount); err != nil {
return fmt.Errorf("failed to release table: %w", err)
}
}
}
return nil
}
// handleTableReleaseOnVoid releases the table when an order is voided
func (s *OrderServiceImpl) handleTableReleaseOnVoid(ctx context.Context, orderID uuid.UUID) error {
table, err := s.tableRepo.GetByOrderID(ctx, orderID)
if err != nil {
// Table might not exist or not be occupied, which is fine
return nil
}
if table != nil {
if err := s.tableRepo.ReleaseTable(ctx, table.ID, 0); err != nil {
return fmt.Errorf("failed to release table: %w", err)
}
}
return nil
}