feat[BE]: add flock response to project flock and projectflockkandang getone and getall API

This commit is contained in:
aguhh18
2025-11-11 12:16:39 +07:00
parent fd0943dfaf
commit 6b5d27ae8e
7 changed files with 220 additions and 58 deletions
@@ -7,6 +7,7 @@ import (
"strconv"
"strings"
flockDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/flocks/dto"
"gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/dto"
service "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/services"
validation "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/validations"
@@ -84,11 +85,20 @@ func (u *ProjectflockController) GetAll(c *fiber.Ctx) error {
query.KandangIds = ids
}
result, totalResults, err := u.ProjectflockService.GetAll(c, query)
result, totalResults, flockMap, err := u.ProjectflockService.GetAll(c, query)
if err != nil {
return err
}
data := make([]dto.ProjectFlockListDTO, 0)
for _, projectFlock := range result {
var flock *flockDTO.FlockBaseDTO
if flockMap != nil {
flock = flockMap[projectFlock.Id]
}
data = append(data, dto.ToProjectFlockListDTO(projectFlock, flock))
}
return c.Status(fiber.StatusOK).
JSON(response.SuccessWithPaginate[dto.ProjectFlockListDTO]{
Code: fiber.StatusOK,
@@ -100,7 +110,7 @@ func (u *ProjectflockController) GetAll(c *fiber.Ctx) error {
TotalPages: int64(math.Ceil(float64(totalResults) / float64(query.Limit))),
TotalResults: totalResults,
},
Data: dto.ToProjectFlockListDTOs(result),
Data: data,
})
}
@@ -112,7 +122,7 @@ func (u *ProjectflockController) GetOne(c *fiber.Ctx) error {
return fiber.NewError(fiber.StatusBadRequest, "Invalid Id")
}
result, err := u.ProjectflockService.GetOne(c, uint(id))
result, flock, err := u.ProjectflockService.GetOne(c, uint(id))
if err != nil {
return err
}
@@ -122,7 +132,7 @@ func (u *ProjectflockController) GetOne(c *fiber.Ctx) error {
Code: fiber.StatusOK,
Status: "success",
Message: "Get projectflock successfully",
Data: dto.ToProjectFlockListDTO(*result),
Data: dto.ToProjectFlockListDTO(*result, flock),
})
}
@@ -143,7 +153,7 @@ func (u *ProjectflockController) CreateOne(c *fiber.Ctx) error {
Code: fiber.StatusCreated,
Status: "success",
Message: "Create projectflock successfully",
Data: dto.ToProjectFlockListDTO(*result),
Data: dto.ToProjectFlockListDTO(*result, nil),
})
}
@@ -170,7 +180,7 @@ func (u *ProjectflockController) UpdateOne(c *fiber.Ctx) error {
Code: fiber.StatusOK,
Status: "success",
Message: "Update projectflock successfully",
Data: dto.ToProjectFlockListDTO(*result),
Data: dto.ToProjectFlockListDTO(*result, nil),
})
}
@@ -210,7 +220,7 @@ func (u *ProjectflockController) Approval(c *fiber.Ctx) error {
message = "Submit projectflock approval successfully"
)
if len(results) == 1 {
data = dto.ToProjectFlockListDTO(results[0])
data = dto.ToProjectFlockListDTO(results[0], nil)
} else {
message = "Submit projectflock approvals successfully"
data = dto.ToProjectFlockListDTOs(results)
@@ -25,7 +25,7 @@ type ProjectFlockBaseDTO struct {
type ProjectFlockListDTO struct {
ProjectFlockBaseDTO
// Flock *flockDTO.FlockBaseDTO `json:"flock,omitempty"`
Flock *flockDTO.FlockBaseDTO `json:"flock,omitempty"`
Area *areaDTO.AreaBaseDTO `json:"area,omitempty"`
Category string `json:"category"`
Fcr *fcrDTO.FcrBaseDTO `json:"fcr,omitempty"`
@@ -51,7 +51,7 @@ type FlockPeriodDTO struct {
NextPeriod int `json:"next_period"`
}
func ToProjectFlockListDTO(e entity.ProjectFlock) ProjectFlockListDTO {
func ToProjectFlockListDTO(e entity.ProjectFlock, flock *flockDTO.FlockBaseDTO) ProjectFlockListDTO {
var createdUser *userDTO.UserBaseDTO
if e.CreatedUser.Id != 0 {
mapped := userDTO.ToUserBaseDTO(e.CreatedUser)
@@ -62,7 +62,7 @@ func ToProjectFlockListDTO(e entity.ProjectFlock) ProjectFlockListDTO {
if len(e.Kandangs) > 0 {
kandangSummaries = make([]KandangWithProjectFlockIdDTO, len(e.Kandangs))
for i, kandang := range e.Kandangs {
// Find project_flock_kandang_id dari KandangHistory
var pfkId uint
for _, kh := range e.KandangHistory {
if kh.KandangId == kandang.Id {
@@ -77,12 +77,6 @@ func ToProjectFlockListDTO(e entity.ProjectFlock) ProjectFlockListDTO {
}
}
// var flockSummary *flockDTO.FlockBaseDTO
// if baseName := pfutils.DeriveBaseName(e.FlockName); baseName != "" {
// summary := flockDTO.FlockBaseDTO{Id: 0, Name: baseName}
// flockSummary = &summary
// }
var areaSummary *areaDTO.AreaBaseDTO
if e.Area.Id != 0 {
mapped := areaDTO.ToAreaBaseDTO(e.Area)
@@ -101,6 +95,11 @@ func ToProjectFlockListDTO(e entity.ProjectFlock) ProjectFlockListDTO {
locationSummary = &mapped
}
var flockSummary *flockDTO.FlockBaseDTO
if flock != nil && flock.Id != 0 {
flockSummary = flock
}
latestApproval := defaultProjectFlockLatestApproval(e)
if e.LatestApproval != nil {
snapshot := approvalDTO.ToApprovalDTO(*e.LatestApproval)
@@ -109,30 +108,51 @@ func ToProjectFlockListDTO(e entity.ProjectFlock) ProjectFlockListDTO {
return ProjectFlockListDTO{
ProjectFlockBaseDTO: createProjectFlockBaseDTO(e),
// Flock: flockSummary,
Area: areaSummary,
Kandangs: kandangSummaries,
Category: e.Category,
Fcr: fcrSummary,
Location: locationSummary,
CreatedAt: e.CreatedAt,
UpdatedAt: e.UpdatedAt,
CreatedUser: createdUser,
Approval: latestApproval,
Flock: flockSummary,
Area: areaSummary,
Kandangs: kandangSummaries,
Category: e.Category,
Fcr: fcrSummary,
Location: locationSummary,
CreatedAt: e.CreatedAt,
UpdatedAt: e.UpdatedAt,
CreatedUser: createdUser,
Approval: latestApproval,
}
}
func ToProjectFlockListDTOWithFlock(e entity.ProjectFlock, flock *flockDTO.FlockBaseDTO) ProjectFlockListDTO {
return ToProjectFlockListDTO(e, flock)
}
func ToProjectFlockListDTOs(items []entity.ProjectFlock) []ProjectFlockListDTO {
result := make([]ProjectFlockListDTO, len(items))
for i, item := range items {
result[i] = ToProjectFlockListDTO(item)
result[i] = ToProjectFlockListDTO(item, nil)
}
return result
}
func ToProjectFlockDetailDTO(e entity.ProjectFlock) ProjectFlockDetailDTO {
func ToProjectFlockListDTOsWithFlocks(items []entity.ProjectFlock, flocks map[uint]*entity.Flock) []ProjectFlockListDTO {
result := make([]ProjectFlockListDTO, len(items))
for i, item := range items {
var flock *flockDTO.FlockBaseDTO
if flocks != nil {
if f := flocks[item.Id]; f != nil {
flock = &flockDTO.FlockBaseDTO{
Id: f.Id,
Name: f.Name,
}
}
}
result[i] = ToProjectFlockListDTOWithFlock(item, flock)
}
return result
}
func ToProjectFlockDetailDTO(e entity.ProjectFlock, flock *flockDTO.FlockBaseDTO) ProjectFlockDetailDTO {
return ProjectFlockDetailDTO{
ProjectFlockListDTO: ToProjectFlockListDTO(e),
ProjectFlockListDTO: ToProjectFlockListDTO(e, flock),
}
}
@@ -11,6 +11,7 @@ import (
commonSvc "gitlab.com/mbugroup/lti-api.git/internal/common/service"
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
productWarehouseRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/product-warehouses/repositories"
flockDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/flocks/dto"
flockRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/master/flocks/repositories"
kandangRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandangs/repositories"
warehouseRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/master/warehouses/repositories"
@@ -27,8 +28,8 @@ import (
)
type ProjectflockService interface {
GetAll(ctx *fiber.Ctx, params *validation.Query) ([]entity.ProjectFlock, int64, error)
GetOne(ctx *fiber.Ctx, id uint) (*entity.ProjectFlock, error)
GetAll(ctx *fiber.Ctx, params *validation.Query) ([]entity.ProjectFlock, int64, map[uint]*flockDTO.FlockBaseDTO, error)
GetOne(ctx *fiber.Ctx, id uint) (*entity.ProjectFlock, *flockDTO.FlockBaseDTO, error)
CreateOne(ctx *fiber.Ctx, req *validation.Create) (*entity.ProjectFlock, error)
UpdateOne(ctx *fiber.Ctx, req *validation.Update, id uint) (*entity.ProjectFlock, error)
GetAvailableDocQuantity(ctx *fiber.Ctx, kandangID uint) (float64, error)
@@ -92,9 +93,9 @@ func (s projectflockService) withRelations(db *gorm.DB) *gorm.DB {
Preload("KandangHistory.Kandang")
}
func (s projectflockService) GetAll(c *fiber.Ctx, params *validation.Query) ([]entity.ProjectFlock, int64, error) {
func (s projectflockService) GetAll(c *fiber.Ctx, params *validation.Query) ([]entity.ProjectFlock, int64, map[uint]*flockDTO.FlockBaseDTO, error) {
if err := s.Validate.Struct(params); err != nil {
return nil, 0, err
return nil, 0, nil, err
}
if params.Page <= 0 {
@@ -110,7 +111,7 @@ func (s projectflockService) GetAll(c *fiber.Ctx, params *validation.Query) ([]e
if err != nil {
s.Log.Errorf("Failed to get projectflocks: %+v", err)
return nil, 0, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch project flocks")
return nil, 0, nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch project flocks")
}
if s.ApprovalSvc != nil && len(projectflocks) > 0 {
@@ -133,10 +134,28 @@ func (s projectflockService) GetAll(c *fiber.Ctx, params *validation.Query) ([]e
}
}
return projectflocks, total, nil
flockMap := make(map[uint]*flockDTO.FlockBaseDTO)
for i := range projectflocks {
if projectflocks[i].FlockName != "" {
baseName := pfutils.DeriveBaseName(projectflocks[i].FlockName)
if baseName != "" {
flock, err := s.FlockRepo.GetByName(c.Context(), baseName)
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
s.Log.Warnf("Failed to fetch flock %q: %+v", baseName, err)
} else if flock != nil {
flockMap[projectflocks[i].Id] = &flockDTO.FlockBaseDTO{
Id: flock.Id,
Name: flock.Name,
}
}
}
}
}
return projectflocks, total, flockMap, nil
}
func (s projectflockService) GetOne(c *fiber.Ctx, id uint) (*entity.ProjectFlock, error) {
func (s projectflockService) getOneEntityOnly(c *fiber.Ctx, id uint) (*entity.ProjectFlock, error) {
projectflock, err := s.Repository.GetByID(c.Context(), id, s.Repository.WithDefaultRelations())
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, fiber.NewError(fiber.StatusNotFound, "Projectflock not found")
@@ -165,6 +184,52 @@ func (s projectflockService) GetOne(c *fiber.Ctx, id uint) (*entity.ProjectFlock
return projectflock, nil
}
func (s projectflockService) GetOne(c *fiber.Ctx, id uint) (*entity.ProjectFlock, *flockDTO.FlockBaseDTO, error) {
projectflock, err := s.Repository.GetByID(c.Context(), id, s.Repository.WithDefaultRelations())
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil, fiber.NewError(fiber.StatusNotFound, "Projectflock not found")
}
if err != nil {
s.Log.Errorf("Failed get projectflock by id: %+v", err)
return nil, nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch project flock")
}
if s.ApprovalSvc != nil {
approvals, err := s.ApprovalSvc.ListByTarget(c.Context(), s.approvalWorkflow, id, func(db *gorm.DB) *gorm.DB {
return db.Preload("ActionUser")
})
if err != nil {
s.Log.Warnf("Unable to load approvals for projectflock %d: %+v", id, err)
} else if len(approvals) > 0 {
if projectflock.LatestApproval == nil {
latest := approvals[len(approvals)-1]
projectflock.LatestApproval = &latest
}
} else {
projectflock.LatestApproval = nil
}
}
// Fetch Flock master data for this ProjectFlock
var flockResult *flockDTO.FlockBaseDTO
if projectflock.FlockName != "" {
baseName := pfutils.DeriveBaseName(projectflock.FlockName)
if baseName != "" {
flock, err := s.FlockRepo.GetByName(c.Context(), baseName)
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
s.Log.Warnf("Failed to fetch flock %q: %+v", baseName, err)
} else if flock != nil {
flockResult = &flockDTO.FlockBaseDTO{
Id: flock.Id,
Name: flock.Name,
}
}
}
}
return projectflock, flockResult, nil
}
func (s *projectflockService) CreateOne(c *fiber.Ctx, req *validation.Create) (*entity.ProjectFlock, error) {
if err := s.Validate.Struct(req); err != nil {
return nil, err
@@ -275,7 +340,7 @@ func (s *projectflockService) CreateOne(c *fiber.Ctx, req *validation.Create) (*
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to create project flock")
}
return s.GetOne(c, createBody.Id)
return s.getOneEntityOnly(c, createBody.Id)
}
func (s projectflockService) UpdateOne(c *fiber.Ctx, req *validation.Update, id uint) (*entity.ProjectFlock, error) {
@@ -387,7 +452,7 @@ func (s projectflockService) UpdateOne(c *fiber.Ctx, req *validation.Update, id
hasChanges := hasBodyChanges || hasKandangChanges
if !hasChanges {
return s.GetOne(c, id)
return s.getOneEntityOnly(c, id)
}
err = s.Repository.DB().WithContext(c.Context()).Transaction(func(dbTransaction *gorm.DB) error {
@@ -510,7 +575,7 @@ func (s projectflockService) UpdateOne(c *fiber.Ctx, req *validation.Update, id
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to update project flock")
}
return s.GetOne(c, id)
return s.getOneEntityOnly(c, id)
}
func (s projectflockService) Approval(c *fiber.Ctx, req *validation.Approve) ([]entity.ProjectFlock, error) {
@@ -600,7 +665,7 @@ func (s projectflockService) Approval(c *fiber.Ctx, req *validation.Approve) ([]
updated := make([]entity.ProjectFlock, 0, len(approvableIDs))
for _, approvableID := range approvableIDs {
project, err := s.GetOne(c, approvableID)
project, err := s.getOneEntityOnly(c, approvableID)
if err != nil {
return nil, err
}