mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 13:31:56 +00:00
feat(BE-281):add dto standart mean bw and uniformity
This commit is contained in:
@@ -32,6 +32,10 @@ func (u *UniformityController) GetAll(c *fiber.Ctx) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
standards, err := u.UniformityService.MapStandards(c, result)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.Status(fiber.StatusOK).
|
||||
JSON(response.SuccessWithPaginate[dto.UniformityListDTO]{
|
||||
@@ -49,7 +53,7 @@ func (u *UniformityController) GetAll(c *fiber.Ctx) error {
|
||||
"status": "Pengajuan",
|
||||
},
|
||||
},
|
||||
Data: dto.ToUniformityListDTOs(result),
|
||||
Data: dto.ToUniformityListDTOsWithStandard(result, standards),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -90,12 +94,24 @@ func (u *UniformityController) GetOne(c *fiber.Ctx) error {
|
||||
}
|
||||
}
|
||||
|
||||
standard, err := u.UniformityService.GetStandard(c, result)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var standardDTO *dto.UniformityStandardDTO
|
||||
if standard != nil {
|
||||
standardDTO = &dto.UniformityStandardDTO{
|
||||
MeanWeight: standard.MeanWeight,
|
||||
Uniformity: standard.Uniformity,
|
||||
}
|
||||
}
|
||||
|
||||
return c.Status(fiber.StatusOK).
|
||||
JSON(response.Success{
|
||||
Code: fiber.StatusOK,
|
||||
Status: "success",
|
||||
Message: "Get production uniformity successfully",
|
||||
Data: dto.ToUniformityDetailDTO(*result, calculation, document),
|
||||
Data: dto.ToUniformityDetailDTO(*result, calculation, document, standardDTO),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -121,13 +137,24 @@ func (u *UniformityController) CreateOne(c *fiber.Ctx) error {
|
||||
}
|
||||
|
||||
document := dto.NewDocumentForResponse(file.Filename)
|
||||
standard, err := u.UniformityService.GetStandard(c, result)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var standardDTO *dto.UniformityStandardDTO
|
||||
if standard != nil {
|
||||
standardDTO = &dto.UniformityStandardDTO{
|
||||
MeanWeight: standard.MeanWeight,
|
||||
Uniformity: standard.Uniformity,
|
||||
}
|
||||
}
|
||||
|
||||
return c.Status(fiber.StatusCreated).
|
||||
JSON(response.Success{
|
||||
Code: fiber.StatusCreated,
|
||||
Status: "success",
|
||||
Message: "Create uniformity successfully",
|
||||
Data: dto.ToUniformityDetailDTO(*result, calculation, document),
|
||||
Data: dto.ToUniformityDetailDTO(*result, calculation, document, standardDTO),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -181,17 +208,36 @@ func (u *UniformityController) UpdateOne(c *fiber.Ctx) error {
|
||||
return err
|
||||
}
|
||||
|
||||
calculation, document, err := u.UniformityService.CalculateUniformityFromDocument(c, id)
|
||||
standard, err := u.UniformityService.GetStandard(c, result)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var standardDTO *dto.UniformityStandardDTO
|
||||
if standard != nil {
|
||||
standardDTO = &dto.UniformityStandardDTO{
|
||||
MeanWeight: standard.MeanWeight,
|
||||
Uniformity: standard.Uniformity,
|
||||
}
|
||||
}
|
||||
|
||||
calculation := service.UniformityCalculation{
|
||||
ChickQtyOfWeight: result.ChickQtyOfWeight,
|
||||
MeanWeight: math.Round(result.MeanUp / 1.10),
|
||||
MeanDown: result.MeanDown,
|
||||
MeanUp: result.MeanUp,
|
||||
UniformQty: result.UniformQty,
|
||||
OutsideQty: result.NotUniformQty,
|
||||
Uniformity: result.Uniformity,
|
||||
Cv: result.Cv,
|
||||
}
|
||||
var document *entity.Document
|
||||
|
||||
return c.Status(fiber.StatusOK).
|
||||
JSON(response.Success{
|
||||
Code: fiber.StatusOK,
|
||||
Status: "success",
|
||||
Message: "Update uniformity successfully",
|
||||
Data: dto.ToUniformityDetailDTO(*result, calculation, document),
|
||||
Data: dto.ToUniformityDetailDTO(*result, calculation, document, standardDTO),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,11 @@ type UniformityResultDTO struct {
|
||||
Cv float64 `json:"cv"`
|
||||
}
|
||||
|
||||
type UniformityStandardDTO struct {
|
||||
MeanWeight *float64 `json:"mean_weight"`
|
||||
Uniformity *float64 `json:"uniformity"`
|
||||
}
|
||||
|
||||
type UniformityDetailItemDTO struct {
|
||||
Id int `json:"id"`
|
||||
Weight float64 `json:"weight"`
|
||||
@@ -47,6 +52,7 @@ type UniformityDetailDTO struct {
|
||||
InfoUmum UniformityInfoDTO `json:"info_umum"`
|
||||
Sampling UniformitySamplingDTO `json:"sampling"`
|
||||
Result UniformityResultDTO `json:"result"`
|
||||
Standard *UniformityStandardDTO `json:"standard"`
|
||||
UniformityDetails []UniformityDetailItemDTO `json:"uniformity_details"`
|
||||
}
|
||||
|
||||
@@ -65,6 +71,8 @@ type UniformityListDTO struct {
|
||||
UniformQty float64 `json:"uniform_qty"`
|
||||
MeanUp float64 `json:"mean_up"`
|
||||
MeanDown float64 `json:"mean_down"`
|
||||
StandardMeanWeight *float64 `json:"standard_mean_weight"`
|
||||
StandardUniformity *float64 `json:"standard_uniformity"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
CreatedBy uint `json:"created_by"`
|
||||
LatestApproval *approvalDTO.ApprovalRelationDTO `json:"latest_approval"`
|
||||
@@ -89,6 +97,7 @@ func ToUniformityDetailDTO(
|
||||
entityData entity.ProjectFlockKandangUniformity,
|
||||
calc service.UniformityCalculation,
|
||||
document *entity.Document,
|
||||
standard *UniformityStandardDTO,
|
||||
) UniformityDetailDTO {
|
||||
info := UniformityInfoDTO{
|
||||
Tanggal: formatUniformityDate(entityData.UniformDate),
|
||||
@@ -106,6 +115,7 @@ func ToUniformityDetailDTO(
|
||||
InfoUmum: info,
|
||||
Sampling: toUniformitySamplingDTO(calc),
|
||||
Result: toUniformityResultDTO(calc),
|
||||
Standard: standard,
|
||||
UniformityDetails: toUniformityDetailItemsDTO(calc),
|
||||
}
|
||||
}
|
||||
@@ -146,6 +156,24 @@ func ToUniformityListDTOs(items []entity.ProjectFlockKandangUniformity) []Unifor
|
||||
return result
|
||||
}
|
||||
|
||||
func ToUniformityListDTOsWithStandard(
|
||||
items []entity.ProjectFlockKandangUniformity,
|
||||
standards map[uint]service.UniformityStandard,
|
||||
) []UniformityListDTO {
|
||||
result := ToUniformityListDTOs(items)
|
||||
if len(result) == 0 || len(standards) == 0 {
|
||||
return result
|
||||
}
|
||||
|
||||
for i := range result {
|
||||
if std, ok := standards[result[i].Id]; ok {
|
||||
result[i].StandardMeanWeight = std.MeanWeight
|
||||
result[i].StandardUniformity = std.Uniformity
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func toUniformitySamplingDTO(calc service.UniformityCalculation) UniformitySamplingDTO {
|
||||
return UniformitySamplingDTO{
|
||||
ChickQtyOfWeight: calc.ChickQtyOfWeight,
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
|
||||
commonRepo "gitlab.com/mbugroup/lti-api.git/internal/common/repository"
|
||||
commonSvc "gitlab.com/mbugroup/lti-api.git/internal/common/service"
|
||||
rProductionStandard "gitlab.com/mbugroup/lti-api.git/internal/modules/master/production-standards/repositories"
|
||||
rProjectFlock "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/repositories"
|
||||
rUniformity "gitlab.com/mbugroup/lti-api.git/internal/modules/production/uniformities/repositories"
|
||||
sUniformity "gitlab.com/mbugroup/lti-api.git/internal/modules/production/uniformities/services"
|
||||
@@ -26,6 +27,8 @@ func (UniformityModule) RegisterRoutes(router fiber.Router, db *gorm.DB, validat
|
||||
documentRepo := commonRepo.NewDocumentRepository(db)
|
||||
approvalRepo := commonRepo.NewApprovalRepository(db)
|
||||
projectFlockKandangRepo := rProjectFlock.NewProjectFlockKandangRepository(db)
|
||||
productionStandardRepo := rProductionStandard.NewProductionStandardRepository(db)
|
||||
standardGrowthDetailRepo := rProductionStandard.NewStandardGrowthDetailRepository(db)
|
||||
userRepo := rUser.NewUserRepository(db)
|
||||
|
||||
documentSvc, err := commonSvc.NewDocumentServiceFromConfig(context.Background(), documentRepo)
|
||||
@@ -38,7 +41,16 @@ func (UniformityModule) RegisterRoutes(router fiber.Router, db *gorm.DB, validat
|
||||
panic(fmt.Sprintf("failed to register uniformity approval workflow: %v", err))
|
||||
}
|
||||
|
||||
uniformityService := sUniformity.NewUniformityService(uniformityRepo, documentSvc, approvalRepo, approvalSvc, projectFlockKandangRepo, validate)
|
||||
uniformityService := sUniformity.NewUniformityService(
|
||||
uniformityRepo,
|
||||
documentSvc,
|
||||
approvalRepo,
|
||||
approvalSvc,
|
||||
projectFlockKandangRepo,
|
||||
productionStandardRepo,
|
||||
standardGrowthDetailRepo,
|
||||
validate,
|
||||
)
|
||||
userService := sUser.NewUserService(userRepo, validate)
|
||||
|
||||
UniformityRoutes(router, userService, uniformityService)
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
commonSvc "gitlab.com/mbugroup/lti-api.git/internal/common/service"
|
||||
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
||||
m "gitlab.com/mbugroup/lti-api.git/internal/middleware"
|
||||
rProductionStandard "gitlab.com/mbugroup/lti-api.git/internal/modules/master/production-standards/repositories"
|
||||
rProjectFlock "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/repositories"
|
||||
repository "gitlab.com/mbugroup/lti-api.git/internal/modules/production/uniformities/repositories"
|
||||
validation "gitlab.com/mbugroup/lti-api.git/internal/modules/production/uniformities/validations"
|
||||
@@ -30,6 +31,8 @@ type UniformityService interface {
|
||||
GetAll(ctx *fiber.Ctx, params *validation.Query) ([]entity.ProjectFlockKandangUniformity, int64, error)
|
||||
GetOne(ctx *fiber.Ctx, id uint) (*entity.ProjectFlockKandangUniformity, error)
|
||||
GetSummary(ctx *fiber.Ctx, id uint) (*entity.ProjectFlockKandangUniformity, error)
|
||||
GetStandard(ctx *fiber.Ctx, uniformity *entity.ProjectFlockKandangUniformity) (*UniformityStandard, error)
|
||||
MapStandards(ctx *fiber.Ctx, items []entity.ProjectFlockKandangUniformity) (map[uint]UniformityStandard, error)
|
||||
CreateOne(ctx *fiber.Ctx, req *validation.Create, file *multipart.FileHeader, rows []BodyWeightExcelRow) (*entity.ProjectFlockKandangUniformity, error)
|
||||
UpdateOne(ctx *fiber.Ctx, req *validation.Update, id uint, file *multipart.FileHeader, rows []BodyWeightExcelRow) (*entity.ProjectFlockKandangUniformity, error)
|
||||
DeleteOne(ctx *fiber.Ctx, id uint) error
|
||||
@@ -40,13 +43,15 @@ type UniformityService interface {
|
||||
}
|
||||
|
||||
type uniformityService struct {
|
||||
Log *logrus.Logger
|
||||
Validate *validator.Validate
|
||||
Repository repository.UniformityRepository
|
||||
DocumentSvc commonSvc.DocumentService
|
||||
ApprovalRepo commonRepo.ApprovalRepository
|
||||
ApprovalSvc commonSvc.ApprovalService
|
||||
ProjectFlockKandangRepo rProjectFlock.ProjectFlockKandangRepository
|
||||
Log *logrus.Logger
|
||||
Validate *validator.Validate
|
||||
Repository repository.UniformityRepository
|
||||
DocumentSvc commonSvc.DocumentService
|
||||
ApprovalRepo commonRepo.ApprovalRepository
|
||||
ApprovalSvc commonSvc.ApprovalService
|
||||
ProjectFlockKandangRepo rProjectFlock.ProjectFlockKandangRepository
|
||||
ProductionStandardRepo rProductionStandard.ProductionStandardRepository
|
||||
StandardGrowthDetailRepo rProductionStandard.StandardGrowthDetailRepository
|
||||
}
|
||||
|
||||
func NewUniformityService(
|
||||
@@ -55,16 +60,20 @@ func NewUniformityService(
|
||||
approvalRepo commonRepo.ApprovalRepository,
|
||||
approvalSvc commonSvc.ApprovalService,
|
||||
projectFlockKandangRepo rProjectFlock.ProjectFlockKandangRepository,
|
||||
productionStandardRepo rProductionStandard.ProductionStandardRepository,
|
||||
standardGrowthDetailRepo rProductionStandard.StandardGrowthDetailRepository,
|
||||
validate *validator.Validate,
|
||||
) UniformityService {
|
||||
return &uniformityService{
|
||||
Log: utils.Log,
|
||||
Validate: validate,
|
||||
Repository: repo,
|
||||
DocumentSvc: documentSvc,
|
||||
ApprovalRepo: approvalRepo,
|
||||
ApprovalSvc: approvalSvc,
|
||||
ProjectFlockKandangRepo: projectFlockKandangRepo,
|
||||
Log: utils.Log,
|
||||
Validate: validate,
|
||||
Repository: repo,
|
||||
DocumentSvc: documentSvc,
|
||||
ApprovalRepo: approvalRepo,
|
||||
ApprovalSvc: approvalSvc,
|
||||
ProjectFlockKandangRepo: projectFlockKandangRepo,
|
||||
ProductionStandardRepo: productionStandardRepo,
|
||||
StandardGrowthDetailRepo: standardGrowthDetailRepo,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,6 +130,64 @@ func (s uniformityService) GetSummary(c *fiber.Ctx, id uint) (*entity.ProjectFlo
|
||||
return s.GetOne(c, id)
|
||||
}
|
||||
|
||||
func (s uniformityService) GetStandard(c *fiber.Ctx, uniformity *entity.ProjectFlockKandangUniformity) (*UniformityStandard, error) {
|
||||
if uniformity == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return s.resolveUniformityStandard(c.Context(), *uniformity)
|
||||
}
|
||||
|
||||
func (s uniformityService) MapStandards(c *fiber.Ctx, items []entity.ProjectFlockKandangUniformity) (map[uint]UniformityStandard, error) {
|
||||
if len(items) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
if s.ProductionStandardRepo == nil || s.StandardGrowthDetailRepo == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
categoryStandard := make(map[string]*entity.ProductionStandard)
|
||||
detailCache := make(map[uint]map[int]entity.StandardGrowthDetail)
|
||||
result := make(map[uint]UniformityStandard, len(items))
|
||||
|
||||
for _, item := range items {
|
||||
if item.Id == 0 {
|
||||
continue
|
||||
}
|
||||
standard, err := s.resolveCategoryStandard(c.Context(), item.ProjectFlockKandang.ProjectFlock.Category, categoryStandard)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if standard == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
weekMap, ok := detailCache[standard.Id]
|
||||
if !ok {
|
||||
details, err := s.StandardGrowthDetailRepo.GetByProductionStandardID(c.Context(), standard.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
weekMap = make(map[int]entity.StandardGrowthDetail, len(details))
|
||||
for _, detail := range details {
|
||||
weekMap[detail.Week] = detail
|
||||
}
|
||||
detailCache[standard.Id] = weekMap
|
||||
}
|
||||
|
||||
detail, ok := weekMap[item.Week]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
standardDTO := UniformityStandard{
|
||||
MeanWeight: cloneFloat64(detail.TargetMeanBw),
|
||||
Uniformity: float64Ptr(detail.MinUniformity),
|
||||
}
|
||||
result[item.Id] = standardDTO
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s *uniformityService) CreateOne(c *fiber.Ctx, req *validation.Create, file *multipart.FileHeader, rows []BodyWeightExcelRow) (*entity.ProjectFlockKandangUniformity, error) {
|
||||
if err := s.Validate.Struct(req); err != nil {
|
||||
return nil, err
|
||||
@@ -516,6 +583,11 @@ type UniformityCalculation struct {
|
||||
Details []UniformityDetailItem
|
||||
}
|
||||
|
||||
type UniformityStandard struct {
|
||||
MeanWeight *float64
|
||||
Uniformity *float64
|
||||
}
|
||||
|
||||
func (s uniformityService) ComputeUniformity(rows []BodyWeightExcelRow) (UniformityCalculation, error) {
|
||||
return computeUniformity(rows)
|
||||
}
|
||||
@@ -664,6 +736,81 @@ func (s *uniformityService) attachLatestApproval(ctx context.Context, item *enti
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *uniformityService) resolveUniformityStandard(ctx context.Context, item entity.ProjectFlockKandangUniformity) (*UniformityStandard, error) {
|
||||
if s.ProductionStandardRepo == nil || s.StandardGrowthDetailRepo == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
standard, err := s.resolveCategoryStandard(ctx, item.ProjectFlockKandang.ProjectFlock.Category, nil)
|
||||
if err != nil || standard == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
detail, err := s.StandardGrowthDetailRepo.GetByStandardIDAndWeek(ctx, standard.Id, item.Week)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &UniformityStandard{
|
||||
MeanWeight: cloneFloat64(detail.TargetMeanBw),
|
||||
Uniformity: float64Ptr(detail.MinUniformity),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *uniformityService) resolveCategoryStandard(
|
||||
ctx context.Context,
|
||||
category string,
|
||||
cache map[string]*entity.ProductionStandard,
|
||||
) (*entity.ProductionStandard, error) {
|
||||
category = strings.TrimSpace(category)
|
||||
if category == "" {
|
||||
return nil, nil
|
||||
}
|
||||
if cache != nil {
|
||||
if cached, ok := cache[category]; ok {
|
||||
return cached, nil
|
||||
}
|
||||
}
|
||||
|
||||
var standard entity.ProductionStandard
|
||||
err := s.ProductionStandardRepo.DB().WithContext(ctx).
|
||||
Where("project_category = ?", category).
|
||||
Where("deleted_at IS NULL").
|
||||
Order("created_at DESC").
|
||||
First(&standard).Error
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
if cache != nil {
|
||||
cache[category] = nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
standardCopy := standard
|
||||
if cache != nil {
|
||||
cache[category] = &standardCopy
|
||||
}
|
||||
return &standardCopy, nil
|
||||
}
|
||||
|
||||
func cloneFloat64(value *float64) *float64 {
|
||||
if value == nil {
|
||||
return nil
|
||||
}
|
||||
copy := *value
|
||||
return ©
|
||||
}
|
||||
|
||||
func float64Ptr(value float64) *float64 {
|
||||
copy := value
|
||||
return ©
|
||||
}
|
||||
|
||||
func (s *uniformityService) rollbackUniformityCreate(ctx context.Context, uniformityID uint) {
|
||||
if uniformityID == 0 {
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user