1.新增库存调拨相关接口(新增、编辑、审核、删除、列表、详情、发货、收货);
This commit is contained in:
parent
e5367b8c4e
commit
7c8a431c2b
|
@ -2,8 +2,12 @@ package inventorymanage
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"go-admin/app/admin/models"
|
"go-admin/app/admin/models"
|
||||||
|
orm "go-admin/common/global"
|
||||||
|
"go-admin/logger"
|
||||||
|
"go-admin/tools"
|
||||||
"go-admin/tools/app"
|
"go-admin/tools/app"
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
@ -19,14 +23,33 @@ import (
|
||||||
// @Success 200 {object} models.ErpInventoryAllotOrder
|
// @Success 200 {object} models.ErpInventoryAllotOrder
|
||||||
// @Router /api/v1/inventory/allot/add [post]
|
// @Router /api/v1/inventory/allot/add [post]
|
||||||
func InventoryAllotAdd(c *gin.Context) {
|
func InventoryAllotAdd(c *gin.Context) {
|
||||||
req := &models.ErpStockListReq{}
|
req := &models.InventoryAllotAddReq{}
|
||||||
if err := c.ShouldBindJSON(&req); err != nil {
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
//logger.Error(err)
|
app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误:"+err.Error())
|
||||||
app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
app.OK(c, "", "OK")
|
err := tools.Validate(req) //必填参数校验
|
||||||
|
if err != nil {
|
||||||
|
app.Error(c, http.StatusBadRequest, err, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
sysUser, err := models.GetSysUserByCtx(c)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("sys user err:", logger.Field("err", err))
|
||||||
|
app.Error(c, http.StatusInternalServerError, err, "操作失败")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
inventoryProductOrder, err := models.AddInventoryAllot(req, sysUser)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("InventoryAllotAdd err:", logger.Field("err", err))
|
||||||
|
app.Error(c, http.StatusInternalServerError, err, "新增失败:"+err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
app.OK(c, inventoryProductOrder, "新增成功")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,14 +62,26 @@ func InventoryAllotAdd(c *gin.Context) {
|
||||||
// @Success 200 {object} models.ErpInventoryAllotOrder
|
// @Success 200 {object} models.ErpInventoryAllotOrder
|
||||||
// @Router /api/v1/inventory/allot/edit [post]
|
// @Router /api/v1/inventory/allot/edit [post]
|
||||||
func InventoryAllotEdit(c *gin.Context) {
|
func InventoryAllotEdit(c *gin.Context) {
|
||||||
req := &models.ErpStockListReq{}
|
req := &models.InventoryAllotEditReq{}
|
||||||
if err := c.ShouldBindJSON(&req); err != nil {
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
//logger.Error(err)
|
app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误:"+err.Error())
|
||||||
app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
app.OK(c, "", "OK")
|
err := tools.Validate(req) //必填参数校验
|
||||||
|
if err != nil {
|
||||||
|
app.Error(c, http.StatusBadRequest, err, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
inventoryProductOrder, err := models.EditAllotInventory(req)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("InventoryAllotEdit err:", logger.Field("err", err))
|
||||||
|
app.Error(c, http.StatusInternalServerError, err, "编辑失败:"+err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
app.OK(c, inventoryProductOrder, "编辑成功")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,14 +94,27 @@ func InventoryAllotEdit(c *gin.Context) {
|
||||||
// @Success 200 {object} app.Response
|
// @Success 200 {object} app.Response
|
||||||
// @Router /api/v1/inventory/allot/audit [post]
|
// @Router /api/v1/inventory/allot/audit [post]
|
||||||
func InventoryAllotAudit(c *gin.Context) {
|
func InventoryAllotAudit(c *gin.Context) {
|
||||||
req := &models.ErpStockListReq{}
|
req := &models.InventoryAllotAuditReq{}
|
||||||
if err := c.ShouldBindJSON(&req); err != nil {
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
//logger.Error(err)
|
//logger.Error(err)
|
||||||
app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误")
|
app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误:"+err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
app.OK(c, "", "OK")
|
sysUser, err := models.GetSysUserByCtx(c)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("sys user err:", logger.Field("err", err))
|
||||||
|
app.Error(c, http.StatusInternalServerError, err, "操作失败")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = models.AuditAllotInventory(req, sysUser)
|
||||||
|
if err != nil {
|
||||||
|
app.Error(c, http.StatusInternalServerError, err, "审核失败:"+err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
app.OK(c, nil, "操作成功")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,11 +130,77 @@ func InventoryAllotDelete(c *gin.Context) {
|
||||||
req := &models.InventoryAllotDeleteReq{}
|
req := &models.InventoryAllotDeleteReq{}
|
||||||
if err := c.ShouldBindJSON(&req); err != nil {
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
//logger.Error(err)
|
//logger.Error(err)
|
||||||
app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误")
|
app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误:"+err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
app.OK(c, "", "OK")
|
err := tools.Validate(req) //必填参数校验
|
||||||
|
if err != nil {
|
||||||
|
app.Error(c, http.StatusBadRequest, err, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo 需要校验当前用户是否有权限
|
||||||
|
|
||||||
|
var inventoryAllotOrder models.ErpInventoryAllotOrder
|
||||||
|
err = orm.Eloquent.Table("erp_inventory_allot_order").Where("serial_number = ?", req.SerialNumber).
|
||||||
|
Find(&inventoryAllotOrder).Error
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("order err:", logger.Field("err", err))
|
||||||
|
app.Error(c, http.StatusInternalServerError, err, "删除失败:"+err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if inventoryAllotOrder.SerialNumber == "" {
|
||||||
|
logger.Error("order is null")
|
||||||
|
app.Error(c, http.StatusInternalServerError, err, "删除失败:订单不存在")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 仅待审核订单可删除
|
||||||
|
if inventoryAllotOrder.State != models.ErpInventoryAllotOrderUnAudit {
|
||||||
|
logger.Error("order err, inventoryAllotOrder.State is:", logger.Field("inventoryAllotOrder.State",
|
||||||
|
inventoryAllotOrder.State))
|
||||||
|
app.Error(c, http.StatusInternalServerError, err, "删除失败:仅待审核订单可删除")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
begin := orm.Eloquent.Begin()
|
||||||
|
// 1-删除采购订单表
|
||||||
|
err = begin.Delete(inventoryAllotOrder).Error
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("order delete1 err:", logger.Field("err", err))
|
||||||
|
app.Error(c, http.StatusInternalServerError, err, "删除失败:"+err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2-删除采购订单商品表
|
||||||
|
var commodities []models.ErpInventoryAllotCommodity
|
||||||
|
err = orm.Eloquent.Table("erp_inventory_allot_commodity").Where("allot_order_id = ?",
|
||||||
|
inventoryAllotOrder.ID).Find(&commodities).Error
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("query erp_inventory_allot_commodity err:", logger.Field("err", err))
|
||||||
|
app.Error(c, http.StatusInternalServerError, err, "删除失败:"+err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(commodities) != 0 {
|
||||||
|
err = begin.Delete(&commodities).Error
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("更新商品订单信息-删除 error")
|
||||||
|
app.Error(c, http.StatusInternalServerError, err, "删除失败:"+err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = begin.Commit().Error
|
||||||
|
if err != nil {
|
||||||
|
begin.Rollback()
|
||||||
|
logger.Error("commit err:", logger.Field("err", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
app.OK(c, nil, "删除成功")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,11 +216,17 @@ func InventoryAllotList(c *gin.Context) {
|
||||||
req := &models.InventoryAllotListReq{}
|
req := &models.InventoryAllotListReq{}
|
||||||
if err := c.ShouldBindJSON(&req); err != nil {
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
//logger.Error(err)
|
//logger.Error(err)
|
||||||
app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误")
|
app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误:"+err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
app.OK(c, "", "OK")
|
resp, err := req.List()
|
||||||
|
if err != nil {
|
||||||
|
app.Error(c, http.StatusInternalServerError, err, "获取失败:"+err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
app.OK(c, resp, "查询成功")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,12 +241,42 @@ func InventoryAllotList(c *gin.Context) {
|
||||||
func InventoryAllotDetail(c *gin.Context) {
|
func InventoryAllotDetail(c *gin.Context) {
|
||||||
req := &models.InventoryAllotDetailReq{}
|
req := &models.InventoryAllotDetailReq{}
|
||||||
if err := c.ShouldBindJSON(&req); err != nil {
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
//logger.Error(err)
|
app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误:"+err.Error())
|
||||||
app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
app.OK(c, "", "OK")
|
var allotOrder models.ErpInventoryAllotOrder
|
||||||
|
err := orm.Eloquent.Table("erp_inventory_allot_order").Where("serial_number=?", req.SerialNumber).Find(&allotOrder).Error
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("allot order err:", logger.Field("err", err))
|
||||||
|
app.Error(c, http.StatusBadRequest, err, "获取失败")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if allotOrder.ID == 0 {
|
||||||
|
logger.Error("allot commodities err:", logger.Field("err", err))
|
||||||
|
app.Error(c, http.StatusBadRequest, err, fmt.Sprintf("未查询到订单[%s]", req.SerialNumber))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 校验时间,如果为01-01-01 08:05,则赋值为空
|
||||||
|
if allotOrder.MakerTime != nil && allotOrder.MakerTime.IsZero() {
|
||||||
|
allotOrder.MakerTime = nil
|
||||||
|
}
|
||||||
|
if allotOrder.AuditTime != nil && allotOrder.AuditTime.IsZero() {
|
||||||
|
allotOrder.AuditTime = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var allotCommodities []models.ErpInventoryAllotCommodity
|
||||||
|
err = orm.Eloquent.Table("erp_inventory_allot_commodity").Where("allot_order_id=?", allotOrder.ID).
|
||||||
|
Find(&allotCommodities).Error
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("allot commodities err:", logger.Field("err", err))
|
||||||
|
app.Error(c, http.StatusBadRequest, err, "获取失败")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
allotOrder.Commodities = allotCommodities
|
||||||
|
app.OK(c, allotOrder, "查询成功")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,11 +292,17 @@ func InventoryAllotDeliver(c *gin.Context) {
|
||||||
req := &models.InventoryAllotDeliverReq{}
|
req := &models.InventoryAllotDeliverReq{}
|
||||||
if err := c.ShouldBindJSON(&req); err != nil {
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
//logger.Error(err)
|
//logger.Error(err)
|
||||||
app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误")
|
app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误:"+err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
app.OK(c, "", "OK")
|
err := models.DeliverAllotInventory(req)
|
||||||
|
if err != nil {
|
||||||
|
app.Error(c, http.StatusInternalServerError, err, "操作失败:"+err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
app.OK(c, nil, "操作成功")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,10 +318,16 @@ func InventoryAllotReceive(c *gin.Context) {
|
||||||
req := &models.InventoryAllotReceiveReq{}
|
req := &models.InventoryAllotReceiveReq{}
|
||||||
if err := c.ShouldBindJSON(&req); err != nil {
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
//logger.Error(err)
|
//logger.Error(err)
|
||||||
app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误")
|
app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误:"+err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
app.OK(c, "", "OK")
|
err := models.ReceiveAllotInventory(req)
|
||||||
|
if err != nil {
|
||||||
|
app.Error(c, http.StatusInternalServerError, err, "操作失败:"+err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
app.OK(c, nil, "操作成功")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ const (
|
||||||
InStock = 1 // 在库
|
InStock = 1 // 在库
|
||||||
SoldOut = 2 // 已售
|
SoldOut = 2 // 已售
|
||||||
PurchaseReturn = 3 // 采购退货
|
PurchaseReturn = 3 // 采购退货
|
||||||
InAllot = 4 // 调拨中
|
InAllot = 4 // 调拨中(调入门店)
|
||||||
OnSale = 5 // 销售锁定中
|
OnSale = 5 // 销售锁定中
|
||||||
ProductReturn = 6 // 产品出库
|
ProductReturn = 6 // 产品出库
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,6 +1,20 @@
|
||||||
package models
|
package models
|
||||||
|
|
||||||
import "time"
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
orm "go-admin/common/global"
|
||||||
|
"go-admin/logger"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
ErpInventoryAllotOrderUnAudit = 1 // 库存调拨-待审核
|
||||||
|
ErpInventoryAllotOrderWaitSend = 2 // 库存调拨-待发货
|
||||||
|
ErpInventoryAllotOrderWaitReceive = 3 // 库存调拨-待收货
|
||||||
|
ErpInventoryAllotOrderFinished = 4 // 库存调拨-已完成
|
||||||
|
)
|
||||||
|
|
||||||
// ErpInventoryAllotOrder 库存调拨订单表
|
// ErpInventoryAllotOrder 库存调拨订单表
|
||||||
type ErpInventoryAllotOrder struct {
|
type ErpInventoryAllotOrder struct {
|
||||||
|
@ -104,3 +118,742 @@ type InventoryAllotDeliverReq struct {
|
||||||
type InventoryAllotReceiveReq struct {
|
type InventoryAllotReceiveReq struct {
|
||||||
SerialNumber string `json:"serial_number" binding:"required"` // 单据编号
|
SerialNumber string `json:"serial_number" binding:"required"` // 单据编号
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 检查新增库存调拨信息
|
||||||
|
func checkAllotInventoryParam(req *InventoryAllotAddReq, editFlag bool) error {
|
||||||
|
if len(req.Commodities) == 0 {
|
||||||
|
return errors.New("商品信息为空")
|
||||||
|
}
|
||||||
|
|
||||||
|
noIMEICommodityMap := make(map[uint32]bool, 0)
|
||||||
|
for _, item := range req.Commodities {
|
||||||
|
// 校验数量
|
||||||
|
if item.Count <= 0 {
|
||||||
|
return fmt.Errorf("商品[%s]数量[%d]错误,需大于0", item.CommodityName, item.Count)
|
||||||
|
} else {
|
||||||
|
if item.Count != 1 && item.IMEIType != NoIMEICommodity { // 串码商品数量不为1,则报错
|
||||||
|
return fmt.Errorf("串码商品[%s]数量[%d]错误,需为1", item.CommodityName, item.Count)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 校验编辑订单时是否有传商品ID
|
||||||
|
if editFlag {
|
||||||
|
if item.ID == 0 {
|
||||||
|
return fmt.Errorf("商品[%s]ID为空", item.CommodityName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 校验串码类型
|
||||||
|
switch item.IMEIType {
|
||||||
|
case 1, 2, 3:
|
||||||
|
// 串码商品校验串码是否为空
|
||||||
|
if item.IMEIType != NoIMEICommodity && item.IMEI == "" {
|
||||||
|
return fmt.Errorf("[%s]是串码商品,其串码不能为空", item.CommodityName)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("商品[%s]串码类型[%d]错误", item.CommodityName, item.IMEIType)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 校验非串码商品是否重复
|
||||||
|
if item.IMEIType == NoIMEICommodity {
|
||||||
|
_, ok := noIMEICommodityMap[item.CommodityId]
|
||||||
|
if !ok {
|
||||||
|
noIMEICommodityMap[item.CommodityId] = true
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("商品[%s]重复,相同的非串码商品只能有1条数据", item.CommodityName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查调出门店是否有对应商品,调拨数量是否 < 商品库存数量
|
||||||
|
var stockCount int64
|
||||||
|
var err error
|
||||||
|
if item.IMEIType == NoIMEICommodity { // 非串码商品
|
||||||
|
err = orm.Eloquent.Table("erp_stock_commodity").
|
||||||
|
Where("erp_commodity_id = ? AND store_id = ? AND state = 1", item.CommodityId, req.DeliverStoreId).
|
||||||
|
Count(&stockCount).Error
|
||||||
|
} else { // 串码商品
|
||||||
|
err = orm.Eloquent.Table("erp_stock_commodity").
|
||||||
|
Where("erp_commodity_id = ? AND store_id = ? AND state = 1 AND imei = ?", item.CommodityId,
|
||||||
|
req.DeliverStoreId, item.IMEI).Count(&stockCount).Error
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return errors.New("查询商品库存失败," + err.Error())
|
||||||
|
}
|
||||||
|
if stockCount == 0 {
|
||||||
|
return fmt.Errorf("商品[%s]库存数量为0", item.CommodityName)
|
||||||
|
}
|
||||||
|
if stockCount < int64(item.Count) {
|
||||||
|
return fmt.Errorf("商品[%s]库存数量[%d]少于调拨数量[%d]", item.CommodityName, stockCount, item.Count)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddInventoryAllot 新增库存调拨
|
||||||
|
func AddInventoryAllot(req *InventoryAllotAddReq, sysUser *SysUser) (*ErpInventoryAllotOrder, error) {
|
||||||
|
// 检查库存调拨信息
|
||||||
|
if err := checkAllotInventoryParam(req, false); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
nowTime := time.Now()
|
||||||
|
|
||||||
|
// 计算库存调拨的总数量
|
||||||
|
var nTotalCount uint32
|
||||||
|
for i, _ := range req.Commodities {
|
||||||
|
nTotalCount += req.Commodities[i].Count // 数量
|
||||||
|
}
|
||||||
|
|
||||||
|
// 组合库存调拨订单数据
|
||||||
|
inventoryAllotOrder := &ErpInventoryAllotOrder{
|
||||||
|
SerialNumber: "db" + NewProductInventorySn(),
|
||||||
|
DeliverStoreId: req.DeliverStoreId,
|
||||||
|
DeliverStoreName: req.DeliverStoreName,
|
||||||
|
ReceiveStoreId: req.ReceiveStoreId,
|
||||||
|
ReceiveStoreName: req.ReceiveStoreName,
|
||||||
|
HandlerId: req.HandlerId,
|
||||||
|
HandlerName: req.HandlerName,
|
||||||
|
MakerTime: &nowTime,
|
||||||
|
MakerId: uint32(sysUser.UserId),
|
||||||
|
MakerName: sysUser.NickName,
|
||||||
|
State: ErpInventoryAllotOrderUnAudit,
|
||||||
|
TotalCount: nTotalCount,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建库存调拨订单
|
||||||
|
begin := orm.Eloquent.Begin()
|
||||||
|
err = begin.Create(inventoryAllotOrder).Error
|
||||||
|
if err != nil {
|
||||||
|
begin.Rollback()
|
||||||
|
logger.Error("create allot order err:", logger.Field("err", err))
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建库存调拨商品信息,添加库存调拨订单id
|
||||||
|
for i, _ := range req.Commodities {
|
||||||
|
req.Commodities[i].AllotOrderId = inventoryAllotOrder.ID
|
||||||
|
err = begin.Create(&req.Commodities[i]).Error
|
||||||
|
if err != nil {
|
||||||
|
begin.Rollback()
|
||||||
|
logger.Error("create allot commodity err:", logger.Field("err", err))
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = begin.Commit().Error
|
||||||
|
if err != nil {
|
||||||
|
begin.Rollback()
|
||||||
|
logger.Error("commit allot commodity err:", logger.Field("err", err))
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return inventoryAllotOrder, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// EditAllotInventory 编辑库存调拨
|
||||||
|
func EditAllotInventory(req *InventoryAllotEditReq) (*ErpInventoryAllotOrder, error) {
|
||||||
|
// 查询订单信息
|
||||||
|
var inventoryAllotOrder ErpInventoryAllotOrder
|
||||||
|
err := orm.Eloquent.Table("erp_inventory_allot_order").Where("serial_number = ?", req.SerialNumber).
|
||||||
|
Find(&inventoryAllotOrder).Error
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("allot order err:", logger.Field("err", err))
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 未找到订单
|
||||||
|
if inventoryAllotOrder.ID == 0 {
|
||||||
|
return nil, fmt.Errorf("未找到该订单,请检查单据编号[%s]", req.SerialNumber)
|
||||||
|
}
|
||||||
|
|
||||||
|
if inventoryAllotOrder.State != ErpInventoryAllotOrderUnAudit { // 只有待审核的订单才能编辑
|
||||||
|
return nil, errors.New("订单不是待审核状态")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查库存调拨信息
|
||||||
|
if err = checkAllotInventoryParam(&req.InventoryAllotAddReq, true); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算库存调拨的总数量
|
||||||
|
var nTotalCount uint32
|
||||||
|
for i, _ := range req.Commodities {
|
||||||
|
nTotalCount += req.Commodities[i].Count // 数量
|
||||||
|
}
|
||||||
|
|
||||||
|
begin := orm.Eloquent.Begin()
|
||||||
|
// 1-更新库存调拨信息
|
||||||
|
inventoryAllotOrder.DeliverStoreId = req.DeliverStoreId
|
||||||
|
inventoryAllotOrder.DeliverStoreName = req.DeliverStoreName
|
||||||
|
inventoryAllotOrder.ReceiveStoreId = req.ReceiveStoreId
|
||||||
|
inventoryAllotOrder.ReceiveStoreName = req.ReceiveStoreName
|
||||||
|
inventoryAllotOrder.HandlerId = req.HandlerId
|
||||||
|
inventoryAllotOrder.HandlerName = req.HandlerName
|
||||||
|
inventoryAllotOrder.TotalCount = nTotalCount
|
||||||
|
|
||||||
|
err = begin.Model(&ErpInventoryAllotOrder{}).Where("id = ?", inventoryAllotOrder.ID).
|
||||||
|
Updates(inventoryAllotOrder).Error
|
||||||
|
if err != nil {
|
||||||
|
begin.Rollback()
|
||||||
|
logger.Error("update allot order err:", logger.Field("err", err))
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2-更新库存调拨商品表
|
||||||
|
err = updateAllotCommodityData(begin, inventoryAllotOrder.ID, req)
|
||||||
|
if err != nil {
|
||||||
|
begin.Rollback()
|
||||||
|
logger.Error("update erp_inventory_allot_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 &inventoryAllotOrder, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// updateAllotCommodityData 更新库存调拨商品信息
|
||||||
|
func updateAllotCommodityData(gdb *gorm.DB, orderId uint32, req *InventoryAllotEditReq) error {
|
||||||
|
// 查询现有的零售订单信息
|
||||||
|
var commodities []ErpInventoryAllotCommodity
|
||||||
|
err := orm.Eloquent.Table("erp_inventory_allot_commodity").Where("allot_order_id = ?", orderId).Find(&commodities).Error
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("query erp_inventory_allot_commodity err:", logger.Field("err", err))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var newCommodities []ErpInventoryAllotCommodity
|
||||||
|
var deletedCommodities []ErpInventoryAllotCommodity
|
||||||
|
var matchingCommodities []ErpInventoryAllotCommodity
|
||||||
|
// 找到新增的商品
|
||||||
|
for i, reqCommodity := range req.Commodities {
|
||||||
|
// 订单商品表信息添加零售订单id
|
||||||
|
req.Commodities[i].AllotOrderId = orderId
|
||||||
|
|
||||||
|
var found bool
|
||||||
|
for _, dbCommodity := range commodities {
|
||||||
|
if reqCommodity.CommodityId == dbCommodity.CommodityId && reqCommodity.IMEI == dbCommodity.IMEI {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
newCommodities = append(newCommodities, reqCommodity)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 找到删除的商品
|
||||||
|
for _, dbCommodity := range commodities {
|
||||||
|
var found bool
|
||||||
|
for _, reqCommodity := range req.Commodities {
|
||||||
|
if reqCommodity.CommodityId == dbCommodity.CommodityId && reqCommodity.IMEI == dbCommodity.IMEI {
|
||||||
|
found = true
|
||||||
|
// 找到匹配的商品,加入匹配列表
|
||||||
|
matchingCommodities = append(matchingCommodities, reqCommodity)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
deletedCommodities = append(deletedCommodities, dbCommodity)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2-更新商品订单信息-更新
|
||||||
|
for _, commodity := range matchingCommodities {
|
||||||
|
if err := gdb.Model(&ErpInventoryAllotCommodity{}).Where("id = ?", commodity.ID).Updates(commodity).Error; err != nil {
|
||||||
|
logger.Error("更新商品订单信息-更新 error")
|
||||||
|
return errors.New("操作失败:" + err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2-更新商品订单信息-新增
|
||||||
|
if len(newCommodities) != 0 {
|
||||||
|
err = gdb.Create(&newCommodities).Error
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("更新商品订单信息-新增 error")
|
||||||
|
return errors.New("操作失败:" + err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//2-更新商品订单信息-删除
|
||||||
|
if len(deletedCommodities) != 0 {
|
||||||
|
err = gdb.Delete(&deletedCommodities).Error
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("更新商品订单信息-删除 error")
|
||||||
|
return errors.New("操作失败:" + err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// List 查询采购订单列表
|
||||||
|
func (m *InventoryAllotListReq) List() (*InventoryAllotListResp, error) {
|
||||||
|
resp := &InventoryAllotListResp{
|
||||||
|
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_inventory_allot_order")
|
||||||
|
if m.SerialNumber != "" {
|
||||||
|
qs = qs.Where("serial_number=?", m.SerialNumber)
|
||||||
|
} else {
|
||||||
|
if m.DeliverStoreId != 0 {
|
||||||
|
qs = qs.Where("deliver_store_id=?", m.DeliverStoreId)
|
||||||
|
}
|
||||||
|
if m.ReceiveStoreId != 0 {
|
||||||
|
qs = qs.Where("receive_store_id=?", m.ReceiveStoreId)
|
||||||
|
}
|
||||||
|
if m.HandlerId != 0 {
|
||||||
|
qs = qs.Where("handler_id=?", m.HandlerId)
|
||||||
|
}
|
||||||
|
if m.State != 0 {
|
||||||
|
qs = qs.Where("state=?", m.State)
|
||||||
|
}
|
||||||
|
if m.AuditTimeStart != "" {
|
||||||
|
parse, err := time.Parse(QueryTimeFormat, m.AuditTimeStart)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("AllotInventoryList 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("AllotInventoryList err:", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
qs = qs.Where("audit_time < ?", parse)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 []ErpInventoryAllotOrder
|
||||||
|
err = qs.Order("id DESC").Offset(page * m.PageSize).Limit(m.PageSize).Find(&orders).Error
|
||||||
|
if err != nil && err != RecordNotFound {
|
||||||
|
logger.Error("allot 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
|
||||||
|
}
|
||||||
|
|
||||||
|
// AuditAllotInventory 审核产品入库 state:1-审核,2-取消审核
|
||||||
|
func AuditAllotInventory(req *InventoryAllotAuditReq, sysUser *SysUser) error {
|
||||||
|
// 查询订单信息
|
||||||
|
var inventoryAllotOrder ErpInventoryAllotOrder
|
||||||
|
err := orm.Eloquent.Table("erp_inventory_allot_order").Where("serial_number = ?", req.SerialNumber).
|
||||||
|
Find(&inventoryAllotOrder).Error
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("order err:", logger.Field("err", err))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if inventoryAllotOrder.ID == 0 {
|
||||||
|
return errors.New("未查询到订单信息")
|
||||||
|
}
|
||||||
|
|
||||||
|
begin := orm.Eloquent.Begin()
|
||||||
|
|
||||||
|
// 判断入参state:1-审核,2-取消审核
|
||||||
|
orderState := 0
|
||||||
|
switch req.State {
|
||||||
|
case 1: // 1-审核:待审核状态可以审核
|
||||||
|
if inventoryAllotOrder.State != ErpInventoryAllotOrderUnAudit { // 订单不是未审核状态
|
||||||
|
return errors.New("订单已审核,无需再次审核")
|
||||||
|
}
|
||||||
|
orderState = ErpInventoryAllotOrderWaitSend
|
||||||
|
// 更新商品的库存状态
|
||||||
|
err = allotAuditAndUpdateStock(begin, inventoryAllotOrder)
|
||||||
|
if err != nil {
|
||||||
|
begin.Rollback()
|
||||||
|
logger.Error("ProductAuditAndUpdateStock err:", logger.Field("err", err))
|
||||||
|
return fmt.Errorf("审核失败,%s", err.Error())
|
||||||
|
}
|
||||||
|
case 2: // 2-取消审核
|
||||||
|
orderState = ErpInventoryAllotOrderUnAudit
|
||||||
|
if inventoryAllotOrder.State == ErpInventoryAllotOrderUnAudit { // 订单未审核
|
||||||
|
return errors.New("订单是未审核状态,无需取消审核")
|
||||||
|
}
|
||||||
|
// 更新商品的库存状态
|
||||||
|
err = cancelAllotAuditAndUpdateStock(begin, inventoryAllotOrder)
|
||||||
|
if err != nil {
|
||||||
|
begin.Rollback()
|
||||||
|
return fmt.Errorf("取消审核失败,%s", err.Error())
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
logger.Error("order err, req.State is:", logger.Field("req.State", req.State))
|
||||||
|
return errors.New("参数有误")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新库存调拨订单表
|
||||||
|
err = begin.Table("erp_inventory_allot_order").Where("id = ?", inventoryAllotOrder.ID).
|
||||||
|
Updates(map[string]interface{}{
|
||||||
|
"state": orderState,
|
||||||
|
"auditor_id": sysUser.UserId,
|
||||||
|
"audit_time": time.Now(),
|
||||||
|
"auditor_name": sysUser.NickName,
|
||||||
|
}).Error
|
||||||
|
if err != nil {
|
||||||
|
begin.Rollback()
|
||||||
|
logger.Error("update erp_inventory_allot_order err:", logger.Field("err", err))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = begin.Commit().Error
|
||||||
|
if err != nil {
|
||||||
|
begin.Rollback()
|
||||||
|
logger.Errorf("commit err:", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// allotAuditAndUpdateStock 库存调拨审核后更新库存信息
|
||||||
|
func allotAuditAndUpdateStock(gdb *gorm.DB, allotOrder ErpInventoryAllotOrder) error {
|
||||||
|
// 查询库存调拨商品信息
|
||||||
|
var commodities []ErpInventoryAllotCommodity
|
||||||
|
err := orm.Eloquent.Table("erp_inventory_allot_commodity").Where("allot_order_id = ?",
|
||||||
|
allotOrder.ID).Find(&commodities).Error
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("query erp_inventory_allot_commodity err:", logger.Field("err", err))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 遍历库存调拨商品信息
|
||||||
|
for _, v := range commodities {
|
||||||
|
var stockCommodity []ErpStockCommodity
|
||||||
|
err = orm.Eloquent.Table("erp_stock_commodity").Where("erp_commodity_id = ? AND store_id = ? "+
|
||||||
|
"AND state = ? AND imei = ?", v.CommodityId, allotOrder.DeliverStoreId, InStock, v.IMEI).
|
||||||
|
Find(&stockCommodity).Error
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("审核失败,查询商品库存失败:[%s]", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(stockCommodity) == 0 {
|
||||||
|
return fmt.Errorf("审核失败,未找到商品库存信息")
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.Count > uint32(len(stockCommodity)) {
|
||||||
|
return fmt.Errorf("审核失败,商品[%s]库存数量[%d]少于调拨数量[%d]", v.CommodityName,
|
||||||
|
len(stockCommodity), v.Count)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新库存商品表商品状态为:调拨中
|
||||||
|
for i := 0; i < int(v.Count); i++ {
|
||||||
|
stockCommodity[i].StoreId = allotOrder.ReceiveStoreId
|
||||||
|
stockCommodity[i].StoreName = allotOrder.ReceiveStoreName
|
||||||
|
stockCommodity[i].State = InAllot
|
||||||
|
if err := gdb.Model(&ErpStockCommodity{}).Where("id = ?", stockCommodity[i].ID).
|
||||||
|
Updates(stockCommodity[i]).Error; err != nil {
|
||||||
|
return fmt.Errorf("审核失败,更新商品库存失败:%s", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新库存商品数量
|
||||||
|
err = gdb.Exec(fmt.Sprintf(
|
||||||
|
"UPDATE erp_stock SET count=count-%d WHERE store_id=%d AND erp_commodity_id=%d",
|
||||||
|
v.Count, allotOrder.DeliverStoreId, v.CommodityId)).Error
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("update stock err:", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// cancelAllotAuditAndUpdateStock 库存调拨反审核后更新库存信息
|
||||||
|
func cancelAllotAuditAndUpdateStock(gdb *gorm.DB, allotOrder ErpInventoryAllotOrder) error {
|
||||||
|
// 查询库存调拨商品信息
|
||||||
|
var commodities []ErpInventoryAllotCommodity
|
||||||
|
if err := orm.Eloquent.Table("erp_inventory_allot_commodity").Where("allot_order_id = ?",
|
||||||
|
allotOrder.ID).Find(&commodities).Error; err != nil {
|
||||||
|
logger.Error("query erp_inventory_allot_commodity err:", logger.Field("err", err))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(commodities) == 0 {
|
||||||
|
return errors.New("取消审核失败,未查询到库存调拨商品信息")
|
||||||
|
}
|
||||||
|
|
||||||
|
switch allotOrder.State {
|
||||||
|
// 2 待发货:状态改为待审核,调拨中库存恢复为在库
|
||||||
|
// 3 待收货:状态改为待审核,调拨中库存恢复为在库
|
||||||
|
case ErpInventoryAllotOrderWaitSend, ErpInventoryAllotOrderWaitReceive:
|
||||||
|
// 遍历库存调拨商品信息
|
||||||
|
for _, v := range commodities {
|
||||||
|
var stockCommodity []ErpStockCommodity
|
||||||
|
err := orm.Eloquent.Table("erp_stock_commodity").Where("erp_commodity_id = ? AND store_id = ? "+
|
||||||
|
"AND state = ? AND imei = ?", v.CommodityId, allotOrder.ReceiveStoreId, InAllot, v.IMEI).
|
||||||
|
Find(&stockCommodity).Error
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("查询商品库存失败:[%s]", err.Error())
|
||||||
|
}
|
||||||
|
if len(stockCommodity) == 0 {
|
||||||
|
return fmt.Errorf("未找到商品库存信息")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新库存商品表商品状态为:在库
|
||||||
|
for i := 0; i < int(v.Count); i++ {
|
||||||
|
stockCommodity[i].StoreId = allotOrder.DeliverStoreId
|
||||||
|
stockCommodity[i].StoreName = allotOrder.DeliverStoreName
|
||||||
|
stockCommodity[i].State = InStock
|
||||||
|
err = gdb.Model(&ErpStockCommodity{}).Where("id = ?", stockCommodity[i].ID).
|
||||||
|
Updates(stockCommodity[i]).Error
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("更新商品库存失败:%s", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新库存商品数量
|
||||||
|
err = gdb.Exec(fmt.Sprintf(
|
||||||
|
"UPDATE erp_stock SET count=count+%d WHERE store_id=%d AND erp_commodity_id=%d",
|
||||||
|
v.Count, allotOrder.DeliverStoreId, v.CommodityId)).Error
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("update stock err:", err)
|
||||||
|
return fmt.Errorf("更新库存商品数量失败:%s", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
case ErpInventoryAllotOrderFinished: // 已完成:状态改为待审核,调入门店对应商品的库存更新到调出门店,如果库存不足则报错
|
||||||
|
// 遍历库存调拨商品信息
|
||||||
|
for _, v := range commodities {
|
||||||
|
var stockCommodity []ErpStockCommodity
|
||||||
|
err := orm.Eloquent.Table("erp_stock_commodity").Where("erp_commodity_id = ? AND store_id = ? "+
|
||||||
|
"AND state = ? AND imei = ?", v.CommodityId, allotOrder.ReceiveStoreId, InStock, v.IMEI).
|
||||||
|
Find(&stockCommodity).Error
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("查询商品库存失败:[%s]", err.Error())
|
||||||
|
}
|
||||||
|
if len(stockCommodity) == 0 {
|
||||||
|
return fmt.Errorf("未找到商品库存信息")
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.Count > uint32(len(stockCommodity)) {
|
||||||
|
return fmt.Errorf("商品[%s]库存数量[%d]不足", v.CommodityName, len(stockCommodity))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新库存商品表商品状态为:在库
|
||||||
|
for i := 0; i < int(v.Count); i++ {
|
||||||
|
stockCommodity[i].StoreId = allotOrder.DeliverStoreId
|
||||||
|
stockCommodity[i].StoreName = allotOrder.DeliverStoreName
|
||||||
|
stockCommodity[i].State = InStock
|
||||||
|
err = gdb.Model(&ErpStockCommodity{}).Where("id = ?", stockCommodity[i].ID).
|
||||||
|
Updates(stockCommodity[i]).Error
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("更新商品库存失败:%s", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新库存商品数量
|
||||||
|
// 调入门店减去对应调入的数量
|
||||||
|
err = gdb.Exec(fmt.Sprintf(
|
||||||
|
"UPDATE erp_stock SET count=count-%d WHERE store_id=%d AND erp_commodity_id=%d",
|
||||||
|
v.Count, allotOrder.ReceiveStoreId, v.CommodityId)).Error
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("update stock err:", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调出门店加上对应调出的数量
|
||||||
|
err = gdb.Exec(fmt.Sprintf(
|
||||||
|
"UPDATE erp_stock SET count=count+%d WHERE store_id=%d AND erp_commodity_id=%d",
|
||||||
|
v.Count, allotOrder.DeliverStoreId, v.CommodityId)).Error
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("update stock err:", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("订单当前状态未知[%d]", allotOrder.State)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新库存调拨订单信息
|
||||||
|
allotOrder.State = ErpInventoryAllotOrderUnAudit
|
||||||
|
err := gdb.Model(&ErpInventoryAllotOrder{}).Where("id = ?", allotOrder.ID).
|
||||||
|
Updates(allotOrder).Error
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("更新库存调拨订单失败:%s", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeliverAllotInventory 调拨发货
|
||||||
|
func DeliverAllotInventory(req *InventoryAllotDeliverReq) error {
|
||||||
|
// 查询订单信息
|
||||||
|
var inventoryAllotOrder ErpInventoryAllotOrder
|
||||||
|
err := orm.Eloquent.Table("erp_inventory_allot_order").Where("serial_number = ?", req.SerialNumber).
|
||||||
|
Find(&inventoryAllotOrder).Error
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("order err:", logger.Field("err", err))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if inventoryAllotOrder.ID == 0 {
|
||||||
|
return errors.New("未查询到订单信息")
|
||||||
|
}
|
||||||
|
|
||||||
|
if inventoryAllotOrder.State != ErpInventoryAllotOrderWaitSend {
|
||||||
|
return errors.New("订单不是待发货状态")
|
||||||
|
}
|
||||||
|
|
||||||
|
inventoryAllotOrder.LogisticsNumber = req.LogisticsNumber
|
||||||
|
inventoryAllotOrder.Remark = req.Remark
|
||||||
|
inventoryAllotOrder.State = ErpInventoryAllotOrderWaitReceive
|
||||||
|
|
||||||
|
err = orm.Eloquent.Model(&ErpInventoryAllotOrder{}).Where("id = ?", inventoryAllotOrder.ID).
|
||||||
|
Updates(inventoryAllotOrder).Error
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReceiveAllotInventory 调拨收货
|
||||||
|
func ReceiveAllotInventory(req *InventoryAllotReceiveReq) error {
|
||||||
|
// 查询订单信息
|
||||||
|
var inventoryAllotOrder ErpInventoryAllotOrder
|
||||||
|
if err := orm.Eloquent.Table("erp_inventory_allot_order").Where("serial_number = ?", req.SerialNumber).
|
||||||
|
Find(&inventoryAllotOrder).Error; err != nil {
|
||||||
|
logger.Error("order err:", logger.Field("err", err))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if inventoryAllotOrder.ID == 0 {
|
||||||
|
return errors.New("未查询到订单信息")
|
||||||
|
}
|
||||||
|
|
||||||
|
if inventoryAllotOrder.State != ErpInventoryAllotOrderWaitReceive {
|
||||||
|
return errors.New("订单不是待收货状态")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询库存调拨商品信息
|
||||||
|
var commodities []ErpInventoryAllotCommodity
|
||||||
|
if err := orm.Eloquent.Table("erp_inventory_allot_commodity").Where("allot_order_id = ?",
|
||||||
|
inventoryAllotOrder.ID).Find(&commodities).Error; err != nil {
|
||||||
|
logger.Error("query erp_inventory_allot_commodity err:", logger.Field("err", err))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(commodities) == 0 {
|
||||||
|
return errors.New("未查询到库存调拨商品信息")
|
||||||
|
}
|
||||||
|
|
||||||
|
begin := orm.Eloquent.Begin()
|
||||||
|
// 遍历库存调拨商品信息
|
||||||
|
for _, v := range commodities {
|
||||||
|
commodityInfo, err := GetCommodity(v.CommodityId)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("GetCommodity err:", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var stockCommodity []ErpStockCommodity
|
||||||
|
err = orm.Eloquent.Table("erp_stock_commodity").Where("erp_commodity_id = ? AND store_id = ? "+
|
||||||
|
"AND state = ? AND imei = ?", v.CommodityId, inventoryAllotOrder.ReceiveStoreId, InAllot, v.IMEI).
|
||||||
|
Find(&stockCommodity).Error
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("查询商品库存失败:[%s]", err.Error())
|
||||||
|
}
|
||||||
|
if len(stockCommodity) == 0 {
|
||||||
|
return fmt.Errorf("未找到商品库存信息")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新库存商品表商品状态为:在库
|
||||||
|
for i := 0; i < int(v.Count); i++ {
|
||||||
|
stockCommodity[i].State = InStock
|
||||||
|
err = begin.Model(&ErpStockCommodity{}).Where("id = ?", stockCommodity[i].ID).
|
||||||
|
Updates(stockCommodity[i]).Error
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("更新商品库存失败:%s", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新库存商品数量
|
||||||
|
exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_stock WHERE store_id=%d AND erp_commodity_id=%d",
|
||||||
|
inventoryAllotOrder.ReceiveStoreId, v.CommodityId))
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("exist err:", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if exist {
|
||||||
|
err = begin.Exec(fmt.Sprintf(
|
||||||
|
"UPDATE erp_stock SET count=count+%d WHERE store_id=%d AND erp_commodity_id=%d",
|
||||||
|
v.Count, inventoryAllotOrder.ReceiveStoreId, v.CommodityId)).Error
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("update stock err:", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
stock := &ErpStock{
|
||||||
|
StoreId: inventoryAllotOrder.ReceiveStoreId,
|
||||||
|
StoreName: inventoryAllotOrder.ReceiveStoreName,
|
||||||
|
ErpCommodityId: v.CommodityId,
|
||||||
|
ErpCommodityName: v.CommodityName,
|
||||||
|
ErpCategoryId: commodityInfo.ErpCategoryId,
|
||||||
|
ErpCategoryName: commodityInfo.ErpCategoryName,
|
||||||
|
CommoditySerialNumber: commodityInfo.SerialNumber,
|
||||||
|
IMEIType: v.IMEIType,
|
||||||
|
RetailPrice: commodityInfo.RetailPrice,
|
||||||
|
MinRetailPrice: commodityInfo.MinRetailPrice,
|
||||||
|
Count: v.Count,
|
||||||
|
DispatchCount: 0,
|
||||||
|
}
|
||||||
|
err = begin.Create(stock).Error
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("create stock err:", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新调拨订单的状态为:已完成
|
||||||
|
inventoryAllotOrder.State = ErpInventoryAllotOrderFinished
|
||||||
|
err := begin.Model(&ErpInventoryAllotOrder{}).Where("id = ?", inventoryAllotOrder.ID).
|
||||||
|
Updates(inventoryAllotOrder).Error
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = begin.Commit().Error
|
||||||
|
if err != nil {
|
||||||
|
begin.Rollback()
|
||||||
|
logger.Errorf("commit err:", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -11,8 +11,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ErpInventoryProductOrderUnAudit = 1 // 待审核
|
ErpInventoryProductOrderUnAudit = 1 // 产品入库-待审核
|
||||||
ErpInventoryProductOrderFinished = 2 // 已完成
|
ErpInventoryProductOrderFinished = 2 // 产品入库-已完成
|
||||||
)
|
)
|
||||||
|
|
||||||
// ErpInventoryProductOrder 产品入库订单表
|
// ErpInventoryProductOrder 产品入库订单表
|
||||||
|
@ -134,6 +134,7 @@ func CheckProductInventoryParam(req *ProductInventoryAddReq, editFlag bool) erro
|
||||||
}
|
}
|
||||||
|
|
||||||
noIMEICommodityMap := make(map[uint32]bool, 0)
|
noIMEICommodityMap := make(map[uint32]bool, 0)
|
||||||
|
IMEICommodityMap := make(map[string]bool, 0)
|
||||||
for _, item := range req.Commodities {
|
for _, item := range req.Commodities {
|
||||||
// 校验商品是否存在
|
// 校验商品是否存在
|
||||||
commodityInfo, err := GetCommodity(item.CommodityId)
|
commodityInfo, err := GetCommodity(item.CommodityId)
|
||||||
|
@ -206,6 +207,13 @@ func CheckProductInventoryParam(req *ProductInventoryAddReq, editFlag bool) erro
|
||||||
} else {
|
} else {
|
||||||
return fmt.Errorf("商品[%s]重复,相同的非串码商品只能有1条数据", item.CommodityName)
|
return fmt.Errorf("商品[%s]重复,相同的非串码商品只能有1条数据", item.CommodityName)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
_, ok := IMEICommodityMap[item.IMEI]
|
||||||
|
if !ok {
|
||||||
|
IMEICommodityMap[item.IMEI] = true
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("串码[%s]有重复项", item.IMEI)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
13
docs/docs.go
13
docs/docs.go
|
@ -8028,6 +8028,10 @@ const docTemplate = `{
|
||||||
"description": "收货时间/调入时间",
|
"description": "收货时间/调入时间",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"remark": {
|
||||||
|
"description": "备注",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"serial_number": {
|
"serial_number": {
|
||||||
"description": "单据编号",
|
"description": "单据编号",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
@ -10648,7 +10652,7 @@ const docTemplate = `{
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"storage_type": {
|
"storage_type": {
|
||||||
"description": "入库方式:1-系统入库 2-采购入库",
|
"description": "入库方式:1-系统入库 2-采购入库 3-产品入库",
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
"store_id": {
|
"store_id": {
|
||||||
|
@ -11285,6 +11289,9 @@ const docTemplate = `{
|
||||||
},
|
},
|
||||||
"models.InventoryAllotDeliverReq": {
|
"models.InventoryAllotDeliverReq": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"serial_number"
|
||||||
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
"logistics_number": {
|
"logistics_number": {
|
||||||
"description": "物流单号",
|
"description": "物流单号",
|
||||||
|
@ -11293,6 +11300,10 @@ const docTemplate = `{
|
||||||
"remark": {
|
"remark": {
|
||||||
"description": "备注",
|
"description": "备注",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
},
|
||||||
|
"serial_number": {
|
||||||
|
"description": "单据编号",
|
||||||
|
"type": "string"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -8017,6 +8017,10 @@
|
||||||
"description": "收货时间/调入时间",
|
"description": "收货时间/调入时间",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"remark": {
|
||||||
|
"description": "备注",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"serial_number": {
|
"serial_number": {
|
||||||
"description": "单据编号",
|
"description": "单据编号",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
@ -10637,7 +10641,7 @@
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"storage_type": {
|
"storage_type": {
|
||||||
"description": "入库方式:1-系统入库 2-采购入库",
|
"description": "入库方式:1-系统入库 2-采购入库 3-产品入库",
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
"store_id": {
|
"store_id": {
|
||||||
|
@ -11274,6 +11278,9 @@
|
||||||
},
|
},
|
||||||
"models.InventoryAllotDeliverReq": {
|
"models.InventoryAllotDeliverReq": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"serial_number"
|
||||||
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
"logistics_number": {
|
"logistics_number": {
|
||||||
"description": "物流单号",
|
"description": "物流单号",
|
||||||
|
@ -11282,6 +11289,10 @@
|
||||||
"remark": {
|
"remark": {
|
||||||
"description": "备注",
|
"description": "备注",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
},
|
||||||
|
"serial_number": {
|
||||||
|
"description": "单据编号",
|
||||||
|
"type": "string"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -1575,6 +1575,9 @@ definitions:
|
||||||
receive_time:
|
receive_time:
|
||||||
description: 收货时间/调入时间
|
description: 收货时间/调入时间
|
||||||
type: string
|
type: string
|
||||||
|
remark:
|
||||||
|
description: 备注
|
||||||
|
type: string
|
||||||
serial_number:
|
serial_number:
|
||||||
description: 单据编号
|
description: 单据编号
|
||||||
type: string
|
type: string
|
||||||
|
@ -3491,7 +3494,7 @@ definitions:
|
||||||
description: 最近入库时间
|
description: 最近入库时间
|
||||||
type: string
|
type: string
|
||||||
storage_type:
|
storage_type:
|
||||||
description: 入库方式:1-系统入库 2-采购入库
|
description: 入库方式:1-系统入库 2-采购入库 3-产品入库
|
||||||
type: integer
|
type: integer
|
||||||
store_id:
|
store_id:
|
||||||
description: 门店id
|
description: 门店id
|
||||||
|
@ -3958,6 +3961,11 @@ definitions:
|
||||||
remark:
|
remark:
|
||||||
description: 备注
|
description: 备注
|
||||||
type: string
|
type: string
|
||||||
|
serial_number:
|
||||||
|
description: 单据编号
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- serial_number
|
||||||
type: object
|
type: object
|
||||||
models.InventoryAllotDetailReq:
|
models.InventoryAllotDetailReq:
|
||||||
properties:
|
properties:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user