package erms3 import ( "encoding/json" "math" "mtp2_if/db" "mtp2_if/global/app" "mtp2_if/global/e" "mtp2_if/logger" "mtp2_if/models" "net/http" "time" "github.com/gin-gonic/gin" ) // RecordUtcCount UTC计数(毫秒) var RecordUtcCount int = 0 // SecondCount 秒计数 var SecondCount int = 0 // SpotPriceOrder 定价明细 type SpotPriceOrder struct { Price float64 `json:"price" binding:"required"` // 价格 Qty float64 `json:"qty" binding:"required"` // 数量 Amount float64 `json:"amount" binding:"required"` // 金额 } // SpotPointOrder 点价明细 type SpotPointOrder struct { GoodsID int32 `json:"goodsid" binding:"required"` // 商品ID GoodsName string `json:"goodsname"` // 商品名称 Qty float64 `json:"qty" binding:"required"` // 数量 Basic float64 `json:"basic" binding:"required"` // 基差 StartDate string `json:"startdate" binding:"required"` // 点价开始日期 EndDate string `json:"enddate" binding:"required"` // 点价结束日期 } // SoptContractDetail 合同明细信息 type SoptContractDetail struct { WrStandardID int64 `json:"wrstandardid" binding:"required"` // 交易标的ID WrStandardName string `json:"wrstandardname" binding:"required"` // 交易标的名称 ProductType int32 `json:"producttype" binding:"required"` // 产品类型 1:标准仓单 2:等标 3:非标 ProductTypeName string `json:"producttypename"` // 产品类型名称 DeliveryGoodsID int32 `json:"deliverygoodsid" binding:"required"` // 现货品种ID DeliveryGoodsName string `json:"deliverygoodsname"` // 现货品种名称 DeliveryGoodsDesc string `json:"deliverygoodsdesc"` // 现货品种说明 WarehouseID int32 `json:"warehouseid" binding:"required"` // 仓库ID WarehouseName int32 `json:"warehousename"` // 仓库名称 UnitName string `json:"unitname" binding:"required"` // 单位名称 PointDesc string `json:"pointdesc"` // 点价描述 SpotPriceOrderList []SpotPriceOrder `json:"spotPriceOrderList"` // 定价列表 SpotPointOrderVoList []SpotPointOrder `json:"spotPointOrderVoList"` // 点价列表 } // SoptContractDetailSum 合同明细信息汇总(组织JSON使用) type SoptContractDetailSum struct { WrStandardID int64 `json:"wrstandardid" binding:"required"` // 交易标的ID WrStandardName string `json:"wrstandardname" binding:"required"` // 交易标的名称 ProductType int32 `json:"producttype" binding:"required"` // 产品类型 1:标准仓单 2:等标 3:非标 ProductTypeName string `json:"producttypename"` // 产品类型名称 DeliveryGoodsID int32 `json:"deliverygoodsid" binding:"required"` // 现货品种ID DeliveryGoodsName string `json:"deliverygoodsname"` // 现货品种名称 DeliveryGoodsDesc string `json:"deliverygoodsdesc"` // 现货品种说明 WarehouseID int32 `json:"warehouseid" binding:"required"` // 仓库ID WarehouseName int32 `json:"warehousename"` // 仓库名称 UnitName string `json:"unitname" binding:"required"` // 单位名称 PointDesc string `json:"pointdesc"` // 点价描述 SpotPriceOrderList []SpotPriceOrder `json:"spotPriceOrderList"` // 定价列表 SpotPointOrderVoList []SpotPointOrder `json:"spotPointOrderVoList"` // 点价列表 TotalPriceOrderQty float64 `json:"totalPriceOrderQty"` // 定价总数量 TotalPriceOrderPrice float64 `json:"totalPriceOrderPrice"` // 定价总价格 TotalPriceOrderAmount float64 `json:"totalPriceOrderAmount"` // 定价总金额 TotalPointOrderQty float64 `json:"totalPointOrderQty"` // 点价总数量 TotalQty float64 `json:"totalQty"` // 总数量 } // AddSpotContractApplyReq 新增现货合同申请请求 type AddSpotContractApplyReq struct { ContractNo string `json:"contractno" binding:"required"` // 现货合同编号 ContractType int32 `json:"contracttype" binding:"required"` // 现货合同类型 - 1:采购 -1:销售 AreaUserID int32 `json:"areauserid" binding:"required"` // 所属机构 AccountID int64 `json:"accountid" binding:"required"` // 资金账户ID CustomerUserID int32 `json:"customeruserid" binding:"required"` // 客户ID CustomerAccountID int64 `json:"customeraccountid" binding:"required"` // 客户资金账户ID SignDate time.Time `json:"signdate" binding:"required"` // 签订日期 LastDate time.Time `json:"lastdate" binding:"required"` // 交货时间 ContractAttachment string `json:"contractattachment"` // 合同附件 OriMarginPayer int32 `json:"orimarginpayer" binding:"required"` // 初始保证金支付方 -1:买方 2:卖方 OriMargin float64 `json:"orimargin" binding:"required"` // 初始保证金 Remark string `json:"remark"` // 备注 MarketID int32 `json:"marketid" binding:"required"` // 市场ID CreatorID int32 `json:"creatorid"` // 申请人 Details []SoptContractDetail `json:"details" binding:"required"` // 明细 } // AddSpotContractApplyRsp 新增现货合同申请响应 type AddSpotContractApplyRsp struct { SpotContractID int64 `json:"spotcontractid" binging:"required"` // 现货合同ID(345+Unix秒时间戳(10位)+xxxxxx) ContractNo string `json:"contractno" binding:"required""` // 现货合同编号 } // AddSpotContractApply 新增现货合同申请 // @Summary 新增现货合同申请 // @Produce json // @Security ApiKeyAuth // @Param contractno query string true "现货合同编号" // @Param contracttype query int true "现货合同类型, 1:采购 -1:销售" // @Param areauserid query int true "所属机构" // @Param accountid query int true "资金账户ID" // @Param customeruserid query int true "客户ID" // @Param customeraccountid query int true "客户资金账户ID" // @Param signdate query string true "签订日期, 格式:yyyy-MM-dd HH:mm:ss" // @Param lastdate query string true "交货时间, 格式:yyyy-MM-dd HH:mm:ss" // @Param contractattachment query string true "合同附件" // @Param orimarginpayer query int true "初始保证金支付方, 1:买方 2:卖方" // @Param orimargin query float true "初始保证金" // @Param remark query string true "备注" // @Param marketid query int true "市场ID" // @Param creatorid query int true "申请人" // @Param details query []SoptContractDetail true "明细" // @Success 200 {object} AddSpotContractApplyRsp // @Failure 500 {object} app.Response // @Router /Erms3/AddSpotContractApply [post] // @Tags 风险管理 func AddSpotContractApply(c *gin.Context) { appG := app.Gin{C: c} // 获取请求参数 var req AddSpotContractApplyReq err := appG.C.ShouldBindQuery(&req) if err != nil { logger.GetLogger().Errorf("AddSpotContractApply failed: %s", err.Error()) appG.Response(http.StatusBadRequest, e.INVALID_PARAMS, nil) return } // 生成申请ID spotcontractid := GenSpotContractID() // 获取当前交易日 tradedate, err := GetMarketTradeDate(int(req.MarketID)) if err != nil { // 返回失败 logger.GetLogger().Errorf("AddSpotContractApply get market trade date failed: %s", err.Error()) appG.Response(http.StatusBadRequest, e.ERROR_OPERATION_FAILED, nil) return } // 根据明细,生成JSON信息 detailjson, err := BuildDetailJSON(req.Details) if err != nil { // 返回失败 logger.GetLogger().Errorf("AddSpotContractApply build detail json failed: %s", err.Error()) appG.Response(http.StatusBadRequest, e.ERROR_OPERATION_FAILED, nil) return } // 组织sql,插入现货合同申请信息 sql := `INSERT INTO ERMS3_SPOTCONTRACTAPPLY(SPOTCONTRACTID, TRADEDATE, CONTRACTNO, CONTRACTTYPE, AREAUSERID, ACCOUNTID, CUSTOMERUSERID, CUSTOMERACCOUNTID, SIGNDATE, LASTDATE, CONTRACTATTACHMENT, ORIMARGINPAYER, ORIMARGIN, REMARK, DETAILJSON, APPLYSTATUS, APPLYSRC, MARKETID, CREATORID, CREATETIME) VALUES( ?, ?, ?, ?, ?, ?, ?, ?, to_date(?, 'YYYY-MM-DD HH24:MI:SS'), to_date(?, 'YYYY-MM-DD HH24:MI:SS'), ?, ?, ?, ?, ?, 0, 2, ?, ?, sysdate)` engine := db.GetEngine() if _, err := engine.Exec(sql, spotcontractid, tradedate, req.ContractNo, req.ContractType, req.AreaUserID, req.AccountID, req.CustomerUserID, req.CustomerAccountID, req.SignDate, req.LastDate, req.ContractAttachment, req.OriMarginPayer, req.OriMargin, req.Remark, detailjson, req.MarketID, req.CreatorID); err != nil { // 插入失败 logger.GetLogger().Errorf("AddSpotContractApply failed: %s", err.Error()) appG.Response(http.StatusBadRequest, e.ERROR_OPERATION_FAILED, nil) return } rsp := AddSpotContractApplyRsp{ SpotContractID: spotcontractid, ContractNo: req.ContractNo, } // 查询成功 logger.GetLogger().Debugln("AddSpotContractApply successed: %v", rsp) appG.Response(http.StatusOK, e.SUCCESS, rsp) } // GenSpotContractID 生成现货合同ID func GenSpotContractID() int64 { // 获取当前时间 cur := time.Now() // UnitNano获取的是纳秒,除以1000000获取毫秒级的时间戳 timestamp := cur.UnixNano() / 1000000 // 除以1000获取秒级的时间戳 var curutc int = int(timestamp / 1000) if RecordUtcCount == curutc { SecondCount = SecondCount + 1 } else { RecordUtcCount = curutc SecondCount = 1 } var id int64 = int64(345)*int64(math.Pow(10, 16)) + int64(RecordUtcCount)*int64(math.Pow(10, 6)) + int64(SecondCount) return id } // GetMarketTradeDate 获取市场交易日 func GetMarketTradeDate(marketid int) (string, error) { marketrun, err := models.GetMarketRun(marketid) if err != nil { return "", err } return marketrun.Tradedate, nil } // BuildDetailJSON 组件合同明细JSON func BuildDetailJSON(details []SoptContractDetail) (string, error) { detailsums := make([]SoptContractDetailSum, 0) for _, detail := range details { var totalpriceorderqty float64 = 0 var totalpriceorderprice float64 = 0 var totalpriceorderamount float64 = 0 var totalpointorderqty float64 = 0 var totalqty float64 = 0 for _, spotpriceorder := range detail.SpotPriceOrderList { totalpriceorderqty = totalpriceorderqty + spotpriceorder.Qty totalpriceorderprice = totalpriceorderprice + spotpriceorder.Price totalpriceorderamount = totalpriceorderamount + spotpriceorder.Amount } for _, spotpointorder := range detail.SpotPointOrderVoList { totalpointorderqty = totalpointorderqty + spotpointorder.Qty } totalqty = totalpriceorderqty + totalpointorderqty var detailsum SoptContractDetailSum detailsum = SoptContractDetailSum{ WrStandardID: detail.WrStandardID, WrStandardName: detail.WrStandardName, ProductType: detail.ProductType, ProductTypeName: detail.ProductTypeName, DeliveryGoodsID: detail.DeliveryGoodsID, DeliveryGoodsName: detail.DeliveryGoodsName, DeliveryGoodsDesc: detail.DeliveryGoodsDesc, WarehouseID: detail.WarehouseID, WarehouseName: detail.WarehouseName, UnitName: detail.UnitName, PointDesc: detail.PointDesc, SpotPriceOrderList: detail.SpotPriceOrderList, SpotPointOrderVoList: detail.SpotPointOrderVoList, TotalPriceOrderQty: totalpriceorderqty, TotalPriceOrderPrice: totalpriceorderprice, TotalPriceOrderAmount: totalpriceorderamount, TotalPointOrderQty: totalpointorderqty, TotalQty: totalqty, } detailsums = append(detailsums, detailsum) } jsoninfo, err := json.Marshal(detailsums) if err != nil { return "", err } return string(jsoninfo), nil }