/**
* @Author: zou.yingbin
* @Create  : 2021/1/5 15:15
* @Modify  : 2021/1/5 15:15
 */

// 企业风险管理
package models

import (
	"fmt"
	"mtp2_if/db"
	"mtp2_if/logger"
	"mtp2_if/mtpcache"
)

// 现货合同结构（对应现货合同菜单)
type ErmcpSpotContractModel struct {
	SPOTCONTRACTID    string  `json:"spotcontractid"  xorm:"'SPOTCONTRACTID'"`       //现货合同ID(602+Unix秒时间戳(10位)+xxxxxx)
	CONTRACTNO        string  `json:"contractno"  xorm:"'CONTRACTNO'"`               //现货合同编号
	CONTRACTTYPE      int32   `json:"contracttype"  xorm:"'CONTRACTTYPE'"`           //现货合同类型 - 1:采购 -1:销售
	USERID            int64   `json:"userid"  xorm:"'USERID'"`                       //机构ID
	BUYUSERID         int64   `json:"buyuserid"  xorm:"'BUYUSERID'"`                 //采购方ID
	BUYUSERName       string  `json:"buyusername"  xorm:"'BUYUSERName'"`             //采购方名称
	SELLUSERID        int64   `json:"selluserid"  xorm:"'SELLUSERID'"`               //销售方ID
	SELLUSERNAME      string  `json:"sellusername"  xorm:"'SELLUSERNAME'"`           //销售方名称
	DELIVERYGOODSID   int32   `json:"deliverygoodsid"  xorm:"'DELIVERYGOODSID'"`     //现货品种ID
	DELIVERYGOODSCODE string  `json:"deliverygoodscode"  xorm:"'DELIVERYGOODSCODE'"` //现货品种代码
	DELIVERYGOODSNAME string  `json:"deliverygoodsname"  xorm:"'DELIVERYGOODSNAME'"` //现货品种名称
	PRODUCTTYPE       int32   `json:"producttype"  xorm:"'PRODUCTTYPE'"`             //产品类型 - 1:标准仓单 2:等标 3:非标
	CONVERTFACTOR     float64 `json:"convertfactor"  xorm:"'CONVERTFACTOR'"`         //标仓系数
	SPOTGOODSDESC     string  `json:"spotgoodsdesc"  xorm:"'SPOTGOODSDESC'"`         //商品型号
	PRICETYPE         int32   `json:"pricetype"  xorm:"'PRICETYPE'"`                 //定价类型 - 1:一口价 2:点价 3:暂定价
	QTY               float64 `json:"qty"  xorm:"'QTY'"`                             //数量
	PRICE             float64 `json:"price"  xorm:"'PRICE'"`                         //价格\暂定价 [1:一口价、3:暂定价]
	AMOUNT            float64 `json:"amount"  xorm:"'AMOUNT'"`                       //金额 [1:一口价、3:暂定价]
	DELIVERYSTARTDATE string  `json:"deliverystartdate"  xorm:"'DELIVERYSTARTDATE'"` //交收期(开始)
	DELIVERYENDDATE   string  `json:"deliveryenddate"  xorm:"'DELIVERYENDDATE'"`     //交收期(结束)
	GOODSID           int32   `json:"goodsid"  xorm:"'GOODSID'"`                     //点价合约ID - 0:为现货，其它为期货商品合约ID [2:点价 3:暂定价]
	GOODSCODE         string  `json:"goodscode"  xorm:"'GOODSCODE'"`                 //点价合约代码
	PRICEMOVE         float64 `json:"pricemove"  xorm:"'PRICEMOVE'"`                 //升贴水 [2:点价 3:暂定价]
	STARTDATE         string  `json:"startdate"  xorm:"'STARTDATE'"`                 //点价开始日期 [2:点价 3:暂定价]
	ENDDATE           string  `json:"enddate"  xorm:"'ENDDATE'"`                     //点价结束日期 [2:点价 3:暂定价]
	MARGIN            float64 `json:"margin"  xorm:"'MARGIN'"`                       //当前保证金
	EnumdicName       string  `json:"enumdicname"  xorm:"'ENUMDICNAME'"`             //单位名称
	CONTRACCTSTATUS   int32   `json:"contracctstatus"  xorm:"'CONTRACTSTATUS'"`      //合同状态 - 0:未提交 1:待审核 2:执行中 3:正常完结 4:审核拒绝 5:异常完结 6:已撤回
	Remark            string  `json:"remark"  xorm:"'Remark'"`                       //备注
}

