2025-09-12 01:12:11 +07:00
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 {
2025-09-13 02:17:51 +07:00
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 })
}
2025-09-12 01:12:11 +07:00
2026-06-18 15:27:20 +07:00
var outletID * uuid . UUID
if apctx . OutletID != uuid . Nil {
outletID = & apctx . OutletID
}
poResponse , err := s . purchaseOrderProcessor . CreatePurchaseOrder ( ctx , apctx . OrganizationID , outletID , modelReq )
2025-09-12 01:12:11 +07:00
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 {
2025-09-13 02:17:51 +07:00
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 })
}
2025-09-12 01:12:11 +07:00
2026-06-18 15:27:20 +07:00
var outletID * uuid . UUID
if apctx . OutletID != uuid . Nil {
outletID = & apctx . OutletID
}
poResponse , err := s . purchaseOrderProcessor . UpdatePurchaseOrder ( ctx , id , apctx . OrganizationID , outletID , modelReq )
2025-09-12 01:12:11 +07:00
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 )
}