From dc134e138aa74358be538fe7caee9b85814d8614 Mon Sep 17 00:00:00 2001 From: chenlin Date: Thu, 31 Oct 2024 18:05:55 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E6=9F=A5=E8=AF=A2=E9=97=A8=E5=BA=97?= =?UTF-8?q?=E7=BB=8F=E8=90=A5=E5=85=A5=E5=8F=82=E9=97=A8=E5=BA=97=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=E6=94=B9=E6=88=90=E5=8F=AF=E4=BB=A5=E5=A4=8D=E9=80=89?= =?UTF-8?q?=EF=BC=9B=202=E3=80=81=E5=BA=93=E5=AD=98=E8=B0=83=E6=8B=A8?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E6=9F=A5=E8=AF=A2=E8=AF=A6=E6=83=85=E6=97=B6?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=E5=AF=B9=E5=BA=94=E5=95=86=E5=93=81=E7=9A=84?= =?UTF-8?q?=E5=BA=93=E5=AD=98=E6=95=B0=E9=87=8F=EF=BC=9B=203=E3=80=81?= =?UTF-8?q?=E9=87=87=E8=B4=AD=E5=85=A5=E5=BA=93=E4=BC=98=E5=8C=96=EF=BC=8C?= =?UTF-8?q?=E5=85=A5=E5=BA=93=E5=90=8E=E4=B8=8D=E5=86=8D=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E5=AE=A1=E6=A0=B8=E6=97=B6=E9=97=B4=EF=BC=9B=204=E3=80=81?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E9=87=87=E8=B4=AD=E6=8A=A5=E8=A1=A8=EF=BC=88?= =?UTF-8?q?=E6=8C=89=E5=8D=95=EF=BC=89=E5=89=94=E9=99=A4=E5=BE=85=E5=85=A5?= =?UTF-8?q?=E5=BA=93=E4=B8=94=E5=B7=B2=E5=85=A5=E5=BA=93=E6=95=B0=E9=87=8F?= =?UTF-8?q?=E4=B8=BA0=E7=9A=84=E8=AE=A2=E5=8D=95=EF=BC=9B=205=E3=80=81?= =?UTF-8?q?=E9=87=87=E8=B4=AD=E6=8A=A5=E8=A1=A8=EF=BC=88=E6=8C=89=E5=95=86?= =?UTF-8?q?=E5=93=81=EF=BC=89=E5=89=94=E9=99=A4=E5=B7=B2=E7=BB=88=E6=AD=A2?= =?UTF-8?q?=E7=9A=84=E8=AE=A2=E5=8D=95=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/admin/models/erp_order.go | 38 ++++++------ app/admin/models/inventory_allot.go | 94 +++++++++++++++++++---------- app/admin/models/purchase.go | 39 ++++++------ docs/docs.go | 49 ++++++++++++++- docs/swagger.json | 49 ++++++++++++++- docs/swagger.yaml | 37 +++++++++++- 6 files changed, 236 insertions(+), 70 deletions(-) diff --git a/app/admin/models/erp_order.go b/app/admin/models/erp_order.go index 845e1b2..f15cafd 100644 --- a/app/admin/models/erp_order.go +++ b/app/admin/models/erp_order.go @@ -253,13 +253,13 @@ type ErpOrderAddInvoiceReq struct { // ErpOrderStoreManageDataReq 查询门店经营入参 type ErpOrderStoreManageDataReq struct { - StoreId uint32 `json:"store_id"` // 门店ID - StartTime string `json:"start_time"` // 开始时间 - EndTime string `json:"end_time"` // 结束时间 - PageIndex int `json:"pageIndex"` // 页码 - PageSize int `json:"pageSize"` // 页面条数 - IsExport uint32 `json:"is_export"` // 1-导出 - SortType string `json:"sort_type"` // 排序类型:desc 降序、asc 升序 + StoreId []uint32 `json:"store_id"` // 门店ID + StartTime string `json:"start_time"` // 开始时间 + EndTime string `json:"end_time"` // 结束时间 + PageIndex int `json:"pageIndex"` // 页码 + PageSize int `json:"pageSize"` // 页面条数 + IsExport uint32 `json:"is_export"` // 1-导出 + SortType string `json:"sort_type"` // 排序类型:desc 降序、asc 升序 } // ErpOrderStoreManageDataResp 查询门店经营出参 @@ -2398,8 +2398,8 @@ func QueryStoreManageData(req *ErpOrderStoreManageDataReq, c *gin.Context) (*Erp // 构建查询条件 qs := orm.Eloquent.Model(&ErpOrder{}) - if req.StoreId != 0 { - qs = qs.Where("store_id = ?", req.StoreId) + if len(req.StoreId) != 0 { + qs.Where("erp_order.store_id in ?", req.StoreId) } // 非管理员才判断所属门店 if !(tools.GetRoleName(c) == "admin" || tools.GetRoleName(c) == "系统管理员") { @@ -2499,18 +2499,18 @@ func QueryStoreManageData(req *ErpOrderStoreManageDataReq, c *gin.Context) (*Erp resp.TotalCount = summary.TotalCount if req.IsExport == 1 { //导出excel - storeName := "所有门店" - if req.StoreId != 0 { - storeInfo, err := GetStore(req.StoreId) - if err != nil { - logger.Error("GetStore err:", logger.Field("err", err)) - return nil, err - } - storeName = storeInfo.Name - } + //storeName := "所有门店" + //if req.StoreId != 0 { + // storeInfo, err := GetStore(req.StoreId) + // if err != nil { + // logger.Error("GetStore err:", logger.Field("err", err)) + // return nil, err + // } + // storeName = storeInfo.Name + //} finalStoreManageDataList = constructFinalStoreManageDataList(storeManageDataList, req) - filePath, err := storeManageDataExport(finalStoreManageDataList, storeName, summary, c) + filePath, err := storeManageDataExport(finalStoreManageDataList, "门店", summary, c) if err != nil { logger.Error("StoreManageDataExport err:", logger.Field("err", err)) return nil, err diff --git a/app/admin/models/inventory_allot.go b/app/admin/models/inventory_allot.go index f8f6e70..eafd79c 100644 --- a/app/admin/models/inventory_allot.go +++ b/app/admin/models/inventory_allot.go @@ -787,40 +787,72 @@ func MergeCommodities(commodities []ErpInventoryAllotCommodity) []ErpInventoryAl return mergedCommodities } -// UpdateStockCounts 根据传入的 storeId 更新每个商品的库存数量。 +// UpdateStockCounts 根据商品类型(串码或非串码)以及 storeId 更新每个商品的库存数量。 func UpdateStockCounts(commodities []ErpInventoryAllotCommodity, storeId uint32) ([]ErpInventoryAllotCommodity, error) { - // 收集商品 ID - var commodityIDs []uint32 - for _, commodity := range commodities { - commodityIDs = append(commodityIDs, commodity.CommodityId) - } + // 创建映射表,分开存储串码商品和非串码商品 + imeiMap := make(map[string]*ErpInventoryAllotCommodity) // 串码商品 + nonImeiMap := make(map[uint32]*ErpInventoryAllotCommodity) // 非串码商品 - // 查询数据库中的库存数量 - var stockCounts []struct { - ErpCommodityID uint32 `gorm:"column:erp_commodity_id"` - StockCount int64 `gorm:"column:stock_count"` - } - err := orm.Eloquent.Table("erp_stock_commodity"). - Where("erp_commodity_id IN (?) AND state = ? AND store_id = ?", commodityIDs, InStock, storeId). - Select("erp_commodity_id, COUNT(*) as stock_count"). - Group("erp_commodity_id"). - Scan(&stockCounts).Error - if err != nil { - return nil, err - } - - // 创建库存数量映射 - stockCountMap := make(map[uint32]int64) - for _, stock := range stockCounts { - stockCountMap[stock.ErpCommodityID] = stock.StockCount - } - - // 更新商品的 StockCount 字段 + // 将商品按串码和非串码分开 for i, commodity := range commodities { - if count, exists := stockCountMap[commodity.CommodityId]; exists { - commodities[i].StockCount = uint32(count) - } else { - commodities[i].StockCount = 0 // 如果没有库存记录,则默认为 0 + if commodity.IMEIType == 2 { + imeiMap[commodity.IMEI] = &commodities[i] + } else if commodity.IMEIType == 1 { + nonImeiMap[commodity.CommodityId] = &commodities[i] + } + } + + // 查询串码商品的库存数量 + if len(imeiMap) > 0 { + var imeiKeys []string + for imei := range imeiMap { + imeiKeys = append(imeiKeys, imei) + } + + var stockCounts []struct { + IMEI string `gorm:"column:imei"` + StockCount int64 `gorm:"column:stock_count"` + } + err := orm.Eloquent.Table("erp_stock_commodity"). + Where("imei IN (?) AND state = ?", imeiKeys, InStock). + Select("imei, COUNT(*) as stock_count"). + Group("imei"). + Scan(&stockCounts).Error + if err != nil { + return nil, err + } + + for _, stock := range stockCounts { + if commodity, exists := imeiMap[stock.IMEI]; exists { + commodity.StockCount = uint32(stock.StockCount) + } + } + } + + // 查询非串码商品的库存数量 + if len(nonImeiMap) > 0 { + var commodityIDs []uint32 + for id := range nonImeiMap { + commodityIDs = append(commodityIDs, id) + } + + var stockCounts []struct { + ErpCommodityID uint32 `gorm:"column:erp_commodity_id"` + StockCount int64 `gorm:"column:stock_count"` + } + err := orm.Eloquent.Table("erp_stock_commodity"). + Where("erp_commodity_id IN (?) AND store_id = ? AND state = ?", commodityIDs, storeId, InStock). + Select("erp_commodity_id, COUNT(*) as stock_count"). + Group("erp_commodity_id"). + Scan(&stockCounts).Error + if err != nil { + return nil, err + } + + for _, stock := range stockCounts { + if commodity, exists := nonImeiMap[stock.ErpCommodityID]; exists { + commodity.StockCount = uint32(stock.StockCount) + } } } diff --git a/app/admin/models/purchase.go b/app/admin/models/purchase.go index 0a74b13..680e0b6 100644 --- a/app/admin/models/purchase.go +++ b/app/admin/models/purchase.go @@ -1254,7 +1254,7 @@ func CheckAndUpdatePurchaseOrderState(orderId uint32) error { if order.PurchaseType == ErpProcureOrder && commodity.Count != uint32(commodity.InventoryCount) { if err := orm.Eloquent.Model(&order).Updates(map[string]interface{}{ "state": ErpPurchaseOrderWaitInventory, - "audit_time": time.Now(), + "updated_at": time.Now(), }).Error; err != nil { return err } @@ -1263,7 +1263,7 @@ func CheckAndUpdatePurchaseOrderState(orderId uint32) error { if order.PurchaseType == ErpRejectOrder && commodity.RejectedCount != uint32(commodity.InventoryCount) { if err := orm.Eloquent.Model(&order).Updates(map[string]interface{}{ "state": ErpPurchaseOrderWaitReject, - "audit_time": time.Now(), + "updated_at": time.Now(), }).Error; err != nil { return err } @@ -1275,7 +1275,7 @@ func CheckAndUpdatePurchaseOrderState(orderId uint32) error { if err := orm.Eloquent.Model(&order). Updates(map[string]interface{}{ "state": ErpPurchaseOrderFinished, - "audit_time": time.Now(), + "updated_at": time.Now(), }).Error; err != nil { return err } @@ -3414,32 +3414,35 @@ func getReportByOrderFromCommon(req *ErpPurchaseReportByOrderReq, c *gin.Context PageIndex: page + 1, PageSize: req.PageSize, } - qs := orm.Eloquent.Table("erp_purchase_order").Where("state != ?", ErpPurchaseOrderUnAudit) // 未审核订单不展示 - if req.SerialNumber != "" { // 单据编号 - qs = qs.Where("serial_number=?", req.SerialNumber) + qs := orm.Eloquent.Table("erp_purchase_order"). + Joins("JOIN erp_purchase_commodity ON erp_purchase_order.id = erp_purchase_commodity.erp_purchase_order_id"). + Where("erp_purchase_order.state != ?", ErpPurchaseOrderUnAudit). // 未审核订单不展示 + Where("NOT (erp_purchase_order.state = 2 AND erp_purchase_commodity.inventory_count = 0)") // 排除 commodity 表中 state=2 且 inventory_count = 0 的记录 + if req.SerialNumber != "" { // 单据编号 + qs = qs.Where("erp_purchase_order.serial_number=?", req.SerialNumber) } if req.PurchaseType != "" { // 采购类型 - qs = qs.Where("purchase_type=?", req.PurchaseType) + qs = qs.Where("erp_purchase_order.purchase_type=?", req.PurchaseType) } if len(req.ErpSupplierId) > 0 { // 供应商复选 var supplierIDs []uint32 for _, supplier := range req.ErpSupplierId { supplierIDs = append(supplierIDs, supplier) } - qs = qs.Where("erp_supplier_id IN (?)", supplierIDs) + qs = qs.Where("erp_purchase_order.erp_supplier_id IN (?)", supplierIDs) } if len(req.StoreId) > 0 { // 门店复选 var storeIDs []uint32 for _, store := range req.StoreId { storeIDs = append(storeIDs, store) } - qs = qs.Where("store_id IN (?)", storeIDs) + qs = qs.Where("erp_purchase_order.store_id IN (?)", storeIDs) } if req.HandlerId != 0 { // 经手人id - qs = qs.Where("handler_id=?", req.HandlerId) + qs = qs.Where("erp_purchase_order.handler_id=?", req.HandlerId) } if req.State != 0 { // 订单状态 - qs = qs.Where("state=?", req.State) + qs = qs.Where("erp_purchase_order.state=?", req.State) } if req.AuditTimeStart != "" { // 审核开始时间 parse, err := time.Parse(QueryTimeFormat, req.AuditTimeStart) @@ -3447,7 +3450,7 @@ func getReportByOrderFromCommon(req *ErpPurchaseReportByOrderReq, c *gin.Context logger.Errorf("erpPurchaseOrderList err:", err) return nil, err } - qs = qs.Where("audit_time > ?", parse) + qs = qs.Where("erp_purchase_order.audit_time > ?", parse) } if req.AuditTimeEnd != "" { // 审核结束时间 parse, err := time.Parse(QueryTimeFormat, req.AuditTimeEnd) @@ -3456,11 +3459,11 @@ func getReportByOrderFromCommon(req *ErpPurchaseReportByOrderReq, c *gin.Context return nil, err } //parse = parse.AddDate(0, 0, 1) - qs = qs.Where("audit_time < ?", parse) + qs = qs.Where("erp_purchase_order.audit_time < ?", parse) } var count int64 - err := qs.Count(&count).Error + err := qs.Distinct("erp_purchase_order.id").Count(&count).Error if err != nil { logger.Error("getReportByOrderFromCommon count err:", logger.Field("err", err)) return resp, err @@ -3468,9 +3471,10 @@ func getReportByOrderFromCommon(req *ErpPurchaseReportByOrderReq, c *gin.Context resp.Total = int(count) var orders []ErpPurchaseOrder if req.ErpCategoryID != 0 || req.ErpCommodityName != "" || req.IsExport == 1 { - err = qs.Order("id DESC").Find(&orders).Error + err = qs.Order("erp_purchase_order.id DESC").Distinct("erp_purchase_order.*").Find(&orders).Error } else { - err = qs.Order("id DESC").Offset(page * req.PageSize).Limit(req.PageSize).Find(&orders).Error + err = qs.Order("erp_purchase_order.id DESC").Distinct("erp_purchase_order.*"). + Offset(page * req.PageSize).Limit(req.PageSize).Find(&orders).Error } if err != nil && err != RecordNotFound { logger.Error("getReportByOrderFromCommon erp_purchase_order err:", logger.Field("err", err)) @@ -4175,7 +4179,8 @@ func getReportByCommodityFromCommon(req *ErpPurchaseReportByCommodityReq, c *gin PageIndex: page + 1, PageSize: req.PageSize, } - qs := orm.Eloquent.Table("erp_purchase_order").Where("state != ?", ErpPurchaseOrderUnAudit) + qs := orm.Eloquent.Table("erp_purchase_order"). + Where("state NOT IN (?, ?)", ErpPurchaseOrderUnAudit, ErpPurchaseOrderEnd) if req.SerialNumber != "" { // 单据编号 qs = qs.Where("serial_number=?", req.SerialNumber) } diff --git a/docs/docs.go b/docs/docs.go index bb522b7..05f9236 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -8695,6 +8695,10 @@ const docTemplate = `{ "description": "备注", "type": "string" }, + "stock_count": { + "description": "库存数量", + "type": "integer" + }, "updatedAt": { "description": "更新时间", "type": "string" @@ -10089,7 +10093,10 @@ const docTemplate = `{ }, "store_id": { "description": "门店ID", - "type": "integer" + "type": "array", + "items": { + "type": "integer" + } } } }, @@ -10292,9 +10299,25 @@ const docTemplate = `{ "description": "商品名称", "type": "string" }, + "first_erp_category_id": { + "description": "商品一级分类id", + "type": "integer" + }, + "first_erp_category_name": { + "description": "商品一级分类名称", + "type": "string" + }, "price": { "description": "已执行单价", "type": "number" + }, + "second_erp_category_id": { + "description": "商品二级分类id", + "type": "integer" + }, + "second_erp_category_name": { + "description": "商品二级分类名称", + "type": "string" } } }, @@ -10862,6 +10885,10 @@ const docTemplate = `{ "type": "integer" } }, + "first_erp_category_id": { + "description": "商品一级分类id", + "type": "integer" + }, "handler_id": { "description": "经手人id", "type": "integer" @@ -10882,6 +10909,10 @@ const docTemplate = `{ "description": "采购类型:procure-采购 reject-退货", "type": "string" }, + "second_erp_category_id": { + "description": "商品二级分类id", + "type": "integer" + }, "serial_number": { "description": "单据编号", "type": "string" @@ -15352,6 +15383,14 @@ const docTemplate = `{ "description": "商品名称", "type": "string" }, + "first_erp_category_id": { + "description": "商品一级分类id", + "type": "integer" + }, + "first_erp_category_name": { + "description": "商品一级分类名称", + "type": "string" + }, "non_execution_amount": { "description": "未执行金额", "type": "number" @@ -15386,6 +15425,14 @@ const docTemplate = `{ "price": { "description": "已执行单价", "type": "number" + }, + "second_erp_category_id": { + "description": "商品二级分类id", + "type": "integer" + }, + "second_erp_category_name": { + "description": "商品二级分类名称", + "type": "string" } } }, diff --git a/docs/swagger.json b/docs/swagger.json index b1fddf7..ac583b0 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -8684,6 +8684,10 @@ "description": "备注", "type": "string" }, + "stock_count": { + "description": "库存数量", + "type": "integer" + }, "updatedAt": { "description": "更新时间", "type": "string" @@ -10078,7 +10082,10 @@ }, "store_id": { "description": "门店ID", - "type": "integer" + "type": "array", + "items": { + "type": "integer" + } } } }, @@ -10281,9 +10288,25 @@ "description": "商品名称", "type": "string" }, + "first_erp_category_id": { + "description": "商品一级分类id", + "type": "integer" + }, + "first_erp_category_name": { + "description": "商品一级分类名称", + "type": "string" + }, "price": { "description": "已执行单价", "type": "number" + }, + "second_erp_category_id": { + "description": "商品二级分类id", + "type": "integer" + }, + "second_erp_category_name": { + "description": "商品二级分类名称", + "type": "string" } } }, @@ -10851,6 +10874,10 @@ "type": "integer" } }, + "first_erp_category_id": { + "description": "商品一级分类id", + "type": "integer" + }, "handler_id": { "description": "经手人id", "type": "integer" @@ -10871,6 +10898,10 @@ "description": "采购类型:procure-采购 reject-退货", "type": "string" }, + "second_erp_category_id": { + "description": "商品二级分类id", + "type": "integer" + }, "serial_number": { "description": "单据编号", "type": "string" @@ -15341,6 +15372,14 @@ "description": "商品名称", "type": "string" }, + "first_erp_category_id": { + "description": "商品一级分类id", + "type": "integer" + }, + "first_erp_category_name": { + "description": "商品一级分类名称", + "type": "string" + }, "non_execution_amount": { "description": "未执行金额", "type": "number" @@ -15375,6 +15414,14 @@ "price": { "description": "已执行单价", "type": "number" + }, + "second_erp_category_id": { + "description": "商品二级分类id", + "type": "integer" + }, + "second_erp_category_name": { + "description": "商品二级分类名称", + "type": "string" } } }, diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 646c0a2..8ff1039 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -1757,6 +1757,9 @@ definitions: remark: description: 备注 type: string + stock_count: + description: 库存数量 + type: integer updatedAt: description: 更新时间 type: string @@ -2778,7 +2781,9 @@ definitions: type: string store_id: description: 门店ID - type: integer + items: + type: integer + type: array type: object models.ErpOrderStoreManageDataResp: properties: @@ -2926,9 +2931,21 @@ definitions: erp_commodity_name: description: 商品名称 type: string + first_erp_category_id: + description: 商品一级分类id + type: integer + first_erp_category_name: + description: 商品一级分类名称 + type: string price: description: 已执行单价 type: number + second_erp_category_id: + description: 商品二级分类id + type: integer + second_erp_category_name: + description: 商品二级分类名称 + type: string type: object models.ErpPurchaseCreateReq: properties: @@ -3342,6 +3359,9 @@ definitions: items: type: integer type: array + first_erp_category_id: + description: 商品一级分类id + type: integer handler_id: description: 经手人id type: integer @@ -3357,6 +3377,9 @@ definitions: purchase_type: description: 采购类型:procure-采购 reject-退货 type: string + second_erp_category_id: + description: 商品二级分类id + type: integer serial_number: description: 单据编号 type: string @@ -6569,6 +6592,12 @@ definitions: erp_commodity_name: description: 商品名称 type: string + first_erp_category_id: + description: 商品一级分类id + type: integer + first_erp_category_name: + description: 商品一级分类名称 + type: string non_execution_amount: description: 未执行金额 type: number @@ -6595,6 +6624,12 @@ definitions: price: description: 已执行单价 type: number + second_erp_category_id: + description: 商品二级分类id + type: integer + second_erp_category_name: + description: 商品二级分类名称 + type: string type: object models.ReportByOrderData: properties: