2025-09-12 01:12:11 +07:00
package handler
import (
"apskel-pos-be/internal/appcontext"
"apskel-pos-be/internal/util"
"strconv"
"time"
"apskel-pos-be/internal/constants"
"apskel-pos-be/internal/contract"
"apskel-pos-be/internal/logger"
"apskel-pos-be/internal/service"
"apskel-pos-be/internal/validator"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
)
type PurchaseOrderHandler struct {
purchaseOrderService service . PurchaseOrderService
purchaseOrderValidator validator . PurchaseOrderValidator
}
func NewPurchaseOrderHandler (
purchaseOrderService service . PurchaseOrderService ,
purchaseOrderValidator validator . PurchaseOrderValidator ,
) * PurchaseOrderHandler {
return & PurchaseOrderHandler {
purchaseOrderService : purchaseOrderService ,
purchaseOrderValidator : purchaseOrderValidator ,
}
}
func ( h * PurchaseOrderHandler ) CreatePurchaseOrder ( c * gin . Context ) {
ctx := c . Request . Context ()
contextInfo := appcontext . FromGinContext ( ctx )
var req contract . CreatePurchaseOrderRequest
if err := c . ShouldBindJSON ( & req ); err != nil {
logger . FromContext ( c . Request . Context ()). WithError ( err ). Error ( "PurchaseOrderHandler::CreatePurchaseOrder -> request binding failed" )
validationResponseError := contract . NewResponseError ( constants . MissingFieldErrorCode , constants . RequestEntity , err . Error ())
util . HandleResponse ( c . Writer , c . Request , contract . BuildErrorResponse ([] * contract . ResponseError { validationResponseError }), "PurchaseOrderHandler::CreatePurchaseOrder" )
return
}
validationError , validationErrorCode := h . purchaseOrderValidator . ValidateCreatePurchaseOrderRequest ( & req )
if validationError != nil {
validationResponseError := contract . NewResponseError ( validationErrorCode , constants . RequestEntity , validationError . Error ())
util . HandleResponse ( c . Writer , c . Request , contract . BuildErrorResponse ([] * contract . ResponseError { validationResponseError }), "PurchaseOrderHandler::CreatePurchaseOrder" )
return
}
poResponse := h . purchaseOrderService . CreatePurchaseOrder ( ctx , contextInfo , & req )
if poResponse . HasErrors () {
errorResp := poResponse . GetErrors ()[ 0 ]
logger . FromContext ( ctx ). WithError ( errorResp ). Error ( "PurchaseOrderHandler::CreatePurchaseOrder -> Failed to create purchase order from service" )
}
util . HandleResponse ( c . Writer , c . Request , poResponse , "PurchaseOrderHandler::CreatePurchaseOrder" )
}
func ( h * PurchaseOrderHandler ) UpdatePurchaseOrder ( c * gin . Context ) {
ctx := c . Request . Context ()
contextInfo := appcontext . FromGinContext ( ctx )
poIDStr := c . Param ( "id" )
poID , err := uuid . Parse ( poIDStr )
if err != nil {
logger . FromContext ( ctx ). WithError ( err ). Error ( "PurchaseOrderHandler::UpdatePurchaseOrder -> Invalid purchase order ID" )
validationResponseError := contract . NewResponseError ( constants . MalformedFieldErrorCode , constants . RequestEntity , "Invalid purchase order ID" )
util . HandleResponse ( c . Writer , c . Request , contract . BuildErrorResponse ([] * contract . ResponseError { validationResponseError }), "PurchaseOrderHandler::UpdatePurchaseOrder" )
return
}
var req contract . UpdatePurchaseOrderRequest
if err := c . ShouldBindJSON ( & req ); err != nil {
logger . FromContext ( ctx ). WithError ( err ). Error ( "PurchaseOrderHandler::UpdatePurchaseOrder -> request binding failed" )
validationResponseError := contract . NewResponseError ( constants . MissingFieldErrorCode , constants . RequestEntity , "Invalid request body" )
util . HandleResponse ( c . Writer , c . Request , contract . BuildErrorResponse ([] * contract . ResponseError { validationResponseError }), "PurchaseOrderHandler::UpdatePurchaseOrder" )
return
}
validationError , validationErrorCode := h . purchaseOrderValidator . ValidateUpdatePurchaseOrderRequest ( & req )
if validationError != nil {
validationResponseError := contract . NewResponseError ( validationErrorCode , constants . RequestEntity , validationError . Error ())
util . HandleResponse ( c . Writer , c . Request , contract . BuildErrorResponse ([] * contract . ResponseError { validationResponseError }), "PurchaseOrderHandler::UpdatePurchaseOrder" )
return
}
poResponse := h . purchaseOrderService . UpdatePurchaseOrder ( ctx , contextInfo , poID , & req )
if poResponse . HasErrors () {
errorResp := poResponse . GetErrors ()[ 0 ]
logger . FromContext ( ctx ). WithError ( errorResp ). Error ( "PurchaseOrderHandler::UpdatePurchaseOrder -> Failed to update purchase order from service" )
}
util . HandleResponse ( c . Writer , c . Request , poResponse , "PurchaseOrderHandler::UpdatePurchaseOrder" )
}
func ( h * PurchaseOrderHandler ) DeletePurchaseOrder ( c * gin . Context ) {
ctx := c . Request . Context ()
contextInfo := appcontext . FromGinContext ( ctx )
poIDStr := c . Param ( "id" )
poID , err := uuid . Parse ( poIDStr )
if err != nil {
logger . FromContext ( ctx ). WithError ( err ). Error ( "PurchaseOrderHandler::DeletePurchaseOrder -> Invalid purchase order ID" )
validationResponseError := contract . NewResponseError ( constants . MalformedFieldErrorCode , constants . RequestEntity , "Invalid purchase order ID" )
util . HandleResponse ( c . Writer , c . Request , contract . BuildErrorResponse ([] * contract . ResponseError { validationResponseError }), "PurchaseOrderHandler::DeletePurchaseOrder" )
return
}
poResponse := h . purchaseOrderService . DeletePurchaseOrder ( ctx , contextInfo , poID )
if poResponse . HasErrors () {
errorResp := poResponse . GetErrors ()[ 0 ]
logger . FromContext ( ctx ). WithError ( errorResp ). Error ( "PurchaseOrderHandler::DeletePurchaseOrder -> Failed to delete purchase order from service" )
}
util . HandleResponse ( c . Writer , c . Request , poResponse , "PurchaseOrderHandler::DeletePurchaseOrder" )
}
func ( h * PurchaseOrderHandler ) GetPurchaseOrder ( c * gin . Context ) {
ctx := c . Request . Context ()
contextInfo := appcontext . FromGinContext ( ctx )
poIDStr := c . Param ( "id" )
poID , err := uuid . Parse ( poIDStr )
if err != nil {
logger . FromContext ( ctx ). WithError ( err ). Error ( "PurchaseOrderHandler::GetPurchaseOrder -> Invalid purchase order ID" )
validationResponseError := contract . NewResponseError ( constants . MalformedFieldErrorCode , constants . RequestEntity , "Invalid purchase order ID" )
util . HandleResponse ( c . Writer , c . Request , contract . BuildErrorResponse ([] * contract . ResponseError { validationResponseError }), "PurchaseOrderHandler::GetPurchaseOrder" )
return
}
poResponse := h . purchaseOrderService . GetPurchaseOrderByID ( ctx , contextInfo , poID )
if poResponse . HasErrors () {
errorResp := poResponse . GetErrors ()[ 0 ]
logger . FromContext ( ctx ). WithError ( errorResp ). Error ( "PurchaseOrderHandler::GetPurchaseOrder -> Failed to get purchase order from service" )
}
util . HandleResponse ( c . Writer , c . Request , poResponse , "PurchaseOrderHandler::GetPurchaseOrder" )
}
func ( h * PurchaseOrderHandler ) ListPurchaseOrders ( c * gin . Context ) {
ctx := c . Request . Context ()
contextInfo := appcontext . FromGinContext ( ctx )
req := & contract . ListPurchaseOrdersRequest {
Page : 1 ,
Limit : 10 ,
}
// Parse query parameters
if pageStr := c . Query ( "page" ); pageStr != "" {
if page , err := strconv . Atoi ( pageStr ); err == nil {
req . Page = page
}
}
if limitStr := c . Query ( "limit" ); limitStr != "" {
if limit , err := strconv . Atoi ( limitStr ); err == nil {
req . Limit = limit
}
}
if search := c . Query ( "search" ); search != "" {
req . Search = search
}
if status := c . Query ( "status" ); status != "" {
req . Status = status
}
if vendorIDStr := c . Query ( "vendor_id" ); vendorIDStr != "" {
if vendorID , err := uuid . Parse ( vendorIDStr ); err == nil {
req . VendorID = & vendorID
}
}
2026-08-11 16:39:13 +07:00
if teamScope := c . Query ( "team_scope" ); teamScope != "" {
req . TeamScope = teamScope
}
if teamCategoryIDStr := c . Query ( "team_category_id" ); teamCategoryIDStr != "" {
if teamCategoryID , err := uuid . Parse ( teamCategoryIDStr ); err == nil {
req . TeamCategoryID = & teamCategoryID
}
}
2025-09-12 01:12:11 +07:00
if startDateStr := c . Query ( "start_date" ); startDateStr != "" {
if startDate , err := time . Parse ( "2006-01-02" , startDateStr ); err == nil {
req . StartDate = & startDate
}
}
if endDateStr := c . Query ( "end_date" ); endDateStr != "" {
if endDate , err := time . Parse ( "2006-01-02" , endDateStr ); err == nil {
req . EndDate = & endDate
}
}
validationError , validationErrorCode := h . purchaseOrderValidator . ValidateListPurchaseOrdersRequest ( req )
if validationError != nil {
validationResponseError := contract . NewResponseError ( validationErrorCode , constants . RequestEntity , validationError . Error ())
util . HandleResponse ( c . Writer , c . Request , contract . BuildErrorResponse ([] * contract . ResponseError { validationResponseError }), "PurchaseOrderHandler::ListPurchaseOrders" )
return
}
poResponse := h . purchaseOrderService . ListPurchaseOrders ( ctx , contextInfo , req )
if poResponse . HasErrors () {
errorResp := poResponse . GetErrors ()[ 0 ]
logger . FromContext ( ctx ). WithError ( errorResp ). Error ( "PurchaseOrderHandler::ListPurchaseOrders -> Failed to list purchase orders from service" )
}
util . HandleResponse ( c . Writer , c . Request , poResponse , "PurchaseOrderHandler::ListPurchaseOrders" )
}
func ( h * PurchaseOrderHandler ) GetPurchaseOrdersByStatus ( c * gin . Context ) {
ctx := c . Request . Context ()
contextInfo := appcontext . FromGinContext ( ctx )
status := c . Param ( "status" )
if status == "" {
validationResponseError := contract . NewResponseError ( constants . MissingFieldErrorCode , constants . RequestEntity , "Status parameter is required" )
util . HandleResponse ( c . Writer , c . Request , contract . BuildErrorResponse ([] * contract . ResponseError { validationResponseError }), "PurchaseOrderHandler::GetPurchaseOrdersByStatus" )
return
}
poResponse := h . purchaseOrderService . GetPurchaseOrdersByStatus ( ctx , contextInfo , status )
if poResponse . HasErrors () {
errorResp := poResponse . GetErrors ()[ 0 ]
logger . FromContext ( ctx ). WithError ( errorResp ). Error ( "PurchaseOrderHandler::GetPurchaseOrdersByStatus -> Failed to get purchase orders by status from service" )
}
util . HandleResponse ( c . Writer , c . Request , poResponse , "PurchaseOrderHandler::GetPurchaseOrdersByStatus" )
}
2026-08-11 16:39:13 +07:00
// ListPurchaseTeams serves the team picker for the purchase form: the parent
// categories of the caller's outlet, plus Pusat.
func ( h * PurchaseOrderHandler ) ListPurchaseTeams ( c * gin . Context ) {
ctx := c . Request . Context ()
contextInfo := appcontext . FromGinContext ( ctx )
teamsResponse := h . purchaseOrderService . ListPurchaseTeams ( ctx , contextInfo )
if teamsResponse . HasErrors () {
errorResp := teamsResponse . GetErrors ()[ 0 ]
logger . FromContext ( ctx ). WithError ( errorResp ). Error ( "PurchaseOrderHandler::ListPurchaseTeams -> Failed to list purchase teams from service" )
}
util . HandleResponse ( c . Writer , c . Request , teamsResponse , "PurchaseOrderHandler::ListPurchaseTeams" )
}
2025-09-12 01:12:11 +07:00
func ( h * PurchaseOrderHandler ) GetOverduePurchaseOrders ( c * gin . Context ) {
ctx := c . Request . Context ()
contextInfo := appcontext . FromGinContext ( ctx )
poResponse := h . purchaseOrderService . GetOverduePurchaseOrders ( ctx , contextInfo )
if poResponse . HasErrors () {
errorResp := poResponse . GetErrors ()[ 0 ]
logger . FromContext ( ctx ). WithError ( errorResp ). Error ( "PurchaseOrderHandler::GetOverduePurchaseOrders -> Failed to get overdue purchase orders from service" )
}
util . HandleResponse ( c . Writer , c . Request , poResponse , "PurchaseOrderHandler::GetOverduePurchaseOrders" )
}
func ( h * PurchaseOrderHandler ) UpdatePurchaseOrderStatus ( c * gin . Context ) {
ctx := c . Request . Context ()
contextInfo := appcontext . FromGinContext ( ctx )
poIDStr := c . Param ( "id" )
poID , err := uuid . Parse ( poIDStr )
if err != nil {
logger . FromContext ( ctx ). WithError ( err ). Error ( "PurchaseOrderHandler::UpdatePurchaseOrderStatus -> Invalid purchase order ID" )
validationResponseError := contract . NewResponseError ( constants . MalformedFieldErrorCode , constants . RequestEntity , "Invalid purchase order ID" )
util . HandleResponse ( c . Writer , c . Request , contract . BuildErrorResponse ([] * contract . ResponseError { validationResponseError }), "PurchaseOrderHandler::UpdatePurchaseOrderStatus" )
return
}
status := c . Param ( "status" )
if status == "" {
validationResponseError := contract . NewResponseError ( constants . MissingFieldErrorCode , constants . RequestEntity , "Status parameter is required" )
util . HandleResponse ( c . Writer , c . Request , contract . BuildErrorResponse ([] * contract . ResponseError { validationResponseError }), "PurchaseOrderHandler::UpdatePurchaseOrderStatus" )
return
}
poResponse := h . purchaseOrderService . UpdatePurchaseOrderStatus ( ctx , contextInfo , poID , status )
if poResponse . HasErrors () {
errorResp := poResponse . GetErrors ()[ 0 ]
logger . FromContext ( ctx ). WithError ( errorResp ). Error ( "PurchaseOrderHandler::UpdatePurchaseOrderStatus -> Failed to update purchase order status from service" )
}
util . HandleResponse ( c . Writer , c . Request , poResponse , "PurchaseOrderHandler::UpdatePurchaseOrderStatus" )
}