mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-22 14:25:45 +00:00
feat(BE-74-76-78-278):adjustment project flock,recording,purchase getall
This commit is contained in:
@@ -23,6 +23,7 @@ import (
|
||||
validation "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/validations"
|
||||
recordingRepo "gitlab.com/mbugroup/lti-api.git/internal/modules/production/recordings/repositories"
|
||||
uniformityRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/production/uniformities/repositories"
|
||||
purchaseRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/purchases/repositories"
|
||||
utils "gitlab.com/mbugroup/lti-api.git/internal/utils"
|
||||
approvalutils "gitlab.com/mbugroup/lti-api.git/internal/utils/approvals"
|
||||
|
||||
@@ -308,12 +309,12 @@ func (s *projectflockService) CreateOne(c *fiber.Ctx, req *validation.Create) (*
|
||||
}
|
||||
|
||||
createBody := &entity.ProjectFlock{
|
||||
AreaId: req.AreaId,
|
||||
Category: cat,
|
||||
FcrId: req.FcrId,
|
||||
AreaId: req.AreaId,
|
||||
Category: cat,
|
||||
FcrId: req.FcrId,
|
||||
ProductionStandardId: req.ProductionStandardId,
|
||||
LocationId: req.LocationId,
|
||||
CreatedBy: actorID,
|
||||
LocationId: req.LocationId,
|
||||
CreatedBy: actorID,
|
||||
}
|
||||
|
||||
err = s.Repository.DB().WithContext(c.Context()).Transaction(func(dbTransaction *gorm.DB) error {
|
||||
@@ -823,22 +824,7 @@ func (s projectflockService) detachKandangs(ctx context.Context, dbTransaction *
|
||||
return nil
|
||||
}
|
||||
|
||||
blocked, err := s.pivotRepoWithTx(dbTransaction).FindKandangsWithRecordings(ctx, projectFlockID, kandangIDs)
|
||||
if err != nil {
|
||||
s.Log.Errorf("Failed to check recordings before detaching kandangs: %+v", err)
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "Failed to validate kandang detachment")
|
||||
}
|
||||
if len(blocked) > 0 {
|
||||
names := make([]string, 0, len(blocked))
|
||||
for _, item := range blocked {
|
||||
label := fmt.Sprintf("ID %d", item.Id)
|
||||
if strings.TrimSpace(item.Name) != "" {
|
||||
label = fmt.Sprintf("%s (%s)", label, item.Name)
|
||||
}
|
||||
names = append(names, label)
|
||||
}
|
||||
return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("Tidak dapat melepas kandang karena sudah memiliki recording: %s", strings.Join(names, ", ")))
|
||||
}
|
||||
// NOTE: Recording constraints are enforced via FK cascade; allow detachment even if recordings exist.
|
||||
|
||||
pfkIDs, err := s.pivotRepoWithTx(dbTransaction).ListIDsByProjectAndKandang(ctx, projectFlockID, kandangIDs)
|
||||
if err != nil {
|
||||
@@ -854,6 +840,14 @@ func (s projectflockService) detachKandangs(ctx context.Context, dbTransaction *
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "Failed to remove uniformity data for project flock kandang")
|
||||
}
|
||||
|
||||
db := s.Repository.DB()
|
||||
if dbTransaction != nil {
|
||||
db = dbTransaction
|
||||
}
|
||||
purchaseRepo := purchaseRepository.NewPurchaseRepository(db)
|
||||
if err := purchaseRepo.SoftDeleteByProjectFlockKandangIDs(ctx, pfkIDs); err != nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "Failed to soft delete purchases for project flock kandang")
|
||||
}
|
||||
pwRepo := s.ProductWarehouseRepo
|
||||
if dbTransaction != nil {
|
||||
pwRepo = productWarehouseRepository.NewProductWarehouseRepository(dbTransaction)
|
||||
@@ -906,6 +900,11 @@ func (s projectflockService) ensureProjectFlockKandangProductWarehouses(ctx cont
|
||||
return nil
|
||||
}
|
||||
|
||||
projectFlockID := records[0].ProjectFlockId
|
||||
if projectFlockID == 0 {
|
||||
return fiber.NewError(fiber.StatusBadRequest, "Project flock id tidak ditemukan")
|
||||
}
|
||||
|
||||
pwRepo := s.ProductWarehouseRepo
|
||||
if dbTransaction != nil {
|
||||
pwRepo = productWarehouseRepository.NewProductWarehouseRepository(dbTransaction)
|
||||
@@ -920,24 +919,34 @@ func (s projectflockService) ensureProjectFlockKandangProductWarehouses(ctx cont
|
||||
warehouseRepo = warehouseRepository.NewWarehouseRepository(s.Repository.DB())
|
||||
}
|
||||
|
||||
flags := []utils.FlagType{
|
||||
utils.FlagAyamAfkir,
|
||||
utils.FlagAyamCulling,
|
||||
utils.FlagAyamMati,
|
||||
utils.FlagTelurPecah,
|
||||
utils.FlagTelurUtuh,
|
||||
db := s.Repository.DB()
|
||||
if dbTransaction != nil {
|
||||
db = dbTransaction
|
||||
}
|
||||
var category string
|
||||
if err := db.WithContext(ctx).
|
||||
Model(&entity.ProjectFlock{}).
|
||||
Select("category").
|
||||
Where("id = ?", projectFlockID).
|
||||
Scan(&category).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if strings.TrimSpace(category) == "" {
|
||||
return fiber.NewError(fiber.StatusBadRequest, "Project flock category tidak ditemukan")
|
||||
}
|
||||
|
||||
productIDs := make(map[utils.FlagType]uint, len(flags))
|
||||
for _, flag := range flags {
|
||||
product, err := pwRepo.GetFirstProductByFlag(ctx, string(flag))
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("Product untuk flag %s tidak ditemukan", flag))
|
||||
}
|
||||
return err
|
||||
}
|
||||
productIDs[flag] = product.Id
|
||||
prefixes := []string{"AYAM-"}
|
||||
if strings.EqualFold(category, string(utils.ProjectFlockCategoryLaying)) {
|
||||
prefixes = append(prefixes, "TELUR")
|
||||
}
|
||||
|
||||
invisibleOnly := false
|
||||
productIDs, err := pwRepo.ListProductIDsByFlagPrefixes(ctx, prefixes, &invisibleOnly)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(productIDs) == 0 {
|
||||
return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("Product dengan flag %s tidak ditemukan", strings.Join(prefixes, ", ")))
|
||||
}
|
||||
|
||||
for _, record := range records {
|
||||
@@ -953,8 +962,7 @@ func (s projectflockService) ensureProjectFlockKandangProductWarehouses(ctx cont
|
||||
return err
|
||||
}
|
||||
|
||||
for _, flag := range flags {
|
||||
productID := productIDs[flag]
|
||||
for _, productID := range productIDs {
|
||||
if _, err := pwRepo.GetByProductWarehouseAndProjectFlockKandang(ctx, productID, warehouse.Id, record.Id); err == nil {
|
||||
continue
|
||||
} else if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
|
||||
@@ -25,16 +25,16 @@ type RecordingRelationDTO struct {
|
||||
CumIntake int `json:"cum_intake"`
|
||||
FcrValue float64 `json:"fcr_value"`
|
||||
TotalChickQty float64 `json:"total_chick_qty"`
|
||||
HandDay float64 `json:"hand_day"`
|
||||
HandHouse float64 `json:"hand_house"`
|
||||
HenDay float64 `json:"hen_day"`
|
||||
HenHouse float64 `json:"hen_house"`
|
||||
FeedIntake float64 `json:"feed_intake"`
|
||||
EggMesh float64 `json:"egg_mesh"`
|
||||
EggMass float64 `json:"egg_mass"`
|
||||
EggWeight float64 `json:"egg_weight"`
|
||||
StandardHandDay *float64 `json:"hand_day_std,omitempty"`
|
||||
StandardHandHouse *float64 `json:"hand_house_std,omitempty"`
|
||||
StandardHenDay *float64 `json:"hen_day_std,omitempty"`
|
||||
StandardHenHouse *float64 `json:"hen_house_std,omitempty"`
|
||||
StandardFeedIntake *float64 `json:"feed_intake_std,omitempty"`
|
||||
StandardMaxDepletion *float64 `json:"max_depletion_std,omitempty"`
|
||||
StandardEggMesh *float64 `json:"egg_mesh_std,omitempty"`
|
||||
StandardEggMass *float64 `json:"egg_mass_std,omitempty"`
|
||||
StandardEggWeight *float64 `json:"egg_weight_std,omitempty"`
|
||||
StandardFcr *float64 `json:"fcr_std,omitempty"`
|
||||
Approval approvalDTO.ApprovalRelationDTO `json:"approval"`
|
||||
@@ -94,10 +94,10 @@ func ToRecordingRelationDTO(e entity.Recording) RecordingRelationDTO {
|
||||
cumIntake int
|
||||
fcrValue float64
|
||||
totalChickQty float64
|
||||
handDay float64
|
||||
handHouse float64
|
||||
henDay float64
|
||||
henHouse float64
|
||||
feedIntake float64
|
||||
eggMesh float64
|
||||
eggMass float64
|
||||
eggWeight float64
|
||||
)
|
||||
|
||||
@@ -119,17 +119,17 @@ func ToRecordingRelationDTO(e entity.Recording) RecordingRelationDTO {
|
||||
if e.TotalChickQty != nil {
|
||||
totalChickQty = *e.TotalChickQty
|
||||
}
|
||||
if e.HandDay != nil {
|
||||
handDay = *e.HandDay
|
||||
if e.HenDay != nil {
|
||||
henDay = *e.HenDay
|
||||
}
|
||||
if e.HandHouse != nil {
|
||||
handHouse = *e.HandHouse
|
||||
if e.HenHouse != nil {
|
||||
henHouse = *e.HenHouse
|
||||
}
|
||||
if e.FeedIntake != nil {
|
||||
feedIntake = *e.FeedIntake
|
||||
}
|
||||
if e.EggMesh != nil {
|
||||
eggMesh = *e.EggMesh
|
||||
if e.EggMass != nil {
|
||||
eggMass = *e.EggMass
|
||||
}
|
||||
if e.EggWeight != nil {
|
||||
eggWeight = *e.EggWeight
|
||||
@@ -157,16 +157,16 @@ func ToRecordingRelationDTO(e entity.Recording) RecordingRelationDTO {
|
||||
CumIntake: cumIntake,
|
||||
FcrValue: fcrValue,
|
||||
TotalChickQty: totalChickQty,
|
||||
HandDay: handDay,
|
||||
HandHouse: handHouse,
|
||||
HenDay: henDay,
|
||||
HenHouse: henHouse,
|
||||
FeedIntake: feedIntake,
|
||||
EggMesh: eggMesh,
|
||||
EggMass: eggMass,
|
||||
EggWeight: eggWeight,
|
||||
StandardHandDay: e.StandardHandDay,
|
||||
StandardHandHouse: e.StandardHandHouse,
|
||||
StandardHenDay: e.StandardHenDay,
|
||||
StandardHenHouse: e.StandardHenHouse,
|
||||
StandardFeedIntake: e.StandardFeedIntake,
|
||||
StandardMaxDepletion: e.StandardMaxDepletion,
|
||||
StandardEggMesh: e.StandardEggMesh,
|
||||
StandardEggMass: e.StandardEggMass,
|
||||
StandardEggWeight: e.StandardEggWeight,
|
||||
StandardFcr: e.StandardFcr,
|
||||
Approval: latestApproval,
|
||||
|
||||
@@ -16,10 +16,10 @@ func RecordingRoutes(v1 fiber.Router, u user.UserService, s recording.RecordingS
|
||||
route.Use(m.Auth(u))
|
||||
|
||||
route.Get("/",m.RequirePermissions(m.P_RecordingGetAll), ctrl.GetAll)
|
||||
route.Get("/next-day",m.RequirePermissions(m.P_RecordingNextDay), ctrl.GetNextDay)
|
||||
route.Get("/:id",m.RequirePermissions(m.P_RecordingGetOne), ctrl.GetOne)
|
||||
route.Post("/",m.RequirePermissions(m.P_RecordingCreateOne), ctrl.CreateOne)
|
||||
route.Patch("/:id",m.RequirePermissions(m.P_RecordingUpdateOne), ctrl.UpdateOne)
|
||||
route.Delete("/:id",m.RequirePermissions(m.P_RecordingDeleteOne), ctrl.DeleteOne)
|
||||
route.Get("/next-day",m.RequirePermissions(m.P_RecordingNextDay), ctrl.GetNextDay)
|
||||
route.Post("/approvals",m.RequirePermissions(m.P_RecordingApproval), ctrl.Approve)
|
||||
}
|
||||
|
||||
@@ -1156,34 +1156,34 @@ func (s *recordingService) computeAndUpdateMetrics(ctx context.Context, tx *gorm
|
||||
recording.FeedIntake = nil
|
||||
}
|
||||
|
||||
var handDay float64
|
||||
var henDay float64
|
||||
if remainingChick > 0 && totalEggQty >= 0 {
|
||||
handDay = (totalEggQty / remainingChick) * 100
|
||||
updates["hand_day"] = handDay
|
||||
recording.HandDay = &handDay
|
||||
henDay = (totalEggQty / remainingChick) * 100
|
||||
updates["hen_day"] = henDay
|
||||
recording.HenDay = &henDay
|
||||
} else {
|
||||
updates["hand_day"] = gorm.Expr("NULL")
|
||||
recording.HandDay = nil
|
||||
updates["hen_day"] = gorm.Expr("NULL")
|
||||
recording.HenDay = nil
|
||||
}
|
||||
|
||||
var handHouse float64
|
||||
var henHouse float64
|
||||
if initialChickin > 0 && cumulativeEggQty >= 0 {
|
||||
handHouse = cumulativeEggQty / initialChickin
|
||||
updates["hand_house"] = handHouse
|
||||
recording.HandHouse = &handHouse
|
||||
henHouse = cumulativeEggQty / initialChickin
|
||||
updates["hen_house"] = henHouse
|
||||
recording.HenHouse = &henHouse
|
||||
} else {
|
||||
updates["hand_house"] = gorm.Expr("NULL")
|
||||
recording.HandHouse = nil
|
||||
updates["hen_house"] = gorm.Expr("NULL")
|
||||
recording.HenHouse = nil
|
||||
}
|
||||
|
||||
var eggMesh float64
|
||||
var eggMass float64
|
||||
if remainingChick > 0 && totalEggWeightGrams > 0 {
|
||||
eggMesh = (totalEggWeightGrams / remainingChick) * 1000
|
||||
updates["egg_mesh"] = eggMesh
|
||||
recording.EggMesh = &eggMesh
|
||||
eggMass = (totalEggWeightGrams / remainingChick) * 1000
|
||||
updates["egg_mass"] = eggMass
|
||||
recording.EggMass = &eggMass
|
||||
} else {
|
||||
updates["egg_mesh"] = gorm.Expr("NULL")
|
||||
recording.EggMesh = nil
|
||||
updates["egg_mass"] = gorm.Expr("NULL")
|
||||
recording.EggMass = nil
|
||||
}
|
||||
|
||||
var eggWeight float64
|
||||
@@ -1334,11 +1334,11 @@ func (s *recordingService) attachLatestApproval(ctx context.Context, item *entit
|
||||
}
|
||||
|
||||
type productionStandardValues struct {
|
||||
HandDay *float64
|
||||
HandHouse *float64
|
||||
HenDay *float64
|
||||
HenHouse *float64
|
||||
FeedIntake *float64
|
||||
MaxDepletion *float64
|
||||
EggMesh *float64
|
||||
EggMass *float64
|
||||
EggWeight *float64
|
||||
}
|
||||
|
||||
@@ -1389,10 +1389,10 @@ func (s *recordingService) attachProductionStandard(ctx context.Context, item *e
|
||||
return err
|
||||
}
|
||||
if detail != nil {
|
||||
standard.HandDay = detail.TargetHenDayProduction
|
||||
standard.HandHouse = detail.TargetHenHouseProduction
|
||||
standard.HenDay = detail.TargetHenDayProduction
|
||||
standard.HenHouse = detail.TargetHenHouseProduction
|
||||
standard.EggWeight = detail.TargetEggWeight
|
||||
standard.EggMesh = detail.TargetEggMass
|
||||
standard.EggMass = detail.TargetEggMass
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1420,11 +1420,11 @@ func (s *recordingService) attachProductionStandard(ctx context.Context, item *e
|
||||
}
|
||||
}
|
||||
|
||||
item.StandardHandDay = standard.HandDay
|
||||
item.StandardHandHouse = standard.HandHouse
|
||||
item.StandardHenDay = standard.HenDay
|
||||
item.StandardHenHouse = standard.HenHouse
|
||||
item.StandardFeedIntake = standard.FeedIntake
|
||||
item.StandardMaxDepletion = standard.MaxDepletion
|
||||
item.StandardEggMesh = standard.EggMesh
|
||||
item.StandardEggMass = standard.EggMass
|
||||
item.StandardEggWeight = standard.EggWeight
|
||||
item.StandardFcr = standardFcr
|
||||
|
||||
|
||||
Reference in New Issue
Block a user