From 3dd501a3dcb01d4bd02bfd975de6bcf0a5157378 Mon Sep 17 00:00:00 2001 From: chenlin Date: Wed, 17 Apr 2024 09:37:02 +0800 Subject: [PATCH] =?UTF-8?q?1.=E6=96=B0=E5=A2=9E=E5=BA=93=E5=AD=98=E5=8F=98?= =?UTF-8?q?=E5=8A=A8=E7=9B=B8=E5=85=B3=E6=8E=A5=E5=8F=A3=EF=BC=88=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E3=80=81=E7=BC=96=E8=BE=91=E3=80=81=E5=AE=A1=E6=A0=B8?= =?UTF-8?q?=E3=80=81=E5=88=A0=E9=99=A4=E3=80=81=E5=88=97=E8=A1=A8=E3=80=81?= =?UTF-8?q?=E8=AF=A6=E6=83=85=EF=BC=89=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/admin/apis/basic/commodity.go | 16 +- app/admin/apis/inventorymanage/change.go | 181 ++++- app/admin/apis/system/sysuser.go | 4 +- app/admin/models/commodity.go | 95 +-- app/admin/models/erp_order.go | 2 +- app/admin/models/file.go | 39 +- app/admin/models/inventory_allot.go | 40 +- app/admin/models/inventory_change.go | 899 ++++++++++++++++++++++- app/admin/models/inventory_product.go | 20 +- app/admin/models/purchase.go | 128 +++- docs/docs.go | 54 +- docs/swagger.json | 54 +- docs/swagger.yaml | 52 +- 13 files changed, 1375 insertions(+), 209 deletions(-) diff --git a/app/admin/apis/basic/commodity.go b/app/admin/apis/basic/commodity.go index fddbd47..d4ad991 100644 --- a/app/admin/apis/basic/commodity.go +++ b/app/admin/apis/basic/commodity.go @@ -20,10 +20,10 @@ type CommodityCreateRequest struct { ErpBarcode string `json:"erp_barcode"` // 商品条码 IMEIType uint32 `json:"imei_type"` // 系统生成串码:2-是(系统生成) 3-否(手动添加) ErpSupplierId uint32 `json:"erp_supplier_id" binding:"required"` // 主供应商 - RetailPrice uint32 `json:"retail_price"` // 指导零售价 - MinRetailPrice uint32 `json:"min_retail_price"` // 最低零售价 - StaffCostPrice uint32 `json:"staff_cost_price"` // 员工成本价加价 - WholesalePrice uint32 `json:"wholesale_price"` // 指导采购价 + RetailPrice float64 `json:"retail_price"` // 指导零售价 + MinRetailPrice float64 `json:"min_retail_price"` // 最低零售价 + StaffCostPrice float64 `json:"staff_cost_price"` // 员工成本价加价 + WholesalePrice float64 `json:"wholesale_price"` // 指导采购价 Brokerage1 float64 `json:"brokerage_1"` // 销售毛利提成 Brokerage2 float64 `json:"brokerage_2"` // 员工毛利提成 MemberDiscount float64 `json:"member_discount"` // 会员优惠 @@ -240,10 +240,10 @@ type CommodityEditRequest struct { IsIMEI uint32 `json:"is_imei" binding:"required"` // 是否串码:1-串码类 2-非串码 IMEIType uint32 `json:"imei_type" binding:"required"` // 1-无串码 2-串码(系统生成) 3-串码(手动添加) ErpSupplierId uint32 `json:"erp_supplier_id" binding:"required"` // 主供应商id - RetailPrice uint32 `json:"retail_price"` // 指导零售价 - MinRetailPrice uint32 `json:"min_retail_price"` // 最低零售价 - StaffCostPrice uint32 `json:"staff_cost_price"` // 员工成本价加价 - WholesalePrice uint32 `json:"wholesale_price"` // 指导采购价 + RetailPrice float64 `json:"retail_price"` // 指导零售价 + MinRetailPrice float64 `json:"min_retail_price"` // 最低零售价 + StaffCostPrice float64 `json:"staff_cost_price"` // 员工成本价加价 + WholesalePrice float64 `json:"wholesale_price"` // 指导采购价 Brokerage1 float64 `json:"brokerage_1"` // 销售毛利提成 Brokerage2 float64 `json:"brokerage_2"` // 员工毛利提成 MemberDiscount float64 `json:"member_discount"` // 会员优惠 diff --git a/app/admin/apis/inventorymanage/change.go b/app/admin/apis/inventorymanage/change.go index 4528ce2..ab66ff4 100644 --- a/app/admin/apis/inventorymanage/change.go +++ b/app/admin/apis/inventorymanage/change.go @@ -2,8 +2,12 @@ package inventorymanage import ( "errors" + "fmt" "github.com/gin-gonic/gin" "go-admin/app/admin/models" + orm "go-admin/common/global" + "go-admin/logger" + "go-admin/tools" "go-admin/tools/app" "net/http" ) @@ -21,12 +25,31 @@ import ( func InventoryChangeAdd(c *gin.Context) { req := &models.InventoryChangeAddReq{} if err := c.ShouldBindJSON(&req); err != nil { - //logger.Error(err) - app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误") + app.Error(c, http.StatusBadRequest, errors.New("param err"), "参数错误:"+err.Error()) 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 + } + + changeProductOrder, err := models.AddInventoryChange(req, sysUser) + if err != nil { + logger.Error("InventoryChangeAdd err:", logger.Field("err", err)) + app.Error(c, http.StatusInternalServerError, err, "新增失败:"+err.Error()) + return + } + + app.OK(c, changeProductOrder, "新增成功") return } @@ -41,12 +64,24 @@ func InventoryChangeAdd(c *gin.Context) { func InventoryChangeEdit(c *gin.Context) { req := &models.InventoryChangeEditReq{} if err := c.ShouldBindJSON(&req); err != nil { - //logger.Error(err) - app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误") + app.Error(c, http.StatusBadRequest, errors.New("param err"), "参数错误:"+err.Error()) return } - app.OK(c, "", "OK") + err := tools.Validate(req) //必填参数校验 + if err != nil { + app.Error(c, http.StatusBadRequest, err, err.Error()) + return + } + + changeProductOrder, err := models.EditChangeInventory(req) + if err != nil { + logger.Error("InventoryChangeEdit err:", logger.Field("err", err)) + app.Error(c, http.StatusInternalServerError, err, "编辑失败:"+err.Error()) + return + } + + app.OK(c, changeProductOrder, "编辑成功") return } @@ -62,11 +97,24 @@ func InventoryChangeAudit(c *gin.Context) { req := &models.InventoryChangeAuditReq{} if err := c.ShouldBindJSON(&req); err != nil { //logger.Error(err) - app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误") + app.Error(c, http.StatusBadRequest, errors.New("param err"), "参数错误:"+err.Error()) 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.AuditChangeInventory(req, sysUser) + if err != nil { + app.Error(c, http.StatusInternalServerError, err, "审核失败:"+err.Error()) + return + } + + app.OK(c, nil, "操作成功") return } @@ -82,11 +130,77 @@ func InventoryChangeDelete(c *gin.Context) { req := &models.InventoryChangeDeleteReq{} if err := c.ShouldBindJSON(&req); err != nil { //logger.Error(err) - app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误") + app.Error(c, http.StatusBadRequest, errors.New("param err"), "参数错误") return } - app.OK(c, "", "OK") + err := tools.Validate(req) //必填参数校验 + if err != nil { + app.Error(c, http.StatusBadRequest, err, err.Error()) + return + } + + // todo 需要校验当前用户是否有权限 + + var inventoryChangeOrder models.ErpInventoryChangeOrder + err = orm.Eloquent.Table("erp_inventory_change_order").Where("serial_number = ?", req.SerialNumber). + Find(&inventoryChangeOrder).Error + if err != nil { + logger.Error("order err:", logger.Field("err", err)) + app.Error(c, http.StatusInternalServerError, err, "删除失败:"+err.Error()) + return + } + + if inventoryChangeOrder.SerialNumber == "" { + logger.Error("order is null") + app.Error(c, http.StatusInternalServerError, err, "删除失败:订单不存在") + return + } + + // 仅待审核订单可删除 + if inventoryChangeOrder.State != models.ErpInventoryChangeOrderUnAudit { + logger.Error("order err, inventoryChangeOrder.State is:", logger.Field("inventoryChangeOrder.State", + inventoryChangeOrder.State)) + app.Error(c, http.StatusInternalServerError, err, "删除失败:仅待审核订单可删除") + return + } + + begin := orm.Eloquent.Begin() + // 1-删除采购订单表 + err = begin.Delete(inventoryChangeOrder).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.ErpInventoryChangeCommodity + err = orm.Eloquent.Table("erp_inventory_change_commodity").Where("change_order_id = ?", + inventoryChangeOrder.ID).Find(&commodities).Error + if err != nil { + logger.Error("query erp_inventory_change_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 } @@ -102,11 +216,17 @@ func InventoryChangeList(c *gin.Context) { req := &models.InventoryChangeListReq{} if err := c.ShouldBindJSON(&req); err != nil { //logger.Error(err) - app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误") + app.Error(c, http.StatusBadRequest, errors.New("param err"), "参数错误:"+err.Error()) 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 } @@ -121,11 +241,42 @@ func InventoryChangeList(c *gin.Context) { func InventoryChangeDetail(c *gin.Context) { req := &models.InventoryChangeDetailReq{} if err := c.ShouldBindJSON(&req); err != nil { - //logger.Error(err) - app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误") + app.Error(c, http.StatusBadRequest, errors.New("param err"), "参数错误:"+err.Error()) return } - app.OK(c, "", "OK") + var changeOrder models.ErpInventoryChangeOrder + err := orm.Eloquent.Table("erp_inventory_change_order").Where("serial_number=?", req.SerialNumber). + Find(&changeOrder).Error + if err != nil { + logger.Error("change order err:", logger.Field("err", err)) + app.Error(c, http.StatusBadRequest, err, "获取失败") + return + } + if changeOrder.ID == 0 { + logger.Error("change commodities err:", logger.Field("err", err)) + app.Error(c, http.StatusBadRequest, err, fmt.Sprintf("未查询到订单[%s]", req.SerialNumber)) + return + } + + // 校验时间,如果为01-01-01 08:05,则赋值为空 + if changeOrder.MakerTime != nil && changeOrder.MakerTime.IsZero() { + changeOrder.MakerTime = nil + } + if changeOrder.AuditTime != nil && changeOrder.AuditTime.IsZero() { + changeOrder.AuditTime = nil + } + + var changeCommodities []models.ErpInventoryChangeCommodity + err = orm.Eloquent.Table("erp_inventory_change_commodity").Where("change_order_id=?", changeOrder.ID). + Find(&changeCommodities).Error + if err != nil { + logger.Error("change commodities err:", logger.Field("err", err)) + app.Error(c, http.StatusBadRequest, err, "获取失败") + return + } + + changeOrder.Commodities = changeCommodities + app.OK(c, changeOrder, "查询成功") return } diff --git a/app/admin/apis/system/sysuser.go b/app/admin/apis/system/sysuser.go index 4ed794e..ee63290 100644 --- a/app/admin/apis/system/sysuser.go +++ b/app/admin/apis/system/sysuser.go @@ -281,8 +281,9 @@ func UpdateSysUser(c *gin.Context) { tools.HasError(err, "数据解析失败", 500) } + sysInfo := models.GetUserById(uint32(req.UserId)) // 判断小程序账号ID是否正常 - if req.Uid != 0 { + if req.Uid != 0 && sysInfo.Uid != req.Uid { userInfo, err := models.GetUserInfoByUid(req.Uid) if err != nil { logger.Error("get user info err:", logger.Field("err", err)) @@ -339,7 +340,6 @@ func UpdateSysUser(c *gin.Context) { tools.HasError(err, "修改失败", 500) // 判断是否修改了uid - sysInfo := models.GetUserById(uint32(req.UserId)) if sysInfo.Uid == 0 && req.Uid != 0 { // 新增uid,直接更新为2即可 err = models.UpdateUserType(begin, req.Uid, 2) } else if sysInfo.Uid != 0 { diff --git a/app/admin/models/commodity.go b/app/admin/models/commodity.go index 5bd53b1..61dfdc4 100644 --- a/app/admin/models/commodity.go +++ b/app/admin/models/commodity.go @@ -6,6 +6,7 @@ import ( "github.com/xuri/excelize/v2" orm "go-admin/common/global" "go-admin/logger" + "go-admin/tools" "go-admin/tools/config" "golang.org/x/sync/errgroup" "gorm.io/gorm" @@ -18,9 +19,12 @@ import ( ) const ( - NoIMEICommodity = 1 // 非串码商品类型 + NoIMEICommodity = 1 // 非串码商品类型 + + SystemInventory = 1 // 系统入库 PurchaseInventory = 2 // 采购入库 ProductInventory = 3 // 产品入库 + CheckInventory = 4 // 盘点入库 InStock = 1 // 在库 SoldOut = 2 // 已售 @@ -28,6 +32,7 @@ const ( InAllot = 4 // 调拨中(调入门店) OnSale = 5 // 销售锁定中 ProductReturn = 6 // 产品出库 + CheckOut = 7 // 盘点出库 ) // ErpStock 库存列表 @@ -42,8 +47,8 @@ type ErpStock struct { ErpCategoryName string `json:"erp_category_name"` // 分类名称 CommoditySerialNumber string `json:"commodity_serial_number" gorm:"index"` // 商品编码/串码 IMEIType uint32 `json:"imei_type"` // 1-无串码 2-串码(系统生成) 3-串码(手动添加) - RetailPrice uint32 `json:"retail_price"` // 指导零售价 - MinRetailPrice uint32 `json:"min_retail_price"` // 最低零售价 + RetailPrice float64 `json:"retail_price"` // 指导零售价 + MinRetailPrice float64 `json:"min_retail_price"` // 最低零售价 Count uint32 `json:"count"` // 数量 DispatchCount uint32 `json:"dispatch_count"` // 调拨中数量 Commodities []ErpStockCommodity `json:"commodities" gorm:"-"` @@ -67,14 +72,14 @@ type ErpStockCommodity struct { ErpSupplierId uint32 `json:"erp_supplier_id" gorm:"index"` // 供应商id ErpSupplierName string `json:"erp_supplier_name"` // 供应商名称 StockTime time.Time `json:"stock_time"` // 最近入库时间 - RetailPrice uint32 `json:"retail_price"` // 指导零售价 - MinRetailPrice uint32 `json:"min_retail_price"` // 最低零售价 - StaffCostPrice uint32 `json:"staff_cost_price"` // 员工成本价加价(如:加价50,不是加价后的价格) - WholesalePrice uint32 `json:"wholesale_price"` // 指导采购价 + RetailPrice float64 `json:"retail_price"` // 指导零售价 + MinRetailPrice float64 `json:"min_retail_price"` // 最低零售价 + StaffCostPrice float64 `json:"staff_cost_price"` // 员工成本价加价(如:加价50,不是加价后的价格) + WholesalePrice float64 `json:"wholesale_price"` // 指导采购价 MemberDiscount float64 `json:"member_discount"` // 会员优惠 - State uint32 `json:"state"` // 状态:1-在库 2-已售 3-采购退货 4-调拨中 5-销售锁定中 + State uint32 `json:"state"` // 状态:1-在库 2-已售 3-采购退货 4-调拨中 5-销售锁定中 6-产品出库 7-盘点出库 Count uint32 `json:"count"` // 数量 - StorageType uint32 `json:"storage_type"` // 入库方式:1-系统入库 2-采购入库 3-产品入库 + StorageType uint32 `json:"storage_type"` // 入库方式:1-系统入库 2-采购入库 3-产品入库 4-盘点入库 FirstStockTime time.Time `json:"first_stock_time"` // 首次入库时间 StockSn string `json:"stock_sn"` // 库存订单编号(跟采购入库的入库编号关联) OriginalSn string `json:"original_sn" gorm:"index"` // 首次入库订单编号(单据编号) @@ -102,10 +107,10 @@ type ErpCommodity struct { IMEI string `json:"imei"` // 串码 ErpSupplierId uint32 `json:"erp_supplier_id" gorm:"index"` // 主供应商id ErpSupplierName string `json:"erp_supplier_name"` // 主供应商名称 - RetailPrice uint32 `json:"retail_price"` // 指导零售价 - MinRetailPrice uint32 `json:"min_retail_price"` // 最低零售价 - StaffCostPrice uint32 `json:"staff_cost_price"` // 员工成本价加价(如:加价50,不是加价后的价格) - WholesalePrice uint32 `json:"wholesale_price"` // 指导采购价 + RetailPrice float64 `json:"retail_price"` // 指导零售价 + MinRetailPrice float64 `json:"min_retail_price"` // 最低零售价 + StaffCostPrice float64 `json:"staff_cost_price"` // 员工成本价加价(如:加价50,不是加价后的价格) + WholesalePrice float64 `json:"wholesale_price"` // 指导采购价 Brokerage1 float64 `json:"brokerage_1"` // 销售毛利提成 Brokerage2 float64 `json:"brokerage_2"` // 员工毛利提成 MemberDiscount float64 `json:"member_discount"` // 会员优惠 @@ -155,18 +160,18 @@ type ErpSupplier struct { type ErpInventoryStock struct { Model - StoreId uint32 `json:"store_id" gorm:"index"` - StoreName string `json:"store_name"` - ErpCommodityId uint32 `json:"erp_commodity_id" gorm:"index"` - ErpCommodityName string `json:"erp_commodity_name"` - ErpCategoryId uint32 `json:"erp_category_id" gorm:"index"` - ErpCategoryName string `json:"erp_category_name"` - CommoditySerialNumber string `json:"commodity_serial_number" gorm:"index"` - IMEIType uint32 `json:"imei_type"` // 1-无串码 2-串码(系统生成) 3-串码(手动添加) - RetailPrice uint32 `json:"retail_price"` - MinRetailPrice uint32 `json:"min_retail_price"` - Count uint32 `json:"count"` - Sn string `json:"sn" gorm:"index"` + StoreId uint32 `json:"store_id" gorm:"index"` + StoreName string `json:"store_name"` + ErpCommodityId uint32 `json:"erp_commodity_id" gorm:"index"` + ErpCommodityName string `json:"erp_commodity_name"` + ErpCategoryId uint32 `json:"erp_category_id" gorm:"index"` + ErpCategoryName string `json:"erp_category_name"` + CommoditySerialNumber string `json:"commodity_serial_number" gorm:"index"` + IMEIType uint32 `json:"imei_type"` // 1-无串码 2-串码(系统生成) 3-串码(手动添加) + RetailPrice float64 `json:"retail_price"` + MinRetailPrice float64 `json:"min_retail_price"` + Count uint32 `json:"count"` + Sn string `json:"sn" gorm:"index"` //ErpSupplierId uint32 `json:"erp_supplier_id" gorm:"index"` //ErpSupplierName string `json:"erp_supplier_name"` //IMEI string `json:"imei"` @@ -188,10 +193,10 @@ type ErpInventoryStockCommodity struct { ErpSupplierId uint32 `json:"erp_supplier_id" gorm:"index"` ErpSupplierName string `json:"erp_supplier_name"` StockTime time.Time `json:"stock_time"` - RetailPrice uint32 `json:"retail_price"` - MinRetailPrice uint32 `json:"min_retail_price"` - StaffCostPrice uint32 `json:"staff_cost_price"` - WholesalePrice uint32 `json:"wholesale_price"` + RetailPrice float64 `json:"retail_price"` + MinRetailPrice float64 `json:"min_retail_price"` + StaffCostPrice float64 `json:"staff_cost_price"` + WholesalePrice float64 `json:"wholesale_price"` Count uint32 `json:"count"` StorageType uint32 `json:"storage_type"` Sn string `json:"sn" gorm:"index"` @@ -564,10 +569,10 @@ func (e *ErpStockFileExcel) Processing() { } e.StockTime = parseTime - e.RetailPrice = PercentFloatStringToUin32(e.RetailPriceString) - e.MinRetailPrice = PercentFloatStringToUin32(e.MinRetailPriceString) - e.StaffCostPrice = PercentFloatStringToUin32(e.StaffCostPriceString) - e.WholesalePrice = PercentFloatStringToUin32(e.WholesalePriceString) + e.RetailPrice = PercentFloatStringToFloat64(e.RetailPriceString) + e.MinRetailPrice = PercentFloatStringToFloat64(e.MinRetailPriceString) + e.StaffCostPrice = PercentFloatStringToFloat64(e.StaffCostPriceString) + e.WholesalePrice = PercentFloatStringToFloat64(e.WholesalePriceString) } @@ -669,11 +674,11 @@ func (m *StockImporter) ImportStockData(colsMap []map[string]interface{}) error } // 注意:表格导入是员工成本价,数据库存储是员工成本价加价=员工成本价-指导采购价 - nStaffCostPrice, err := strconv.ParseUint(list[i].StaffCostPrice, 10, 32) + nStaffCostPrice, err := strconv.ParseFloat(list[i].StaffCostPrice, 64) if err != nil { return fmt.Errorf("员工成本价转换有误:[%v]", err) } - nWholesalePrice, err := strconv.ParseUint(list[i].WholesalePrice, 10, 32) // 指导采购价 + nWholesalePrice, err := strconv.ParseFloat(list[i].WholesalePrice, 64) // 指导采购价 if err != nil { return fmt.Errorf("指导采购价转换有误:[%v]", err) } @@ -697,10 +702,10 @@ func (m *StockImporter) ImportStockData(colsMap []map[string]interface{}) error ErpCategoryName: v2.ErpCategoryName, ErpSupplierId: v3, ErpSupplierName: list[i].SupplierName, - StaffCostPrice: uint32(nStaffCostPrice - nWholesalePrice), - WholesalePrice: uint32(nWholesalePrice), - State: 1, - StorageType: 1, + StaffCostPrice: tools.RoundToTwoDecimalPlaces(nStaffCostPrice - nWholesalePrice), + WholesalePrice: tools.RoundToTwoDecimalPlaces(nWholesalePrice), + State: InStock, + StorageType: SystemInventory, FirstStockTime: nowTime, StockTime: nowTime, Count: 1, @@ -1825,8 +1830,8 @@ func (m *ErpStockCommodityListReq) GetDetailList() (*ErpStockCommodityListResp, } nTotalCount := &struct { - TotalWholesalePrice int `json:"total_wholesale_price"` - TotalStaffCostPrice int `json:"total_staff_cost_price"` + TotalWholesalePrice float64 `json:"total_wholesale_price"` + TotalStaffCostPrice float64 `json:"total_staff_cost_price"` }{} err := es.Debug().Select("SUM(wholesale_price) as total_wholesale_price, SUM(staff_cost_price) as total_staff_cost_price"). Scan(&nTotalCount).Error @@ -2102,8 +2107,8 @@ func StringToFloat(req string) (float64, error) { return strconv.ParseFloat(req, 64) } -func PercentFloatStringToUin32(s string) uint32 { - u := uint32(0) +func PercentFloatStringToFloat64(s string) float64 { + u := float64(0) if s != "" { s = strings.ReplaceAll(s, "%", "") } @@ -2113,8 +2118,8 @@ func PercentFloatStringToUin32(s string) uint32 { return u } - u = uint32(f * 100) - return u + u = f * 100 + return tools.RoundToTwoDecimalPlaces(u) } func IntStringToUin32(s string) uint32 { diff --git a/app/admin/models/erp_order.go b/app/admin/models/erp_order.go index c810f1d..a02228b 100644 --- a/app/admin/models/erp_order.go +++ b/app/admin/models/erp_order.go @@ -817,7 +817,7 @@ func UpdateStock(gdb *gorm.DB, erpOrder ErpOrder, state int) error { for j := 0; j < int(commodities[i].Count); j++ { // 通过门店id,商品id,查找状态为2-已售的非串码商品 err = orm.Eloquent.Table("erp_stock_commodity").Where("erp_commodity_id = ? and store_id = ? "+ - "and state = ? and imei_type = ?", commodities[i].ErpCommodityId, erpOrder.StoreId, 2, 1). + "and state = ? and imei_type = ?", commodities[i].ErpCommodityId, erpOrder.StoreId, SoldOut, NoIMEICommodity). Order("first_stock_time DESC").Find(&stockCommodity).Error if err != nil { logger.Error("RetailTypeRejected commodities err:", logger.Field("err", err)) diff --git a/app/admin/models/file.go b/app/admin/models/file.go index ca53ad5..afe87e7 100644 --- a/app/admin/models/file.go +++ b/app/admin/models/file.go @@ -10,6 +10,7 @@ import ( "go-admin/app/admin/models/tools" orm "go-admin/common/global" "go-admin/logger" + tool "go-admin/tools" "gorm.io/gorm" "reflect" "strconv" @@ -349,11 +350,11 @@ func hasDuplicateNames(sheetCols [][]string) (string, bool) { // 确保每一列数据都有相同数量的行数 rowsCount := len(sheetCols[0]) - for i, col := range sheetCols { - if len(col) != rowsCount && i != 2 { - return "每列数据的行数不一致", true - } - } + //for i, col := range sheetCols { + // if len(col) != rowsCount && i != 2 { + // return "每列数据的行数不一致", true + // } + //} for i := 0; i < rowsCount; i++ { //// 检查第一列 @@ -524,13 +525,13 @@ func checkStockExcel(sheetCols [][]string) error { // 采购价、员工成本价必须大于0 if i < len(sheetCols[4]) { - if purchasePrice, err := strconv.Atoi(sheetCols[4][i]); err != nil || purchasePrice <= 0 { + if purchasePrice, err := strconv.ParseFloat(sheetCols[4][i], 64); err != nil || purchasePrice <= 0 { return errors.New("第" + strconv.Itoa(i+1) + "行采购价必须是大于0的数字") } } if i < len(sheetCols[5]) { - if employeeCost, err := strconv.Atoi(sheetCols[5][i]); err != nil || employeeCost <= 0 { + if employeeCost, err := strconv.ParseFloat(sheetCols[5][i], 64); err != nil || employeeCost <= 0 { return errors.New("第" + strconv.Itoa(i+1) + "行员工成本价必须是大于0的数字") } } @@ -1059,19 +1060,19 @@ func convertToErpCommodity(item CommodityExcel, category *Category, supplier *Su if err != nil { return ErpCommodity{}, fmt.Errorf("会员优惠转换有误:[%v]", err) } - nRetailPrice, err := strconv.ParseUint(item.RetailPrice, 10, 32) // 指导零售价 + nRetailPrice, err := strconv.ParseFloat(item.RetailPrice, 64) // 指导零售价 if err != nil { return ErpCommodity{}, fmt.Errorf("指导零售价转换有误:[%v]", err) } - nMinRetailPrice, err := strconv.ParseUint(item.MinRetailPrice, 10, 32) // 最低零售价 + nMinRetailPrice, err := strconv.ParseFloat(item.MinRetailPrice, 64) // 最低零售价 if err != nil { return ErpCommodity{}, fmt.Errorf("最低零售价转换有误:[%v]", err) } - nStaffCostPrice, err := strconv.ParseUint(item.StaffCostPrice, 10, 32) // 员工成本价加价 + nStaffCostPrice, err := strconv.ParseFloat(item.StaffCostPrice, 64) // 员工成本价加价 if err != nil { return ErpCommodity{}, fmt.Errorf("员工成本价加价转换有误:[%v]", err) } - nWholesalePrice, err := strconv.ParseUint(item.WholesalePrice, 10, 32) // 指导采购价 + nWholesalePrice, err := strconv.ParseFloat(item.WholesalePrice, 64) // 指导采购价 if err != nil { return ErpCommodity{}, fmt.Errorf("指导采购价转换有误:[%v]", err) } @@ -1105,13 +1106,13 @@ func convertToErpCommodity(item CommodityExcel, category *Category, supplier *Su IMEIType: nIMEIType, ErpSupplierId: supplier.ID, ErpSupplierName: item.SupplierName, - RetailPrice: uint32(nRetailPrice), - MinRetailPrice: uint32(nMinRetailPrice), - StaffCostPrice: uint32(nStaffCostPrice), - WholesalePrice: uint32(nWholesalePrice), - Brokerage1: brokerage1Float, - Brokerage2: brokerage2Float, - MemberDiscount: memberDiscountFloat, + RetailPrice: tool.RoundToTwoDecimalPlaces(nRetailPrice), + MinRetailPrice: tool.RoundToTwoDecimalPlaces(nMinRetailPrice), + StaffCostPrice: tool.RoundToTwoDecimalPlaces(nStaffCostPrice), + WholesalePrice: tool.RoundToTwoDecimalPlaces(nWholesalePrice), + Brokerage1: tool.RoundToTwoDecimalPlaces(brokerage1Float), + Brokerage2: tool.RoundToTwoDecimalPlaces(brokerage2Float), + MemberDiscount: tool.RoundToTwoDecimalPlaces(memberDiscountFloat), Origin: item.Origin, Remark: item.Remark, }, nil @@ -1207,7 +1208,7 @@ func GenerateSerialNumber(categoryId uint32) (string, error) { } // UpdateErpStockAmountInfo 更新库存和库存商品表的金额:指导零售价、最低零售价 -func UpdateErpStockAmountInfo(begin *gorm.DB, commodityId, retailPrice, minRetailPrice uint32, barCode string, +func UpdateErpStockAmountInfo(begin *gorm.DB, commodityId uint32, retailPrice, minRetailPrice float64, barCode string, category *ErpCategory) error { if category != nil && category.ID != 0 { // 分类信息有值 // 更新库存表 diff --git a/app/admin/models/inventory_allot.go b/app/admin/models/inventory_allot.go index 1827f15..967243c 100644 --- a/app/admin/models/inventory_allot.go +++ b/app/admin/models/inventory_allot.go @@ -6,6 +6,7 @@ import ( orm "go-admin/common/global" "go-admin/logger" "gorm.io/gorm" + "math/rand" "time" ) @@ -190,6 +191,31 @@ func checkAllotInventoryParam(req *InventoryAllotAddReq, editFlag bool) error { return nil } +// newAllotInventorySn 生成库存调拨订单号 +func newAllotInventorySn() string { + nowTime := time.Now() + rand.Seed(nowTime.UnixNano()) + max := 1 + for { + if max > 5 { + logger.Error("create NewProductInventorySn err") + return "" + } + random := rand.Intn(9000) + 1000 + sn := fmt.Sprintf("%s%d", nowTime.Format("060102"), random) + exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_inventory_allot_order "+ + "WHERE serial_number='%s'", "db"+sn)) + if err != nil { + logger.Error("exist sn err") + } + if !exist { + return "db" + sn + } + + max++ + } +} + // AddInventoryAllot 新增库存调拨 func AddInventoryAllot(req *InventoryAllotAddReq, sysUser *SysUser) (*ErpInventoryAllotOrder, error) { // 检查库存调拨信息 @@ -208,12 +234,12 @@ func AddInventoryAllot(req *InventoryAllotAddReq, sysUser *SysUser) (*ErpInvento // 组合库存调拨订单数据 inventoryAllotOrder := &ErpInventoryAllotOrder{ - SerialNumber: "db" + NewProductInventorySn(), + SerialNumber: newAllotInventorySn(), DeliverStoreId: req.DeliverStoreId, DeliverStoreName: req.DeliverStoreName, ReceiveStoreId: req.ReceiveStoreId, ReceiveStoreName: req.ReceiveStoreName, - HandlerId: req.HandlerId, + HandlerId: uint32(sysUser.UserId), HandlerName: req.HandlerName, MakerTime: &nowTime, MakerId: uint32(sysUser.UserId), @@ -339,7 +365,7 @@ func updateAllotCommodityData(gdb *gorm.DB, orderId uint32, req *InventoryAllotE var found bool for _, dbCommodity := range commodities { - if reqCommodity.CommodityId == dbCommodity.CommodityId && reqCommodity.IMEI == dbCommodity.IMEI { + if reqCommodity.CommodityId == dbCommodity.CommodityId && reqCommodity.ID == dbCommodity.ID { found = true break } @@ -353,7 +379,7 @@ func updateAllotCommodityData(gdb *gorm.DB, orderId uint32, req *InventoryAllotE for _, dbCommodity := range commodities { var found bool for _, reqCommodity := range req.Commodities { - if reqCommodity.CommodityId == dbCommodity.CommodityId && reqCommodity.IMEI == dbCommodity.IMEI { + if reqCommodity.CommodityId == dbCommodity.CommodityId && reqCommodity.ID == dbCommodity.ID { found = true // 找到匹配的商品,加入匹配列表 matchingCommodities = append(matchingCommodities, reqCommodity) @@ -470,7 +496,7 @@ func (m *InventoryAllotListReq) List() (*InventoryAllotListResp, error) { return resp, nil } -// AuditAllotInventory 审核产品入库 state:1-审核,2-取消审核 +// AuditAllotInventory 审核库存调拨入库 state:1-审核,2-取消审核 func AuditAllotInventory(req *InventoryAllotAuditReq, sysUser *SysUser) error { // 查询订单信息 var inventoryAllotOrder ErpInventoryAllotOrder @@ -732,9 +758,11 @@ func DeliverAllotInventory(req *InventoryAllotDeliverReq) error { return errors.New("订单不是待发货状态") } + nowTime := time.Now() inventoryAllotOrder.LogisticsNumber = req.LogisticsNumber inventoryAllotOrder.Remark = req.Remark inventoryAllotOrder.State = ErpInventoryAllotOrderWaitReceive + inventoryAllotOrder.DeliverTime = &nowTime err = orm.Eloquent.Model(&ErpInventoryAllotOrder{}).Where("id = ?", inventoryAllotOrder.ID). Updates(inventoryAllotOrder).Error @@ -842,7 +870,9 @@ func ReceiveAllotInventory(req *InventoryAllotReceiveReq) error { } // 更新调拨订单的状态为:已完成 + nowTime := time.Now() inventoryAllotOrder.State = ErpInventoryAllotOrderFinished + inventoryAllotOrder.ReceiveTime = &nowTime err := begin.Model(&ErpInventoryAllotOrder{}).Where("id = ?", inventoryAllotOrder.ID). Updates(inventoryAllotOrder).Error if err != nil { diff --git a/app/admin/models/inventory_change.go b/app/admin/models/inventory_change.go index 2e39ebe..64699fe 100644 --- a/app/admin/models/inventory_change.go +++ b/app/admin/models/inventory_change.go @@ -1,6 +1,23 @@ package models -import "time" +import ( + "errors" + "fmt" + orm "go-admin/common/global" + "go-admin/logger" + "go-admin/tools" + "gorm.io/gorm" + "math/rand" + "time" +) + +const ( + ErpInventoryChangeOrderUnAudit = 1 // 库存变动-待审核 + ErpInventoryChangeOrderFinished = 2 // 库存变动-已完成 + + AddChangeOrder = "add" // 库存增加 + ReduceChangeOrder = "reduce" // 库存减少 +) // ErpInventoryChangeOrder 库存变动订单表 type ErpInventoryChangeOrder struct { @@ -46,6 +63,7 @@ type InventoryChangeAddReq struct { StoreName string `json:"store_name" binding:"required"` // 门店名称 HandlerId uint32 `json:"handler_id" binding:"required"` // 经手人id HandlerName string `json:"handler_name" binding:"required"` // 经手人名称 + ChangeType string `json:"change_type" binding:"required"` // 库存变动类型:add-库存增加 reduce-库存减少 Commodities []ErpInventoryChangeCommodity `json:"commodities" binding:"required"` // 库存变动商品信息 } @@ -91,3 +109,882 @@ type InventoryChangeListResp struct { type InventoryChangeDetailReq struct { SerialNumber string `json:"serial_number" binding:"required"` // 单据编号 } + +// newChangeInventorySn 生成库存变动订单号 +func newChangeInventorySn(changeType string) string { + var prefix string + switch changeType { + case "add": // 库存增加 + prefix = "kcz" + case "reduce": // 库存减少 + prefix = "kcj" + } + + nowTime := time.Now() + rand.Seed(nowTime.UnixNano()) + max := 1 + for { + if max > 5 { + logger.Error("create NewChangeInventorySn err") + return "" + } + random := rand.Intn(9000) + 1000 + sn := fmt.Sprintf("%s%d", nowTime.Format("060102"), random) + exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_inventory_change_order "+ + "WHERE serial_number='%s'", prefix+sn)) + if err != nil { + logger.Error("exist sn err") + } + if !exist { + return prefix + sn + } + + max++ + } +} + +// 检查新增库存变动入参信息 +func checkChangeInventoryParam(req *InventoryChangeAddReq, editFlag bool) error { + if len(req.Commodities) == 0 { + return errors.New("商品信息为空") + } + + if req.ChangeType != AddChangeOrder && req.ChangeType != ReduceChangeOrder { + 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) + } + } + + if req.ChangeType == ReduceChangeOrder { // 库存减少 + // 检查调出门店是否有对应商品,库存变动数量是否 > 商品库存数量 + 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.StoreId). + 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.StoreId, 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 +} + +// AddInventoryChange 新增库存变动订单 +func AddInventoryChange(req *InventoryChangeAddReq, sysUser *SysUser) (*ErpInventoryChangeOrder, error) { + // 检查库存变动信息 + if err := checkChangeInventoryParam(req, false); err != nil { + return nil, err + } + + var err error + nowTime := time.Now() + + // 计算库存变动的总数量,总金额 + var nTotalCount uint32 + var nTotalAmount float64 + for i, _ := range req.Commodities { + nTotalCount += req.Commodities[i].Count // 数量 + nTotalAmount += req.Commodities[i].Amount // 金额 + } + + // 组合库存变动订单数据 + inventoryChangeOrder := &ErpInventoryChangeOrder{ + SerialNumber: newChangeInventorySn(req.ChangeType), + ChangeType: req.ChangeType, + StoreId: req.StoreId, + StoreName: req.StoreName, + HandlerId: uint32(sysUser.UserId), + HandlerName: req.HandlerName, + MakerTime: &nowTime, + MakerId: uint32(sysUser.UserId), + MakerName: sysUser.NickName, + State: ErpInventoryChangeOrderUnAudit, + TotalCount: nTotalCount, + TotalAmount: nTotalAmount, + } + + // 创建库存变动订单 + begin := orm.Eloquent.Begin() + err = begin.Create(inventoryChangeOrder).Error + if err != nil { + begin.Rollback() + logger.Error("create change order err:", logger.Field("err", err)) + return nil, err + } + + // 创建库存变动商品信息,添加库存变动订单id + for i, _ := range req.Commodities { + req.Commodities[i].ChangeOrderId = inventoryChangeOrder.ID + err = begin.Create(&req.Commodities[i]).Error + if err != nil { + begin.Rollback() + logger.Error("create change commodity err:", logger.Field("err", err)) + return nil, err + } + } + + err = begin.Commit().Error + if err != nil { + begin.Rollback() + logger.Error("commit change commodity err:", logger.Field("err", err)) + return nil, err + } + + return inventoryChangeOrder, nil +} + +// EditChangeInventory 编辑库存变动 +func EditChangeInventory(req *InventoryChangeEditReq) (*ErpInventoryChangeOrder, error) { + // 查询订单信息 + var inventoryChangeOrder ErpInventoryChangeOrder + err := orm.Eloquent.Table("erp_inventory_change_order").Where("serial_number = ?", req.SerialNumber). + Find(&inventoryChangeOrder).Error + if err != nil { + logger.Error("allot order err:", logger.Field("err", err)) + return nil, err + } + + // 未找到订单 + if inventoryChangeOrder.ID == 0 { + return nil, fmt.Errorf("未找到该订单,请检查单据编号[%s]", req.SerialNumber) + } + + if inventoryChangeOrder.State != ErpInventoryChangeOrderUnAudit { // 只有待审核的订单才能编辑 + return nil, errors.New("订单不是待审核状态") + } + + // 检查库存调拨信息 + if err = checkChangeInventoryParam(&req.InventoryChangeAddReq, true); err != nil { + return nil, err + } + + // 计算库存调拨的总数量 + var nTotalCount uint32 + var nTotalAmount float64 + for i, _ := range req.Commodities { + nTotalCount += req.Commodities[i].Count // 数量 + nTotalAmount += req.Commodities[i].Amount // 金额 + } + + begin := orm.Eloquent.Begin() + // 1-更新库存调拨信息 + inventoryChangeOrder.ChangeType = req.ChangeType + inventoryChangeOrder.StoreId = req.StoreId + inventoryChangeOrder.StoreName = req.StoreName + inventoryChangeOrder.HandlerId = req.HandlerId + inventoryChangeOrder.HandlerName = req.HandlerName + inventoryChangeOrder.TotalCount = nTotalCount + inventoryChangeOrder.TotalAmount = nTotalAmount + + err = begin.Model(&ErpInventoryChangeOrder{}).Where("id = ?", inventoryChangeOrder.ID). + Updates(inventoryChangeOrder).Error + if err != nil { + begin.Rollback() + logger.Error("update change order err:", logger.Field("err", err)) + return nil, err + } + + // 2-更新库存调拨商品表 + err = updateChangeCommodityData(begin, inventoryChangeOrder.ID, req) + if err != nil { + begin.Rollback() + logger.Error("update erp_inventory_change_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 &inventoryChangeOrder, nil +} + +// updateChangeCommodityData 更新库存变动商品信息 +func updateChangeCommodityData(gdb *gorm.DB, orderId uint32, req *InventoryChangeEditReq) error { + // 查询现有的零售订单信息 + var commodities []ErpInventoryChangeCommodity + err := orm.Eloquent.Table("erp_inventory_change_commodity").Where("change_order_id = ?", orderId).Find(&commodities).Error + if err != nil { + logger.Error("query erp_inventory_change_commodity err:", logger.Field("err", err)) + return err + } + + var newCommodities []ErpInventoryChangeCommodity + var deletedCommodities []ErpInventoryChangeCommodity + var matchingCommodities []ErpInventoryChangeCommodity + // 找到新增的商品 + for i, reqCommodity := range req.Commodities { + // 订单商品表信息添加零售订单id + req.Commodities[i].ChangeOrderId = orderId + + var found bool + for _, dbCommodity := range commodities { + if reqCommodity.CommodityId == dbCommodity.CommodityId && reqCommodity.ID == dbCommodity.ID { + 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.ID == dbCommodity.ID { + found = true + // 找到匹配的商品,加入匹配列表 + matchingCommodities = append(matchingCommodities, reqCommodity) + break + } + } + if !found { + deletedCommodities = append(deletedCommodities, dbCommodity) + } + } + + // 2-更新商品订单信息-更新 + for _, commodity := range matchingCommodities { + if err := gdb.Model(&ErpInventoryChangeCommodity{}).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 *InventoryChangeListReq) List() (*InventoryChangeListResp, error) { + resp := &InventoryChangeListResp{ + 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_change_order") + if m.SerialNumber != "" { + qs = qs.Where("serial_number=?", m.SerialNumber) + } else { + if m.ChangeType != "" { + qs = qs.Where("change_type=?", m.ChangeType) + } + if m.StoreId != 0 { + qs = qs.Where("store_id=?", m.StoreId) + } + 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("ChangeInventoryList 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("ChangeInventoryList 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 []ErpInventoryChangeOrder + err = qs.Order("id DESC").Offset(page * m.PageSize).Limit(m.PageSize).Find(&orders).Error + if err != nil && err != RecordNotFound { + logger.Error("change 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 +} + +// AuditChangeInventory 审核库存变动入库 state:1-审核,2-取消审核 +func AuditChangeInventory(req *InventoryChangeAuditReq, sysUser *SysUser) error { + // 查询订单信息 + var inventoryChangeOrder ErpInventoryChangeOrder + err := orm.Eloquent.Table("erp_inventory_change_order").Where("serial_number = ?", req.SerialNumber). + Find(&inventoryChangeOrder).Error + if err != nil { + logger.Error("order err:", logger.Field("err", err)) + return err + } + + if inventoryChangeOrder.ID == 0 { + return errors.New("未查询到订单信息") + } + + begin := orm.Eloquent.Begin() + + // 判断入参state:1-审核,2-取消审核 + orderState := 0 + switch req.State { + case 1: // 1-审核:待审核状态可以审核 + if inventoryChangeOrder.State == ErpInventoryChangeOrderFinished { // 订单已完成 + return errors.New("订单已审核,无需再次审核") + } + orderState = ErpInventoryChangeOrderFinished + case 2: // 2-取消审核 + if inventoryChangeOrder.State == ErpInventoryChangeOrderUnAudit { // 订单未审核 + return errors.New("订单是未审核状态,无需取消审核") + } + orderState = ErpInventoryChangeOrderUnAudit + default: + logger.Error("order err, req.State is:", logger.Field("req.State", req.State)) + return errors.New("参数有误") + } + + // 更新商品的库存状态 + err = changeInventoryUpdateStock(begin, inventoryChangeOrder, req.State) + if err != nil { + begin.Rollback() + logger.Error("changeInventoryUpdateStock err:", logger.Field("err", err)) + return err + } + + // 更新库存调拨订单表 + err = begin.Table("erp_inventory_change_order").Where("id = ?", inventoryChangeOrder.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_change_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 +} + +// changeInventoryUpdateStock 库存变动更新库存信息 +func changeInventoryUpdateStock(gdb *gorm.DB, changeOrder ErpInventoryChangeOrder, nState int) error { + if nState != 1 && nState != 2 { + return errors.New("无效的状态") + } + + if changeOrder.ChangeType != AddChangeOrder && changeOrder.ChangeType != ReduceChangeOrder { + return errors.New("无效的库存变动类型") + } + + // 根据状态和库存变动类型执行不同的逻辑 + switch { + case nState == 1 && changeOrder.ChangeType == AddChangeOrder: + return handleInventoryAdd(gdb, changeOrder) + case nState == 1 && changeOrder.ChangeType == ReduceChangeOrder: + return handleInventoryReduce(gdb, changeOrder) + case nState == 2 && changeOrder.ChangeType == AddChangeOrder: + return handleCancelInventoryAdd(gdb, changeOrder) + case nState == 2 && changeOrder.ChangeType == ReduceChangeOrder: + return handleCancelInventoryReduce(gdb, changeOrder) + default: + return nil + } +} + +// 库存增加逻辑 +func handleInventoryAdd(gdb *gorm.DB, changeOrder ErpInventoryChangeOrder) error { + // 查询库存变动商品信息 + var commodities []ErpInventoryChangeCommodity + err := orm.Eloquent.Table("erp_inventory_change_commodity").Where("change_order_id = ?", + changeOrder.ID).Find(&commodities).Error + if err != nil { + logger.Error("query erp_inventory_change_commodity err:", logger.Field("err", err)) + return err + } + + // 遍历采购入库商品信息 + var stockList []ErpStockCommodity + for _, v := range commodities { + commodityInfo, err := GetCommodity(v.CommodityId) + if err != nil { + logger.Errorf("GetCommodity err:", err) + return err + } + exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_stock WHERE store_id=%d AND "+ + "erp_commodity_id=%d", changeOrder.StoreId, v.CommodityId)) + if err != nil { + logger.Errorf("exist err:", err) + return err + } + if exist { + err = gdb.Exec(fmt.Sprintf( + "UPDATE erp_stock SET count=count+%d WHERE store_id=%d AND erp_commodity_id=%d", + v.Count, changeOrder.StoreId, v.CommodityId)).Error + if err != nil { + logger.Errorf("update stock err:", err) + return err + } + } else { + stock := &ErpStock{ + StoreId: changeOrder.StoreId, + StoreName: changeOrder.StoreName, + 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 = gdb.Create(stock).Error + if err != nil { + logger.Errorf("create stock err:", err) + return err + } + } + + for i := 0; i < int(v.Count); i++ { + nowTime := time.Now() + stockCommodity := ErpStockCommodity{ + StoreId: changeOrder.StoreId, + StoreName: changeOrder.StoreName, + ErpCommodityId: v.CommodityId, + ErpCommodityName: v.CommodityName, + CommoditySerialNumber: commodityInfo.SerialNumber, + ErpCategoryId: commodityInfo.ErpCategoryId, + ErpCategoryName: commodityInfo.ErpCategoryName, + ErpSupplierId: v.SupplierId, + ErpSupplierName: v.SupplierName, + StaffCostPrice: tools.RoundToTwoDecimalPlaces(v.EmployeePrice - v.Price), + WholesalePrice: tools.RoundToTwoDecimalPlaces(v.Price), + State: InStock, + StorageType: CheckInventory, // 盘点入库 + FirstStockTime: nowTime, + StockTime: nowTime, + Count: 1, + ErpBarcode: commodityInfo.ErpBarcode, // 240106新增商品条码 + IMEIType: v.IMEIType, + IMEI: v.IMEI, + Remark: "", + MemberDiscount: commodityInfo.MemberDiscount, + MinRetailPrice: commodityInfo.MinRetailPrice, + RetailPrice: commodityInfo.RetailPrice, + OriginalSn: changeOrder.SerialNumber, + //StockSn: v.SerialNumber, + } + stockList = append(stockList, stockCommodity) + } + } + + err = gdb.Debug().Create(&stockList).Error + if err != nil { + logger.Errorf("create stock commodity err:", err) + return err + } + + return nil +} + +// 库存减少逻辑 +func handleInventoryReduce(gdb *gorm.DB, changeOrder ErpInventoryChangeOrder) error { + // 查询库存变动商品信息 + var commodities []ErpInventoryChangeCommodity + err := orm.Eloquent.Table("erp_inventory_change_commodity").Where("change_order_id = ?", + changeOrder.ID).Find(&commodities).Error + if err != nil { + logger.Error("query erp_inventory_change_commodity err:", logger.Field("err", err)) + return err + } + + if len(commodities) == 0 { + return errors.New("未查询到商品信息") + } + + usedStockCommodityIdList := make(map[uint32][]uint32) // 记录非串码商品已使用的商品库存表主键id + // 更新库存数量 + for i, _ := range commodities { + if commodities[i].IMEIType == 2 { // 串码商品 + if commodities[i].IMEI == "" { + return errors.New("串码为空") + } + + // 判断该串码商品是否已经销售 + var stockCommodityInfo ErpStockCommodity + err = orm.Eloquent.Table("erp_stock_commodity").Where("imei = ?", + commodities[i].IMEI).Find(&stockCommodityInfo).Error + if err != nil { + logger.Error("handleInventoryReduce query commodities err:", logger.Field("err", err)) + return err + } + if stockCommodityInfo.State == SoldOut { + return fmt.Errorf("商品[%s]已经销售", stockCommodityInfo.ErpCommodityName) + } else if stockCommodityInfo.State == OnSale { + return fmt.Errorf("商品[%s]在销售锁定中", stockCommodityInfo.ErpCommodityName) + } + + // 更新库存商品状态为:盘点出库 + err = gdb.Table("erp_stock_commodity").Where("imei = ?", commodities[i].IMEI). + Update("state", CheckOut).Error + if err != nil { + logger.Error("handleInventoryReduce update erp_stock_commodity err:", + logger.Field("err", err)) + return err + } + + // 更新库存数量:库存数量-1 + err = gdb.Table("erp_stock").Where("store_id = ? and erp_commodity_id = ?", + changeOrder.StoreId, commodities[i].CommodityId). + Updates(map[string]interface{}{"count": gorm.Expr("count - ?", 1)}).Error + if err != nil { + logger.Error("handleInventoryReduce update erp_stock err:", logger.Field("err", err)) + return err + } + } else { + // 查询商品实际库存详情处剩余有效数,不包含已出库的数量 + var nCount int64 + err = orm.Eloquent.Table("erp_stock_commodity"). + Where("erp_commodity_id = ? AND store_id = ? AND state = 1", commodities[i].CommodityId, + changeOrder.StoreId).Count(&nCount).Error + if err != nil { + return err + } + + // 如果库存数量不够则报错 + if uint32(nCount) < commodities[i].Count { + return fmt.Errorf("商品[%s]库存不足", commodities[i].CommodityName) + } + + var stockCommodity []ErpStockCommodity + // 非串码商品可能不止1个,更新库存商品状态 + for j := 0; j < int(commodities[i].Count); j++ { + // 通过门店id,商品id,查找状态为1-在库的非串码商品 + err = orm.Eloquent.Table("erp_stock_commodity").Where("erp_commodity_id = ? and "+ + "store_id = ? and state = ? and imei_type = ?", commodities[i].CommodityId, changeOrder.StoreId, + InStock, NoIMEICommodity).Order("first_stock_time DESC").Find(&stockCommodity).Error + if err != nil { + logger.Error("get commodities err:", logger.Field("err", err)) + return err + } + if stockCommodity == nil { + return errors.New("find no stock commodity") + } + + // 找一个可用的库存商品表主键ID + rightId, err := findRightErpStockCommodityId(usedStockCommodityIdList, + commodities[i].CommodityId, stockCommodity) + if err != nil { + return err + } + + err = gdb.Table("erp_stock_commodity").Where("id = ?", rightId). + Update("state", CheckOut).Error // 状态更新为:盘点出库 + if err != nil { + logger.Error("handleInventoryReduce update erp_stock_commodity err:", + logger.Field("err", err)) + return err + } + usedStockCommodityIdList[commodities[i].ID] = append(usedStockCommodityIdList[commodities[i].ID], rightId) + } + + // 更新库存数量:库存数量-count + err = gdb.Table("erp_stock").Where("store_id = ? and erp_commodity_id = ?", + changeOrder.StoreId, commodities[i].CommodityId). + Updates(map[string]interface{}{"count": gorm.Expr("count - ?", commodities[i].Count)}).Error + if err != nil { + logger.Error("handleInventoryReduce update erp_stock err:", logger.Field("err", err)) + return err + } + } + } + + return nil +} + +// 取消审核时库存增加逻辑 +func handleCancelInventoryAdd(gdb *gorm.DB, changeOrder ErpInventoryChangeOrder) error { + // 查询库存变动商品信息 + var commodities []ErpInventoryChangeCommodity + err := orm.Eloquent.Table("erp_inventory_change_commodity").Where("change_order_id = ?", + changeOrder.ID).Find(&commodities).Error + if err != nil { + logger.Error("query erp_inventory_change_commodity err:", logger.Field("err", err)) + return err + } + + if len(commodities) == 0 { + return errors.New("未查询到商品信息") + } + + // 更新库存数量 + for i, _ := range commodities { + if commodities[i].IMEIType == 2 { // 串码商品 + if commodities[i].IMEI == "" { + return errors.New("串码为空") + } + + // 判断该串码商品是否已经销售 + var stockCommodityInfo ErpStockCommodity + err = orm.Eloquent.Table("erp_stock_commodity").Where("imei = ?", + commodities[i].IMEI).Find(&stockCommodityInfo).Error + if err != nil { + logger.Error("handleCancelInventoryAdd query commodities err:", logger.Field("err", err)) + return err + } + if stockCommodityInfo.State == SoldOut { + return fmt.Errorf("商品[%s]已经销售", stockCommodityInfo.ErpCommodityName) + } else if stockCommodityInfo.State == OnSale { + return fmt.Errorf("商品[%s]在销售锁定中", stockCommodityInfo.ErpCommodityName) + } + + // 更新库存数量:库存数量-1 + err = gdb.Table("erp_stock").Where("store_id = ? and erp_commodity_id = ?", + changeOrder.StoreId, commodities[i].CommodityId). + Updates(map[string]interface{}{"count": gorm.Expr("count - ?", 1)}).Error + if err != nil { + logger.Error("handleCancelInventoryAdd commodities err:", logger.Field("err", err)) + return err + } + } else { + // 查询入库商品实际库存详情处剩余有效数,不包含已出库的数量 + nCount, err := GetCommodityStockByPurchaseId(changeOrder.SerialNumber, + commodities[i].CommodityId) + if err != nil { + logger.Error("handleCancelInventoryAdd GetCommodityStockByPurchaseId err:", + logger.Field("err", err)) + return err + } + // 如果库存数量不够则报错 + if nCount < commodities[i].Count { + return fmt.Errorf("商品[%s]库存数量不足", commodities[i].CommodityName) + } + + // 更新库存数量:库存数量-count + err = gdb.Table("erp_stock").Where("store_id = ? and erp_commodity_id = ?", + changeOrder.StoreId, commodities[i].CommodityId). + Updates(map[string]interface{}{"count": gorm.Expr("count - ?", commodities[i].Count)}).Error + if err != nil { + logger.Error("handleCancelInventoryAdd commodities err:", logger.Field("err", err)) + return err + } + } + } + + // 删除库存商品表对应的记录 + err = gdb.Where("original_sn = ? and state = ?", changeOrder.SerialNumber, InStock).Delete(&ErpStockCommodity{}).Error + if err != nil { + logger.Error("delete erp_stock_commodity err:", logger.Field("err", err)) + return err + } + + return nil +} + +// 取消审核时库存减少逻辑 +func handleCancelInventoryReduce(gdb *gorm.DB, changeOrder ErpInventoryChangeOrder) error { + // 查询库存变动商品信息 + var commodities []ErpInventoryChangeCommodity + err := orm.Eloquent.Table("erp_inventory_change_commodity").Where("change_order_id = ?", + changeOrder.ID).Find(&commodities).Error + if err != nil { + logger.Error("query erp_inventory_change_commodity err:", logger.Field("err", err)) + return err + } + + if len(commodities) == 0 { + return errors.New("未查询到商品信息") + } + + usedStockCommodityIdList := make(map[uint32][]uint32) // 记录非串码商品已使用的商品库存表主键id + // 更新库存数量 + for i, _ := range commodities { + if commodities[i].IMEIType == 2 { // 串码商品 + if commodities[i].IMEI == "" { + return errors.New("串码为空") + } + + // 判断该串码商品是否已经销售 + var stockCommodityInfo ErpStockCommodity + err = orm.Eloquent.Table("erp_stock_commodity").Where("imei = ?", + commodities[i].IMEI).Find(&stockCommodityInfo).Error + if err != nil { + logger.Error("handleCancelInventoryReduce query commodities err:", logger.Field("err", err)) + return err + } + if stockCommodityInfo.State == SoldOut { + return fmt.Errorf("商品[%s]已经销售", stockCommodityInfo.ErpCommodityName) + } else if stockCommodityInfo.State == OnSale { + return fmt.Errorf("商品[%s]在销售锁定中", stockCommodityInfo.ErpCommodityName) + } + + // 更新库存商品状态:在库 + err = gdb.Table("erp_stock_commodity").Where("imei = ?", commodities[i].IMEI). + Update("state", InStock).Error + if err != nil { + logger.Error("handleCancelInventoryReduce update erp_stock_commodity err:", + logger.Field("err", err)) + return err + } + + // 更新库存数量:库存数量+1 + err = gdb.Table("erp_stock").Where("store_id = ? and erp_commodity_id = ?", + changeOrder.StoreId, commodities[i].CommodityId). + Updates(map[string]interface{}{"count": gorm.Expr("count + ?", 1)}).Error + if err != nil { + logger.Error("handleCancelInventoryReduce update erp_stock err:", logger.Field("err", err)) + return err + } + } else { + var stockCommodity []ErpStockCommodity + // 非串码商品可能不止1个,更新库存商品状态 + for j := 0; j < int(commodities[i].Count); j++ { + // 通过门店id,商品id,查找状态为7-盘点出库的非串码商品 + err = orm.Eloquent.Table("erp_stock_commodity").Where("erp_commodity_id = ? and "+ + "store_id = ? and state = ? and imei_type = ?", commodities[i].CommodityId, changeOrder.StoreId, + CheckOut, NoIMEICommodity).Order("first_stock_time DESC").Find(&stockCommodity).Error + if err != nil { + logger.Error("get commodities err:", logger.Field("err", err)) + return err + } + if stockCommodity == nil { + return errors.New("find no stock commodity") + } + + // 找一个可用的库存商品表主键ID + rightId, err := findRightErpStockCommodityId(usedStockCommodityIdList, + commodities[i].CommodityId, stockCommodity) + if err != nil { + return err + } + + err = gdb.Table("erp_stock_commodity").Where("id = ?", rightId). + Update("state", InStock).Error // 状态更新为:在库 + if err != nil { + logger.Error("handleCancelInventoryReduce update erp_stock_commodity err:", + logger.Field("err", err)) + return err + } + + usedStockCommodityIdList[commodities[i].ID] = append(usedStockCommodityIdList[commodities[i].ID], rightId) + } + + // 更新库存数量:库存数量+count + err = gdb.Table("erp_stock").Where("store_id = ? and erp_commodity_id = ?", + changeOrder.StoreId, commodities[i].CommodityId). + Updates(map[string]interface{}{"count": gorm.Expr("count + ?", commodities[i].Count)}).Error + if err != nil { + logger.Error("handleCancelInventoryReduce update erp_stock err:", logger.Field("err", err)) + return err + } + } + } + + return nil +} diff --git a/app/admin/models/inventory_product.go b/app/admin/models/inventory_product.go index dadc4b1..bd15844 100644 --- a/app/admin/models/inventory_product.go +++ b/app/admin/models/inventory_product.go @@ -5,6 +5,7 @@ import ( "fmt" orm "go-admin/common/global" "go-admin/logger" + "go-admin/tools" "gorm.io/gorm" "math/rand" "time" @@ -103,8 +104,8 @@ type ProductInventoryDetailReq struct { SerialNumber string `json:"serial_number" binding:"required"` // 单据编号 } -// NewProductInventorySn 生成产品入库订单号 -func NewProductInventorySn() string { +// newProductInventorySn 生成产品入库订单号 +func newProductInventorySn() string { nowTime := time.Now() rand.Seed(nowTime.UnixNano()) max := 1 @@ -115,12 +116,13 @@ func NewProductInventorySn() string { } random := rand.Intn(9000) + 1000 sn := fmt.Sprintf("%s%d", nowTime.Format("060102"), random) - exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_inventory_product_order WHERE serial_number='%s'", sn)) + exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_inventory_product_order "+ + "WHERE serial_number='%s'", "cpr"+sn)) if err != nil { logger.Error("exist sn err") } if !exist { - return sn + return "cpr" + sn } max++ @@ -240,7 +242,7 @@ func AddProductInventory(req *ProductInventoryAddReq, sysUser *SysUser) (*ErpInv // 组合产品入库订单数据 inventoryProductOrder := &ErpInventoryProductOrder{ - SerialNumber: "cpr" + NewProductInventorySn(), + SerialNumber: newProductInventorySn(), StoreId: req.StoreId, StoreName: req.StoreName, HandlerId: req.HandlerId, @@ -371,7 +373,7 @@ func updateProductCommodityData(gdb *gorm.DB, orderId uint32, req *ProductInvent var found bool for _, dbCommodity := range commodities { - if reqCommodity.CommodityId == dbCommodity.CommodityId && reqCommodity.IMEI == dbCommodity.IMEI { + if reqCommodity.CommodityId == dbCommodity.CommodityId && reqCommodity.ID == dbCommodity.ID { found = true break } @@ -385,7 +387,7 @@ func updateProductCommodityData(gdb *gorm.DB, orderId uint32, req *ProductInvent for _, dbCommodity := range commodities { var found bool for _, reqCommodity := range req.Commodities { - if reqCommodity.CommodityId == dbCommodity.CommodityId && reqCommodity.IMEI == dbCommodity.IMEI { + if reqCommodity.CommodityId == dbCommodity.CommodityId && reqCommodity.ID == dbCommodity.ID { found = true // 找到匹配的商品,加入匹配列表 matchingCommodities = append(matchingCommodities, reqCommodity) @@ -641,8 +643,8 @@ func productAuditAndUpdateStock(gdb *gorm.DB, productOrder ErpInventoryProductOr ErpCategoryName: commodityInfo.ErpCategoryName, ErpSupplierId: v.SupplierId, ErpSupplierName: v.SupplierName, - StaffCostPrice: uint32(v.EmployeePrice - v.Price), - WholesalePrice: uint32(v.Price), + StaffCostPrice: tools.RoundToTwoDecimalPlaces(v.EmployeePrice - v.Price), + WholesalePrice: tools.RoundToTwoDecimalPlaces(v.Price), State: InStock, StorageType: ProductInventory, // 产品入库 FirstStockTime: nowTime, diff --git a/app/admin/models/purchase.go b/app/admin/models/purchase.go index 53918be..c19e2d2 100644 --- a/app/admin/models/purchase.go +++ b/app/admin/models/purchase.go @@ -6,6 +6,7 @@ import ( "github.com/xuri/excelize/v2" orm "go-admin/common/global" "go-admin/logger" + "go-admin/tools" "go-admin/tools/config" "gorm.io/gorm" "math" @@ -72,7 +73,7 @@ type ErpPurchaseCommodity struct { CommoditySerialNumber string `json:"commodity_serial_number" gorm:"index"` // 商品编号 IMEIType uint32 `json:"imei_type"` // 1-无串码 2-串码 IMEI string `json:"imei"` // 商品串码 - RetailPrice uint32 `json:"retail_price"` // 指导零售价 + RetailPrice float64 `json:"retail_price"` // 指导零售价 Count uint32 `json:"count"` // 计划采购数量 Price float64 `json:"price"` // 计划采购单价 Amount float64 `json:"amount"` // 计划采购金额 @@ -275,7 +276,7 @@ type DemandData struct { ErpCommodityName string `json:"erp_commodity_name"` // 商品名称 ErpCategoryID uint32 `json:"erp_category_id"` // 商品分类id ErpCategoryName string `json:"erp_category_name"` // 商品分类名称 - RetailPrice uint32 `json:"retail_price"` // 指导零售价 + RetailPrice float64 `json:"retail_price"` // 指导零售价 LastWholesalePrice float64 `json:"last_wholesale_price"` // 最近采购价 TotalCount uint32 `json:"total_count"` // 需采购总数量 TotalAmount float64 `json:"total_amount"` // 需采购总金额 @@ -463,7 +464,7 @@ type ErpPurchaseReportBySupplierResp struct { Total int `json:"total"` // 总条数 PageIndex int `json:"pageIndex"` // 页码 PageSize int `json:"pageSize"` // 页面条数 - Count uint32 `json:"count"` // 采购数量 + Count int32 `json:"count"` // 采购数量 Amount float64 `json:"amount"` // 采购金额 RejectAmount float64 `json:"reject_amount"` // 退货金额 Difference float64 `json:"difference"` // 差额 @@ -482,7 +483,7 @@ type PurchaseReportData struct { ErpCommodityName string `json:"erp_commodity_name"` // 商品名称 ErpCategoryID uint32 `json:"erp_category_id"` // 商品分类id ErpCategoryName string `json:"erp_category_name"` // 商品分类名称 - Count uint32 `json:"count"` // 采购数量 + Count int32 `json:"count"` // 采购数量 Amount float64 `json:"amount"` // 采购金额 RejectAmount float64 `json:"reject_amount"` // 退货金额 Difference float64 `json:"difference"` // 差额 @@ -622,8 +623,16 @@ func (m *ErpPurchaseOrderListReq) List() (*ErpPurchaseOrderListResp, error) { return resp, nil } -// NewErpPurchaseSn 生成采购订单号 -func NewErpPurchaseSn() string { +// newErpPurchaseSn 生成采购订单号 +func newErpPurchaseSn(purchaseType string) string { + var prefix string + switch purchaseType { + case ErpProcureOrder: // 采购入库订单 + prefix = "cgr" + case ErpRejectOrder: // 采购退货订单 + prefix = "cgt" + } + nowTime := time.Now() rand.Seed(nowTime.UnixNano()) max := 1 @@ -634,12 +643,13 @@ func NewErpPurchaseSn() string { } random := rand.Intn(9000) + 1000 sn := fmt.Sprintf("%s%d", nowTime.Format("060102"), random) - exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_purchase_order WHERE serial_number='%s'", sn)) + exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_purchase_order WHERE "+ + "serial_number='%s'", prefix+sn)) if err != nil { logger.Error("exist sn err") } if !exist { - return sn + return prefix + sn } max++ @@ -823,7 +833,7 @@ func CreateErpPurchaseOrder(req *ErpPurchaseCreateReq, sysUser *SysUser) (*ErpPu purchaseOrder := &ErpPurchaseOrder{} if req.PurchaseType == ErpProcureOrder { // 采购入库订单 purchaseOrder = &ErpPurchaseOrder{ - SerialNumber: "cgr" + NewErpPurchaseSn(), + SerialNumber: newErpPurchaseSn(req.PurchaseType), PurchaseType: req.PurchaseType, StoreId: req.StoreId, ErpSupplierId: req.ErpSupplierId, @@ -854,7 +864,7 @@ func CreateErpPurchaseOrder(req *ErpPurchaseCreateReq, sysUser *SysUser) (*ErpPu } purchaseOrder = &ErpPurchaseOrder{ - SerialNumber: "cgt" + NewErpPurchaseSn(), + SerialNumber: newErpPurchaseSn(req.PurchaseType), PurchaseType: req.PurchaseType, StoreId: erpPurchaseOrder.StoreId, ErpSupplierId: erpPurchaseOrder.ErpSupplierId, @@ -1235,8 +1245,8 @@ func InventoryErpPurchaseUpdateStock(gdb *gorm.DB, list []ErpPurchaseInventory, ErpCategoryName: commodityInfo.ErpCategoryName, ErpSupplierId: purchaseOrder.ErpSupplierId, ErpSupplierName: purchaseOrder.ErpSupplierName, - StaffCostPrice: uint32(v.EmployeePrice - v.ImplementationPrice), - WholesalePrice: uint32(v.ImplementationPrice), + StaffCostPrice: tools.RoundToTwoDecimalPlaces(v.EmployeePrice - v.ImplementationPrice), + WholesalePrice: tools.RoundToTwoDecimalPlaces(v.ImplementationPrice), State: InStock, StorageType: PurchaseInventory, // 采购入库 FirstStockTime: nowTime, @@ -2781,7 +2791,7 @@ func GetTotalsAndAveragesByCommodityID(commodityID, orderID uint32) (Result, err } // UpdateRetailPrice 更新指导零售价 -func UpdateRetailPrice(begin *gorm.DB, commodityId, retailPrice uint32) error { +func UpdateRetailPrice(begin *gorm.DB, commodityId uint32, retailPrice float64) error { // 更新商品信息表 err := begin.Table("erp_commodity").Where("id=?", commodityId). Updates(map[string]interface{}{ @@ -4446,8 +4456,20 @@ func GetReportBySupplier(req *ErpPurchaseReportBySupplierReq) (*ErpPurchaseRepor "erp_purchase_order.erp_supplier_name, " + "erp_purchase_inventory.erp_commodity_id, erp_purchase_inventory.erp_commodity_name, " + "erp_purchase_inventory.erp_category_id, erp_purchase_inventory.erp_category_name, " + - "SUM(erp_purchase_inventory.count) AS total_count, " + - "SUM(erp_purchase_inventory.amount) AS total_amount"). + "SUM(erp_purchase_inventory.count) AS count, " + + "SUM(erp_purchase_inventory.amount) AS amount"). + Joins("JOIN erp_purchase_order ON erp_purchase_order.id = erp_purchase_inventory.erp_purchase_order_id"). + Group("erp_purchase_inventory.erp_purchase_order_id, erp_purchase_inventory.erp_commodity_id, " + + "erp_purchase_inventory.erp_commodity_name, erp_purchase_inventory.erp_category_id") + + countQuery := orm.Eloquent.Model(&ErpPurchaseInventory{}). + Select("erp_purchase_inventory.erp_purchase_order_id, erp_purchase_inventory.purchase_type, " + + "erp_purchase_order.store_id, erp_purchase_order.store_name, erp_purchase_order.erp_supplier_id, " + + "erp_purchase_order.erp_supplier_name, " + + "erp_purchase_inventory.erp_commodity_id, erp_purchase_inventory.erp_commodity_name, " + + "erp_purchase_inventory.erp_category_id, erp_purchase_inventory.erp_category_name, " + + "SUM(erp_purchase_inventory.count) AS count, " + + "SUM(erp_purchase_inventory.amount) AS amount"). Joins("JOIN erp_purchase_order ON erp_purchase_order.id = erp_purchase_inventory.erp_purchase_order_id"). Group("erp_purchase_inventory.erp_purchase_order_id, erp_purchase_inventory.erp_commodity_id, " + "erp_purchase_inventory.erp_commodity_name, erp_purchase_inventory.erp_category_id") @@ -4455,13 +4477,16 @@ func GetReportBySupplier(req *ErpPurchaseReportBySupplierReq) (*ErpPurchaseRepor // 根据请求参数过滤数据 if req.PurchaseType != "" { query = query.Where("erp_purchase_inventory.purchase_type = ?", req.PurchaseType) + countQuery = countQuery.Where("erp_purchase_inventory.purchase_type = ?", req.PurchaseType) } if len(req.ErpCommodityName) > 0 { query = query.Where("erp_purchase_inventory.erp_commodity_name IN (?)", req.ErpCommodityName) + countQuery = countQuery.Where("erp_purchase_inventory.erp_commodity_name IN (?)", req.ErpCommodityName) } if len(req.ErpCategoryID) > 0 { query = query.Where("erp_purchase_inventory.erp_category_id IN (?)", req.ErpCategoryID) + countQuery = countQuery.Where("erp_purchase_inventory.erp_category_id IN (?)", req.ErpCategoryID) } if req.StartTime != "" { // 入/出库开始时间 @@ -4471,6 +4496,7 @@ func GetReportBySupplier(req *ErpPurchaseReportBySupplierReq) (*ErpPurchaseRepor return nil, err } query = query.Where("erp_purchase_inventory.created_at >= ?", parse) + countQuery = countQuery.Where("erp_purchase_inventory.created_at >= ?", parse) } if req.EndTime != "" { // 入/出库结束时间 @@ -4480,15 +4506,17 @@ func GetReportBySupplier(req *ErpPurchaseReportBySupplierReq) (*ErpPurchaseRepor return nil, err } query = query.Where("erp_purchase_inventory.created_at <= ?", parse) + countQuery = countQuery.Where("erp_purchase_inventory.created_at <= ?", parse) } if len(req.StoreList) > 0 { query = query.Where("erp_purchase_order.store_id IN (?)", req.StoreList) + countQuery = countQuery.Where("erp_purchase_order.store_id IN (?)", req.StoreList) } - // 获取总数 + //获取总数 var total int64 - query.Count(&total) + countQuery.Count(&total) resp.Total = int(total) // 分页查询 @@ -4536,9 +4564,24 @@ func GetReportBySupplier(req *ErpPurchaseReportBySupplierReq) (*ErpPurchaseRepor } if data.PurchaseType == "reject" { - data.Amount = -data.Amount - data.RejectAmount = -data.RejectAmount - data.Difference = data.Amount + data.RejectAmount + // 查询退货商品的采购金额 + var oldOrderInfo ErpPurchaseOrder + err = orm.Eloquent.Where("serial_number = ?", po.SerialNumber).First(&oldOrderInfo).Error + if err != nil { + return nil, err + } + + // 查找对应的采购入库记录 + var resultInfo Result + resultInfo, err = GetTotalsAndAveragesByCommodityID(respItem.ErpCommodityId, oldOrderInfo.ID) + if err != nil { + return nil, err + } + + data.RejectAmount = -data.Amount + data.Amount = -resultInfo.AvgImplementationPrice * float64(data.Count) + data.Difference = data.RejectAmount - data.Amount + data.Count = -data.Count } esData = append(esData, data) @@ -4550,7 +4593,10 @@ func GetReportBySupplier(req *ErpPurchaseReportBySupplierReq) (*ErpPurchaseRepor // 补充关联的供应商和店铺信息 for i := range resp.List { var purchaseOrderInfo ErpPurchaseOrder - orm.Eloquent.Where("id = ?", resp.List[i].ErpPurchaseOrderId).First(&purchaseOrderInfo) + err = orm.Eloquent.Where("id = ?", resp.List[i].ErpPurchaseOrderId).First(&purchaseOrderInfo).Error + if err != nil { + return nil, err + } resp.List[i].StoreId = purchaseOrderInfo.StoreId resp.List[i].StoreName = purchaseOrderInfo.StoreName @@ -4558,9 +4604,24 @@ func GetReportBySupplier(req *ErpPurchaseReportBySupplierReq) (*ErpPurchaseRepor resp.List[i].ErpSupplierName = purchaseOrderInfo.ErpSupplierName if resp.List[i].PurchaseType == "reject" { - resp.List[i].Amount = -resp.List[i].Amount - resp.List[i].RejectAmount = -resp.List[i].RejectAmount - resp.List[i].Difference = resp.List[i].Amount + resp.List[i].RejectAmount + // 查询退货商品的采购金额 + var oldOrderInfo ErpPurchaseOrder + err = orm.Eloquent.Where("serial_number = ?", purchaseOrderInfo.SerialNumber).First(&oldOrderInfo).Error + if err != nil { + return nil, err + } + + // 查找对应的采购入库记录 + var resultInfo Result + resultInfo, err = GetTotalsAndAveragesByCommodityID(resp.List[i].ErpCommodityId, oldOrderInfo.ID) + if err != nil { + return nil, err + } + + resp.List[i].RejectAmount = -resp.List[i].Amount + resp.List[i].Amount = -resultInfo.AvgImplementationPrice * float64(resp.List[i].Count) + resp.List[i].Difference = resp.List[i].RejectAmount - resp.List[i].Amount + resp.List[i].Count = -resp.List[i].Count } } } @@ -4569,7 +4630,7 @@ func GetReportBySupplier(req *ErpPurchaseReportBySupplierReq) (*ErpPurchaseRepor // 统计总计数量和金额 var totalAmount float64 - var totalCount uint32 + var totalCount int32 var totalRejectAmount float64 var totalDifference float64 for _, item := range mergedData { @@ -4676,10 +4737,6 @@ func mergeData(esData []PurchaseReportData) []PurchaseReportData { Difference: data.Difference, } - if data.PurchaseType == ErpRejectOrder { - mergedMap[key].RejectAmount = mergedMap[key].Amount - mergedMap[key].Amount = 0 - } keys = append(keys, key) // 将键添加到有序的键列表中 } else { // 如果键已存在,进行累加操作 @@ -4687,11 +4744,6 @@ func mergeData(esData []PurchaseReportData) []PurchaseReportData { mergedMap[key].Amount += data.Amount mergedMap[key].RejectAmount += data.RejectAmount mergedMap[key].Difference += data.Difference - - if data.PurchaseType == ErpRejectOrder { - mergedMap[key].RejectAmount = mergedMap[key].Amount - mergedMap[key].Amount = 0 - } } } @@ -4936,7 +4988,7 @@ func GetReportDetail(req *ErpPurchaseReportDetailReq) (*ErpPurchaseReportDetailR return nil, err } - resp.List[i].Price = -float64(price) + resp.List[i].Price = -price resp.List[i].DifferencePrice = -resp.List[i].DifferencePrice resp.List[i].RejectPrice = -resp.List[i].RejectPrice @@ -4960,7 +5012,7 @@ func GetReportDetail(req *ErpPurchaseReportDetailReq) (*ErpPurchaseReportDetailR } // 根据采购单据号查询入库采购价 -func getPrice(serialNumber string) (uint32, error) { +func getPrice(serialNumber string) (float64, error) { var stockCommodity ErpStockCommodity err := orm.Eloquent.Table("erp_stock_commodity").Where("stock_sn = ?", serialNumber). Find(&stockCommodity).Error @@ -5264,8 +5316,8 @@ func ErpRejectOrderCancelAuditUpdateStock(gdb *gorm.DB, req *ErpPurchaseInventor ErpCategoryName: commodityInfo.ErpCategoryName, ErpSupplierId: purchaseOrder.ErpSupplierId, ErpSupplierName: purchaseOrder.ErpSupplierName, - StaffCostPrice: uint32(v.EmployeePrice - v.ImplementationPrice), - WholesalePrice: uint32(v.ImplementationPrice), + StaffCostPrice: tools.RoundToTwoDecimalPlaces(v.EmployeePrice - v.ImplementationPrice), + WholesalePrice: tools.RoundToTwoDecimalPlaces(v.ImplementationPrice), State: InStock, StorageType: PurchaseInventory, // 采购入库 FirstStockTime: nowTime, diff --git a/docs/docs.go b/docs/docs.go index efb1e55..6ed8b8c 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -6054,7 +6054,7 @@ const docTemplate = `{ }, "min_retail_price": { "description": "最低零售价", - "type": "integer" + "type": "number" }, "name": { "description": "商品名称", @@ -6070,15 +6070,15 @@ const docTemplate = `{ }, "retail_price": { "description": "指导零售价", - "type": "integer" + "type": "number" }, "staff_cost_price": { "description": "员工成本价加价", - "type": "integer" + "type": "number" }, "wholesale_price": { "description": "指导采购价", - "type": "integer" + "type": "number" } } }, @@ -6156,7 +6156,7 @@ const docTemplate = `{ }, "min_retail_price": { "description": "最低零售价", - "type": "integer" + "type": "number" }, "name": { "description": "商品名称", @@ -6172,15 +6172,15 @@ const docTemplate = `{ }, "retail_price": { "description": "指导零售价", - "type": "integer" + "type": "number" }, "staff_cost_price": { "description": "员工成本价加价", - "type": "integer" + "type": "number" }, "wholesale_price": { "description": "指导采购价", - "type": "integer" + "type": "number" } } }, @@ -7267,7 +7267,7 @@ const docTemplate = `{ }, "retail_price": { "description": "指导零售价", - "type": "integer" + "type": "number" }, "store_list": { "type": "array", @@ -7567,7 +7567,7 @@ const docTemplate = `{ }, "min_retail_price": { "description": "最低零售价", - "type": "integer" + "type": "number" }, "name": { "description": "商品名称", @@ -7587,7 +7587,7 @@ const docTemplate = `{ }, "retail_price": { "description": "指导零售价", - "type": "integer" + "type": "number" }, "serial_number": { "description": "商品编号", @@ -7595,7 +7595,7 @@ const docTemplate = `{ }, "staff_cost_price": { "description": "员工成本价加价(如:加价50,不是加价后的价格)", - "type": "integer" + "type": "number" }, "stock_count": { "description": "库存数量", @@ -7603,7 +7603,7 @@ const docTemplate = `{ }, "wholesale_price": { "description": "指导采购价", - "type": "integer" + "type": "number" } } }, @@ -9386,7 +9386,7 @@ const docTemplate = `{ }, "retail_price": { "description": "指导零售价", - "type": "integer" + "type": "number" } } }, @@ -10520,11 +10520,11 @@ const docTemplate = `{ }, "min_retail_price": { "description": "最低零售价", - "type": "integer" + "type": "number" }, "retail_price": { "description": "指导零售价", - "type": "integer" + "type": "number" }, "store_id": { "description": "门店编号", @@ -10613,7 +10613,7 @@ const docTemplate = `{ }, "min_retail_price": { "description": "最低零售价", - "type": "integer" + "type": "number" }, "original_sn": { "description": "首次入库订单编号(单据编号)", @@ -10625,14 +10625,14 @@ const docTemplate = `{ }, "retail_price": { "description": "指导零售价", - "type": "integer" + "type": "number" }, "staff_cost_price": { "description": "员工成本价加价(如:加价50,不是加价后的价格)", - "type": "integer" + "type": "number" }, "state": { - "description": "状态:1-在库 2-已售 3-采购退货 4-调拨中 5-销售锁定中", + "description": "状态:1-在库 2-已售 3-采购退货 4-调拨中 5-销售锁定中 6-产品出库 7-盘点出库", "type": "integer" }, "stock_end_time": { @@ -10652,7 +10652,7 @@ const docTemplate = `{ "type": "string" }, "storage_type": { - "description": "入库方式:1-系统入库 2-采购入库 3-产品入库", + "description": "入库方式:1-系统入库 2-采购入库 3-产品入库 4-盘点入库", "type": "integer" }, "store_id": { @@ -10665,7 +10665,7 @@ const docTemplate = `{ }, "wholesale_price": { "description": "指导采购价", - "type": "integer" + "type": "number" } } }, @@ -11448,6 +11448,7 @@ const docTemplate = `{ "models.InventoryChangeAddReq": { "type": "object", "required": [ + "change_type", "commodities", "handler_id", "handler_name", @@ -11455,6 +11456,10 @@ const docTemplate = `{ "store_name" ], "properties": { + "change_type": { + "description": "库存变动类型:add-库存增加 reduce-库存减少", + "type": "string" + }, "commodities": { "description": "库存变动商品信息", "type": "array", @@ -11524,6 +11529,7 @@ const docTemplate = `{ "models.InventoryChangeEditReq": { "type": "object", "required": [ + "change_type", "commodities", "handler_id", "handler_name", @@ -11532,6 +11538,10 @@ const docTemplate = `{ "store_name" ], "properties": { + "change_type": { + "description": "库存变动类型:add-库存增加 reduce-库存减少", + "type": "string" + }, "commodities": { "description": "库存变动商品信息", "type": "array", diff --git a/docs/swagger.json b/docs/swagger.json index 071f4ee..7ec2084 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -6043,7 +6043,7 @@ }, "min_retail_price": { "description": "最低零售价", - "type": "integer" + "type": "number" }, "name": { "description": "商品名称", @@ -6059,15 +6059,15 @@ }, "retail_price": { "description": "指导零售价", - "type": "integer" + "type": "number" }, "staff_cost_price": { "description": "员工成本价加价", - "type": "integer" + "type": "number" }, "wholesale_price": { "description": "指导采购价", - "type": "integer" + "type": "number" } } }, @@ -6145,7 +6145,7 @@ }, "min_retail_price": { "description": "最低零售价", - "type": "integer" + "type": "number" }, "name": { "description": "商品名称", @@ -6161,15 +6161,15 @@ }, "retail_price": { "description": "指导零售价", - "type": "integer" + "type": "number" }, "staff_cost_price": { "description": "员工成本价加价", - "type": "integer" + "type": "number" }, "wholesale_price": { "description": "指导采购价", - "type": "integer" + "type": "number" } } }, @@ -7256,7 +7256,7 @@ }, "retail_price": { "description": "指导零售价", - "type": "integer" + "type": "number" }, "store_list": { "type": "array", @@ -7556,7 +7556,7 @@ }, "min_retail_price": { "description": "最低零售价", - "type": "integer" + "type": "number" }, "name": { "description": "商品名称", @@ -7576,7 +7576,7 @@ }, "retail_price": { "description": "指导零售价", - "type": "integer" + "type": "number" }, "serial_number": { "description": "商品编号", @@ -7584,7 +7584,7 @@ }, "staff_cost_price": { "description": "员工成本价加价(如:加价50,不是加价后的价格)", - "type": "integer" + "type": "number" }, "stock_count": { "description": "库存数量", @@ -7592,7 +7592,7 @@ }, "wholesale_price": { "description": "指导采购价", - "type": "integer" + "type": "number" } } }, @@ -9375,7 +9375,7 @@ }, "retail_price": { "description": "指导零售价", - "type": "integer" + "type": "number" } } }, @@ -10509,11 +10509,11 @@ }, "min_retail_price": { "description": "最低零售价", - "type": "integer" + "type": "number" }, "retail_price": { "description": "指导零售价", - "type": "integer" + "type": "number" }, "store_id": { "description": "门店编号", @@ -10602,7 +10602,7 @@ }, "min_retail_price": { "description": "最低零售价", - "type": "integer" + "type": "number" }, "original_sn": { "description": "首次入库订单编号(单据编号)", @@ -10614,14 +10614,14 @@ }, "retail_price": { "description": "指导零售价", - "type": "integer" + "type": "number" }, "staff_cost_price": { "description": "员工成本价加价(如:加价50,不是加价后的价格)", - "type": "integer" + "type": "number" }, "state": { - "description": "状态:1-在库 2-已售 3-采购退货 4-调拨中 5-销售锁定中", + "description": "状态:1-在库 2-已售 3-采购退货 4-调拨中 5-销售锁定中 6-产品出库 7-盘点出库", "type": "integer" }, "stock_end_time": { @@ -10641,7 +10641,7 @@ "type": "string" }, "storage_type": { - "description": "入库方式:1-系统入库 2-采购入库 3-产品入库", + "description": "入库方式:1-系统入库 2-采购入库 3-产品入库 4-盘点入库", "type": "integer" }, "store_id": { @@ -10654,7 +10654,7 @@ }, "wholesale_price": { "description": "指导采购价", - "type": "integer" + "type": "number" } } }, @@ -11437,6 +11437,7 @@ "models.InventoryChangeAddReq": { "type": "object", "required": [ + "change_type", "commodities", "handler_id", "handler_name", @@ -11444,6 +11445,10 @@ "store_name" ], "properties": { + "change_type": { + "description": "库存变动类型:add-库存增加 reduce-库存减少", + "type": "string" + }, "commodities": { "description": "库存变动商品信息", "type": "array", @@ -11513,6 +11518,7 @@ "models.InventoryChangeEditReq": { "type": "object", "required": [ + "change_type", "commodities", "handler_id", "handler_name", @@ -11521,6 +11527,10 @@ "store_name" ], "properties": { + "change_type": { + "description": "库存变动类型:add-库存增加 reduce-库存减少", + "type": "string" + }, "commodities": { "description": "库存变动商品信息", "type": "array", diff --git a/docs/swagger.yaml b/docs/swagger.yaml index d438bb7..ef0d8a1 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -131,7 +131,7 @@ definitions: type: number min_retail_price: description: 最低零售价 - type: integer + type: number name: description: 商品名称 type: string @@ -143,13 +143,13 @@ definitions: type: string retail_price: description: 指导零售价 - type: integer + type: number staff_cost_price: description: 员工成本价加价 - type: integer + type: number wholesale_price: description: 指导采购价 - type: integer + type: number required: - erp_category_id - erp_supplier_id @@ -204,7 +204,7 @@ definitions: type: number min_retail_price: description: 最低零售价 - type: integer + type: number name: description: 商品名称 type: string @@ -216,13 +216,13 @@ definitions: type: string retail_price: description: 指导零售价 - type: integer + type: number staff_cost_price: description: 员工成本价加价 - type: integer + type: number wholesale_price: description: 指导采购价 - type: integer + type: number required: - erp_category_id - erp_supplier_id @@ -1021,7 +1021,7 @@ definitions: type: string retail_price: description: 指导零售价 - type: integer + type: number store_list: items: properties: @@ -1237,7 +1237,7 @@ definitions: type: number min_retail_price: description: 最低零售价 - type: integer + type: number name: description: 商品名称 type: string @@ -1252,19 +1252,19 @@ definitions: type: string retail_price: description: 指导零售价 - type: integer + type: number serial_number: description: 商品编号 type: string staff_cost_price: description: 员工成本价加价(如:加价50,不是加价后的价格) - type: integer + type: number stock_count: description: 库存数量 type: integer wholesale_price: description: 指导采购价 - type: integer + type: number type: object models.ErpCommodityListReq: properties: @@ -2568,7 +2568,7 @@ definitions: type: string retail_price: description: 指导零售价 - type: integer + type: number type: object models.ErpPurchaseCommodityData: properties: @@ -3396,10 +3396,10 @@ definitions: type: integer min_retail_price: description: 最低零售价 - type: integer + type: number retail_price: description: 指导零售价 - type: integer + type: number store_id: description: 门店编号 type: integer @@ -3465,7 +3465,7 @@ definitions: type: number min_retail_price: description: 最低零售价 - type: integer + type: number original_sn: description: 首次入库订单编号(单据编号) type: string @@ -3474,12 +3474,12 @@ definitions: type: string retail_price: description: 指导零售价 - type: integer + type: number staff_cost_price: description: 员工成本价加价(如:加价50,不是加价后的价格) - type: integer + type: number state: - description: 状态:1-在库 2-已售 3-采购退货 4-调拨中 5-销售锁定中 + description: 状态:1-在库 2-已售 3-采购退货 4-调拨中 5-销售锁定中 6-产品出库 7-盘点出库 type: integer stock_end_time: description: 最近入库结束时间 @@ -3494,7 +3494,7 @@ definitions: description: 最近入库时间 type: string storage_type: - description: 入库方式:1-系统入库 2-采购入库 3-产品入库 + description: 入库方式:1-系统入库 2-采购入库 3-产品入库 4-盘点入库 type: integer store_id: description: 门店id @@ -3504,7 +3504,7 @@ definitions: type: string wholesale_price: description: 指导采购价 - type: integer + type: number type: object models.ErpStockCommodityListReq: properties: @@ -4069,6 +4069,9 @@ definitions: type: object models.InventoryChangeAddReq: properties: + change_type: + description: 库存变动类型:add-库存增加 reduce-库存减少 + type: string commodities: description: 库存变动商品信息 items: @@ -4087,6 +4090,7 @@ definitions: description: 门店名称 type: string required: + - change_type - commodities - handler_id - handler_name @@ -4123,6 +4127,9 @@ definitions: type: object models.InventoryChangeEditReq: properties: + change_type: + description: 库存变动类型:add-库存增加 reduce-库存减少 + type: string commodities: description: 库存变动商品信息 items: @@ -4144,6 +4151,7 @@ definitions: description: 门店名称 type: string required: + - change_type - commodities - handler_id - handler_name