mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 13:31:56 +00:00
adjust api informasi umum filter per kandang
This commit is contained in:
@@ -116,7 +116,17 @@ func (u *ClosingController) GetClosingSummary(c *fiber.Ctx) error {
|
||||
return fiber.NewError(fiber.StatusBadRequest, "Invalid projectFlockId")
|
||||
}
|
||||
|
||||
result, err := u.ClosingService.GetClosingSummary(c, uint(id))
|
||||
var kandangID *uint
|
||||
if raw := c.Query("kandang_id"); raw != "" {
|
||||
kandangInt, convErr := strconv.Atoi(raw)
|
||||
if convErr != nil || kandangInt <= 0 {
|
||||
return fiber.NewError(fiber.StatusBadRequest, "Invalid kandang_id")
|
||||
}
|
||||
kandangUint := uint(kandangInt)
|
||||
kandangID = &kandangUint
|
||||
}
|
||||
|
||||
result, err := u.ClosingService.GetClosingSummary(c, uint(id), kandangID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -59,6 +59,21 @@ type ClosingSummaryDTO struct {
|
||||
StatusClosing string `json:"closing_status"`
|
||||
}
|
||||
|
||||
type ClosingSummaryKandangDTO struct {
|
||||
FlockID uint `json:"flock_id"`
|
||||
Period int `json:"period"`
|
||||
LocationName string `json:"location_name"`
|
||||
Population int `json:"population"`
|
||||
PopulationFormatted string `json:"population_formatted"`
|
||||
ProjectType string `json:"project_type"`
|
||||
ClosingDate string `json:"closing_date"`
|
||||
KandangName string `json:"kandang_name"`
|
||||
ChickInDate string `json:"chick_in_date"`
|
||||
PicName string `json:"pic_name"`
|
||||
ApprovalDate string `json:"approval_date"`
|
||||
ProjectStatus string `json:"project_status"`
|
||||
}
|
||||
|
||||
type ClosingPurchaseDTO struct {
|
||||
InitialPopulation int `json:"initial_population"`
|
||||
ClaimCulling int `json:"claim_culling"`
|
||||
@@ -83,18 +98,18 @@ type ClosingEggSalesDTO struct {
|
||||
}
|
||||
|
||||
type ClosingPerformanceDTO struct {
|
||||
Depletion float64 `json:"depletion"`
|
||||
Age float64 `json:"age_day"`
|
||||
MortalityStd float64 `json:"mor_std"`
|
||||
MortalityAct float64 `json:"mor_act"`
|
||||
DeffMortality float64 `json:"mor_diff"`
|
||||
FcrStd float64 `json:"fcr_std"`
|
||||
FcrAct float64 `json:"fcr_act"`
|
||||
DeffFcr float64 `json:"fcr_diff"`
|
||||
AwgAct float64 `json:"awg_act"`
|
||||
AwgStd float64 `json:"awg_std"`
|
||||
FeedIntake float64 `json:"feed_intake"`
|
||||
FeedIntakeStd float64 `json:"feed_intake_std"`
|
||||
Depletion float64 `json:"depletion"`
|
||||
Age float64 `json:"age_day"`
|
||||
MortalityStd float64 `json:"mor_std"`
|
||||
MortalityAct float64 `json:"mor_act"`
|
||||
DeffMortality float64 `json:"mor_diff"`
|
||||
FcrStd float64 `json:"fcr_std"`
|
||||
FcrAct float64 `json:"fcr_act"`
|
||||
DeffFcr float64 `json:"fcr_diff"`
|
||||
AwgAct float64 `json:"awg_act"`
|
||||
AwgStd float64 `json:"awg_std"`
|
||||
FeedIntake float64 `json:"feed_intake"`
|
||||
FeedIntakeStd float64 `json:"feed_intake_std"`
|
||||
HenDayAct *float64 `json:"hen_day_act,omitempty"`
|
||||
HendayStd *float64 `json:"hen_day_std,omitempty"`
|
||||
EggMass *float64 `json:"egg_mass,omitempty"`
|
||||
@@ -175,7 +190,7 @@ func sumPopulation(history []entity.ProjectFlockKandang) float64 {
|
||||
var total float64
|
||||
for _, h := range history {
|
||||
for _, chickin := range h.Chickins {
|
||||
total += chickin.UsageQty + chickin.PendingUsageQty
|
||||
total += chickin.UsageQty
|
||||
}
|
||||
}
|
||||
return total
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -35,7 +36,7 @@ type ClosingService interface {
|
||||
GetAll(ctx *fiber.Ctx, params *validation.Query) ([]dto.ClosingListItemDTO, int64, error)
|
||||
GetProjectFlockByID(ctx *fiber.Ctx, id uint) (*entity.ProjectFlock, error)
|
||||
GetPenjualan(ctx *fiber.Ctx, projectFlockID uint, projectFlockKandangID *uint) ([]entity.MarketingDeliveryProduct, error)
|
||||
GetClosingSummary(ctx *fiber.Ctx, projectFlockID uint) (*dto.ClosingSummaryDTO, error)
|
||||
GetClosingSummary(ctx *fiber.Ctx, projectFlockID uint, kandangID *uint) (any, error)
|
||||
GetClosingDataProduksi(ctx *fiber.Ctx, projectFlockID uint, kandangID *uint) (*dto.ClosingProductionReportDTO, error)
|
||||
GetOverhead(ctx *fiber.Ctx, projectFlockID uint, projectFlockKandangID *uint) (*dto.OverheadListDTO, error)
|
||||
GetClosingSapronak(ctx *fiber.Ctx, projectFlockID uint, params *validation.ClosingSapronakQuery) ([]dto.ClosingSapronakItemDTO, int64, error)
|
||||
@@ -150,11 +151,15 @@ func (s closingService) GetPenjualan(c *fiber.Ctx, projectFlockID uint, projectF
|
||||
return realisasi, nil
|
||||
}
|
||||
|
||||
func (s closingService) GetClosingSummary(c *fiber.Ctx, projectFlockID uint) (*dto.ClosingSummaryDTO, error) {
|
||||
func (s closingService) GetClosingSummary(c *fiber.Ctx, projectFlockID uint, kandangID *uint) (any, error) {
|
||||
if projectFlockID == 0 {
|
||||
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid project flock id")
|
||||
}
|
||||
|
||||
if kandangID != nil {
|
||||
return s.getClosingSummaryByKandang(c.Context(), projectFlockID, *kandangID)
|
||||
}
|
||||
|
||||
project, err := s.Repository.GetByID(c.Context(), projectFlockID, s.withClosingRelations)
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, fiber.NewError(fiber.StatusNotFound, "Project flock not found")
|
||||
@@ -175,6 +180,124 @@ func (s closingService) GetClosingSummary(c *fiber.Ctx, projectFlockID uint) (*d
|
||||
return &summary, nil
|
||||
}
|
||||
|
||||
func (s closingService) getClosingSummaryByKandang(ctx context.Context, projectFlockID uint, kandangID uint) (*dto.ClosingSummaryKandangDTO, error) {
|
||||
if projectFlockID == 0 || kandangID == 0 {
|
||||
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid project flock id or kandang id")
|
||||
}
|
||||
|
||||
db := s.Repository.DB().WithContext(ctx)
|
||||
|
||||
var kandang entity.ProjectFlockKandang
|
||||
if err := db.
|
||||
Preload("Kandang").
|
||||
Preload("Kandang.Location").
|
||||
Preload("Kandang.Pic").
|
||||
Where("project_flock_id = ?", projectFlockID).
|
||||
Where("kandang_id = ?", kandangID).
|
||||
First(&kandang).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, fiber.NewError(fiber.StatusNotFound, "Project flock kandang not found")
|
||||
}
|
||||
s.Log.Errorf("Failed get project flock kandang %d/%d: %+v", projectFlockID, kandangID, err)
|
||||
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch project flock kandang")
|
||||
}
|
||||
|
||||
var project entity.ProjectFlock
|
||||
if err := db.
|
||||
Select("id", "category").
|
||||
First(&project, projectFlockID).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, fiber.NewError(fiber.StatusNotFound, "Project flock not found")
|
||||
}
|
||||
s.Log.Errorf("Failed get project flock %d: %+v", projectFlockID, err)
|
||||
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch project flock")
|
||||
}
|
||||
|
||||
var population float64
|
||||
if err := db.
|
||||
Table("project_flock_populations pfp").
|
||||
Joins("JOIN project_chickins pc ON pc.id = pfp.project_chickin_id").
|
||||
Where("pc.project_flock_kandang_id = ?", kandang.Id).
|
||||
Select("COALESCE(SUM(pfp.total_qty), 0)").
|
||||
Scan(&population).Error; err != nil {
|
||||
s.Log.Errorf("Failed to sum population for project flock kandang %d: %+v", kandang.Id, err)
|
||||
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch population data")
|
||||
}
|
||||
|
||||
var chickInDate time.Time
|
||||
if err := db.
|
||||
Table("project_chickins").
|
||||
Where("project_flock_kandang_id = ?", kandang.Id).
|
||||
Select("MIN(chick_in_date)").
|
||||
Scan(&chickInDate).Error; err != nil {
|
||||
s.Log.Errorf("Failed to fetch chick in date for project flock kandang %d: %+v", kandang.Id, err)
|
||||
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch chick in date")
|
||||
}
|
||||
|
||||
statusProject := "Belum Selesai"
|
||||
var approvalDate string
|
||||
if s.ApprovalSvc != nil {
|
||||
records, _, err := s.ApprovalSvc.List(ctx, utils.ApprovalWorkflowProjectFlockKandang.String(), &kandang.Id, 1, 1000, "")
|
||||
if err != nil {
|
||||
s.Log.Errorf("Failed to fetch approvals for project flock kandang %d: %+v", kandang.Id, err)
|
||||
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch approval data")
|
||||
}
|
||||
|
||||
var (
|
||||
minStep uint16
|
||||
latestActionAt time.Time
|
||||
)
|
||||
|
||||
for _, rec := range records {
|
||||
if minStep == 0 || rec.StepNumber < minStep {
|
||||
minStep = rec.StepNumber
|
||||
}
|
||||
|
||||
if latestActionAt.IsZero() || rec.ActionAt.After(latestActionAt) {
|
||||
latestActionAt = rec.ActionAt
|
||||
statusProject = rec.StepName
|
||||
}
|
||||
}
|
||||
|
||||
if statusProject == "" && minStep > 0 {
|
||||
if label, ok := approvalutils.ApprovalStepName(utils.ApprovalWorkflowProjectFlockKandang, approvalutils.ApprovalStep(minStep)); ok {
|
||||
statusProject = label
|
||||
}
|
||||
}
|
||||
|
||||
if !latestActionAt.IsZero() {
|
||||
approvalDate = latestActionAt.Format("2006-01-02")
|
||||
}
|
||||
}
|
||||
|
||||
closingDate := ""
|
||||
if kandang.ClosedAt != nil {
|
||||
closingDate = kandang.ClosedAt.Format("2006-01-02")
|
||||
}
|
||||
|
||||
chickInDateStr := ""
|
||||
if !chickInDate.IsZero() {
|
||||
chickInDateStr = chickInDate.Format("2006-01-02")
|
||||
}
|
||||
|
||||
populationInt := int(population)
|
||||
|
||||
return &dto.ClosingSummaryKandangDTO{
|
||||
FlockID: projectFlockID,
|
||||
Period: kandang.Period,
|
||||
LocationName: kandang.Kandang.Location.Name,
|
||||
Population: populationInt,
|
||||
PopulationFormatted: fmt.Sprintf("%d Ekor", populationInt),
|
||||
ProjectType: project.Category,
|
||||
ClosingDate: closingDate,
|
||||
KandangName: kandang.Kandang.Name,
|
||||
ChickInDate: chickInDateStr,
|
||||
PicName: kandang.Kandang.Pic.Name,
|
||||
ApprovalDate: approvalDate,
|
||||
ProjectStatus: statusProject,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s closingService) GetClosingSapronak(c *fiber.Ctx, projectFlockID uint, params *validation.ClosingSapronakQuery) ([]dto.ClosingSapronakItemDTO, int64, error) {
|
||||
if projectFlockID == 0 {
|
||||
return nil, 0, fiber.NewError(fiber.StatusBadRequest, "Invalid project flock id")
|
||||
|
||||
Reference in New Issue
Block a user