Browse Source

event: 称重和入场事件优化

Yi 1 month ago
parent
commit
1fab5949dc

+ 5 - 7
.drone.yml

@@ -5,14 +5,12 @@ name: kptPasture
 #clone:
 #  depth: 1
 #  disable: true
-
 steps:
-  #- name: clone
-  #  image: alpine/git
-  #  commands:
-  #    - git clone -b develop http://kpt.kptyun.cn:3000/xuyiping/kpt-pasture.git
-  #    - ls -l
-  #    - pwd
+#  - name: clone
+#    image: alpine/git
+#    commands:
+#      - git clone -b feature/event http://192.168.1.8:3000/xuyiping/kpt-pasture.git
+#      - cp -R kpt-pasture/* ./
   - name: build
     image: plugins/docker:20.14.2
     volumes:

+ 1 - 1
go.mod

@@ -3,7 +3,7 @@ module kpt-pasture
 go 1.17
 
 require (
-	gitee.com/xuyiping_admin/go_proto v0.0.0-20250206052721-b3db038e7785
+	gitee.com/xuyiping_admin/go_proto v0.0.0-20250208022155-41067ebaa17d
 	gitee.com/xuyiping_admin/pkg v0.0.0-20241108060137-caea58c59f5b
 	github.com/dgrijalva/jwt-go v3.2.0+incompatible
 	github.com/eclipse/paho.mqtt.golang v1.4.3

+ 5 - 0
go.sum

@@ -146,6 +146,11 @@ gitee.com/xuyiping_admin/go_proto v0.0.0-20250206034014-bf215fbc8803 h1:+VDhdJnU
 gitee.com/xuyiping_admin/go_proto v0.0.0-20250206034014-bf215fbc8803/go.mod h1:BKrFW6YLDectlQcQk3FYKBeXvjEiodAKJ5rq7O/QiPE=
 gitee.com/xuyiping_admin/go_proto v0.0.0-20250206052721-b3db038e7785 h1:DmfvtWuaFoSlAX9uQmOXu/JVh7Nqm/u2n/adB/rlBWw=
 gitee.com/xuyiping_admin/go_proto v0.0.0-20250206052721-b3db038e7785/go.mod h1:BKrFW6YLDectlQcQk3FYKBeXvjEiodAKJ5rq7O/QiPE=
+gitee.com/xuyiping_admin/go_proto v0.0.0-20250208020725-17a400a07936/go.mod h1:BKrFW6YLDectlQcQk3FYKBeXvjEiodAKJ5rq7O/QiPE=
+gitee.com/xuyiping_admin/go_proto v0.0.0-20250208021036-c6018bf8a9e2 h1:eFOdl5NVDP6bnSB9XjMzBwgy2DnN6WaXwEx0KrwKlY8=
+gitee.com/xuyiping_admin/go_proto v0.0.0-20250208021036-c6018bf8a9e2/go.mod h1:BKrFW6YLDectlQcQk3FYKBeXvjEiodAKJ5rq7O/QiPE=
+gitee.com/xuyiping_admin/go_proto v0.0.0-20250208022155-41067ebaa17d h1:2l7WoxgnJf/Jf6YzSUh+Cm+m65iQU2WWvSz5LQo7jjc=
+gitee.com/xuyiping_admin/go_proto v0.0.0-20250208022155-41067ebaa17d/go.mod h1:BKrFW6YLDectlQcQk3FYKBeXvjEiodAKJ5rq7O/QiPE=
 gitee.com/xuyiping_admin/pkg v0.0.0-20241108060137-caea58c59f5b h1:w05MxH7yqveRlaRbxHhbif5YjPrJFodRPfOjYhXn7Zk=
 gitee.com/xuyiping_admin/pkg v0.0.0-20241108060137-caea58c59f5b/go.mod h1:8tF25X6pE9WkFCczlNAC0K2mrjwKvhhp02I7o0HtDxY=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=

+ 5 - 5
http/handler/event/event_base.go

@@ -197,20 +197,20 @@ func WeightList(c *gin.Context) {
 }
 
 func WeightBatch(c *gin.Context) {
-	var req pasturePb.EventWeight
+	var req pasturePb.BatchEventWeight
 	if err := ginutil.BindProto(c, &req); err != nil {
 		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
 		return
 	}
 
 	if err := valid.ValidateStruct(&req,
-		valid.Field(&req.WeightAt, valid.Required),
-		valid.Field(&req.OperationId, valid.Required),
-		valid.Field(&req.WeightItems, valid.Required, valid.Each(valid.By(func(value interface{}) error {
-			s := value.(pasturePb.WeightItem)
+		valid.Field(&req.Items, valid.Required, valid.Each(valid.By(func(value interface{}) error {
+			s := value.(pasturePb.EventWeight)
 			return valid.ValidateStruct(&s,
 				valid.Field(&s.Weight, valid.Required),
 				valid.Field(&s.CowId, valid.Required),
+				valid.Field(&s.WeightAt, valid.Required),
+				valid.Field(&s.OperationId, valid.Required),
 			)
 		}))),
 	); err != nil {

+ 1 - 2
http/handler/event/event_breed.go

@@ -375,7 +375,7 @@ func WeaningCreateBatch(c *gin.Context) {
 		valid.Field(req.OperationId, valid.Required),
 		valid.Field(req.PenId, valid.Required),
 		valid.Field(&req.Item, valid.Required, valid.Each(valid.By(func(value interface{}) error {
-			item := value.(pasturePb.WeaningBatch)
+			item := value.(pasturePb.BatchWeaning)
 			return valid.ValidateStruct(&item,
 				valid.Field(&item.CowId, valid.Required),
 				valid.Field(&item.Weight, valid.Required),
@@ -390,7 +390,6 @@ func WeaningCreateBatch(c *gin.Context) {
 		apierr.ClassifiedAbort(c, err)
 		return
 	}
-
 	ginutil.JSONResp(c, &operationPb.CommonOK{
 		Code: http.StatusOK,
 		Msg:  "ok",

+ 1 - 0
http/route/event_api.go

@@ -38,6 +38,7 @@ func EventAPI(opts ...func(engine *gin.Engine)) func(s *gin.Engine) {
 		eventRoute.POST("/mating/list", event.MatingEventList)
 		eventRoute.POST("/mating/create", event.MatingCreate)
 		// 发情
+		eventRoute.POST("/estrus/list/", event.EstrusEventList)
 		eventRoute.POST("/estrus/mating/batch/", event.EstrusBatchMating)
 		// 同期
 		eventRoute.POST("/same/time/list", event.SameTimeList)

+ 7 - 7
model/event_weight.go

@@ -31,21 +31,21 @@ func (c *EventWeight) TableName() string {
 	return "event_weight"
 }
 
-func NewEventWeight(pastureId int64, cow *Cow, currentUser *SystemUser, weight, height int32, req *pasturePb.EventWeight) *EventWeight {
+func NewEventWeight(pastureId int64, cow *Cow, currentUser *SystemUser, item *pasturePb.EventWeight) *EventWeight {
 	return &EventWeight{
 		PastureId:     pastureId,
 		CowId:         cow.Id,
 		EarNumber:     cow.EarNumber,
-		Weight:        weight,
-		Height:        height,
+		Weight:        int32(item.Weight * 1000),
+		Height:        item.Height,
 		Lact:          cow.Lact,
 		DayAge:        cow.GetDayAge(),
-		WeightAt:      int64(req.WeightAt),
-		Remarks:       req.Remarks,
+		WeightAt:      int64(item.WeightAt),
+		Remarks:       item.Remarks,
 		MessageId:     currentUser.Id,
 		MessageName:   currentUser.Name,
-		OperationId:   req.OperationId,
-		OperationName: req.OperationName,
+		OperationId:   item.OperationId,
+		OperationName: item.OperationName,
 	}
 }
 

+ 4 - 4
module/backend/analysis.go

@@ -487,7 +487,7 @@ func (s *StoreEntry) TwentyOnePregnantRate(ctx context.Context, req *pasturePb.T
 		}
 		middleDayUnix := util.TimeParseLocalEndUnix(middleDay)
 		chart.Header = append(chart.Header, fmt.Sprintf("%s ~ %s", v[0], v[1]))
-		cowList := s.TwentyonePregnantCowList(ctx, req.CowType, stopBreedingDay, middleDayUnix, []int64{})
+		cowList := s.TwentyOnePregnantCowList(ctx, req.CowType, stopBreedingDay, middleDayUnix, []int64{})
 		twentyOnePregnantRateList = append(twentyOnePregnantRateList, &pasturePb.TwentyOnePregnantRateList{
 			StartDay:             v[0],
 			EndDay:               v[1],
@@ -516,8 +516,8 @@ func (s *StoreEntry) TwentyOnePregnantRate(ctx context.Context, req *pasturePb.T
 	}, nil
 }
 
-// TwentyonePregnantCowList 21天牛只停配期牛只列表
-func (s *StoreEntry) TwentyonePregnantCowList(
+// TwentyOnePregnantCowList 21天牛只停配期牛只列表
+func (s *StoreEntry) TwentyOnePregnantCowList(
 	ctx context.Context,
 	cowType pasturePb.CowType_Kind,
 	stopBreedingDay int32,
@@ -537,7 +537,7 @@ func (s *StoreEntry) TwentyonePregnantCowList(
 			pref = pref.Where("id NOT IN ?", notInCow)
 		}
 		if err := pref.Find(&cowList).Error; err != nil {
-			zaplog.Error("TwentyonePregnantCowList",
+			zaplog.Error("TwentyOnePregnantCowList",
 				zap.Any("cowType", cowType),
 				zap.Any("stopBreedingDay", stopBreedingDay),
 				zap.Any("middleDay", middleDay),

+ 2 - 1
module/backend/analysis_other.go

@@ -139,9 +139,10 @@ func (s *StoreEntry) CalvingReport(ctx context.Context, req *pasturePb.CalvingRe
 		}
 		if v.TotalCount > 0 {
 			v.TwinsRate = float32(util.RoundToTwoDecimals(float64(v.Twins) / float64(v.TotalCount) * 100))
-			v.BullsDieRate = float32(util.RoundToTwoDecimals(float64(v.Bulls) / float64(v.TotalCount) * 100))
 			v.CowsRate = float32(util.RoundToTwoDecimals(float64(v.Cows) / float64(v.TotalCount) * 100))
 			v.DieRate = float32(util.RoundToTwoDecimals(float64(v.DieCount) / float64(v.TotalCount) * 100))
+			v.BullsRate = float32(util.RoundToTwoDecimals(float64(v.Bulls) / float64(v.TotalCount) * 100))
+			v.SurviveRate = float32(util.RoundToTwoDecimals(float64(v.SurviveCount) / float64(v.TotalCount) * 100))
 		}
 
 		if v.Bulls > 0 {

+ 27 - 27
module/backend/event_base.go

@@ -77,7 +77,7 @@ func (s *StoreEntry) EnterList(ctx context.Context, req *pasturePb.SearchEventRe
 	}, nil
 }
 
-func (s *StoreEntry) CreateEnter(ctx context.Context, req *pasturePb.EventEnterRequest) error {
+func (s *StoreEntry) CreateEnter(ctx context.Context, req *pasturePb.EventEnterRequest) (err error) {
 	userModel, err := s.GetUserModel(ctx)
 	if err != nil {
 		return xerr.WithStack(err)
@@ -91,26 +91,31 @@ func (s *StoreEntry) CreateEnter(ctx context.Context, req *pasturePb.EventEnterR
 	}
 
 	penMap := s.PenMap(ctx, userModel.AppPasture.Id)
+	newCow := model.NewCow(userModel.AppPasture.Id, req, penMap)
+	defer func() {
+		if err == nil {
+			cowLogs := s.SubmitEventLog(ctx, userModel.AppPasture.Id, newCow, pasturePb.EventType_Enter, pasturePb.ExposeEstrusType_Invalid, req)
+			s.DB.Table(cowLogs.TableName()).Create(cowLogs)
+		}
+	}()
 	if err = s.DB.Transaction(func(tx *gorm.DB) error {
-		newCowData := model.NewCow(userModel.AppPasture.Id, req, penMap)
-		if err = tx.Create(newCowData).Error; err != nil {
+		if err = tx.Create(newCow).Error; err != nil {
 			return xerr.WithStack(err)
 		}
-		newEventEnter := model.NewEventEnter(userModel.AppPasture.Id, newCowData.Id, req)
+		newEventEnter := model.NewEventEnter(userModel.AppPasture.Id, newCow.Id, req)
 		if err = tx.Create(newEventEnter).Error; err != nil {
 			return xerr.WithStack(err)
 		}
 		eventWeight := model.NewEventWeight(
 			userModel.AppPasture.Id,
-			newCowData,
+			newCow,
 			userModel.SystemUser,
-			int32(req.Weight*1000),
-			0,
 			&pasturePb.EventWeight{
 				WeightAt:      req.EnterAt,
 				Remarks:       "入场体重",
 				OperationId:   req.OperationId,
 				OperationName: req.OperationName,
+				Weight:        req.Weight,
 			})
 		if err = tx.Create(eventWeight).Error; err != nil {
 			return xerr.WithStack(err)
@@ -126,9 +131,9 @@ func (s *StoreEntry) GroupTransferList(ctx context.Context, req *pasturePb.Searc
 	eventGroupTransferList := make([]*pasturePb.EventTransferGroupData, 0)
 	var count int64 = 0
 	pref := s.DB.Table(fmt.Sprintf("%s as a", new(model.EventTransferGroup).TableName())).
-		Select(`a.id,a.cow_id,a.pen_in_id as transfer_in_pen_id,a.pen_out_id as transfer_out_pen_id,a.lact,a.remarks,a.transfer_reason_id,a.transfer_reason_name,
-			a.transfer_date,a.created_at,a.operation_id,a.operation_name,b.name as transfer_in_pen_name,c.name as transfer_out_pen_name,
-			f.lact,f.ear_number`).
+		Select(`a.id,a.cow_id,a.pen_in_id as transfer_in_pen_id,a.pen_out_id as transfer_out_pen_id,a.lact,a.remarks,
+		a.transfer_reason_id,a.transfer_reason_name,a.transfer_date,a.created_at,a.operation_id,a.operation_name,
+		b.name as transfer_in_pen_name,c.name as transfer_out_pen_name,f.lact,f.ear_number`).
 		Joins(fmt.Sprintf("JOIN %s AS b ON a.pen_in_id = b.id", new(model.Pen).TableName())).
 		Joins(fmt.Sprintf("JOIN %s AS c on a.pen_out_id = c.id", new(model.Pen).TableName())).
 		Joins(fmt.Sprintf("JOIN %s AS f ON a.cow_id = f.id", new(model.Cow).TableName()))
@@ -188,7 +193,7 @@ func (s *StoreEntry) CreateGroupTransfer(ctx context.Context, req *pasturePb.Tra
 	}
 
 	defer func() {
-		if err != nil {
+		if err == nil {
 			for _, etg := range newEventTransferGroupModelList {
 				cowLogs := s.SubmitEventLog(ctx, userModel.AppPasture.Id, etg.Cow, pasturePb.EventType_Transfer_Ben, pasturePb.ExposeEstrusType_Invalid, etg.EventTransferGroup)
 				s.DB.Table(cowLogs.TableName()).Create(cowLogs)
@@ -266,6 +271,7 @@ func (s *StoreEntry) CreateBodyScore(ctx context.Context, req *pasturePb.BodySco
 	if len(bodyScourEvent) <= 0 {
 		return nil
 	}
+
 	return s.DB.Create(bodyScourEvent).Error
 }
 
@@ -299,9 +305,9 @@ func (s *StoreEntry) WeightList(ctx context.Context, req *pasturePb.SearchEventR
 	}, nil
 }
 
-func (s *StoreEntry) WeightBatch(ctx context.Context, req *pasturePb.EventWeight) (err error) {
-	if len(req.WeightItems) <= 0 {
-		return xerr.Custom("请选择相关牛只")
+func (s *StoreEntry) WeightBatch(ctx context.Context, req *pasturePb.BatchEventWeight) (err error) {
+	if len(req.Items) <= 0 {
+		return xerr.Custom("称重数据不能为空")
 	}
 
 	userModel, err := s.GetUserModel(ctx)
@@ -309,32 +315,25 @@ func (s *StoreEntry) WeightBatch(ctx context.Context, req *pasturePb.EventWeight
 		return xerr.WithStack(err)
 	}
 
-	operationUser, err := s.GetSystemUserById(ctx, int64(req.OperationId))
-	if err != nil {
-		return xerr.WithStack(err)
-	}
-	req.OperationName = operationUser.Name
-
 	defer func() {
 		if err == nil {
 			// 记录事件日志
-			for _, item := range req.WeightItems {
+			for _, item := range req.Items {
 				cow, _ := s.GetCowInfoByCowId(ctx, userModel.AppPasture.Id, int64(item.CowId))
-				cowLogs := s.SubmitEventLog(ctx, userModel.AppPasture.Id, cow, pasturePb.EventType_Weight, pasturePb.ExposeEstrusType_Invalid, req)
+				cowLogs := s.SubmitEventLog(ctx, userModel.AppPasture.Id, cow, pasturePb.EventType_Weight, pasturePb.ExposeEstrusType_Invalid, item)
 				s.DB.Table(cowLogs.TableName()).Create(cowLogs)
 			}
 		}
 	}()
 	cow := &model.Cow{}
-	for _, item := range req.WeightItems {
+	for _, item := range req.Items {
 		cow, err = s.GetCowInfoByCowId(ctx, userModel.AppPasture.Id, int64(item.CowId))
 		if err != nil {
 			return xerr.WithStack(err)
 		}
-		item.WeightAt = req.WeightAt
 
 		// 更新牛只信息
-		cow.EventWeightUpdate(int64(item.Weight), int64(req.WeightAt))
+		cow.EventWeightUpdate(int64(item.Weight), int64(item.WeightAt))
 		if err = s.DB.Model(new(model.Cow)).
 			Select("last_second_weight_at", "last_second_weight", "last_weight_at", "current_weight").
 			Where("id = ?", cow.Id).
@@ -342,9 +341,10 @@ func (s *StoreEntry) WeightBatch(ctx context.Context, req *pasturePb.EventWeight
 			Updates(cow).Error; err != nil {
 			return xerr.WithStack(err)
 		}
-
+		operationUser, _ := s.GetSystemUserById(ctx, int64(item.OperationId))
+		item.OperationName = operationUser.Name
 		// 创建牛只的体重记录
-		eventWeight := model.NewEventWeight(userModel.AppPasture.Id, cow, userModel.SystemUser, int32(item.Weight*1000), item.Height, req)
+		eventWeight := model.NewEventWeight(userModel.AppPasture.Id, cow, userModel.SystemUser, item)
 		if err = s.DB.Create(eventWeight).Error; err != nil {
 			return xerr.WithStack(err)
 		}

+ 5 - 4
module/backend/event_breed.go

@@ -30,7 +30,7 @@ func (s *StoreEntry) CalvingList(ctx context.Context, req *pasturePb.SearchEvent
 		Select(`a.*,b.name as pen_name,c.name as staff_member_name`).
 		Joins(fmt.Sprintf("JOIN %s AS b on a.pen_id = b.id", new(model.Pen).TableName())).
 		Joins(fmt.Sprintf("JOIN %s AS c on a.operation_id = c.id", new(model.SystemUser).TableName())).
-		Where("pasture_id = ?", userModel.AppPasture.Id)
+		Where("a.pasture_id = ?", userModel.AppPasture.Id)
 	if len(req.CowId) > 0 {
 		cowIds := strings.Split(req.CowId, ",")
 		pref.Where("a.cow_id IN ?", cowIds)
@@ -320,7 +320,8 @@ func (s *StoreEntry) EstrusList(ctx context.Context, req *pasturePb.EstrusItemsR
 	var count int64 = 0
 	pref := s.DB.Table(new(model.EventEstrus).TableName()).
 		Where("is_show = ?", pasturePb.IsShow_Ok).
-		Where("pasture_id = ?", userModel.AppPasture.Id)
+		Where("pasture_id = ?", userModel.AppPasture.Id).
+		Where("expose_estrus_type = ?", pasturePb.ExposeEstrusType_Natural_Estrus)
 	if len(req.CowIds) > 0 {
 		cowIds := strings.Split(util.ArrayInt32ToStrings(req.CowIds, ","), ",")
 		pref.Where("cow_id IN ?", cowIds)
@@ -662,13 +663,13 @@ func (s *StoreEntry) WeaningBatch(ctx context.Context, req *pasturePb.EventWeani
 				userModel.AppPasture.Id,
 				cowInfo,
 				userModel.SystemUser,
-				int32(cowWeightMap[v.CowId]*1000),
-				0,
 				&pasturePb.EventWeight{
 					WeightAt:      req.WeaningAt,
 					OperationId:   req.OperationId,
 					OperationName: req.OperationName,
 					Remarks:       req.Remarks,
+					Weight:        float32(cowWeightMap[cowInfo.Id]),
+					Height:        0,
 				})
 			if err = tx.Create(newEventWeight).Error; err != nil {
 				return xerr.WithStack(err)

+ 17 - 6
module/backend/event_cow_log.go

@@ -32,7 +32,23 @@ func (s *StoreEntry) SubmitEventLog(
 
 	switch eventType {
 	case pasturePb.EventType_Enter:
+		data := req.(*pasturePb.EventEnterRequest)
+		eventAt = int64(data.EnterAt)
+		remarks = data.Remarks
 		eventCategoryId = pasturePb.EventCategory_Base
+		sourceMap := s.CowSourceMap()
+		sex := "公"
+		if data.Sex == pasturePb.Genders_Female {
+			sex = "母"
+		}
+		desc = fmt.Sprintf("入场时间: %s; 性别: %s; 栏舍: %s; 体重: %f kg; price: %f; 来源: %s;",
+			time.Unix(eventAt, 0).Format(model.LayoutDate2),
+			sex,
+			penMap[cow.PenId].Name,
+			data.Weight,
+			data.Price,
+			sourceMap[cow.SourceId],
+		)
 	case pasturePb.EventType_Transfer_Ben:
 		data := req.(*model.EventTransferGroup)
 		transferAt, _ := time.Parse(model.LayoutDate2, data.TransferDate)
@@ -162,12 +178,7 @@ func (s *StoreEntry) SubmitEventLog(
 		operationUser.Id = int64(data.OperationId)
 		operationUser.Name = data.OperationName
 		remarks = data.Remarks
-		for _, v := range data.WeightItems {
-			if int64(v.CowId) == cow.Id {
-				desc = fmt.Sprintf("日龄: %d;具体体重: %f", cow.DayAge, v.Weight)
-				break
-			}
-		}
+		desc = fmt.Sprintf("日龄: %d;具体体重: %f kg", cow.DayAge, data.Weight)
 		eventCategoryId = pasturePb.EventCategory_Base
 	case pasturePb.EventType_Castrated:
 		eventCategoryId = pasturePb.EventCategory_Health

+ 1 - 1
module/backend/interface.go

@@ -186,7 +186,7 @@ type EventService interface {
 	SameTimeList(ctx context.Context, req *pasturePb.SearchEventRequest, pagination *pasturePb.PaginationModel) (*pasturePb.SearchSameTimeResponse, error)
 	// WeightList 称重
 	WeightList(ctx context.Context, req *pasturePb.SearchEventRequest, pagination *pasturePb.PaginationModel) (*pasturePb.SearchWeightEventResponse, error)
-	WeightBatch(ctx context.Context, req *pasturePb.EventWeight) error
+	WeightBatch(ctx context.Context, req *pasturePb.BatchEventWeight) error
 
 	// CowDiseaseCreate 提交发病牛只
 	CowDiseaseCreate(ctx context.Context, req *pasturePb.EventCowDiseaseRequest, source string) error

+ 6 - 6
module/crontab/cow_cron.go

@@ -58,19 +58,19 @@ func (e *Entry) GenerateAsynqWorkOrder() error {
 
 // Indicators 指标维护
 func (e *Entry) Indicators() error {
-	indicatorsRemarksList := make([]*model.IndicatorsDetails, 0)
+	indicatorsDetailsList := make([]*model.IndicatorsDetails, 0)
 	if err := e.DB.Model(new(model.IndicatorsDetails)).
-		Find(&indicatorsRemarksList).Error; err != nil {
+		Find(&indicatorsDetailsList).Error; err != nil {
 		return err
 	}
 	nowTime := time.Now().Format(model.LayoutMonth)
-	zaplog.Info("Indicators", zap.Any("nowTime", nowTime))
-	for _, v := range indicatorsRemarksList {
-		switch v.Kind {
+	zaplog.Info("Indicators", zap.Any("nowTime", nowTime), zap.Any("indicatorsDetailsList", indicatorsDetailsList))
+	for _, indicatorsDetail := range indicatorsDetailsList {
+		switch indicatorsDetail.Kind {
 		case "all_cow":
 			pastureIdAllCow := e.FindPastureAllCow()
 			for pastureId, value := range pastureIdAllCow {
-				e.UpdatePastureIndicators(pastureId, v, nowTime, fmt.Sprintf("%d", value))
+				e.UpdatePastureIndicators(pastureId, indicatorsDetail, nowTime, fmt.Sprintf("%d", value))
 			}
 		case "calving_interval":