func (r *ErmcpSpotContractModel) buildSql(nQueryType int32) string {
	str := "SELECT to_char(t.SPOTCONTRACTID) SPOTCONTRACTID," +
		"       t.CONTRACTNO," +
		"       t.CONTRACTTYPE," +
		"       t.USERID," +
		"       t.BUYUSERID," +
		"       t.SELLUSERID," +
		"       t.DELIVERYGOODSID," +
		"       t.PRODUCTTYPE," +
		"       t.CONVERTFACTOR," +
		"       t.SPOTGOODSDESC," +
		"       t.PRICETYPE," +
		"       t.QTY," +
		"       t.PRICE," +
		"       t.AMOUNT," +
		"       to_char(t.DELIVERYSTARTDATE, 'yyyy-mm-dd hh24:mi:ss') DELIVERYSTARTDATE," +
		"       to_char(t.DELIVERYENDDATE,'yyyy-mm-dd hh24:mi:ss') DELIVERYENDDATE," +
		"       t.GOODSID," +
		"       t.PRICEMOVE," +
		"       to_char(t.STARTDATE, 'yyyy-mm-dd hh24:mi:ss') STARTDATE," +
		"       to_char(t.ENDDATE,'yyyy-mm-dd hh24:mi:ss') ENDDATE," +
		"       t.MARGIN," +
		"       t.remark," +
		"       t.contractstatus," +
		"       u1.accountname      BuyUserName," +
		"       u2.accountname      SellUserName," +
		"       g.deliverygoodscode," +
		"       g.deliverygoodsname," +
		"       g2.goodscode," +
		"       e.Enumdicname" +
		"  FROM ERMCP_SPOTCONTRACT t" +
		"  left join useraccount u1" +
		"    on t.buyuserid = u1.userid" +
		"  left join useraccount u2" +
		"    on t.selluserid = u2.userid" +
		"  left join deliverygoods g" +
		"    on t.deliverygoodsid = g.deliverygoodsid" +
		"  left join goods g2" +
		"    on t.goodsid = g2.goodsid" +
		"  left join enumdicitem e on g.goodsunitid = e.enumitemname and e.enumdiccode = 'goodsunit'" +
		"  where t.contractstatus in (%v) and t.userid=%v"

	// 查询类型 1-未提交 2-待审核 3-履约中 4-已完成
	// 合同状态 - 0:未提交 1:待审核 2:执行中 3:正常完结 4:审核拒绝 5:异常完结 6:已撤回
	var status string
	switch nQueryType {
	case 1:
		status = "0"
	case 2:
		status = "1"
	case 3:
		status = "2"
	case 4:
		status = "3,5,6"
	}

	return fmt.Sprintf(str, status, r.USERID)
}

// 从数据库中查询现货合同
func (r *ErmcpSpotContractModel) GetData(nQueryType int32) ([]ErmcpSpotContractModel, error) {
	sData := make([]ErmcpSpotContractModel, 0)
	e := db.GetEngine()
	s := e.SQL(r.buildSql(nQueryType))
	if err := s.Find(&sData); err != nil {
		logger.GetLogger().Errorf("ermcp query fail:%v", err)
		return sData, err
	}
	return sData, nil
}

