package contract import ( "github.com/beego/beego/v2/client/orm" "hongze/hz_crm_api/utils" "time" ) // 合同审批单 type ContractApproval struct { ContractApprovalId int `orm:"column(contract_approval_id);pk"` ApprovalType string `description:"审批单类型,枚举值,合同:contract;用印:sale;默认:contract"` ContractId int `orm:"column(contract_id)" description:"合同id"` Status string `description:"审批单状态,枚举值:待审批','已审批','已驳回','已撤回',默认待审批"` ApplyContent string `description:"待审内容,长度255位"` ContractDetail string `description:"审批单详情,完整的合同json数据"` ApplyUserId int `description:"申请人id"` ApplyUserName string `description:"申请人名称"` ApproveRemark string `description:"审批人备注,可以是驳回理由,长度128位"` FlowId int `description:"审批流程id"` FlowVersion int `description:"审批流程版本"` CurrNodeId int `description:"当前审批节点id"` StartNodeId int `description:"开始审批节点id"` ModifyTime time.Time `description:"发起申请时间"` CreateTime time.Time `description:"最近一次审批单修改时间"` } // 根据合同审批单id获取合同审批单信息 func GetContractApprovalById(contractApprovalId int) (contractApprovalInfo *ContractApproval, err error) { o := orm.NewOrm() sql := `select * from contract_approval where contract_approval_id = ? ` err = o.Raw(sql, contractApprovalId).QueryRow(&contractApprovalInfo) return } // 根据合同id获取最近一次待审批的合同审批单信息 func GetLastPendingContractApprovalByContractId(contractId int, approvalType string) (contractApprovalInfo *ContractApproval, err error) { o := orm.NewOrm() sql := `select * from contract_approval where status = "待审批" AND contract_id=? AND approval_type=?` err = o.Raw(sql, contractId, approvalType).QueryRow(&contractApprovalInfo) return } // 根据合同id获取最近一次提交的合同审批单信息 func GetLastContractApprovalByContractId(contractId int, approvalType string) (contractApprovalInfo *ContractApproval, err error) { o := orm.NewOrm() sql := `select * from contract_approval where contract_id=? and approval_type =? order by contract_approval_id desc` err = o.Raw(sql, contractId, approvalType).QueryRow(&contractApprovalInfo) return } // GetRejectContractCountByContractId 根据合同id获取总共被驳回的次数 func GetRejectContractCountByContractId(contractId int, approvalType string) (total int64, err error) { o := orm.NewOrm() sql := `select count(1) total from contract_approval where status = "已驳回" AND contract_id=? and approval_type =? ` err = o.Raw(sql, contractId, approvalType).QueryRow(&total) return } // GetLastContractApprovalByContractIdAndStatus 根据合同id获取最近已驳回、已审批的审批单 func GetLastContractApprovalByContractIdAndStatus(contractId int, approvalType string) (item *ContractApproval, err error) { o := orm.NewOrm() sql := `select * from contract_approval where status in ("已驳回","已审批") AND contract_id=? and approval_type =? order by contract_approval_id desc` err = o.Raw(sql, contractId, approvalType).QueryRow(&item) return } // 获取审批列表数据数量 func GetContractApprovalListCount(condition string, pars []interface{}) (count int, err error) { o := orm.NewOrm() sql := ` SELECT a.* from contract_approval a JOIN contract c ON a.contract_id = c.contract_id WHERE c.is_delete = 0 and a.approval_type = "contract" ` sql += condition sql += ` GROUP BY a.contract_id ` sql = `select count(*) count from (` + sql + `) b` err = o.Raw(sql, pars).QueryRow(&count) return } // 审批列表 type ContractApprovalList struct { ContractApprovalId int `description:"审批单id"` ContractId int `description:"合同id"` ContractApprovalRecordId int `description:"审批流id"` ContractCode string `description:"合同编号"` Status string `description:"审批单状态,枚举值:待审批','已审批','已驳回','已撤回',默认待审批"` ContractStatus string `json:"-" description:"合同状态,枚举值:'待提交','待审批','已撤回','已审批','已驳回','已作废','已签回','已解约',默认待审批"` ApplyContent string `description:"待审内容"` ContractDetail string `json:"-" description:"提交审批时的合同信息;合同快照"` ContractInfo ContractDetail `description:"提交审批时的合同信息;合同快照"` ApproveRemark string `description:"审核备注"` ContractType string `description:"合同类型"` ContractBusinessType string `description:"合同业务类型"` PayChannel string `description:"支付渠道"` Price float64 `description:"合同金额"` OriginalPrice float64 `json:"-" description:"合同金额"` CompanyName string `description:"客户名称"` FileUrl string `description:"合同下载地址"` CheckBackFileUrl string `description:"签回合同下载地址"` RescindFileUrl string `description:"解约合同下载地址"` SellerId int `description:"销售id"` ProductId int `description:"产品id,1:ficc;2:权益"` SellerName string `description:"销售名称"` StartDate time.Time `description:"合同开始日期"` EndDate time.Time `description:"合同结束日期"` CreateTime time.Time `description:"发起审批的时间"` ModifyTime time.Time `description:"最后一次修改的时间"` ApproveTime time.Time `description:"审批时间"` InvalidTime time.Time `description:"作废时间"` CheckBackFileTime time.Time `description:"合同签回时间"` RescindTime time.Time `description:"解约时间"` StartDateStr string `description:"合同开始日期(字符串类型)"` EndDateStr string `description:"合同结束日期(字符串类型)"` CreateTimeStr string `description:"发起审批的时间(字符串类型)"` ModifyTimeStr string `description:"最后一次修改的时间(字符串类型)"` ApproveTimeStr string `description:"审批时间(字符串类型)"` InvalidTimeStr string `description:"作废时间(字符串类型)"` CheckBackFileTimeStr string `description:"合同签回时间(字符串类型)"` RescindTimeStr string `description:"解约时间(字符串类型)"` OpButton ContractButton `description:"按钮操作权限"` Remark string `json:"-" description:"备注"` } // 合同权限 type ContractButton struct { Approval bool `description:"是否具有审核操作权限,true才允许审核操作"` CheckBackFile bool `description:"是否具有文件签回权限,true才允许操作"` RescindFile bool `description:"是否具有文件解约权限,true才允许操作"` } // 获取审批列表数据 func GetContractApprovalList(childCondition, condition string, childPars, pars []interface{}, startSize, pageSize int) (list []*ContractApprovalList, err error) { o := orm.NewOrm() sql := ` SELECT a.contract_approval_id,a.contract_id,a.apply_content,a.contract_detail,a.approve_remark,a.create_time,a.modify_time,a.status,c.status contract_status,c.product_id, c.contract_type,c.contract_business_type,c.pay_channel,c.start_date,c.end_date,c.price,c.original_price,c.remark,c.company_name,c.seller_id,c.seller_name,c.file_url,c.contract_code,c.approve_time,c.invalid_time,c.check_back_file_url,c.rescind_file_url,c.check_back_file_time,c.rescind_time from contract_approval a join ( SELECT max( contract_approval_id ) max_id,contract_id FROM contract_approval where 1=1 and approval_type="contract"` sql += childCondition sql += ` GROUP BY contract_id ) b on a.contract_approval_id=b.max_id JOIN contract c ON a.contract_id = c.contract_id WHERE c.is_delete = 0 and a.approval_type="contract" ` sql += condition sql += ` group by contract_id order by modify_time desc LIMIT ?,? ` _, err = o.Raw(sql, childPars, pars, startSize, pageSize).QueryRows(&list) return } // 根据合同id获取合同审批单信息 func (ContractApproval) CheckPendingByContractId(contractId int, approvalType string) (has bool, err error) { o := orm.NewOrm() var contractApprovalInfo ContractApproval sql := `select * from contract_approval where contract_id = ? AND approval_type =? AND status="待审批" limit 1` err = o.Raw(sql, contractId, approvalType).QueryRow(&contractApprovalInfo) if err != nil { if err.Error() == utils.ErrNoRow() { //如果不存在待审批记录,那么报错信息置空,存在与否直接返回false err = nil return } //系统异常,返回错误信息 return } //存在待审批的审批单 has = true return } // 根据审批单id获取所有审批流列表信息 func GetContractApprovalRecordListByContractApprovalIdAndNodeId(contractApprovalId, nodeId int) (contractApprovalRecordList []*ContractApprovalRecord, err error) { o := orm.NewOrm() sql := `select * from contract_approval_record where contract_approval_id=? and node_id=? order by node_id,contract_approval_record_id asc` _, err = o.Raw(sql, contractApprovalId, nodeId).QueryRows(&contractApprovalRecordList) return } // 发起审批 func (ContractApproval) Apply(contractApprovalInfo *ContractApproval, contractApprovalRecord *ContractApprovalRecord) (err error) { o := orm.NewOrm() to, err := o.Begin() if err != nil { return } defer func() { if err != nil { _ = to.Rollback() } else { _ = to.Commit() } }() //审批单记录 ContractApprovalId, err := to.Insert(contractApprovalInfo) if err != nil { return } //审批单id contractApprovalInfo.ContractApprovalId = int(ContractApprovalId) //审批流记录 contractApprovalRecord.ContractApprovalId = contractApprovalInfo.ContractApprovalId contractApprovalRecordId, err := to.Insert(contractApprovalRecord) if err != nil { return } //审批流id contractApprovalRecord.ContractApprovalRecordId = int(contractApprovalRecordId) //修改合同状态为待审批 sql := `UPDATE contract SET status="待审批",modify_time=NOW() WHERE contract_id = ?` _, err = to.Raw(sql, contractApprovalInfo.ContractId).Exec() return } // 发起审批(工作流) func (ContractApproval) Apply2(contractApprovalInfo *ContractApproval, contractApprovalRecordList []*ContractApprovalRecord) (err error) { o := orm.NewOrm() to, err := o.Begin() if err != nil { return } defer func() { if err != nil { _ = to.Rollback() } else { _ = to.Commit() } }() //审批单记录 ContractApprovalId, err := to.Insert(contractApprovalInfo) if err != nil { return } //审批单id contractApprovalInfo.ContractApprovalId = int(ContractApprovalId) for _, contractApprovalRecord := range contractApprovalRecordList { //审批流记录 contractApprovalRecord.ContractApprovalId = contractApprovalInfo.ContractApprovalId contractApprovalRecordId, tmpErr := to.Insert(contractApprovalRecord) if tmpErr != nil { err = tmpErr return } //审批流id contractApprovalRecord.ContractApprovalRecordId = int(contractApprovalRecordId) } switch contractApprovalInfo.ApprovalType { case "contract": //修改合同状态为待审批 sql := `UPDATE contract SET status="待审批",modify_time=NOW() WHERE contract_id = ?` _, err = to.Raw(sql, contractApprovalInfo.ContractId).Exec() case "seal": //修改用印状态为待审批 sql := `UPDATE seal SET status="待审批",modify_time=NOW() WHERE seal_id = ?` _, err = to.Raw(sql, contractApprovalInfo.ContractId).Exec() case "company": //修改客户单状态为待审批 //因为本身就是待审批,所以不需要 } return } // 撤回审核单 func (ContractApproval) Cancel(contractApprovalInfo *ContractApproval, contractApprovalRecordList []*ContractApprovalRecord) (err error) { o := orm.NewOrm() to, err := o.Begin() if err != nil { return } defer func() { if err != nil { _ = to.Rollback() } else { _ = to.Commit() } }() //变更审批单记录 contractApprovalInfo.Status = "已撤回" contractApprovalInfo.ModifyTime = time.Now() _, err = to.Update(contractApprovalInfo, "Status", "ModifyTime") if err != nil { return } //变更所有审批流记录 for _, contractApprovalRecord := range contractApprovalRecordList { contractApprovalRecord.Status = "已撤回" contractApprovalRecord.ModifyTime = time.Now() _, tmpErr := to.Update(contractApprovalRecord, "Status", "ModifyTime") if tmpErr != nil { err = tmpErr return } } //撤回审批单 switch contractApprovalInfo.ApprovalType { case "contract": //修改合同状态为已撤回 sql := `UPDATE contract SET status="已撤回",modify_time=NOW() WHERE contract_id = ?` _, err = to.Raw(sql, contractApprovalInfo.ContractId).Exec() return case "seal": // 修改用印审批状态为已撤回 sql := `UPDATE seal SET status="已撤回",modify_time=NOW() WHERE seal_id = ?` _, err = to.Raw(sql, contractApprovalInfo.ContractId).Exec() return } return } // 审核驳回 func (ContractApproval) Reject(contractApprovalInfo *ContractApproval, contractApprovalRecord *ContractApprovalRecord, approveUserId int, approveUserName, remark string) (err error) { o := orm.NewOrm() to, err := o.Begin() if err != nil { return } defer func() { if err != nil { _ = to.Rollback() } else { _ = to.Commit() } }() //变更审批单记录 contractApprovalInfo.Status = "已驳回" contractApprovalInfo.ApproveRemark = remark //审核失败理由 contractApprovalInfo.ModifyTime = time.Now() //contractApprovalInfo.CurrNodeId = 0 //当前节点变更为0,代表当前审批流程已经结束了 _, err = to.Update(contractApprovalInfo, "Status", "ApproveRemark", "ModifyTime") if err != nil { return } //变更审批流记录 contractApprovalRecord.Status = "已驳回" contractApprovalRecord.ApproveRemark = remark //审核失败理由 contractApprovalRecord.ApproveUserId = approveUserId //审批人id contractApprovalRecord.ApproveUserName = approveUserName //审批人名称 contractApprovalRecord.ApproveTime = time.Now() //审批时间 contractApprovalRecord.ModifyTime = time.Now() _, err = to.Update(contractApprovalRecord, "Status", "ApproveRemark", "ApproveUserId", "ApproveUserName", "ApproveTime", "ModifyTime") if err != nil { return } //修改合同状态为已驳回 switch contractApprovalInfo.ApprovalType { case "contract": //修改合同状态为已驳回 sql := `UPDATE contract SET status="已驳回",modify_content="",approval_remark=?,approve_time=NOW(),modify_time=NOW() WHERE contract_id = ?` _, err = to.Raw(sql, remark, contractApprovalInfo.ContractId).Exec() case "seal": //修改用印状态为已驳回 sql := `UPDATE seal SET status="已驳回",approval_remark=?,approve_time=NOW(),modify_time=NOW() WHERE seal_id = ?` _, err = to.Raw(sql, remark, contractApprovalInfo.ContractId).Exec() } return } // 下级审批人信息 type NextApproval struct { ApproveRoleTypeCode string ApproveUserId int ApproveUserName string } // 审核通过 func (ContractApproval) ApprovedOld(contractApprovalInfo *ContractApproval, contractApprovalRecord *ContractApprovalRecord, approveUserId int, approveUserName, remark string, nextApproval NextApproval) (err error) { o := orm.NewOrm() to, err := o.Begin() if err != nil { return } defer func() { if err != nil { _ = to.Rollback() } else { _ = to.Commit() } }() //变更审批流记录 contractApprovalRecord.Status = "已审批" contractApprovalRecord.ApproveRemark = remark //审核失败理由 contractApprovalRecord.ApproveUserId = approveUserId //审批人id contractApprovalRecord.ApproveUserName = approveUserName //审批人名称 contractApprovalRecord.ApproveTime = time.Now() //审批人名称 contractApprovalRecord.ModifyTime = time.Now() _, err = to.Update(contractApprovalRecord, "Status", "ApproveRemark", "ApproveUserId", "ApproveUserName", "ApproveTime", "ModifyTime") if err != nil { return } //判断是否存在下一级的审批人,如果不存在,那么就去变更审批单和合同的状态 if nextApproval.ApproveRoleTypeCode == "" && nextApproval.ApproveUserId == 0 { //变更审批单记录 contractApprovalInfo.Status = "已审批" contractApprovalInfo.ApproveRemark = remark //审核理由 contractApprovalInfo.ModifyTime = time.Now() _, tmpErr := to.Update(contractApprovalInfo, "Status", "ApproveRemark", "ModifyTime") if tmpErr != nil { err = tmpErr return } //修改合同状态为已审批 sql := `UPDATE contract SET status="已审批",approval_remark=?,modify_time=NOW() WHERE contract_id = ?` _, tmpErr = to.Raw(sql, remark, contractApprovalInfo.ContractId).Exec() if tmpErr != nil { err = tmpErr return } } else { //如果还存在下一级审批人,那么进入下级审批流 nextContractApprovalRecord := &ContractApprovalRecord{ ContractApprovalId: contractApprovalInfo.ContractApprovalId, Status: "待审批", ApproveRoleTypeCode: nextApproval.ApproveRoleTypeCode, ApproveUserId: nextApproval.ApproveUserId, ApproveUserName: nextApproval.ApproveUserName, ModifyTime: time.Now(), CreateTime: time.Now(), } nextContractApprovalRecordId, tmpErr := to.Insert(nextContractApprovalRecord) if tmpErr != nil { err = tmpErr return } nextContractApprovalRecord.ContractApprovalRecordId = int(nextContractApprovalRecordId) } return } func (ContractApproval) Approved(contractApprovalInfo *ContractApproval, contractApprovalRecord *ContractApprovalRecord, remark string) (err error) { o := orm.NewOrm() to, err := o.Begin() if err != nil { return } defer func() { if err != nil { _ = to.Rollback() } else { _ = to.Commit() } }() //变更审批流记录 contractApprovalRecord.Status = "已审批" contractApprovalRecord.ApproveRemark = remark //审核失败理由 contractApprovalRecord.ApproveTime = time.Now() //审批时间 contractApprovalRecord.ModifyTime = time.Now() _, err = to.Update(contractApprovalRecord, "Status", "ApproveRemark", "ApproveTime", "ModifyTime") if err != nil { return } //如果没有下级节点了,那么完成该审批单 if contractApprovalRecord.NextNodeId <= 0 { //变更审批单记录 contractApprovalInfo.Status = "已审批" contractApprovalInfo.ApproveRemark = remark //审核理由 //contractApprovalInfo.CurrNodeId = contractApprovalRecord.NextNodeId //下级审批节点id contractApprovalInfo.ModifyTime = time.Now() _, tmpErr := to.Update(contractApprovalInfo, "Status", "ApproveRemark", "ModifyTime") if tmpErr != nil { err = tmpErr return } //修改合同状态为已审批 switch contractApprovalInfo.ApprovalType { case "contract": //修改合同状态为已审批 sql := `UPDATE contract SET status="已审批",approval_remark=?,approve_time=NOW(),modify_time=NOW() WHERE contract_id = ?` _, tmpErr = to.Raw(sql, remark, contractApprovalInfo.ContractId).Exec() if tmpErr != nil { err = tmpErr return } case "seal": //修改用印状态为已审批 sql := `UPDATE seal SET status="已审批",approval_remark=?,approve_time=NOW(),modify_time=NOW() WHERE seal_id = ?` _, tmpErr = to.Raw(sql, remark, contractApprovalInfo.ContractId).Exec() if tmpErr != nil { err = tmpErr return } } } else { //变更审批单记录 contractApprovalInfo.ApproveRemark = remark //审核理由 contractApprovalInfo.CurrNodeId = contractApprovalRecord.NextNodeId //下级审批节点id contractApprovalInfo.ModifyTime = time.Now() _, tmpErr := to.Update(contractApprovalInfo, "ApproveRemark", "CurrNodeId", "ModifyTime") if tmpErr != nil { err = tmpErr return } } return } // 抄送 func (ContractApproval) ApprovedByCc(contractApprovalInfo *ContractApproval, contractApprovalRecordList []*ContractApprovalRecord, remark string, nextNodeId int) (err error) { o := orm.NewOrm() to, err := o.Begin() if err != nil { return } defer func() { if err != nil { _ = to.Rollback() } else { _ = to.Commit() } }() for _, contractApprovalRecord := range contractApprovalRecordList { //变更审批流记录 contractApprovalRecord.Status = "已审批" contractApprovalRecord.ApproveTime = time.Now() //审批时间 contractApprovalRecord.ModifyTime = time.Now() _, err = to.Update(contractApprovalRecord, "Status", "ApproveTime", "ModifyTime") if err != nil { return } } if err != nil { return } //如果没有下级节点了,那么完成该审批单 if nextNodeId <= 0 { //变更审批单记录 contractApprovalInfo.Status = "已审批" //contractApprovalInfo.CurrNodeId = nextNodeId //下级审批节点id contractApprovalInfo.ModifyTime = time.Now() _, tmpErr := to.Update(contractApprovalInfo, "Status", "ModifyTime") if tmpErr != nil { err = tmpErr return } //修改合同状态为已审批 switch contractApprovalInfo.ApprovalType { case "contract": //修改合同状态为已审批 sql := `UPDATE contract SET status="已审批",approval_remark=?,approve_time=NOW(),modify_time=NOW() WHERE contract_id = ?` _, tmpErr = to.Raw(sql, remark, contractApprovalInfo.ContractId).Exec() if tmpErr != nil { err = tmpErr return } case "seal": //修改用印状态为已审批 sql := `UPDATE seal SET status="已审批",approval_remark=?,approve_time=NOW(),modify_time=NOW() WHERE seal_id = ?` _, tmpErr = to.Raw(sql, remark, contractApprovalInfo.ContractId).Exec() if tmpErr != nil { err = tmpErr return } } } else { //变更审批单记录 contractApprovalInfo.CurrNodeId = nextNodeId //下级审批节点id contractApprovalInfo.ModifyTime = time.Now() _, tmpErr := to.Update(contractApprovalInfo, "CurrNodeId", "ModifyTime") if tmpErr != nil { err = tmpErr return } } return }