package service import ( "apskel-pos-be/internal/appcontext" "context" "apskel-pos-be/internal/constants" "apskel-pos-be/internal/contract" "apskel-pos-be/internal/processor" "apskel-pos-be/internal/transformer" "github.com/google/uuid" ) type PurchaseOrderService interface { CreatePurchaseOrder(ctx context.Context, apctx *appcontext.ContextInfo, req *contract.CreatePurchaseOrderRequest) *contract.Response UpdatePurchaseOrder(ctx context.Context, apctx *appcontext.ContextInfo, id uuid.UUID, req *contract.UpdatePurchaseOrderRequest) *contract.Response DeletePurchaseOrder(ctx context.Context, apctx *appcontext.ContextInfo, id uuid.UUID) *contract.Response GetPurchaseOrderByID(ctx context.Context, apctx *appcontext.ContextInfo, id uuid.UUID) *contract.Response ListPurchaseOrders(ctx context.Context, apctx *appcontext.ContextInfo, req *contract.ListPurchaseOrdersRequest) *contract.Response GetPurchaseOrdersByStatus(ctx context.Context, apctx *appcontext.ContextInfo, status string) *contract.Response GetOverduePurchaseOrders(ctx context.Context, apctx *appcontext.ContextInfo) *contract.Response UpdatePurchaseOrderStatus(ctx context.Context, apctx *appcontext.ContextInfo, id uuid.UUID, status string) *contract.Response } type PurchaseOrderServiceImpl struct { purchaseOrderProcessor processor.PurchaseOrderProcessor } func NewPurchaseOrderService(purchaseOrderProcessor processor.PurchaseOrderProcessor) *PurchaseOrderServiceImpl { return &PurchaseOrderServiceImpl{ purchaseOrderProcessor: purchaseOrderProcessor, } } func (s *PurchaseOrderServiceImpl) CreatePurchaseOrder(ctx context.Context, apctx *appcontext.ContextInfo, req *contract.CreatePurchaseOrderRequest) *contract.Response { modelReq, err := transformer.CreatePurchaseOrderRequestToModel(req) if err != nil { errorResp := contract.NewResponseError(constants.MalformedFieldErrorCode, constants.PurchaseOrderServiceEntity, "Invalid date format. Use YYYY-MM-DD format") return contract.BuildErrorResponse([]*contract.ResponseError{errorResp}) } poResponse, err := s.purchaseOrderProcessor.CreatePurchaseOrder(ctx, apctx.OrganizationID, modelReq) if err != nil { errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.PurchaseOrderServiceEntity, err.Error()) return contract.BuildErrorResponse([]*contract.ResponseError{errorResp}) } contractResponse := transformer.PurchaseOrderModelResponseToResponse(poResponse) return contract.BuildSuccessResponse(contractResponse) } func (s *PurchaseOrderServiceImpl) UpdatePurchaseOrder(ctx context.Context, apctx *appcontext.ContextInfo, id uuid.UUID, req *contract.UpdatePurchaseOrderRequest) *contract.Response { modelReq, err := transformer.UpdatePurchaseOrderRequestToModel(req) if err != nil { errorResp := contract.NewResponseError(constants.MalformedFieldErrorCode, constants.PurchaseOrderServiceEntity, "Invalid date format. Use YYYY-MM-DD format") return contract.BuildErrorResponse([]*contract.ResponseError{errorResp}) } poResponse, err := s.purchaseOrderProcessor.UpdatePurchaseOrder(ctx, id, apctx.OrganizationID, modelReq) if err != nil { errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.PurchaseOrderServiceEntity, err.Error()) return contract.BuildErrorResponse([]*contract.ResponseError{errorResp}) } contractResponse := transformer.PurchaseOrderModelResponseToResponse(poResponse) return contract.BuildSuccessResponse(contractResponse) } func (s *PurchaseOrderServiceImpl) DeletePurchaseOrder(ctx context.Context, apctx *appcontext.ContextInfo, id uuid.UUID) *contract.Response { err := s.purchaseOrderProcessor.DeletePurchaseOrder(ctx, id, apctx.OrganizationID) if err != nil { errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.PurchaseOrderServiceEntity, err.Error()) return contract.BuildErrorResponse([]*contract.ResponseError{errorResp}) } return contract.BuildSuccessResponse(map[string]interface{}{ "message": "Purchase order deleted successfully", }) } func (s *PurchaseOrderServiceImpl) GetPurchaseOrderByID(ctx context.Context, apctx *appcontext.ContextInfo, id uuid.UUID) *contract.Response { poResponse, err := s.purchaseOrderProcessor.GetPurchaseOrderByID(ctx, id, apctx.OrganizationID) if err != nil { errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.PurchaseOrderServiceEntity, err.Error()) return contract.BuildErrorResponse([]*contract.ResponseError{errorResp}) } contractResponse := transformer.PurchaseOrderModelResponseToResponse(poResponse) return contract.BuildSuccessResponse(contractResponse) } func (s *PurchaseOrderServiceImpl) ListPurchaseOrders(ctx context.Context, apctx *appcontext.ContextInfo, req *contract.ListPurchaseOrdersRequest) *contract.Response { modelReq := transformer.ListPurchaseOrdersRequestToModel(req) filters := make(map[string]interface{}) if modelReq.Search != "" { filters["search"] = modelReq.Search } if modelReq.Status != "" { filters["status"] = modelReq.Status } if modelReq.VendorID != nil { filters["vendor_id"] = *modelReq.VendorID } if modelReq.StartDate != nil { filters["start_date"] = *modelReq.StartDate } if modelReq.EndDate != nil { filters["end_date"] = *modelReq.EndDate } pos, totalPages, err := s.purchaseOrderProcessor.ListPurchaseOrders(ctx, apctx.OrganizationID, filters, modelReq.Page, modelReq.Limit) if err != nil { errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.PurchaseOrderServiceEntity, err.Error()) return contract.BuildErrorResponse([]*contract.ResponseError{errorResp}) } contractResponses := make([]contract.PurchaseOrderResponse, len(pos)) for i, po := range pos { response := transformer.PurchaseOrderModelResponseToResponse(po) if response != nil { contractResponses[i] = *response } } response := contract.ListPurchaseOrdersResponse{ PurchaseOrders: contractResponses, TotalCount: len(contractResponses), Page: modelReq.Page, Limit: modelReq.Limit, TotalPages: totalPages, } return contract.BuildSuccessResponse(response) } func (s *PurchaseOrderServiceImpl) GetPurchaseOrdersByStatus(ctx context.Context, apctx *appcontext.ContextInfo, status string) *contract.Response { poResponses, err := s.purchaseOrderProcessor.GetPurchaseOrdersByStatus(ctx, apctx.OrganizationID, status) if err != nil { errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.PurchaseOrderServiceEntity, err.Error()) return contract.BuildErrorResponse([]*contract.ResponseError{errorResp}) } contractResponses := make([]contract.PurchaseOrderResponse, len(poResponses)) for i, po := range poResponses { response := transformer.PurchaseOrderModelResponseToResponse(po) if response != nil { contractResponses[i] = *response } } return contract.BuildSuccessResponse(contractResponses) } func (s *PurchaseOrderServiceImpl) GetOverduePurchaseOrders(ctx context.Context, apctx *appcontext.ContextInfo) *contract.Response { poResponses, err := s.purchaseOrderProcessor.GetOverduePurchaseOrders(ctx, apctx.OrganizationID) if err != nil { errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.PurchaseOrderServiceEntity, err.Error()) return contract.BuildErrorResponse([]*contract.ResponseError{errorResp}) } contractResponses := make([]contract.PurchaseOrderResponse, len(poResponses)) for i, po := range poResponses { response := transformer.PurchaseOrderModelResponseToResponse(po) if response != nil { contractResponses[i] = *response } } return contract.BuildSuccessResponse(contractResponses) } func (s *PurchaseOrderServiceImpl) UpdatePurchaseOrderStatus(ctx context.Context, apctx *appcontext.ContextInfo, id uuid.UUID, status string) *contract.Response { poResponse, err := s.purchaseOrderProcessor.UpdatePurchaseOrderStatus(ctx, id, apctx.OrganizationID, apctx.UserID, apctx.OutletID, status) if err != nil { errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.PurchaseOrderServiceEntity, err.Error()) return contract.BuildErrorResponse([]*contract.ResponseError{errorResp}) } contractResponse := transformer.PurchaseOrderModelResponseToResponse(poResponse) return contract.BuildSuccessResponse(contractResponse) }