diff --git a/app/admin/models/inventory_report.go b/app/admin/models/inventory_report.go index a048eb4..e641f03 100644 --- a/app/admin/models/inventory_report.go +++ b/app/admin/models/inventory_report.go @@ -239,8 +239,8 @@ type ReportOtherDetailData struct { EmployeePrice float64 `json:"employee_price"` // 入库员工成本价 } -// ReportByProductList 产品库存汇总(按门店) -func (m *InventoryReportByProductReq) ReportByProductList(c *gin.Context) (*InventoryReportByProductResp, error) { +// ReportByProductList2 产品库存汇总(按门店) +func (m *InventoryReportByProductReq) ReportByProductList2(c *gin.Context) (*InventoryReportByProductResp, error) { // 非管理员才判断所属门店 if !(tools.GetRoleName(c) == "admin" || tools.GetRoleName(c) == "系统管理员") { sysUser, err := GetSysUserByCtx(c) @@ -411,6 +411,192 @@ func (m *InventoryReportByProductReq) ReportByProductList(c *gin.Context) (*Inve return resp, nil } +// ReportByProductList 产品库存汇总(按门店) +func (m *InventoryReportByProductReq) ReportByProductList(c *gin.Context) (*InventoryReportByProductResp, error) { + // 检查和设置门店权限... + if !(tools.GetRoleName(c) == "admin" || tools.GetRoleName(c) == "系统管理员") { + sysUser, err := GetSysUserByCtx(c) + if err != nil { + return nil, errors.New("操作失败:" + err.Error()) + } + + // 返回sysUser未过期的门店id列表 + storeList := GetValidStoreIDs(sysUser.StoreData) + if len(storeList) > 0 { + m.StoreId = CompareLists(storeList, m.StoreId) + if len(m.StoreId) == 0 { // 没有匹配的数据,表示入参门店不是用户有权限的门店 + return &InventoryReportByProductResp{}, nil + } + } else { + return nil, errors.New("用户未绑定门店") + } + } + + resp := &InventoryReportByProductResp{ + 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.Debug().Table("erp_stock") + sumQs := orm.Eloquent.Debug().Table("erp_stock_commodity") + + // 应用 StoreId 和其他条件 + if len(m.StoreId) > 0 { + qs = qs.Where("store_id IN (?)", m.StoreId) + sumQs = sumQs.Where("store_id IN (?)", m.StoreId) + } + + if len(m.CategoryID) > 0 { + qs = qs.Where("erp_category_id IN (?)", m.CategoryID) + sumQs = sumQs.Where("erp_category_id IN (?)", m.CategoryID) + } + + if len(m.CommoditySerialNumber) > 0 { // 商品编号 + qs = qs.Where("commodity_serial_number IN (?)", m.CommoditySerialNumber) + sumQs = sumQs.Where("commodity_serial_number IN (?)", m.CommoditySerialNumber) + } + + if len(m.CommodityName) > 0 { // 商品名称 + qs = qs.Where("erp_commodity_name IN (?)", m.CommodityName) + sumQs = sumQs.Where("erp_commodity_name IN (?)", m.CommodityName) + } + + // 统计总条数并直接赋值给 resp.Total + var count int64 + err := qs.Where("count != 0 or dispatch_count != 0 ").Count(&count).Error + if err != nil { + logger.Error("查询无库存列表数量失败", logger.Field("err", err)) + return nil, err + } + resp.Total = uint32(count) + + // 批量查询 EffectiveAmount 和 TransferAmount + effectiveAmounts, transferAmounts, err := getBatchAmounts(m.StoreId, m.CategoryID) + if err != nil { + return nil, err + } + + // 获取库存商品数据并填充金额 + var commodities []ErpStock + if m.IsExport == 1 { // 导出excel + err = qs.Order("erp_commodity_id, store_id desc").Find(&commodities).Error + } else { + err = qs.Order("erp_commodity_id, store_id desc"). + Offset(page * m.PageSize). + Limit(m.PageSize). + Find(&commodities).Error + } + if err != nil && err != RecordNotFound { + logger.Error("查询无库存列表失败", logger.Field("err", err)) + return nil, err + } + + if m.IsExport == 1 { + SortStockCommodities(commodities) + } + + // 构造报表数据 + var reportList []ReportByProductData + for _, item := range commodities { + reportData := ReportByProductData{ + StoreId: item.StoreId, + StoreName: item.StoreName, + CommoditySerialNumber: item.CommoditySerialNumber, + CommodityId: item.ErpCommodityId, + CommodityName: item.ErpCommodityName, + CategoryID: item.ErpCategoryId, + CategoryName: item.ErpCategoryName, + EffectiveCount: item.Count, + TransferCount: item.DispatchCount, + Count: item.Count + item.DispatchCount, + } + + reportData.EffectiveAmount = effectiveAmounts[item.StoreId][item.ErpCommodityId] + reportData.TransferAmount = transferAmounts[item.StoreId][item.ErpCommodityId] + reportData.Amount = reportData.EffectiveAmount + reportData.TransferAmount + + reportList = append(reportList, reportData) + } + + // 获取汇总数据 + sumData, err := getReportByProductSumData(sumQs) + if err != nil { + return nil, err + } + + // 填充响应数据 + resp.TotalEffectiveCount = sumData.TotalEffectiveCount + resp.TotalTransferCount = sumData.TotalTransferCount + resp.TotalCount = sumData.TotalCount + resp.TotalEffectiveAmount = math.Round(sumData.TotalEffectiveAmount*100) / 100 + resp.TotalTransferAmount = math.Round(sumData.TotalTransferAmount*100) / 100 + resp.TotalAmount = math.Round((resp.TotalEffectiveAmount+resp.TotalTransferAmount)*100) / 100 + resp.List = reportList + + if m.IsExport == 1 { // 导出excel + resp.ExportUrl, err = reportByProductExport(resp) + if err != nil { + return nil, err + } + resp.List = []ReportByProductData{} + } + + return resp, nil +} + +// 批量查询有效库存金额和调拨中金额 +func getBatchAmounts(storeIDs, categoryIDs []uint32) (map[uint32]map[uint32]float64, map[uint32]map[uint32]float64, error) { + effectiveAmounts := make(map[uint32]map[uint32]float64) + transferAmounts := make(map[uint32]map[uint32]float64) + + // 基于 storeIDs 和 categoryIDs 限制查询范围 + query := orm.Eloquent.Debug().Table("erp_stock_commodity"). + Select("store_id, erp_commodity_id, state, SUM(wholesale_price) AS amount"). + Where("state IN (?, ?)", InStock, InAllot) + + if len(storeIDs) > 0 { + query = query.Where("store_id IN (?)", storeIDs) + } + if len(categoryIDs) > 0 { + query = query.Where("erp_category_id IN (?)", categoryIDs) + } + + rows, err := query.Group("store_id, erp_commodity_id, state").Rows() + if err != nil { + return nil, nil, err + } + defer rows.Close() + + for rows.Next() { + var storeID, commodityID uint32 + var state int + var amount float64 + rows.Scan(&storeID, &commodityID, &state, &amount) + + if state == InStock { + if _, exists := effectiveAmounts[storeID]; !exists { + effectiveAmounts[storeID] = make(map[uint32]float64) + } + effectiveAmounts[storeID][commodityID] = amount + } else if state == InAllot { + if _, exists := transferAmounts[storeID]; !exists { + transferAmounts[storeID] = make(map[uint32]float64) + } + transferAmounts[storeID][commodityID] = amount + } + } + + return effectiveAmounts, transferAmounts, nil +} + // 查询有效库存金额 func getStockCommodityAmount(storeId, commodityId uint32) (float64, error) { var nCount int64