feat: add GetLinesByReceiptId method to InventoryReceiptController and service for retrieving receipt lines

This commit is contained in:
Habib Fatkhul Rohman 2025-11-28 11:27:33 +07:00
parent f6a7b5911a
commit dd7ea563a6
4 changed files with 120 additions and 57 deletions

View File

@ -19,6 +19,7 @@ type InventoryReceiptController interface {
Delete(ctx *gin.Context) Delete(ctx *gin.Context)
GetById(ctx *gin.Context) GetById(ctx *gin.Context)
GetAll(ctx *gin.Context) GetAll(ctx *gin.Context)
GetLinesByReceiptId(ctx *gin.Context)
CreateLine(ctx *gin.Context) CreateLine(ctx *gin.Context)
UpdateLine(ctx *gin.Context) UpdateLine(ctx *gin.Context)
DeleteLine(ctx *gin.Context) DeleteLine(ctx *gin.Context)
@ -30,6 +31,19 @@ type inventoryReceiptController struct {
db *gorm.DB db *gorm.DB
} }
// GetLines implements InventoryReceiptController.
func (c *inventoryReceiptController) GetLinesByReceiptId(ctx *gin.Context) {
id := ctx.Param("id")
lines, err := c.receiptService.GetLinesByReceiptId(ctx, id)
if err != nil {
res := utils.BuildResponseFailed(dto.MESSAGE_FAILED_GET_INVENTORY_RECEIPT_LINES, err.Error(), nil)
ctx.JSON(http.StatusInternalServerError, res)
return
}
res := utils.BuildResponseSuccess(dto.MESSAGE_SUCCESS_GET_INVENTORY_RECEIPT_LINES, lines)
ctx.JSON(http.StatusOK, res)
}
// OnComplete implements InventoryReceiptController. // OnComplete implements InventoryReceiptController.
func (c *inventoryReceiptController) OnComplete(ctx *gin.Context) { func (c *inventoryReceiptController) OnComplete(ctx *gin.Context) {
id := ctx.Param("id") id := ctx.Param("id")

View File

@ -1,6 +1,10 @@
package dto package dto
import pkgdto "github.com/Caknoooo/go-gin-clean-starter/pkg/dto" import (
"github.com/Caknoooo/go-gin-clean-starter/database/entities"
pkgdto "github.com/Caknoooo/go-gin-clean-starter/pkg/dto"
"github.com/google/uuid"
)
const ( const (
MESSAGE_FAILED_CREATE_INVENTORY_RECEIPT = "failed create inventory receipt" MESSAGE_FAILED_CREATE_INVENTORY_RECEIPT = "failed create inventory receipt"
@ -20,6 +24,8 @@ const (
MESSAGE_FAILED_GET_DATA_FROM_BODY = "failed get data from body" MESSAGE_FAILED_GET_DATA_FROM_BODY = "failed get data from body"
MESSAGE_SUCCESS_COMPLETE_INVENTORY_RECEIPT = "success complete inventory receipt" MESSAGE_SUCCESS_COMPLETE_INVENTORY_RECEIPT = "success complete inventory receipt"
MESSAGE_FAILED_COMPLETE_INVENTORY_RECEIPT = "failed complete inventory receipt" MESSAGE_FAILED_COMPLETE_INVENTORY_RECEIPT = "failed complete inventory receipt"
MESSAGE_FAILED_GET_INVENTORY_RECEIPT_LINES = "failed get inventory receipt lines"
MESSAGE_SUCCESS_GET_INVENTORY_RECEIPT_LINES = "success get inventory receipt lines"
) )
type InventoryReceiptCreateRequest struct { type InventoryReceiptCreateRequest struct {
@ -52,17 +58,17 @@ type InventoryReceiptUpdateRequest struct {
} }
type InventoryReceiptResponse struct { type InventoryReceiptResponse struct {
ID string `json:"id"` ID string `json:"id"`
ReferenceNumber string `json:"reference_number"` ReferenceNumber string `json:"reference_number"`
DocumentNumber string `json:"document_number"` DocumentNumber string `json:"document_number"`
DocumentDate string `json:"document_date"` DocumentDate string `json:"document_date"`
Source string `json:"source"` Source string `json:"source"`
QrCodeFile string `json:"qr_code_file"` QrCodeFile string `json:"qr_code_file"`
Status string `json:"status"` Status string `json:"status"`
Client pkgdto.IdNameResponse `json:"client"` Client pkgdto.IdNameResponse `json:"client"`
ReceiptLines []InventoryReceiptLineResponse `json:"receipt_lines"` // ReceiptLines []InventoryReceiptLineResponse `json:"receipt_lines"`
LineCount int `json:"line_count"` // LineCount int `json:"line_count"`
Assignment AssignmentResponse `json:"assignment,omitempty"` Assignment *AssignmentResponse `json:"assignment"`
} }
type AssignmentResponse struct { type AssignmentResponse struct {
@ -109,3 +115,29 @@ type InventoryReceiptLineUpdateRequest struct {
RepackUomID *string `json:"repack_uom_id"` RepackUomID *string `json:"repack_uom_id"`
ProductID *string `json:"product_id"` ProductID *string `json:"product_id"`
} }
func ToInventoryReceiptLineResponse(line entities.TInventoryReceiptLineEntity) InventoryReceiptLineResponse {
var repackUomID *string
if line.RepackUomID != nil {
tmp := line.RepackUomID.String()
repackUomID = &tmp
}
product := InventoryReceiptLineProductResponse{}
if line.Product.ID != uuid.Nil {
product = InventoryReceiptLineProductResponse{
ID: line.Product.ID.String(),
Name: line.Product.Name,
}
}
return InventoryReceiptLineResponse{
ID: line.ID.String(),
Quantity: line.Quantity,
BatchNumber: line.BatchNumber,
RepackingSuggestion: line.RepackingSuggestion,
RepackUomID: repackUomID,
Product: product,
ClientID: line.ClientID.String(),
}
}

View File

@ -20,6 +20,7 @@ func RegisterRoutes(server *gin.Engine, injector *do.Injector) {
receiptRoutes.PUT(":id", middlewares.Authenticate(jwtService), receiptController.Update) receiptRoutes.PUT(":id", middlewares.Authenticate(jwtService), receiptController.Update)
receiptRoutes.DELETE(":id", middlewares.Authenticate(jwtService), receiptController.Delete) receiptRoutes.DELETE(":id", middlewares.Authenticate(jwtService), receiptController.Delete)
receiptRoutes.GET("", middlewares.Authenticate(jwtService), receiptController.GetAll) receiptRoutes.GET("", middlewares.Authenticate(jwtService), receiptController.GetAll)
receiptRoutes.GET(":id/lines", middlewares.Authenticate(jwtService), receiptController.GetLinesByReceiptId)
receiptRoutes.POST(":id/lines", middlewares.Authenticate(jwtService), receiptController.CreateLine) receiptRoutes.POST(":id/lines", middlewares.Authenticate(jwtService), receiptController.CreateLine)
receiptRoutes.PUT("lines/:id", middlewares.Authenticate(jwtService), receiptController.UpdateLine) receiptRoutes.PUT("lines/:id", middlewares.Authenticate(jwtService), receiptController.UpdateLine)
receiptRoutes.DELETE("lines/:id", middlewares.Authenticate(jwtService), receiptController.DeleteLine) receiptRoutes.DELETE("lines/:id", middlewares.Authenticate(jwtService), receiptController.DeleteLine)

View File

@ -24,6 +24,7 @@ type InventoryReceiptService interface {
GetAll(ctx context.Context, filter query.InventoryReceiptFilter) ([]dtodomain.InventoryReceiptResponse, int64, error) GetAll(ctx context.Context, filter query.InventoryReceiptFilter) ([]dtodomain.InventoryReceiptResponse, int64, error)
Update(ctx context.Context, req dtodomain.InventoryReceiptUpdateRequest, id string) (dtodomain.InventoryReceiptResponse, error) Update(ctx context.Context, req dtodomain.InventoryReceiptUpdateRequest, id string) (dtodomain.InventoryReceiptResponse, error)
Delete(ctx context.Context, id string) error Delete(ctx context.Context, id string) error
GetLinesByReceiptId(ctx context.Context, id string) ([]dtodomain.InventoryReceiptLineResponse, error)
CreateLine(ctx context.Context, receiptId string, req dtodomain.InventoryReceiptLineCreateRequest) (dtodomain.InventoryReceiptLineResponse, error) CreateLine(ctx context.Context, receiptId string, req dtodomain.InventoryReceiptLineCreateRequest) (dtodomain.InventoryReceiptLineResponse, error)
UpdateLine(ctx context.Context, lineId string, req dtodomain.InventoryReceiptLineUpdateRequest) (dtodomain.InventoryReceiptLineResponse, error) UpdateLine(ctx context.Context, lineId string, req dtodomain.InventoryReceiptLineUpdateRequest) (dtodomain.InventoryReceiptLineResponse, error)
DeleteLine(ctx context.Context, lineId string) error DeleteLine(ctx context.Context, lineId string) error
@ -39,6 +40,18 @@ type inventoryReceiptService struct {
invStorageRepository invstoragerepository.InventoryStorageRepository invStorageRepository invstoragerepository.InventoryStorageRepository
} }
func (s *inventoryReceiptService) GetLinesByReceiptId(ctx context.Context, id string) ([]dtodomain.InventoryReceiptLineResponse, error) {
lines, err := s.receiptLineRepo.GetAllByReceiptId(ctx, id)
if err != nil {
return nil, err
}
var responses []dtodomain.InventoryReceiptLineResponse
for _, line := range lines {
responses = append(responses, dtodomain.ToInventoryReceiptLineResponse(line))
}
return responses, nil
}
func (s *inventoryReceiptService) OnComplete(ctx context.Context, id string) (dtodomain.InventoryReceiptResponse, error) { func (s *inventoryReceiptService) OnComplete(ctx context.Context, id string) (dtodomain.InventoryReceiptResponse, error) {
tx := s.db.Begin() tx := s.db.Begin()
defer func() { defer func() {
@ -186,6 +199,7 @@ func toAssignmentResponse(e entities.TAssignmentEntity) dtodomain.AssignmentResp
} }
users = append(users, userResp) users = append(users, userResp)
} }
return dtodomain.AssignmentResponse{ return dtodomain.AssignmentResponse{
ID: e.ID.String(), ID: e.ID.String(),
DocumentType: e.DocumentType, DocumentType: e.DocumentType,
@ -204,50 +218,52 @@ func toInventoryReceiptResponse(e entities.TInventoryReceiptEntity) dtodomain.In
} }
} }
lines := make([]dtodomain.InventoryReceiptLineResponse, 0) // lines := make([]dtodomain.InventoryReceiptLineResponse, 0)
for _, line := range e.ReceiptLines { // for _, line := range e.ReceiptLines {
product := dtodomain.InventoryReceiptLineProductResponse{} // product := dtodomain.InventoryReceiptLineProductResponse{}
if line.Product.ID != uuid.Nil { // if line.Product.ID != uuid.Nil {
product = dtodomain.InventoryReceiptLineProductResponse{ // product = dtodomain.InventoryReceiptLineProductResponse{
ID: line.Product.ID.String(), // ID: line.Product.ID.String(),
Name: line.Product.Name, // Name: line.Product.Name,
RefNumber: line.Product.RefNumber, // RefNumber: line.Product.RefNumber,
Uom: pkgdto.IdNameResponse{ // Uom: pkgdto.IdNameResponse{
ID: line.Product.Uom.ID.String(), // ID: line.Product.Uom.ID.String(),
Name: line.Product.Uom.Name, // Name: line.Product.Uom.Name,
}, // },
DimLength: line.Product.DimLength, // DimLength: line.Product.DimLength,
DimWidth: line.Product.DimWidth, // DimWidth: line.Product.DimWidth,
DimHeight: line.Product.DimHeight, // DimHeight: line.Product.DimHeight,
DimUom: pkgdto.IdNameResponse{ // DimUom: pkgdto.IdNameResponse{
ID: line.Product.DimUom.ID.String(), // ID: line.Product.DimUom.ID.String(),
Name: line.Product.DimUom.Name, // Name: line.Product.DimUom.Name,
}, // },
} // }
} // }
var repackUomID *string // var repackUomID *string
if line.RepackUomID != nil { // if line.RepackUomID != nil {
tmp := line.RepackUomID.String() // tmp := line.RepackUomID.String()
repackUomID = &tmp // repackUomID = &tmp
} else { // } else {
repackUomID = nil // repackUomID = nil
} // }
lines = append(lines, dtodomain.InventoryReceiptLineResponse{ // lines = append(lines, dtodomain.InventoryReceiptLineResponse{
ID: line.ID.String(), // ID: line.ID.String(),
Quantity: line.Quantity, // Quantity: line.Quantity,
BatchNumber: line.BatchNumber, // BatchNumber: line.BatchNumber,
RepackingSuggestion: line.RepackingSuggestion, // RepackingSuggestion: line.RepackingSuggestion,
RepackUomID: repackUomID, // RepackUomID: repackUomID,
Product: product, // Product: product,
ClientID: line.ClientID.String(), // ClientID: line.ClientID.String(),
}) // })
} // }
var assignment *dtodomain.AssignmentResponse
assignment := dtodomain.AssignmentResponse{}
if e.Assignment.ID != uuid.Nil { if e.Assignment.ID != uuid.Nil {
assignment = toAssignmentResponse(e.Assignment) assignmentObj := toAssignmentResponse(e.Assignment)
assignment = &assignmentObj
} else {
assignment = nil
} }
return dtodomain.InventoryReceiptResponse{ return dtodomain.InventoryReceiptResponse{
@ -259,10 +275,10 @@ func toInventoryReceiptResponse(e entities.TInventoryReceiptEntity) dtodomain.In
Source: e.Source, Source: e.Source,
QrCodeFile: e.QrCodeFile, QrCodeFile: e.QrCodeFile,
// ClientID: e.ClientID.String(), // ClientID: e.ClientID.String(),
Client: client, Client: client,
LineCount: len(lines), // LineCount: len(lines),
ReceiptLines: lines, // ReceiptLines: lines,
Assignment: assignment, Assignment: assignment,
} }
} }