mh_goadmin_server/app/admin/models/purchase_change.go

583 lines
19 KiB
Go
Raw Normal View History

2025-02-18 10:17:08 +00:00
package models
import (
"errors"
"fmt"
"github.com/gin-gonic/gin"
orm "go-admin/common/global"
"go-admin/logger"
"go-admin/tools"
"gorm.io/gorm"
"math/rand"
"time"
)
// ErpPurchaseChangeOrder 采购换机订单表
type ErpPurchaseChangeOrder struct {
Model
SerialNumber string `json:"serial_number" gorm:"index"` // 单据编号
StoreId uint32 `json:"store_id" gorm:"index"` // 门店id
StoreName string `json:"store_name"` // 门店名称
ErpSupplierId uint32 `json:"erp_supplier_id" gorm:"index"` // 供应商id
ErpSupplierName string `json:"erp_supplier_name"` // 供应商名称
MakerTime *time.Time `json:"maker_time"` // 制单时间
MakerId uint32 `json:"maker_id" gorm:"index"` // 制单人id
MakerName string `json:"maker_name"` // 制单人名称
AuditTime *time.Time `json:"audit_time"` // 审核时间
AuditorId uint32 `json:"auditor_id" gorm:"index"` // 审核人id
AuditorName string `json:"auditor_name"` // 审核人名称
State uint32 `json:"state"` // 1-待审核 2-已完成
Remark string `json:"remark"` // 备注
Commodities []ErpPurchaseChangeCommodity `json:"commodities" gorm:"-"` // 采购换机商品信息
}
// ErpPurchaseChangeCommodity 采购换机订单商品表
type ErpPurchaseChangeCommodity struct {
Model
ChangeOrderId uint32 `json:"change_order_id" gorm:"index"` // 采购换机订单id
ErpCommodityId uint32 `json:"erp_commodity_id" gorm:"index"` // 商品id
ErpCommodityName string `json:"erp_commodity_name"` // 商品名称
CommoditySerialNumber string `json:"commodity_serial_number" gorm:"index"` // 商品编号
IMEIType uint32 `json:"imei_type"` // 1-无串码 2-串码
OriginIMEI string `json:"origin_imei"` // 原机身串码
NewIMEI string `json:"new_imei"` // 新机身串码
Count uint32 `json:"count"` // 数量
OriginColor string `json:"origin_color"` // 原机身颜色
NewColor string `json:"new_color"` // 新机身颜色
Remark string `json:"remark"` // 备注
}
// ErpPurchaseChangeCreateReq 新建采购换机订单入参
type ErpPurchaseChangeCreateReq struct {
StoreId uint32 `json:"store_id"` // 门店id:入库必传
ErpSupplierId uint32 `json:"erp_supplier_id"` // 供应商id:入库必传
Remark string `json:"remark"` // 备注
Commodities []ErpPurchaseChangeCommodity `json:"commodities" binding:"required"` // 采购换机商品信息
}
// ErpPurchaseChangeEditReq 编辑采购换机订单入参
type ErpPurchaseChangeEditReq struct {
ChangeOrderId uint32 `json:"change_order_id" gorm:"index"` // 采购换机订单id
StoreId uint32 `json:"store_id"` // 门店id:入库必传
ErpSupplierId uint32 `json:"erp_supplier_id"` // 供应商id:入库必传
Remark string `json:"remark"` // 备注
Commodities []ErpPurchaseChangeCommodity `json:"Commodities" binding:"required"` // 采购商品信息
}
// ErpPurchaseChangeOrderListReq 查询采购换机订单列表入参
type ErpPurchaseChangeOrderListReq struct {
SerialNumber string `json:"serial_number"` // 单据编号
StoreId uint32 `json:"store_id"` // 门店id
ErpSupplierId uint32 `json:"erp_supplier_id"` // 供应商id
AuditTimeStart string `json:"audit_time_start"` // 审核开始时间
AuditTimeEnd string `json:"audit_time_end"` // 审核结束时间
State []uint32 `json:"state"` // 状态1-待审核 2-已完成 3-已终止
HandlerId uint32 `json:"handler_id"` // 经手人id
PageIndex int `json:"pageIndex"` // 页码
PageSize int `json:"pageSize"` // 页面条数
}
// ErpPurchaseChangeOrderListResp 查询采购换机订单列表出参
type ErpPurchaseChangeOrderListResp struct {
List []ErpPurchaseChangeOrder `json:"list"`
Total int `json:"total"` // 总条数
PageIndex int `json:"pageIndex"` // 页码
PageSize int `json:"pageSize"` // 页面条数
}
// ErpPurchaseChangeDeleteReq 删除采购换机订单入参
type ErpPurchaseChangeDeleteReq struct {
SerialNumber string `json:"serial_number" binding:"required"` // 单据编号
}
// ErpPurchaseChangeAuditReq 审核采购换机订单入参
type ErpPurchaseChangeAuditReq struct {
SerialNumber string `json:"serial_number" binding:"required"` // 单据编号
State int `json:"state" binding:"required"` // 审核操作: 1-审核 2-取消审核
}
// newErpPurchaseChangeSn 生成采购换机订单号
func newErpPurchaseChangeSn() string {
var prefix string
prefix = "cgh"
nowTime := time.Now()
rand.Seed(nowTime.UnixNano())
max := 1
for {
if max > 5 {
logger.Error("create sn err")
return ""
}
random := rand.Intn(9000) + 1000
sn := fmt.Sprintf("%s%d", nowTime.Format("060102"), random)
exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_purchase_change_order WHERE "+
"serial_number='%s'", prefix+sn))
if err != nil {
logger.Error("exist sn err")
}
if !exist {
return prefix + sn
}
max++
}
}
// IdInit 添加商户和供应商信息
func (m *ErpPurchaseChangeOrder) IdInit() error {
if m.StoreId != 0 {
store, err := GetStore(m.StoreId)
if err != nil {
logger.Error("get store err:", logger.Field("err", err))
return err
}
m.StoreName = store.Name
}
if m.ErpSupplierId != 0 {
supplier, err := GetErpSupplier(m.ErpSupplierId)
if err != nil {
logger.Error("get supplier err:", logger.Field("err", err))
return err
}
m.ErpSupplierName = supplier.Name
}
return nil
}
// CheckCreateErpPurchaseChangeOrderParam 新增采购换机订单-检查参数
func CheckCreateErpPurchaseChangeOrderParam(req *ErpPurchaseChangeCreateReq) error {
if req.StoreId == 0 {
return errors.New("操作失败:门店id为空")
}
if req.ErpSupplierId == 0 {
return errors.New("操作失败:供应商id为空")
}
for _, item := range req.Commodities {
if item.Count <= 0 {
return errors.New("操作失败:采购换机数量需大于0")
}
// 判断是否是串码商品,非串码商品不支持
if item.IMEIType == 1 {
2025-02-20 07:15:09 +00:00
return errors.New("操作失败:采购换机不支持非串码商品")
2025-02-18 10:17:08 +00:00
}
var imeiStockCommodity ErpStockCommodity
err := orm.Eloquent.Table("erp_stock_commodity").Where("imei = ? and state = ?",
item.OriginIMEI, InStock).Find(&imeiStockCommodity).Error
if err != nil {
return err
}
if imeiStockCommodity.ID == 0 {
return errors.New("商品" + "[" + item.OriginIMEI + "]不在库")
}
if imeiStockCommodity.StoreId != req.StoreId {
2025-02-20 07:15:09 +00:00
return errors.New("商品" + "[" + item.OriginIMEI + "]非所选门店库存,请检查")
2025-02-18 10:17:08 +00:00
}
// 判断新商品串码是否已录入或者使用过
var newImeiStockCommodity ErpStockCommodity
err = orm.Eloquent.Table("erp_stock_commodity").Where("imei = ?",
item.NewIMEI).Find(&newImeiStockCommodity).Error
if err != nil {
return err
}
2025-02-20 07:15:09 +00:00
if newImeiStockCommodity.ID != 0 {
return errors.New("串码" + "[" + item.NewIMEI + "]重复")
2025-02-18 10:17:08 +00:00
}
}
return nil
}
// CheckEditErpPurchaseChangeOrderParam 编辑采购换机订单-检查参数
func CheckEditErpPurchaseChangeOrderParam(req *ErpPurchaseChangeEditReq) error {
if req.StoreId == 0 {
return errors.New("操作失败:门店id为空")
}
if req.ErpSupplierId == 0 {
return errors.New("操作失败:供应商id为空")
}
for _, item := range req.Commodities {
if item.Count <= 0 {
return errors.New("操作失败:采购换机数量需大于0")
}
// 判断是否是串码商品,非串码商品不支持
if item.IMEIType == 1 {
2025-02-20 07:15:09 +00:00
return errors.New("操作失败:采购换机不支持非串码商品")
2025-02-18 10:17:08 +00:00
}
var imeiStockCommodity ErpStockCommodity
err := orm.Eloquent.Table("erp_stock_commodity").Where("imei = ? and state = ?",
item.OriginIMEI, InStock).Find(&imeiStockCommodity).Error
if err != nil {
return err
}
if imeiStockCommodity.ID == 0 {
return errors.New("商品" + "[" + item.OriginIMEI + "]不在库")
}
if imeiStockCommodity.StoreId != req.StoreId {
2025-02-20 07:15:09 +00:00
return errors.New("商品" + "[" + item.OriginIMEI + "]非所选门店库存,请检查")
2025-02-18 10:17:08 +00:00
}
// 判断新商品串码是否已录入或者使用过
var newImeiStockCommodity ErpStockCommodity
err = orm.Eloquent.Table("erp_stock_commodity").Where("imei = ?",
item.NewIMEI).Find(&newImeiStockCommodity).Error
if err != nil {
return err
}
2025-02-20 07:15:09 +00:00
if newImeiStockCommodity.ID != 0 {
2025-02-18 10:17:08 +00:00
return errors.New("串码" + "[" + item.OriginIMEI + "]重复")
}
}
return nil
}
// CreateErpPurchaseChangeOrder 新增采购换机订单
func CreateErpPurchaseChangeOrder(req *ErpPurchaseChangeCreateReq, sysUser *SysUser) (*ErpPurchaseChangeOrder, error) {
var err error
nowTime := time.Now()
purchaseOrder := &ErpPurchaseChangeOrder{}
purchaseOrder = &ErpPurchaseChangeOrder{
SerialNumber: newErpPurchaseChangeSn(),
StoreId: req.StoreId,
ErpSupplierId: req.ErpSupplierId,
MakerTime: &nowTime,
MakerId: uint32(sysUser.UserId),
MakerName: sysUser.NickName,
State: ErpPurchaseChangeOrderUnAudit, // 1-待审核
Remark: req.Remark,
}
err = purchaseOrder.IdInit()
if err != nil {
logger.Error("info err:", logger.Field("err", err))
return nil, err
}
begin := orm.Eloquent.Begin()
err = begin.Create(purchaseOrder).Error
if err != nil {
begin.Rollback()
logger.Error("create purchase order err:", logger.Field("err", err))
return nil, err
}
for i, _ := range req.Commodities {
req.Commodities[i].ChangeOrderId = purchaseOrder.ID
err = begin.Create(&req.Commodities[i]).Error
if err != nil {
begin.Rollback()
logger.Error("create purchase commodity err:", logger.Field("err", err))
return nil, err
}
}
err = begin.Commit().Error
if err != nil {
begin.Rollback()
logger.Error("commit purchase commodity err:", logger.Field("err", err))
return nil, err
}
return purchaseOrder, nil
}
// EditErpPurchaseChangeOrder 编辑采购订单
func EditErpPurchaseChangeOrder(req *ErpPurchaseChangeEditReq, sysUser *SysUser) (*ErpPurchaseChangeOrder, error) {
// 查询订单信息
var purchaseChangeOrder ErpPurchaseChangeOrder
err := orm.Eloquent.Table("erp_purchase_change_order").Where("id=?", req.ChangeOrderId).Find(&purchaseChangeOrder).Error
if err != nil {
logger.Error("purchase change order err:", logger.Field("err", err))
return nil, err
}
if purchaseChangeOrder.State != ErpPurchaseChangeOrderUnAudit { // 只有待审核的订单才能编辑
return nil, errors.New("订单不是待审核状态")
}
if req.StoreId == 0 {
return nil, errors.New("操作失败:门店id为空")
}
begin := orm.Eloquent.Begin()
// 1-更新采购订单信息
purchaseChangeOrder.StoreId = req.StoreId
purchaseChangeOrder.ErpSupplierId = req.ErpSupplierId
purchaseChangeOrder.MakerId = uint32(sysUser.UserId)
purchaseChangeOrder.MakerName = sysUser.NickName
purchaseChangeOrder.Remark = req.Remark
err = purchaseChangeOrder.IdInit()
if err != nil {
logger.Error("purchase change IdInit err:", logger.Field("err", err))
return nil, err
}
err = begin.Model(&ErpPurchaseChangeOrder{}).Where("id = ?", req.ChangeOrderId).
Omit("created_at").Save(purchaseChangeOrder).Error
if err != nil {
begin.Rollback()
logger.Error("update erp_order err:", logger.Field("err", err))
return nil, err
}
// 2-更新采购订单商品表
err = updatePurchaseChangeCommodityData(begin, req.ChangeOrderId, req)
if err != nil {
begin.Rollback()
logger.Error("update erp_purchase_commodity err:", logger.Field("err", err))
return nil, err
}
err = begin.Commit().Error
if err != nil {
begin.Rollback()
logger.Error("commit err:", logger.Field("err", err))
return nil, err
}
return &purchaseChangeOrder, nil
}
// updatePurchaseChangeCommodityData 更新采购订单商品信息
func updatePurchaseChangeCommodityData(gdb *gorm.DB, orderId uint32, req *ErpPurchaseChangeEditReq) error {
// 查询现有的零售订单信息
var commodities []ErpPurchaseChangeCommodity
err := orm.Eloquent.Table("erp_purchase_change_commodity").Where("change_order_id = ?", orderId).Find(&commodities).Error
if err != nil {
logger.Error("query erp_purchase_change_commodity err:", logger.Field("err", err))
return err
}
// 1-删除所有的商品信息
if len(commodities) != 0 {
err = gdb.Delete(&commodities).Error
if err != nil {
logger.Error("更新商品订单信息-删除 error")
return errors.New("操作失败:" + err.Error())
}
}
for i, _ := range req.Commodities {
req.Commodities[i].ID = 0
if req.Commodities[i].ChangeOrderId == 0 { //发现前端有时会没传,后端打补丁
req.Commodities[i].ChangeOrderId = req.ChangeOrderId
}
}
// 2-更新商品订单信息-新增
if len(req.Commodities) != 0 {
err = gdb.Create(&req.Commodities).Error
if err != nil {
logger.Error("更新商品订单信息-新增 error")
return errors.New("操作失败:" + err.Error())
}
}
return nil
}
// List 查询采购订单列表
func (m *ErpPurchaseChangeOrderListReq) List(c *gin.Context) (*ErpPurchaseChangeOrderListResp, error) {
resp := &ErpPurchaseChangeOrderListResp{
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_purchase_change_order")
if m.SerialNumber != "" {
qs = qs.Where("serial_number=?", m.SerialNumber)
} else {
if m.StoreId != 0 {
qs = qs.Where("store_id=?", m.StoreId)
}
// 非管理员才判断所属门店
if !(tools.GetRoleName(c) == "admin" || tools.GetRoleName(c) == "系统管理员") {
sysUser, err := GetSysUserByCtx(c)
if err != nil {
return nil, errors.New("操作失败:" + err.Error())
}
// 返回sysUser未过期的门店id列表
storeList := GetValidStoreIDs(sysUser.StoreData)
if len(storeList) > 0 {
if len(storeList) == 1 {
qs = qs.Where("store_id = ?", storeList[0])
} else {
qs = qs.Where("store_id IN (?)", storeList)
}
} else {
return nil, errors.New("用户未绑定门店")
}
}
if m.ErpSupplierId != 0 {
qs = qs.Where("erp_supplier_id=?", m.ErpSupplierId)
}
if len(m.State) > 0 {
qs = qs.Where("state IN (?)", m.State)
}
if m.AuditTimeStart != "" {
parse, err := time.Parse(QueryTimeFormat, m.AuditTimeStart)
if err != nil {
logger.Errorf("erpPurchaseChangeOrderList err:", err)
return nil, err
}
qs = qs.Where("audit_time > ?", parse)
}
if m.AuditTimeEnd != "" {
parse, err := time.Parse(QueryTimeFormat, m.AuditTimeEnd)
if err != nil {
logger.Errorf("erpPurchaseChangeOrderList err:", err)
return nil, err
}
//parse = parse.AddDate(0, 0, 1)
qs = qs.Where("audit_time < ?", parse)
}
if m.HandlerId != 0 {
qs = qs.Where("handler_id=?", m.HandlerId)
}
}
var count int64
err := qs.Count(&count).Error
if err != nil {
logger.Error("count err:", logger.Field("err", err))
return resp, err
}
resp.Total = int(count)
var orders []ErpPurchaseChangeOrder
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
}
// 校验时间如果为01-01-01 08:05则赋值为空
for i, v := range orders {
if v.MakerTime != nil && v.MakerTime.IsZero() {
orders[i].MakerTime = nil
}
if v.AuditTime != nil && v.AuditTime.IsZero() {
orders[i].AuditTime = nil
}
}
resp.List = orders
return resp, nil
}
// AuditChangeOrder 审核采购换机订单
func AuditChangeOrder(begin *gorm.DB, req ErpPurchaseChangeOrder, state int) error {
2025-02-20 07:15:09 +00:00
var commodities []ErpPurchaseChangeCommodity
err := orm.Eloquent.Table("erp_purchase_change_commodity").Where("change_order_id = ?", req.ID).Find(&commodities).Error
2025-02-18 10:17:08 +00:00
if err != nil {
logger.Error("check erp_purchase_change_order err:", logger.Field("err", err))
return err
}
2025-02-20 07:15:09 +00:00
if state == 1 { // 审核
for i, _ := range commodities {
if commodities[i].IMEIType == 2 || commodities[i].IMEIType == 3 { // 串码商品
if commodities[i].OriginIMEI == "" {
2025-02-18 10:17:08 +00:00
return errors.New("串码为空")
}
var imeiStockCommodity ErpStockCommodity
err = orm.Eloquent.Table("erp_stock_commodity").Where("imei = ? and state = ?",
2025-02-20 07:15:09 +00:00
commodities[i].OriginIMEI, InStock).Find(&imeiStockCommodity).Error
2025-02-18 10:17:08 +00:00
if err != nil {
return err
}
if imeiStockCommodity.ID == 0 {
2025-02-20 07:15:09 +00:00
return errors.New("商品" + "[" + commodities[i].ErpCommodityName + "]库存不足")
2025-02-18 10:17:08 +00:00
}
if imeiStockCommodity.StoreId != req.StoreId {
2025-02-20 07:15:09 +00:00
return errors.New("商品" + "[" + commodities[i].OriginIMEI + "]非所选门店库存,请检查")
2025-02-18 10:17:08 +00:00
}
2025-02-20 07:15:09 +00:00
err = begin.Table("erp_stock_commodity").Where("imei = ?", commodities[i].OriginIMEI).
2025-02-18 10:17:08 +00:00
Updates(map[string]interface{}{
"state": PurchaseChange,
"updated_at": time.Now(),
}).Error // 状态更新为"采购换机"
if err != nil {
begin.Rollback()
logger.Error("commodities err:", logger.Field("err", err))
return err
}
// 新串码商品入库
newStockCommodity := imeiStockCommodity
newStockCommodity.ID = 0
2025-02-20 07:15:09 +00:00
newStockCommodity.IMEI = commodities[i].NewIMEI
newStockCommodity.StockSn = req.SerialNumber
err = begin.Create(&newStockCommodity).Error
2025-02-18 10:17:08 +00:00
if err != nil {
begin.Rollback()
logger.Error("create purchase order err:", logger.Field("err", err))
return err
}
} else {
return errors.New("非串码商品不支持采购换货")
}
}
2025-02-20 07:15:09 +00:00
} else if state == 2 { // 取消审核
for i, _ := range commodities {
2025-02-18 10:17:08 +00:00
// 查询新串码的库存情况
var imeiStockCommodity ErpStockCommodity
err = orm.Eloquent.Table("erp_stock_commodity").Where("imei = ? and state = ?",
2025-02-20 07:15:09 +00:00
commodities[i].NewIMEI, InStock).Find(&imeiStockCommodity).Error
2025-02-18 10:17:08 +00:00
if err != nil {
return err
}
if imeiStockCommodity.ID == 0 {
2025-02-20 07:15:09 +00:00
return errors.New("商品" + "[" + commodities[i].NewIMEI + "]不在库")
2025-02-18 10:17:08 +00:00
}
err = begin.Delete(imeiStockCommodity).Error // 删除新串码库存
if err != nil {
begin.Rollback()
logger.Error("commodities err:", logger.Field("err", err))
return err
}
// 更新旧串码为在库状态
2025-02-20 07:15:09 +00:00
err = begin.Table("erp_stock_commodity").Where("imei = ?", commodities[i].OriginIMEI).
2025-02-18 10:17:08 +00:00
Updates(map[string]interface{}{
"state": InStock,
"updated_at": time.Now(),
}).Error // 状态更新为"在库"
if err != nil {
begin.Rollback()
logger.Error("commodities err:", logger.Field("err", err))
return err
}
}
}
return nil
}