// 风险管理合同(对应采购和销售菜单)
type ErmcpModel struct {
	UserID             int64   `json:"userid"  xorm:"'UserID'"`                         // 用户ID
	SpotContractId     string  `json:"spotcontractid"  xorm:"'SPOTCONTRACTID'"`         // 合同ID
	AccountId          string  `json:"accountid"  xorm:"'ACCOUNTID'"`                   // 账户ID
	AccountName        string  `json:"accountname"  xorm:"'ACCOUNTNAME'"`               // 账户名称
	DeliveryGoodsId    int     `json:"deliverygoodsid"  xorm:"'DELIVERYGOODSID'"`       // 现货商品ID
	DeliveryGoodsCode  string  `json:"deliverygoodscode"  xorm:"'DELIVERYGOODSCODE'"`   // 现货商品代码
	DeliveryGoodsName  string  `json:"deliverygoodsname"  xorm:"'DELIVERYGOODSNAME'"`   // 现货商品名称
	SpotGoodsdesc      string  `json:"spotgoodsdesc"  xorm:"'SPOTGOODSDESC'"`           // 商品型号(商品规格)
	GoodsId            int     `json:"goodsid"  xorm:"'GOODSID'"`                       // 点价商品ID
	Goodscode          string  `json:"goodscode"  xorm:"'GOODSCODE'"`                   // 点价商品代码
	Pricemove          float64 `json:"pricemove"  xorm:"'PRICEMOVE'"`                   // 升贴水
	Qty                float64 `json:"qty"  xorm:"'QTY'"`                               // 合同量
	UnpricedQty        float64 `json:"unpricedqty"  xorm:"'UNPRICEDQTY'"`               // 未定价量
	PricedQty          float64 `json:"pricedqty"  xorm:"'PRICEDQTY'"`                   // 已定价量
	UnsureQty          float64 `json:"unsureqty"  xorm:"'UNSUREQTY'"`                   // 未确定量
	PayAmount          float64 `json:"payamount"  xorm:"'PAYAMOUNT'"`                   // 已收付额(收款或付款)
	UnpayAmount        float64 `json:"unpayamount"  xorm:"'UNPAYAMOUNT'"`               // 待支收额(支付或收款)
	InvoiceAmount      float64 `json:"invoiceamount"  xorm:"'INVOICEAMOUNT'"`           // 已开票额
	DaikaiAmount       float64 `json:"daikaiamount"  xorm:"'DAIKAIAMOUNT'"`             // 待开票额
	StartDate          string  `json:"startdate"  xorm:"'STARTDATE'"`                   // 点价开始日
	EndDate            string  `json:"enddate"  xorm:"'ENDDATE'"`                       // 点价结束日
	DeliveryStartDate  string  `json:"deliverystartdate"  xorm:"'DELIVERYSTARTDATE'"`   // 交割开始日
	DeliveryendDate    string  `json:"deliveryenddate"  xorm:"'DELIVERYENDDATE'"`       // 交割结束日
	Convertfactor      float64 `json:"convertfactor"  xorm:"'CONVERTFACTOR'"`           // 标仓系数
	EnumdicName        string  `json:"enumdicname"  xorm:"'ENUMDICNAME'"`               // 单位名称
	Contracctstatus    uint    `json:"contracctstatus"  xorm:"'CONTRACTSTATUS'"`        // 合同状态- 0:未提交 1:待审核 2:执行中 3:正常完结 4:审核拒绝 5:异常完结 6:已撤回
	PriceType          int     `json:"pricetype"  xorm:"'PRICETYPE'"`                   // 定价类型 - 1:一口价 2:点价 3:暂定价
	ProductType        int     `json:"producttype"  xorm:"'PRODUCTTYPE'"`               // 产品类型 - 1:标准仓单 2:等标 3:非标
	Contracttype       int32   `json:"contracttype"  xorm:"'CONTRACTTYPE'"`             // 合同类型 1-采购, -1-销售
	Pricedamount       float64 `json:"pricedamount"  xorm:"'PRICEDAMOUNT'"`             // 已定价额
	PricedAvg          float64 `json:"pricedavg"  xorm:"'PRICEDAVG'"`                   // 已点均价
	Margin             float64 `json:"margin"  xorm:"'MARGIN'"`                         // 保证金
	Remark             string  `json:"remark"  xorm:"'Remark'"`                         // 备注
	ReckonRealQty      float64 `json:"reckonrealqty"  xorm:"'ReckonRealQty'"`           // 已确定量
	ReckonOtherAmount  float64 `json:"reckonotheramount"  xorm:"'ReckonOtherAmount'"`   // 其它费用
	ReckonAdjustAmount float64 `json:"reckonadjustamount"  xorm:"'ReckonAdjustAmount'"` // 调整金额
	Price              float64 `json:"price"  xorm:"'Price'"`                           // 价格
	LoanAmount         float64 `json:"loanamount"  xorm:"'LoanAmount'"`                 // 贷款总额=已定价额+调整金额
	Contractno         string  `json:"contractno"  xorm:"'Contractno'"`                 // 合同编号
	TotalAmount        float64 `json:"totalamount"  xorm:"'-'"`                         // 合计总额
	ReckonedAmount     float64 `json:"reckonedamount"  xorm:"'ReckonedAmount'"`         // 已收付额(已确定额)
	BUYUSERID          int64   `json:"-"  xorm:"'BUYUSERID'"`                           //采购方ID
	SELLUSERID         int64   `json:"-"  xorm:"'SELLUSERID'"`                          //销售方ID
}

func (r *ErmcpModel) calc() {
	r.TotalAmount = r.LoanAmount + r.ReckonOtherAmount - r.ReckonedAmount
	if r.Contracttype == 1 {
		//采购合同, 取销售方名称
		r.AccountName = mtpcache.GetUserNameByUserId(r.SELLUSERID)
	} else {
		//销售合同, 取采购方名称
		r.AccountName = mtpcache.GetUserNameByUserId(r.BUYUSERID)
	}
}

