|
|
package wallet
|
|
|
|
|
|
import (
|
|
|
"errors"
|
|
|
"fmt"
|
|
|
"git.oa00.com/go/mysql"
|
|
|
"github.com/shopspring/decimal"
|
|
|
"gorm.io/gorm"
|
|
|
"recook/internal/libs/bean"
|
|
|
"recook/internal/v2/logic/source/wallet"
|
|
|
finance2 "recook/internal/v2/model/finance"
|
|
|
"recook/internal/v2/model/gys"
|
|
|
"recook/internal/v2/model/gys/enterprise"
|
|
|
"recook/internal/v2/model/recook/goods"
|
|
|
manage "recook/internal/v2/model/recook/order"
|
|
|
"recook/tools"
|
|
|
"time"
|
|
|
)
|
|
|
|
|
|
var DepositLogic = &depositLogic{}
|
|
|
|
|
|
type depositLogic struct {
|
|
|
}
|
|
|
type depositItem struct {
|
|
|
Id uint `json:"id"`
|
|
|
Name string `json:"name"`
|
|
|
BillType uint `json:"bill_type"`
|
|
|
DepositAmount decimal.Decimal `json:"deposit_amount"`
|
|
|
DepositFreezeAmount decimal.Decimal `json:"deposit_freeze_amount"`
|
|
|
DepositBillAmount decimal.Decimal `json:"deposit_bill_amount"`
|
|
|
DepositTotalAmount decimal.Decimal `json:"deposit_total_amount"`
|
|
|
WarningAmount decimal.Decimal `json:"warning_amount"`
|
|
|
Status uint `json:"status"`
|
|
|
}
|
|
|
|
|
|
// Lists @Title 运营方预存款列表
|
|
|
func (d *depositLogic) Lists(sourceId uint, page bean.Page) (lists []depositItem, total int64) {
|
|
|
lists = []depositItem{}
|
|
|
sources := []gys.GysSourceModel{}
|
|
|
where := mysql.Db.Where("bill_type=?", 2)
|
|
|
if sourceId > 0 {
|
|
|
where = where.Where("id = ?", sourceId)
|
|
|
}
|
|
|
mysql.Db.Model(&sources).Where(where).Count(&total)
|
|
|
if page.HasPage(total) {
|
|
|
mysql.Db.Preload("Wallet").Where(where).Offset(page.GetStart()).Limit(page.GetLimit()).Find(&sources)
|
|
|
for _, source := range sources {
|
|
|
lists = append(lists, depositItem{
|
|
|
Id: source.Id,
|
|
|
Name: source.Name,
|
|
|
BillType: source.BillType,
|
|
|
Status: source.Wallet.DepositEarlyWarningStatus,
|
|
|
WarningAmount: source.Wallet.DepositEarlyWarningAmount,
|
|
|
DepositAmount: source.Wallet.DepositAmount,
|
|
|
DepositFreezeAmount: source.Wallet.DepositFreezeAmount,
|
|
|
DepositBillAmount: source.Wallet.DepositBillAmount,
|
|
|
DepositTotalAmount: source.Wallet.DepositTotalAmount,
|
|
|
})
|
|
|
}
|
|
|
}
|
|
|
return
|
|
|
}
|
|
|
|
|
|
type depositHistoryItem struct {
|
|
|
Id uint `json:"id"`
|
|
|
Type uint `json:"type"`
|
|
|
CreatedAt int64 `json:"created_at"`
|
|
|
Proof string `json:"proof"`
|
|
|
Amount decimal.Decimal `json:"amount"`
|
|
|
AfterAmount decimal.Decimal `json:"after_amount"`
|
|
|
}
|
|
|
|
|
|
// History @Title 预存款变动明细
|
|
|
func (d *depositLogic) History(sourceId, historyType uint, timeStart, timeEnd string, page bean.Page) (lists []depositHistoryItem, total int64) {
|
|
|
lists = []depositHistoryItem{}
|
|
|
depositHistories := []gys.GysSourceDepositHistory{}
|
|
|
where := mysql.Db.Where("source_id = ?", sourceId)
|
|
|
if historyType > 0 {
|
|
|
switch historyType {
|
|
|
case gys.GysSourceDepositHistoryTypeDeposit:
|
|
|
where = where.Where("type = ?", gys.GysSourceDepositHistoryTypeDeposit)
|
|
|
case gys.GysSourceDepositHistoryTypeBill:
|
|
|
where = where.Where("type = ?", gys.GysSourceDepositHistoryTypeDeposit)
|
|
|
}
|
|
|
}
|
|
|
if timeStart != "" && timeEnd != "" {
|
|
|
start, err := time.ParseInLocation("2006-01-02", timeStart, time.Local)
|
|
|
if err == nil {
|
|
|
end, err := time.ParseInLocation("2006-01-02 15:04:05", timeEnd+" 23:59:59", time.Local)
|
|
|
if err == nil {
|
|
|
where = where.Where("created_at between ? and ?", start, end)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
mysql.Db.Model(&depositHistories).Where(where).Count(&total)
|
|
|
if page.HasPage(total) {
|
|
|
mysql.Db.Where(where).Offset(page.GetStart()).Limit(page.GetLimit()).Find(&depositHistories)
|
|
|
for _, history := range depositHistories {
|
|
|
lists = append(lists, depositHistoryItem{
|
|
|
Id: history.Id,
|
|
|
Type: history.Type,
|
|
|
CreatedAt: history.CreatedAt.Unix(),
|
|
|
Proof: history.Proof,
|
|
|
Amount: history.Amount,
|
|
|
AfterAmount: history.AfterAmount,
|
|
|
})
|
|
|
}
|
|
|
}
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// Deposit @Title 充值
|
|
|
func (d *depositLogic) Deposit(sourceId uint, amount decimal.Decimal, proof string, status uint) error {
|
|
|
sourceWallet := gys.GysSourceWallet{SourceId: sourceId}
|
|
|
mysql.Db.Where(&sourceWallet).First(&sourceWallet)
|
|
|
afterAmount := decimal.Zero
|
|
|
|
|
|
if status == 1 {
|
|
|
//充值
|
|
|
afterAmount = amount.Add(sourceWallet.DepositAmount).Add(sourceWallet.DepositFreezeAmount)
|
|
|
} else {
|
|
|
//退款
|
|
|
afterAmount = (sourceWallet.DepositAmount).Add(sourceWallet.DepositFreezeAmount).Sub(amount)
|
|
|
}
|
|
|
|
|
|
return mysql.Db.Transaction(func(tx *gorm.DB) error {
|
|
|
|
|
|
typeNum := 0
|
|
|
if status == 1 {
|
|
|
typeNum = 3
|
|
|
} else {
|
|
|
typeNum = 4
|
|
|
}
|
|
|
if tx.Create(&gys.GysSourceDepositHistory{
|
|
|
SourceId: sourceId,
|
|
|
Type: uint(typeNum),
|
|
|
Proof: proof,
|
|
|
Amount: amount,
|
|
|
AfterAmount: afterAmount,
|
|
|
}).Error != nil {
|
|
|
return errors.New("充值失败")
|
|
|
}
|
|
|
if err := wallet.DepositLogic.Add(tx, sourceId, amount, status); err != nil {
|
|
|
return err
|
|
|
}
|
|
|
return nil
|
|
|
})
|
|
|
}
|
|
|
|
|
|
//// Refund 退款
|
|
|
//func (d *depositLogic) Refund(sourceId uint, amount decimal.Decimal, proof string) error {
|
|
|
// sourceWallet := gys.GysSourceWallet{SourceId: sourceId}
|
|
|
// mysql.Db.Where(&sourceWallet).First(&sourceWallet)
|
|
|
// afterAmount := amount.Mul(decimal.NewFromInt32(-1))
|
|
|
// if sourceWallet.Id > 0 {
|
|
|
// afterAmount = afterAmount.Add(sourceWallet.DepositAmount).Add(sourceWallet.DepositFreezeAmount)
|
|
|
// }
|
|
|
// return mysql.Db.Transaction(func(tx *gorm.DB) error {
|
|
|
// if tx.Create(&gys.GysSourceDepositHistory{
|
|
|
// SourceId: sourceId,
|
|
|
// Type: gys.GysSourceDepositHistoryTypeDeposit,
|
|
|
// Proof: proof,
|
|
|
// Amount: amount,
|
|
|
// AfterAmount: afterAmount,
|
|
|
// }).Error != nil {
|
|
|
// return errors.New("退款失败")
|
|
|
// }
|
|
|
// if err := wallet.DepositLogic.Sub(tx, sourceId, amount); err != nil {
|
|
|
// return err
|
|
|
// }
|
|
|
// return nil
|
|
|
// })
|
|
|
//}
|
|
|
|
|
|
// EarlyWarning @Title 预警配置
|
|
|
func (d *depositLogic) EarlyWarning(sourceId, status uint, amount decimal.Decimal) error {
|
|
|
sourceWallet := gys.GysSourceWallet{SourceId: sourceId}
|
|
|
if mysql.Db.Where(&sourceWallet).First(&sourceWallet).Error != nil {
|
|
|
if status == 0 {
|
|
|
// 关闭
|
|
|
sourceWallet.DepositEarlyWarningStatus = gys.GysSourceWalletDepositEarlyWarningStatusDisable
|
|
|
} else {
|
|
|
sourceWallet.DepositEarlyWarningStatus = gys.GysSourceWalletDepositEarlyWarningStatusEnable
|
|
|
sourceWallet.DepositEarlyWarningAmount = amount
|
|
|
}
|
|
|
if mysql.Db.Create(&sourceWallet).Error != nil {
|
|
|
return errors.New("配置失败")
|
|
|
}
|
|
|
} else {
|
|
|
if status == 0 {
|
|
|
// 关闭
|
|
|
if mysql.Db.Model(&sourceWallet).UpdateColumns(map[string]interface{}{
|
|
|
"deposit_early_warning_status": gys.GysSourceWalletDepositEarlyWarningStatusDisable,
|
|
|
}).Error != nil {
|
|
|
return errors.New("配置失败")
|
|
|
}
|
|
|
} else {
|
|
|
if mysql.Db.Model(&sourceWallet).UpdateColumns(map[string]interface{}{
|
|
|
"deposit_early_warning_status": gys.GysSourceWalletDepositEarlyWarningStatusEnable,
|
|
|
"deposit_early_warning_amount": amount,
|
|
|
}).Error != nil {
|
|
|
return errors.New("配置失败")
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
// EarlyWarningEmail @Title 预警邮箱
|
|
|
func (d *depositLogic) EarlyWarningEmail(sourceId uint, emails []string) error {
|
|
|
warningEmails := []gys.GysSourceDepositEarlyWarningEmail{}
|
|
|
for _, email := range emails {
|
|
|
if !tools.VerifyEmail(email) {
|
|
|
return errors.New("邮箱格式错误")
|
|
|
}
|
|
|
warningEmails = append(warningEmails, gys.GysSourceDepositEarlyWarningEmail{
|
|
|
SourceId: sourceId,
|
|
|
Email: email,
|
|
|
})
|
|
|
}
|
|
|
return mysql.Db.Transaction(func(tx *gorm.DB) error {
|
|
|
if tx.Where("source_id = ?", sourceId).Delete(&gys.GysSourceDepositEarlyWarningEmail{}).Error != nil {
|
|
|
return errors.New("设置失败")
|
|
|
}
|
|
|
if tx.Create(&warningEmails).Error != nil {
|
|
|
return errors.New("设置失败")
|
|
|
}
|
|
|
return nil
|
|
|
})
|
|
|
}
|
|
|
|
|
|
type ShowItem struct {
|
|
|
OrderStatus string `json:"order_status" xlsx:"订单状态"`
|
|
|
OrderId uint `json:"order_id" xlsx:"主订单编号"`
|
|
|
OrderGoodsId uint `json:"order_goods_id" xlsx:"订单编号"`
|
|
|
AssType string `json:"ass_type" xlsx:"售后类型"`
|
|
|
AfterId uint `json:"after_id" xlsx:"售后单号"`
|
|
|
PayTime string `json:"pay_time" xlsx:"订单时间"`
|
|
|
ExpressTime string `json:"express_time" xlsx:"发货时间"`
|
|
|
CompletedAt string `json:"completed_at" xlsx:"订单完结时间"`
|
|
|
SkuCode string `json:"sku_code" xlsx:"商品条码"`
|
|
|
SkuGoodsNum string `json:"sku_goods_num" xlsx:"商品编码"`
|
|
|
InvoiceGoodsName string `json:"invoice_goods_name" xlsx:"开票商品名称"`
|
|
|
SkuName string `json:"sku_name" xlsx:"规格名称"`
|
|
|
InvoiceUnit string `json:"invoice_unit" xlsx:"单位"`
|
|
|
Quantity uint `json:"quantity" xlsx:"发货数量"`
|
|
|
PurchasePrice decimal.Decimal `json:"purchase_price" xlsx:"结算含税单价(元)"`
|
|
|
ExpressFee decimal.Decimal `json:"express_fee" xlsx:"运费金额(元)"`
|
|
|
Amount decimal.Decimal `json:"amount" xlsx:"应结算金额(元)"`
|
|
|
AfterQuantity uint `json:"after_quantity" xlsx:"退货数量"`
|
|
|
RefundAmount decimal.Decimal `json:"refund_amount" xlsx:"退款金额(元)"`
|
|
|
CompensateAmount decimal.Decimal `json:"compensate_amount" xlsx:"赔偿金额(元)"`
|
|
|
BillQuantity uint `json:"bill_quantity" xlsx:"实际结算数量"`
|
|
|
BillAmount decimal.Decimal `json:"bill_amount" xlsx:"实际结算金额(元)"`
|
|
|
EnterpriseName string `json:"enterprise_name" xlsx:"供应商"`
|
|
|
}
|
|
|
type OperateListReq struct {
|
|
|
OrderId uint `json:"order_id"`
|
|
|
Code string `json:"code"`
|
|
|
InvoiceGoodsName string `json:"invoice_goods_name"`
|
|
|
OrderStatus uint `json:"order_status"`
|
|
|
RefundType uint `json:"refund_type"`
|
|
|
ExpressTimeStart string `json:"express_time_start"`
|
|
|
ExpressTimeEnd string `json:"express_time_end"`
|
|
|
FinishTimeStart string `json:"finish_time_start"`
|
|
|
FinishTimeEnd string `json:"finish_time_end"`
|
|
|
Export uint `json:"export"`
|
|
|
GysId uint `json:"gys_id"`
|
|
|
SourceId uint `json:"source_id"`
|
|
|
bean.Page
|
|
|
}
|
|
|
|
|
|
//运营:展示采购订单list
|
|
|
func (d *depositLogic) OperateShowList(filter OperateListReq) (result []ShowItem, total int64) {
|
|
|
|
|
|
var bill finance2.RecookFinanceBillOrder
|
|
|
table := bill.TableName()
|
|
|
where := mysql.Db
|
|
|
if filter.SourceId > 0 {
|
|
|
//非超级管理员----传入运营方id
|
|
|
q := mysql.Db.Table((&enterprise.GysEnterpriseStateModel{}).TableName()).Where("source=?", filter.SourceId).Select("user_id")
|
|
|
where = where.Where(fmt.Sprintf("%s.supplier_id in (?)", table), q)
|
|
|
}
|
|
|
if filter.GysId > 0 {
|
|
|
where = where.Where(fmt.Sprintf("%s.supplier_id=?", table), filter.GysId)
|
|
|
}
|
|
|
if filter.OrderId > 0 {
|
|
|
where = where.Where(fmt.Sprintf("%s.order_id like ?", table), fmt.Sprintf("%%%d%%", filter.OrderId))
|
|
|
}
|
|
|
if filter.Code != "" {
|
|
|
where = where.Where("Sku.code like ?", fmt.Sprintf("%%%d%%", filter.OrderId))
|
|
|
}
|
|
|
if filter.InvoiceGoodsName != "" {
|
|
|
q := mysql.Db.Table((&goods.RecookSkuInvoiceModel{}).TableName()).Where("goodsName like ?", fmt.Sprintf("%%%s%%", filter.InvoiceGoodsName)).Select("sku_id")
|
|
|
where = where.Where(fmt.Sprintf("%s.sku_id in(?)", table), q)
|
|
|
}
|
|
|
|
|
|
if filter.OrderStatus > 0 {
|
|
|
switch filter.OrderStatus {
|
|
|
case 1: // 已发货待确认
|
|
|
where = where.Where("OrderGoods.express_status = ? and OrderGoods.refund_status = ?", manage.RecookOrderGoodsDetailExpressStatusTrue, manage.RecookOrderGoodsDetailRefundStatusNone)
|
|
|
case 2: // 售后中
|
|
|
where = where.Where("OrderGoods.express_status = ? and OrderGoods.refund_status = ?", manage.RecookOrderGoodsDetailExpressStatusTrue, manage.RecookOrderGoodsDetailRefundStatusIng)
|
|
|
case 3: // 收货已完成
|
|
|
where = where.Where("OrderGoods.express_status = ? and OrderGoods.refund_status = ?", manage.RecookOrderGoodsDetailExpressStatusTrue, manage.RecookOrderGoodsDetailRefundStatusSuc)
|
|
|
case 4: // 已完成
|
|
|
where = where.Where("OrderGoods.express_status = ?", manage.RecookOrderGoodsDetailExpressStatusConfirm)
|
|
|
}
|
|
|
}
|
|
|
if filter.RefundType > 0 {
|
|
|
switch filter.RefundType {
|
|
|
case manage.RecookOrderGoodsDetailAssTypeRejected:
|
|
|
where = where.Where("OrderGoods.ass_type = ?", manage.RecookOrderGoodsDetailAssTypeRejected)
|
|
|
case manage.RecookOrderGoodsDetailAssTypeCompensate:
|
|
|
where = where.Where("OrderGoods.ass_type = ?", manage.RecookOrderGoodsDetailAssTypeCompensate)
|
|
|
}
|
|
|
}
|
|
|
if filter.ExpressTimeStart != "" && filter.ExpressTimeEnd != "" {
|
|
|
start, err := time.ParseInLocation("2006-01-02", filter.ExpressTimeStart, time.Local)
|
|
|
if err == nil {
|
|
|
end, err := time.ParseInLocation("2006-01-02 15:04:05", filter.ExpressTimeEnd+" 23:59:59", time.Local)
|
|
|
if err == nil {
|
|
|
where = where.Where("OrderExpress.express_time between ? and ?", start, end)
|
|
|
}
|
|
|
fmt.Println("发货时间:", start, end)
|
|
|
}
|
|
|
}
|
|
|
if filter.FinishTimeStart != "" && filter.FinishTimeEnd != "" {
|
|
|
start, err := time.ParseInLocation("2006-01-02", filter.FinishTimeStart, time.Local)
|
|
|
if err == nil {
|
|
|
end, err := time.ParseInLocation("2006-01-02 15:04:05", filter.FinishTimeEnd+" 23:59:59", time.Local)
|
|
|
if err == nil {
|
|
|
where = where.Where("Order.completed_at between ? and ?", start, end)
|
|
|
}
|
|
|
fmt.Println("完成时间:", start, end)
|
|
|
}
|
|
|
}
|
|
|
query := mysql.Db.Joins("Goods").Joins("OrderExpress").Joins("Sku").Joins("OrderGoods").Joins("Supplier").Joins("Order").Model(&bill)
|
|
|
query.Where(where).Count(&total)
|
|
|
var list []finance2.RecookFinanceBillOrder
|
|
|
if filter.Export > 0 {
|
|
|
query.Preload("After").Preload("Order").Preload("OrderExpress").Preload("Sku").Preload("Sku.Invoice").Preload("OrderGoods").Preload("Supplier").Where(where).Find(&list)
|
|
|
} else {
|
|
|
query.Preload("After").Preload("OrderExpress").Preload("Order").Preload("Sku").Preload("Sku.Invoice").Preload("OrderGoods").Preload("Supplier").Where(where).Limit(filter.Page.GetLimit()).Offset(filter.Page.GetStart()).Find(&list)
|
|
|
}
|
|
|
|
|
|
for _, v := range list {
|
|
|
//订单状态:已发货待确认 售后中 已完成 售后已退款
|
|
|
ostr := ""
|
|
|
if v.OrderGoods.RefundStatus == 2 && v.OrderGoods.AssType > 0 {
|
|
|
ostr = "售后已退款"
|
|
|
} else if v.OrderGoods.RefundStatus == 1 && v.OrderGoods.AssType > 0 {
|
|
|
ostr = "售后中"
|
|
|
}
|
|
|
if v.OrderGoods.PayStatus > 0 && v.OrderGoods.ExpressStatus > 0 {
|
|
|
ostr = "已发货待确认"
|
|
|
}
|
|
|
if v.OrderGoods.Status == 1 {
|
|
|
ostr = "已完成"
|
|
|
}
|
|
|
//fmt.Println(ostr)
|
|
|
//fmt.Println("订单详情:", v.OrderGoods)
|
|
|
ast := ""
|
|
|
//售后类型:正常,退货退款,订单补偿
|
|
|
if v.OrderGoods.RefundStatus > 0 && v.OrderGoods.AssType == 2 {
|
|
|
ast = "退货退款"
|
|
|
} else if v.OrderGoods.AssType == 3 {
|
|
|
ast = "订单补偿"
|
|
|
}
|
|
|
if v.OrderGoods.AssType == 0 {
|
|
|
ast = "正常"
|
|
|
}
|
|
|
fmt.Println(ast)
|
|
|
amount := v.OrderGoods.PurchasePrice.Mul(decimal.NewFromInt(int64(v.OrderGoods.Quantity))).Add(v.OrderGoods.ExpressFee)
|
|
|
one := ShowItem{
|
|
|
OrderStatus: ostr,
|
|
|
OrderId: v.OrderId,
|
|
|
OrderGoodsId: v.OrderGoodsId,
|
|
|
AssType: ast,
|
|
|
AfterId: v.AfterId,
|
|
|
PayTime: v.Order.PayTime.Time.Format("2006-01-02 15:04:05"),
|
|
|
ExpressTime: v.OrderExpress.ExpressTime.Time.Format("2006-01-02 15:04:05"),
|
|
|
CompletedAt: v.Order.CompletedAt.Time.Format("2006-01-02 15:04:05"),
|
|
|
SkuCode: v.Sku.Code,
|
|
|
SkuGoodsNum: v.Sku.GoodsNum,
|
|
|
InvoiceGoodsName: v.Sku.Invoice.GoodsName,
|
|
|
SkuName: v.Sku.Name,
|
|
|
InvoiceUnit: v.Sku.Invoice.Unit,
|
|
|
Quantity: v.OrderGoods.Quantity,
|
|
|
PurchasePrice: v.OrderGoods.PurchasePrice,
|
|
|
ExpressFee: v.OrderGoods.ExpressFee,
|
|
|
Amount: amount,
|
|
|
AfterQuantity: v.After.Quantity,
|
|
|
RefundAmount: v.After.RefundAmount,
|
|
|
CompensateAmount: v.After.SupplierPrice,
|
|
|
BillQuantity: v.OrderGoods.Quantity - v.After.Quantity,
|
|
|
BillAmount: amount.Sub(v.After.RefundAmount).Sub(v.After.SupplierPrice),
|
|
|
EnterpriseName: v.Supplier.EnterpriseName,
|
|
|
}
|
|
|
//fmt.Println(one)
|
|
|
result = append(result, one)
|
|
|
}
|
|
|
fmt.Println(len(result))
|
|
|
return result, total
|
|
|
}
|