ermcpExposure.go 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /**
  2. * @Author: zou.yingbin
  3. * @Create : 2021/1/18 9:26
  4. * @Modify : 2021/1/18 9:26
  5. */
  6. package models
  7. import (
  8. "fmt"
  9. "github.com/golang/protobuf/proto"
  10. "mtp2_if/db"
  11. "mtp2_if/mtpcache"
  12. "mtp2_if/pb"
  13. "mtp2_if/rediscli"
  14. )
  15. //实时敞口
  16. type ErmcpRealExposureModel struct {
  17. MiddleGoodsID uint32 // 套保品种
  18. AreaUserID uint32 // 所属机构
  19. OriBuyPlanQty float64 // 期初采购计划数量
  20. OriBuyPricedQty float64 // 期初采购合同已定价数量
  21. OriSellPlanQty float64 // 期初销售计划数量
  22. OriSellPricedQty float64 // 期初销售合同已定价数量
  23. OriBuyFutureQty uint64 // 期初买入期货数量
  24. OriSellFutureQty uint64 // 期初卖出期货数量
  25. BuyPlanQty float64 // 采购计划数量
  26. BuyPricedQty float64 // 采购合同已定价数量
  27. SellPlanQty float64 // 销售计划数量
  28. SellPricedQty float64 // 销售合同已定价数量
  29. BuyFutureQty float64 // 买入期货数量
  30. SellFutureQty float64 // 卖出期货数量
  31. TotalSpotQty float64 // 现货数量
  32. TotalFutureQty float64 // 期货数量
  33. TotalExposure float64 // 总敞口
  34. TotalHedgeRatio float64 // 敞口比例
  35. TotalNeedHedgeQty float64 // 期货应套保量
  36. NeedHedgeExposoure float64 // 应套保敞口
  37. NeedHedgeRatio float64 // 应套保敞口比例
  38. //************以下需计算或非redis数据************//
  39. MiddleGoodsName string // 套保品种名称
  40. MiddleGoodsCode string // 套保品种代码
  41. MiddleGoodsHedgeRatio float64 // 应套保比例
  42. OriTotalSpotQty float64 // 期初现货数量=(期初销售计划数量-期初销售合同已定价数量)-(期初采购计划数量-期初采购合同已定价数量)
  43. OriTotalFutuQty uint64 // 期初期货数量=期初买入期货数量-期初卖出期货数量
  44. }
  45. // 计算相关字段
  46. func (r *ErmcpRealExposureModel) calc() {
  47. r.OriTotalSpotQty = (r.OriSellPlanQty - r.OriSellPricedQty) - (r.OriBuyPlanQty - r.OriBuyPricedQty)
  48. r.OriTotalFutuQty = r.OriBuyFutureQty - r.OriSellFutureQty
  49. }
  50. func (r *ErmcpRealExposureModel) ParseFromProto(v *pb.ErmcpAreaExposure) {
  51. r.MiddleGoodsID = *v.MiddleGoodsID
  52. r.AreaUserID = *v.AreaUserID
  53. r.OriBuyPlanQty = *v.OriBuyPlanQty
  54. r.OriBuyPricedQty = *v.OriBuyPricedQty
  55. r.OriSellPlanQty = *v.OriSellPlanQty
  56. r.OriSellPricedQty = *v.OriSellPricedQty
  57. r.OriBuyFutureQty = *v.OriBuyFutureQty
  58. r.OriSellFutureQty = *v.OriSellFutureQty
  59. r.BuyPlanQty = *v.BuyPlanQty
  60. r.BuyPricedQty = *v.BuyPricedQty
  61. r.SellPlanQty = *v.SellPlanQty
  62. r.SellPricedQty = *v.SellPricedQty
  63. r.BuyFutureQty = *v.BuyFutureQty
  64. r.SellFutureQty = *v.SellFutureQty
  65. r.TotalSpotQty = *v.TotalSpotQty
  66. r.TotalFutureQty = *v.TotalFutureQty
  67. r.TotalExposure = *v.TotalExposure
  68. r.TotalHedgeRatio = *v.TotalHedgeRatio
  69. r.TotalNeedHedgeQty = *v.TotalNeedHedgeQty
  70. r.NeedHedgeExposoure = *v.NeedHedgeExposoure
  71. r.NeedHedgeRatio = *v.NeedHedgeRatio
  72. // 执行相关计算
  73. r.calc()
  74. }
  75. // 实时敞口数据: Redis数据 + 套保品种信息表
  76. func (r *ErmcpRealExposureModel) GetData() ([]ErmcpRealExposureModel, error) {
  77. // 获取关联的套路商品
  78. if sGoods, err := mtpcache.GetMiddleGoodsByUserID(r.AreaUserID); err == nil {
  79. sData := make([]ErmcpRealExposureModel, 0)
  80. // 从Redis获取数据
  81. for i := range sGoods {
  82. key := fmt.Sprintf("ErmcpAreaExposure:%d_%d", sGoods[i].AREAUSERID, sGoods[i].MIDDLEGOODSID)
  83. if ret, err := rediscli.GetRedisClient().Get(key).Result(); err == nil {
  84. if len(ret) > 0 {
  85. var data pb.ErmcpAreaExposure
  86. if err := proto.Unmarshal([]byte(ret), &data); err == nil {
  87. var m ErmcpRealExposureModel
  88. m.ParseFromProto(&data)
  89. sData = append(sData, m)
  90. }
  91. }
  92. }
  93. }
  94. return sData, nil
  95. }
  96. return nil, nil
  97. }
  98. /*************敞口明细**************/
  99. //敞口明细结构
  100. type ErmcpExposureDetailModel struct {
  101. Createtime string `json:"createtime" xorm:"'createtime'"` // 时间
  102. Areauserid uint32 `json:"areauserid" xorm:"'areauserid'"` // 机构ID
  103. Logtype int32 `json:"logtype" xorm:"'logtype'"` // 类型 - 1:套保计划 2:现货合同
  104. Contracttype int32 `json:"contracttype" xorm:"'contracttype'"` // 现货合同类型 - 1:采购 -1:销售
  105. Wrstandardid int32 `json:"wrstandardid" xorm:"'wrstandardid'"` // 现货商品ID
  106. Qty float64 `json:"qty" xorm:"'qty'"` // 数量
  107. RelateNo string `json:"relateNo" xorm:"'relateNo'"` // 现货合同/套保计划编号
  108. Middlegoodsname string `json:"middlegoodsname" xorm:"'middlegoodsname'"` // 套保商品名称
  109. Middlegoodscode string `json:"middlegoodscode" xorm:"'middlegoodscode'"` // 套保商品代码
  110. MiddlegoodsId int32 `json:"middlegoodsId" xorm:"'middlegoodsId'"` // 套保商品id
  111. Unitid int32 `json:"-" xorm:"'unitid'"` // 现货商品单位ID
  112. Wrstandardname string `json:"wrstandardname" xorm:"'wrstandardname'"` // 现货商品名称
  113. Wrstandardcode string `json:"wrstandardcode" xorm:"'wrstandardcode'"` // 现货商品代码
  114. Enumdicname string `json:"enumdicname" xorm:"'enumdicname'"` // 现货商品单位名称
  115. ChangeQty float64 `json:"changeQty" xorm:"'changeQty'"` // 套保变动量
  116. Convertfactor float64 `json:"convertfactor" xorm:"'convertfactor'"` // 标仓系数
  117. Convertratio float64 `json:"convertratio" xorm:"'convertratio'"` // 套保系数
  118. }
  119. func (r *ErmcpExposureDetailModel) buildSql() string {
  120. str := "with tmp as" +
  121. " (select 2 as LogType," +
  122. " s.spotcontractid as relatedid," +
  123. " s.contractno as relateNo" +
  124. " from ermcp_spotcontract s" +
  125. " union all" +
  126. " select 1, t.hedgeplanid as relateid, t.hedgeplanno as relateNo" +
  127. " from ermcp_hedgeplan t)" +
  128. "select to_char(t.createtime, 'yyyy-mm-dd hh:mi:ss') createtime," +
  129. " t.middlegoodsid," +
  130. " t.areauserid," +
  131. " t.logtype," +
  132. " t.contracttype," +
  133. " wc.wrstandardid," +
  134. " t.qty," +
  135. " t.convertfactor," +
  136. " t.convertratio," +
  137. " t.qty * t.convertfactor * t.convertratio as changeQty," +
  138. " tmp.relateNo," +
  139. " m.middlegoodsname," +
  140. " m.middlegoodscode," +
  141. " w.unitid," +
  142. " w.wrstandardname," +
  143. " w.wrstandardcode," +
  144. " e.enumdicname" +
  145. " from ermcp_spotexposurelog t" +
  146. " left join erms2_wrsconvertdetail wc" +
  147. " on t.wrstandardid = wc.wrstandardid" +
  148. " and t.middlegoodsid = wc.middlegoodsid" +
  149. " left join erms_middlegoods m" +
  150. " on t.middlegoodsid = m.middlegoodsid" +
  151. " left join wrstandard w" +
  152. " on t.wrstandardid = w.wrstandardid" +
  153. " left join enumdicitem e" +
  154. " on w.unitid = e.enumitemname" +
  155. " and e.enumdiccode = 'goodsunit'" +
  156. " left join tmp" +
  157. " on t.logtype = tmp.LogType" +
  158. " and t.relatedid = tmp.relatedid" +
  159. " where t.middlegoodsid=%v and t.areauserid=%v"
  160. return fmt.Sprintf(str, r.MiddlegoodsId, r.Areauserid)
  161. }
  162. // 查询敞口现货明细
  163. func (r *ErmcpExposureDetailModel) GetData() ([]ErmcpExposureDetailModel, error) {
  164. e := db.GetEngine()
  165. s := e.SQL(r.buildSql())
  166. sData := make([]ErmcpExposureDetailModel, 0)
  167. if err := s.Find(&sData); err != nil {
  168. return nil, err
  169. }
  170. return sData, nil
  171. }