mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 13:31:56 +00:00
FIX[BE]: period and adjustment helper to function
This commit is contained in:
@@ -101,7 +101,11 @@ func (s *kandangService) CreateOne(c *fiber.Ctx, req *validation.Create) (*entit
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
status := strings.ToUpper(req.Status)
|
||||
|
||||
status := strings.ToUpper(strings.TrimSpace(req.Status))
|
||||
if status == "" {
|
||||
status = string(utils.KandangStatusNonActive)
|
||||
}
|
||||
if !utils.IsValidKandangStatus(status) {
|
||||
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid kandang status")
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package validation
|
||||
|
||||
type Create struct {
|
||||
Name string `json:"name" validate:"required_strict,min=3"`
|
||||
Status string `json:"status" validate:"required_strict,min=3"`
|
||||
Status string `json:"status,omitempty" validate:"omitempty,min=3"`
|
||||
LocationId uint `json:"location_id" validate:"required_strict,number,gt=0"`
|
||||
PicId uint `json:"pic_id" validate:"required_strict,number,gt=0"`
|
||||
ProjectFlockId *uint `json:"project_flock_id" validate:"omitempty,number,gt=0"`
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"gitlab.com/mbugroup/lti-api.git/internal/common/repository"
|
||||
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
|
||||
type ProjectflockRepository interface {
|
||||
@@ -14,6 +15,7 @@ type ProjectflockRepository interface {
|
||||
GetAllByFlock(ctx context.Context, flockID uint) ([]entity.ProjectFlock, error)
|
||||
GetActiveByFlock(ctx context.Context, flockID uint) (*entity.ProjectFlock, error)
|
||||
GetMaxPeriodByFlock(ctx context.Context, flockID uint) (int, error)
|
||||
GetNextPeriodForFlock(ctx context.Context, flockID uint) (int, error)
|
||||
}
|
||||
|
||||
type ProjectflockRepositoryImpl struct {
|
||||
@@ -64,3 +66,23 @@ func (r *ProjectflockRepositoryImpl) GetMaxPeriodByFlock(ctx context.Context, fl
|
||||
}
|
||||
return max, nil
|
||||
}
|
||||
|
||||
func (r *ProjectflockRepositoryImpl) GetNextPeriodForFlock(ctx context.Context, flockID uint) (int, error) {
|
||||
var payload struct {
|
||||
Period int
|
||||
}
|
||||
if err := r.DB().WithContext(ctx).
|
||||
Model(&entity.ProjectFlock{}).
|
||||
Where("flock_id = ?", flockID).
|
||||
Clauses(clause.Locking{Strength: "UPDATE"}).
|
||||
Order("period DESC").
|
||||
Limit(1).
|
||||
Select("period").
|
||||
Scan(&payload).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return 1, nil
|
||||
}
|
||||
return 0, err
|
||||
}
|
||||
return payload.Period + 1, nil
|
||||
}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
commonRepo "gitlab.com/mbugroup/lti-api.git/internal/common/repository"
|
||||
common "gitlab.com/mbugroup/lti-api.git/internal/common/service"
|
||||
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
||||
flockRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/master/flocks/repositories"
|
||||
kandangRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandangs/repositories"
|
||||
@@ -15,7 +18,6 @@ import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/sirupsen/logrus"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
|
||||
type ProjectflockService interface {
|
||||
@@ -106,6 +108,16 @@ func (s *projectflockService) CreateOne(c *fiber.Ctx, req *validation.Create) (*
|
||||
return nil, fiber.NewError(fiber.StatusBadRequest, "kandang_ids is required")
|
||||
}
|
||||
|
||||
if err := common.EnsureRelations(c.Context(),
|
||||
common.RelationCheck{Name: "Flock", ID: &req.FlockId, Exists: relationExistsChecker[entity.Flock](s.Repository.DB())},
|
||||
common.RelationCheck{Name: "Area", ID: &req.AreaId, Exists: relationExistsChecker[entity.Area](s.Repository.DB())},
|
||||
common.RelationCheck{Name: "Product category", ID: &req.ProductCategoryId, Exists: relationExistsChecker[entity.ProductCategory](s.Repository.DB())},
|
||||
common.RelationCheck{Name: "FCR", ID: &req.FcrId, Exists: relationExistsChecker[entity.Fcr](s.Repository.DB())},
|
||||
common.RelationCheck{Name: "Location", ID: &req.LocationId, Exists: relationExistsChecker[entity.Location](s.Repository.DB())},
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
kandangIDs := uniqueUintSlice(req.KandangIds)
|
||||
kandangs, err := s.KandangRepo.GetByIDs(c.Context(), kandangIDs, nil)
|
||||
if err != nil {
|
||||
@@ -128,18 +140,14 @@ func (s *projectflockService) CreateOne(c *fiber.Ctx, req *validation.Create) (*
|
||||
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to start transaction")
|
||||
}
|
||||
|
||||
var nextPeriod int
|
||||
periodQuery := tx.Model(&entity.ProjectFlock{}).
|
||||
Where("flock_id = ?", req.FlockId).
|
||||
Clauses(clause.Locking{Strength: "UPDATE"})
|
||||
if err := periodQuery.Select("COALESCE(MAX(period), 0)").Scan(&nextPeriod).Error; err != nil {
|
||||
projectRepo := repository.NewProjectflockRepository(tx)
|
||||
nextPeriod, err := projectRepo.GetNextPeriodForFlock(c.Context(), req.FlockId)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
s.Log.Errorf("Failed to determine next period for flock %d: %+v", req.FlockId, err)
|
||||
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to determine next period")
|
||||
}
|
||||
nextPeriod++
|
||||
|
||||
projectRepo := s.Repository.WithTx(tx)
|
||||
createBody := &entity.ProjectFlock{
|
||||
FlockId: req.FlockId,
|
||||
AreaId: req.AreaId,
|
||||
@@ -190,26 +198,58 @@ func (s projectflockService) UpdateOne(c *fiber.Ctx, req *validation.Update, id
|
||||
}
|
||||
|
||||
updateBody := make(map[string]any)
|
||||
var relationChecks []common.RelationCheck
|
||||
|
||||
if req.FlockId != nil {
|
||||
updateBody["flock_id"] = *req.FlockId
|
||||
relationChecks = append(relationChecks, common.RelationCheck{
|
||||
Name: "Flock",
|
||||
ID: req.FlockId,
|
||||
Exists: relationExistsChecker[entity.Flock](s.Repository.DB()),
|
||||
})
|
||||
}
|
||||
if req.AreaId != nil {
|
||||
updateBody["area_id"] = *req.AreaId
|
||||
relationChecks = append(relationChecks, common.RelationCheck{
|
||||
Name: "Area",
|
||||
ID: req.AreaId,
|
||||
Exists: relationExistsChecker[entity.Area](s.Repository.DB()),
|
||||
})
|
||||
}
|
||||
if req.ProductCategoryId != nil {
|
||||
updateBody["product_category_id"] = *req.ProductCategoryId
|
||||
relationChecks = append(relationChecks, common.RelationCheck{
|
||||
Name: "Product category",
|
||||
ID: req.ProductCategoryId,
|
||||
Exists: relationExistsChecker[entity.ProductCategory](s.Repository.DB()),
|
||||
})
|
||||
}
|
||||
if req.FcrId != nil {
|
||||
updateBody["fcr_id"] = *req.FcrId
|
||||
relationChecks = append(relationChecks, common.RelationCheck{
|
||||
Name: "FCR",
|
||||
ID: req.FcrId,
|
||||
Exists: relationExistsChecker[entity.Fcr](s.Repository.DB()),
|
||||
})
|
||||
}
|
||||
if req.LocationId != nil {
|
||||
updateBody["location_id"] = *req.LocationId
|
||||
relationChecks = append(relationChecks, common.RelationCheck{
|
||||
Name: "Location",
|
||||
ID: req.LocationId,
|
||||
Exists: relationExistsChecker[entity.Location](s.Repository.DB()),
|
||||
})
|
||||
}
|
||||
if req.Period != nil {
|
||||
updateBody["period"] = *req.Period
|
||||
}
|
||||
|
||||
if len(relationChecks) > 0 {
|
||||
if err := common.EnsureRelations(c.Context(), relationChecks...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
var newKandangIDs []uint
|
||||
if req.KandangIds != nil {
|
||||
if len(req.KandangIds) == 0 {
|
||||
@@ -238,7 +278,7 @@ func (s projectflockService) UpdateOne(c *fiber.Ctx, req *validation.Update, id
|
||||
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to start transaction")
|
||||
}
|
||||
|
||||
projectRepo := s.Repository.WithTx(tx)
|
||||
projectRepo := repository.NewProjectflockRepository(tx)
|
||||
if len(updateBody) > 0 {
|
||||
if err := projectRepo.PatchOne(c.Context(), id, updateBody, nil); err != nil {
|
||||
tx.Rollback()
|
||||
@@ -332,7 +372,7 @@ func (s projectflockService) DeleteOne(c *fiber.Ctx, id uint) error {
|
||||
}
|
||||
}
|
||||
|
||||
if err := s.Repository.WithTx(tx).DeleteOne(c.Context(), id); err != nil {
|
||||
if err := repository.NewProjectflockRepository(tx).DeleteOne(c.Context(), id); err != nil {
|
||||
tx.Rollback()
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return fiber.NewError(fiber.StatusNotFound, "Projectflock not found")
|
||||
@@ -385,3 +425,9 @@ func uniqueUintSlice(values []uint) []uint {
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func relationExistsChecker[T any](db *gorm.DB) func(context.Context, uint) (bool, error) {
|
||||
return func(ctx context.Context, id uint) (bool, error) {
|
||||
return commonRepo.Exists[T](ctx, db, id)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user