event_breed.go 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679
  1. package backend
  2. import (
  3. "context"
  4. "fmt"
  5. "kpt-pasture/model"
  6. "kpt-pasture/util"
  7. "net/http"
  8. "strconv"
  9. "strings"
  10. "time"
  11. "gitee.com/xuyiping_admin/pkg/logger/zaplog"
  12. "go.uber.org/zap"
  13. pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow"
  14. "gitee.com/xuyiping_admin/pkg/xerr"
  15. "gorm.io/gorm"
  16. )
  17. func (s *StoreEntry) CalvingList(ctx context.Context, req *pasturePb.SearchEventRequest, pagination *pasturePb.PaginationModel) (*pasturePb.SearchLavingEventResponse, error) {
  18. lavingList := make([]*model.EventCalvingList, 0)
  19. var count int64 = 0
  20. pref := s.DB.Table(fmt.Sprintf("%s as a", new(model.EventCalving).TableName())).
  21. Select(`a.*,b.name as pen_name,c.name as staff_member_name`).
  22. Joins(fmt.Sprintf("JOIN %s AS b on a.pen_id = b.id", new(model.Pen).TableName())).
  23. Joins(fmt.Sprintf("JOIN %s AS c on a.operation_id = c.id", new(model.SystemUser).TableName()))
  24. if len(req.CowId) > 0 {
  25. cowIds := strings.Split(req.CowId, ",")
  26. pref.Where("a.cow_id IN ?", cowIds)
  27. }
  28. if err := pref.Order("a.id desc").
  29. Count(&count).Limit(int(pagination.PageSize)).
  30. Offset(int(pagination.PageOffset)).
  31. Find(&lavingList).Error; err != nil {
  32. return nil, xerr.WithStack(err)
  33. }
  34. calvingIds := make([]int64, 0)
  35. for _, v := range lavingList {
  36. calvingIds = append(calvingIds, v.Id)
  37. }
  38. calvingCalfList := make([]*model.CalvingCalf, 0)
  39. if err := s.DB.Model(new(model.CalvingCalf)).
  40. Where("calving_id IN ?", calvingIds).
  41. Find(&calvingCalfList).Error; err != nil {
  42. return nil, xerr.WithStack(err)
  43. }
  44. return &pasturePb.SearchLavingEventResponse{
  45. Code: http.StatusOK,
  46. Message: "ok",
  47. Data: &pasturePb.SearchLavingData{
  48. List: model.EventCalvingListSlice(lavingList).ToPB(calvingCalfList),
  49. Total: int32(count),
  50. PageSize: pagination.PageSize,
  51. Page: pagination.Page,
  52. },
  53. }, nil
  54. }
  55. func (s *StoreEntry) CalvingCreate(ctx context.Context, req *pasturePb.EventCalving) error {
  56. if len(req.CowId) <= 0 {
  57. return xerr.Custom("请选择相关牛只")
  58. }
  59. cowList, err := s.ParseCowIds(ctx, req.CowId)
  60. if err != nil {
  61. return xerr.WithStack(err)
  62. }
  63. if len(cowList) <= 0 {
  64. return xerr.Custom("请选择相关牛只")
  65. }
  66. cow := cowList[0]
  67. newEventCalving := &model.EventCalving{}
  68. if err = s.DB.Model(new(model.EventCalving)).
  69. Where("cow_id = ?", cow.Id).
  70. Where("lact = ?", cow.Lact).
  71. First(newEventCalving).Error; err != nil {
  72. return xerr.Custom("该母牛信息不存在")
  73. }
  74. if err = s.DB.Transaction(func(tx *gorm.DB) error {
  75. // 母牛信息
  76. if err = tx.Model(new(model.EventCalving)).
  77. Where("id = ?", newEventCalving.Id).
  78. Updates(map[string]interface{}{
  79. "reality_day": int64(req.CalvingAt),
  80. "day_age": cow.DayAge,
  81. "lact": cow.Lact + 1,
  82. "pregnancy_age": cow.PregnancyAge,
  83. "calving_level": req.CalvingLevel,
  84. "bull_number": cow.LastBullNumber,
  85. "child_number": len(req.CalfItemList),
  86. }).
  87. Error; err != nil {
  88. return xerr.WithStack(err)
  89. }
  90. // 犊牛信息
  91. newCalvingCalfList := model.NewEventCalvingCalf(cow.Id, newEventCalving.Id, req)
  92. for _, v := range newCalvingCalfList {
  93. if v.IsLive == pasturePb.IsShow_No || v.IsAdoption == pasturePb.IsShow_No {
  94. continue
  95. }
  96. // 留养犊牛
  97. newCow := model.NewCalfCow(cow.Id, cow.LastBullNumber, v)
  98. if err = tx.Create(newCow).Error; err != nil {
  99. return xerr.WithStack(err)
  100. }
  101. v.CowId = newCow.Id
  102. }
  103. if err = tx.Create(newCalvingCalfList).Error; err != nil {
  104. return xerr.WithStack(err)
  105. }
  106. if err = tx.Model(new(model.Cow)).Where("id = ?", cow.Id).
  107. Updates(map[string]interface{}{
  108. "calving_age": 0,
  109. "mating_times": 0,
  110. "lact": cow.Lact + 1,
  111. "breed_status": pasturePb.BreedStatus_Calving,
  112. "is_pregnant": pasturePb.IsShow_No,
  113. "last_calving_at": int64(req.CalvingAt),
  114. }).Error; err != nil {
  115. return xerr.WithStack(err)
  116. }
  117. return nil
  118. }); err != nil {
  119. return xerr.WithStack(err)
  120. }
  121. return nil
  122. }
  123. func (s *StoreEntry) EstrusList(ctx context.Context, req *pasturePb.EstrusItemsRequest, pagination *pasturePb.PaginationModel) (*pasturePb.EstrusItemsResponse, error) {
  124. estrusList := make([]*model.EventEstrus, 0)
  125. var count int64 = 0
  126. pref := s.DB.Table(new(model.EventEstrus).TableName()).
  127. Where("is_show = ?", pasturePb.IsShow_Ok)
  128. if len(req.CowIds) > 0 {
  129. cowIds := strings.Split(util.ArrayInt32ToStrings(req.CowIds, ","), ",")
  130. pref.Where("cow_id IN ?", cowIds)
  131. }
  132. if req.Level > 0 {
  133. pref.Where("level = ?", req.Level)
  134. }
  135. if len(req.PenIds) > 0 {
  136. penIds := strings.Split(util.ArrayInt32ToStrings(req.PenIds, ","), ",")
  137. pref.Where("pen_id IN ?", penIds)
  138. }
  139. if err := pref.Order("id desc").
  140. Count(&count).Limit(int(pagination.PageSize)).
  141. Offset(int(pagination.PageOffset)).
  142. Find(&estrusList).Error; err != nil {
  143. return nil, xerr.WithStack(err)
  144. }
  145. getCowInfoByCowId := GetCowInfoByCowId
  146. getCowLastEvent := GetCowLastEvent
  147. return &pasturePb.EstrusItemsResponse{
  148. Code: http.StatusOK,
  149. Message: "ok",
  150. Data: &pasturePb.EstrusItemsData{
  151. List: model.EstrusSlice(estrusList).ToPB(s.DB, getCowInfoByCowId, getCowLastEvent),
  152. Total: int32(count),
  153. PageSize: pagination.PageSize,
  154. Page: pagination.Page,
  155. },
  156. }, nil
  157. }
  158. func (s *StoreEntry) EstrusBatch(ctx context.Context, req *pasturePb.EventEstrus) error {
  159. eventMatingList := make([]*model.EventMating, 0)
  160. currentUser, err := s.GetCurrentSystemUser(ctx)
  161. if err != nil {
  162. return xerr.Custom("当前用户信息错误")
  163. }
  164. operationUser, err := s.GetSystemUserById(ctx, int64(req.OperationId))
  165. if err != nil {
  166. return xerr.Customf("该用户不存在: %d", req.OperationId)
  167. }
  168. eventEstrusIds := make([]string, 0)
  169. for _, cowId := range req.CowIds {
  170. cowInfo := GetCowInfoByCowId(s.DB, int64(cowId))
  171. if cowInfo == nil {
  172. return xerr.Custom("牛只信息不存在")
  173. }
  174. newEventMating := model.NewEventMating(cowInfo, time.Now().Unix(), pasturePb.ExposeEstrusType_Neck_Ring)
  175. eventEstrus, ok := s.EventEstrusIsExist(ctx, int64(cowId))
  176. if ok {
  177. newEventMating.EventEstrusId = eventEstrus.Id
  178. newEventMating.MatingTimes = cowInfo.MatingTimes + 1
  179. newEventMating.Status = pasturePb.IsShow_Ok
  180. newEventMating.RealityDay = int64(req.MatingAt)
  181. newEventMating.OperationId = operationUser.Id
  182. newEventMating.OperationName = operationUser.Name
  183. newEventMating.FrozenSemenNumber = req.BullNumber
  184. newEventMating.Remarks = req.Remarks
  185. newEventMating.MessageId = currentUser.Id
  186. newEventMating.MessageName = currentUser.Name
  187. eventEstrusIds = append(eventEstrusIds, strconv.FormatInt(eventEstrus.Id, 10))
  188. }
  189. eventMatingList = append(eventMatingList, newEventMating)
  190. }
  191. if len(eventMatingList) <= 0 {
  192. return nil
  193. }
  194. if err = s.DB.Transaction(func(tx *gorm.DB) error {
  195. if len(eventEstrusIds) > 0 {
  196. if err = tx.Model(new(model.EventEstrus)).
  197. Where("id IN ?", eventEstrusIds).
  198. Updates(map[string]interface{}{
  199. "is_show": pasturePb.IsShow_No,
  200. "result": pasturePb.EstrusResult_Correct,
  201. }).Error; err != nil {
  202. return xerr.WithStack(err)
  203. }
  204. }
  205. if len(eventMatingList) > 0 {
  206. if err = tx.Create(eventMatingList).Error; err != nil {
  207. return xerr.WithStack(err)
  208. }
  209. }
  210. return nil
  211. }); err != nil {
  212. return xerr.WithStack(err)
  213. }
  214. return nil
  215. }
  216. func (s *StoreEntry) SameTimeCreate(ctx context.Context, req *pasturePb.EventSameTime) error {
  217. eventCowSameTime, err := s.GetEventCowSameTimeById(ctx, int64(req.Id))
  218. if err != nil {
  219. return xerr.WithStack(err)
  220. }
  221. if eventCowSameTime.Status == pasturePb.IsShow_Ok {
  222. return xerr.Custom("该事件已处理")
  223. }
  224. if eventCowSameTime.CowId != int64(req.CowId) {
  225. return xerr.Custom("牛只Id 不匹配")
  226. }
  227. drugs := &model.Drugs{}
  228. if req.DrugsId > 0 {
  229. if drugs, err = s.GetDrugsById(ctx, int64(req.DrugsId)); err != nil {
  230. return xerr.WithStack(err)
  231. }
  232. }
  233. operationUser, err := s.GetSystemUserById(ctx, int64(req.OperationId))
  234. if err != nil {
  235. return xerr.WithStack(err)
  236. }
  237. if err = s.DB.Transaction(func(tx *gorm.DB) error {
  238. if err = tx.Model(new(model.CowSameTime)).
  239. Where("cow_id = ?", eventCowSameTime.CowId).
  240. Where("same_time_id = ?", eventCowSameTime.Id).
  241. Where("same_time_status = ?", pasturePb.SameTimeStatus_No_Start).
  242. Update("same_time_status", pasturePb.SameTimeStatus_In_Progress).Error; err != nil {
  243. zaplog.Error("SameTimeCreate", zap.Any("err", err), zap.Any("req", req))
  244. }
  245. if err = tx.Model(new(model.EventCowSameTime)).
  246. Where("id = ?", eventCowSameTime.Id).
  247. Where("cow_id = ?", eventCowSameTime.CowId).
  248. Where("status = ?", pasturePb.IsShow_No).
  249. Updates(map[string]interface{}{
  250. "status": pasturePb.IsShow_Ok,
  251. "drug_id": drugs.Id,
  252. "unit": drugs.Unit,
  253. "usage": req.Usage,
  254. "remarks": req.Remarks,
  255. "operation_id": operationUser.Id,
  256. "operation_name": operationUser.Name,
  257. }).Error; err != nil {
  258. return xerr.WithStack(err)
  259. }
  260. return nil
  261. }); err != nil {
  262. return xerr.WithStack(err)
  263. }
  264. return nil
  265. }
  266. func (s *StoreEntry) SameTimeBatch(ctx context.Context, req *pasturePb.EventSameTimeBatch) error {
  267. drugs := &model.Drugs{}
  268. var err error
  269. if req.DrugsId > 0 {
  270. if drugs, err = s.GetDrugsById(ctx, int64(req.DrugsId)); err != nil {
  271. return xerr.WithStack(err)
  272. }
  273. }
  274. operationUser, err := s.GetSystemUserById(ctx, int64(req.OperationId))
  275. if err != nil {
  276. return xerr.WithStack(err)
  277. }
  278. eventCowSameTimeList := make([]*model.EventCowSameTime, 0)
  279. for _, v := range req.Item {
  280. eventCowSameTime, err := s.GetEventCowSameTimeById(ctx, int64(v.Id))
  281. if err != nil {
  282. return xerr.WithStack(err)
  283. }
  284. if eventCowSameTime.Status == pasturePb.IsShow_Ok {
  285. return xerr.Custom("该事件已处理")
  286. }
  287. if eventCowSameTime.CowId != int64(v.CowId) {
  288. return xerr.Custom(" 牛只Id 不匹配")
  289. }
  290. eventCowSameTimeList = append(eventCowSameTimeList, eventCowSameTime)
  291. }
  292. if err = s.DB.Transaction(func(tx *gorm.DB) error {
  293. for _, v := range eventCowSameTimeList {
  294. if err = tx.Model(new(model.CowSameTime)).
  295. Where("cow_id = ?", v.CowId).
  296. Where("same_time_id = ?", v.Id).
  297. Where("same_time_status = ?", pasturePb.SameTimeStatus_No_Start).
  298. Update("same_time_status", pasturePb.SameTimeStatus_In_Progress).Error; err != nil {
  299. zaplog.Error("SameTimeCreate", zap.Any("err", err), zap.Any("req", req))
  300. }
  301. if err = tx.Model(new(model.EventCowSameTime)).
  302. Where("id = ?", v.Id).
  303. Where("cow_id = ?", v.CowId).
  304. Where("status = ?", pasturePb.IsShow_No).
  305. Updates(map[string]interface{}{
  306. "status": pasturePb.IsShow_Ok,
  307. "drugs_id": drugs.Id,
  308. "unit": drugs.Unit,
  309. "usage": req.Usage,
  310. "remarks": req.Remarks,
  311. "operation_id": operationUser.Id,
  312. "operation_name": operationUser.Name,
  313. }).Error; err != nil {
  314. return xerr.WithStack(err)
  315. }
  316. }
  317. return nil
  318. }); err != nil {
  319. return xerr.WithStack(err)
  320. }
  321. return nil
  322. }
  323. func (s *StoreEntry) SameTimeList(
  324. ctx context.Context,
  325. req *pasturePb.SearchEventRequest,
  326. pagination *pasturePb.PaginationModel,
  327. ) (*pasturePb.SearchSameTimeResponse, error) {
  328. cowSameTimeList := make([]*model.EventCowSameTime, 0)
  329. var count int64 = 0
  330. pref := s.DB.Table(new(model.EventCowSameTime).TableName())
  331. if req.CowId != "" {
  332. cowIds := strings.Split(req.CowId, ",")
  333. pref.Where("cow_id IN ?", cowIds)
  334. }
  335. if err := pref.Count(&count).
  336. Limit(int(pagination.PageSize)).
  337. Offset(int(pagination.PageOffset)).
  338. Find(&cowSameTimeList).Error; err != nil {
  339. return nil, xerr.WithStack(err)
  340. }
  341. sameTimeTypeMap := s.SameTimeTypeMap()
  342. return &pasturePb.SearchSameTimeResponse{
  343. Code: http.StatusOK,
  344. Message: "ok",
  345. Data: &pasturePb.SameTimeData{
  346. List: model.EventCowSameTimeSlice(cowSameTimeList).ToPB(sameTimeTypeMap),
  347. Total: int32(count),
  348. PageSize: pagination.PageSize,
  349. Page: pagination.Page,
  350. },
  351. }, nil
  352. }
  353. func (s *StoreEntry) MatingList(ctx context.Context, req *pasturePb.SearchEventRequest, pagination *pasturePb.PaginationModel) (*pasturePb.MatingEventResponse, error) {
  354. matingList := make([]*model.EventMating, 0)
  355. var count int64 = 0
  356. pref := s.DB.Model(new(model.EventMating)).
  357. Where("mating_result > ?", pasturePb.MatingResult_Invalid).
  358. Where("status = ?", pasturePb.IsShow_No)
  359. if len(req.CowId) > 0 {
  360. cowIds := strings.Split(req.CowId, ",")
  361. pref.Where("cow_id IN ?", cowIds)
  362. }
  363. if err := pref.Order("id desc").
  364. Count(&count).Limit(int(pagination.PageSize)).
  365. Offset(int(pagination.PageOffset)).
  366. Find(&matingList).Error; err != nil {
  367. return nil, xerr.WithStack(err)
  368. }
  369. exposeEstrusTypeMap := s.ExposeEstrusTypeMap()
  370. return &pasturePb.MatingEventResponse{
  371. Code: http.StatusOK,
  372. Message: "ok",
  373. Data: &pasturePb.SearchMatingData{
  374. List: model.EventMatingSlice(matingList).ToPB(exposeEstrusTypeMap),
  375. Total: int32(count),
  376. PageSize: pagination.PageSize,
  377. Page: pagination.Page,
  378. },
  379. }, nil
  380. }
  381. func (s *StoreEntry) MatingCreate(ctx context.Context, req *pasturePb.EventMating) error {
  382. eventCheckModel, err := s.MatingCreateCheck(ctx, req)
  383. if err != nil {
  384. return xerr.WithStack(err)
  385. }
  386. frozenSemen := &model.FrozenSemen{}
  387. if err = s.DB.Where("bull_id = ?", req.FrozenSemenNumber).
  388. First(frozenSemen).Error; err != nil {
  389. return xerr.Custom("未找到冻精信息")
  390. }
  391. if frozenSemen.Quantity < req.FrozenSemenCount {
  392. return xerr.Custom("冻精数量不足")
  393. }
  394. // 更新复配的牛只
  395. matingReMatchIds := make([]int64, 0)
  396. // 新建配种信息的牛只
  397. newMatingList := make([]*model.EventMating, 0)
  398. // 更新配种信息牛只
  399. updateMatingList := make([]int64, 0)
  400. // 所有牛只
  401. cowIds := make([]int64, 0)
  402. // 需要更新配次的牛只
  403. matingTimes := make([]*MatingTimes, 0)
  404. // 需要更新空怀的牛只
  405. emptyCowIds := make([]int64, 0)
  406. for _, cow := range eventCheckModel.CowList {
  407. // 1. 第一次配种,创建配种信息(自然发情牛只,未经过同期的牛只)
  408. if cow.LastMatingAt <= 0 {
  409. newMatingList = append(newMatingList, model.NewEventMating2(cow, req, eventCheckModel.CurrentUser))
  410. continue
  411. }
  412. eventMatingHistory, err := s.GetEventMatingIsExIstByCowId(ctx, cow)
  413. if err != nil {
  414. return xerr.WithStack(err)
  415. }
  416. // 2. 同期更新配种信息 牛号&& 胎次 && 未配 && 配种结果未知 ==> 同期初配
  417. if eventMatingHistory.Status == pasturePb.IsShow_No &&
  418. eventMatingHistory.MatingResult == pasturePb.MatingResult_Unknown {
  419. updateMatingList = append(updateMatingList, eventMatingHistory.Id)
  420. continue
  421. }
  422. lastMatingAt := time.Unix(cow.LastMatingAt, 0)
  423. currentMatingAt := time.Unix(int64(req.MatingAt), 0)
  424. daysBetween := util.DaysBetween(currentMatingAt.Unix(), lastMatingAt.Unix())
  425. // 3. 如何两次配种时间为连续两天之内&&有过一次配种记录,则更新为复配状态 牛号&& 胎次 && 已配 && 配种结果未知 ==> 复配
  426. if (currentMatingAt.Format(model.LayoutDate2) == lastMatingAt.Format(model.LayoutDate2) || daysBetween == 1) &&
  427. eventMatingHistory.Status == pasturePb.IsShow_Ok &&
  428. eventMatingHistory.MatingResult == pasturePb.MatingResult_Unknown {
  429. matingReMatchIds = append(matingReMatchIds, eventMatingHistory.Id)
  430. } else {
  431. matingTimes = append(matingTimes, &MatingTimes{
  432. Mt: cow.MatingTimes + 1,
  433. CowId: cow.Id,
  434. EventMatingId: eventMatingHistory.Id,
  435. })
  436. }
  437. // 4. 提交的配种数据中,如何定位出空怀的牛只,
  438. if (eventMatingHistory.MatingResult == pasturePb.MatingResult_Unknown || eventMatingHistory.MatingResult == pasturePb.MatingResult_ReMatch) &&
  439. daysBetween >= 2 {
  440. emptyCowIds = append(emptyCowIds, eventMatingHistory.Id)
  441. newMatingList = append(newMatingList, model.NewEventMating2(cow, req, eventCheckModel.CurrentUser))
  442. }
  443. cowIds = append(cowIds, cow.Id)
  444. }
  445. if len(cowIds) != len(updateMatingList)+len(matingReMatchIds)+len(newMatingList) {
  446. zaplog.Error("MatingCreate",
  447. zap.Any("cowIds", cowIds),
  448. zap.Any("updateMatingList", updateMatingList),
  449. zap.Any("newMatingList", newMatingList),
  450. zap.Any("matingReMatchIds", matingReMatchIds),
  451. zap.Any("req", req),
  452. )
  453. return xerr.Custom("配种信息有误")
  454. }
  455. itemFrozenSemenLog := model.NewEventFrozenSemenLog(req)
  456. if err = s.DB.Transaction(func(tx *gorm.DB) error {
  457. // 更新配种事件数据(初配)
  458. if len(updateMatingList) > 0 {
  459. if err = tx.Model(new(model.EventMating)).
  460. Where("id IN ?", updateMatingList).
  461. Where("status = ?", pasturePb.IsShow_No).
  462. Updates(map[string]interface{}{
  463. "mating_result": pasturePb.MatingResult_Unknown,
  464. "status": pasturePb.IsShow_Ok,
  465. "reality_day": int64(req.MatingAt),
  466. "frozen_semen_number": req.FrozenSemenNumber,
  467. "operation_id": eventCheckModel.OperationUser.Id,
  468. "operation_name": eventCheckModel.OperationUser.Name,
  469. "message_id": eventCheckModel.CurrentUser.Id,
  470. "message_name": eventCheckModel.CurrentUser.Name,
  471. }).Error; err != nil {
  472. return xerr.WithStack(err)
  473. }
  474. }
  475. // 更新已配种的牛只为复配状态
  476. if len(matingReMatchIds) > 0 {
  477. if err = tx.Model(new(model.EventMating)).
  478. Where("id IN ?", matingReMatchIds).
  479. Where("mating_result = ?", pasturePb.MatingResult_Unknown).
  480. Where("status = ?", pasturePb.IsShow_Ok).
  481. Update("mating_result", pasturePb.MatingResult_ReMatch).
  482. Error; err != nil {
  483. return xerr.WithStack(err)
  484. }
  485. }
  486. // 更新上次已配种的牛只为空怀
  487. if len(emptyCowIds) > 0 {
  488. if err = tx.Model(new(model.EventMating)).
  489. Where("id IN ?", emptyCowIds).
  490. Update("mating_result", pasturePb.BreedStatus_Empty).
  491. Error; err != nil {
  492. return xerr.WithStack(err)
  493. }
  494. }
  495. // 创建配种事件数据
  496. if len(newMatingList) > 0 {
  497. if err = tx.Create(newMatingList).Error; err != nil {
  498. return xerr.WithStack(err)
  499. }
  500. }
  501. // 创建冻精使用记录日志
  502. if err = tx.Create(itemFrozenSemenLog).Error; err != nil {
  503. return xerr.WithStack(err)
  504. }
  505. // 如果有同期牛只,则修改为已结束状态
  506. if err = tx.Model(new(model.CowSameTime)).
  507. Where("cow_id IN ?", cowIds).
  508. UpdateColumn("same_time_status", pasturePb.SameTimeStatus_End).Error; err != nil {
  509. return xerr.WithStack(err)
  510. }
  511. // 更新牛只的繁殖状态为配种
  512. if err = tx.Model(new(model.Cow)).
  513. Where("id IN ?", cowIds).
  514. Where("admission_status = ?", pasturePb.AdmissionStatus_Admission).
  515. Updates(map[string]interface{}{
  516. "breed_status": pasturePb.BreedStatus_Breeding,
  517. "last_bull_number": req.FrozenSemenNumber,
  518. "last_mating_at": int64(req.MatingAt),
  519. }).Error; err != nil {
  520. return xerr.WithStack(err)
  521. }
  522. // 减去精液的数量
  523. if err = tx.Model(frozenSemen).
  524. Where("id = ?", frozenSemen.Id).
  525. Where("quantity > 0").
  526. UpdateColumn("quantity",
  527. gorm.Expr("quantity - ?", req.FrozenSemenCount),
  528. ).Error; err != nil {
  529. return xerr.WithStack(err)
  530. }
  531. // 更新配次
  532. if len(matingTimes) > 0 {
  533. for _, mt := range matingTimes {
  534. if err = tx.Model(new(model.EventMating)).
  535. Where("id = ?", mt.EventMatingId).
  536. Update("mating_times", mt.Mt).Error; err != nil {
  537. return xerr.WithStack(err)
  538. }
  539. if err = tx.Model(new(model.Cow)).
  540. Where("id = ?", mt.CowId).
  541. Where("admission_status = ?", pasturePb.AdmissionStatus_Admission).
  542. Where("breed_status = ?", pasturePb.BreedStatus_Breeding).
  543. Update("mating_times", mt.Mt).Error; err != nil {
  544. return xerr.WithStack(err)
  545. }
  546. }
  547. }
  548. return nil
  549. }); err != nil {
  550. return xerr.WithStack(err)
  551. }
  552. return nil
  553. }
  554. func (s *StoreEntry) WeaningBatch(ctx context.Context, req *pasturePb.EventWeaningBatchRequest) error {
  555. if len(req.Item) <= 0 {
  556. return nil
  557. }
  558. cowIds := make([]int64, 0)
  559. cowWeightMap := make(map[int64]float64)
  560. for _, item := range req.Item {
  561. cowIds = append(cowIds, int64(item.CowId))
  562. cowWeightMap[int64(item.CowId)] = float64(item.Weight)
  563. }
  564. eventWeaningList := make([]*model.EventWeaning, 0)
  565. if err := s.DB.Model(new(model.EventWeaning)).
  566. Where("cow_id IN ?", cowIds).
  567. Where("status = ?", pasturePb.IsShow_No).
  568. Find(&eventWeaningList).Error; err != nil {
  569. return xerr.WithStack(err)
  570. }
  571. operation, err := s.GetSystemUserById(ctx, int64(req.OperationId))
  572. if err != nil {
  573. return xerr.WithStack(err)
  574. }
  575. currentUser, err := s.GetCurrentSystemUser(ctx)
  576. if err != nil {
  577. return xerr.WithStack(err)
  578. }
  579. if err = s.DB.Transaction(func(tx *gorm.DB) error {
  580. for _, v := range eventWeaningList {
  581. if err = tx.Model(new(model.EventWeaning)).Where("id = ?", v.Id).Updates(map[string]interface{}{
  582. "status": pasturePb.IsShow_Ok,
  583. "reality_day": int64(req.WeaningAt),
  584. "operation_id": req.OperationId,
  585. "operation_name": operation.Name,
  586. "message_id": currentUser.Id,
  587. "message_name": currentUser.Name,
  588. "remarks": req.Remarks,
  589. "after_pen_id": req.PenId,
  590. }).Error; err != nil {
  591. return xerr.WithStack(err)
  592. }
  593. if err = tx.Model(new(model.Cow)).Where("id = ?", v.CowId).Updates(map[string]interface{}{
  594. "pen_id": req.PenId,
  595. "current_weight": cowWeightMap[v.CowId],
  596. "weaning_at": req.WeaningAt,
  597. "last_weight_at": req.WeaningAt,
  598. }).Error; err != nil {
  599. return xerr.WithStack(err)
  600. }
  601. }
  602. return nil
  603. }); err != nil {
  604. return xerr.WithStack(err)
  605. }
  606. return nil
  607. }