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 MakerTimeStart string `json:"make_time_start"` // 制单开始时间 MakerTimeEnd string `json:"make_time_end"` // 制单结束时间 AuditTimeStart string `json:"audit_time_start"` // 审核开始时间 AuditTimeEnd string `json:"audit_time_end"` // 审核结束时间 State []uint32 `json:"state"` // 状态:1-待审核 2-已完成 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 { return errors.New("操作失败:采购换机不支持非串码商品") } 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 { return errors.New("商品" + "[" + item.OriginIMEI + "]非所选门店库存,请检查") } // 判断新商品串码是否已录入或者使用过 var newImeiStockCommodity ErpStockCommodity err = orm.Eloquent.Table("erp_stock_commodity").Where("imei = ?", item.NewIMEI).Find(&newImeiStockCommodity).Error if err != nil { return err } if newImeiStockCommodity.ID != 0 { return errors.New("串码" + "[" + item.NewIMEI + "]重复") } } 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 { return errors.New("操作失败:采购换机不支持非串码商品") } 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 { return errors.New("商品" + "[" + item.OriginIMEI + "]非所选门店库存,请检查") } // 判断新商品串码是否已录入或者使用过 var newImeiStockCommodity ErpStockCommodity err = orm.Eloquent.Table("erp_stock_commodity").Where("imei = ?", item.NewIMEI).Find(&newImeiStockCommodity).Error if err != nil { return err } if newImeiStockCommodity.ID != 0 { 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.MakerTimeStart != "" { parse, err := time.Parse(QueryTimeFormat, m.MakerTimeStart) if err != nil { logger.Errorf("erpPurchaseChangeOrderList err:", err) return nil, err } qs = qs.Where("make_time > ?", parse) } if m.MakerTimeEnd != "" { parse, err := time.Parse(QueryTimeFormat, m.MakerTimeEnd) if err != nil { logger.Errorf("erpPurchaseChangeOrderList err:", err) return nil, err } //parse = parse.AddDate(0, 0, 1) qs = qs.Where("make_time < ?", parse) } if m.HandlerId != 0 { qs = qs.Where("handler_id=?", m.HandlerId) } 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 } } changeOrderListSetCommodity(orders) resp.List = orders return resp, nil } // AuditChangeOrder 审核采购换机订单 func AuditChangeOrder(begin *gorm.DB, req ErpPurchaseChangeOrder, state int) error { var commodities []ErpPurchaseChangeCommodity err := orm.Eloquent.Table("erp_purchase_change_commodity").Where("change_order_id = ?", req.ID).Find(&commodities).Error if err != nil { logger.Error("check erp_purchase_change_order err:", logger.Field("err", err)) return err } if state == 1 { // 审核 for i, _ := range commodities { if commodities[i].IMEIType == 2 || commodities[i].IMEIType == 3 { // 串码商品 if commodities[i].OriginIMEI == "" { return errors.New("串码为空") } var imeiStockCommodity ErpStockCommodity err = orm.Eloquent.Table("erp_stock_commodity").Where("imei = ? and state = ?", commodities[i].OriginIMEI, InStock).Find(&imeiStockCommodity).Error if err != nil { return err } if imeiStockCommodity.ID == 0 { return errors.New("商品" + "[" + commodities[i].ErpCommodityName + "]库存不足") } if imeiStockCommodity.StoreId != req.StoreId { return errors.New("商品" + "[" + commodities[i].OriginIMEI + "]非所选门店库存,请检查") } err = begin.Table("erp_stock_commodity").Where("imei = ?", commodities[i].OriginIMEI). 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 newStockCommodity.IMEI = commodities[i].NewIMEI newStockCommodity.StockSn = req.SerialNumber err = begin.Create(&newStockCommodity).Error if err != nil { begin.Rollback() logger.Error("create purchase order err:", logger.Field("err", err)) return err } } else { return errors.New("非串码商品不支持采购换货") } } } else if state == 2 { // 取消审核 for i, _ := range commodities { // 查询新串码的库存情况 var imeiStockCommodity ErpStockCommodity err = orm.Eloquent.Table("erp_stock_commodity").Where("imei = ? and state = ?", commodities[i].NewIMEI, InStock).Find(&imeiStockCommodity).Error if err != nil { return err } if imeiStockCommodity.ID == 0 { return errors.New("商品" + "[" + commodities[i].NewIMEI + "]不在库") } err = begin.Delete(imeiStockCommodity).Error // 删除新串码库存 if err != nil { begin.Rollback() logger.Error("commodities err:", logger.Field("err", err)) return err } // 更新旧串码为在库状态 err = begin.Table("erp_stock_commodity").Where("imei = ?", commodities[i].OriginIMEI). 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 } // 添加采购换机订单的商品信息 func changeOrderListSetCommodity(list []ErpPurchaseChangeOrder) { for i, _ := range list { list[i].SetCommodity() } } func (m *ErpPurchaseChangeOrder) SetCommodity() { var orderCommodities []ErpPurchaseChangeCommodity err := orm.Eloquent.Table("erp_purchase_change_commodity").Where("change_order_id = ?", m.ID).Find(&orderCommodities).Error if err != nil { logger.Error("SetCommodity query erp_purchase_change_commodity err:", logger.Field("err", err)) } m.Commodities = orderCommodities }