From 6f91388f05f2b974c1203c542e7dd437ce8fdff7 Mon Sep 17 00:00:00 2001 From: chenlin Date: Fri, 10 May 2024 09:54:37 +0800 Subject: [PATCH] =?UTF-8?q?1.=E4=BF=AE=E5=A4=8D=E7=BC=BA=E9=99=B7=EF=BC=9A?= =?UTF-8?q?=20=EF=BC=881=EF=BC=89=E5=95=86=E5=93=81=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E6=8E=92=E5=BA=8F=E8=A7=84=E5=88=99=E8=B0=83=E6=95=B4=EF=BC=9B?= =?UTF-8?q?=20=EF=BC=882=EF=BC=89=E9=9B=B6=E5=94=AE=E8=AE=A2=E5=8D=95?= =?UTF-8?q?=E5=95=86=E5=93=81=E8=A1=A8=E4=B8=AD=EF=BC=8CRetailPrice?= =?UTF-8?q?=E3=80=81SalePrice=E6=94=B9=E4=B8=BAfloat64=E7=B1=BB=E5=9E=8B;?= =?UTF-8?q?=20=EF=BC=883=EF=BC=89=E6=96=B0=E5=BB=BA=E9=87=87=E8=B4=AD?= =?UTF-8?q?=E8=AE=A2=E5=8D=95=E6=97=B6=E9=87=87=E8=B4=AD=E6=88=96=E9=80=80?= =?UTF-8?q?=E8=B4=A7=E6=95=B0=E9=87=8F=E9=9C=80=E5=A4=A7=E4=BA=8E0?= =?UTF-8?q?=EF=BC=9B=20=EF=BC=884=EF=BC=89=E9=87=87=E8=B4=AD=E5=8D=95?= =?UTF-8?q?=E5=85=A5=E5=BA=93=E6=97=B6=E6=AF=8F=E6=9D=A1=E8=AE=B0=E5=BD=95?= =?UTF-8?q?=E9=83=BD=E5=8D=95=E7=8B=AC=E7=94=9F=E6=88=90=E5=85=A5=E5=BA=93?= =?UTF-8?q?=E7=BC=96=E5=8F=B7=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/admin/apis/inventorymanage/Inventory.go | 6 +- app/admin/apis/purchasemanage/purchase.go | 30 ++- app/admin/models/commodity.go | 180 ++++++++++++--- app/admin/models/erp_order.go | 178 ++++++++++++--- app/admin/models/game_card.go | 4 +- app/admin/models/inventory_allot.go | 46 +--- app/admin/models/inventory_report.go | 35 +-- app/admin/models/purchase.go | 230 ++++++++++++-------- docs/docs.go | 149 +++++++------ docs/swagger.json | 149 +++++++------ docs/swagger.yaml | 110 +++++----- 11 files changed, 720 insertions(+), 397 deletions(-) diff --git a/app/admin/apis/inventorymanage/Inventory.go b/app/admin/apis/inventorymanage/Inventory.go index a4eece7..fd44947 100644 --- a/app/admin/apis/inventorymanage/Inventory.go +++ b/app/admin/apis/inventorymanage/Inventory.go @@ -94,7 +94,11 @@ func GetInventoryDetail(c *gin.Context) { list, err := req.GetDetailList(c) if err != nil { //logger.Error("erp stock err:", err) - app.Error(c, http.StatusInternalServerError, err, "查询失败:"+err.Error()) + if err.Error() == "该商品在调拨中" { + app.Error(c, http.StatusInternalServerError, err, err.Error()) + } else { + app.Error(c, http.StatusInternalServerError, err, "查询失败:"+err.Error()) + } return } diff --git a/app/admin/apis/purchasemanage/purchase.go b/app/admin/apis/purchasemanage/purchase.go index b6740e3..c30455b 100644 --- a/app/admin/apis/purchasemanage/purchase.go +++ b/app/admin/apis/purchasemanage/purchase.go @@ -228,9 +228,9 @@ func ErpPurchaseDetail(c *gin.Context) { return } if purchaseOrder.PurchaseType == model.ErpProcureOrder { - v.DefaultEmployeePrice = v.Price + float64(erpCommodity.StaffCostPrice) + v.DefaultEmployeePrice = v.Price + erpCommodity.StaffCostPrice } else if purchaseOrder.PurchaseType == model.ErpProcureOrder { - v.DefaultEmployeePrice = v.RejectedPrice + float64(erpCommodity.StaffCostPrice) + v.DefaultEmployeePrice = v.RejectedPrice + erpCommodity.StaffCostPrice } // 查询执行数量之和、平均执行单价、执行金额之和和平均员工成本价 @@ -249,8 +249,32 @@ func ErpPurchaseDetail(c *gin.Context) { v.ExecutionEmployeePrice = math.Round(v.ExecutionEmployeePrice*100) / 100 v.ExecutionPrice = math.Round(v.ExecutionPrice*100) / 100 + serialNumber := purchaseOrder.SerialNumber + if purchaseOrder.PurchaseType == model.ErpRejectOrder { // 采购退货订单 + serialNumber = purchaseOrder.RejectedSerialNumber + + // 查询原始采购订单的信息 + var rejectOrder model.ErpPurchaseOrder + err := orm.Eloquent.Table("erp_purchase_order").Where("serial_number=?", serialNumber).Find(&rejectOrder).Error + if err != nil { + logger.Error("purchase order err:", logger.Field("err", err)) + app.Error(c, http.StatusBadRequest, err, "获取失败") + return + } + + // 查询执行数量之和、平均执行单价、执行金额之和和平均员工成本价 + rejectResult, err := model.GetTotalsAndAveragesByCommodityID(v.ErpCommodityId, rejectOrder.ID) + if err != nil { + logger.Error("GetTotalsAndAveragesByCommodityID err:", logger.Field("err", err)) + app.Error(c, http.StatusBadRequest, err, "获取失败") + return + } + v.ExecutionCount = rejectResult.TotalCount + v.ExecutionPrice = rejectResult.AvgImplementationPrice + v.ExecutionAmount = rejectResult.TotalAmount + } // 查询入库商品实际库存详情处剩余有效数,不包含已出库的数量 - nCount, err := model.GetCommodityStockByPurchaseId(purchaseOrder.SerialNumber, v.ErpCommodityId) + nCount, err := model.GetCommodityStockByPurchaseId(serialNumber, v.ErpCommodityId) if err != nil { logger.Error("ErpPurchaseDetail GetCommodityStockByPurchaseId err:", logger.Field("err", err)) app.Error(c, http.StatusBadRequest, err, "获取失败") diff --git a/app/admin/models/commodity.go b/app/admin/models/commodity.go index 19132c8..35c1e61 100644 --- a/app/admin/models/commodity.go +++ b/app/admin/models/commodity.go @@ -12,6 +12,7 @@ import ( "golang.org/x/sync/errgroup" "gorm.io/gorm" "math/rand" + "sort" "strconv" "strings" "sync" @@ -343,55 +344,151 @@ func (m *ErpCommodityListReq) List() (*ErpCommodityListResp, error) { //logger.Error("count err:", err) return resp, err } - //resp.Total = int(count)/m.PageSize + 1 + var commodities []ErpCommodity + err = qs.Order("id DESC").Find(&commodities).Error + if err != nil && err != RecordNotFound { + //logger.Error("dailys err:", err) + return resp, err + } + + // 按商品编号进行排序 + SortCommodities(commodities) if m.IsExport == 1 { - err = qs.Order("id DESC").Find(&commodities).Error - if err != nil && err != RecordNotFound { - //logger.Error("dailys err:", err) - return resp, err - } - listExport, err := ErpCommodityListExport(commodities) if err != nil { //logger.Error("list export err:", err) } resp.ExportUrl = listExport } else { - err = qs.Order("id DESC").Offset(page * m.PageSize).Limit(m.PageSize).Find(&commodities).Error - if err != nil && err != RecordNotFound { - //logger.Error("erp commodity list err:", err) - return resp, err + for i, v := range commodities { + if v.IMEIType == 1 { //无串码 + commodities[i].IsIMEI = 2 // 非串码 + } else { + commodities[i].IsIMEI = 1 // 串码 + } + + // 查询库存数量 + var stockCount int64 + err = orm.Eloquent.Table("erp_stock_commodity").Where("erp_commodity_id = ? and state = ?", + v.ID, InStock).Count(&stockCount).Error + if err != nil { + return nil, err + } + commodities[i].StockCount = uint32(stockCount) } - resp.List = commodities + + // 计算分页所需的切片索引 + startIndex := page * m.PageSize + endIndex := (page + 1) * m.PageSize + if endIndex > len(commodities) { + endIndex = len(commodities) + } + resp.List = commodities[startIndex:endIndex] + + //跟之前保持一致 + resp.Total = int(count) + resp.PageIndex = page + 1 + resp.PageSize = m.PageSize } - for i, v := range resp.List { - if v.IMEIType == 1 { //无串码 - resp.List[i].IsIMEI = 2 // 非串码 - } else { - resp.List[i].IsIMEI = 1 // 串码 - } - - // 查询库存数量 - var stockCount int64 - err = orm.Eloquent.Table("erp_stock_commodity").Where("erp_commodity_id = ? and state = ?", - resp.List[i].ID, InStock).Count(&stockCount).Error - if err != nil { - return nil, err - } - resp.List[i].StockCount = uint32(stockCount) - } - - //跟之前保持一致 - resp.Total = int(count) - resp.PageIndex = page + 1 - resp.PageSize = m.PageSize - return resp, nil } +// SortStockCommodities 对库存商品数组进行排序 +func SortStockCommodities(commodities []ErpStock) { + // 定义排序函数 + less := func(i, j int) bool { + // 解析商品编号,提取分类编号和商品编号的数字部分 + catNumI, subCatNumI, threeSubCatNumI, itemNumI := parseSerialNumber(commodities[i].CommoditySerialNumber) + catNumJ, subCatNumJ, threeSubCatNumJ, itemNumJ := parseSerialNumber(commodities[j].CommoditySerialNumber) + + // 按照分类编号从小到大排序 + if catNumI != catNumJ { + return catNumI < catNumJ + } + + // 如果分类编号相同,按照具体分类下的商品编号递增排序 + if subCatNumI != subCatNumJ { + return subCatNumI < subCatNumJ + } + + if threeSubCatNumI != threeSubCatNumJ { + return threeSubCatNumI < threeSubCatNumJ + } + + // 如果具体分类编号也相同,按照商品编号递增排序 + return itemNumI < itemNumJ + } + + // 调用排序函数进行排序 + sort.SliceStable(commodities, less) +} + +// SortCommodities 对商品数组进行排序 +func SortCommodities(commodities []ErpCommodity) { + // 定义排序函数 + less := func(i, j int) bool { + // 解析商品编号,提取分类编号和商品编号的数字部分 + catNumI, subCatNumI, threeSubCatNumI, itemNumI := parseSerialNumber(commodities[i].SerialNumber) + catNumJ, subCatNumJ, threeSubCatNumJ, itemNumJ := parseSerialNumber(commodities[j].SerialNumber) + + // 按照分类编号从小到大排序 + if catNumI != catNumJ { + return catNumI < catNumJ + } + + // 如果分类编号相同,按照具体分类下的商品编号递增排序 + if subCatNumI != subCatNumJ { + return subCatNumI < subCatNumJ + } + + if threeSubCatNumI != threeSubCatNumJ { + return threeSubCatNumI < threeSubCatNumJ + } + + // 如果具体分类编号也相同,按照商品编号递增排序 + return itemNumI < itemNumJ + } + + // 调用排序函数进行排序 + sort.SliceStable(commodities, less) +} + +// parseSerialNumber 解析商品编号,提取分类编号、具体分类编号和商品编号的数字部分 +func parseSerialNumber(serialNumber string) (catNum, subCatNum, threeSubCatNum, itemNum int) { + if len(serialNumber) < 3 { + return 0, 0, 0, 0 // 如果商品编号长度不足3位,则返回默认值 + } + a := serialNumber[:3] + fmt.Println(a) + catNum, _ = strconv.Atoi(serialNumber[:3]) + + switch len(serialNumber) { + case 7: // 一级分类 + subCatNum, _ = strconv.Atoi(serialNumber[3:7]) + case 10: // 二级分类 + b := serialNumber[3:6] + fmt.Println(b) + subCatNum, _ = strconv.Atoi(serialNumber[3:6]) + threeSubCatNum = 0 + c := serialNumber[6:] + fmt.Println(c) + itemNum, _ = strconv.Atoi(serialNumber[6:]) + case 13: // 三级分类 + subCatNum, _ = strconv.Atoi(serialNumber[3:6]) + d := serialNumber[6:9] + fmt.Println(d) + threeSubCatNum, _ = strconv.Atoi(serialNumber[6:9]) + e := serialNumber[9:] + fmt.Println(e) + itemNum, _ = strconv.Atoi(serialNumber[9:]) + } + + return catNum, subCatNum, threeSubCatNum, itemNum +} + type ErpCategoryListReq struct { ErpCategoryId uint32 `json:"erp_category_id"` Pid uint32 `json:"pid"` @@ -1502,6 +1599,8 @@ func (m *ErpStockListReq) stockIsEmptyList(c *gin.Context) (*ErpStockListResp, e } } + SortStockCommodities(stockList) + // Paginate results startIndex := page * m.PageSize endIndex := startIndex + m.PageSize @@ -1677,6 +1776,8 @@ func (m *ErpStockListReq) stockNoEmptyList(c *gin.Context) (*ErpStockListResp, e } } + SortStockCommodities(stockList) + // Paginate results startIndex := page * m.PageSize endIndex := startIndex + m.PageSize @@ -1852,6 +1953,8 @@ func (m *ErpStockListReq) allCommodityList(c *gin.Context) (*ErpStockListResp, e stockList = append(stockList, stock) } + SortStockCommodities(stockList) + //跟之前保持一致 resp.Total = int(count) resp.PageIndex = page + 1 @@ -1993,6 +2096,10 @@ func (m *ErpStockCommodityListReq) GetDetailList(c *gin.Context) (*ErpStockCommo resp.List = commodities } + if len(commodities) == 1 && commodities[0].State == InAllot && m.ScanCode != "" { + return nil, errors.New("该商品在调拨中") + } + //跟之前保持一致 resp.Total = int(count) resp.PageIndex = page + 1 @@ -2077,7 +2184,7 @@ func contains(s []int, e int) bool { func (m *ErpStockCommodityListReq) buildQueryConditions(qs *gorm.DB) { if m.ScanCode != "" { qs = qs.Where("erp_barcode = ? or imei = ?", m.ScanCode, m.ScanCode) - qs = qs.Where("state = ?", InStock) + qs = qs.Where("state in (?)", []uint32{InStock, InAllot}) } else { qs = qs.Where("state in (?)", []uint32{InStock, InAllot}) if m.ErpStockId != 0 { //库存id @@ -2454,7 +2561,8 @@ func GetCodeList(req *QueryCodeReq) (*QueryCodeResp, error) { for _, commodity := range commodities { if commodity.IMEI != "" && strings.Contains(commodity.IMEI, req.ScanCode) { // 串码非空且包含查找的数据 strCode = commodity.IMEI - } else if commodity.IMEI != "" && strings.Contains(commodity.ErpBarcode, req.ScanCode) { // 串码不为空,但条码包含扫码数据 + //} else if commodity.IMEI != "" && strings.Contains(commodity.ErpBarcode, req.ScanCode) { // 串码不为空,但条码包含扫码数据 + } else if commodity.IMEI != "" && commodity.ErpBarcode == req.ScanCode { // 串码不为空,但条码包含扫码数据 return nil, errors.New("串码类商品请直接输入串码") } else { strCode = commodity.ErpBarcode diff --git a/app/admin/models/erp_order.go b/app/admin/models/erp_order.go index 0a343ee..1c687a1 100644 --- a/app/admin/models/erp_order.go +++ b/app/admin/models/erp_order.go @@ -102,8 +102,8 @@ type ErpOrderCommodity struct { IMEIType uint32 `json:"imei_type"` // 1-无串码 2-串码 IMEI string `json:"imei" gorm:"index"` // 串码 PresentType uint32 `json:"present_type"` // 赠送类型:1-非赠送 2-赠送 - RetailPrice int32 `json:"retail_price"` // 指导零售价 - SalePrice int32 `json:"sale_price"` // 零售价 + RetailPrice float64 `json:"retail_price"` // 指导零售价 + SalePrice float64 `json:"sale_price"` // 零售价 Count int32 `json:"count"` // 销售数量 SaleDiscount float64 `json:"sale_discount"` // 零售优惠 MemberDiscount float64 `json:"member_discount"` // 会员优惠 @@ -121,6 +121,7 @@ type ErpOrderCommodity struct { SalesProfit float64 `json:"sales_profit"` // 销售毛利:实际零售价-采购单价;如果为退货订单,则为实际退货价-采购单价 StaffProfit float64 `json:"staff_profit"` // 员工毛利:实际零售价-员工成本价;如果为退货订单,则为实际退货价-员工成本价 ErpStockCommodityID string `json:"erp_stock_commodity_id"` // 库存商品表主键id + StaffPrice int32 `json:"staff_price" gorm:"-"` // 员工成本价 } // ErpOrderCashier 订单收款方式 @@ -174,8 +175,8 @@ type ErpOrderCreateReq struct { RetailType string `json:"retail_type" binding:"required"` // 销售类型:sale 零售销售; rejected 零售退货 Tel string `json:"tel" binding:"required"` // 会员手机号 MemberType string `json:"member_type" binding:"required"` // 会员类型:general 普通; member 会员 - TotalRetailPrice float64 `json:"total_retail_price" binding:"required"` // 订单总指导零售价 - TotalAmount float64 `json:"total_amount" binding:"required"` // 订单实收金额 + TotalRetailPrice float64 `json:"total_retail_price"` // 订单总指导零售价:如果是赠送商品,金额可以为0 + TotalAmount float64 `json:"total_amount"` // 订单实收金额:如果只有1个赠送商品,金额可以为0 TotalCount uint32 `json:"total_count" binding:"required"` // 订单商品数量 VmAmount uint32 `json:"vm_count"` // 使用会员积分 Cashiers []ErpOrderCashier `json:"cashiers" binding:"required"` // 收付款方式 @@ -1080,6 +1081,7 @@ func (m *ErpOrder) SetRetailDetailCommodity() { item.StaffCostPrice = -item.StaffCostPrice item.WholesalePrice = -item.WholesalePrice } + item.StaffPrice = item.StaffCostPrice + item.WholesalePrice if item.IMEIType == 2 || item.IMEIType == 3 || item.IMEI != "" { // 串码 respOrderCommodities = append(respOrderCommodities, item) @@ -1120,6 +1122,7 @@ func (m *ErpOrder) SetRetailDetailCommodity() { orderCommodity.ErpSupplierName = stockCommodity.ErpSupplierName orderCommodity.WholesalePrice = int32(stockCommodity.WholesalePrice) orderCommodity.StaffCostPrice = int32(stockCommodity.StaffCostPrice) + orderCommodity.StaffPrice = orderCommodity.WholesalePrice + orderCommodity.StaffCostPrice respOrderCommodities = append(respOrderCommodities, orderCommodity) } } @@ -1152,7 +1155,7 @@ func erpOrderListSetSalesman(list []ErpOrder) { } func (m *ErpOrder) SetOrderSalesman() error { - var salesProfit, staffProfit float64 + var salesProfit, staffProfit, totalStaffProfit float64 //获取销售毛利、员工毛利数据 for _, item := range m.Commodities { erpCommodity, err := GetCommodity(item.ErpCommodityId) @@ -1161,10 +1164,12 @@ func (m *ErpOrder) SetOrderSalesman() error { } salesProfit += item.SalesProfit * erpCommodity.Brokerage1 * 0.01 staffProfit += item.StaffProfit * erpCommodity.Brokerage2 * 0.01 + totalStaffProfit += item.StaffProfit } // 四舍五入并保留两位小数 salesProfit = math.Round(salesProfit*100) / 100 staffProfit = math.Round(staffProfit*100) / 100 + totalStaffProfit = math.Round(totalStaffProfit*100) / 100 var salesmanInfo []ErpOrderSales err := orm.Eloquent.Model(&ErpOrderSales{}).Where("erp_order_id = ?", m.ID).Find(&salesmanInfo).Error @@ -1183,7 +1188,7 @@ func (m *ErpOrder) SetOrderSalesman() error { logger.Error("GetSysUserInfoByUid err:", logger.Field("err", err)) } item.Name = userInfo.NickName - item.SalesmanPer = staffProfit * userInfo.SalesCommRate / float64(len(salesmanInfo)) + item.SalesmanPer = totalStaffProfit * userInfo.SalesCommRate * 0.01 / float64(len(salesmanInfo)) //if m.RetailType == RetailTypeRejected { // item.SalesProfitPer = -item.SalesProfitPer @@ -1282,6 +1287,42 @@ func (m *ErpOrder) SetErpCashier() { } } +// 添加订单的付款信息 +func erpRetailDetailSetCashier(list []ErpOrder) { + for i, _ := range list { + list[i].SetErpRetailDetailCashier() + } +} + +func (m *ErpOrder) SetErpRetailDetailCashier() { + if m.CashierList != "" { + var cashiers []ErpOrderCashier + err := json.Unmarshal([]byte(m.CashierList), &cashiers) + if err != nil { + logger.Error("unmarshal err:", logger.Field("err", err)) + } + if m.RetailType == RetailTypeRejected { + for i, _ := range cashiers { + cashiers[i].Amount = -cashiers[i].Amount + } + } + + var nTotalOtherAmount float64 + var newCashiers []ErpOrderCashier + for _, item := range cashiers { + if item.CashierId > 4 { + nTotalOtherAmount += item.Amount + } else { + newCashiers = append(newCashiers, item) + } + } + // 将所有其他类型的支付方式合并到一起 + newCashiers = append(newCashiers, ErpOrderCashier{8090, "", nTotalOtherAmount}) + m.Cashiers = newCashiers + m.CashierList = "" + } +} + func GetErpOrderCommodityMap(ids []uint32) (map[uint32]ErpOrderCommodity, error) { commodityMap := make(map[uint32]ErpOrderCommodity, 0) if len(ids) == 0 { @@ -1852,19 +1893,26 @@ func QueryStoreManageData(req *ErpOrderStoreManageDataReq, c *gin.Context) (*Erp } else { qs = qs.Where("maker_time IS NOT NULL") } + qs.Where("state = ?", ErpOrderStateAudited) // 查询数据 if req.SortType == "asc" { - err = qs.Select("DATE_FORMAT(maker_time, '%Y-%m-%d') AS date, SUM(total_amount) AS total_sales_amount, " + - "(SUM(total_retail_price) - SUM(total_amount)) AS promotion_fee, " + - "SUM(total_sales_profit) AS sales_profit, SUM(total_staff_profit) AS staff_profit, SUM(total_count) AS count"). + err = qs.Select("DATE_FORMAT(maker_time, '%Y-%m-%d') AS date, " + + "SUM(CASE WHEN retail_type = 'sale' THEN total_discount ELSE -total_discount END) AS promotion_fee, " + + "SUM(CASE WHEN retail_type = 'sale' THEN total_amount ELSE -total_amount END) AS total_sales_amount, " + + "SUM(CASE WHEN retail_type = 'sale' THEN total_sales_profit ELSE -total_sales_profit END) AS sales_profit, " + + "SUM(CASE WHEN retail_type = 'sale' THEN total_staff_profit ELSE -total_staff_profit END) AS staff_profit, " + + "SUM(CASE WHEN retail_type = 'sale' THEN total_count ELSE -total_count END) AS count"). Group("date"). Order("date ASC"). Find(&storeManageDataList).Error } else { - err = qs.Select("DATE_FORMAT(maker_time, '%Y-%m-%d') AS date, SUM(total_amount) AS total_sales_amount, " + - "(SUM(total_retail_price) - SUM(total_amount)) AS promotion_fee, " + - "SUM(total_sales_profit) AS sales_profit, SUM(total_staff_profit) AS staff_profit, SUM(total_count) AS count"). + err = qs.Select("DATE_FORMAT(maker_time, '%Y-%m-%d') AS date, " + + "SUM(CASE WHEN retail_type = 'sale' THEN total_discount ELSE -total_discount END) AS promotion_fee, " + + "SUM(CASE WHEN retail_type = 'sale' THEN total_amount ELSE -total_amount END) AS total_sales_amount, " + + "SUM(CASE WHEN retail_type = 'sale' THEN total_sales_profit ELSE -total_sales_profit END) AS sales_profit, " + + "SUM(CASE WHEN retail_type = 'sale' THEN total_staff_profit ELSE -total_staff_profit END) AS staff_profit, " + + "SUM(CASE WHEN retail_type = 'sale' THEN total_count ELSE -total_count END) AS count"). Group("date"). Order("date DESC"). Find(&storeManageDataList).Error @@ -2330,8 +2378,14 @@ func QueryRetailMargin(req *ErpOrderRetailMarginReq, c *gin.Context) (*ErpOrderR } resp.ExportUrl = filePath } else { - resp.List = list - resp.Total = len(resp.List) + // 计算分页所需的切片索引 + startIndex := page * req.PageSize + endIndex := (page + 1) * req.PageSize + if endIndex > len(list) { + endIndex = len(list) + } + resp.List = list[startIndex:endIndex] + resp.Total = len(list) resp.PageIndex = req.PageIndex resp.PageSize = req.PageSize } @@ -2654,9 +2708,9 @@ func queryRetailDetailByJoin(req *ErpOrderRetailDetailReq, c *gin.Context) (*Erp orderSumQs = orderSumQs.Where("oc.erp_category_id=?", req.ErpCategoryId) } if req.ErpCommodityName != "" { // 商品名称 - qs = qs.Where("erp_order_commodity.erp_commodity_name like ?", "%"+req.ErpCommodityName+"%") - es = es.Where("erp_order_commodity.erp_commodity_name like ?", "%"+req.ErpCommodityName+"%") - orderSumQs = orderSumQs.Where("oc.erp_commodity_name like ?", "%"+req.ErpCommodityName+"%") + qs = qs.Where("erp_order_commodity.erp_commodity_name = ?", req.ErpCommodityName) + es = es.Where("erp_order_commodity.erp_commodity_name = ?", req.ErpCommodityName) + orderSumQs = orderSumQs.Where("oc.erp_commodity_name = ?", req.ErpCommodityName) } if req.RetailType != "" { // 销售类型 qs = qs.Where("erp_order.retail_type=?", req.RetailType) @@ -2797,6 +2851,12 @@ func queryRetailDetailByJoin(req *ErpOrderRetailDetailReq, c *gin.Context) (*Erp sumData.TotalAmount = 0 // 订单实收金额 sumData.StorePer = 0 // 门店提成 + sumData.ScanAmount = cashier.ScanAmount + sumData.CashAmount = cashier.CashAmount + sumData.PosAmount = cashier.PosAmount + sumData.StoreVmAmount = cashier.StoreVmAmount + sumData.OtherAmount = cashier.OtherAmount + var result []RetailDetailByJoin if req.IsExport == 1 { //导出excel @@ -2836,9 +2896,9 @@ func queryRetailDetailByJoin(req *ErpOrderRetailDetailReq, c *gin.Context) (*Erp } orders := packData(result) + erpOrderListSetCashier(orders) + erpOrderListSetSalesman(orders) pagedOrders := paginate(orders, page, req.PageSize) - //erpOrderListSetCashier(orders) - //erpOrderListSetSalesman(orders) resp.List = pagedOrders @@ -3072,7 +3132,7 @@ func queryRetailDetailCommon(req *ErpOrderRetailDetailReq, c *gin.Context) (*Erp // 计算销售订单和退货订单汇总后的提成数据 totalPerData = subtractTotalPerData(totalPerData, rejectedTotalPerData) - // 销售订单支持汇总 + // 销售订单支付汇总 var cashier TotalCashierData cashierQs := qs cashier, err = getTotalCashierData(cashierQs, RetailTypeSale) @@ -3096,6 +3156,11 @@ func queryRetailDetailCommon(req *ErpOrderRetailDetailReq, c *gin.Context) (*Erp sumData.TotalSalesProfitPer = totalPerData.TotalSalesProfitPer sumData.TotalStaffProfitPer = totalPerData.TotalStaffProfitPer sumData.SalesmanPer = totalPerData.SalesmanPer + sumData.ScanAmount = cashier.ScanAmount + sumData.CashAmount = cashier.CashAmount + sumData.PosAmount = cashier.PosAmount + sumData.StoreVmAmount = cashier.StoreVmAmount + sumData.OtherAmount = cashier.OtherAmount if req.IsExport == 1 { // 导出excel var orders []ErpOrder @@ -3582,12 +3647,6 @@ func CheckUserStore(userStoreId uint32, sysUser *SysUser) bool { // checkOrderData 校验订单数据 func checkOrderData(req *ErpOrderCreateReq, c *gin.Context) (*ErpOrder, error) { - jCashier, err := json.Marshal(req.Cashiers) - if err != nil { - logger.Error("cashiers marshal err:", logger.Field("err", err)) - return nil, errors.New("操作失败:" + err.Error()) - } - sysUser, err := GetSysUserByCtx(c) if err != nil { return nil, errors.New("操作失败:" + err.Error()) @@ -3600,13 +3659,19 @@ func checkOrderData(req *ErpOrderCreateReq, c *gin.Context) (*ErpOrder, error) { } if req.RetailType == RetailTypeSale { - // 校验商品是否有库存 - err = checkOrderCommodityStock(req) + // 校验商品是否有库存,是否是对应门店库存商品 + err = checkOrderCommodityStock(req, sysUser) if err != nil { return nil, err } } + jCashier, err := json.Marshal(req.Cashiers) + if err != nil { + logger.Error("cashiers marshal err:", logger.Field("err", err)) + return nil, errors.New("操作失败:" + err.Error()) + } + // 通过手机号查询用户id,如果没有,则新建一个用户id userInfo, err := GetUserInfoByTel(req.Tel) if err != nil { @@ -3709,6 +3774,7 @@ func checkOrderData(req *ErpOrderCreateReq, c *gin.Context) (*ErpOrder, error) { } } + bCheckFlag := false // 校验商品相关金额是否符合要求 for i, _ := range req.ErpOrderCommodities { if req.RetailType == RetailTypeRejected { // 零售退货订单 @@ -3762,6 +3828,10 @@ func checkOrderData(req *ErpOrderCreateReq, c *gin.Context) (*ErpOrder, error) { req.ErpOrderCommodities[i].StaffProfit = StaffProfit // 员工毛利 erpOrder.TotalSalesProfit += salesProfit erpOrder.TotalStaffProfit += StaffProfit + + if v.PresentType == 1 { // 有非赠送商品 + bCheckFlag = true + } } else if req.RetailType == RetailTypeSale { // 零售订单 var v ErpStockCommodity var ok bool @@ -3790,7 +3860,7 @@ func checkOrderData(req *ErpOrderCreateReq, c *gin.Context) (*ErpOrder, error) { req.ErpOrderCommodities[i].ErpCategoryName = v.ErpCategoryName // 分类名称 req.ErpOrderCommodities[i].ErpSupplierId = v.ErpSupplierId // 供应商id req.ErpOrderCommodities[i].ErpSupplierName = v.ErpSupplierName // 供应商名称 - req.ErpOrderCommodities[i].RetailPrice = int32(v.RetailPrice) // 指导零售价 + req.ErpOrderCommodities[i].RetailPrice = v.RetailPrice // 指导零售价 req.ErpOrderCommodities[i].MemberDiscount = v.MemberDiscount // 会员优惠 req.ErpOrderCommodities[i].StaffCostPrice = int32(v.StaffCostPrice) // 员工成本价加价 req.ErpOrderCommodities[i].WholesalePrice = int32(v.WholesalePrice) // 指导采购价 @@ -3800,7 +3870,7 @@ func checkOrderData(req *ErpOrderCreateReq, c *gin.Context) (*ErpOrder, error) { return nil, errors.New("赠送商品最低零售价不为0,不符合赠送条件,请检查") } - if req.ErpOrderCommodities[i].SalePrice < int32(v.MinRetailPrice) { //零售价不能低于最低零售价 + if req.ErpOrderCommodities[i].SalePrice < v.MinRetailPrice { //零售价不能低于最低零售价 logger.Error("SalePrice less than MinRetailPrice") return nil, errors.New("零售价不能低于最低零售价,请检查") } @@ -3825,6 +3895,41 @@ func checkOrderData(req *ErpOrderCreateReq, c *gin.Context) (*ErpOrder, error) { req.ErpOrderCommodities[i].StaffProfit = StaffProfit // 员工毛利 erpOrder.TotalSalesProfit += salesProfit erpOrder.TotalStaffProfit += StaffProfit + + if req.ErpOrderCommodities[i].PresentType == 1 { // 有非赠送商品 + bCheckFlag = true + } + } + } + + if erpOrder.TotalAmount == 0 && bCheckFlag { + return nil, errors.New("订单包含非赠送商品,实收金额不能为0") + } + + // 判断线上支付金额是否>0 + if req.RetailType == RetailTypeSale { + onlinePayFlag := false + onlinePayAmount := erpOrder.TotalAmount + var nWaitPayAmount float64 + for _, item := range req.Cashiers { + if item.CashierId == 1 { // 线上支付 + onlinePayFlag = true + } else { + onlinePayAmount -= item.Amount + } + nWaitPayAmount += item.Amount + } + if onlinePayFlag && onlinePayAmount <= 0 { // 线上支付且金额小于0则报错 + logger.Error("线上支付金额小于0") + return nil, errors.New("扫码付金额需>0") + } + if nWaitPayAmount > erpOrder.TotalAmount { // 收款金额大于订单金额 + logger.Error("收款金额大于订单金额") + return nil, errors.New("收款金额大于订单金额") + } + if nWaitPayAmount < erpOrder.TotalAmount { // 收款金额小于订单金额 + logger.Error("收款金额小于订单金额") + return nil, errors.New("收款金额小于订单金额") } } @@ -3849,7 +3954,7 @@ func checkOrderData(req *ErpOrderCreateReq, c *gin.Context) (*ErpOrder, error) { } // 校验商品是否有库存 -func checkOrderCommodityStock(req *ErpOrderCreateReq) error { +func checkOrderCommodityStock(req *ErpOrderCreateReq, sysUser *SysUser) error { if len(req.ErpOrderCommodities) != 0 { // 统计串码和非串码商品信息 commodityMap := make(map[uint32]uint32) // 记录非串码商品id及其数量 @@ -3890,18 +3995,21 @@ func checkOrderCommodityStock(req *ErpOrderCreateReq) error { } if len(imeiCommodityMap) != 0 { // 查询串码商品库存 - var count int64 for commodityId, imei := range imeiCommodityMap { + var imeiStockCommodity ErpStockCommodity err := orm.Eloquent.Table("erp_stock_commodity").Where("imei = ? and state = ?", imei, InStock). - Count(&count).Error + Find(&imeiStockCommodity).Error if err != nil { return err } - - if count == 0 { + if imeiStockCommodity.ID == 0 { // 获取商品名称 return errors.New("商品" + "[" + commodityNameMap[commodityId] + "]库存不足") } + + if !CheckUserStore(imeiStockCommodity.StoreId, sysUser) { + return errors.New(commodityNameMap[commodityId] + "商品非所选门店库存,请检查") + } } } diff --git a/app/admin/models/game_card.go b/app/admin/models/game_card.go index bdca8c3..cc6889e 100644 --- a/app/admin/models/game_card.go +++ b/app/admin/models/game_card.go @@ -1492,8 +1492,10 @@ func ExpireMemberSMSSendDay(day uint32, nowTime time.Time) { end := start.AddDate(0, 0, 1) var users []UserInfo + //err := orm.Eloquent.Table("user").Where("member_expire > ?", start).Where("member_expire < ?", end). + // Where("member_level in (?)", []uint32{2, 3, 4, 5}).Find(&users).Error err := orm.Eloquent.Table("user").Where("member_expire > ?", start).Where("member_expire < ?", end). - Where("member_level in (?)", []uint32{2, 3, 4, 5}).Find(&users).Error + Where("member_level = ?", MemberLevelUser).Find(&users).Error if err != nil { logger.Error(err.Error()) return diff --git a/app/admin/models/inventory_allot.go b/app/admin/models/inventory_allot.go index a23004f..c52afc4 100644 --- a/app/admin/models/inventory_allot.go +++ b/app/admin/models/inventory_allot.go @@ -862,14 +862,8 @@ func ReceiveAllotInventory(req *InventoryAllotReceiveReq) error { 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 = ? "+ + 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 { @@ -890,42 +884,14 @@ func ReceiveAllotInventory(req *InventoryAllotReceiveReq) error { } } - // 更新库存商品数量 - exist, err := QueryRecordExist(fmt.Sprintf("SELECT * FROM erp_stock WHERE store_id=%d AND erp_commodity_id=%d", - inventoryAllotOrder.ReceiveStoreId, v.CommodityId)) + // 更新库存商品数量,扣减库存调拨数量 + err = begin.Exec(fmt.Sprintf( + "UPDATE erp_stock SET count=count+%d, dispatch_count = dispatch_count-%d WHERE store_id=%d AND erp_commodity_id=%d", + v.Count, v.Count, inventoryAllotOrder.ReceiveStoreId, v.CommodityId)).Error if err != nil { - logger.Errorf("exist err:", err) + logger.Errorf("update stock 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 - } - } } // 更新调拨订单的状态为:已完成 diff --git a/app/admin/models/inventory_report.go b/app/admin/models/inventory_report.go index 9b88ff2..ba74729 100644 --- a/app/admin/models/inventory_report.go +++ b/app/admin/models/inventory_report.go @@ -586,18 +586,18 @@ func (m *InventoryReportByAllotReq) ReportAllotList(c *gin.Context) (*InventoryR for _, commodityName := range m.CommodityName { commodityNames = append(commodityNames, commodityName) } - qs = qs.Where("erp_inventory_allot_order.commodity_name IN (?)", commodityNames) - countQuery = countQuery.Where("erp_inventory_allot_order.commodity_name IN (?)", commodityNames) + qs = qs.Where("erp_inventory_allot_commodity.commodity_name IN (?)", commodityNames) + countQuery = countQuery.Where("erp_inventory_allot_commodity.commodity_name IN (?)", commodityNames) } - if len(m.CategoryID) > 0 { // 商品分类id - var categoryIDs []uint32 - for _, category := range m.CategoryID { - categoryIDs = append(categoryIDs, category) - } - qs = qs.Where("erp_inventory_allot_order.category_id IN (?)", categoryIDs) - countQuery = countQuery.Where("erp_inventory_allot_order.category_id IN (?)", categoryIDs) - } + //if len(m.CategoryID) > 0 { // 商品分类id + // var categoryIDs []uint32 + // for _, category := range m.CategoryID { + // categoryIDs = append(categoryIDs, category) + // } + // qs = qs.Where("erp_inventory_allot_order.category_id IN (?)", categoryIDs) + // countQuery = countQuery.Where("erp_inventory_allot_order.category_id IN (?)", categoryIDs) + //} if m.State != 0 { // 调拨状态 switch m.State { @@ -669,9 +669,6 @@ func (m *InventoryReportByAllotReq) ReportAllotList(c *gin.Context) (*InventoryR summaryMap := make(map[string]*ReportByAllotData) // 遍历 commodities 切片 for _, item := range commodities { - nTotalAllotCount += item.AllotCount - nTotalAllotAmount += item.AllotAmount - // 生成键 key := fmt.Sprintf("%d_%d_%d", item.DeliverStoreId, item.ReceiveStoreId, item.State) // 检查是否已经存在该键的汇总数据 @@ -707,10 +704,20 @@ func (m *InventoryReportByAllotReq) ReportAllotList(c *gin.Context) (*InventoryR if err != nil { logger.Error("SetCategory err:", logger.Field("err", err)) } + + // 判断分类信息是否有筛选 + if len(m.CategoryID) > 0 { // 商品分类id + if !tools.Uint32SliceContains(m.CategoryID, commodityInfo.ErpCategoryId) { + continue + } + } + summaryMap[i].CategoryID = commodityInfo.ErpCategoryId summaryMap[i].CategoryName = commodityInfo.ErpCategoryName summaryList = append(summaryList, *summary) + nTotalAllotCount += summary.AllotCount + nTotalAllotAmount += summary.AllotAmount } // 排序规则:商品编号小>调出店铺编号小>调入门店编号小>状态为已完成 @@ -734,7 +741,7 @@ func (m *InventoryReportByAllotReq) ReportAllotList(c *gin.Context) (*InventoryR endIndex = len(summaryList) } - resp.Total = len(summaryMap) + resp.Total = len(summaryList) resp.TotalAllotCount = nTotalAllotCount resp.TotalAllotAmount = nTotalAllotAmount resp.List = summaryList[startIndex:endIndex] diff --git a/app/admin/models/purchase.go b/app/admin/models/purchase.go index 44d567a..4a6cc5a 100644 --- a/app/admin/models/purchase.go +++ b/app/admin/models/purchase.go @@ -474,20 +474,21 @@ type ErpPurchaseReportBySupplierResp struct { } type PurchaseReportData struct { - ErpPurchaseOrderId uint32 `json:"erp_purchase_order_id"` // 采购订单id - StoreId uint32 `json:"store_id"` // 门店id - StoreName string `json:"store_name"` // 门店名称 - PurchaseType string `json:"purchase_type"` // 采购类型:procure-采购 reject-退货 - ErpSupplierId uint32 `json:"erp_supplier_id"` // 供应商id - ErpSupplierName string `json:"erp_supplier_name"` // 供应商名称 - ErpCommodityId uint32 `json:"erp_commodity_id"` // 商品id - ErpCommodityName string `json:"erp_commodity_name"` // 商品名称 - ErpCategoryID uint32 `json:"erp_category_id"` // 商品分类id - ErpCategoryName string `json:"erp_category_name"` // 商品分类名称 - Count int32 `json:"count"` // 采购数量 - Amount float64 `json:"amount"` // 采购金额 - RejectAmount float64 `json:"reject_amount"` // 退货金额 - Difference float64 `json:"difference"` // 差额 + ErpPurchaseOrderId uint32 `json:"erp_purchase_order_id"` // 采购订单id + SerialNumber string `json:"serial_number" gorm:"index"` // 入库编号 + StoreId uint32 `json:"store_id"` // 门店id + StoreName string `json:"store_name"` // 门店名称 + PurchaseType string `json:"purchase_type"` // 采购类型:procure-采购 reject-退货 + ErpSupplierId uint32 `json:"erp_supplier_id"` // 供应商id + ErpSupplierName string `json:"erp_supplier_name"` // 供应商名称 + ErpCommodityId uint32 `json:"erp_commodity_id"` // 商品id + ErpCommodityName string `json:"erp_commodity_name"` // 商品名称 + ErpCategoryID uint32 `json:"erp_category_id"` // 商品分类id + ErpCategoryName string `json:"erp_category_name"` // 商品分类名称 + Count int32 `json:"count"` // 采购数量 + Amount float64 `json:"amount"` // 采购金额 + RejectAmount float64 `json:"reject_amount"` // 退货金额 + Difference float64 `json:"difference"` // 差额 } // ErpPurchaseReportDetailReq 采购明细入参 @@ -795,10 +796,20 @@ func CheckCreateErpPurchaseOrderParam(req *ErpPurchaseCreateReq) error { if req.DeliveryTime == "" { return errors.New("操作失败:交货日期为空") } + for _, item := range req.ErpPurchaseCommodities { + if item.Count <= 0 { + return errors.New("操作失败:采购数量需大于0") + } + } } else if req.PurchaseType == ErpRejectOrder { // 退货单 if req.PurchaseOrderSn == "" { return errors.New("操作失败:采购退货单据编号为空") } + for _, item := range req.ErpPurchaseCommodities { + if item.RejectedCount <= 0 { + return errors.New("操作失败:采购退货数量需大于0") + } + } } else { return errors.New("操作失败:采购类型有误") } @@ -1108,7 +1119,6 @@ func InventoryErpPurchase(req *ErpPurchaseInventoryReq, c *gin.Context) error { begin := orm.Eloquent.Begin() var inventoryList []ErpPurchaseInventory for i, v := range req.Inventories { - v.SerialNumber = GetPurchaseInventorySn() req.Inventories[i].SerialNumber = v.SerialNumber // 更新采购商品表的执行数量 // todo 如果用户在同一个采购单中新建了同一个商品的2条采购信息,可能采购价不同,需要区分入库的是哪一条(已修改) @@ -1127,6 +1137,7 @@ func InventoryErpPurchase(req *ErpPurchaseInventoryReq, c *gin.Context) error { nCount := v.Count nAmount := v.Amount for j := 0; j < int(nCount); j++ { // 采购入库记录表都是单笔数据 + v.SerialNumber = GetPurchaseInventorySn() v.ID = 0 v.Count = 1 v.Amount = nAmount / float64(nCount) // 前端传的执行金额是总金额 @@ -1364,7 +1375,7 @@ func InventoryErpPurchaseUpdateRejectStock(gdb *gorm.DB, list []ErpPurchaseInven // 通过首次入库订单编号,查找状态为1-在库的非串码商品 err = orm.Eloquent.Table("erp_stock_commodity"). Where("erp_commodity_id = ? and state = ? and imei_type = ? and original_sn = ?", - list[i].ErpCommodityId, purchaseOrder.StoreId, InStock, 1, purchaseOrder.RejectedSerialNumber). + list[i].ErpCommodityId, InStock, 1, purchaseOrder.RejectedSerialNumber). Order("id DESC").Find(&stockCommodity).Error if err != nil { logger.Error("RetailTypeRejected commodities err:", logger.Field("err", err)) @@ -1547,6 +1558,9 @@ func ExecuteErpPurchase(req *ErpPurchaseExecuteReq, c *gin.Context) (*ErpPurchas } for _, inventory := range req.Inventories { + if inventory.Count == 0 { + continue + } // 获取商品信息 commodityInfo, err := GetCommodity(inventory.ErpCommodityId) if err != nil { @@ -2387,18 +2401,14 @@ func getErpPurchaseDemandAll(req *GetErpPurchaseDemandReq) (*GetErpPurchaseDeman } var commodities []ErpCommodity - if req.IsExport == 1 { // 导出excel - err := qs.Order("id DESC").Find(&commodities).Error - if err != nil && err != RecordNotFound { - return resp, err - } - } else { - err := qs.Order("id DESC").Offset(page * req.PageSize).Limit(req.PageSize).Find(&commodities).Error - if err != nil && err != RecordNotFound { - return resp, err - } + err := qs.Order("id DESC").Find(&commodities).Error + if err != nil && err != RecordNotFound { + return resp, err } + // 按商品编号进行排序 + SortCommodities(commodities) + // 批量查询门店信息 stores, err := GetOnlineStores() if err != nil { @@ -2433,7 +2443,13 @@ func getErpPurchaseDemandAll(req *GetErpPurchaseDemandReq) (*GetErpPurchaseDeman return nil, err } } else { - resp.List = demandDataList + // 计算分页所需的切片索引 + startIndex := page * req.PageSize + endIndex := (page + 1) * req.PageSize + if endIndex > len(demandDataList) { + endIndex = len(demandDataList) + } + resp.List = demandDataList[startIndex:endIndex] resp.Total = count } @@ -2602,7 +2618,7 @@ func convertToDemandData(commodity ErpCommodity, stores []Store) (DemandData, er var lastWholesalePrices map[uint32]float64 var stockCounts map[uint32]uint32 - var lastMonthSales uint32 + var lastMonthSales map[uint32]uint32 go func() { defer wg.Done() @@ -2640,7 +2656,7 @@ func convertToDemandData(commodity ErpCommodity, stores []Store) (DemandData, er demandData.StoreList[i].StoreName = store.Name demandData.StoreList[i].StockCount = stockCounts[store.ID] - demandData.StoreList[i].LastMonthSales = lastMonthSales + demandData.StoreList[i].LastMonthSales = lastMonthSales[store.ID] // 设置最近采购价 demandData.LastWholesalePrice = lastWholesalePrices[commodity.ID] @@ -2758,7 +2774,7 @@ func GetCommodityStockByPurchaseId(serialNumber string, orderId uint32) (uint32, } // GetCommodityLastMonthSales 批量查询商品的上月销售数量 -func GetCommodityLastMonthSales(commodityID uint32, stores []Store) (uint32, error) { +func GetCommodityLastMonthSales(commodityID uint32, stores []Store) (map[uint32]uint32, error) { // 获取上个月的时间范围 firstDay, lastDay := GetLastMonthRange() @@ -2766,21 +2782,17 @@ func GetCommodityLastMonthSales(commodityID uint32, stores []Store) (uint32, err var wg sync.WaitGroup wg.Add(len(stores)) - var totalSales uint32 + result := make(map[uint32]uint32) var mu sync.Mutex // 用于保护 totalSales 的并发访问 for _, store := range stores { go func(storeID uint32) { defer wg.Done() // 查询上月销售数量 - var sales uint32 - err := orm.Eloquent.Table("erp_order_commodity"). - Joins("JOIN erp_order ON erp_order_commodity.erp_order_id = erp_order.id"). - Where("erp_order.pay_status = ? AND erp_order_commodity.erp_commodity_id = ? AND erp_order.store_id = ? "+ - "AND erp_order_commodity.created_at BETWEEN ? AND ?", - HavePaid, commodityID, storeID, firstDay, lastDay). - Select("SUM(erp_order_commodity.count) AS sales"). - Scan(&sales).Error + var sales int64 + err := orm.Eloquent.Table("erp_stock_commodity"). + Where("state = ? AND erp_commodity_id = ? AND store_id = ? AND updated_at BETWEEN ? AND ?", + SoldOut, commodityID, storeID, firstDay, lastDay).Count(&sales).Error if err != nil { // Handle error return @@ -2789,13 +2801,13 @@ func GetCommodityLastMonthSales(commodityID uint32, stores []Store) (uint32, err // 保护 totalSales 的并发访问 mu.Lock() defer mu.Unlock() - totalSales += sales + result[storeID] = uint32(sales) }(store.ID) } wg.Wait() - return totalSales, nil + return result, nil } // GetLastMonthRange 获取上个月的时间范围 @@ -2839,6 +2851,24 @@ func GetTotalsAndAveragesByCommodityID(commodityID, orderID uint32) (Result, err return result, nil } +type ResultPrice struct { + TotalWholesalePrice float64 `gorm:"column:total_wholesale_price"` +} + +// GetTotalWholesalePrice 查询采购退货订单对应的采购金额 +func GetTotalWholesalePrice(commodityID uint32, serialNumber string) (ResultPrice, error) { + var result ResultPrice + err := orm.Eloquent.Table("erp_stock_commodity"). + Select("SUM(`wholesale_price`) AS total_wholesale_price"). + Where("erp_commodity_id = ? and stock_sn = ?", commodityID, serialNumber). + Scan(&result).Error + if err != nil { + return ResultPrice{}, err + } + + return result, nil +} + // UpdateRetailPrice 更新指导零售价 func UpdateRetailPrice(begin *gorm.DB, commodityId uint32, retailPrice float64) error { // 更新商品信息表 @@ -3117,7 +3147,8 @@ func getReportByOrderFromCommodityOrCategory(req *ErpPurchaseReportByOrderReq, c // 遍历 inventoryList,将不同的 ErpCommodityId 存入 map 中 for _, inventory := range inventoryList { - commodityMap[inventory.ErpCommodityId] = inventory.ErpPurchaseOrderId + //commodityMap[inventory.ErpCommodityId] = inventory.ErpPurchaseOrderId + commodityMap[inventory.ErpPurchaseOrderId] = inventory.ErpCommodityId } // 计算不同的 ErpCommodityId 的数量 differentCommodityCount := len(commodityMap) @@ -3126,7 +3157,7 @@ func getReportByOrderFromCommodityOrCategory(req *ErpPurchaseReportByOrderReq, c var nTotalAmount float64 var nTotalCount int32 // 查询采购订单信息 - for _, v := range commodityMap { + for k, _ := range commodityMap { var purchaseOrder ErpPurchaseOrder var commodityList []ErpPurchaseCommodityData @@ -3139,7 +3170,7 @@ func getReportByOrderFromCommodityOrCategory(req *ErpPurchaseReportByOrderReq, c query = query.Where("erp_purchase_order.store_id IN (?)", req.StoreId) } - err = query.Where("id = ?", v).Find(&purchaseOrder).Error + err = query.Where("id = ?", k).Find(&purchaseOrder).Error if err != nil { return nil, err } @@ -4024,6 +4055,7 @@ func getReportByCommodityFromCommon(req *ErpPurchaseReportByCommodityReq, c *gin go getPurchaseOrderAndCommodityDataAsync(v.ID, commodityID, ch, &wg) } } + wg.Wait() close(ch) @@ -4130,7 +4162,15 @@ func getReportByCommodityFromCommon(req *ErpPurchaseReportByCommodityReq, c *gin sortByCommodityIDDesc(dataList) resp.Total = len(dataList) - resp.List = dataList + + // 计算分页所需的切片索引 + startIndex := page * req.PageSize + endIndex := (page + 1) * req.PageSize + if endIndex > len(dataList) { + endIndex = len(dataList) + } + + resp.List = dataList[startIndex:endIndex] resp.PlanCount = totalData.PlanCount resp.PlanAmount = totalData.PlanAmount resp.Amount = totalData.Amount @@ -4315,18 +4355,23 @@ func getSignalPurchaseData(erpPurchaseOrderId, commodityId uint32) (PurchaseData func getAllOrderCommodity(pageIndex, pageSize, isExport int) (map[uint32][]uint32, error) { var commodityMap = make(map[uint32][]uint32) var query string - if isExport == 1 { //导出excel - // 执行原生 SQL 查询,联结表格,按照每个商品ID列出所有的订单ID - query = fmt.Sprintf(` + // if isExport == 1 { //导出excel + // // 执行原生 SQL 查询,联结表格,按照每个商品ID列出所有的订单ID + // query = fmt.Sprintf(` + // SELECT erp_commodity_id, GROUP_CONCAT(erp_purchase_order_id) AS order_ids FROM erp_purchase_commodity + //GROUP BY erp_commodity_id`) + // } else { + // // 执行原生 SQL 查询,联结表格,按照每个商品ID列出所有的订单ID + // query = fmt.Sprintf(` + // SELECT erp_commodity_id, GROUP_CONCAT(erp_purchase_order_id) AS order_ids FROM erp_purchase_commodity + //GROUP BY erp_commodity_id + // LIMIT %d OFFSET %d`, pageSize, pageIndex*pageSize) + // } + + // 执行原生 SQL 查询,联结表格,按照每个商品ID列出所有的订单ID + query = fmt.Sprintf(` SELECT erp_commodity_id, GROUP_CONCAT(erp_purchase_order_id) AS order_ids FROM erp_purchase_commodity GROUP BY erp_commodity_id`) - } else { - // 执行原生 SQL 查询,联结表格,按照每个商品ID列出所有的订单ID - query = fmt.Sprintf(` - SELECT erp_commodity_id, GROUP_CONCAT(erp_purchase_order_id) AS order_ids FROM erp_purchase_commodity -GROUP BY erp_commodity_id - LIMIT %d OFFSET %d`, pageSize, pageIndex*pageSize) - } rows, err := orm.Eloquent.Raw(query).Rows() if err != nil { @@ -4593,7 +4638,8 @@ func GetReportBySupplier(req *ErpPurchaseReportBySupplierReq, c *gin.Context) ( // 构建查询条件 query := orm.Eloquent.Model(&ErpPurchaseInventory{}). - Select("erp_purchase_inventory.erp_purchase_order_id, erp_purchase_inventory.purchase_type, " + + Select("erp_purchase_inventory.erp_purchase_order_id, " + + "erp_purchase_inventory.purchase_type, erp_purchase_inventory.serial_number, " + "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, " + @@ -4605,7 +4651,8 @@ func GetReportBySupplier(req *ErpPurchaseReportBySupplierReq, c *gin.Context) ( "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, " + + Select("erp_purchase_inventory.erp_purchase_order_id, " + + "erp_purchase_inventory.purchase_type, erp_purchase_inventory.serial_number, " + "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, " + @@ -4661,14 +4708,8 @@ func GetReportBySupplier(req *ErpPurchaseReportBySupplierReq, c *gin.Context) ( countQuery.Count(&total) resp.Total = int(total) - // 分页查询 var err error - if req.IsExport == 1 { // 导出excel - err = query.Find(&resp.List).Error - } else { - //err = query.Offset((req.PageIndex - 1) * req.PageSize).Limit(req.PageSize).Find(&resp.List).Error - err = query.Find(&resp.List).Error - } + err = query.Find(&resp.List).Error if err != nil { return nil, err } @@ -4706,23 +4747,23 @@ func GetReportBySupplier(req *ErpPurchaseReportBySupplierReq, c *gin.Context) ( } if data.PurchaseType == "reject" { - // 查询退货商品的采购金额 - var oldOrderInfo ErpPurchaseOrder - err = orm.Eloquent.Where("serial_number = ?", po.SerialNumber).First(&oldOrderInfo).Error - if err != nil { - return nil, err - } + //// 查询退货商品的采购金额 + //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) + var resultInfo ResultPrice + resultInfo, err = GetTotalWholesalePrice(respItem.ErpCommodityId, respItem.SerialNumber) if err != nil { return nil, err } + data.Difference = -(resultInfo.TotalWholesalePrice - data.Amount) data.RejectAmount = -data.Amount - data.Amount = -resultInfo.AvgImplementationPrice * float64(data.Count) - data.Difference = data.RejectAmount - data.Amount + data.Amount = -resultInfo.TotalWholesalePrice data.Count = -data.Count } @@ -4746,23 +4787,22 @@ func GetReportBySupplier(req *ErpPurchaseReportBySupplierReq, c *gin.Context) ( resp.List[i].ErpSupplierName = purchaseOrderInfo.ErpSupplierName if resp.List[i].PurchaseType == "reject" { - // 查询退货商品的采购金额 - var oldOrderInfo ErpPurchaseOrder - err = orm.Eloquent.Where("serial_number = ?", purchaseOrderInfo.SerialNumber).First(&oldOrderInfo).Error - if err != nil { - return nil, err - } + //// 查询退货商品的采购金额 + //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) + var resultInfo ResultPrice + resultInfo, err = GetTotalWholesalePrice(resp.List[i].ErpCommodityId, resp.List[i].SerialNumber) if err != nil { return nil, err } - + resp.List[i].Difference = -(resultInfo.TotalWholesalePrice - resp.List[i].Amount) 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].Amount = -resultInfo.TotalWholesalePrice resp.List[i].Count = -resp.List[i].Count } } @@ -4788,6 +4828,26 @@ func GetReportBySupplier(req *ErpPurchaseReportBySupplierReq, c *gin.Context) ( resp.Difference = totalDifference resp.Total = len(mergedData) + // 排序规则:供应商编号小>商品编号小>店铺编号小>类型为采购入库 + sort.Slice(mergedData, func(i, j int) bool { + if mergedData[i].ErpSupplierId != mergedData[j].ErpSupplierId { + return mergedData[i].ErpSupplierId < mergedData[j].ErpSupplierId + } + if mergedData[i].ErpCommodityId != mergedData[j].ErpCommodityId { + return mergedData[i].ErpCommodityId < mergedData[j].ErpCommodityId + } + if mergedData[i].StoreId != mergedData[j].StoreId { + return mergedData[i].StoreId < mergedData[j].StoreId + } + if mergedData[i].PurchaseType == ErpProcureOrder && mergedData[j].PurchaseType != ErpProcureOrder { + return true + } + if mergedData[i].PurchaseType != ErpProcureOrder && mergedData[j].PurchaseType == ErpProcureOrder { + return false + } + return false // 默认情况下相等 + }) + // 分页处理 startIdx := (resp.PageIndex - 1) * resp.PageSize endIdx := resp.PageIndex * resp.PageSize diff --git a/docs/docs.go b/docs/docs.go index 3736e12..d0ba700 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -7254,6 +7254,75 @@ const docTemplate = `{ } } }, + "models.DecisionSumData": { + "type": "object", + "properties": { + "total_allot_in": { + "description": "调拨入库", + "type": "integer" + }, + "total_allot_out": { + "description": "调拨出库", + "type": "integer" + }, + "total_allot_wait_in": { + "description": "在途库存(入库)", + "type": "integer" + }, + "total_allot_wait_out": { + "description": "在途库存(出库)", + "type": "integer" + }, + "total_begin_amount": { + "description": "期初金额", + "type": "number" + }, + "total_begin_stock": { + "description": "期初库存", + "type": "integer" + }, + "total_check_in": { + "description": "盘点入库", + "type": "integer" + }, + "total_check_out": { + "description": "盘点出库", + "type": "integer" + }, + "total_end_amount": { + "description": "期末金额", + "type": "number" + }, + "total_end_stock": { + "description": "期末数量", + "type": "integer" + }, + "total_order_reject": { + "description": "零售退货", + "type": "integer" + }, + "total_order_sale": { + "description": "零售销售", + "type": "integer" + }, + "total_product_in": { + "description": "产品入库", + "type": "integer" + }, + "total_purchase_return": { + "description": "采购退货", + "type": "integer" + }, + "total_purchase_stock": { + "description": "采购进货", + "type": "integer" + }, + "total_system_out": { + "description": "系统出库", + "type": "integer" + } + } + }, "models.DefaultUserNameAndPasswordResp": { "type": "object", "properties": { @@ -7859,6 +7928,7 @@ const docTemplate = `{ "type": "string" }, "list": { + "description": "明细数据", "type": "array", "items": { "$ref": "#/definitions/models.DecisionReportData" @@ -7872,73 +7942,17 @@ const docTemplate = `{ "description": "页面条数", "type": "integer" }, + "sum_data": { + "description": "汇总数据", + "allOf": [ + { + "$ref": "#/definitions/models.DecisionSumData" + } + ] + }, "total": { "description": "总条数/记录数", "type": "integer" - }, - "total_allot_in": { - "description": "调拨入库", - "type": "integer" - }, - "total_allot_out": { - "description": "调拨出库", - "type": "integer" - }, - "total_allot_wait_in": { - "description": "在途库存(入库)", - "type": "integer" - }, - "total_allot_wait_out": { - "description": "在途库存(出库)", - "type": "integer" - }, - "total_begin_amount": { - "description": "期初金额", - "type": "number" - }, - "total_begin_stock": { - "description": "期初库存", - "type": "integer" - }, - "total_check_in": { - "description": "盘点入库", - "type": "integer" - }, - "total_check_out": { - "description": "盘点出库", - "type": "integer" - }, - "total_end_amount": { - "description": "期末金额", - "type": "number" - }, - "total_end_stock": { - "description": "期末数量", - "type": "integer" - }, - "total_order_reject": { - "description": "零售退货", - "type": "integer" - }, - "total_order_sale": { - "description": "零售销售", - "type": "integer" - }, - "total_product_in": { - "description": "产品入库", - "type": "integer" - }, - "total_purchase_return": { - "description": "采购退货", - "type": "integer" - }, - "total_purchase_stock": { - "description": "采购进货", - "type": "integer" - }, - "total_system_out": { - "description": "系统出库", - "type": "integer" } } }, @@ -8694,6 +8708,10 @@ const docTemplate = `{ "description": "员工成本价加价(如:加价50,不是加价后的价格)", "type": "integer" }, + "staff_price": { + "description": "员工成本价", + "type": "integer" + }, "staff_profit": { "description": "员工毛利:实际零售价-员工成本价;如果为退货订单,则为实际退货价-员工成本价", "type": "number" @@ -8719,7 +8737,6 @@ const docTemplate = `{ "store_id", "store_name", "tel", - "total_amount", "total_count", "total_retail_price" ], @@ -8770,7 +8787,7 @@ const docTemplate = `{ "type": "string" }, "total_amount": { - "description": "订单实收金额", + "description": "订单实收金额:如果只有1个赠送商品,金额可以为0", "type": "number" }, "total_count": { diff --git a/docs/swagger.json b/docs/swagger.json index 5711bdd..9ea92eb 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -7243,6 +7243,75 @@ } } }, + "models.DecisionSumData": { + "type": "object", + "properties": { + "total_allot_in": { + "description": "调拨入库", + "type": "integer" + }, + "total_allot_out": { + "description": "调拨出库", + "type": "integer" + }, + "total_allot_wait_in": { + "description": "在途库存(入库)", + "type": "integer" + }, + "total_allot_wait_out": { + "description": "在途库存(出库)", + "type": "integer" + }, + "total_begin_amount": { + "description": "期初金额", + "type": "number" + }, + "total_begin_stock": { + "description": "期初库存", + "type": "integer" + }, + "total_check_in": { + "description": "盘点入库", + "type": "integer" + }, + "total_check_out": { + "description": "盘点出库", + "type": "integer" + }, + "total_end_amount": { + "description": "期末金额", + "type": "number" + }, + "total_end_stock": { + "description": "期末数量", + "type": "integer" + }, + "total_order_reject": { + "description": "零售退货", + "type": "integer" + }, + "total_order_sale": { + "description": "零售销售", + "type": "integer" + }, + "total_product_in": { + "description": "产品入库", + "type": "integer" + }, + "total_purchase_return": { + "description": "采购退货", + "type": "integer" + }, + "total_purchase_stock": { + "description": "采购进货", + "type": "integer" + }, + "total_system_out": { + "description": "系统出库", + "type": "integer" + } + } + }, "models.DefaultUserNameAndPasswordResp": { "type": "object", "properties": { @@ -7848,6 +7917,7 @@ "type": "string" }, "list": { + "description": "明细数据", "type": "array", "items": { "$ref": "#/definitions/models.DecisionReportData" @@ -7861,73 +7931,17 @@ "description": "页面条数", "type": "integer" }, + "sum_data": { + "description": "汇总数据", + "allOf": [ + { + "$ref": "#/definitions/models.DecisionSumData" + } + ] + }, "total": { "description": "总条数/记录数", "type": "integer" - }, - "total_allot_in": { - "description": "调拨入库", - "type": "integer" - }, - "total_allot_out": { - "description": "调拨出库", - "type": "integer" - }, - "total_allot_wait_in": { - "description": "在途库存(入库)", - "type": "integer" - }, - "total_allot_wait_out": { - "description": "在途库存(出库)", - "type": "integer" - }, - "total_begin_amount": { - "description": "期初金额", - "type": "number" - }, - "total_begin_stock": { - "description": "期初库存", - "type": "integer" - }, - "total_check_in": { - "description": "盘点入库", - "type": "integer" - }, - "total_check_out": { - "description": "盘点出库", - "type": "integer" - }, - "total_end_amount": { - "description": "期末金额", - "type": "number" - }, - "total_end_stock": { - "description": "期末数量", - "type": "integer" - }, - "total_order_reject": { - "description": "零售退货", - "type": "integer" - }, - "total_order_sale": { - "description": "零售销售", - "type": "integer" - }, - "total_product_in": { - "description": "产品入库", - "type": "integer" - }, - "total_purchase_return": { - "description": "采购退货", - "type": "integer" - }, - "total_purchase_stock": { - "description": "采购进货", - "type": "integer" - }, - "total_system_out": { - "description": "系统出库", - "type": "integer" } } }, @@ -8683,6 +8697,10 @@ "description": "员工成本价加价(如:加价50,不是加价后的价格)", "type": "integer" }, + "staff_price": { + "description": "员工成本价", + "type": "integer" + }, "staff_profit": { "description": "员工毛利:实际零售价-员工成本价;如果为退货订单,则为实际退货价-员工成本价", "type": "number" @@ -8708,7 +8726,6 @@ "store_id", "store_name", "tel", - "total_amount", "total_count", "total_retail_price" ], @@ -8759,7 +8776,7 @@ "type": "string" }, "total_amount": { - "description": "订单实收金额", + "description": "订单实收金额:如果只有1个赠送商品,金额可以为0", "type": "number" }, "total_count": { diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 1ba9d27..be35ed6 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -987,6 +987,57 @@ definitions: description: 系统出库 type: integer type: object + models.DecisionSumData: + properties: + total_allot_in: + description: 调拨入库 + type: integer + total_allot_out: + description: 调拨出库 + type: integer + total_allot_wait_in: + description: 在途库存(入库) + type: integer + total_allot_wait_out: + description: 在途库存(出库) + type: integer + total_begin_amount: + description: 期初金额 + type: number + total_begin_stock: + description: 期初库存 + type: integer + total_check_in: + description: 盘点入库 + type: integer + total_check_out: + description: 盘点出库 + type: integer + total_end_amount: + description: 期末金额 + type: number + total_end_stock: + description: 期末数量 + type: integer + total_order_reject: + description: 零售退货 + type: integer + total_order_sale: + description: 零售销售 + type: integer + total_product_in: + description: 产品入库 + type: integer + total_purchase_return: + description: 采购退货 + type: integer + total_purchase_stock: + description: 采购进货 + type: integer + total_system_out: + description: 系统出库 + type: integer + type: object models.DefaultUserNameAndPasswordResp: properties: password: @@ -1426,6 +1477,7 @@ definitions: description: 导出excel路径 type: string list: + description: 明细数据 items: $ref: '#/definitions/models.DecisionReportData' type: array @@ -1435,57 +1487,13 @@ definitions: pageSize: description: 页面条数 type: integer + sum_data: + allOf: + - $ref: '#/definitions/models.DecisionSumData' + description: 汇总数据 total: description: 总条数/记录数 type: integer - total_allot_in: - description: 调拨入库 - type: integer - total_allot_out: - description: 调拨出库 - type: integer - total_allot_wait_in: - description: 在途库存(入库) - type: integer - total_allot_wait_out: - description: 在途库存(出库) - type: integer - total_begin_amount: - description: 期初金额 - type: number - total_begin_stock: - description: 期初库存 - type: integer - total_check_in: - description: 盘点入库 - type: integer - total_check_out: - description: 盘点出库 - type: integer - total_end_amount: - description: 期末金额 - type: number - total_end_stock: - description: 期末数量 - type: integer - total_order_reject: - description: 零售退货 - type: integer - total_order_sale: - description: 零售销售 - type: integer - total_product_in: - description: 产品入库 - type: integer - total_purchase_return: - description: 采购退货 - type: integer - total_purchase_stock: - description: 采购进货 - type: integer - total_system_out: - description: 系统出库 - type: integer type: object models.ErpInventoryAllotCommodity: properties: @@ -2042,6 +2050,9 @@ definitions: staff_cost_price: description: 员工成本价加价(如:加价50,不是加价后的价格) type: integer + staff_price: + description: 员工成本价 + type: integer staff_profit: description: 员工毛利:实际零售价-员工成本价;如果为退货订单,则为实际退货价-员工成本价 type: number @@ -2088,7 +2099,7 @@ definitions: description: 会员手机号 type: string total_amount: - description: 订单实收金额 + description: 订单实收金额:如果只有1个赠送商品,金额可以为0 type: number total_count: description: 订单商品数量 @@ -2108,7 +2119,6 @@ definitions: - store_id - store_name - tel - - total_amount - total_count - total_retail_price type: object