// 组装查询的sql
func (r *ErmcpModel) buildSql(nContractType, nQueryType int32) string {
	str := "select t.contractno," +
		"       to_char(t.SpotContractId) SpotContractId," +
		"       t.deliverygoodsid," +
		"       t.spotgoodsdesc," +
		"       t.goodsid," +
		"       t.pricemove," +
		"       t.userid," +
		"       t.BUYUSERID," +
		"       t.SELLUSERID," +
		"       t.qty," +
		"       t.qty - t.pricedqty unpricedqty," +
		"       t.pricedqty," +
		"       (case" +
		"         when t.pricetype = 3 then" +
		"          t.qty - t.RECKONREALQTY" +
		"         else" +
		"          t.qty - t.pricedqty" +
		"       end) unsureqty," +
		"       t.reckonedamount PayAmount," +
		"       t.pricedamount + t.reckonadjustamount - t.RECKONEDAMOUNT unpayAmount," +
		"       t.invoiceamount," +
		"       (t.pricedamount + t.RECKONADJUSTAMOUNT + t.RECKONOTHERAMOUNT -" +
		"       t.invoiceamount) as daikaiAmount," +
		"       to_char(t.startdate, 'yyyy-mm-dd hh24:mi:ss') startdate," +
		"       to_char(t.enddate, 'yyyy-mm-dd hh24:mi:ss') enddate," +
		"       to_char(t.deliverystartdate, 'yyyy-mm-dd hh24:mi:ss') deliverystartdate," +
		"       to_char(t.deliveryenddate, 'yyyy-mm-dd hh24:mi:ss') deliveryenddate," +
		"       t.convertfactor," +
		"       t.contractstatus," +
		"       t.pricetype," +
		"       t.producttype," +
		"       t.contracttype," +
		"       t.remark," +
		"       t.margin," +
		"       to_char(ta.accountid) accountid," +
		"       ta.accountname," +
		"       g.deliverygoodscode," +
		"       g.deliverygoodsname," +
		"       g2.goodscode," +
		"       e.enumdicname," +
		"       t.contracttype," +
		"       t.pricedamount," +
		"       case when t.pricedqty > 0 then t.pricedamount/t.pricedqty else 0 end pricedAvg," +
		"       t.ReckonRealQty," +
		"       t.ReckonOtherAmount," +
		"       t.ReckonAdjustAmount," +
		"       t.Price," +
		"       t.ReckonedAmount," +
		"       t.pricedamount + t.ReckonAdjustAmount as LoanAmount" +
		"  from ermcp_spotcontract t" +
		"  left join taaccount ta" +
		"    on t.%v = ta.userid" +
		"  left join deliverygoods g" +
		"    on t.deliverygoodsid = g.deliverygoodsid" +
		"  left join goods g2" +
		"    on t.goodsid = g2.goodsid" +
		"  left join wrstandard wr" +
		"    on t.wrstandardid = wr.wrstandardid" +
		"  left join enumdicitem e" +
		"    on wr.unitid = e.enumitemname" +
		"   and e.enumdiccode = 'goodsunit'" +
		" where t.contractstatus in (%v)" +
		"   and t.contracttype in (%v) and t.userid=%v"

	var status string
	if 1 == nQueryType {
		// 全部
		status = "0,1,2,3,4,5,6"
		str = str + " order by t.audittime desc"
	} else if 2 == nQueryType {
		// 待点价
		status = "2"
		str = str + "  and t.qty - t.pricedqty > 0 " +
			"order by unpricedqty, t.audittime desc"
	} else {
		// 履约
		status = "2"
		str = str + " order by t.audittime desc"
	}

	var usrId string

	switch nContractType {
	case 1: // 采购
		usrId = "buyuserid"
	case -1: // 销售
		usrId = "selluserid"
	}

	sqlId := fmt.Sprintf(str, usrId, status, nContractType, r.UserID)

	return sqlId
}

// 从数据库中查询合同
func (r *ErmcpModel) GetData(contractType, nQueryType int32) ([]ErmcpModel, error) {
	sData := make([]ErmcpModel, 0)
	e := db.GetEngine()
	s := e.SQL(r.buildSql(contractType, nQueryType))
	if err := s.Find(&sData); err != nil {
		logger.GetLogger().Errorf("ermcp query fail:%v", err)
		return sData, err
	}
	for i := range sData {
		sData[i].calc()
	}
	return sData, nil
}
