mh_goadmin_server/app/admin/models/erp_order.go

876 lines
31 KiB
Go
Raw Normal View History

package models
import (
"encoding/json"
"errors"
"fmt"
"go-admin/app/admin/apis/pay"
orm "go-admin/common/global"
"go-admin/logger"
"gorm.io/gorm"
"math/rand"
"strings"
"time"
)
const (
ErpOrderStateUnAudit = "un_audit" // 未审核
ErpOrderStateAudited = "audited" // 已审核
ErpOrderMemberTypeGeneral = "general" // 普通
ErpOrderMemberTypeMember = "member" // 会员
RetailTypeSale = "sale" // 零售订单
RetailTypeRejected = "rejected" // 零售退货订单
NoCreatePayOrder = 0 // 未创建
WaitForPaying = 1 // 待支付
HavePaid = 2 // 已支付
NoPrint = 1 // 未打印
HavePrinted = 2 // 已打印
OnlinePay = 1 // 线上支付(微信/支付宝/云闪付扫码)
PayInit = "pay_init"
Paying = "paying"
PayOk = "pay_ok"
PayFailed = "pay_failed"
PayUnknown = "pay_unknown"
)
type ErpOrder struct {
Model
BillSn string `json:"bill_sn" gorm:"index"` // 单据编号
RetailType string `json:"retail_type"` // 销售类型:sale 零售销售; rejected 零售退货
Uid int `json:"uid"` // 用户id
Tel string `json:"tel" gorm:"index"` // 客户手机号
StoreId uint32 `json:"store_id" gorm:"index"` // 门店id
StoreName string `json:"store_name"` // 门店名称
MakerId uint32 `json:"maker_id" gorm:"index"` // 制单人id
MakerName string `json:"maker_name"` // 制单人名称
MakerTime time.Time `json:"maker_time"` // 制单时间
AuditorId uint32 `json:"auditor_id" gorm:"index"` // 审核人id
AuditorName string `json:"auditor_name"` // 审核人姓名
AuditTime time.Time `json:"audit_time"` // 审核时间
CashierList string `json:"cashier_list" gorm:"type:text"` // 付款方式存储json数据
Salesman1 uint32 `json:"salesman_1"` // 销售员一用户ID
SalesmanName1 uint32 `json:"salesmanName_1"` // 销售员一用户姓名
Salesman2 uint32 `json:"salesman_2"` // 销售员二用户ID
SalesmanName2 uint32 `json:"salesmanName_2"` // 销售员二用户姓名
MemberType string `json:"member_type"` // 会员类型:general 普通; member 会员
State string `json:"state" gorm:"index"` // 订单状态:un_audit 待审核; audited 已审核
TotalRetailPrice float64 `json:"total_retail_price"` // 订单总指导零售价
TotalAmount float64 `json:"total_amount"` // 订单实收金额
TotalCount uint32 `json:"total_count"` // 订单商品数量
VmCount uint32 `json:"vm_count"` // 使用会员积分
SaleOrderId uint32 `json:"sale_order_id"` // 销售订单id
PayStatus uint32 `json:"pay_status"` // 支付状态 0-未创建 1-待支付; 2-已支付
IsPrint uint32 `json:"is_print"` // 是否打印小票 1-未打印 2-已打印
PrintCount uint32 `json:"print_count"` // 小票打印次数
InvoiceCode uint32 `json:"invoice_code"` // 发票代码
InvoiceNumber uint32 `json:"invoice_number"` // 发票编码
RejectedTotalAmount float64 `json:"rejected_total_amount" gorm:"-"` // 订单总退货金额
RejectedTotalCount uint32 `json:"rejected_total_count" gorm:"-"` // 订单总退货数量
Commodities []ErpOrderCommodity `json:"commodities" gorm:"-"` // 零售订单商品信息
Cashiers []ErpOrderCashier `json:"cashiers" gorm:"-"` // 收付款方式
}
type ErpOrderCommodity struct {
Model
ErpOrderId uint32 `json:"erp_order_id" gorm:"index"` // 零售订单id后端生成
ErpCategoryId uint32 `json:"erp_category_id" gorm:"index"` // 分类id
ErpCategoryName string `json:"erp_category_name"` // 分类名称
ErpCommodityId uint32 `json:"erp_commodity_id" gorm:"index"` // 商品id
ErpCommodityName string `json:"erp_commodity_name"` // 商品名称
IMEIType uint32 `json:"imei_type"` // 1-无串码 2-串码
IMEI string `json:"imei" gorm:"index"` // 串码
PresentType uint32 `json:"present_type"` // 赠送类型:1-非赠送 2-赠送
RetailPrice uint32 `json:"retail_price"` // 指导零售价
SalePrice uint32 `json:"sale_price"` // 零售价
Count uint32 `json:"count"` // 销售数量
SaleDiscount float64 `json:"sale_discount"` // 零售优惠
MemberDiscount float64 `json:"member_discount"` // 会员优惠
VmDiscount float64 `json:"vm_discount"` // 会员积分抵扣
Amount float64 `json:"amount"` // 实际零售价
TotalAmount float64 `json:"total_amount"` // 商品实收金额
Remark string `json:"remark"` // 备注
Tel string `json:"tel" gorm:"index"` // 手机号
RejectedPrice float64 `json:"rejected_price"` // 退货单价
RejectedCount uint32 `json:"rejected_count"` // 退货数量
RejectedAmount float64 `json:"rejected_amount"` // 退货金额
RejectedOrderCommodityId uint32 `json:"rejected_order_commodity_id"` // 退货订单商品id
}
type ErpOrderCashier struct {
CashierId uint32 `json:"cashier_id"` // 收付款方式id
Name string `json:"name"` // 收付款方式名称
Amount float64 `json:"amount"` // 金额
}
type ErpOrderRecord struct {
Model
ErpOrderId uint32 `json:"erp_order_id" gorm:"index"` // 零售订单id
BillSn string `json:"bill_sn" gorm:"index"` // 单据编号
OutOrderNo string `json:"out_order_no"` // 商户订单号
PlatTrxNo string `json:"plat_trx_no"` // 平台交易流水号
BankOrderNo string `json:"bank_order_no"` // 银行订单号
TotalAmount float64 `json:"total_amount"` // 订单总金额
PayWay string `json:"pay_way"` // 支付方式
Status string `json:"status"` // 支付状态
}
type ErpOrderCreateReq struct {
BillSn string `json:"bill_sn"` // 单据编号
StoreId uint32 `json:"store_id" binding:"required"` // 门店id
StoreName string `json:"store_name"` // 门店名称
Salesman1 uint32 `json:"salesman_1" binding:"required"` // 销售员一
SalesmanName1 uint32 `json:"salesmanName_1"` // 销售员一用户姓名
Salesman2 uint32 `json:"salesman_2"` // 销售员二
SalesmanName2 uint32 `json:"salesmanName_2"` // 销售员二用户姓名
RetailType string `json:"retail_type" binding:"required"` // 销售类型sale 零售销售; rejected 零售退货
Tel string `json:"tel" binding:"required"` // 会员手机号
MemberType string `json:"member_type"` // 会员类型general 普通; member 会员
TotalRetailPrice float64 `json:"total_retail_price"` // 订单总指导零售价
TotalAmount float64 `json:"total_amount"` // 订单实收金额
TotalCount uint32 `json:"total_count"` // 订单商品数量
VmAmount uint32 `json:"vm_count"` // 使用会员积分
Cashiers []ErpOrderCashier `json:"cashiers" binding:"required"` // 收付款方式
ErpOrderCommodities []ErpOrderCommodity `json:"erp_order_commodities" binding:"required"` // 零售订单商品信息
}
type ErpOrderListReq struct {
BillSn string `json:"bill_sn"` // 单据编号
RetailType string `json:"retail_type"` // 销售类型sale 零售销售; rejected 零售退货
Uid int `json:"uid"` // 用户ID
Tel string `json:"tel"` // 客户手机号
Salesman uint32 `json:"salesman"` // 销售人员ID
StoreId uint32 `json:"store_id"` // 门店ID
State string `json:"state"` // 订单状态
PayStatus uint32 `json:"pay_status"` // 支付状态 0-未创建 1-待支付; 2-已支付
StartTime string `json:"start_time"` // 开始时间
EndTime string `json:"end_time"` // 结束时间
PageIndex int `json:"pageIndex"` // 页码
PageSize int `json:"pageSize"` // 页面条数
IsExport uint32 `json:"is_export"` // 1-导出
}
type ErpOrderListResp struct {
List []ErpOrder `json:"list"`
Total int `json:"total"` // 总条数
PageIndex int `json:"pageIndex"` // 页码
PageSize int `json:"pageSize"` // 每页展示条数
ExportUrl string `json:"export_url"`
}
type ErpOrderDeleteReq struct {
BillSn string `json:"bill_sn" binding:"required"` // 单据编号
}
type ErpOrderPayReq struct {
BillSn string `json:"bill_sn" binding:"required"` // 单据编号
AuthCode string `json:"auth_code" binding:"required"` // 用户付款码
}
type ErpOrderPayResp struct {
Status string `json:"status"` // 支付成功pay_ok支付失败pay_failed 等待支付paying; 未知状态pay_unknown
}
type ErpOrderAuditReq struct {
BillSn string `json:"bill_sn" binding:"required"` // 单据编号
State int `json:"state" binding:"required"` // 审核操作: 1-审核 2-取消审核
}
type ErpOrderAddInvoiceReq struct {
BillSn string `json:"bill_sn" binding:"required"` // 单据编号
InvoiceCode uint32 `json:"invoice_code" binding:"required"` // 发票代码
InvoiceNumber uint32 `json:"invoice_number" binding:"required"` // 发票编码
}
func (m *ErpOrderListReq) List() (*ErpOrderListResp, error) {
resp := &ErpOrderListResp{
PageIndex: m.PageIndex,
PageSize: m.PageSize,
}
page := m.PageIndex - 1
if page < 0 {
page = 0
}
if m.PageSize == 0 {
m.PageSize = 10
}
qs := orm.Eloquent.Table("erp_order")
if m.BillSn != "" {
qs = qs.Where("bill_sn=?", m.BillSn)
} else {
if m.RetailType != "" {
qs = qs.Where("retail_type=?", m.RetailType)
}
if m.Tel != "" {
qs = qs.Where("tel=?", m.Tel)
}
if m.StoreId != 0 {
qs = qs.Where("store_id=?", m.StoreId)
}
if m.Salesman != 0 {
qs = qs.Where("salesman1 = ? or salesman2 = ?", m.Salesman, m.Salesman)
}
if m.PayStatus != 0 {
qs = qs.Where("pay_status=?", m.PayStatus)
}
if m.State != "" {
qs = qs.Where("state=?", m.State)
}
if m.StartTime != "" {
parse, err := time.Parse(DateTimeFormat, m.StartTime)
if err != nil {
logger.Errorf("err:", err)
}
qs = qs.Where("created_at > ?", parse)
}
if m.EndTime != "" {
parse, err := time.Parse(DateTimeFormat, m.EndTime)
if err != nil {
logger.Errorf("err:", err)
}
parse = parse.AddDate(0, 0, 1)
qs = qs.Where("created_at < ?", parse)
}
}
var count int64
err := qs.Count(&count).Error
if err != nil {
logger.Error("count err:", logger.Field("err", err))
return resp, err
}
var orders []ErpOrder
if m.IsExport == 1 {
err = qs.Order("id DESC").Find(&orders).Error
if err != nil && err != RecordNotFound {
logger.Error("dailys err:", logger.Field("err", err))
return resp, err
}
//listExport, err := ErpOrderListExport(orders)
//if err != nil {
// logger.Error("list export err:", err)
//}
//resp.ExportUrl = listExport
} else {
resp.Total = int(count)/m.PageSize + 1
err = qs.Order("id DESC").Offset(page * m.PageSize).Limit(m.PageSize).Find(&orders).Error
if err != nil && err != RecordNotFound {
logger.Error("erp commodity list err:", logger.Field("err", err))
return resp, err
}
ErpOrderListSetCashier(orders)
resp.List = orders
//跟之前保持一致
resp.Total = int(count)
resp.PageIndex = page + 1
resp.PageSize = m.PageSize
}
return resp, nil
}
// UpdateStock 扣减or添加库存
// 零售订单:
// 有串码,通过串码查找库存详情表,然后更改对应库存的状态为"已售"
// 非串码通过门店id、商品id、商品名称查找库存详情表找到库存时间最长的然后更改其状态为"已售"。
// 同时扣减库存表对应的数量,-1
// 零售退货:
// 有串码,通过串码查找库存详情表,然后更改对应库存的状态为"在库"
// 非串码通过门店id、商品id、商品名称查找库存详情表找到状态为"已售"且时间最近的单,将其状态改为"在库"
// 同时扣减库存表对应的数量,+1
func UpdateStock(gdb *gorm.DB, erpOrder ErpOrder) error {
var commodities []ErpOrderCommodity
err := orm.Eloquent.Table("erp_order_commodity").Where("erp_order_id = ?", erpOrder.ID).
Find(&commodities).Error
if err != nil {
logger.Error("commodities err:", logger.Field("err", err))
return err
}
if erpOrder.RetailType == RetailTypeSale { // 零售订单
for i, _ := range commodities {
if commodities[i].IMEIType == 2 { // 串码商品
if commodities[i].IMEI == "" {
return errors.New("串码为空")
}
err = gdb.Table("erp_stock_commodity").Where("imei = ?", commodities[i].IMEI).
Update("state", 2).Error // 状态更新为已售
if err != nil {
logger.Error("commodities err:", logger.Field("err", err))
return err
}
err = gdb.Table("erp_stock").Where("store_id = ? and erp_commodity_id = ?",
erpOrder.StoreId, commodities[i].ErpCommodityId).
Updates(map[string]interface{}{"count": gorm.Expr("count - ?", 1)}).Error // 库存数量-1
if err != nil {
logger.Error("commodities err:", logger.Field("err", err))
return err
}
} else { // 非串码商品
var stockCommodity []ErpStockCommodity
// 通过门店id商品id查找状态为1-在库的非串码商品
err = orm.Eloquent.Table("erp_stock_commodity").Where("erp_commodity_id = ? and store_id = ? "+
"and state = ? and imei_type = ?", commodities[i].ErpCommodityId, erpOrder.StoreId, 1, 1).
Order("sort DESC").Find(&stockCommodity).Error
if err != nil {
logger.Error("commodities err:", logger.Field("err", err))
return err
}
if stockCommodity == nil {
return errors.New("find no stock commodity")
}
err = gdb.Table("erp_stock_commodity").Where("id = ?", stockCommodity[0].ID).
Update("state", 2).Error // 状态更新为已售
if err != nil {
logger.Error("commodities err:", logger.Field("err", err))
return err
}
err = gdb.Table("erp_stock").Where("store_id = ? and erp_commodity_id = ?",
erpOrder.StoreId, commodities[i].ErpCommodityId).
Updates(map[string]interface{}{"count": gorm.Expr("count - ?", 1)}).Error // 库存数量-1
if err != nil {
logger.Error("commodities err:", logger.Field("err", err))
return err
}
}
}
} else if erpOrder.RetailType == RetailTypeRejected { // 零售退货订单
for i, _ := range commodities {
if commodities[i].IMEIType == 2 { // 串码商品
if commodities[i].IMEI == "" {
return errors.New("串码为空")
}
err = gdb.Table("erp_stock_commodity").Where("imei = ?", commodities[i].IMEI).
Update("state", 1).Error // 状态更新为在库
if err != nil {
logger.Error("RetailTypeRejected commodities err:", logger.Field("err", err))
return err
}
err = gdb.Table("erp_stock").Where("store_id = ? and erp_commodity_id = ?",
erpOrder.StoreId, commodities[i].ErpCommodityId).
Updates(map[string]interface{}{"count": gorm.Expr("count + ?", 1)}).Error // 库存数量+1
if err != nil {
logger.Error("RetailTypeRejected commodities err:", logger.Field("err", err))
return err
}
} else { // 非串码商品
var stockCommodity []ErpStockCommodity
// 通过门店id商品id查找状态为2-已售的非串码商品
err = orm.Eloquent.Table("erp_stock_commodity").Where("erp_commodity_id = ? and store_id = ? "+
"and state = ? and imei_type = ?", commodities[i].ErpCommodityId, erpOrder.StoreId, 2, 1).
Order("sort DESC").Find(&stockCommodity).Error
if err != nil {
logger.Error("RetailTypeRejected commodities err:", logger.Field("err", err))
return err
}
if stockCommodity == nil {
return errors.New("RetailTypeRejected find no stock commodity")
}
err = gdb.Table("erp_stock_commodity").Where("id = ?", stockCommodity[0].ID).
Update("state", 1).Error // 状态更新为在库
if err != nil {
logger.Error("RetailTypeRejected commodities err:", logger.Field("err", err))
return err
}
err = gdb.Table("erp_stock").Where("store_id = ? and erp_commodity_id = ?",
erpOrder.StoreId, commodities[i].ErpCommodityId).
Updates(map[string]interface{}{"count": gorm.Expr("count + ?", 1)}).Error // 库存数量+1
if err != nil {
logger.Error("RetailTypeRejected commodities err:", logger.Field("err", err))
return err
}
}
}
} else {
return errors.New("订单类型错误")
}
return nil
}
// CheckIsOnlinePay 检查是否包含线上支付
func CheckIsOnlinePay(jCashier []ErpOrderCashier) bool {
for _, cashier := range jCashier {
if cashier.CashierId == OnlinePay || strings.Contains(cashier.Name, "微信") || strings.Contains(cashier.Name, "支付宝") {
return true
}
}
return false
}
func NewErpBillSn() string {
nowTime := time.Now()
rand.Seed(nowTime.UnixNano())
max := 1
for {
if max > 5 {
logger.Error("create sn err")
return ""
}
random := rand.Int31n(9999) + 1000
sn := fmt.Sprintf("%s%d", nowTime.Format("060102"), random)
exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_order WHERE bill_sn='%s'", sn))
if err != nil {
logger.Error("exist sn err")
}
if !exist {
return sn
}
max++
}
}
func NewErpPurchaseSn() string {
nowTime := time.Now()
rand.Seed(nowTime.UnixNano())
max := 1
for {
if max > 5 {
logger.Error("create sn err")
return ""
}
random := rand.Int31n(9999) + 1000
sn := fmt.Sprintf("%s%d", nowTime.Format("060102"), random)
exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_purchase_order WHERE serial_number='%s'", sn))
if err != nil {
logger.Error("exist sn err")
}
if !exist {
return sn
}
max++
}
}
func ErpOrderListSetCashier(list []ErpOrder) {
for i, _ := range list {
list[i].SetErpCashier()
}
}
func (m *ErpOrder) SetErpCashier() {
if m.CashierList != "" {
var cashiers []ErpOrderCashier
err := json.Unmarshal([]byte(m.CashierList), &cashiers)
if err != nil {
logger.Error("unmarshal err:", logger.Field("err", err))
}
m.Cashiers = cashiers
m.CashierList = ""
}
}
func GetErpOrderCommodityMap(ids []uint32) (map[uint32]ErpOrderCommodity, error) {
commodityMap := make(map[uint32]ErpOrderCommodity, 0)
if len(ids) == 0 {
return commodityMap, nil
}
var commodities []ErpOrderCommodity
err := orm.Eloquent.Table("erp_order_commodity").Where("id IN (?)", ids).Find(&commodities).Error
if err != nil {
logger.Error("commodities err:", logger.Field("err", err))
return commodityMap, err
}
for i, _ := range commodities {
commodityMap[commodities[i].ID] = commodities[i]
}
return commodityMap, nil
}
func SetUserInfo(tel string) {
var user UserInfo
err := orm.Eloquent.Table("user").Where("tel=?", tel).Find(&user).Error
if err != nil {
logger.Error("user err:", logger.Field("err", err))
return
}
if user.FirstRetailOrder.IsZero() {
err := orm.Eloquent.Table("user").Where("uid=?", user.Uid).Update("first_retail_order", time.Now()).Error
if err != nil {
logger.Error("update user err:", logger.Field("err", err))
}
}
}
func SetInvoice(req *ErpOrderAddInvoiceReq) error {
var orderInfo ErpOrder
err := orm.Eloquent.Table("erp_order").Where("bill_sn = ?", req.BillSn).Find(&orderInfo).Error
if err != nil {
logger.Error("操作失败,未查询到订单", logger.Field("err", err))
return errors.New("未查询到订单")
}
if orderInfo.State == ErpOrderStateUnAudit {
logger.Errorf("order delete err, state is:", orderInfo.State)
return errors.New("订单未审核")
}
if orderInfo.PayStatus != 2 {
logger.Errorf("order delete err, state is:", orderInfo.State)
return errors.New("订单未支付")
}
err = orm.Eloquent.Table("erp_order").Where("id = ?", orderInfo.ID).Updates(map[string]interface{}{
"invoice_code": req.InvoiceCode,
"invoice_number": req.InvoiceNumber,
}).Error
if err != nil {
logger.Error("AddInvoice err:", logger.Field("err", err))
return err
}
return nil
}
func DeleteOrder(req *ErpOrderDeleteReq) error {
var orderInfo ErpOrder
err := orm.Eloquent.Table("erp_order").Where("bill_sn = ?", req.BillSn).Find(&orderInfo).Error
if err != nil {
logger.Error("order delete err:", logger.Field("err", err))
return errors.New("未查询到订单")
}
if orderInfo.State != ErpOrderStateUnAudit {
logger.Errorf("order delete err, state is:", orderInfo.State)
return errors.New("已审核订单不能删除")
}
var orderCommodities ErpOrderCommodity
err = orm.Eloquent.Table("erp_order_commodity").Where("erp_order_id = ?", orderInfo.ID).Find(&orderCommodities).Error
if err != nil {
logger.Error("order delete err:", logger.Field("err", err))
return errors.New("未查询到订单商品信息")
}
begin := orm.Eloquent.Begin()
err = begin.Delete(orderCommodities).Error
if err != nil {
begin.Rollback()
logger.Error("order delete1 err:", logger.Field("err", err))
return err
}
err = begin.Delete(orderInfo).Error
if err != nil {
begin.Rollback()
logger.Error("order delete2 err:", logger.Field("err", err))
return err
}
err = begin.Commit().Error
if err != nil {
begin.Rollback()
logger.Error("order delete3 err:", logger.Field("err", err))
return err
}
return nil
}
// 生成序列号
func GenErpOrderSerialNo() string {
currentDate := time.Now().Format("20060102")
tradeNO := "sale" + currentDate + pay.RandomNumString(10000000, 99999999)
return tradeNO
}
// GetErpOrderSn 生成零售订单号
func GetErpOrderSn() string {
var erpOrderSn string
for {
erpOrderSn = GenErpOrderSerialNo()
var count int64
err := orm.Eloquent.Table("erp_order_record").Where("out_order_no=?", erpOrderSn).Count(&count)
if err != nil {
logger.Error("err:", logger.Field("err", err))
}
if count == 0 {
break
}
}
return erpOrderSn
}
// 查询是否有已支付的订单
func checkIsPayOk(billSn string) bool {
var count int64
err := orm.Eloquent.Table("erp_order_record").Where("bill_sn = ? and status = ?", billSn, PayOk).
Count(&count).Error
if err != nil {
logger.Error("checkIsPayOk err:", logger.Field("err", err))
}
return count > 0
}
// 查询是否有待支付的订单
func checkIsPaying(billSn string) bool {
var count int64
err := orm.Eloquent.Table("erp_order_record").Where("bill_sn = ? and status = ?", billSn, Paying).
Count(&count).Error
if err != nil {
logger.Error("checkIsPayOk err:", logger.Field("err", err))
}
return count > 0
}
// 查询是否有刚初始化的订单
func checkIsPayInit(billSn string) bool {
var count int64
err := orm.Eloquent.Table("erp_order_record").Where("bill_sn = ? and status = ?", billSn, PayInit).
Count(&count).Error
if err != nil {
logger.Error("checkIsPayOk err:", logger.Field("err", err))
}
return count > 0
}
// ErpOrderPay 零售订单支付
func ErpOrderPay(req *ErpOrderPayReq) (*ErpOrderPayResp, error) {
resp := &ErpOrderPayResp{
Status: PayFailed,
}
//通过单据号查询收款金额
var orderInfo ErpOrder
err := orm.Eloquent.Table("erp_order").Where("bill_sn = ?", req.BillSn).Find(&orderInfo).Error
if err != nil {
logger.Error("未查询到订单:", logger.Field("err", err))
return resp, err
}
if orderInfo.PayStatus == HavePaid {
logger.Error("ErpOrderPay err, 订单已支付")
return resp, errors.New("订单已支付")
}
if orderInfo.PayStatus != WaitForPaying {
logger.Error("ErpOrderPay err, 订单不是待支付状态")
return resp, errors.New("订单不是待支付状态")
}
var cashiers []ErpOrderCashier
err = json.Unmarshal([]byte(orderInfo.CashierList), &cashiers)
if err != nil {
logger.Error("unmarshal CashierList err:", logger.Field("err", err))
}
var amount float64
for i, _ := range cashiers {
if cashiers[i].CashierId == OnlinePay { //线上支付
amount = cashiers[i].Amount
break
}
}
if amount == 0 {
logger.Error("ErpOrderPay err, 订单金额为0")
return resp, errors.New("订单金额为0")
}
// 查询是否有已支付的订单
if checkIsPayOk(req.BillSn) {
// 更新零售订单表
err = orm.Eloquent.Model(&ErpOrder{}).Where("id = ?", orderInfo.ID).
Update("pay_status", HavePaid).Error
if err != nil {
logger.Error("ErpOrderPay update erp_order_record err:", logger.Field("err", err))
}
resp.Status = PayOk
logger.Error("ErpOrderPay err2, 订单已支付")
return resp, errors.New("订单已支付")
}
// 查询是否有待支付订单
if checkIsPaying(req.BillSn) {
queryResp, err := QueryErpOrderPayStatus(req.BillSn)
if err != nil {
logger.Error("查询订单失败", logger.Field("err", err))
return resp, err
}
// 等待支付或成功支付则返回,否则新建订单
if queryResp.Status == Paying || queryResp.Status == PayOk {
resp.Status = queryResp.Status
return resp, nil
}
}
// 查询是否有刚初始化的订单
var orderSn string
if checkIsPayInit(req.BillSn) {
var orderRecordInfo ErpOrderRecord
err := orm.Eloquent.Table("erp_order_record").Where("bill_sn = ? and status = ?", req.BillSn, PayInit).
Find(&orderRecordInfo).Error
if err != nil {
logger.Error("未查询到订单:", logger.Field("err", err))
return resp, errors.New("未查询到待支付订单")
}
orderSn = orderRecordInfo.OutOrderNo
} else {
// 创建支付订单号,并记录到支付记录表,关联零售订单号
orderSn = GetErpOrderSn()
var erpOrderRecord ErpOrderRecord
erpOrderRecord.ErpOrderId = orderInfo.ID
erpOrderRecord.BillSn = orderInfo.BillSn
erpOrderRecord.OutOrderNo = orderSn
erpOrderRecord.Status = PayInit
err = orm.Eloquent.Table("erp_order_record").Create(&erpOrderRecord).Error
if err != nil {
logger.Error("Create erp_order_record err:", logger.Field("err", err))
return resp, err
}
}
resp.Status = Paying
// 发起支付扣款
hmPayResp, err := pay.HmJsPayBToCOrder(orderSn, amount, req.AuthCode, "")
if err != nil {
logger.Error("HmJsPayBToCOrder err")
return resp, err
}
// 更新支付状态
var payStatus string
switch hmPayResp.SubCode {
case "SUCCESS":
payStatus = PayOk
case "FAILED":
payStatus = PayFailed
case "WAITING_PAYMENT":
payStatus = Paying
default:
payStatus = PayUnknown
}
updateInfo := map[string]interface{}{
"bank_order_no": hmPayResp.BankOrderNo,
"plat_trx_no": hmPayResp.PlatTrxNo,
"total_amount": hmPayResp.TotalAmount,
"pay_way": hmPayResp.PayWay,
"status": payStatus,
}
begin := orm.Eloquent.Begin()
err = begin.Model(&ErpOrderRecord{}).Where("out_order_no = ?", orderSn).
Updates(updateInfo).Error
if err != nil {
begin.Rollback()
logger.Error("update erp_order_record err:", logger.Field("err", err))
return resp, err
}
if payStatus == PayOk { // 支付成功
// 更新零售订单表
err = begin.Model(&ErpOrder{}).Where("id = ?", orderInfo.ID).
Update("pay_status", HavePaid).Error
if err != nil {
begin.Rollback()
logger.Error("update erp_order_record err:", logger.Field("err", err))
return resp, err
}
}
err = begin.Commit().Error
if err != nil {
begin.Rollback()
return resp, fmt.Errorf("ErpOrderPay[commit err]%v", err)
}
resp.Status = payStatus
return resp, nil
}
// QueryErpOrderPayStatus 查询零售订单支付状态
func QueryErpOrderPayStatus(billSn string) (*ErpOrderPayResp, error) {
resp := &ErpOrderPayResp{
Status: Paying,
}
// 查询待支付订单
var orderRecordInfo ErpOrderRecord
err := orm.Eloquent.Table("erp_order_record").Where("bill_sn = ? and status = ?", billSn, Paying).
Find(&orderRecordInfo).Error
if err != nil {
logger.Error("未查询到订单:", logger.Field("err", err))
resp.Status = PayFailed
return resp, errors.New("未查询到待支付订单")
}
// 查询支付状态
hmQueryResp, err := pay.HmQueryOrder(orderRecordInfo.OutOrderNo)
if err != nil {
logger.Error("查询失败:", logger.Field("err", err))
return resp, err
}
// 更新订单状态
var payStatus string
switch hmQueryResp.SubCode {
case "SUCCESS":
payStatus = PayOk
case "FAILED":
payStatus = PayFailed
case "WAITING_PAYMENT":
payStatus = Paying
default:
payStatus = PayUnknown
}
updateInfo := map[string]interface{}{
"bank_order_no": hmQueryResp.BankOrderNo,
"plat_trx_no": hmQueryResp.PlatTrxNo,
"total_amount": hmQueryResp.TotalAmount,
"pay_way": hmQueryResp.PayWayCode,
"status": payStatus,
}
begin := orm.Eloquent.Begin()
err = begin.Model(&ErpOrderRecord{}).Where("out_order_no = ?", orderRecordInfo.OutOrderNo).
Updates(updateInfo).Error
if err != nil {
begin.Rollback()
logger.Error("query update erp_order_record err:", logger.Field("err", err))
return resp, err
}
if payStatus == PayOk { // 支付成功
// 更新零售订单表
err = begin.Model(&ErpOrder{}).Where("id = ?", orderRecordInfo.ID).
Update("pay_status", HavePaid).Error
if err != nil {
begin.Rollback()
logger.Error("query update erp_order_record err:", logger.Field("err", err))
return resp, err
}
}
err = begin.Commit().Error
if err != nil {
begin.Rollback()
return resp, fmt.Errorf("QueryErpOrderPayStatus[commit err]%v", err)
}
resp.Status = payStatus
return resp, nil
}