feat: add GetLinesByIssueId method to InventoryIssueController and service for retrieving issue lines

This commit is contained in:
Habib Fatkhul Rohman 2025-11-28 14:27:48 +07:00
parent dd7ea563a6
commit 0eed8f6a7b
4 changed files with 187 additions and 127 deletions

View File

@ -19,6 +19,7 @@ type InventoryIssueController 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)
GetLinesByIssueId(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)
@ -37,6 +38,18 @@ func NewInventoryIssueController(i *do.Injector, issueService service.InventoryI
} }
} }
func (c *inventoryIssueController) GetLinesByIssueId(ctx *gin.Context) {
issueId := ctx.Param("id")
lines, err := c.issueService.GetLinesByIssueId(ctx, issueId)
if err != nil {
res := utils.BuildResponseFailed(dto.MESSAGE_FAILED_GET_INVENTORY_ISSUE_LINE, err.Error(), nil)
ctx.JSON(http.StatusInternalServerError, res)
return
}
res := utils.BuildResponseSuccess(dto.MESSAGE_SUCCESS_GET_INVENTORY_ISSUE_LINE, lines)
ctx.JSON(http.StatusOK, res)
}
func (c *inventoryIssueController) Create(ctx *gin.Context) { func (c *inventoryIssueController) Create(ctx *gin.Context) {
var req dto.InventoryIssueCreateRequest var req dto.InventoryIssueCreateRequest
if err := ctx.ShouldBindJSON(&req); err != nil { if err := ctx.ShouldBindJSON(&req); err != nil {

View File

@ -1,6 +1,11 @@
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/Caknoooo/go-gin-clean-starter/pkg/utils"
"github.com/google/uuid"
)
const ( const (
MESSAGE_FAILED_CREATE_INVENTORY_ISSUE = "failed create inventory issue" MESSAGE_FAILED_CREATE_INVENTORY_ISSUE = "failed create inventory issue"
@ -18,6 +23,8 @@ const (
MESSAGE_SUCCESS_DELETE_INVENTORY_ISSUE = "success delete inventory issue" MESSAGE_SUCCESS_DELETE_INVENTORY_ISSUE = "success delete inventory issue"
MESSAGE_SUCCESS_DELETE_INVENTORY_ISSUE_LINE = "success delete inventory issue line" MESSAGE_SUCCESS_DELETE_INVENTORY_ISSUE_LINE = "success delete inventory issue line"
MESSAGE_FAILED_GET_DATA_FROM_BODY = "failed get data from body" MESSAGE_FAILED_GET_DATA_FROM_BODY = "failed get data from body"
MESSAGE_FAILED_GET_INVENTORY_ISSUE_LINE = "failed get inventory issue line"
MESSAGE_SUCCESS_GET_INVENTORY_ISSUE_LINE = "success get inventory issue line"
) )
type InventoryIssueCreateRequest struct { type InventoryIssueCreateRequest struct {
@ -59,17 +66,17 @@ type InventoryIssueLineUpdateRequest struct {
} }
type InventoryIssueResponse struct { type InventoryIssueResponse struct {
ID string `json:"id"` ID string `json:"id"`
DocumentNumber string `json:"document_number"` DocumentNumber string `json:"document_number"`
DocumentDate string `json:"document_date"` DocumentDate string `json:"document_date"`
DueDate string `json:"due_date"` DueDate string `json:"due_date"`
Status string `json:"status"` Status string `json:"status"`
IssuerBy pkgdto.IdNameResponse `json:"issuer_by"` IssuerBy pkgdto.IdNameResponse `json:"issuer_by"`
InvRequest pkgdto.IdNameResponse `json:"inv_request"` InvRequest pkgdto.IdNameResponse `json:"inv_request"`
Client pkgdto.IdNameResponse `json:"client"` Client pkgdto.IdNameResponse `json:"client"`
LineCount int `json:"line_count"` // LineCount int `json:"line_count"`
IssueLines []InventoryIssueLineResponse `json:"issue_lines"` // IssueLines []InventoryIssueLineResponse `json:"issue_lines"`
Assignment AssignmentResponse `json:"assignment,omitempty"` Assignment AssignmentResponse `json:"assignment,omitempty"`
} }
type InventoryIssueLineResponse struct { type InventoryIssueLineResponse struct {
@ -91,10 +98,9 @@ type InventoryIssueProductResponse struct {
} }
type AssignmentResponse struct { type AssignmentResponse struct {
ID string `json:"id"` ID string `json:"id"`
DocumentType string `json:"document_type"` DocumentType string `json:"document_type"`
DocumentID string `json:"document_id"` DocumentID string `json:"document_id"`
// Client pkgdto.IdNameResponse `json:"client"`
AssignmentUsers []AssignmentUserResponse `json:"assignment_users"` AssignmentUsers []AssignmentUserResponse `json:"assignment_users"`
} }
@ -103,5 +109,141 @@ type AssignmentUserResponse struct {
TaskType string `json:"task_type"` TaskType string `json:"task_type"`
User pkgdto.IdNameResponse `json:"user"` User pkgdto.IdNameResponse `json:"user"`
Role pkgdto.IdNameResponse `json:"role"` Role pkgdto.IdNameResponse `json:"role"`
// Client pkgdto.IdNameResponse `json:"client"` }
func ToInventoryIssueResponse(e entities.TInventoryIssueEntity) InventoryIssueResponse {
issuer := pkgdto.IdNameResponse{}
if e.Issuer.ID != uuid.Nil {
issuer = pkgdto.IdNameResponse{
ID: e.Issuer.ID.String(),
Name: e.Issuer.Name,
}
}
invRequest := pkgdto.IdNameResponse{}
if e.InvRequest.ID != uuid.Nil {
invRequest = pkgdto.IdNameResponse{
ID: e.InvRequest.ID.String(),
Name: e.InvRequest.DocumentNumber,
}
}
client := pkgdto.IdNameResponse{}
if e.Client.ID != uuid.Nil {
client = pkgdto.IdNameResponse{
ID: e.Client.ID.String(),
Name: e.Client.Name,
}
}
assignment := AssignmentResponse{}
if e.Assignment.ID != uuid.Nil {
assignment = ToAssignmentResponse(e.Assignment)
}
// lines := make([]InventoryIssueLineResponse, 0)
// for _, line := range e.IssueLines {
// product := InventoryIssueProductResponse{}
// if line.Product.ID != uuid.Nil {
// product = InventoryIssueProductResponse{
// ID: line.Product.ID.String(),
// RefNumber: line.Product.RefNumber,
// Name: line.Product.Name,
// }
// }
// warehouse := pkgdto.IdNameResponse{}
// if line.Warehouse.ID != uuid.Nil {
// warehouse = pkgdto.IdNameResponse{
// ID: line.Warehouse.ID.String(),
// Name: line.Warehouse.Name,
// }
// }
// clientLine := pkgdto.IdNameResponse{}
// if line.Client.ID != uuid.Nil {
// clientLine = pkgdto.IdNameResponse{
// ID: line.Client.ID.String(),
// Name: line.Client.Name,
// }
// }
// lines = append(lines, InventoryIssueLineResponse{
// ID: line.ID.String(),
// CurrentStock: line.CurrentStock,
// MinStock: line.MinStock,
// RequestQuantity: line.RequestQuantity,
// IssuedQuantity: line.IssuedQuantity,
// Remarks: line.Remarks,
// Product: product,
// Warehouse: warehouse,
// Client: clientLine,
// })
// }
return InventoryIssueResponse{
ID: e.ID.String(),
DocumentNumber: e.DocumentNumber,
DocumentDate: utils.DateTimeToString(e.DocumentDate),
DueDate: utils.DateTimeToString(e.DueDate),
Status: e.Status,
IssuerBy: issuer,
InvRequest: invRequest,
Client: client,
// LineCount: len(lines),
// IssueLines: lines,
Assignment: assignment,
}
}
func ToAssignmentResponse(e entities.TAssignmentEntity) AssignmentResponse {
users := make([]AssignmentUserResponse, 0)
for _, user := range e.AssignmentUsers {
userResp := AssignmentUserResponse{
ID: user.ID.String(),
TaskType: user.TaskType,
User: pkgdto.IdNameResponse{ID: user.User.ID.String(), Name: user.User.Name},
Role: pkgdto.IdNameResponse{ID: user.Role.ID.String(), Name: user.Role.Name},
}
users = append(users, userResp)
}
return AssignmentResponse{
ID: e.ID.String(),
DocumentType: e.DocumentType,
DocumentID: e.DocumentID.String(),
AssignmentUsers: users,
}
}
func ToInventoryIssueLineResponses(lines []entities.TInventoryIssueLineEntity) []InventoryIssueLineResponse {
responses := make([]InventoryIssueLineResponse, 0)
for _, line := range lines {
product := InventoryIssueProductResponse{}
if line.Product.ID != uuid.Nil {
product = InventoryIssueProductResponse{
ID: line.Product.ID.String(),
RefNumber: line.Product.RefNumber,
Name: line.Product.Name,
}
}
warehouse := pkgdto.IdNameResponse{}
if line.Warehouse.ID != uuid.Nil {
warehouse = pkgdto.IdNameResponse{
ID: line.Warehouse.ID.String(),
Name: line.Warehouse.Name,
}
}
clientLine := pkgdto.IdNameResponse{}
if line.Client.ID != uuid.Nil {
clientLine = pkgdto.IdNameResponse{
ID: line.Client.ID.String(),
Name: line.Client.Name,
}
}
responses = append(responses, InventoryIssueLineResponse{
ID: line.ID.String(),
CurrentStock: line.CurrentStock,
MinStock: line.MinStock,
RequestQuantity: line.RequestQuantity,
IssuedQuantity: line.IssuedQuantity,
Remarks: line.Remarks,
Product: product,
Warehouse: warehouse,
Client: clientLine,
})
}
return responses
} }

View File

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

View File

@ -19,6 +19,7 @@ type InventoryIssueService interface {
GetAll(ctx context.Context, filter query.InventoryIssueFilter) ([]dtodomain.InventoryIssueResponse, int64, error) GetAll(ctx context.Context, filter query.InventoryIssueFilter) ([]dtodomain.InventoryIssueResponse, int64, error)
Update(ctx context.Context, req dtodomain.InventoryIssueUpdateRequest, id string) (dtodomain.InventoryIssueResponse, error) Update(ctx context.Context, req dtodomain.InventoryIssueUpdateRequest, id string) (dtodomain.InventoryIssueResponse, error)
Delete(ctx context.Context, id string) error Delete(ctx context.Context, id string) error
GetLinesByIssueId(ctx context.Context, issueId string) ([]dtodomain.InventoryIssueLineResponse, error)
CreateLine(ctx context.Context, issueId string, req dtodomain.InventoryIssueLineCreateRequest) (dtodomain.InventoryIssueLineResponse, error) CreateLine(ctx context.Context, issueId string, req dtodomain.InventoryIssueLineCreateRequest) (dtodomain.InventoryIssueLineResponse, error)
UpdateLine(ctx context.Context, lineId string, req dtodomain.InventoryIssueLineUpdateRequest) (dtodomain.InventoryIssueLineResponse, error) UpdateLine(ctx context.Context, lineId string, req dtodomain.InventoryIssueLineUpdateRequest) (dtodomain.InventoryIssueLineResponse, error)
DeleteLine(ctx context.Context, lineId string) error DeleteLine(ctx context.Context, lineId string) error
@ -30,116 +31,19 @@ type inventoryIssueService struct {
issueLineRepo repository.InventoryIssueLineRepository issueLineRepo repository.InventoryIssueLineRepository
} }
// GetLinesByIssueId implements InventoryIssueService.
func (s *inventoryIssueService) GetLinesByIssueId(ctx context.Context, issueId string) ([]dtodomain.InventoryIssueLineResponse, error) {
lines, err := s.issueLineRepo.GetAllByIssueId(ctx, issueId)
if err != nil {
return nil, err
}
return dtodomain.ToInventoryIssueLineResponses(lines), nil
}
func NewInventoryIssueService(db *gorm.DB, issueRepo repository.InventoryIssueRepository, issueLineRepo repository.InventoryIssueLineRepository) InventoryIssueService { func NewInventoryIssueService(db *gorm.DB, issueRepo repository.InventoryIssueRepository, issueLineRepo repository.InventoryIssueLineRepository) InventoryIssueService {
return &inventoryIssueService{db: db, issueRepo: issueRepo, issueLineRepo: issueLineRepo} return &inventoryIssueService{db: db, issueRepo: issueRepo, issueLineRepo: issueLineRepo}
} }
func toInventoryIssueResponse(e entities.TInventoryIssueEntity) dtodomain.InventoryIssueResponse {
issuer := pkgdto.IdNameResponse{}
if e.Issuer.ID != uuid.Nil {
issuer = pkgdto.IdNameResponse{
ID: e.Issuer.ID.String(),
Name: e.Issuer.Name,
}
}
invRequest := pkgdto.IdNameResponse{}
if e.InvRequest.ID != uuid.Nil {
invRequest = pkgdto.IdNameResponse{
ID: e.InvRequest.ID.String(),
Name: e.InvRequest.DocumentNumber,
}
}
client := pkgdto.IdNameResponse{}
if e.Client.ID != uuid.Nil {
client = pkgdto.IdNameResponse{
ID: e.Client.ID.String(),
Name: e.Client.Name,
}
}
assignment := dtodomain.AssignmentResponse{}
if e.Assignment.ID != uuid.Nil {
assignment = toAssignmentResponse(e.Assignment)
}
lines := make([]dtodomain.InventoryIssueLineResponse, 0)
for _, line := range e.IssueLines {
product := dtodomain.InventoryIssueProductResponse{}
if line.Product.ID != uuid.Nil {
product = dtodomain.InventoryIssueProductResponse{
ID: line.Product.ID.String(),
RefNumber: line.Product.RefNumber,
Name: line.Product.Name,
}
}
warehouse := pkgdto.IdNameResponse{}
if line.Warehouse.ID != uuid.Nil {
warehouse = pkgdto.IdNameResponse{
ID: line.Warehouse.ID.String(),
Name: line.Warehouse.Name,
}
}
clientLine := pkgdto.IdNameResponse{}
if line.Client.ID != uuid.Nil {
clientLine = pkgdto.IdNameResponse{
ID: line.Client.ID.String(),
Name: line.Client.Name,
}
}
lines = append(lines, dtodomain.InventoryIssueLineResponse{
ID: line.ID.String(),
CurrentStock: line.CurrentStock,
MinStock: line.MinStock,
RequestQuantity: line.RequestQuantity,
IssuedQuantity: line.IssuedQuantity,
Remarks: line.Remarks,
Product: product,
Warehouse: warehouse,
Client: clientLine,
})
}
return dtodomain.InventoryIssueResponse{
ID: e.ID.String(),
DocumentNumber: e.DocumentNumber,
DocumentDate: utils.DateTimeToString(e.DocumentDate),
DueDate: utils.DateTimeToString(e.DueDate),
Status: e.Status,
IssuerBy: issuer,
InvRequest: invRequest,
Client: client,
LineCount: len(lines),
IssueLines: lines,
Assignment: assignment,
}
}
func toAssignmentResponse(e entities.TAssignmentEntity) dtodomain.AssignmentResponse {
// client := pkgdto.IdNameResponse{}
// if e.Client.ID != uuid.Nil {
// client = pkgdto.IdNameResponse{
// ID: e.Client.ID.String(),
// Name: e.Client.Name,
// }
// }
users := make([]dtodomain.AssignmentUserResponse, 0)
for _, user := range e.AssignmentUsers {
userResp := dtodomain.AssignmentUserResponse{
ID: user.ID.String(),
TaskType: user.TaskType,
User: pkgdto.IdNameResponse{ID: user.User.ID.String(), Name: user.User.Name},
Role: pkgdto.IdNameResponse{ID: user.Role.ID.String(), Name: user.Role.Name},
// Client: pkgdto.IdNameResponse{ID: user.Client.ID.String(), Name: user.Client.Name},
}
users = append(users, userResp)
}
return dtodomain.AssignmentResponse{
ID: e.ID.String(),
DocumentType: e.DocumentType,
DocumentID: e.DocumentID.String(),
// Client: client,
AssignmentUsers: users,
}
}
func (s *inventoryIssueService) Create(ctx context.Context, req dtodomain.InventoryIssueCreateRequest) (dtodomain.InventoryIssueResponse, error) { func (s *inventoryIssueService) Create(ctx context.Context, req dtodomain.InventoryIssueCreateRequest) (dtodomain.InventoryIssueResponse, error) {
tx := s.db.Begin() tx := s.db.Begin()
defer func() { defer func() {
@ -223,7 +127,7 @@ func (s *inventoryIssueService) Create(ctx context.Context, req dtodomain.Invent
if err != nil { if err != nil {
return dtodomain.InventoryIssueResponse{}, err return dtodomain.InventoryIssueResponse{}, err
} }
return toInventoryIssueResponse(result), nil return dtodomain.ToInventoryIssueResponse(result), nil
} }
func (s *inventoryIssueService) GetById(ctx context.Context, id string) (dtodomain.InventoryIssueResponse, error) { func (s *inventoryIssueService) GetById(ctx context.Context, id string) (dtodomain.InventoryIssueResponse, error) {
@ -231,7 +135,7 @@ func (s *inventoryIssueService) GetById(ctx context.Context, id string) (dtodoma
if err != nil { if err != nil {
return dtodomain.InventoryIssueResponse{}, err return dtodomain.InventoryIssueResponse{}, err
} }
return toInventoryIssueResponse(issue), nil return dtodomain.ToInventoryIssueResponse(issue), nil
} }
func (s *inventoryIssueService) GetAll(ctx context.Context, filter query.InventoryIssueFilter) ([]dtodomain.InventoryIssueResponse, int64, error) { func (s *inventoryIssueService) GetAll(ctx context.Context, filter query.InventoryIssueFilter) ([]dtodomain.InventoryIssueResponse, int64, error) {
@ -241,7 +145,7 @@ func (s *inventoryIssueService) GetAll(ctx context.Context, filter query.Invento
} }
var responses []dtodomain.InventoryIssueResponse var responses []dtodomain.InventoryIssueResponse
for _, e := range issues { for _, e := range issues {
responses = append(responses, toInventoryIssueResponse(e)) responses = append(responses, dtodomain.ToInventoryIssueResponse(e))
} }
if responses == nil { if responses == nil {
responses = make([]dtodomain.InventoryIssueResponse, 0) responses = make([]dtodomain.InventoryIssueResponse, 0)
@ -274,7 +178,7 @@ func (s *inventoryIssueService) Update(ctx context.Context, req dtodomain.Invent
if err != nil { if err != nil {
return dtodomain.InventoryIssueResponse{}, err return dtodomain.InventoryIssueResponse{}, err
} }
return toInventoryIssueResponse(result), nil return dtodomain.ToInventoryIssueResponse(result), nil
} }
func (s *inventoryIssueService) Delete(ctx context.Context, id string) error { func (s *inventoryIssueService) Delete(ctx context.Context, id string) error {