feat: implement GetLineById method in multiple controllers and services, and enhance filtering with status in queries
Deploy Application / deploy (push) Successful in 22s Details

This commit is contained in:
Habib Fatkhul Rohman 2025-12-08 15:41:30 +07:00
parent 923cbaba6a
commit b0eaa3fd33
19 changed files with 157 additions and 2 deletions

View File

@ -20,6 +20,7 @@ type InventoryIssueController interface {
GetById(ctx *gin.Context)
GetAll(ctx *gin.Context)
GetLinesByIssueId(ctx *gin.Context)
GetLineById(ctx *gin.Context)
CreateLine(ctx *gin.Context)
UpdateLine(ctx *gin.Context)
DeleteLine(ctx *gin.Context)
@ -30,6 +31,19 @@ type inventoryIssueController struct {
db *gorm.DB
}
// GetLineById implements InventoryIssueController.
func (c *inventoryIssueController) GetLineById(ctx *gin.Context) {
id := ctx.Param("id")
line, err := c.issueService.GetLineById(ctx, id)
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, line)
ctx.JSON(http.StatusOK, res)
}
func NewInventoryIssueController(i *do.Injector, issueService service.InventoryIssueService) InventoryIssueController {
db := do.MustInvokeNamed[*gorm.DB](i, constants.DB)
return &inventoryIssueController{
@ -112,6 +126,7 @@ func (c *inventoryIssueController) GetAll(ctx *gin.Context) {
clientId := ctx.MustGet("client_id").(string)
var filter query.InventoryIssueFilter
filter.ClientID = clientId
filter.Status = ctx.Query("status")
if err := ctx.ShouldBindQuery(&filter); err != nil {
res := utils.BuildResponseFailed(dto.MESSAGE_FAILED_GET_INVENTORY_ISSUE, err.Error(), nil)
ctx.JSON(http.StatusBadRequest, res)

View File

@ -9,6 +9,7 @@ type InventoryIssueFilter struct {
IssuerBy string `form:"issuer_by"`
PerPage int `form:"per_page"`
Page int `form:"page"`
Status string `form:"status"`
}
func ApplyInventoryIssueFilters(db *gorm.DB, filter InventoryIssueFilter) *gorm.DB {
@ -18,5 +19,8 @@ func ApplyInventoryIssueFilters(db *gorm.DB, filter InventoryIssueFilter) *gorm.
if filter.IssuerBy != "" {
db = db.Where("issuer_by = ?", filter.IssuerBy)
}
if filter.Status != "" {
db = db.Where("status = ?", filter.Status)
}
return db
}

View File

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

View File

@ -23,6 +23,7 @@ type InventoryIssueService interface {
Update(ctx context.Context, req dtodomain.InventoryIssueUpdateRequest, id string) (dtodomain.InventoryIssueResponse, error)
Delete(ctx context.Context, id string) error
GetLinesByIssueId(ctx context.Context, issueId string) ([]dtodomain.InventoryIssueLineResponse, error)
GetLineById(ctx context.Context, lineId string) (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)
DeleteLine(ctx context.Context, lineId string) error
@ -36,6 +37,47 @@ type inventoryIssueService struct {
log *logrus.Logger
}
// GetLineById implements InventoryIssueService.
func (s *inventoryIssueService) GetLineById(ctx context.Context, lineId string) (dtodomain.InventoryIssueLineResponse, error) {
line, err := s.issueLineRepo.GetById(ctx, nil, lineId)
if err != nil {
return dtodomain.InventoryIssueLineResponse{}, err
}
clientLine := pkgdto.IdNameResponse{}
if line.Client.ID != uuid.Nil {
clientLine = pkgdto.IdNameResponse{
ID: line.Client.ID.String(),
Name: line.Client.Name,
}
}
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,
}
}
return 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,
}, nil
}
// GetLinesByIssueId implements InventoryIssueService.
func (s *inventoryIssueService) GetLinesByIssueId(ctx context.Context, issueId string) ([]dtodomain.InventoryIssueLineResponse, error) {
lines, err := s.issueLineRepo.GetAllByIssueId(ctx, issueId)

View File

@ -18,6 +18,7 @@ type InventoryMovementController interface {
GetById(ctx *gin.Context)
GetAll(ctx *gin.Context)
GetLinesByMovementId(ctx *gin.Context)
GetLineById(ctx *gin.Context)
CreateLine(ctx *gin.Context)
UpdateLine(ctx *gin.Context)
DeleteLine(ctx *gin.Context)
@ -27,6 +28,19 @@ type inventoryMovementController struct {
movementService service.InventoryMovementService
}
// GetLineById implements InventoryMovementController.
func (c *inventoryMovementController) GetLineById(ctx *gin.Context) {
id := ctx.Param("id")
result, err := c.movementService.GetLineById(ctx, id)
if err != nil {
res := utils.BuildResponseFailed(dto.MESSAGE_FAILED_GET_INVENTORY_MOVEMENT_LINE, err.Error(), nil)
ctx.JSON(http.StatusInternalServerError, res)
return
}
res := utils.BuildResponseSuccess(dto.MESSAGE_SUCCESS_GET_INVENTORY_MOVEMENT_LINE, result)
ctx.JSON(http.StatusOK, res)
}
func (c *inventoryMovementController) GetLinesByMovementId(ctx *gin.Context) {
id := ctx.Param("id")
result, err := c.movementService.GetLinesByMovementId(ctx, id)
@ -101,6 +115,7 @@ func (c *inventoryMovementController) GetAll(ctx *gin.Context) {
clientId := ctx.DefaultQuery("client_id", "")
var filter query.InventoryMovementFilter
filter.ClientID = clientId
filter.Status = ctx.Query("status")
if err := ctx.ShouldBindQuery(&filter); err != nil {
res := utils.BuildResponseFailed(dto.MESSAGE_FAILED_GET_INVENTORY_MOVEMENT, err.Error(), nil)
ctx.JSON(http.StatusBadRequest, res)

View File

@ -10,6 +10,7 @@ type InventoryMovementFilter struct {
DestinationLocation string `form:"destination_location"`
PerPage int `form:"per_page"`
Page int `form:"page"`
Status string `form:"status"`
}
func ApplyInventoryMovementFilters(db *gorm.DB, filter InventoryMovementFilter) *gorm.DB {
@ -22,5 +23,8 @@ func ApplyInventoryMovementFilters(db *gorm.DB, filter InventoryMovementFilter)
if filter.DestinationLocation != "" {
db = db.Where("destination_location_id = ?", filter.DestinationLocation)
}
if filter.Status != "" {
db = db.Where("status = ?", filter.Status)
}
return db
}

View File

@ -21,6 +21,7 @@ func RegisterRoutes(server *gin.Engine, injector *do.Injector) {
movementRoutes.DELETE(":id", middlewares.Authenticate(jwtService), movementController.Delete)
movementRoutes.GET("", middlewares.Authenticate(jwtService), movementController.GetAll)
movementRoutes.GET(":id/lines", middlewares.Authenticate(jwtService), movementController.GetLinesByMovementId)
movementRoutes.GET("lines/:id", middlewares.Authenticate(jwtService), movementController.GetLineById)
movementRoutes.POST(":id/lines", middlewares.Authenticate(jwtService), movementController.CreateLine)
movementRoutes.PUT("lines/:id", middlewares.Authenticate(jwtService), movementController.UpdateLine)
movementRoutes.DELETE("lines/:id", middlewares.Authenticate(jwtService), movementController.DeleteLine)

View File

@ -22,6 +22,7 @@ type InventoryMovementService interface {
Update(ctx context.Context, req dtodomain.InventoryMovementUpdateRequest, id string) (dtodomain.InventoryMovementResponse, error)
Delete(ctx context.Context, id string) error
GetLinesByMovementId(ctx context.Context, movementId string) ([]dtodomain.InventoryMovementLineResponse, error)
GetLineById(ctx context.Context, lineId string) (dtodomain.InventoryMovementLineResponse, error)
CreateLine(ctx context.Context, movementId string, req dtodomain.InventoryMovementLineCreateRequest) (dtodomain.InventoryMovementLineResponse, error)
UpdateLine(ctx context.Context, lineId string, req dtodomain.InventoryMovementLineUpdateRequest) (dtodomain.InventoryMovementLineResponse, error)
DeleteLine(ctx context.Context, lineId string) error
@ -35,6 +36,15 @@ type inventoryMovementService struct {
log *logrus.Logger
}
// GetLineById implements InventoryMovementService.
func (s *inventoryMovementService) GetLineById(ctx context.Context, lineId string) (dtodomain.InventoryMovementLineResponse, error) {
line, err := s.movementLineRepo.GetById(ctx, nil, lineId)
if err != nil {
return dtodomain.InventoryMovementLineResponse{}, err
}
return dtodomain.ToInventoryMovementLineResponse(line), nil
}
// GetLinesByMovementId implements InventoryMovementService.
func (s *inventoryMovementService) GetLinesByMovementId(ctx context.Context, movementId string) ([]dtodomain.InventoryMovementLineResponse, error) {
lines, err := s.movementLineRepo.GetAllByMovementId(ctx, movementId)

View File

@ -20,6 +20,7 @@ type InventoryReceiptController interface {
GetById(ctx *gin.Context)
GetAll(ctx *gin.Context)
GetLinesByReceiptId(ctx *gin.Context)
GetLineById(ctx *gin.Context)
CreateLine(ctx *gin.Context)
UpdateLine(ctx *gin.Context)
DeleteLine(ctx *gin.Context)
@ -31,6 +32,19 @@ type inventoryReceiptController struct {
db *gorm.DB
}
// GetLineById implements InventoryReceiptController.
func (c *inventoryReceiptController) GetLineById(ctx *gin.Context) {
id := ctx.Param("id")
line, err := c.receiptService.GetLineById(ctx, id)
if err != nil {
res := utils.BuildResponseFailed(dto.MESSAGE_FAILED_GET_INVENTORY_RECEIPT_LINE, err.Error(), nil)
ctx.JSON(http.StatusInternalServerError, res)
return
}
res := utils.BuildResponseSuccess(dto.MESSAGE_SUCCESS_GET_INVENTORY_RECEIPT_LINE, line)
ctx.JSON(http.StatusOK, res)
}
// GetLines implements InventoryReceiptController.
func (c *inventoryReceiptController) GetLinesByReceiptId(ctx *gin.Context) {
id := ctx.Param("id")
@ -169,6 +183,7 @@ func (c *inventoryReceiptController) GetAll(ctx *gin.Context) {
clientId := ctx.DefaultQuery("client_id", "")
var filter query.InventoryReceiptFilter
filter.ClientID = clientId
filter.Status = ctx.Query("status")
if err := ctx.ShouldBindQuery(&filter); err != nil {
res := utils.BuildResponseFailed(dto.MESSAGE_FAILED_GET_INVENTORY_RECEIPT, err.Error(), nil)
ctx.JSON(http.StatusBadRequest, res)

View File

@ -26,6 +26,8 @@ const (
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"
MESSAGE_FAILED_GET_INVENTORY_RECEIPT_LINE = "failed get inventory receipt line"
MESSAGE_SUCCESS_GET_INVENTORY_RECEIPT_LINE = "success get inventory receipt line"
)
type InventoryReceiptCreateRequest struct {

View File

@ -9,6 +9,7 @@ type InventoryReceiptFilter struct {
Source string `form:"source"`
PerPage int `form:"per_page"`
Page int `form:"page"`
Status string `form:"status"`
}
func ApplyInventoryReceiptFilters(db *gorm.DB, filter InventoryReceiptFilter) *gorm.DB {

View File

@ -27,6 +27,7 @@ type InventoryReceiptService interface {
Update(ctx context.Context, req dtodomain.InventoryReceiptUpdateRequest, id string) (dtodomain.InventoryReceiptResponse, error)
Delete(ctx context.Context, id string) error
GetLinesByReceiptId(ctx context.Context, id string) ([]dtodomain.InventoryReceiptLineResponse, error)
GetLineById(ctx context.Context, lineId string) (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)
DeleteLine(ctx context.Context, lineId string) error
@ -44,6 +45,15 @@ type inventoryReceiptService struct {
log *logrus.Logger
}
// GetLineById implements InventoryReceiptService.
func (s *inventoryReceiptService) GetLineById(ctx context.Context, lineId string) (dtodomain.InventoryReceiptLineResponse, error) {
line, err := s.receiptLineRepo.GetById(ctx, nil, lineId)
if err != nil {
return dtodomain.InventoryReceiptLineResponse{}, err
}
return dtodomain.ToInventoryReceiptLineResponse(line), nil
}
func (s *inventoryReceiptService) GetLinesByReceiptId(ctx context.Context, id string) ([]dtodomain.InventoryReceiptLineResponse, error) {
lines, err := s.receiptLineRepo.GetAllByReceiptId(ctx, id)
if err != nil {

View File

@ -166,6 +166,7 @@ func (c *inventoryRequestController) GetAll(ctx *gin.Context) {
clientId := ctx.DefaultQuery("client_id", "")
var filter query.InventoryRequestFilter
filter.ClientID = clientId
filter.Status = ctx.Query("status")
if err := ctx.ShouldBindQuery(&filter); err != nil {
res := utils.BuildResponseFailed(dto.MESSAGE_FAILED_GET_INVENTORY_REQUEST, err.Error(), nil)
ctx.JSON(http.StatusBadRequest, res)

View File

@ -9,6 +9,7 @@ type InventoryRequestFilter struct {
RequestType string `form:"request_type"`
PerPage int `form:"per_page"`
Page int `form:"page"`
Status string `form:"status"`
}
func ApplyInventoryRequestFilters(db *gorm.DB, filter InventoryRequestFilter) *gorm.DB {
@ -18,5 +19,8 @@ func ApplyInventoryRequestFilters(db *gorm.DB, filter InventoryRequestFilter) *g
if filter.RequestType != "" {
db = db.Where("request_type ILIKE ?", "%"+filter.RequestType+"%")
}
if filter.Status != "" {
db = db.Where("status = ?", filter.Status)
}
return db
}

View File

@ -18,6 +18,7 @@ type InventoryReturnController interface {
GetById(ctx *gin.Context)
GetAll(ctx *gin.Context)
GetLinesByReturnId(ctx *gin.Context)
GetLineById(ctx *gin.Context)
CreateLine(ctx *gin.Context)
UpdateLine(ctx *gin.Context)
DeleteLine(ctx *gin.Context)
@ -27,6 +28,19 @@ type inventoryReturnController struct {
returnService service.InventoryReturnService
}
// GetLineById implements InventoryReturnController.
func (c *inventoryReturnController) GetLineById(ctx *gin.Context) {
lineId := ctx.Param("line_id")
line, err := c.returnService.GetLineById(ctx, lineId)
if err != nil {
res := utils.BuildResponseFailed(dto.MESSAGE_FAILED_GET_INVENTORY_RETURN_LINE, err.Error(), nil)
ctx.JSON(http.StatusInternalServerError, res)
return
}
res := utils.BuildResponseSuccess(dto.MESSAGE_SUCCESS_GET_INVENTORY_RETURN_LINE, line)
ctx.JSON(http.StatusOK, res)
}
func (c *inventoryReturnController) GetLinesByReturnId(ctx *gin.Context) {
returnId := ctx.Param("id")
lines, err := c.returnService.GetLinesByReturnId(ctx, returnId)
@ -132,6 +146,7 @@ func (c *inventoryReturnController) GetAll(ctx *gin.Context) {
clientId := ctx.MustGet("client_id").(string)
var filter query.InventoryReturnFilter
filter.ClientID = clientId
filter.Status = ctx.Query("status")
if err := ctx.ShouldBindQuery(&filter); err != nil {
res := utils.BuildResponseFailed(dto.MESSAGE_FAILED_GET_INVENTORY_RETURN, err.Error(), nil)
ctx.JSON(http.StatusBadRequest, res)

View File

@ -9,6 +9,7 @@ type InventoryReturnFilter struct {
Source string `form:"source"`
PerPage int `form:"per_page"`
Page int `form:"page"`
Status string `form:"status"`
}
func ApplyInventoryReturnFilters(db *gorm.DB, filter InventoryReturnFilter) *gorm.DB {
@ -18,5 +19,8 @@ func ApplyInventoryReturnFilters(db *gorm.DB, filter InventoryReturnFilter) *gor
if filter.Source != "" {
db = db.Where("source ILIKE ?", "%"+filter.Source+"%")
}
if filter.Status != "" {
db = db.Where("status = ?", filter.Status)
}
return db
}

View File

@ -21,6 +21,7 @@ func RegisterRoutes(server *gin.Engine, injector *do.Injector) {
returnRoutes.DELETE(":id", middlewares.Authenticate(jwtService), returnController.Delete)
returnRoutes.GET("", middlewares.Authenticate(jwtService), returnController.GetAll)
returnRoutes.GET(":id/lines", middlewares.Authenticate(jwtService), returnController.GetLinesByReturnId)
returnRoutes.GET("lines/:id", middlewares.Authenticate(jwtService), returnController.GetLineById)
returnRoutes.POST(":id/lines", middlewares.Authenticate(jwtService), returnController.CreateLine)
returnRoutes.PUT("lines/:id", middlewares.Authenticate(jwtService), returnController.UpdateLine)
returnRoutes.DELETE("lines/:id", middlewares.Authenticate(jwtService), returnController.DeleteLine)

View File

@ -26,6 +26,7 @@ type InventoryReturnService interface {
GetLinesByReturnId(ctx context.Context, returnId string) ([]dtodomain.InventoryReturnLineResponse, error)
Update(ctx context.Context, req dtodomain.InventoryReturnUpdateRequest, id string) (dtodomain.InventoryReturnResponse, error)
Delete(ctx context.Context, id string) error
GetLineById(ctx context.Context, lineId string) (dtodomain.InventoryReturnLineResponse, error)
CreateLine(ctx context.Context, returnId string, req dtodomain.InventoryReturnLineCreateRequest) (dtodomain.InventoryReturnLineResponse, error)
UpdateLine(ctx context.Context, lineId string, req dtodomain.InventoryReturnLineUpdateRequest) (dtodomain.InventoryReturnLineResponse, error)
DeleteLine(ctx context.Context, lineId string) error
@ -41,6 +42,15 @@ type inventoryReturnService struct {
log *logrus.Logger
}
// GetLineById implements InventoryReturnService.
func (s *inventoryReturnService) GetLineById(ctx context.Context, lineId string) (dtodomain.InventoryReturnLineResponse, error) {
line, err := s.returnLineRepo.GetById(ctx, nil, lineId)
if err != nil {
return dtodomain.InventoryReturnLineResponse{}, err
}
return dtodomain.ToInventoryReturnLineResponse(line), nil
}
// GetLinesByReturnId implements InventoryReturnService.
func (s *inventoryReturnService) GetLinesByReturnId(ctx context.Context, returnId string) ([]dtodomain.InventoryReturnLineResponse, error) {
lines, err := s.returnLineRepo.GetAllByReturnId(ctx, returnId)

View File

@ -40,7 +40,7 @@ func (f *UserFilter) ApplyFilters(query *gorm.DB) *gorm.DB {
query = query.Where("name ILIKE ?", "%"+f.Name+"%")
}
if f.ClientID != "" {
query = query.Where("client_id = ?", f.ClientID)
query = query.Where("m_users.client_id = ?", f.ClientID)
}
if f.GroupID != "" {